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
00013 #include <CompuCell3D/plugins/NeighborTracker/NeighborTrackerPlugin.h>
00014
00015
00016
00017 #include <BasicUtils/BasicString.h>
00018 #include <BasicUtils/BasicException.h>
00019 #include <BasicUtils/BasicRandomNumberGenerator.h>
00020 #include <PublicUtilities/StringUtils.h>
00021 #include <string>
00022 #include <cmath>
00023 #include <iostream>
00024 #include <fstream>
00025
00026
00027
00028
00029 using namespace CompuCell3D;
00030 using namespace std;
00031 #define EXP_STL
00032 #include "AdvectionDiffusionSolverFE.h"
00033
00035 AdvectionDiffusionSolverFE::AdvectionDiffusionSolverFE()
00036 : DiffusableGraph<float>()
00037 {
00038 }
00040 AdvectionDiffusionSolverFE::~AdvectionDiffusionSolverFE()
00041 {
00042
00043 }
00045 void AdvectionDiffusionSolverFE::init(Simulator *simulator, CC3DXMLElement *_xmlData) {
00046
00047 simPtr=simulator;
00048 potts = simulator->getPotts();
00049 automaton=potts->getAutomaton();
00050
00051
00053 cellInventoryPtr=& potts->getCellInventory();
00054
00056 cellFieldG=(WatchableField3D<CellG *> *)potts->getCellFieldG();
00057 fieldDim=cellFieldG->getDim();
00058
00059 update(_xmlData,true);
00060
00061 NeighborTrackerPlugin * neighborTrackerPlugin=(NeighborTrackerPlugin*)(Simulator::pluginManager.get("NeighborTracker"));
00062 neighborTrackerAccessorPtr= neighborTrackerPlugin->getNeighborTrackerAccessorPtr();
00063
00065 diffusePtr=&AdvectionDiffusionSolverFE::diffuse;
00066 secretePtr=&AdvectionDiffusionSolverFE::secrete;
00067
00068
00069
00070 numberOfFields=diffSecrFieldTuppleVec.size();
00071
00073 workFieldDim=Dim3D(fieldDim.x+2,fieldDim.y+2,fieldDim.z+2);
00074
00075 allocateDiffusableFieldVector(diffSecrFieldTuppleVec.size()+1,workFieldDim);
00076
00077
00079 concentrationFieldNameVector.assign(diffSecrFieldTuppleVec.size(),string(""));
00080
00081
00082
00083 for(unsigned int i = 0 ; i < diffDataVec.size() ; ++i){
00084 concentrationFieldNameVector[i] = diffSecrFieldTuppleVec[i].diffData.fieldName;
00085
00086 }
00087
00088
00089 for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00090 simPtr->registerConcentrationField(concentrationFieldNameVector[i] , concentrationFieldVector[i]);
00091 cerr<<"registring field: "<<concentrationFieldNameVector[i]<<" field address="<<concentrationFieldVector[i]<<endl;
00092 }
00093
00094
00096
00097 for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i){
00098
00099 diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec.assign(diffSecrFieldTuppleVec[i].secrData.secrTypesNameSet.size(),0);
00100 unsigned int j=0;
00101 for(set<string>::iterator sitr=diffSecrFieldTuppleVec[i].secrData.secrTypesNameSet.begin() ; sitr != diffSecrFieldTuppleVec[i].secrData.secrTypesNameSet.end() ; ++sitr){
00102 if((*sitr)=="Secretion"){
00103 diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec[j]=&AdvectionDiffusionSolverFE::secreteSingleField;
00104 ++j;
00105 }
00106 else if((*sitr)=="SecretionOnContact"){
00107 diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec[j]=&AdvectionDiffusionSolverFE::secreteOnContactSingleField;
00108 ++j;
00109 }
00110 }
00111 }
00112
00113
00114 cerr<<"ALLOCATED ALL FIELDS"<<endl;
00115
00116
00117 }
00119 void AdvectionDiffusionSolverFE::extraInit(Simulator *simulator){
00120
00121
00122 }
00124 double AdvectionDiffusionSolverFE::computeAverageCellRadius(){
00125 double sumRadius=0.0;
00126 double radical=1.0/3.0;
00127 int numberOfCells=0;
00128 CellG *cell;
00129 CellInventory::cellInventoryIterator cInvItr;
00130
00131 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00132
00133 cell=*cInvItr;
00134 sumRadius+=pow(cell->volume,radical);
00135 ++numberOfCells;
00136
00137 }
00138
00139 return 1.33*sumRadius/numberOfCells;
00140
00141 }
00142
00144 void AdvectionDiffusionSolverFE::update(){
00145
00146 for(unsigned int i = 0 ; i <= diffDataVec.size() ; ++i ){
00147 updateLocalCellInventory(i);
00148 }
00149
00150 }
00151
00153 void AdvectionDiffusionSolverFE::updateLocalCellInventory(unsigned int idx){
00154
00155 CellG *cell;
00156 CellInventory::cellInventoryIterator cInvItr;
00157
00158 map<CellG*,float> * concentrationField=concentrationFieldMapVector[idx];
00159 map<CellG*,float>::iterator concentrationItr;
00160 map<CellG*,float>::iterator concentrationEndItr=concentrationField->end();
00161
00162
00163 for(concentrationItr = concentrationField->begin() ; concentrationItr != concentrationField->end() ; ){
00164 cInvItr=cellInventoryPtr->find(concentrationItr->first);
00165 if(cInvItr==cellInventoryPtr->cellInventoryEnd()){
00166 concentrationField->erase(concentrationItr++);
00167 }else{
00168 concentrationItr++;
00169 }
00170 }
00171
00172 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00173
00174 cell=*cInvItr;
00175 concentrationItr=concentrationField->find(cell);
00176 if(concentrationItr==concentrationEndItr){
00177 concentrationField->insert(make_pair(cell,0.0));
00178 }
00179
00180
00181 }
00182
00183
00184 }
00185
00186
00187
00189 void AdvectionDiffusionSolverFE::start() {
00190
00191 update();
00192 cerr<<"GOT HERE BEFORE INITIALIZE FIELD"<<endl;
00193 initializeConcentration();
00194
00195 cerr<<"GOT HERE AFTER INITIALIZE FIELD"<<endl;
00196 }
00197
00199
00200 void AdvectionDiffusionSolverFE::initializeConcentration(){
00201
00202
00203 for(unsigned int i = 0 ; i <diffDataVec.size() ; ++i){
00204 if(diffSecrFieldTuppleVec[i].diffData.concentrationFileName.empty()) continue;
00205
00206 readConcentrationField(diffSecrFieldTuppleVec[i].diffData.concentrationFileName,concentrationFieldVector[i]);
00207 field2CellMap(concentrationFieldVector[i] , concentrationFieldMapVector[i] );
00208 cellMap2Field(concentrationFieldMapVector[i] , concentrationFieldVector[i]);
00209 }
00210
00211
00212
00213
00214
00215 }
00217 void AdvectionDiffusionSolverFE::readConcentrationField(std::string fileName,ConcentrationField_t *concentrationField){
00218
00219 ifstream in(fileName.c_str());
00220
00221 ASSERT_OR_THROW(string("Could not open chemical concentration file '") +
00222 fileName + "'!", in.is_open());
00223
00224 Point3D pt;
00225 float c;
00226 while(!in.eof()){
00227 in>>pt.x>>pt.y>>pt.z>>c;
00228 if(!in.fail())
00229 concentrationField->set(pt,c);
00230 }
00231
00232 }
00233
00234
00236 void AdvectionDiffusionSolverFE::cellMap2Field(std::map<CellG *, float> *concentrationMapField , ConcentrationField_t *concentrationField){
00237
00238 CellG *currentCellPtr=0;
00239 Point3D pt;
00240 float currentConcentration;
00241 std::map<CellG *, float>::iterator mitr;
00242
00243 Array3D_t & concentrationArray = concentrationField->getContainer();
00244
00245 for (int z = 1; z < workFieldDim.z-1; z++)
00246 for (int y = 1; y < workFieldDim.y-1; y++)
00247 for (int x = 1; x < workFieldDim.x-1; x++){
00248 pt=Point3D(x-1,y-1,z-1);
00249 currentCellPtr=cellFieldG->get(pt);
00250
00251 mitr=concentrationMapField->find(currentCellPtr);
00252 if(mitr != concentrationMapField->end() ){
00253 currentConcentration = mitr->second;
00254
00255 }else{
00256 currentConcentration =0.0;
00257 }
00258 concentrationArray[x][y][z]=currentConcentration;
00259 }
00260
00261 }
00262
00263
00265 void AdvectionDiffusionSolverFE::field2CellMap(ConcentrationField_t *concentrationField , std::map<CellG *, float> *concentrationMapField ){
00266
00267 CellG *currentCellPtr=0;
00268 Point3D pt;
00269 float currentConcentration;
00270 Array3D_t & concentrationArray = concentrationField->getContainer();
00271
00272 std::map<CellG *, float>::iterator mitr;
00273
00274 for (int z = 1; z < workFieldDim.z-1; z++)
00275 for (int y = 1; y < workFieldDim.y-1; y++)
00276 for (int x = 1; x < workFieldDim.x-1; x++){
00277 pt=Point3D(x-1,y-1,z-1);
00278
00279 currentCellPtr=cellFieldG->get(pt);
00280
00281 mitr=concentrationMapField->find(currentCellPtr);
00282 currentConcentration=concentrationArray[x][y][z];
00283
00284
00285 if(mitr != concentrationMapField->end() ){
00286
00287 mitr->second=currentConcentration;
00288 }else{
00289
00290 }
00291
00292 }
00293
00294
00295
00296
00297 }
00298
00299
00301 void AdvectionDiffusionSolverFE::step(const unsigned int _currentStep) {
00302 currentStep=_currentStep;
00303 update();
00304 cellMap2Field(concentrationFieldMapVector[0] ,concentrationFieldVector[0] );
00305 (this->*secretePtr)();
00306 (this->*diffusePtr)();
00307
00308
00309 }
00311
00312
00314 void AdvectionDiffusionSolverFE::secreteSingleField(unsigned int idx){
00315
00316 SecretionDataFlexAD & secrData=diffSecrFieldTuppleVec[idx].secrData;
00317 map<CellG*,float> * concentrationField=concentrationFieldMapVector[idx];
00318 map<CellG*,float>::iterator concentrationItr;
00319 map<CellG*,float>::iterator concentrationEndItr=concentrationField->end();
00320
00321 std::map<unsigned char,float>::iterator mitr;
00322 std::map<unsigned char,float>::iterator end_mitr=secrData.typeIdSecrConstMap.end();
00323
00324 float currentConcentration;
00325 float secrConst;
00326
00327
00328
00329
00330 mitr=secrData.typeIdSecrConstMap.find(automaton->getTypeId("Medium"));
00331
00332
00333 CellG *cell;
00334 CellInventory::cellInventoryIterator cInvItr;
00335
00336 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00337
00338 cell=*cInvItr;
00339
00340 concentrationItr = concentrationField->find(cell);
00341
00342
00343
00344 mitr=secrData.typeIdSecrConstMap.find(cell->type);
00345 if(mitr!=end_mitr){
00346
00347 secrConst=mitr->second;
00348 currentConcentration=concentrationItr->second;
00349 concentrationItr->second=currentConcentration+secrConst;
00350
00351 }
00352
00353
00354 }
00355
00356
00357 }
00358
00360
00361 void AdvectionDiffusionSolverFE::secreteOnContactSingleField(unsigned int idx){
00362
00363 SecretionDataFlexAD & secrData=diffSecrFieldTuppleVec[idx].secrData;
00364 map<CellG*,float> * concentrationField=concentrationFieldMapVector[idx];
00365 map<CellG*,float>::iterator concentrationItr;
00366 map<CellG*,float>::iterator concentrationEndItr=concentrationField->end();
00367
00368 std::map<unsigned char,SecretionOnContactData>::iterator mitr;
00369 std::map<unsigned char,SecretionOnContactData>::iterator end_mitr=secrData.typeIdSecrOnContactDataMap.end();
00370 map<unsigned char, float> * contactCellMapPtr;
00371 std::map<unsigned char, float>::iterator mitrTypeConst;
00372
00373 set<NeighborSurfaceData>::iterator neighborItr;
00374 NeighborTracker * neighborTracker;
00375
00376
00377 float currentConcentration;
00378 float secrConst;
00379
00380
00381
00382 CellG *cell;
00383 CellG *nCellPtr;
00384
00385 CellInventory::cellInventoryIterator cInvItr;
00386
00387 for(cInvItr=cellInventoryPtr->cellInventoryBegin() ; cInvItr !=cellInventoryPtr->cellInventoryEnd() ;++cInvItr ){
00388
00389 cell=*cInvItr;
00390
00391 concentrationItr = concentrationField->find(cell);
00392
00393
00394 mitr=secrData.typeIdSecrOnContactDataMap.find(cell->type);
00395
00396
00397 if(mitr!=end_mitr){
00398 contactCellMapPtr = &(mitr->second.contactCellMap);
00399 neighborTracker = neighborTrackerAccessorPtr->get(cell->extraAttribPtr);
00400 for(
00401 neighborItr = neighborTracker->cellNeighbors.begin() ;
00402 neighborItr != neighborTracker->cellNeighbors.end() ;
00403 ++neighborItr
00404 ){
00405 nCellPtr = neighborItr->neighborAddress;
00406 if(!nCellPtr) continue;
00407
00408 mitrTypeConst=contactCellMapPtr->find(nCellPtr->type);
00409 if(mitrTypeConst != contactCellMapPtr->end()){
00410 secrConst = mitrTypeConst->second;
00411 currentConcentration=concentrationItr->second;
00412 concentrationItr->second=currentConcentration+secrConst;
00413 }
00414
00415
00416 }
00417
00418 }
00419
00420
00421 }
00422
00423
00424 }
00425
00427 void AdvectionDiffusionSolverFE::diffuseSingleField(unsigned int idx){
00428
00429 map<CellG*,float> * concentrationField=concentrationFieldMapVector[idx];
00430 map<CellG*,float>::iterator concentrationItr;
00431 map<CellG*,float>::iterator nConcentrationItr;
00432 map<CellG*,float>::iterator scratchConcentrationItr;
00433 map<CellG*,float>::iterator concentrationEndItr=concentrationField->end();
00434 map<CellG*,float> * scratchField=concentrationFieldMapVector[diffDataVec.size()];
00435
00436 set<unsigned char>::iterator sitr;
00437 set<unsigned char>::iterator end_sitr=diffDataVec[idx].avoidTypeIdSet.end();
00438
00439
00440 NeighborTracker * neighborTracker;
00441 set<NeighborSurfaceData>::iterator neighborItr;
00442
00443 DiffusionData & diffData = diffSecrFieldTuppleVec[idx].diffData;
00444 CellG * currentCellPtr;
00445 CellG * nCellPtr;
00446
00447 short currentCellType=0;
00448 float concentrationSum=0.0;
00449 float updatedConcentration=0.0;
00450
00451 float diffConst=diffData.diffConst;
00452 float decayConst=diffData.decayConst;
00453 float deltaT=diffData.deltaT;
00454 float dt_dx2=deltaT/( averageRadius*averageRadius );
00455
00456 float currentConcentration=0.0;
00457 short neighborCounter=0;
00458
00459 CellInventory::cellInventoryIterator cInvItr;
00460
00461 for(concentrationItr = concentrationField->begin() ; concentrationItr != concentrationField->end() ; ++ concentrationItr ){
00462
00463 currentCellPtr = concentrationItr->first;
00464 currentConcentration = concentrationItr->second;
00465
00466 scratchConcentrationItr = scratchField->find(currentCellPtr);
00467
00468 if(diffData.avoidTypeIdSet.find(currentCellPtr->type) != end_sitr){
00469 scratchConcentrationItr->second = currentConcentration;
00470 continue;
00471 }
00472
00473
00474
00475 concentrationSum=0.0;
00476 neighborCounter=0;
00477
00478
00479
00480 neighborTracker = neighborTrackerAccessorPtr->get(currentCellPtr->extraAttribPtr);
00481
00482 for(neighborItr = neighborTracker->cellNeighbors.begin() ; neighborItr != neighborTracker->cellNeighbors.end() ; ++neighborItr){
00483
00484 nCellPtr=neighborItr->neighborAddress;
00485
00486
00487 if(nCellPtr && diffData.avoidTypeIdSet.find(nCellPtr->type) != end_sitr){
00488 continue;
00489 }
00490
00491 nConcentrationItr=concentrationField->find(nCellPtr);
00492 if(nConcentrationItr != concentrationEndItr){
00493 concentrationSum += nConcentrationItr->second;
00494 ++neighborCounter;
00495 }
00496 }
00497 updatedConcentration = dt_dx2*diffConst*(concentrationSum - neighborCounter*currentConcentration)
00498 -deltaT*(decayConst*currentConcentration)
00499 +currentConcentration;
00500
00501 scratchConcentrationItr->second = updatedConcentration;
00502
00503 }
00504
00505 scrarch2Concentration(scratchField,concentrationField);
00506 cellMap2Field(concentrationField ,concentrationFieldVector[idx] );
00507
00508 }
00510 void AdvectionDiffusionSolverFE::scrarch2Concentration( map<CellG *, float> * scratchField , map<CellG *, float> *concentrationField){
00511
00512 map<CellG*,float>::iterator concentrationItr;
00513 map<CellG*,float>::iterator scratchConcentrationItr;
00514
00515 for(concentrationItr = concentrationField->begin() ; concentrationItr != concentrationField->end() ; ++ concentrationItr ){
00516 scratchConcentrationItr=scratchField->find(concentrationItr->first);
00517 concentrationItr->second = scratchConcentrationItr->second;
00518 scratchConcentrationItr->second=0.0;
00519 }
00520
00521 }
00522
00524 void AdvectionDiffusionSolverFE::diffuse() {
00525 averageRadius = computeAverageCellRadius();
00526 for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i ){
00527 diffuseSingleField(i);
00528 }
00529
00530
00531
00532 }
00533
00534
00535 void AdvectionDiffusionSolverFE::secrete() {
00536
00537
00538
00539 for(unsigned int i = 0 ; i < diffSecrFieldTuppleVec.size() ; ++i ){
00540 for(unsigned int j = 0 ; j <diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec.size() ; ++j){
00541 (this->*diffSecrFieldTuppleVec[i].secrData.secretionFcnPtrVec[j])(i);
00542 }
00543
00544 }
00545
00546
00547 }
00548
00549
00550 void AdvectionDiffusionSolverFE::update(CC3DXMLElement *_xmlData, bool _fullInitFlag){
00551
00552
00553
00554 diffSecrFieldTuppleVec.clear();
00555
00556 CC3DXMLElementList diffFieldXMLVec=_xmlData->getElements("DiffusionField");
00557 for(unsigned int i = 0 ; i < diffFieldXMLVec.size() ; ++i ){
00558 diffSecrFieldTuppleVec.push_back(DiffusionSecretionADFieldTupple());
00559 DiffusionData & diffData=diffSecrFieldTuppleVec[diffSecrFieldTuppleVec.size()-1].diffData;
00560 SecretionData & secrData=diffSecrFieldTuppleVec[diffSecrFieldTuppleVec.size()-1].secrData;
00561
00562 if(diffFieldXMLVec[i]->findElement("DiffusionData"))
00563 diffData.update(diffFieldXMLVec[i]->getFirstElement("DiffusionData"));
00564
00565 if(diffFieldXMLVec[i]->findElement("SecretionData"))
00566 secrData.update(diffFieldXMLVec[i]->getFirstElement("SecretionData"));
00567
00568
00569
00570 }
00571
00572
00573
00574
00575
00576
00577 }
00578
00579
00580 std::string AdvectionDiffusionSolverFE::toString(){
00581 return "AdvectionDiffusionSolverFE";
00582 }
00583
00584
00585 std::string AdvectionDiffusionSolverFE::steerableName(){
00586 return toString();
00587 }
00588
00589
00590