diff --git a/Makefile b/Makefile index 851dac0..ef87776 100644 --- a/Makefile +++ b/Makefile @@ -190,11 +190,11 @@ lib/libecolab$(ECOLIBS_EXT).a: $(OBJS) $(LIBMODS) # build graphcode objects -cd graphcode; $(GRAPHCODE_MAKE) libgraphcode.a -cp -f graphcode/*.h include - ar r $@ $^ + ar r $@ $^ graphcode/*.o ifeq ($(OS),Darwin) ranlib $@ endif - $(CPLUSPLUS) -shared -Wl,-soname,libecolab$(ECOLIBS_EXT).so.$(SOVERSION) $^ -o lib/libecolab$(ECOLIBS_EXT).so.$(SOVERSION) + $(CPLUSPLUS) -shared -Wl,-soname,libecolab$(ECOLIBS_EXT).so.$(SOVERSION) $^ graphcode/*.o $(LIBS) -o lib/libecolab$(ECOLIBS_EXT).so.$(SOVERSION) cd lib; ln -sf libecolab$(ECOLIBS_EXT).so.$(SOVERSION) libecolab$(ECOLIBS_EXT).so cd lib; ln -sf libecolab$(ECOLIBS_EXT).so.$(SOVERSION) ecolab$(ECOLIBS_EXT).so diff --git a/classdesc b/classdesc index 5ac87b1..2ead63b 160000 --- a/classdesc +++ b/classdesc @@ -1 +1 @@ -Subproject commit 5ac87b16643f6a2bd9ff3b72acb9aa2f398e654b +Subproject commit 2ead63b60bf4f564ca08c290f8ab221d2eda09cf diff --git a/graphcode b/graphcode index 6600117..b4205ab 160000 --- a/graphcode +++ b/graphcode @@ -1 +1 @@ -Subproject commit 660011790c421bdbf07eb95917f48756ec731612 +Subproject commit b4205abf9fddd01dcb417b073b652e9ff83e456f diff --git a/include/ecolab_epilogue.h b/include/ecolab_epilogue.h index 9c06f02..c91f9cf 100644 --- a/include/ecolab_epilogue.h +++ b/include/ecolab_epilogue.h @@ -13,5 +13,4 @@ Put this after including all .cd files */ #include "classdesc_epilogue.h" #ifdef GRAPHCODE_H -#include "graphcode.cd" #endif diff --git a/models/ecolab_model.cc b/models/ecolab_model.cc index 491873f..86a26b2 100644 --- a/models/ecolab_model.cc +++ b/models/ecolab_model.cc @@ -26,6 +26,8 @@ using array_ns::pcoord; #include "ecolab_epilogue.h" +using namespace classdesc; + // TODO - move this into main library namespace { @@ -78,7 +80,6 @@ void ModelData::random_interaction(unsigned conn, double sigma) void PanmicticModel::generate(unsigned niter) { - //parallel(args); if (tstep==0) makeConsistent(); EcolabPoint::generate(niter,*this); tstep+=niter; @@ -390,3 +391,30 @@ bool ConnectionPlot::redraw(int x0, int y0, int width, int height) return true; } +void SpatialModel::setGrid(size_t nx, size_t ny) +{ + numX=nx; numY=ny; + for (size_t i=0; ias()->generate(niter,*this); + tstep+=niter; +} + +void SpatialModel::makeConsistent() +{ + // all cells must have same number of species. Pack out with zero density if necessary + unsigned long nsp=0; + for (auto& i: *this) nsp=max(nsp,i->as()->density.size()); +#ifdef MPI_SUPPORT + MPI_AllReduce(MPI_IN_PLACE,&nsp,1,MPI_UNSIGNED_LONG,MPI_MAX,MPI_COMM_WORLD); +#endif + for (auto& i: *this) + i->as()->density<<=array(nsp-i->as()->density.size(),0); + ModelData::makeConsistent(nsp); +} diff --git a/models/ecolab_model.h b/models/ecolab_model.h index 1ecb1bd..07d48fc 100644 --- a/models/ecolab_model.h +++ b/models/ecolab_model.h @@ -80,7 +80,20 @@ struct PanmicticModel: public ModelData, public EcolabPoint struct EcoLabCell: public EcolabPoint, public graphcode::Object {}; -struct SpatialModel: public ModelData, public graphcode::Graph +class SpatialModel: public ModelData, public graphcode::Graph { + size_t numX=1, numY=1; +public: + size_t makeId(size_t x, size_t y) const {return x%numX + numX*(y%numY);} + void setGrid(size_t nx, size_t ny); + graphcode::ObjectPtr cell(size_t x, size_t y) { + return objects[makeId(x,y)]; + } + void makeConsistent(); + void generate(unsigned niter); + void generate() {generate(1);} +// void condense(); +// void mutate(); +// void migrate(); }; diff --git a/models/spatial_ecolab.py b/models/spatial_ecolab.py new file mode 100644 index 0000000..c76b332 --- /dev/null +++ b/models/spatial_ecolab.py @@ -0,0 +1,52 @@ +from ecolab_model import spatial_ecolab as ecolab +from random import random +# initial number of species +nsp=100 + +ecolab.repro_min(-0.1) +ecolab.repro_max(0.1) +ecolab.odiag_min(-1e-5) +ecolab.odiag_max(1e-5) +#ecolab.mut_max(1e-4) +ecolab.mut_max(1e-3) +ecolab.sp_sep(0.1) + +def randomList(num, min, max): + return [random()*(max-min)+min for i in range(num)] + +ecolab.species(range(nsp)) + +numX=2 +numY=2 +ecolab.setGrid(numX,numY) +ecolab.partitionObjects() +for i in range(numX): + for j in range(numY): + ecolab.cell(i,j).density(nsp*[100]) + +ecolab.repro_rate(randomList(nsp, ecolab.repro_min(), ecolab.repro_max())) +ecolab.interaction.diag(randomList(nsp, -1e-3, -1e-3)) +ecolab.random_interaction(3,0) + +ecolab.interaction.val(randomList(len(ecolab.interaction.val), ecolab.odiag_min(), ecolab.odiag_max())) + +ecolab.mutation(nsp*[ecolab.mut_max()]) +ecolab.migration(nsp*[1e-5]) + +from plot import plot + +def step(): + ecolab.generate() + # ecolab.mutate() + # ecolab.condense() + nsp=len(ecolab.species) + statusBar.configure(text=f't={ecolab.tstep()} nsp:{nsp}') + # plot('No. species',ecolab.tstep(),nsp) + for i in range(numX): + for j in range(numY): + plot(f'Density({i},{j}',ecolab.tstep(),ecolab.cell(i,j).density()._properties, pens=ecolab.species()._properties) + +gui(step) + + + diff --git a/src/cairoSurfaceImage.cc b/src/cairoSurfaceImage.cc index c70eb5a..f7f28e9 100644 --- a/src/cairoSurfaceImage.cc +++ b/src/cairoSurfaceImage.cc @@ -89,7 +89,8 @@ namespace if (r==registries().end() || !r->second) throw std::runtime_error("Module: "+module+" not found"); auto rp=r->second->find(object); if (rp==r->second->end()) throw std::runtime_error("Object: "+object+" not found in "+module); - if (CairoSurface* csurf=dynamic_cast(rp->second->getClassdescObject())) + if (CairoSurface* csurf= + dynamic_cast(const_cast(rp->second->getClassdescObject()))) { *masterData=new CD(0,master,*csurf); Tk_ImageChanged(master,0,0,500,500,500,500);