• Main Page
  • Namespaces
  • Classes
  • Files

CompuCell/DOXYGEN/core/CompuCell3D/Potts3D/Potts3D.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *    CompuCell - A software framework for multimodel simulations of     *
00003 * biocomplexity problems Copyright (C) 2003 University of Notre Dame,   *
00004 *                             Indiana                                   *
00005 *                                                                       *
00006 * This program is free software; IF YOU AGREE TO CITE USE OF CompuCell  *
00007 *  IN ALL RELATED RESEARCH PUBLICATIONS according to the terms of the   *
00008 *  CompuCell GNU General Public License RIDER you can redistribute it   *
00009 * and/or modify it under the terms of the GNU General Public License as *
00010 *  published by the Free Software Foundation; either version 2 of the   *
00011 *         License, or (at your option) any later version.               *
00012 *                                                                       *
00013 * This program is distributed in the hope that it will be useful, but `  *
00014 *      WITHOUT ANY WARRANTY; without even the implied warranty of       *
00015 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
00016 *             General Public License for more details.                  *
00017 *                                                                       *
00018 *  You should have received a copy of the GNU General Public License    *
00019 *     along with this program; if not, write to the Free Software       *
00020 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        *
00021 *************************************************************************/
00022 
00023 
00024 #include "Cell.h"
00025 #include "CellTypeMotilityData.h"
00026 #include "DefaultAcceptanceFunction.h"
00027 #include "AcceptanceFunction.h"
00028 #include "EnergyFunction.h"
00029 #include "CellGChangeWatcher.h"
00030 #include "Stepper.h"
00031 #include "FixedStepper.h"
00032 #include "AttributeAdder.h"
00033 #include <CompuCell3D/Automaton/Automaton.h>
00034 
00035 #include <CompuCell3D/Field3D/WatchableField3D.h>
00036 
00037 #include <CompuCell3D/Potts3D/TypeTransition.h>
00038 #include "EnergyFunctionCalculator.h"
00039 #include "EnergyFunctionCalculatorStatistics.h"
00040 
00041 #include <CompuCell3D/Simulator.h>
00042 //#include <CompuCell3D/plugins/Volume/VolumePlugin.h>
00043 //#include <CompuCell3D/plugins/Surface/SurfacePlugin.h>
00044 
00045 #include <BasicUtils/BasicRandomNumberGenerator.h>
00046 #include <BasicUtils/BasicPluginInfo.h>
00047 
00048 
00049 #include <PublicUtilities/StringUtils.h>
00050 #include <sstream>
00051 
00052 #define EXP_STL
00053 #include "Potts3D.h"
00054 
00055 using namespace CompuCell3D;
00056 using namespace std;
00057 
00058 Potts3D::Potts3D() :
00059 cellFieldG(0),
00060 attrAdder(0),
00061 acceptanceFunction(&defaultAcceptanceFunction), 
00062 energy(0),
00063 depth(1.0),
00064 recentlyCreatedCellId(1),
00065 debugOutputFrequency(1),
00066 sim(0),
00067 automaton(0)
00068 {
00069         neighbors.assign(100,Point3D());//statically allocated this buffer maybe will come with something better later
00070         frozenTypeVec.assign(0,0);
00071         energyCalculator = new EnergyFunctionCalculator();
00072         energyCalculator->setPotts(this);
00073         typeTransition=new TypeTransition();
00074         metropolisFcnPtr=&Potts3D::metropolisFast;
00075         cellInventory.setPotts3DPtr(this);
00076 }
00077 
00078 Potts3D::Potts3D(const Dim3D dim) :
00079 cellFieldG(0),
00080 attrAdder(0),
00081 acceptanceFunction(&defaultAcceptanceFunction), 
00082 energy(0) ,
00083 depth(1.0),
00084 recentlyCreatedCellId(1),
00085 debugOutputFrequency(1),
00086 sim(0),
00087 automaton(0)
00088 {
00089         neighbors.assign(100,Point3D());//statically allocated this buffer maybe will come with something better later
00090         frozenTypeVec.assign(0,0);
00091 
00092         createCellField(dim);
00093         energyCalculator = new EnergyFunctionCalculator();
00094         energyCalculator->setPotts(this); 
00095         typeTransition=new TypeTransition();
00096         metropolisFcnPtr=&Potts3D::metropolisFast;
00097         cellInventory.setPotts3DPtr(this);
00098 
00099 }
00100 
00101 
00102 Potts3D::~Potts3D() {
00103         if (cellFieldG) delete cellFieldG;
00104         if (energyCalculator) delete energyCalculator; energyCalculator=0;
00105         if (typeTransition) delete typeTransition; typeTransition=0;
00106         //   if (attrAdder) delete attrAdder; attrAdder=0;
00107 }
00108 
00109 void Potts3D::createEnergyFunction(std::string _energyFunctionType){
00110         if(_energyFunctionType=="Statistics"){
00111                 if (energyCalculator) delete energyCalculator; energyCalculator=0;
00112                 energyCalculator=new EnergyFunctionCalculatorStatistics();
00113                 energyCalculator->setPotts(this);
00114                 //initialize Statistics Output Energy Finction Here
00115                 return;
00116         }
00117         else{
00118                 //default is not to reassign energy finction calculator
00119                 return;
00120         }
00121 }
00122 
00123 LatticeType Potts3D::getLatticeType(){
00124         return BoundaryStrategy::getInstance()->getLatticeType();
00125 }
00126 
00127 void Potts3D::setDepth(double _depth){
00128         //this function has to be called after initializing bondary strategy and after creating cellFieldG
00129         //By default Boundary Strategy will precalculate neighbors up to certain depth (4.0). However if user requests more
00130         //depth additional calculations will be requested here
00131         depth=_depth;
00132         float maxDistance=BoundaryStrategy::getInstance()->getMaxDistance();
00133         if(maxDistance<depth){
00134                 //in such situation user requests depth that is greater than default maxDistance 
00135                 BoundaryStrategy::getInstance()->prepareNeighborLists(depth);
00136         }
00137         Dim3D dim=cellFieldG->getDim();
00138         minCoordinates=Point3D(0,0,0);
00139         maxCoordinates=Point3D(dim.x,dim.y,dim.z);
00140 
00141         //will calculate necesary space for neighbor storage
00142         //this may not work for lattice types other than square
00143 
00144         //   Dim3D dim=cellFieldG->getDim();
00145         // 
00146         //   minCoordinates=Point3D(0,0,0);
00147         //   maxCoordinates=Point3D(dim.x,dim.y,dim.z);
00148         // 
00149         // 
00150         //   Point3D middlePt(dim.x/2,dim.y/2,dim.z/2);
00151         //   
00152         //    unsigned int token = 0;
00153         //    int numNeighbors = 0;
00154         //    double distance;
00155         //    Point3D testPt;
00156         //    token =0;
00157         //    distance=0;
00158         //    
00159         //    
00160         //       while(true){
00161         //       testPt = cellFieldG->getNeighbor(middlePt, token, distance);
00162         //       if (distance > depth) break;
00163         //    
00164         //          numNeighbors++;
00165         //       }
00166         //    //empty previously allocated container for neighbors
00167         //    neighbors.clear();
00168         //    neighbors.assign(numNeighbors+1,Point3D());
00169 
00170         maxNeighborIndex=BoundaryStrategy::getInstance()->getMaxNeighborIndexFromDepth(depth);
00171         cerr<<"\t\t\t\t\t setDepth  maxNeighborIndex="<<maxNeighborIndex<<endl;
00172         neighbors.clear();
00173         neighbors.assign(maxNeighborIndex+1,Point3D());
00174 
00175 }
00176 
00177 void Potts3D::setNeighborOrder(unsigned int _neighborOrder){
00178         BoundaryStrategy::getInstance()->prepareNeighborListsBasedOnNeighborOrder(_neighborOrder);
00179         maxNeighborIndex=BoundaryStrategy::getInstance()->getMaxNeighborIndexFromNeighborOrder(_neighborOrder);
00180         cerr<<"\t\t\t\t\t setNeighborOrder  maxNeighborIndex="<<maxNeighborIndex<<endl;
00181         Dim3D dim=cellFieldG->getDim();
00182         minCoordinates=Point3D(0,0,0);
00183         maxCoordinates=Point3D(dim.x,dim.y,dim.z);
00184 
00185         neighbors.clear();
00186         neighbors.assign(maxNeighborIndex+1,Point3D());
00187 
00188 }
00189 
00190 
00191 void Potts3D::createCellField(const Dim3D dim) {
00192 
00193         ASSERT_OR_THROW("createCellField() cell field G already created!", !cellFieldG);
00194         cellFieldG = new WatchableField3D<CellG *>(dim, 0); //added
00195 
00196 
00197 }
00198 
00199 void Potts3D::registerAttributeAdder(AttributeAdder * _attrAdder){
00200         attrAdder=_attrAdder;
00201 }
00202 
00203 // void Potts3D::registerTypeChangeWatcher(TypeChangeWatcher * _typeChangeWatcher){
00204 //    typeTransition->registerTypeChangeWatcher(_typeChangeWatcher);
00205 // }
00206 
00207 void Potts3D::registerAutomaton(Automaton* autom) {automaton = autom;}
00208 Automaton* Potts3D::getAutomaton() {return automaton;}
00209 
00210 void Potts3D::registerEnergyFunction(EnergyFunction *function) {
00211 
00212         energyCalculator->registerEnergyFunctionWithName(function,function->toString());
00213         //    sim->registerSteerableObject(function);
00214 
00215 }
00216 
00217 void Potts3D::registerEnergyFunctionWithName(EnergyFunction *_function,std::string _functionName){
00218 
00219         energyCalculator->registerEnergyFunctionWithName(_function,_functionName);
00220         //   sim->registerSteerableObject(_function);
00221 
00222 }
00223 
00224 
00225 void Potts3D::unregisterEnergyFunction(std::string _functionName) {
00226 
00227         energyCalculator->unregisterEnergyFunction(_functionName);
00228         //    sim->unregisterSteerableObject(_functionName);
00229         return;
00230 
00231 }
00232 
00233 double Potts3D::getEnergy() {return energy;}
00234 
00235 void Potts3D::setAcceptanceFunctionByName(std::string _acceptanceFunctionName){
00236         if(_acceptanceFunctionName=="FirstOrderExpansion"){
00237                 acceptanceFunction=&firstOrderExpansionAcceptanceFunction;
00238                 //          cerr<<"setting FirstOrderExpansion"<<endl;
00239         }else {
00240                 acceptanceFunction=&defaultAcceptanceFunction;
00241         }
00242 
00243 }
00244 
00245 void Potts3D::registerAcceptanceFunction(AcceptanceFunction *function) {
00246         ASSERT_OR_THROW("registerAcceptanceFunction() function cannot be NULL!",
00247                 function);
00248 
00249         acceptanceFunction = function;
00250 }
00251 
00252 
00254 void Potts3D::registerCellGChangeWatcher(CellGChangeWatcher *_watcher) {
00255         ASSERT_OR_THROW("registerBCGChangeWatcher() _watcher cannot be NULL!",_watcher);
00256 
00257         cellFieldG->addChangeWatcher(_watcher); 
00258         //    sim->registerSteerableObject(_watcher);
00259 }
00260 
00261 
00262 void Potts3D::registerClassAccessor(BasicClassAccessorBase *_accessor) {
00263         ASSERT_OR_THROW("registerClassAccessor() _accessor cannot be NULL!", _accessor);
00264 
00265         cellFactoryGroup.registerClass(_accessor);
00266 }
00267 
00268 
00269 void Potts3D::registerStepper(Stepper *stepper) {
00270         ASSERT_OR_THROW("registerStepper() stepper cannot be NULL!", stepper);
00271 
00272         steppers.push_back(stepper);
00273 }
00275 void Potts3D::registerFixedStepper(FixedStepper *fixedStepper) {
00276         ASSERT_OR_THROW("registerStepper() stepper cannot be NULL!", fixedStepper);
00277 
00278         fixedSteppers.push_back(fixedStepper);
00279 }
00280 
00281 
00283 CellG * Potts3D::createCellG(const Point3D pt) {
00284         ASSERT_OR_THROW("createCell() cellFieldG Point out of range!", cellFieldG->isValid(pt));
00285 
00286         CellG * cell = new CellG();
00287         cell->extraAttribPtr=cellFactoryGroup.create();
00288         cell->id=recentlyCreatedCellId;
00289         ++recentlyCreatedCellId;
00290         cellInventory.addToInventory(cell);
00291         cellFieldG->set(pt, cell);
00292         if(attrAdder){
00293                 attrAdder->addAttribute(cell);
00294         }
00295         return cell;   
00296 }
00297 
00298 
00299 void Potts3D::destroyCellG(CellG *cell,bool _removeFromInventory) {
00300         if(cell->extraAttribPtr){
00301                 cellFactoryGroup.destroy(cell->extraAttribPtr);
00302                 cell->extraAttribPtr=0;
00303         }
00304         if(cell->pyAttrib && attrAdder){
00305                 attrAdder->destroyAttribute(cell);
00306         }
00307         //had to introduce these two cases because in the Cell inventory destructor we deallocate memory of pointers stored int the set
00308         //Since this is done during interation over set changing pointer (cell=0) or removing anything from set might corrupt container or invalidate iterators
00309         if(_removeFromInventory){
00310                 cellInventory.removeFromInventory(cell);
00311                 delete cell;
00312                 cell=0;
00313         }else{
00314                 delete cell;
00315         }
00316 
00317 }
00318 
00320 
00321 double Potts3D::totalEnergy() {
00322         double energy = 0;
00323         Dim3D dim = cellFieldG->getDim();
00324 
00325         Point3D pt;
00326         for (pt.z = 0; pt.z < dim.z; pt.z++)
00327                 for (pt.y = 0; pt.y < dim.y; pt.y++)
00328                         for (pt.x = 0; pt.x < dim.x; pt.x++)
00329                                 for (unsigned int i = 0; i < energyFunctions.size(); i++)
00330                                         energy += energyFunctions[i]->localEnergy(pt);
00331 
00332         return energy;
00333 
00334 }
00335 
00336 
00337 double Potts3D::changeEnergy(Point3D pt, const CellG *newCell,
00338                                                                           const CellG *oldCell) {
00339                                                                                   double change = 0;
00340                                                                                   for (unsigned int i = 0; i < energyFunctions.size(); i++)
00341                                                                                           change += energyFunctions[i]->changeEnergy(pt, newCell, oldCell);
00342 
00343                                                                                   return change;
00344 }
00345 
00346 
00347 unsigned int Potts3D::metropolis(const unsigned int steps, const double temp) {
00348         return (this->*metropolisFcnPtr)(steps,temp);
00349 }
00350 
00351 unsigned int Potts3D::metropolisList(const unsigned int steps, const double temp) {
00352         ASSERT_OR_THROW("Potts3D: cell field G not initialized", cellFieldG);
00353 
00354 
00355         flips = 0;
00356         attemptedEC=0;
00357         BasicRandomNumberGenerator *rand = BasicRandomNumberGenerator::getInstance();
00359         Dim3D dim = cellFieldG->getDim();
00360         ASSERT_OR_THROW("Potts3D: You must supply an acceptance function!",
00361                 acceptanceFunction);
00362 
00363         //   numberOfAttempts=steps;
00364         numberOfAttempts=(int)(maxCoordinates.x-minCoordinates.x)*(maxCoordinates.y-minCoordinates.y)*(maxCoordinates.z-minCoordinates.z)*sim->getFlip2DimRatio();
00365 
00366         BoundaryStrategy * boundaryStrategy = BoundaryStrategy::getInstance();
00367         for (unsigned int i = 0; i < numberOfAttempts; i++) {
00368 
00369                 currentAttempt=i;
00370                 //run fixed steppers - they are executed regardless whether spin flip take place or not . Note, regular steopers are executed only after spin flip attepmts takes place 
00371                 for (unsigned int j = 0; j < fixedSteppers.size(); j++)
00372                         fixedSteppers[j]->step();
00373 
00374 
00375 
00376                 Point3D pt;
00377 
00378                 // Pick a random point
00379                 pt.x = rand->getInteger(minCoordinates.x, maxCoordinates.x - 1);
00380                 pt.y = rand->getInteger(minCoordinates.y, maxCoordinates.y - 1);
00381                 pt.z = rand->getInteger(minCoordinates.z, maxCoordinates.z - 1);
00382 
00383 
00384                 //     pt.x = rand->getInteger(0, dim.x - 1);
00385                 //     pt.y = rand->getInteger(0, dim.y - 1);
00386                 //     pt.z = rand->getInteger(0, dim.z - 1);
00387 
00389                 CellG *cell = cellFieldG->get(pt);
00390 
00391                 if(sizeFrozenTypeVec && cell){
00392                         if(checkIfFrozen(cell->type))
00393                                 continue;
00394                 }
00395 
00396                 unsigned int token = 0;
00397                 int numNeighbors = 0;
00398                 double distance;
00399 
00400                 token =0;
00401                 distance=0;
00402                 while(true){
00403 
00404                         neighbors[numNeighbors] = cellFieldG->getNeighbor(pt, token, distance);
00405                         if (distance > depth) break;
00406 
00407                         if (cellFieldG->get(neighbors[numNeighbors]) != cell)
00408                                 numNeighbors++;
00409 
00410                 }
00411 
00412                 // If no boundry neighbors were found start over
00413                 if (!numNeighbors) continue;
00414 
00415                 // Pick a random neighbor
00416                 Point3D changePixel = neighbors[rand->getInteger(0, numNeighbors - 1)];
00417 
00418 
00419 
00420 
00421                 if(sizeFrozenTypeVec && cellFieldG->get(changePixel)){
00422                         if(checkIfFrozen(cellFieldG->get(changePixel)->type))
00423                                 continue;
00424                 }
00425                 ++attemptedEC;  
00426 
00427                 flipNeighbor=pt;
00428 
00429 
00430                 // Calculate change in energy
00431 
00432                 double change = energyCalculator->changeEnergy(changePixel, cell, cellFieldG->get(changePixel),i); 
00434 
00435                 // Acceptance based on probability
00436                 double motility=0.0;
00437                 if(cellTypeMotilityVec.size()){
00438                         unsigned int newCellTypeId=(cell ? (unsigned int)cell->type :0);
00439                         unsigned int oldCellTypeId=(cellFieldG->get(changePixel)? (unsigned int)cellFieldG->get(changePixel)->type :0);
00440                         if(newCellTypeId && oldCellTypeId)
00441                                 motility=(cellTypeMotilityVec[newCellTypeId]<cellTypeMotilityVec[oldCellTypeId] ? cellTypeMotilityVec[newCellTypeId]:cellTypeMotilityVec[oldCellTypeId]);
00442                         else if(newCellTypeId){
00443                                 motility=cellTypeMotilityVec[newCellTypeId];
00444                         }else if (oldCellTypeId){
00445                                 motility=cellTypeMotilityVec[oldCellTypeId];
00446                         }else{//should never get here
00447                                 motility=0;
00448                         }
00449                 }else{
00450                         motility=temp;
00451                 }
00452                 double prob = acceptanceFunction->accept(motility, change);
00453 
00454 
00455 
00456                 if (prob >= 1 || rand->getRatio() < prob) {
00457                         // Accept the change
00458                         energy += change;
00459 
00460                         cellFieldG->set(changePixel, cell);
00461                         flips++;
00462                         energyCalculator->setLastFlipAccepted(true);
00463                 }else{
00464                         energyCalculator->setLastFlipAccepted(false);
00465                 }
00466 
00467 
00468                 // Run steppers
00469                 for (unsigned int j = 0; j < steppers.size(); j++)
00470                         steppers[j]->step();
00471         }
00472         unsigned int currentStep=sim->getStep();
00473         if(! (currentStep % debugOutputFrequency) ){
00474                 cerr<<"Number of Attempted Energy Calculations="<<attemptedEC<<endl;
00475         }
00476         return flips;
00477 }
00478 
00479 unsigned int Potts3D::metropolisFast(const unsigned int steps, const double temp) {
00480         ASSERT_OR_THROW("Potts3D: cell field G not initialized", cellFieldG);
00481 
00482 
00483         flips = 0;
00484         attemptedEC=0;
00485         BasicRandomNumberGenerator *rand = BasicRandomNumberGenerator::getInstance();
00487         Dim3D dim = cellFieldG->getDim();
00488         ASSERT_OR_THROW("Potts3D: You must supply an acceptance function!",
00489                 acceptanceFunction);
00490         //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00491 
00492         numberOfAttempts=(int)(maxCoordinates.x-minCoordinates.x)*(maxCoordinates.y-minCoordinates.y)*(maxCoordinates.z-minCoordinates.z)*sim->getFlip2DimRatio();
00493         //   numberOfAttempts=steps;
00494 
00495 
00496         cerr<<"FAST numberOfAttempts="<<numberOfAttempts<<endl;
00497         BoundaryStrategy * boundaryStrategy = BoundaryStrategy::getInstance();
00498         for (unsigned int i = 0; i < numberOfAttempts; i++) {
00499 
00500                 currentAttempt=i;
00501                 //run fixed steppers - they are executed regardless whether spin flip take place or not . Note, regular steopers are executed only after spin flip attepmts takes place 
00502                 for (unsigned int j = 0; j < fixedSteppers.size(); j++)
00503                         fixedSteppers[j]->step();
00504 
00505 
00506 
00507                 Point3D pt;
00508 
00509                 // Pick a random point
00510                 pt.x = rand->getInteger(minCoordinates.x, maxCoordinates.x - 1);
00511                 pt.y = rand->getInteger(minCoordinates.y, maxCoordinates.y - 1);
00512                 pt.z = rand->getInteger(minCoordinates.z, maxCoordinates.z - 1);
00513                 //    cerr<<"pt flip="<<pt<<endl;
00514                 //     pt.x = rand->getInteger(0, dim.x - 1);
00515                 //     pt.y = rand->getInteger(0, dim.y - 1);
00516                 //     pt.z = rand->getInteger(0, dim.z - 1);
00517                 //     cout<<"pt="<<pt<<" rand->getSeed()="<<rand->getSeed()<<endl;
00518 
00519 
00521                 CellG *cell = cellFieldG->get(pt);
00522 
00523                 if(sizeFrozenTypeVec && cell){
00524                         if(checkIfFrozen(cell->type))
00525                                 continue;
00526                 }
00527 
00528                 unsigned int directIdx=rand->getInteger(0, maxNeighborIndex);
00529                 //      cerr<<"directIdx="<<directIdx<<endl;
00530 
00531                 Neighbor n=boundaryStrategy->getNeighborDirect(pt,directIdx);
00532                 //      cerr<<"n.pt"<<n.pt<<" n.distance="<<n.distance<<endl;
00533 
00534                 if(!n.distance){
00535                         //if distance is 0 then the neighbor returned is invalid
00536                         continue;
00537                 }
00538                 Point3D changePixel = n.pt;
00539                 //       cerr<<"pt="<<pt<<" n.pt="<<n.pt<<" difference="<<pt-n.pt<<endl;
00540                 //check if changePixel refers to different cell. 
00541 
00542                 if (cellFieldG->get(changePixel) == cell){
00543                         continue;//skip the rest of the loop if change pixel points to the same cell as pt
00544                 }else{
00545                         ;
00546 
00547                 }
00548 
00549                 //     cout<<"pt="<<pt<<" changePixel="<<changePixel<<endl;
00550 
00551                 if(sizeFrozenTypeVec && cellFieldG->get(changePixel)){
00552                         if(checkIfFrozen(cellFieldG->get(changePixel)->type))
00553                                 continue;
00554                 }
00555                 ++attemptedEC;  
00556 
00557                 flipNeighbor=pt;
00558 
00559                 // Calculate change in energy
00560                 //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00561 
00562                 double change = energyCalculator->changeEnergy(changePixel, cell, cellFieldG->get(changePixel),i); 
00563 
00564                 //cerr<<"This is change: "<<change<<endl;       
00565 
00566                 //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00567 
00568                 // Acceptance based on probability
00569                 double motility=0.0;
00570                 if(cellTypeMotilityVec.size()){
00571                         unsigned int newCellTypeId=(cell ? (unsigned int)cell->type :0);
00572                         unsigned int oldCellTypeId=(cellFieldG->get(changePixel)? (unsigned int)cellFieldG->get(changePixel)->type :0);
00573                         if(newCellTypeId && oldCellTypeId)
00574                                 motility=(cellTypeMotilityVec[newCellTypeId]<cellTypeMotilityVec[oldCellTypeId] ? cellTypeMotilityVec[newCellTypeId]:cellTypeMotilityVec[oldCellTypeId]);
00575                         else if(newCellTypeId){
00576                                 motility=cellTypeMotilityVec[newCellTypeId];
00577                         }else if (oldCellTypeId){
00578                                 motility=cellTypeMotilityVec[oldCellTypeId];
00579                         }else{//should never get here
00580                                 motility=0;
00581                         }
00582                 }else{
00583                         motility=temp;
00584                 }
00585 
00586                 //cerr<<"newCell="<<cell<<" oldCell="<<cellFieldG->get(changePixel)<<" motility="<<motility<<endl;
00587 
00588                 double prob = acceptanceFunction->accept(motility, change);
00589                 //     cerr<<"prob="<<prob<<endl;
00590 
00591 
00592                 //     cout<<"change E="<<change<<" prob="<<prob<<endl;
00593                 if (prob >= 1 || rand->getRatio() < prob) {
00594                         // Accept the change
00595                         //        cout<<"accepted flip "<< change<<endl;
00596                         energy += change;
00597                         //       cerr<<"energy="<<energy<<endl;
00598                         cellFieldG->set(changePixel, cell);
00599                         flips++;
00600                         energyCalculator->setLastFlipAccepted(true);
00601                 }else{
00602                         energyCalculator->setLastFlipAccepted(false);
00603                 }
00604 
00605 
00606                 // Run steppers
00607                 for (unsigned int j = 0; j < steppers.size(); j++)
00608                         steppers[j]->step();
00609 
00610                 //     exit(0);
00611         }
00612         unsigned int currentStep=sim->getStep();
00613         if(! (currentStep % debugOutputFrequency) ){
00614                 cerr<<"Number of Attempted Energy Calculations="<<attemptedEC<<endl;
00615         }
00616         //    exit(0);
00617         return flips;
00618 
00619 }
00620 
00621 
00622 unsigned int Potts3D::metropolisBoundaryWalker(const unsigned int steps, const double temp) {
00623         ASSERT_OR_THROW("Potts3D: cell field G not initialized", cellFieldG);
00624 
00625 
00626         flips = 0;
00627         attemptedEC=0;
00628         BasicRandomNumberGenerator *rand = BasicRandomNumberGenerator::getInstance();
00630         Dim3D dim = cellFieldG->getDim();
00631         ASSERT_OR_THROW("Potts3D: You must supply an acceptance function!",
00632                 acceptanceFunction);
00633         //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00634 
00635         //numberOfAttempts=(int)(maxCoordinates.x-minCoordinates.x)*(maxCoordinates.y-minCoordinates.y)*(maxCoordinates.z-minCoordinates.z)*sim->getFlip2DimRatio();
00636         //   numberOfAttempts=steps;
00637         //Number of attempts is equal to number of boundary pixels
00638         numberOfAttempts=boundaryPixelSet.size();
00639 
00640         cerr<<"numberOfAttempts="<<numberOfAttempts<<endl;
00641         long boundaryPointIndex;
00642         long counter=0;
00643         set<Point3D>::iterator sitr;
00644         vector<Point3D> boundaryPointVector;
00645         boundaryPointVector.assign(boundaryPixelSet.begin(),boundaryPixelSet.end());
00646 
00647         BoundaryStrategy * boundaryStrategy = BoundaryStrategy::getInstance();
00648         for (unsigned int i = 0; i < numberOfAttempts; i++) {
00649 
00650                 currentAttempt=i;
00651                 //run fixed steppers - they are executed regardless whether spin flip take place or not . Note, regular steopers are executed only after spin flip attepmts takes place 
00652                 for (unsigned int j = 0; j < fixedSteppers.size(); j++)
00653                         fixedSteppers[j]->step();
00654 
00655 
00656 
00657                 Point3D pt;
00658 
00659                 // Pick a random integer
00660                 boundaryPointIndex=rand->getInteger(minCoordinates.x, boundaryPointVector.size()-1);     
00661                 pt=boundaryPointVector[boundaryPointIndex];
00662 
00663                 //    boundaryPointIndex=rand->getInteger(minCoordinates.x, boundaryPixelSet.size()-1);//we use most up-to-date set size
00664                 //  counter=0;
00665                 //for (set<Point3D>::iterator sitr=boundaryPixelSet.begin() ; sitr!=boundaryPixelSet.end(); ++sitr){
00666                 // if(counter==boundaryPointIndex){
00667                 //      pt=*sitr;
00668                 //      break;
00669                 // }
00670                 // ++counter;
00671                 //}
00672 
00673                 //    cerr<<"pt flip="<<pt<<endl;
00674                 //     pt.x = rand->getInteger(0, dim.x - 1);
00675                 //     pt.y = rand->getInteger(0, dim.y - 1);
00676                 //     pt.z = rand->getInteger(0, dim.z - 1);
00677                 //     cout<<"pt="<<pt<<" rand->getSeed()="<<rand->getSeed()<<endl;
00678 
00679 
00681                 CellG *cell = cellFieldG->get(pt);
00682 
00683                 if(sizeFrozenTypeVec && cell){
00684                         if(checkIfFrozen(cell->type))
00685                                 continue;
00686                 }
00687 
00688                 unsigned int directIdx=rand->getInteger(0, maxNeighborIndex);
00689                 //      cerr<<"directIdx="<<directIdx<<endl;
00690 
00691                 Neighbor n=boundaryStrategy->getNeighborDirect(pt,directIdx);
00692                 //      cerr<<"n.pt"<<n.pt<<" n.distance="<<n.distance<<endl;
00693 
00694                 if(!n.distance){
00695                         //if distance is 0 then the neighbor returned is invalid
00696                         continue;
00697                 }
00698                 Point3D changePixel = n.pt;
00699                 //       cerr<<"pt="<<pt<<" n.pt="<<n.pt<<" difference="<<pt-n.pt<<endl;
00700                 //check if changePixel refers to different cell. 
00701 
00702                 if (cellFieldG->get(changePixel) == cell){
00703                         continue;//skip the rest of the loop if change pixel points to the same cell as pt
00704                 }else{
00705                         ;
00706 
00707                 }
00708 
00709                 //     cout<<"pt="<<pt<<" changePixel="<<changePixel<<endl;
00710 
00711                 if(sizeFrozenTypeVec && cellFieldG->get(changePixel)){
00712                         if(checkIfFrozen(cellFieldG->get(changePixel)->type))
00713                                 continue;
00714                 }
00715                 ++attemptedEC;  
00716 
00717                 flipNeighbor=pt;
00718 
00719                 // Calculate change in energy
00720                 //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00721 
00722                 double change = energyCalculator->changeEnergy(changePixel, cell, cellFieldG->get(changePixel),i); 
00723 
00724                 //cerr<<"This is change: "<<change<<endl;       
00725 
00726                 //cerr<<"steps="<<steps<<" temp="<<temp<<" acceptanceFunction="<<acceptanceFunction<<endl;
00727 
00728                 // Acceptance based on probability
00729                 double motility=0.0;
00730                 if(cellTypeMotilityVec.size()){
00731                         unsigned int newCellTypeId=(cell ? (unsigned int)cell->type :0);
00732                         unsigned int oldCellTypeId=(cellFieldG->get(changePixel)? (unsigned int)cellFieldG->get(changePixel)->type :0);
00733                         if(newCellTypeId && oldCellTypeId)
00734                                 motility=(cellTypeMotilityVec[newCellTypeId]<cellTypeMotilityVec[oldCellTypeId] ? cellTypeMotilityVec[newCellTypeId]:cellTypeMotilityVec[oldCellTypeId]);
00735                         else if(newCellTypeId){
00736                                 motility=cellTypeMotilityVec[newCellTypeId];
00737                         }else if (oldCellTypeId){
00738                                 motility=cellTypeMotilityVec[oldCellTypeId];
00739                         }else{//should never get here
00740                                 motility=0;
00741                         }
00742                 }else{
00743                         motility=temp;
00744                 }
00745                 double prob = acceptanceFunction->accept(motility, change);
00746                 //     cerr<<"prob="<<prob<<endl;
00747 
00748 
00749                 //     cout<<"change E="<<change<<" prob="<<prob<<endl;
00750                 if (prob >= 1 || rand->getRatio() < prob) {
00751                         // Accept the change
00752                         //        cout<<"accepted flip "<< change<<endl;
00753                         energy += change;
00754                         //       cerr<<"energy="<<energy<<endl;
00755                         cellFieldG->set(changePixel, cell);
00756                         flips++;
00757                         energyCalculator->setLastFlipAccepted(true);
00758                 }else{
00759                         energyCalculator->setLastFlipAccepted(false);
00760                 }
00761 
00762 
00763                 // Run steppers
00764                 for (unsigned int j = 0; j < steppers.size(); j++)
00765                         steppers[j]->step();
00766 
00767                 //     exit(0);
00768         }
00769         unsigned int currentStep=sim->getStep();
00770         if(! (currentStep % debugOutputFrequency) ){
00771                 cerr<<"Number of Attempted Energy Calculations="<<attemptedEC<<endl;
00772         }
00773         //    exit(0);
00774         return flips;
00775 
00776 }
00777 
00778 
00779 void Potts3D::setMetropolisAlgorithm(std::string _algName){
00780 
00781         string algName=_algName;
00782         changeToLower(algName);
00783 
00784         if(algName=="list"){
00785                 metropolisFcnPtr=&Potts3D::metropolisList;
00786         }else if (algName=="fast"){
00787                 metropolisFcnPtr=&Potts3D::metropolisFast;
00788         }else if (algName=="boundarywalker"){
00789                 metropolisFcnPtr=&Potts3D::metropolisBoundaryWalker;
00790         }else{
00791                 metropolisFcnPtr=&Potts3D::metropolisFast;
00792         }
00793 
00794 }
00795 
00796 
00798 
00799 void Potts3D::setCellTypeMotilityVec(std::vector<float> & _cellTypeMotilityVec){
00800         cellTypeMotilityVec=_cellTypeMotilityVec;
00801 }
00803 void Potts3D::initializeCellTypeMotility(std::vector<CellTypeMotilityData> & _cellTypeMotilityVector){
00804 
00805         ASSERT_OR_THROW("AUTOMATON IS NOT INITIALIZED",automaton);
00806 
00807         unsigned int typeIdMax=0;
00808         //finding max typeId
00809         for(int i =0 ; i < _cellTypeMotilityVector.size() ;++i ){
00810                 //cerr<<"CHECKING "<<_cellTypeMotilityVector[i].typeName<<endl;
00811                 unsigned int id=automaton->getTypeId(_cellTypeMotilityVector[i].typeName);
00812                 if(id>typeIdMax)
00813                         typeIdMax=id;
00814         }
00815 
00816         cellTypeMotilityVec.assign(typeIdMax+1,0.0);
00817         for(int i =0 ; i < _cellTypeMotilityVector.size() ;++i ){
00818                 unsigned int id = automaton->getTypeId(_cellTypeMotilityVector[i].typeName);
00819                 cellTypeMotilityVec[id]=_cellTypeMotilityVector[i].motility;
00820         }
00821 
00822         //for(int i =0 ; i < _cellTypeMotilityVector.size() ;++i ){
00823         //      
00824         //      cerr<<"cellTypeMotilityVec["<<i<<"]="<<cellTypeMotilityVec[i]<<endl;
00825         //}
00826         //
00827         //exit(0);
00828 }
00829 
00831 
00832 bool Potts3D::checkIfFrozen(unsigned char _type){
00833 
00834 
00835 
00836         for (unsigned int i = 0 ; i< frozenTypeVec.size(); ++i ){
00837                 if(frozenTypeVec[i]==_type)
00838                         return true;
00839         }
00840         return false;
00841 
00842 }
00844 void