have functions in my cell model calling CVODE for each time step.
When I build the application I get a number of link errors:
\cardiacsimulat or.o Release\ccardia ccell.o Release\ccellda ta.o
Release\cgapjun ction.o Release\cheart2 d.o Release\integra tor.o -o
D:\kp\programs\ cardiacsimulato r\Release\cardi acsimulator.exe
Release\integra tor.o: In function `func_f':
/cygdrive/d/kp/programs/cardiacsimulato r/integrator.cpp: 70: multiple
definition of `_func_f'
Release\cardiac simulator.o:/cygdrive/d/kp/programs/cardiacsimulato r/integrator.cpp: 70:
first defined here
What am I doing wrong? I am definitely not redefining any of the
functions!
This is the integrator file
)************** *************** *************** *************** *************** *88
#include "CDFNCell.h "
/* ----------------------------------------------------
code to call CVode
starts here
----------------------------------------------------
*/
#include <sundialstypes. h /* definitions of types realtype and
*/
/* integertype, and the constant FALSE
*/
#include <cvode.h /* prototypes for CVodeMalloc, CVode, and
*/
/* CVodeFree, constants OPT_SIZE, BDF,
NEWTON, */
/* SV, SUCCESS, NST,NFE,NSETUPS , NNI,
NCFN, NETF */
#include <cvdense.h /* prototype for CVDense, constant
DENSE_NJE */
#include <nvector_serial .h /* definitions of type N_Vector and macro
*/
/* NV_Ith_S, prototypes for N_VNew,
N_VFree */
#include <dense.h /* definitions of type DenseMat, macro
DENSE_ELEM*/
/*
CVode specific functions
CVode is a stiff/non-stiff integrator written in C (not in
C++)
To work this code needs header files and a cvode library
*/
extern "C" {
static N_Vector cvode_y;
static void *cvode_mem;
static realtype reltol,abstol;
static N_Vector ew;
static double cvode_t;
M_Env MachEnv;
static realtype ropt[OPT_SIZE];
static long int iopt[OPT_SIZE];
}
// Call CVode
void CDFNCell::CVode _run(double h,double states[])
{
int flag=0,i;
// call CVode to solve ydot(t)=f(y,t) with y(0) given
flag = CVode(cvode_mem , start_time+h, cvode_y, &cvode_t,
NORMAL);
if (flag != SUCCESS) {
cerr<<"CVode failed, flag="<<flag<<" ."<<endl;
}
// copy vector y to states which is returned to compute
for(i=0;i<state size;i++)
states[i]=NV_Ith_S(cvode _y,i);
states[0]=y0[0];
}
// Extra function that acts as a front to CVode
extern "C" void func_f(long N, realtype time, N_Vector y, N_Vector
ydot, void *f_data)
{
cellptr->CVode_f(N, time, y, ydot, f_data);
}
// function f(t,y) for CVode, returns derivatives of variables to CVode
void CDFNCell::CVode _f(int N, double time, N_Vector y, N_Vector ydot,
void *f_data)
{
int z;
static double states2[MAXSTATES];
bool flag=true;
// copy vector y to states2
for(z=0;z<N;z++ )
states2[z]=NV_Ith_S(y,z);
// send states2 to getF which uses it to produce derivatives
calDiff(time,st ates2,flag);
// copy derivatives to vector ydot which is returned to CVode
for(z=0;z<N;z++ ) {
NV_Ith_S(ydot,z )=Diff[z];
}
}
// Initializes CVode
void CDFNCell::CVode Init(double states[],double timenow)
{
int i;
MachEnv = M_EnvInit_Seria l((int)statesiz e);
if (MachEnv == NULL) {
cerr<<"Trouble with MachEnv in CVODE"<<endl;
exit(-3);
}
// Allocate memory for solution vector y(t)
cvode_y = N_VNew((int)sta tesize, MachEnv);
// Allocate memory for solution vector ew(t)
ew = N_VNew((int)sta tesize, MachEnv);
// rel tolerance of 10^-5 might be a good idea
reltol = tolerance_relat ive;
abstol = tolerance_absol ute;
// initialize vector cvode_y with states
for(i=0;i<state size;i++)
NV_Ith_S(cvode_ y,i)=states[i];
// use default values for options
for(i=0;i<OPT_S IZE;i++) {
ropt[i]=0.0;
iopt[i]=0;
}
// except for these
ropt[HMAX]=step_max; // Largest step size
ropt[HMIN]=step_min; // Smallest step size
iopt[MXSTEP]=100000; // max internal step number for cvode
// scale tolerance based on maximum value of state
for(i=0;i<state size;i++) {
NV_Ith_S(ew,i)= abstol/errweight[i];
}
/* CVodeMalloc sets up initial settings for CVode. See
CVODE
documentation.
Integration method is BDF(Backward Differential
Formula)
Other choice would be ADAMS but it is not as stable as
BDF */
#if 0
// This method of calling CVODE does not pass error
weights
cvode_mem = CVodeMalloc(sta tesize, func_f, timenow, cvode_y,
BDF,
NEWTON, SS, &reltol, &abstol,
NULL, NULL, TRUE, iopt, ropt, MachEnv);
//#else
// We wish to pass errorweight to CVODE
//cvode_mem = CVodeMalloc(sta tesize, func_f, timenow, cvode_y,
BDF,
NEWTON,
// SV, &reltol,
ew, NULL, NULL, TRUE, iopt, ropt, MachEnv);
#endif
if (cvode_mem == NULL) {
cerr<<"CVodeMal loc failed."<<endl;
exit(1);
}
/* CVDense is needed by Newton algorithm for solving linear
system
The second NULL tells the solver to compute an approximation
of the
Jacobian. */
CVDense(cvode_m em, NULL, NULL);
}
void CDFNCell::CVode Exit(void)
{
N_VFree(cvode_y );
CVodeFree(cvode _mem);
M_EnvFree_Seria l(MachEnv);
}
*************** *************** *************** *************** ***********
THis is the class definition:
#define CDFNCELL_H
#include <math.h>
#include <iostream>
#include "ccardiaccell.h "
#include <cvode.h /* prototypes for CVodeMalloc, CVode, and
CVodeFree, */
/* constants OPT_SIZE, BDF, NEWTON, SV, SUCCESS,
*/
/* NST, NFE, NSETUPS, NNI, NCFN, NETF
*/
#include <cvdense.h /* prototype for CVDense, constant DENSE_NJE
*/
#include <nvector.h /* definitions of type N_Vector and macro N_VIth,
*/
#include <nvector_serial .h /* definitions of type N_Vector and macro
N_VIth, */
/* prototypes for N_VNew, N_VFree
*/
#include <dense.h /* definitions of type DenseMat, macro DENSE_ELEM
*/
#include <vector>
using namespace std;
const int MAXSTATES = 16;
//Noble Cell Constants
class CDFNCell : public CCardiacCell {
private:
//double iteration;
double I_DFN;
//Membranne Potential
double Vm;
//stim current
double IStim;
void copy(const CDFNCell &);
void setDifferential ();
void setState();
public:
CDFNCell();
~CDFNCell();
void initialize();
void simulate(double Iext);
void calDiff(double, double[],bool);
void returnParameter List(vector<str ing>&);
void returnParamater Values(const vector<string>&
requestedParame ters, vector<double>& );
inline double returnVolt(){re turn (Vm);};
inline double returnNa_i(){re turn (Na_i);};
inline double returnCa_i(){re turn (Ca_i);}; //repeat
function for m n
h
inline double returnK_i(){ret urn (K_i);};
inline double returnK_o(){ret urn (K_c);};
//CVOde functions
void CVode_f(int N, double time, N_Vector y, N_Vector ydot,
void
*f_data);
void CVodeInit(doubl e[],double);
void CVodeExit(void) ;
void CVode_run(doubl e h,double states[]);
int statesize;
bool success;
double start_time;
bool notdone;
double tr_error,errtmp ;
double errweight[15];
double tolerance_relat ive,tolerance_a bsolute; // tolerances for
integrators
double tstep;
double step_min,step_m ax; // minimum and maximum step sizes for
integrators
//constants
int stateFlag; // Is state.txt written out
int currentFlag; // Is current.txt written out
int statederivsFlag ; // Is Deriv.txt written out
int stimulusFlag; // Is stimulus used or not
double y0[15];
double States[MAXSTATES];
double Diff[MAXSTATES];
};
extern CDFNCell *cellptr;
#endif