MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ZombieFunction.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2010 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include "ElementValueFinfo.h"
12 
13 #include "Variable.h"
14 #include "Function.h"
15 #include "ZombieFunction.h"
16 
17 #include "FuncTerm.h"
18 #include "RateTerm.h"
19 #include "SparseMatrix.h"
20 #include "KinSparseMatrix.h"
21 #include "VoxelPoolsBase.h"
22 #include "VoxelJunction.h"
23 #include "XferInfo.h"
24 #include "ZombiePoolInterface.h"
25 #include "Stoich.h"
26 
27 #define EPSILON 1e-15
28 
30 {
32  // Field Definitions: mostly inherited from Function
34 
36  // MsgDest Definitions: All inherited from Function
39  // SrcFinfo Definitions: All inherited from Function
42  // SharedMsg Definitions: Override Function
44  static DestFinfo process( "process",
45  "Handles process call, updates internal time stamp.",
47  static DestFinfo reinit( "reinit",
48  "Handles reinit call.",
50  static Finfo* processShared[] =
51  {
52  &process, &reinit
53  };
54 
55  static SharedFinfo proc( "proc",
56  "This is a shared message to receive Process messages "
57  "from the scheduler objects."
58  "The first entry in the shared msg is a MsgDest "
59  "for the Process operation. It has a single argument, "
60  "ProcInfo, which holds lots of information about current "
61  "time, thread, dt and so on. The second entry is a MsgDest "
62  "for the Reinit operation. It also uses ProcInfo. ",
63  processShared, sizeof( processShared ) / sizeof( Finfo* )
64  );
65 
66  // Note that here the isOneZombie_ flag on the Dinfo constructor is
67  // true. This means that the duplicate and copy operations only make
68  // one copy, regardless of how big the array of zombie pools.
69  // The assumption is that each Id has a single pool, which can be
70  // present in many voxels.
71  static Finfo *functionFinfos[] =
72  {
73  &proc,
74  };
75 
76  static string doc[] =
77  {
78  "Name", "ZombieFunction",
79  "Author", "Upi Bhalla",
80  "Description",
81  "ZombieFunction: Takes over Function, which is a general "
82  "purpose function calculator using real numbers."
83  };
84 
85  static Dinfo< ZombieFunction > dinfo;
86  static Cinfo zombieFunctionCinfo (
87  "ZombieFunction",
89  functionFinfos,
90  sizeof(functionFinfos) / sizeof(Finfo*),
91  &dinfo,
92  doc,
93  sizeof(doc)/sizeof(string)
94  );
95 
96  return &zombieFunctionCinfo;
97 }
98 
99 
100 
101 
103 // Class definitions
106 
108 {;}
109 
111 {;}
112 
114 // MsgDest Definitions
117 {
118  _t = p->currTime;
119 }
120 
122 {;}
123 
125 // Field Definitions
127 
128 void ZombieFunction::innerSetExpr( const Eref& e, string v )
129 {
130  Function::innerSetExpr( e, v );
131  if ( _stoich ) {
132  Stoich* s = reinterpret_cast< Stoich* >( _stoich );
133  s->setFunctionExpr( e, v );
134  } else {
135  // I had this warning here but it is triggered needlessly when we
136  // do an assignment of the Zombie function. So removed.
137  // cout << "Warning: ZombieFunction::setExpr: Stoich not set.\n";
138  }
139 }
140 
142 // Zombie conversion functions.
144 
145 void ZombieFunction::setSolver( Id ksolve, Id dsolve )
146 {
147  if ( ksolve.element()->cinfo()->isA( "Ksolve" ) ||
148  ksolve.element()->cinfo()->isA( "Gsolve" ) ) {
149  Id sid = Field< Id >::get( ksolve, "stoich" );
150  _stoich = ObjId( sid, 0 ).data();
151  if ( _stoich == 0 )
152  cout << "Warning:ZombieFunction::setSolver: Empty Stoich on Ksolve" << ksolve.path() << endl;
153  } else if ( ksolve == Id() ) {
154  _stoich = 0;
155  } else {
156  cout << "Warning:ZombieFunction::setSolver: solver class " <<
157  ksolve.element()->cinfo()->name() <<
158  " not known.\nShould be Ksolve or Gsolve\n";
159  _stoich = 0;
160  }
161 
162  /*
163  if ( dsolve.element()->cinfo()->isA( "Dsolve" ) ) {
164  dsolve_= ObjId( dsolve, 0 ).data();
165  } else if ( dsolve == Id() ) {
166  dsolve_ = 0;
167  } else {
168  cout << "Warning:ZombieFunction::vSetSolver: solver class " <<
169  dsolve.element()->cinfo()->name() <<
170  " not known.\nShould be Dsolve\n";
171  dsolve_ = 0;
172  }
173  */
174 }
175 
176 void ZombieFunction::zombify( Element* orig, const Cinfo* zClass,
177  Id ksolve, Id dsolve )
178 {
179  //cout << "ZombieFunction::zombify: " << orig->id().path() << endl;
180  if ( orig->cinfo() == zClass )
181  return;
182  // unsigned int start = orig->localDataStart();
183  unsigned int num = orig->numLocalData();
184  if ( num == 0 )
185  return;
186  if ( num > 1 )
187  cout << "ZombieFunction::zombify: Warning: ZombieFunction doesn't\n"
188  "handle volumes yet. Proceeding without this.\n";
189 
190  Function* f = reinterpret_cast< Function *>( Eref( orig, 0 ).data() );
191  Function temp = *f;
192  orig->zombieSwap( zClass );
193  if ( zClass == ZombieFunction::initCinfo() ) { // call SetSolver
194  ZombieFunction* zf = reinterpret_cast< ZombieFunction *>(
195  Eref( orig, 0 ).data() );
196  *zf = *static_cast< ZombieFunction* >(&temp);
197  zf->setSolver( ksolve, dsolve );
198  } else {
199  Function* nf =
200  reinterpret_cast< Function *>(Eref( orig, 0 ).data());
201  *nf = temp;
202  }
203 
204  /*
205  // We can swap the class because the class data is identical, just
206  // the moose expr and process handlers are different.
207  if ( orig->cinfo() == ZombieFunction::initCinfo() ) { // unzombify
208  orig->replaceCinfo( Function::initCinfo() );
209  } else { // zombify
210  orig->replaceCinfo( ZombieFunction::initCinfo() );
211  ZombieFunction* zf = reinterpret_cast< ZombieFunction *>(
212  Eref( orig, 0 ).data() );
213  zf->setSolver( ksolve, dsolve );
214  }
215  */
216 }
char * data() const
Definition: Eref.cpp:41
void process(const Eref &e, ProcPtr p)
virtual void innerSetExpr(const Eref &e, string expr)
Definition: Function.cpp:562
char * data() const
Definition: ObjId.cpp:113
char * _stoich
Definition: Function.h:160
Element * element() const
Synonym for Id::operator()()
Definition: Id.cpp:113
void setSolver(Id solver, Id orig)
double currTime
Definition: ProcInfo.h:19
std::string path(const std::string &separator="/") const
Definition: Id.cpp:76
static const Cinfo * initCinfo()
Definition: Dinfo.h:60
virtual void zombieSwap(const Cinfo *zCinfo)
virtual func, this base version must be called by all derived classes
Definition: Element.cpp:159
Definition: ObjId.h:20
void setFunctionExpr(const Eref &e, string expr)
Definition: Stoich.cpp:2028
Definition: Stoich.h:49
static const Cinfo * initCinfo()
Definition: Function.cpp:91
double _t
Definition: Function.h:142
const std::string & name() const
Definition: Cinfo.cpp:260
void innerSetExpr(const Eref &e, string val)
Definition: Eref.h:26
bool isA(const string &ancestor) const
Definition: Cinfo.cpp:280
const Cinfo * cinfo() const
Definition: Element.cpp:66
virtual unsigned int numLocalData() const =0
Returns number of local data entries on this node.
void reinit(const Eref &e, ProcPtr p)
static const Cinfo * zombieFunctionCinfo
Definition: Id.h:17
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
static void zombify(Element *orig, const Cinfo *zClass, Id ksolve, Id dsolve)
Definition: Cinfo.h:18
Definition: Finfo.h:12