openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
clamp.cc
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) NumeriCor GmbH
2 // SPDX-License-Identifier: LicenseRef-APL-1.1
3 
4 #include <stdbool.h>
5 #include <assert.h>
6 
7 #include "MULTI_ION_IF.h"
8 #include "clamp.h"
9 
10 #include "petsc_utils.h" // TODO: for EXIT
11 
12 namespace limpet {
13 
17 using ::opencarp::timer_manager;
18 
29 bool
30 initialize_clamp(Clamp *cl, double cl_val, double ini_val, double start, double dur, const char *f,
31  int trans, float *duration)
32 {
33  bool fmode = (bool) strcmp(f, "");
34  bool isClamp = dur || fmode;
35  memset(cl, 0, sizeof(Clamp));
36 
37  if (fmode) {
38  cl->file = dupstr(f);
39  *duration = trace_duration(&cl->tr, cl->file);
40  }
41  else {
42  cl->dur = dur;
43  cl->val_pre = ini_val;
44  cl->val = cl_val;
45  cl->val_post = ini_val;
46  cl->start = start;
47  cl->tau = 0.1; // clamp time constant in ms
48  cl->transient = trans;
49  }
50 
51  return isClamp;
52 }
53 
54 void clamp_signal(MULTI_IF *pMIIF, Clamp *cl, timer_manager *tm)
55 {
56  if(cl->transient && ! tm->trigger(cl->transient)) return;
57 
58  pMIIF->getRealData();
59 
60  SF_real *v = pMIIF->procdata[Vm];
61  static double v0;
62  static bool fst = true;
63 
64  if (fst) {
65  v0 = v[0];
66  fst = false;
67  if (cl->file) {
68  read_trace(&cl->tr, cl->file);
69  resample_trace(&cl->tr, tm->time_step);
70  }
71  if(cl->transient)
72  cl->val_pre = v0;
73  }
74 
75  double val;
76  if (!cl->file) {
77  double time = tm->time;
78 
79  if (time <= cl->start)
80  val = cl->val_pre + (v0-cl->val_pre)*exp(-time / cl->tau);
81  else if (time > cl->start && time < cl->start+cl->dur)
82  val = cl->val + (cl->val_pre-cl->val)*exp(-(time - cl->start)/cl->tau);
83  else
84  val = cl->val_post + (cl->val-cl->val_post)*exp(-(time-(cl->start+cl->dur))/cl->tau);
85  } else
86  val = cl->tr.s[tm->d_time];
87 
88  for (node_index_t i=0; i<pMIIF->numNode;i++)
89  v[i] = val;
90 
91  pMIIF->releaseRealData();
92 }
93 
94 
102 void initialize_sv_clamp(Clamp *cl, const char *sv, char *file, double dt)
103 {
104  memset(cl, 0, sizeof(Clamp));
105 
106  read_trace(&cl->tr, cl->file=file);
107  resample_trace(&cl->tr, dt);
108  cl->sv = strdup(sv);
109 
110  cl->impDataID = IMPdataLabel2Index(sv);
111  cl->transient = -1000000; // last one was a real long time ago
112 }
113 
114 
122 void
123 sv_clamp(Clamp *cl, timer_manager *tm, MULTI_IF *miif, bool trigger)
124 {
125  int d_time = tm->d_time;
126 
127  if(trigger)
128  cl->transient = d_time;
129 
130  if(d_time - cl->transient < cl->tr.N) {
131  if(cl->impDataID>=0) {
132  if(miif->gdata[cl->impDataID] == NULL) {
133  log_msg(NULL, 5, 0, "Cannot clamp %s as the global vector %s is not used!!\n\n", cl->sv, cl->sv);
134  EXIT(-1);
135  }
136  miif->gdata[cl->impDataID]->set(cl->tr.s[d_time - cl->transient]);
137  }
138  else {
139  int offset;
140  int temparray[1] = {0};
141 
142  SVgetfcn svget = miif->IIF[0]->get_type().get_sv_offset(cl->sv, &offset, temparray);
143  if(!svget) {
144  log_msg(NULL, 5, 0, "\nCannot clamp %s as there is no %s!!\n\n", cl->sv, cl->sv);
145  EXIT(1);
146  }
147  SVputfcn svput= getPutSV(svget);
148  for(node_index_t i=0; i<miif->N_Nodes[0]; i++)
149  svput( *miif->IIF[0], i, offset, cl->tr.s[d_time - cl->transient]);
150  }
151  }
152 }
153 
154 
162 void
163 AP_clamp(Clamp *cl, timer_manager *tm, sf_vec* v, bool trigger)
164 {
165  if(trigger)
166  cl->transient = tm->d_time;
167 
168  if(tm->d_time-cl->transient < cl->tr.N)
169  v->set(cl->tr.s[tm->d_time-cl->transient]);
170 }
171 
172 
181 int
182 process_sv_clamps(char *SVs, char *files, Clamp **clamps, double dt)
183 {
184  *clamps = NULL;
185  int clno=0;
186 
187  if(!strlen(SVs) || !strlen(files))
188  return 0;
189 
190  char *svlist = strdup(SVs);
191  char *flist = strdup(files);
192  char *sptr, *fptr;
193 
194  // count the number of :'s
195  int ncol = 0;
196  char *p = SVs;
197  while((p = strchr(p, ':'))!=NULL) {
198  p++;
199  ncol++;
200  }
201 
202  *clamps = (Clamp*)calloc(ncol+1, sizeof(Clamp));
203 
204  char* sv = strtok_r(svlist, ":", &sptr);
205  char* file = strtok_r(flist, ":", &fptr);
206  while(sv != NULL && file!= NULL) {
207  initialize_sv_clamp((*clamps)+clno++, sv, file, dt);
208  sv = strtok_r(NULL, ":", &sptr);
209  file = strtok_r(NULL, ":", &fptr);
210  }
211 
212  if(sv != file) {
213  log_msg(NULL, 5, 0, "Mismatch between SV list and file list");
214  exit(1);
215  }
216 
217  free(svlist);
218  free(flist );
219 
220  return clno;
221 }
222 
223 } // namespace limpet
Define multiple ionic models to be used in different regions.
opencarp::real_t SF_real
Global scalar type.
Definition: SF_globals.h:18
virtual void set(const vector< T > &idx, const vector< S > &vals, const bool additive=false, const bool local=false)=0
std::vector< IonIfBase * > IIF
array of IIF's
Definition: MULTI_ION_IF.h:198
opencarp::sf_vec * gdata[NUM_IMP_DATA_TYPES]
data used by all IMPs
Definition: MULTI_ION_IF.h:212
node_count_t numNode
local number of nodes
Definition: MULTI_ION_IF.h:206
node_count_t * N_Nodes
#nodes for each IMP
Definition: MULTI_ION_IF.h:196
GlobalData_t * procdata[NUM_IMP_DATA_TYPES]
data for this processor
Definition: MULTI_ION_IF.h:200
#define log_msg(F, L, O,...)
Definition: filament.h:8
void(* SVputfcn)(IonIfBase &, node_index_t, int, GlobalData_t)
Definition: ion_type.h:34
double trace_duration(trace *tr, const char *f)
Definition: trace.cc:179
SVputfcn getPutSV(SVgetfcn)
void resample_trace(trace *tr, double dt)
Definition: trace.cc:147
void clamp_signal(MULTI_IF *pMIIF, Clamp *cl, timer_manager *tm)
Definition: clamp.cc:54
void sv_clamp(Clamp *cl, timer_manager *tm, MULTI_IF *miif, bool trigger)
Definition: clamp.cc:123
int IMPdataLabel2Index(const char *sv)
bool initialize_clamp(Clamp *cl, double cl_val, double ini_val, double start, double dur, const char *f, int trans, float *duration)
Definition: clamp.cc:30
GlobalData_t(* SVgetfcn)(IonIfBase &, node_index_t, int)
Definition: ion_type.h:33
int process_sv_clamps(char *SVs, char *files, Clamp **clamps, double dt)
Definition: clamp.cc:182
int read_trace(trace *tr, const char *name)
Definition: trace.cc:75
void initialize_sv_clamp(Clamp *cl, const char *sv, char *file, double dt)
Definition: clamp.cc:102
opencarp::local_index_t node_index_t
Definition: limpet_types.h:13
void AP_clamp(Clamp *cl, timer_manager *tm, sf_vec *v, bool trigger)
Definition: clamp.cc:163
char * dupstr(const char *old_str)
Definition: basics.cc:29
SF::abstract_vector< SF_int, SF_real > sf_vec
Definition: sf_interface.h:35
int impDataID
Definition: clamp.h:24
double tau
Definition: clamp.h:19
double val_post
Definition: clamp.h:16
double start
Definition: clamp.h:17
double val
Definition: clamp.h:15
double val_pre
Definition: clamp.h:14
int transient
Definition: clamp.h:22
double dur
Definition: clamp.h:18
char * file
Definition: clamp.h:20
trace tr
Definition: clamp.h:21
char * sv
Definition: clamp.h:23
float * s
samples
Definition: trace.h:13
int N
number of samples
Definition: trace.h:11