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
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
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;
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
00128
00129 concentrationFieldNameVectorTmp[i] = diffSecrFieldTuppleVec[i].diffData.fieldName;
00130 cerr<<" concentrationFieldNameVector[i]="<<concentrationFieldNameVectorTmp[i]<<endl;
00131 }
00132
00133
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;
00144 break;
00145 }
00146
00147 if( idx == concentrationFieldNameVectorTmp.size()-1 ){
00148
00149
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);
00172 }else{
00173 allocateDiffusableFieldVector(2*diffSecrFieldTuppleVec.size(),workFieldDim);
00174 }
00175
00176
00177
00178
00179
00180 for(unsigned int i=0 ; i < concentrationFieldNameVectorTmp.size() ; ++i){
00181 concentrationFieldNameVector[i]=concentrationFieldNameVectorTmp[i];
00182 }
00183
00184
00185
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
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
00249
00250
00251
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();
00265 }
00266
00267 }else{
00268 initializeConcentration();
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
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
00352 currentConcentration = concentrationArray[x][y][z];
00353
00354
00355 if(secreteInMedium && ! currentCellPtr){
00356
00357 for (int i = 0 ; i<=maxNeighborIndex ; ++i ){
00358 n=boundaryStrategy->getNeighborDirect(pt,i);
00359 if(!n.distance)
00360 continue;
00362 nCell = fieldG->get(n.pt);
00363
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()){
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; ++i ){
00392
00393 n=boundaryStrategy->getNeighborDirect(pt,i);
00394 if(!n.distance)
00395 continue;
00397 nCell = fieldG->get(n.pt);
00398
00399 if(nCell)
00400 type=nCell->type;
00401 else
00402 type=0;
00403
00404 if (currentCellPtr==nCell) continue;
00405
00406 mitrTypeConst=contactCellMapPtr->find(type);
00407 if(mitrTypeConst != contactCellMapPtr->end()){
00408 secrConst=mitrTypeConst->second;
00409
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
00451 mitr=secrData.typeIdSecrConstMap.find(automaton->getTypeId("Medium"));
00452
00453 if( mitr != end_mitr){
00454 secreteInMedium=true;
00455 secrConstMedium=mitr->second;
00456 }
00457
00458
00459 if(secrData.typeIdUptakeDataMap.size()){
00460 doUptakeFlag=true;
00461 }
00462
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
00481 currentCellPtr=cellFieldG->get(pt);
00482
00483
00484
00485
00486
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
00516 }else{
00517
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
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
00565 currentCellPtr=cellFieldG->get(pt);
00566
00567
00568
00569
00570
00571
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
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
00631 if(periodicBoundaryCheckVector[0]){
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{
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
00657 if(periodicBoundaryCheckVector[1]){
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{
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
00682 if(periodicBoundaryCheckVector[2]){
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{
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);
00768
00769 bool avoidMedium=false;
00770 bool avoidDecayInMedium=false;
00771
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
00801
00802
00803 pt=Point3D(x-1,y-1,z-1);
00805 currentCellPtr=cellFieldG->get(pt);
00806
00807
00808 currentConcentration = concentrationArray[x][y][z];
00809
00810
00811 if(avoidMedium && !currentCellPtr){
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;
00828 }
00829
00830 updatedConcentration=0.0;
00831 concentrationSum=0.0;
00832 neighborCounter=0;
00833
00834
00835 CellG *neighborCellPtr=0;
00836 const std::vector<Point3D> & offsetVecRef=boundaryStrategy->getOffsetVec(pt);
00837
00838 for (int i = 0 ; i<=maxNeighborIndex ; ++i ){
00839 const Point3D & offset = offsetVecRef[i];
00840
00841
00842 if(diffData.avoidTypeIdSet.size()||avoidMedium){
00843
00844 n=pt+offsetVecRef[i];
00845 neighborCellPtr=cellFieldG->get(n);
00846 if(avoidMedium && !neighborCellPtr) continue;
00847 if(neighborCellPtr && diffData.avoidTypeIdSet.find(neighborCellPtr->type)!=end_sitr) continue;
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
00863 if(currentCellPtr){
00864 if(diffData.avoidDecayInIdSet.find(currentCellPtr->type)!=end_sitr_decay){
00865 ;
00866 }else{
00867 updatedConcentration-=deltaT*(decayConst*currentConcentration);
00868 }
00869 }else{
00870 if(avoidDecayInMedium){
00871 ;
00872 }else{
00873 updatedConcentration-=deltaT*(decayConst*currentConcentration);
00874 }
00875 }
00876 if(haveCouplingTerms){
00877 updatedConcentration+=couplingTerm(pt,diffData.couplingDataVec,currentConcentration);
00878 }
00879
00880
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;
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){
00910 ConcentrationField_t * concentrationField=concentrationFieldVector[i];
00911 ConcentrationField_t * scratchField=concentrationFieldVector[diffSecrFieldTuppleVec.size()];
00912
00913 scrarch2Concentration(scratchField,concentrationField);
00914 }
00915
00916 }
00917
00918 if(haveCouplingTerms){
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 <