• Main Page
  • Namespaces
  • Classes
  • Files

CompuCell/DOXYGEN/core/CompuCell3D/steppables/PDESolvers/FlexibleDiffusionSolverFE.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include <CompuCell3D/Simulator.h>
00004 #include <CompuCell3D/Automaton/Automaton.h>
00005 #include <CompuCell3D/Potts3D/Potts3D.h>
00006 #include <CompuCell3D/Potts3D/CellInventory.h>
00007 #include <CompuCell3D/Field3D/WatchableField3D.h>
00008 #include <CompuCell3D/Field3D/Field3DImpl.h>
00009 #include <CompuCell3D/Field3D/Field3D.h>
00010 #include <CompuCell3D/Field3D/Field3DIO.h>
00011 #include <BasicUtils/BasicClassGroup.h>
00012 #include <CompuCell3D/steppables/BoxWatcher/BoxWatcher.h>
00013 
00014 #include <BasicUtils/BasicString.h>
00015 #include <BasicUtils/BasicException.h>
00016 #include <BasicUtils/BasicRandomNumberGenerator.h>
00017 #include <PublicUtilities/StringUtils.h>
00018 #include <string>
00019 #include <cmath>
00020 #include <iostream>
00021 #include <fstream>
00022 #include <sstream>
00023 
00025 // std::ostream & operator<<(std::ostream & out,CompuCell3D::DiffusionData & diffData){
00026 //
00027 //
00028 // }
00029 
00030 
00031 using namespace CompuCell3D;
00032 using namespace std;
00033 
00034 #define EXP_STL
00035 #include "FlexibleDiffusionSolverFE.h"
00036 
00038 void FlexibleDiffusionSolverSerializer::serialize(){
00039 
00040         for(int i = 0 ; i < solverPtr->diffSecrFieldTuppleVec.size() ; ++i){
00041                 ostringstream outName;
00042 
00043                 outName<<solverPtr->diffSecrFieldTuppleVec[i].diffData.fieldName<<"_"<<currentStep<<"."<<serializedFileExtension;
00044                 ofstream outStream(outName.str().c_str());
00045                 solverPtr->outputField( outStream,solverPtr->concentrationFieldVector[i]);
00046         }
00047 
00048 }
00049 
00051 void FlexibleDiffusionSolverSerializer::readFromFile(){
00052         try{
00053                 for(int i = 0 ; i < solverPtr->diffSecrFieldTuppleVec.size() ; ++i){
00054                         ostringstream inName;
00055                         inName<<solverPtr->diffSecrFieldTuppleVec[i].diffData.fieldName<<"."<<serializedFileExtension;
00056 
00057                         solverPtr->readConcentrationField(inName.str().c_str(),solverPtr->concentrationFieldVector[i]);;
00058                 }
00059 
00060         } catch (BasicException &e) {
00061                 cerr<<"COULD NOT FIND ONE OF THE FILES"<<endl;
00062                 throw BasicException("Error in reading diffusion fields from file",e);
00063         }
00064 
00065 
00066 }
00067 
00068 
00069 
00071 FlexibleDiffusionSolverFE::FlexibleDiffusionSolverFE()
00072 : DiffusableVector<float>(),deltaX(1.0),deltaT(1.0)
00073 {
00074         serializerPtr=0;
00075         serializeFlag=false;
00076         readFromFileFlag=false;
00077         haveCouplingTerms=false;
00078         serializeFrequency=0;
00079         boxWatcherSteppable=0;
00080 }
00082 FlexibleDiffusionSolverFE::~FlexibleDiffusionSolverFE()
00083 {
00084         if(serializerPtr)
00085                 delete serializerPtr ; serializerPtr=0;
00086 }
00088 void FlexibleDiffusionSolverFE::init(Simulator *_simulator, CC3DXMLElement *_xmlData) {
00089 
00090 
00091         simPtr=_simulator;
00092         simulator=_simulator;
00093         potts = _simulator->getPotts();
00094         automaton=potts->getAutomaton();
00095 
00097         cellInventoryPtr=& potts->getCellInventory();
00098 
00101         //   cellFieldG=potts->getCellFieldG();
00102         cellFieldG = (WatchableField3D<CellG *> *)potts->getCellFieldG();
00103         fieldDim=cellFieldG->getDim();
00104 
00105         cerr<<"INSIDE INIT"<<endl;
00106 
00107 
00108 
00110         diffusePtr=&FlexibleDiffusionSolverFE::diffuse;
00111         secretePtr=&FlexibleDiffusionSolverFE::secrete;
00112 
00113 
00114         update(_xmlData,true);
00115 
00116         numberOfFields=diffSecrFieldTuppleVec.size();
00117 
00118 
00119 
00120         vector<string> concentrationFieldNameVectorTmp; //temporary vector for field names
00122         concentrationFieldNameVectorTmp.assign(diffSecrFieldTuppleVec.size(),string(""));
00123 
00124         cerr<<"diffSecrFieldTuppleVec.size()="<<diffSecrFieldTuppleVec.size()<<endl;
00125 
00126         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00127                 //       cerr<<" concentrationFieldNameVector[i]="<<diffDataVec[i].fieldName<<endl;
00128                 //       concentrationFieldNameVector.push_back(diffDataVec[i].fieldName);
00129                 concentrationFieldNameVectorTmp[i] = diffSecrFieldTuppleVec[i].diffData.fieldName;
00130                 cerr<<" concentrationFieldNameVector[i]="<<concentrationFieldNameVectorTmp[i]<<endl;
00131         }
00132 
00133         //setting up couplingData - field-field interaction terms
00134         vector<CouplingData>::iterator pos;
00135 
00136         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00137                 pos=diffSecrFieldTuppleVec[i].diffData.couplingDataVec.begin();
00138                 for(int j = 0 ; j < diffSecrFieldTuppleVec[i].diffData.couplingDataVec.size() ; ++j){
00139 
00140                         for(int idx=0; idx<concentrationFieldNameVectorTmp.size() ; ++idx){
00141                                 if( concentrationFieldNameVectorTmp[idx] == diffSecrFieldTuppleVec[i].diffData.couplingDataVec[j].intrFieldName ){
00142                                         diffSecrFieldTuppleVec[i].diffData.couplingDataVec[j].fieldIdx=idx;
00143                                         haveCouplingTerms=true; //if this is called at list once we have already coupling terms and need to proceed differently with scratch field initialization
00144                                         break;
00145                                 }
00146                                 //this means that required interacting field name has not been found
00147                                 if( idx == concentrationFieldNameVectorTmp.size()-1 ){
00148                                         //remove this interacting term
00149                                         //                pos=&(diffDataVec[i].degradationDataVec[j]);
00150                                         diffSecrFieldTuppleVec[i].diffData.couplingDataVec.erase(pos);
00151                                 }
00152                         }
00153                         ++pos;
00154                 }
00155         }
00156 
00157 
00158         cerr<<"FIELDS THAT I HAVE"<<endl;
00159         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00160                 cerr<<"Field "<<i<<" name: "<<concentrationFieldNameVectorTmp[i]<<endl;
00161         }
00162 
00163 
00164 
00165 
00166         cerr<<"FlexibleDiffusionSolverFE: extra Init in read XML"<<endl;
00167 
00168         workFieldDim=Dim3D(fieldDim.x+2,fieldDim.y+2,fieldDim.z+2);
00170         if(!haveCouplingTerms){
00171                 allocateDiffusableFieldVector(diffSecrFieldTuppleVec.size()+1,workFieldDim); //+1 is for additional scratch field
00172         }else{
00173                 allocateDiffusableFieldVector(2*diffSecrFieldTuppleVec.size(),workFieldDim); //with coupling terms every field need to have its own scratch field
00174         }
00175 
00176         //here I need to copy field names from concentrationFieldNameVectorTmp to concentrationFieldNameVector
00177         //because concentrationFieldNameVector is reallocated with default values once I call allocateDiffusableFieldVector
00178 
00179 
00180         for(unsigned int i=0 ; i < concentrationFieldNameVectorTmp.size() ; ++i){
00181                 concentrationFieldNameVector[i]=concentrationFieldNameVectorTmp[i];
00182         }
00183 
00184 
00185         //register fields once they have been allocated
00186         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00187                 simPtr->registerConcentrationField(concentrationFieldNameVector[i] , concentrationFieldVector[i]);
00188                 cerr<<"registring field: "<<concentrationFieldNameVector[i]<<" field address="<<concentrationFieldVector[i]<<endl;
00189         }
00190 
00191 
00192 
00193 
00194 
00195         //    exit(0);
00196 
00197         periodicBoundaryCheckVector.assign(3,false);
00198         string boundaryName;
00199         boundaryName=potts->getBoundaryXName();
00200         changeToLower(boundaryName);
00201         if(boundaryName=="periodic")  {
00202                 periodicBoundaryCheckVector[0]=true;
00203         }
00204         boundaryName=potts->getBoundaryYName();
00205         changeToLower(boundaryName);
00206         if(boundaryName=="periodic")  {
00207                 periodicBoundaryCheckVector[1]=true;
00208         }
00209 
00210         boundaryName=potts->getBoundaryZName();
00211         changeToLower(boundaryName);
00212         if(boundaryName=="periodic")  {
00213                 periodicBoundaryCheckVector[2]=true;
00214         }
00215 
00216         simulator->registerSteerableObject(this);
00217 
00218 }
00220 void FlexibleDiffusionSolverFE::extraInit(Simulator *simulator){
00221 
00222         if((serializeFlag || readFromFileFlag) && !serializerPtr){
00223                 serializerPtr=new FlexibleDiffusionSolverSerializer();
00224                 serializerPtr->solverPtr=this;
00225         }
00226 
00227         if(serializeFlag){
00228                 simulator->registerSerializer(serializerPtr);
00229         }
00230 
00231         bool useBoxWatcher=false;
00232         for (int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00233                 if(diffSecrFieldTuppleVec[i].diffData.useBoxWatcher){
00234                         useBoxWatcher=true;
00235                         break;
00236                 }
00237         }
00238         bool steppableAlreadyRegisteredFlag;
00239         if(useBoxWatcher){
00240                 boxWatcherSteppable=(BoxWatcher*)Simulator::steppableManager.get("BoxWatcher",&steppableAlreadyRegisteredFlag);
00241                 if(!steppableAlreadyRegisteredFlag)
00242                         boxWatcherSteppable->init(simulator);
00243         }
00244 }
00245 
00247 void FlexibleDiffusionSolverFE::start() {
00248         //     if(diffConst> (1.0/6.0-0.05) ){ //hard coded condtion for stability of the solutions - assume dt=1 dx=dy=dz=1
00249         //
00250         //       cerr<<"CANNOT SOLVE DIFFUSION EQUATION: STABILITY PROBLEM - DIFFUSION CONSTANT TOO LARGE. EXITING..."<<endl;
00251         //       exit(0);
00252         //
00253         //    }
00254 
00255 
00256         dt_dx2=deltaT/(deltaX*deltaX);
00257         if(readFromFileFlag){
00258                 try{
00259 
00260                         serializerPtr->readFromFile();
00261 
00262                 } catch (BasicException &e){
00263                         cerr<<"Going to fail-safe initialization"<<endl;
00264                         initializeConcentration(); //if there was error, initialize using failsafe defaults
00265                 }
00266 
00267         }else{
00268                 initializeConcentration();//Normal reading from User specified files
00269         }
00270 
00271 }
00272 
00274 
00275 void FlexibleDiffusionSolverFE::initializeConcentration()
00276 {
00277         for(unsigned int i = 0 ; i <diffSecrFieldTuppleVec.size() ; ++i)
00278         {
00279                 if(diffSecrFieldTuppleVec[i].diffData.concentrationFileName.empty()) continue;
00280                 cerr << "fail-safe initialization " << diffSecrFieldTuppleVec[i].diffData.concentrationFileName << endl;
00281                 readConcentrationField(diffSecrFieldTuppleVec[i].diffData.concentrationFileName,concentrationFieldVector[i]);
00282         }
00283 
00284 
00285 }
00286 
00288 void FlexibleDiffusionSolverFE::step(const unsigned int _currentStep) {
00289 
00290         currentStep=_currentStep;
00291 
00292         (this->*secretePtr)();
00293 
00294         (this->*diffusePtr)();
00295 
00296 
00297         if(serializeFrequency>0 && serializeFlag && !(_currentStep % serializeFrequency)){
00298                 serializerPtr->setCurrentStep(currentStep);
00299                 serializerPtr->serialize();
00300         }
00301 
00302 }
00304 
00305 void FlexibleDiffusionSolverFE::secreteOnContactSingleField(unsigned int idx){
00306 
00307 
00308         SecretionData & secrData=diffSecrFieldTuppleVec[idx].secrData;
00309 
00310 
00311         std::map<unsigned char,SecretionOnContactData>::iterator mitr;
00312         std::map<unsigned char,SecretionOnContactData>::iterator end_mitr=secrData.typeIdSecrOnContactDataMap.end();
00313 
00314         CellG *currentCellPtr;
00315 
00316         ConcentrationField_t * concentrationFieldPtr=concentrationFieldVector[idx];
00317         Array3D_t & concentrationArray = concentrationFieldPtr->getContainer();
00318 
00319         float currentConcentration;
00320         float secrConst;
00321         float secrConstMedium=0.0;
00322         std::map<unsigned char, float> * contactCellMapMediumPtr;
00323         std::map<unsigned char, float> * contactCellMapPtr;
00324         std::map<unsigned char, float>::iterator mitrTypeConst;
00325 
00326         bool secreteInMedium=false;
00327         //the assumption is that medium has type ID 0
00328         mitr=secrData.typeIdSecrOnContactDataMap.find(automaton->getTypeId("Medium"));
00329 
00330         if( mitr != end_mitr ){
00331                 secreteInMedium=true;
00332                 contactCellMapMediumPtr = &(mitr->second.contactCellMap);
00333         }
00334 
00335 
00336 
00337         Point3D pt;
00338         Neighbor n;
00339         CellG *nCell=0;
00340         WatchableField3D<CellG *> *fieldG = (WatchableField3D<CellG *> *)potts->getCellFieldG();
00341         unsigned char type;
00342 
00343 
00344 
00345         for (int z = 1; z < workFieldDim.z-1; z++)
00346                 for (int y = 1; y < workFieldDim.y-1; y++)
00347                         for (int x = 1; x < workFieldDim.x-1; x++){
00348                                 pt=Point3D(x-1,y-1,z-1);
00350                                 currentCellPtr=cellFieldG->get(pt);
00351                                 //             currentCellPtr=cellFieldG->get(pt);
00352                                 currentConcentration = concentrationArray[x][y][z];
00353 
00354 
00355                                 if(secreteInMedium && ! currentCellPtr){
00356 
00357                                         for (int i = 0  ; i<=maxNeighborIndex/*offsetVec.size()*/ ; ++i ){
00358                                                 n=boundaryStrategy->getNeighborDirect(pt,i);
00359                                                 if(!n.distance)//not a valid neighbor
00360                                                         continue;
00362                                                 nCell = fieldG->get(n.pt);
00363                                                 //                      nCell = fieldG->get(n.pt);
00364                                                 if(nCell)
00365                                                         type=nCell->type;
00366                                                 else
00367                                                         type=0;
00368 
00369 
00370                                                 mitrTypeConst=contactCellMapMediumPtr->find(type);
00371 
00372                                                 if(mitrTypeConst != contactCellMapMediumPtr->end()){//OK to secrete, contact detected
00373                                                         secrConstMedium = mitrTypeConst->second;
00374 
00375                                                         concentrationArray[x][y][z]=currentConcentration+secrConstMedium;
00376                                                 }
00377 
00378 
00379 
00380                                         }
00381 
00382                                         continue;
00383                                 }
00384 
00385                                 if(currentCellPtr){
00386                                         mitr=secrData.typeIdSecrOnContactDataMap.find(currentCellPtr->type);
00387                                         if(mitr!=end_mitr){
00388 
00389                                                 contactCellMapPtr = &(mitr->second.contactCellMap);
00390 
00391                                                 for (int i = 0  ; i<=maxNeighborIndex/*offsetVec.size() */; ++i ){
00392 
00393                                                         n=boundaryStrategy->getNeighborDirect(pt,i);
00394                                                         if(!n.distance)//not a valid neighbor
00395                                                                 continue;
00397                                                         nCell = fieldG->get(n.pt);
00398                                                         //                      nCell = fieldG->get(n.pt);
00399                                                         if(nCell)
00400                                                                 type=nCell->type;
00401                                                         else
00402                                                                 type=0;
00403 
00404                                                         if (currentCellPtr==nCell) continue; //skip secretion in pixels belongin to the same cell
00405 
00406                                                         mitrTypeConst=contactCellMapPtr->find(type);
00407                                                         if(mitrTypeConst != contactCellMapPtr->end()){//OK to secrete, contact detected
00408                                                                 secrConst=mitrTypeConst->second;
00409                                                                 //                         concentrationField->set(pt,currentConcentration+secrConst);
00410                                                                 concentrationArray[x][y][z]=currentConcentration+secrConst;
00411                                                         }
00412 
00413                                                 }
00414 
00415 
00416                                         }
00417                                 }
00418                         }
00419 
00420 }
00421 
00423 void FlexibleDiffusionSolverFE::secreteSingleField(unsigned int idx){
00424 
00425 
00426         SecretionData & secrData=diffSecrFieldTuppleVec[idx].secrData;
00427 
00428 
00429         std::map<unsigned char,float>::iterator mitr;   
00430         std::map<unsigned char,float>::iterator end_mitr=secrData.typeIdSecrConstMap.end();
00431         std::map<unsigned char,UptakeData>::iterator mitrUptake;
00432         std::map<unsigned char,UptakeData>::iterator end_mitrUptake=secrData.typeIdUptakeDataMap.end();
00433 
00434 
00435 
00436         CellG *currentCellPtr;
00437         Field3DImpl<float> * concentrationField=concentrationFieldVector[idx];
00438         float currentConcentration;
00439         float secrConst;
00440         float secrConstMedium=0.0;
00441         float maxUptakeInMedium=0.0;
00442         float relativeUptakeRateInMedium=0.0;
00443 
00444         ConcentrationField_t * concentrationFieldPtr=concentrationFieldVector[idx];
00445         Array3D_t & concentrationArray = concentrationFieldPtr->getContainer();
00446 
00447         bool doUptakeFlag=false;
00448         bool uptakeInMediumFlag=false;
00449         bool secreteInMedium=false;
00450         //the assumption is that medium has type ID 0
00451         mitr=secrData.typeIdSecrConstMap.find(automaton->getTypeId("Medium"));
00452 
00453         if( mitr != end_mitr){
00454                 secreteInMedium=true;
00455                 secrConstMedium=mitr->second;
00456         }
00457 
00458         //uptake for medium setup
00459         if(secrData.typeIdUptakeDataMap.size()){
00460                 doUptakeFlag=true;
00461         }
00462         //uptake for medium setup
00463         if(doUptakeFlag){
00464                 mitrUptake=secrData.typeIdUptakeDataMap.find(automaton->getTypeId("Medium"));
00465                 if(mitrUptake != end_mitrUptake){
00466                         maxUptakeInMedium=mitrUptake->second.maxUptake;
00467                         relativeUptakeRateInMedium=mitrUptake->second.relativeUptakeRate;
00468                         uptakeInMediumFlag=true;
00469 
00470                 }
00471         }
00472 
00473         
00474         Point3D pt;
00475         for (int z = 1; z < workFieldDim.z-1; z++)
00476                 for (int y = 1; y < workFieldDim.y-1; y++)
00477                         for (int x = 1; x < workFieldDim.x-1; x++){
00478                                 pt=Point3D(x-1,y-1,z-1);
00479                                 //             cerr<<"pt="<<pt<<" is valid "<<cellFieldG->isValid(pt)<<endl;
00481                                 currentCellPtr=cellFieldG->get(pt);
00482                                 //             currentCellPtr=cellFieldG->get(pt);
00483                                 //             cerr<<"THIS IS PTR="<<currentCellPtr<<endl;
00484 
00485                                 //             if(currentCellPtr)
00486                                 //                cerr<<"This is id="<<currentCellPtr->id<<endl;
00487                                 currentConcentration = concentrationArray[x][y][z];
00488 
00489                                 if(secreteInMedium && ! currentCellPtr){
00490                                         concentrationArray[x][y][z]=currentConcentration+secrConstMedium;
00491                                 }
00492 
00493                                 if(currentCellPtr){
00494                                         mitr=secrData.typeIdSecrConstMap.find(currentCellPtr->type);
00495                                         if(mitr!=end_mitr){
00496                                                 secrConst=mitr->second;
00497                                                 concentrationArray[x][y][z]=currentConcentration+secrConst;
00498                                         }
00499                                 }
00500 
00501                                 if(doUptakeFlag){
00502                                         if(uptakeInMediumFlag && ! currentCellPtr){
00503                                                 if(currentConcentration>maxUptakeInMedium){
00504                                                         concentrationArray[x][y][z]-=maxUptakeInMedium; 
00505                                                 }else{
00506                                                         concentrationArray[x][y][z]-= currentConcentration*relativeUptakeRateInMedium;  
00507                                                 }
00508                                         }
00509                                         if(currentCellPtr){
00510                                                 
00511                                                 mitrUptake=secrData.typeIdUptakeDataMap.find(currentCellPtr->type);
00512                                                 if(mitrUptake!=end_mitrUptake){
00513                                                         if(currentConcentration > mitrUptake->second.maxUptake){
00514                                                                 concentrationArray[x][y][z]-=mitrUptake->second.maxUptake;
00515                                                                 //cerr<<" uptake concentration="<< currentConcentration<<" relativeUptakeRate="<<mitrUptake->second.relativeUptakeRate<<" subtract="<<mitrUptake->second.maxUptake<<endl;
00516                                                         }else{
00517                                                                 //cerr<<"concentration="<< currentConcentration<<" relativeUptakeRate="<<mitrUptake->second.relativeUptakeRate<<" subtract="<<currentConcentration*mitrUptake->second.relativeUptakeRate<<endl;
00518                                                                 concentrationArray[x][y][z]-= currentConcentration*mitrUptake->second.relativeUptakeRate;       
00519                                                         }
00520                                                 }
00521                                         }
00522                                 }
00523                         }
00524 
00525 
00526 }
00527 
00528 
00530 void FlexibleDiffusionSolverFE::secreteConstantConcentrationSingleField(unsigned int idx){
00531 
00532 
00533         SecretionData & secrData=diffSecrFieldTuppleVec[idx].secrData;
00534 
00535 
00536         std::map<unsigned char,float>::iterator mitr;
00537         std::map<unsigned char,float>::iterator end_mitr=secrData.typeIdSecrConstMap.end();
00538 
00539         CellG *currentCellPtr;
00540         Field3DImpl<float> * concentrationField=concentrationFieldVector[idx];
00541         float currentConcentration;
00542         float secrConst;
00543         float secrConstMedium=0.0;
00544 
00545         ConcentrationField_t * concentrationFieldPtr=concentrationFieldVector[idx];
00546         Array3D_t & concentrationArray = concentrationFieldPtr->getContainer();
00547 
00548 
00549         bool secreteInMedium=false;
00550         //the assumption is that medium has type ID 0
00551         mitr=secrData.typeIdSecrConstMap.find(automaton->getTypeId("Medium"));
00552 
00553         if( mitr != end_mitr){
00554                 secreteInMedium=true;
00555                 secrConstMedium=mitr->second;
00556         }
00557 
00558         Point3D pt;
00559         for (int z = 1; z < workFieldDim.z-1; z++)
00560                 for (int y = 1; y < workFieldDim.y-1; y++)
00561                         for (int x = 1; x < workFieldDim.x-1; x++){
00562                                 pt=Point3D(x-1,y-1,z-1);
00563                                 //             cerr<<"pt="<<pt<<" is valid "<<cellFieldG->isValid(pt)<<endl;
00565                                 currentCellPtr=cellFieldG->get(pt);
00566                                 //             currentCellPtr=cellFieldG->get(pt);
00567                                 //             cerr<<"THIS IS PTR="<<currentCellPtr<<endl;
00568 
00569                                 //             if(currentCellPtr)
00570                                 //                cerr<<"This is id="<<currentCellPtr->id<<endl;
00571                                 //currentConcentration = concentrationArray[x][y][z];
00572 
00573                                 if(secreteInMedium && ! currentCellPtr){
00574                                         concentrationArray[x][y][z]=secrConstMedium;
00575                                 }
00576 
00577                                 if(currentCellPtr){
00578                                         mitr=secrData.typeIdSecrConstMap.find(currentCellPtr->type);
00579                                         if(mitr!=end_mitr){
00580                                                 secrConst=mitr->second;
00581                                                 concentrationArray[x][y][z]=secrConst;
00582                                         }
00583                                 }
00584                         }
00585 
00586 
00587 }
00588 
00589 
00590 
00592 void FlexibleDiffusionSolverFE::secrete() {
00593 
00594         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i ){
00595 
00596                 for(unsigned int j = 0 ; j <diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec.size() ; ++j){
00597                         (this->*diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec[j])(i);
00598 
00599                         //          (this->*secrDataVec[i].secretionFcnPtrVec[j])(i);
00600                 }
00601 
00602 
00603         }
00604 
00605 
00606 
00607 }
00608 
00609 
00610 
00612 float FlexibleDiffusionSolverFE::couplingTerm(Point3D & _pt,std::vector<CouplingData> & _couplDataVec,float _currentConcentration){
00613 
00614         float couplingTerm=0.0;
00615         float coupledConcentration;
00616         for(int i =  0 ; i < _couplDataVec.size() ; ++i){
00617                 coupledConcentration=concentrationFieldVector[_couplDataVec[i].fieldIdx]->get(_pt);
00618                 couplingTerm+=_couplDataVec[i].couplingCoef*_currentConcentration*coupledConcentration;
00619         }
00620 
00621         return couplingTerm;
00622 
00623 
00624 
00625 }
00627 void FlexibleDiffusionSolverFE::boundaryConditionInit(ConcentrationField_t *concentrationField){
00628         Array3D_t & concentrationArray=concentrationField->getContainer();
00629 
00630         //dealing with periodic boundary condition in x direction
00631         if(periodicBoundaryCheckVector[0]){//periodic boundary conditions were set in x direction
00632                 int x=0;
00633                 for(int y=0 ; y<workFieldDim.y ; ++y)
00634                         for(int z=0 ; z<workFieldDim.z ; ++z){
00635                                 concentrationArray[x][y][z]=concentrationArray[workFieldDim.x-2][y][z];
00636                         }
00637                         x=workFieldDim.x-1;
00638                         for(int y=0 ; y<workFieldDim.y ; ++y)
00639                                 for(int z=0 ; z<workFieldDim.z ; ++z){
00640                                         concentrationArray[x][y][z]=concentrationArray[1][y][z];
00641                                 }
00642         }else{//noFlux BC
00643                 int x=0;
00644                 for(int y=0 ; y<workFieldDim.y ; ++y)
00645                         for(int z=0 ; z<workFieldDim.z ; ++z){
00646                                 concentrationArray[x][y][z]=concentrationArray[x+1][y][z];
00647                         }
00648                         x=workFieldDim.x-1;
00649                         for(int y=0 ; y<workFieldDim.y ; ++y)
00650                                 for(int z=0 ; z<workFieldDim.z ; ++z){
00651                                         concentrationArray[x][y][z]=concentrationArray[x-1][y][z];
00652                                 }
00653 
00654         }
00655 
00656         //dealing with periodic boundary condition in y direction
00657         if(periodicBoundaryCheckVector[1]){//periodic boundary conditions were set in x direction
00658                 int y=0;
00659                 for(int x=0 ; x<workFieldDim.x ; ++x)
00660                         for(int z=0 ; z<workFieldDim.z ; ++z){
00661                                 concentrationArray[x][y][z]=concentrationArray[x][workFieldDim.y-2][z];
00662                         }
00663                         y=workFieldDim.y-1;
00664                         for(int x=0 ; x<workFieldDim.x ; ++x)
00665                                 for(int z=0 ; z<workFieldDim.z ; ++z){
00666                                         concentrationArray[x][y][z]=concentrationArray[x][1][z];
00667                                 }
00668         }else{//NoFlux BC
00669                 int y=0;
00670                 for(int x=0 ; x<workFieldDim.x ; ++x)
00671                         for(int z=0 ; z<workFieldDim.z ; ++z){
00672                                 concentrationArray[x][y][z]=concentrationArray[x][y+1][z];
00673                         }
00674                         y=workFieldDim.y-1;
00675                         for(int x=0 ; x<workFieldDim.x ; ++x)
00676                                 for(int z=0 ; z<workFieldDim.z ; ++z){
00677                                         concentrationArray[x][y][z]=concentrationArray[x][y-1][z];
00678                                 }
00679         }
00680 
00681         //dealing with periodic boundary condition in z direction
00682         if(periodicBoundaryCheckVector[2]){//periodic boundary conditions were set in x direction
00683                 int z=0;
00684                 for(int x=0 ; x<workFieldDim.x ; ++x)
00685                         for(int y=0 ; y<workFieldDim.y ; ++y){
00686                                 concentrationArray[x][y][z]=concentrationArray[x][y][workFieldDim.z-2];
00687                         }
00688                         z=workFieldDim.z-1;
00689                         for(int x=0 ; x<workFieldDim.x ; ++x)
00690                                 for(int y=0 ; y<workFieldDim.y ; ++y){
00691                                         concentrationArray[x][y][z]=concentrationArray[x][y][1];
00692                                 }
00693         }else{//Noflux BC
00694                 int z=0;
00695                 for(int x=0 ; x<workFieldDim.x ; ++x)
00696                         for(int y=0 ; y<workFieldDim.y ; ++y){
00697                                 concentrationArray[x][y][z]=concentrationArray[x][y][z+1];
00698                         }
00699                         z=workFieldDim.z-1;
00700                         for(int x=0 ; x<workFieldDim.x ; ++x)
00701                                 for(int y=0 ; y<workFieldDim.y ; ++y){
00702                                         concentrationArray[x][y][z]=concentrationArray[x][y][z-1];
00703                                 }
00704 
00705         }
00706 
00707 
00708 
00709 
00710 }
00711 
00713 
00714 void FlexibleDiffusionSolverFE::diffuseSingleField(unsigned int idx){
00715 
00717 
00721 
00726 
00727 
00728         Point3D pt, n;
00729         unsigned int token = 0;
00730         double distance;
00731         CellG * currentCellPtr=0,*nCell=0;
00732 
00733         short currentCellType=0;
00734         float concentrationSum=0.0;
00735         float updatedConcentration=0.0;
00736 
00737 
00738         float currentConcentration=0.0;
00739         short neighborCounter=0;
00740 
00741         DiffusionData & diffData = diffSecrFieldTuppleVec[idx].diffData;
00742         float diffConst=diffData.diffConst;
00743         float decayConst=diffData.decayConst;
00744         float deltaT=diffData.deltaT;
00745         float deltaX=diffData.deltaX;
00746         float dt_dx2=deltaT/(deltaX*deltaX);
00747 
00748 
00749 
00750         std::set<unsigned char>::iterator sitr;
00751         std::set<unsigned char>::iterator end_sitr=diffData.avoidTypeIdSet.end();
00752         std::set<unsigned char>::iterator end_sitr_decay=diffData.avoidDecayInIdSet.end();
00753 
00754         Automaton *automaton=potts->getAutomaton();
00755 
00756         ConcentrationField_t * concentrationFieldPtr=concentrationFieldVector[idx];
00757         ConcentrationField_t * scratchFieldPtr;
00758 
00759         if(!haveCouplingTerms)
00760                 scratchFieldPtr=concentrationFieldVector[diffSecrFieldTuppleVec.size()];
00761         else
00762                 scratchFieldPtr=concentrationFieldVector[diffSecrFieldTuppleVec.size()+idx];
00763 
00764         Array3D_t & concentrationArray = concentrationFieldPtr->getContainer();
00765         Array3D_t & scratchArray = scratchFieldPtr->getContainer();
00766 
00767         boundaryConditionInit(concentrationFieldPtr);//initializing boundary conditions
00768 
00769         bool avoidMedium=false;
00770         bool avoidDecayInMedium=false;
00771         //the assumption is that medium has type ID 0
00772         if(diffData.avoidTypeIdSet.find(automaton->getTypeId("Medium")) != end_sitr){
00773                 avoidMedium=true;
00774         }
00775 
00776         if(diffData.avoidDecayInIdSet.find(automaton->getTypeId("Medium")) != end_sitr_decay){
00777                 avoidDecayInMedium=true;
00778         }
00779 
00780         unsigned x_min=1,x_max=workFieldDim.x-1;
00781         unsigned y_min=1,y_max=workFieldDim.y-1;
00782         unsigned z_min=1,z_max=workFieldDim.z-1;
00783 
00784         if(diffData.useBoxWatcher){
00785                 Point3D minCoordinates=*(boxWatcherSteppable->getMinCoordinatesPtr());
00786                 Point3D maxCoordinates=*(boxWatcherSteppable->getMaxCoordinatesPtr());
00787                 cerr<<"FLEXIBLE DIFF SOLVER maxCoordinates="<<maxCoordinates<<" minCoordinates="<<minCoordinates<<endl;
00788                 x_min=minCoordinates.x+1;
00789                 x_max=maxCoordinates.x+1;
00790                 y_min=minCoordinates.y+1;
00791                 y_max=maxCoordinates.y+1;
00792                 z_min=minCoordinates.z+1;
00793                 z_max=maxCoordinates.z+1;
00794         }
00795         cerr<<"x_min="<<x_min<<" x_max="<<x_max<<"y_min="<<y_min<<" y_max="<<y_max<<"z_min="<<z_min<<" z_max="<<z_max<<endl;
00796 
00797         for (int z = z_min; z < z_max; z++)
00798                 for (int y = y_min; y < y_max; y++)
00799                         for (int x = x_min; x < x_max; x++){
00800                                 //for (int z = 1; z < workFieldDim.z-1; z++)
00801                                 // for (int y = 1; y < workFieldDim.y-1; y++)
00802                                 //   for (int x = 1; x < workFieldDim.x-1; x++){
00803                                 pt=Point3D(x-1,y-1,z-1);
00805                                 currentCellPtr=cellFieldG->get(pt);
00806                                 //          currentCellPtr=cellFieldG->get(pt);
00807 
00808                                 currentConcentration = concentrationArray[x][y][z];
00809 
00810 
00811                                 if(avoidMedium && !currentCellPtr){//if medium is to be avoided
00812                                         if(avoidDecayInMedium){
00813                                                 scratchArray[x][y][z]=currentConcentration;
00814                                         }
00815                                         else{
00816                                                 scratchArray[x][y][z]=currentConcentration-deltaT*(decayConst*currentConcentration);
00817                                         }
00818                                         continue;
00819                                 }
00820 
00821                                 if(currentCellPtr && diffData.avoidTypeIdSet.find(currentCellPtr->type)!=end_sitr){
00822                                         if(diffData.avoidDecayInIdSet.find(currentCellPtr->type)!=end_sitr_decay){
00823                                                 scratchArray[x][y][z]=currentConcentration;
00824                                         }else{
00825                                                 scratchArray[x][y][z]=currentConcentration-deltaT*(decayConst*currentConcentration);
00826                                         }
00827                                         continue; // avoid user defined types
00828                                 }
00829 
00830                                 updatedConcentration=0.0;
00831                                 concentrationSum=0.0;
00832                                 neighborCounter=0;
00833 
00834                                 //loop over nearest neighbors
00835                                 CellG *neighborCellPtr=0;
00836                                 const std::vector<Point3D> & offsetVecRef=boundaryStrategy->getOffsetVec(pt);
00837                                 //          cerr<<"maxNeighborIndex="<<maxNeighborIndex<<endl;
00838                                 for (int i = 0  ; i<=maxNeighborIndex /*offsetVec.size()*/ ; ++i ){ 
00839                                         const Point3D & offset = offsetVecRef[i];
00840 
00841 
00842                                         if(diffData.avoidTypeIdSet.size()||avoidMedium){ //means user defined types to avoid in terms of the diffusion
00843 
00844                                                 n=pt+offsetVecRef[i];
00845                                                 neighborCellPtr=cellFieldG->get(n);
00846                                                 if(avoidMedium && !neighborCellPtr) continue; // avoid medium if specified by the user
00847                                                 if(neighborCellPtr && diffData.avoidTypeIdSet.find(neighborCellPtr->type)!=end_sitr) continue;//avoid user specified types
00848                                         }
00849                                         concentrationSum += concentrationArray[x+offset.x][y+offset.y][z+offset.z];
00850 
00851                                         ++neighborCounter;
00852 
00853                                 }
00854 
00855 
00856                                 updatedConcentration =  dt_dx2*diffConst*(concentrationSum - neighborCounter*currentConcentration)+currentConcentration;
00857 
00858 
00859 
00860 
00861 
00862                                 //processing decay depandent on type of the current cell
00863                                 if(currentCellPtr){
00864                                         if(diffData.avoidDecayInIdSet.find(currentCellPtr->type)!=end_sitr_decay){
00865                                                 ;//decay in this type is forbidden
00866                                         }else{
00867                                                 updatedConcentration-=deltaT*(decayConst*currentConcentration);//decay in this type is allowed
00868                                         }
00869                                 }else{
00870                                         if(avoidDecayInMedium){
00871                                                 ;//decay in Medium is forbidden
00872                                         }else{
00873                                                 updatedConcentration-=deltaT*(decayConst*currentConcentration); //decay in Medium is allowed
00874                                         }
00875                                 }
00876                                 if(haveCouplingTerms){
00877                                         updatedConcentration+=couplingTerm(pt,diffData.couplingDataVec,currentConcentration);
00878                                 }
00879 
00880                                 //imposing artificial limits on allowed concentration
00881                                 if(diffData.useThresholds){
00882                                         if(updatedConcentration>diffData.maxConcentration){
00883                                                 updatedConcentration=diffData.maxConcentration;
00884                                         }
00885                                         if(updatedConcentration<diffData.minConcentration){
00886                                                 updatedConcentration=diffData.minConcentration;
00887                                         }
00888                                 }
00889 
00890                                 scratchArray[x][y][z]=updatedConcentration;//updating scratch
00891                         }
00892 
00893 }
00894 
00896 bool FlexibleDiffusionSolverFE::isBoudaryRegion(int x, int y, int z, Dim3D dim)
00897 {
00898         if (x < 2 || x > dim.x - 3 || y < 2 || y > dim.y - 3 || z < 2 || z > dim.z - 3 )
00899                 return true;
00900         else
00901                 return false;
00902 }
00903 
00905 void FlexibleDiffusionSolverFE::diffuse() {
00906 
00907         for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i ){
00908                 diffuseSingleField(i);
00909                 if(!haveCouplingTerms){ //without coupling terms field swap takes place immediately aftera given field has been diffused
00910                         ConcentrationField_t * concentrationField=concentrationFieldVector[i];
00911                         ConcentrationField_t * scratchField=concentrationFieldVector[diffSecrFieldTuppleVec.size()];
00912                         //copy updated values from scratch to concentration fiel
00913                         scrarch2Concentration(scratchField,concentrationField);
00914                 }
00915 
00916         }
00917 
00918         if(haveCouplingTerms){  //with coupling terms we swap scratch and concentration field after all fields have been diffused
00919                 for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i ){
00920                         ConcentrationField_t * concentrationField=concentrationFieldVector[i];
00921                         ConcentrationField_t * scratchField=concentrationFieldVector[diffSecrFieldTuppleVec.size()+i];
00922                         scrarch2Concentration(scratchField,concentrationField);
00923 
00924                 }
00925 
00926         }
00927 
00928 
00929 }
00931 void FlexibleDiffusionSolverFE::scrarch2Concentration( ConcentrationField_t *scratchField, ConcentrationField_t *concentrationField){
00932         scratchField->switchContainersQuick(*(concentrationField));
00933 
00934 }
00935 
00937 void FlexibleDiffusionSolverFE::outputField( std::ostream & _out, ConcentrationField_t *_concentrationField){
00938         Point3D pt;
00939         float tempValue;
00940 
00941         for (pt.z = 0; pt.z <