openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
ION_IF.cc
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is licensed under the openCARP Academic Public License (APL)
7 // v1.0: You can use and redistribute it and/or modify it in non-commercial
8 // academic environments under the terms of APL as published by the openCARP
9 // project v1.0, or (at your option) any later version. Commercial use requires
10 // a commercial license (info@opencarp.org).
11 //
12 // This program is distributed without any warranty; see the openCARP APL for
13 // more details.
14 //
15 // You should have received a copy of the openCARP APL along with this program
16 // and can find it online: http://www.opencarp.org/license
17 // ----------------------------------------------------------------------------
18 
28 /*
29  * Specify an interface for an IMP
30  *
31  * To use an IMP by itself outside of MULTI_IF.h, one must \n
32  * -# alloc_IIF()
33  * -# set the rdata pointers in the ::IMPDataStruct
34  * -# initialize_params()
35  * -# initialize_IIF()
36  * -# call the compute() method of the IMP
37  *
38  * The IMP library tries to avoid undo computation by using lookup
39  * tables to avoid computation of costly mathematical functions.
40  * Tables indices may be computed based on vltage, calcium concentrations,
41  * or any other quantity.
42  *
43  * One common scenario is commonly encountered with first-order differential
44  * equations:
45  * \f[ \frac{dz}{dt} = \frac{z_{\infty}(x) - z}{\tau_z(x)} \f]
46  *
47  * Using an exponential solution assuming that
48  * \f$z_{\inf}(x)\f$ and \f$\tau_z(x)\f$ constant over a time step:
49  *
50  * \f[ \begin{split}
51  * z_{i+1} & = z_{\infty}(x) - (z_{\infty}(x)-z_i)
52  * \exp\Large (-\Delta t/\tau_z(x) \Large ) \\
53  * & = A(x) + B(x) z_i
54  * \end{split}\f]
55  * where A(x) and B(x) are entered into a look up table which is
56  * indexed by \em x:
57  * \f[ \begin{split}
58  * A(x) &= z_{\infty}(x)\Large ( 1 - \exp(-\Delta t/\tau_z(x)\Large ) \\
59  * &= -z_{\infty}(x) expm1\Large ( -\Delta t/\tau_z(x) \Large ) \\
60  * B(x) &= \exp(-\Delta t/\tau_z(x))
61  * \end{split}\f]
62  *
63  */
64 #include "limpet_types.h"
65 #include "ION_IF.h"
66 #include <stdarg.h>
67 
68 #ifdef USE_CVODE
69 #include <nvector/nvector_serial.h>
70 #include <cvode/cvode.h>
71 #include <cvode/cvode_diag.h>
72 #endif
73 
74 namespace limpet {
75 
79 using ::opencarp::Salt_list;
80 
81 #ifdef USE_HDF5
82 FILE_SPEC _nc_logf = (FILE_SPEC)calloc(1, sizeof(fileptr));
83 #else
84 FILE_SPEC _nc_logf = NULL;
85 #endif
86 
87 
88 char* tokstr_r(char *s1, const char *s2, char **lasts)
89 {
90  char *ret;
91 
92  if (s1 == NULL)
93  s1 = *lasts;
94  while(*s1 && strchr(s2, *s1))
95  ++s1;
96  if(*s1 == '\0')
97  return NULL;
98  ret = s1;
99  while(*s1 && !strchr(s2, *s1))
100  ++s1;
101  if(*s1)
102  *s1++ = '\0';
103  *lasts = s1;
104  return ret;
105 }
106 
107 
108 #ifndef offsetof
109 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
110 #endif
111 
112 // struct exception_context the_exception_context[1];
113 
115 
116 IonIfBase::IonIfBase(const IonType& type, Target target, int num_node, const std::vector<std::reference_wrapper<IonType>>& plugins)
117  : _type(type), _target(type.select_target(target)), _num_node(num_node) {
118  this->_tstp = {};
119  this->_reqdat = type.reqdat();
120  this->_moddat = type.moddat();
121  this->_plugins = {};
122 
123  for (const auto& plugin : plugins) {
124  auto child = plugin.get().make_ion_if(target, num_node, {});
125  child->_parent = this;
126  this->_plugins.push_back(child);
127 
128  this->_reqdat |= child->_reqdat;
129  this->_moddat |= child->_moddat;
130  }
131 }
132 
134  for (auto plugin : this->_plugins) {
135  plugin->get_type().destroy_ion_if(plugin);
136  }
137 
138  this->_type.destroy(*this);
139  if (this->_tables_d != nullptr) {
140  deallocate_on_target<LUT>(this->_target, this->_tables_d);
141  }
142 }
143 
144 const IonType& IonIfBase::get_type() const {
145  return this->_type;
146 }
147 
149  return this->_num_node;
150 }
151 
152 std::size_t IonIfBase::get_num_threads() const {
153  std::size_t num_threads = 0;
154  switch (this->_target) {
155  // CPU target threads number depends on wether OpenMP is enabled or not
156  case Target::CPU:
157  case Target::MLIR_CPU:
158 #ifdef _OPENMP
159  num_threads = omp_get_max_threads();
160 #else
161  num_threads = 1;
162 #endif
163  break;
164  // GPU targets threads numbers is the number of cells
165  case Target::MLIR_CUDA:
166  case Target::MLIR_ROCM:
167  num_threads = this->get_num_node();
168  break;
169  default:
170  throw std::logic_error("The IonIf execution target " + std::to_string(this->_target) + " is invalid");
171  break;
172  }
173  return num_threads;
174 }
175 
177  return this->_parent;
178 }
179 
181  this->_parent = parent;
182 }
183 
184 std::vector<IonIfBase*>& IonIfBase::plugins() {
185  return this->_plugins;
186 }
187 
188 uint32_t IonIfBase::get_reqdat() const {
189  return this->_reqdat;
190 }
191 
192 uint32_t IonIfBase::get_moddat() const {
193  return this->_moddat;
194 }
195 
196 void IonIfBase::set_moddat(uint32_t data) {
197  this->_moddat = data;
198 }
199 
200 float IonIfBase::get_dt() const {
201  return this->dt;
202 }
203 
204 void IonIfBase::set_dt(float dt) {
205  this->dt = dt;
206 }
207 
209  return this->_tstp;
210 }
211 
212 std::vector<LUT>& IonIfBase::tables() {
213  return this->_tables;
214 }
215 
217  return this->_n_tables_d;
218 }
219 
221  if (is_concrete(this->get_type().select_target(target))) {
222  this->_target = target;
223  }
224  else {
225  throw std::invalid_argument("new target set for IMP is unavailable or not concrete (AUTO, UNKNWOWN, ...)");
226  }
227 }
228 
230  this->_type.initialize_params(*this);
231 
232  for (auto& plugin : this->_plugins) {
233  plugin->initialize_params();
234  }
235 }
236 
237 void IonIfBase::initialize(double dt, GlobalData_t **impdat) {
244  this->dt = dt;
245 
246  if (this->_num_node) {
247  this->_type.construct_tables(*this);
248  // If this is a GPU target, we need to copy the LUT definitions to the
249  // device
250  if (is_gpu(this->get_target()) && this->tables().size() > 0) {
251  // Allocate on device and copy
252  this->_tables_d = allocate_on_target<LUT>(this->get_target(), this->tables().size());
253  // TODO replace this with some kind of memcpy (needs to be adjusted
254  // depending on CUDA / HIP
255  for (size_t i = 0; i < this->tables().size(); ++i) {
256  this->_tables_d[i] = this->tables()[i];
257  }
258  this->_n_tables_d = this->tables().size();
259  }
260  }
261 
262  this->_type.initialize_sv(*this, impdat);
263  this->ldata = impdat;
264 
265  for (auto& plugin : this->_plugins) {
266  plugin->initialize(dt, impdat);
267  }
268 }
269 
270 void IonIfBase::compute(int start, int end, GlobalData_t **data) {
271  this->_type.compute(this->_target, start, end, *this, data);
272 }
273 
274 char* IonIfBase::fill_buf(char *buf, int* n, opencarp::Salt_list *l) const {
275  int iif_sz = this->get_sv_size();
276 
277  for (auto& plugin : this->_plugins) {
278  iif_sz += plugin->get_sv_size();
279  }
280 
281  buf = (char *) realloc(buf, *n + l->nitems*iif_sz) + *n;
282  *n += l->nitems * iif_sz;
283 
284  return buf - *n + l->nitems * iif_sz;
285 }
286 
287 int IonIfBase::restore(FILE_SPEC in, int n, const int *pos, IIF_Mask_t *mask,
288  size_t *offset, IMPinfo *impinfo, const int* loc2canon) {
289  if( !impinfo->compatible )
290  return n;
291 
292  char *ptr = (char *)(this->get_sv_address());
293  long base = ftell(in->fd);
294  int mismatch = 0;
295 
296  // Restoration of the model data need to take care of the data layout
297  // optimization. (if it is disabled, the vector size should be 1 anyways
298  std::size_t vec_size = this->get_type().dlo_vector_size();
299  for( int i=0; i<n; i+=vec_size ) {
300  int index = i / vec_size;
301  int canon = loc2canon[pos[i]];
302  if(mask[canon] == this->miifIdx) {
303  fseek(in->fd, base+offset[canon], SEEK_SET);
304  fread(ptr+index*impinfo->sz, impinfo->sz, 1, in->fd);
305 
306  for(int j=0; j<impinfo->nplug; j++) {
307  if(impinfo->plug[j].compatible) {
308  fread((char*)(this->_plugins[impinfo->plug[j].map]->get_sv_address())+index*impinfo->plug[j].sz,
309  impinfo->plug[j].sz, 1, in->fd);
310  }
311  else
312  fseek(in->fd, impinfo->plug[j].sz, SEEK_CUR);
313  }
314  }
315  else
316  mismatch++;
317  }
318  return mismatch;
319 }
320 
321 int IonIfBase::dump_luts(bool zipped) {
322  std::string name;
323  std::string ext = zipped ? ".gz" : "";
324 
325  int dcnt = 0;
326  for (int i=0; i < this->_tables.size(); i++) {
327  // determine file name
328  if (strcmp(this->_tables[i].name, ""))
329  name = this->_type.get_name() + "_LUT_" + this->_tables[i].name + ".bin" + ext;
330  else
331  name = this->_type.get_name() + "_LUT_" + std::to_string(i) + ".bin" + ext;
332 
333  // dump table
334  int err = LUT_dump(&this->_tables[i], name.c_str());
335  if (!err) dcnt++;
336  }
337  return dcnt;
338 }
339 
341  for (auto& lut : this->_tables) {
342  destroy_lut(&lut, this->_target);
343  }
344 
345  std::vector<LUT>().swap(this->_tables);
346 }
347 
348 void IonIfBase::tune(const char *im_par, const char *plugs, const char *plug_par) {
349  char *opar, *oplg, *plg, *nplg, *parlst, *nparlst;
350 
351  if( im_par && *im_par != '\0' ) {
352  log_msg( _nc_logf, 0, 0, "Ionic model: %s", this->_type.get_name().c_str());
353  this->_type.tune(*this, im_par);
354  }
355  opar = parlst = dupstr(plug_par);
356  oplg = plg = dupstr(plugs);
357 
358  while( plg!=NULL && *plg!='\0' ) {
359  nparlst = get_next_list( parlst, ':' );
360  nplg = get_next_list( plg, ':' );
361 
362  log_msg( _nc_logf, 0, 0, "Plug-in: %s", plg );
363 
364  if( parlst==NULL || *parlst=='\0' ) {
365  parlst = nparlst;
366  plg = nplg;
367  continue;
368  }
369 
370  // find apropriate plugin
371  IonType* plugin = get_ion_type(plg);
372  int j;
373 
374  for(j = 0; j < this->_plugins.size(); j++) {
375  if(this->_plugins[j]->get_type() == *plugin) break;
376  }
377 
378  if(j == this->_plugins.size()) {
379  log_msg( _nc_logf, 2, 0, "Plugin %s not used with IM", plg );
380  plg = nplg;
381  parlst = nparlst;
382  continue;
383  }
384 
385  plugin->tune(*this->_plugins[j], parlst);
386  plg = nplg;
387  parlst = nparlst;
388  }
389 
390  log_msg( _nc_logf, 0, 0, "" );
391  free( opar );
392  free( oplg );
393 }
394 
395 int IonIfBase::read_svs(FILE* file) {
396  if(this->get_num_node())
397  return this->_type.read_svs(*this, file);
398  else
399  return 1;
400 }
401 
402 int IonIfBase::write_svs(FILE* file, int node) {
403  return this->_type.write_svs(*this, file, node);
404 }
405 
407  this->_plugins = {};
408 
409  for (auto& plugin : other.plugins()) {
410  auto copy = plugin->get_type().make_ion_if(this->_target, plugin->get_num_node(), {});
411  copy->_parent = this;
412  this->_plugins.push_back(copy);
413  copy->copy_SVs_from(*plugin, true);
414  }
415 }
416 
417 void IonIfBase::for_each(const std::function<void(IonIfBase&)>& consumer) {
418  consumer(*this);
419 
420  for (auto& plugin : this->_plugins) {
421  consumer(*plugin);
422  }
423 }
424 
436 // Is this ever used?
437 void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
438 {
439  // initialize step counter that will run linearly as long the
440  // simulation goes
441  tstp->cnt = -1;
442  tstp->ng = ng;
443  tstp->tcg = allocate_on_target<tc_grp>(target, ng);
444 
445  // initialize time constant grouping
446  // fast variables, use dt=dt
447  tstp->tcg[0].skp = 1;
448  tstp->tcg[0].dt = dt;
449  tstp->tcg[0].update = 1;
450 
451  for (int i=1;i<ng;i++) {
452  tstp->tcg[i].skp = skp[i];
453  tstp->tcg[i].dt = tstp->tcg[i].skp*dt;
454  }
455 }
456 
457 
466 void update_ts(ts *ptstp)
467 {
468  ptstp->cnt++;
469 
470  tc_grp *ptcg = ptstp->tcg;
471  for (int i=1;i<ptstp->ng;i++)
472  ptcg[i].update = !(ptstp->cnt%ptcg[i].skp);
473 }
474 
475 
476 #ifndef _GNU_SOURCE
477 
486 void *memmem( void *haystack, int sz_hay, void *needle, int sz_n )
487 {
488  if( !sz_n ) return NULL;
489 
490  char *h = (char *)haystack;
491 
492  for( int i=0; i>sz_hay-sz_n+1; i++, h++ )
493  if( !memcmp( h, needle, sz_n ) )
494  return (void *)h;
495  break;
496 
497  return NULL;
498 }
499 #endif
500 
501 
512 char *get_next_list( char *lst, char delimiter )
513 {
514  if( lst == NULL || *lst == '\0' )
515  return NULL;
516 
517  while( *lst != delimiter && *lst != '\0' )
518  lst++;
519 
520  if( *lst != '\0' ) {
521  *lst = '\0';
522  return lst+1;
523  } else
524  return lst;
525 }
526 
527 
535  bool verify_flags( const char *flags, const char* given )
536  {
537  char *flag, *ptr, *gvn_cp = dupstr( given );
538 
539  flag = tokstr_r( gvn_cp, "|", &ptr );
540  while( flag ) {
541  if( !flag_set( flags, flag ) )
542  break;
543  flag = tokstr_r( NULL, "|", &ptr );
544  }
545 
546  free( gvn_cp );
547  return flag ? false : true;
548 }
549 
557 bool flag_set( const char *flags, const char *target )
558 {
559  if( !flags ) return false;
560 
561  char *f = dupstr( flags ), *last, *pos;
562 
563  pos = tokstr_r( f, "|", &last );
564  while( pos && strcmp( pos, target ) ) {
565  pos = tokstr_r( NULL, "|", &last );
566  }
567  free( f );
568 
569  return pos? true : false;
570 }
571 
572 
573 #ifdef USE_CVODE
574 
577 void __bogus_function_for_cvode() {
578 
579  int flag;
580  int N_CVODE = 1;
581 #if SUNDIALS_VERSION_MAJOR < 4
582  void* cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
583 #elif SUNDIALS_VERSION_MAJOR < 6
584  void* cvode_mem = CVodeCreate(CV_BDF);
585 #elif SUNDIALS_VERSION_MAJOR < 7
586  SUNContext sunctx;
587  MPI_Comm comm = PETSC_COMM_WORLD;
588  if( SUNContext_Create(&comm, &sunctx )<0 ){
589  assert(0);
590  }
591  void* cvode_mem = CVodeCreate(CV_BDF, sunctx);
592 #else // version from 7.0.0
593  SUNContext sunctx;
594  SUNComm comm = PETSC_COMM_WORLD;
595  if( SUNContext_Create( comm, &sunctx )<0 ){
596  assert(0);
597  }
598  void* cvode_mem = CVodeCreate(CV_BDF, sunctx);
599 #endif
600  assert(cvode_mem != NULL);
601 #if SUNDIALS_VERSION_MAJOR >= 6
602  N_Vector cvode_y = N_VNew_Serial(N_CVODE, sunctx);
603 #else
604  N_Vector cvode_y = N_VNew_Serial(N_CVODE);
605 #endif
606  flag = CVodeInit(cvode_mem, NULL, 0, cvode_y);
607  assert(flag == CV_SUCCESS);
608  N_VDestroy(cvode_y);
609 
610  flag = CVodeSStolerances(cvode_mem, 1e-5, 1e-6);
611  assert(flag == CV_SUCCESS);
612  flag = CVodeSetMaxStep(cvode_mem, 1);
613  assert(flag == CV_SUCCESS);
614  flag = CVodeSetUserData(cvode_mem, NULL);
615  assert(flag == CV_SUCCESS);
616  flag = CVDiag(cvode_mem);
617  assert(flag == CV_SUCCESS);
618 
619  NV_Ith_S(cvode_y,0) = 0;
620 
621  {
622  int CVODE_flag;
623  CVODE_flag = CVodeReInit(NULL, 1, NULL);
624  assert(CVODE_flag == CV_SUCCESS);
625  CVODE_flag = CVodeSetInitStep(NULL, 1);
626  assert(CVODE_flag == CV_SUCCESS);
627 #if SUNDIALS_VERSION_MAJOR >= 7
628  sunrealtype tret;
629 #else
630  realtype tret;
631 #endif
632  CVODE_flag = CVode(cvode_mem, 1, NULL, &tret, CV_NORMAL);
633  assert(CVODE_flag == CV_SUCCESS);
634  }
635 }
636 #endif
637 
638 } // namespace limpet
Target _target
execution target for this IMP
Definition: ION_IF.h:151
float get_dt() const
Gets the basic integration time step.
Definition: ION_IF.cc:200
const std::string & get_name() const
Gets the model name.
Definition: ion_type.cc:23
bool compatible
does IM match stored IM
Definition: ION_IF.h:130
char * dupstr(const char *old_str)
Definition: basics.cc:44
ts _tstp
control time stepping
Definition: ION_IF.h:153
tc_grp * tcg
Definition: ION_IF.h:88
virtual void initialize_sv(IonIfBase &imp, GlobalData_t **data) const =0
Initializes the state variables of the given IMP.
int nplug
number of plugins
Definition: ION_IF.h:128
const IonType & get_type() const
Gets this IMP&#39;s model type.
Definition: ION_IF.cc:144
IonIfBase * parent() const
Gets the parent IMP.
Definition: ION_IF.cc:176
int update
Definition: ION_IF.h:78
vectorized CPU code generated with MLIR
Definition: target.h:49
int restore(opencarp::FILE_SPEC in, int n, const int *pos, IIF_Mask_t *mask, size_t *offset, IMPinfo *impinfo, const int *loc2canon)
Reads in the state variables for an IMP.
Definition: ION_IF.cc:287
uint32_t get_reqdat() const
Gets the data flags for this IMP&#39;s required data.
Definition: ION_IF.cc:188
virtual void initialize_params(IonIfBase &imp) const =0
Initializes the parameters in the given IMP.
virtual int write_svs(IonIfBase &imp, FILE *file, int node) const =0
Write state variable values for one cell to a file/.
FILE_SPEC _nc_logf
Definition: ION_IF.cc:84
void destroy_lut(LUT *plut, Target target)
Definition: LUT.cc:101
IMPinfo * plug
plugins
Definition: ION_IF.h:129
virtual int read_svs(IonIfBase &imp, FILE *file) const =0
Reads state variable values for one cell from a file.
int read_svs(FILE *file)
Reads state variable values for one cell from a file.
Definition: ION_IF.cc:395
virtual std::size_t get_sv_size() const =0
Gets the size of the structure this IMP uses for state variables.
void set_parent(IonIfBase *parent)
Definition: ION_IF.cc:180
Target get_target() const
Definition: ION_IF.h:338
int map
which plugin does this IMO match
Definition: ION_IF.h:131
void set_moddat(uint32_t data)
Set the data flag for this IMP&#39;s modified data.
Definition: ION_IF.cc:196
bool is_gpu(Target const target)
Checks if this is a GPU target.
Definition: target.cc:64
int sz
storage required
Definition: ION_IF.h:127
std::size_t get_num_threads() const
Gets the number of threads used for running this IMP.
Definition: ION_IF.cc:152
virtual void destroy(IonIfBase &imp) const =0
Destroys the given IMP.
virtual uint32_t moddat() const =0
Gets data flags for this IMP&#39;s modified data.
IonIfBase(const IonType &type, Target target, int num_node, const std::vector< std::reference_wrapper< IonType >> &plugins)
Constructor for IonIfBase.
Definition: ION_IF.cc:116
Represents the ionic model and plug-in (IMP) data structure.
Definition: ION_IF.h:138
IonType * get_ion_type(const std::string &name)
virtual void tune(IonIfBase &imp, const char *im_par) const =0
Handles setting of this model&#39;s parameters.
void compute(int start, int end, GlobalData_t **data)
Perform ionic model computation for 1 time step.
Definition: ION_IF.cc:270
virtual size_t dlo_vector_size() const =0
Gets the vector size when using data layout optimization (DLO).
char IIF_Mask_t
Definition: ion_type.h:50
void destroy_luts()
Destroys array of LUTs.
Definition: ION_IF.cc:340
virtual uint32_t reqdat() const =0
Gets data flags for this IMP&#39;s required data.
char * get_next_list(char *lst, char delimiter)
Definition: ION_IF.cc:512
virtual void construct_tables(IonIfBase &imp) const =0
Contructs lookup tables.
int LUT_dump(LUT *plut, const char *fname)
Definition: LUT.cc:74
void tune(const char *im_par, const char *plugs, const char *plug_par)
Tunes specific IMP parameters from files.
Definition: ION_IF.cc:348
int ng
Definition: ION_IF.h:87
float dt
Definition: ION_IF.h:75
ts & get_tstp()
Gets the time stepper.
Definition: ION_IF.cc:208
char * tokstr_r(char *s1, const char *s2, char **lasts)
Definition: ION_IF.cc:88
bool is_concrete(Target const target)
Checks if target is a real, concrete target.
Definition: target.cc:68
virtual void initialize(double dt, GlobalData_t **impdat)
Initializes lookup table and state variable tables.
Definition: ION_IF.cc:237
bool flag_set(const char *flags, const char *target)
Definition: ION_IF.cc:557
size_t get_n_tables_d() const
Gets the size of the array returned by IonIf::tables_d.
Definition: ION_IF.cc:216
void for_each(const std::function< void(IonIfBase &)> &consumer)
Executes the consumer functions on this IMP and each of its plugins.
Definition: ION_IF.cc:417
virtual void set_target(Target target)
Definition: ION_IF.cc:220
baseline CPU model generated with the original opencarp code generator
Definition: target.h:48
void log_msg(FILE_SPEC out, int level, unsigned char flag, const char *fmt,...)
Definition: basics.cc:72
int nitems
number of items
Definition: basics.h:60
int get_num_node() const
Gets the number of nodes handled by this IMP.
Definition: ION_IF.cc:148
int cnt
Definition: ION_IF.h:86
CUDA code for NVIDIA GPUs generated with MLIR.
Definition: target.h:51
time stepper
Definition: ION_IF.h:85
std::vector< IonIfBase * > & plugins()
Returns a vector containing the plugins of this IMP.
Definition: ION_IF.cc:184
int write_svs(FILE *file, int node)
Definition: ION_IF.cc:402
void update_ts(ts *ptstp)
Definition: ION_IF.cc:466
virtual void * get_sv_address()=0
Gets the raw address of the state variables for this IMP.
void initialize_params()
Initializes user modifiable parameters with default values defined in the respective ionic models...
Definition: ION_IF.cc:229
int * curr_node_list
needed to determine the global node number
Definition: ION_IF.cc:114
Target
enum that represents different targets to run ionic models on.
Definition: target.h:45
int dump_luts(bool zipped)
Dumps array of LUTs to file.
Definition: ION_IF.cc:321
bool verify_flags(const char *flags, const char *given)
Definition: ION_IF.cc:535
saltatory list – memory is allocated in chunks
Definition: basics.h:57
virtual ~IonIfBase()
Virtual destructor declaration.
Definition: ION_IF.cc:133
void copy_plugins_from(IonIfBase &other)
Copies the plugins of an IMP.
Definition: ION_IF.cc:406
void initialize_ts(Target target, ts *tstp, int ng, int *skp, double dt)
Definition: ION_IF.cc:437
std::vector< LUT > & tables()
Gets the array of state variables.
Definition: ION_IF.cc:212
char * fill_buf(char *buf, int *n, opencarp::Salt_list *l) const
Appends the state variables to a buffer.
Definition: ION_IF.cc:274
virtual void compute(Target target, int start, int end, IonIfBase &imp, GlobalData_t **data) const =0
Performs computation for 1 time step.
Abstract class representing an ionic model type.
Definition: ion_type.h:59
int miifIdx
imp index within miif
Definition: ION_IF.h:150
time constant groups
Definition: ION_IF.h:74
file_desc * FILE_SPEC
Definition: basics.h:138
void * memmem(void *haystack, int sz_hay, void *needle, int sz_n)
Definition: ION_IF.cc:486
uint32_t get_moddat() const
Gets the data flags for this IMP&#39;s modified data.
Definition: ION_IF.cc:192
ROCM code for AMD GPUs generated with MLIR.
Definition: target.h:50
void set_dt(float dt)
Sets the basic integration time step.
Definition: ION_IF.cc:204
SF_real GlobalData_t
Definition: limpet_types.h:27