Skip to content

Commit 22de01e

Browse files
Fix migration routine
SAR.py outputs CSV Additional area cases Reinitialise last_mig_step every loop Avoid division by zero on global extinction Stagger launch of ensemble members to ensure distnct random seeding.
1 parent 06c00fe commit 22de01e

File tree

3 files changed

+61
-51
lines changed

3 files changed

+61
-51
lines changed

models/SAR.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ def av(x):
3333
#mut_max=float(sys.argv[3]) # mutation rate
3434
#migration=float(sys.argv[4]) # initial migration rate
3535

36-
print("Area, Mutation rate, Migration rate, Number of species, Interaction strength^2")
37-
for A in [1, 2, 4, 9, 16]:
38-
for mut_max in [1e-4, 1e-3, 1e-2]:
39-
for migration in [1e-6, 1e-5, 1e-4, 1e-3]:
40-
for nsp in [100, 200, 400]:
36+
print("Area, Mutation rate, Migration rate, Number of species, Interaction strength^2",flush=True)
37+
for A in [4, 9, 16]:
38+
for mut_max in [1e-5, 1e-4, 1e-3]:
39+
for migration in [1e-6, 1e-5]:
40+
for nsp in [30, 100, 200]:
4141
ecolab.tstep(0)
42+
ecolab.last_mig_tstep(0)
4243
ecolab.repro_min(-0.1)
4344
ecolab.repro_max(0.1)
4445
ecolab.odiag_min(-1e-5)
@@ -71,7 +72,8 @@ def av(x):
7172
for i in range(100):
7273
step()
7374

74-
print(numX*numY, av(ecolab.mutation()), av(ecolab.migration()), len(ecolab.species), sum([x*x for x in ecolab.interaction.val()])/len(ecolab.species)**2)
75+
conn=sum([x*x for x in ecolab.interaction.val()])/len(ecolab.species)**2 if len(ecolab.species)>0 else 0
76+
print(numX*numY, av(ecolab.mutation()), av(ecolab.migration()), len(ecolab.species), conn, flush=True,sep=',')
7577

7678

7779

models/SAR.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
i=0
2-
while [ $i -lt 8 ]; do
2+
while [ $[i++] -lt 8 ]; do
33
python3 SAR.py > SARResults_$i.csv &
4+
sleep 1
45
done
56
wait

models/ecolab_model.cc

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ bool ConnectionPlot::redraw(int x0, int y0, int width, int height)
608608
void SpatialModel::setGrid(size_t nx, size_t ny)
609609
{
610610
numX=nx; numY=ny;
611+
objects.clear();
611612
for (size_t i=0; i<numX; ++i)
612613
for (size_t j=0; j<numY; ++j)
613614
{
@@ -617,10 +618,14 @@ void SpatialModel::setGrid(size_t nx, size_t ny)
617618
c.rand.seed(o.id());
618619
o.proc(o.id() % nprocs()); // TODO can we get this to work without this.
619620
// wire up von Neumann neighborhood
620-
o->neighbours.push_back(makeId(i-1,j));
621-
o->neighbours.push_back(makeId(i+1,j));
622-
o->neighbours.push_back(makeId(i,j-1));
623-
o->neighbours.push_back(makeId(i,j+1));
621+
if (i>0)
622+
o->neighbours.push_back(makeId(i-1,j));
623+
if (i<numX-1)
624+
o->neighbours.push_back(makeId(i+1,j));
625+
if (j>0)
626+
o->neighbours.push_back(makeId(i,j-1));
627+
if (j<numY-1)
628+
o->neighbours.push_back(makeId(i,j+1));
624629
}
625630
rebuildPtrLists();
626631
}
@@ -641,64 +646,66 @@ unsigned SpatialModel::migrate()
641646

642647
prepareNeighbours();
643648

644-
//#ifdef SYCL_LANGUAGE_VERSION
645-
// using ArrayAlloc=graphcode::Allocator<int>;
646-
// using Array=vector<int,ArrayAlloc>;
647-
// using DeltaAlloc=graphcode::Allocator<Array>;
648-
// Array init(species.size(),0,ArrayAlloc(syclQ(),sycl::usm::alloc::device));
649-
// vector<Array,DeltaAlloc> delta(size(), init, DeltaAlloc(syclQ(),sycl::usm::alloc::device));
650-
//#else
651649
vector<array<int>> delta(size(), array<int>(species.size(),0));
652-
//#endif
653-
654-
// for (auto& c: *this)
655-
// c->as<EcolabCell>()->delta.resize(species.size());
656650

657651
hostForAll([&,this](EcolabCell& c) {
658652
/* loop over neighbours */
659653
for (auto& n: c)
660654
{
661655
auto& nbr=*n->as<EcolabCell>();
662-
Float salt=c.id<nbr.id? c.salt: nbr.salt;
656+
Float salt=c.idx()<nbr.idx()? c.salt: nbr.salt;
663657
array<Float> m=(tstep-last_mig_tstep) * migration * (nbr.density - c.density);
664-
delta[c.idx()]+=m+ array<Float>((m!=0.0)*(2*(m>0.0)-1)) * salt;
658+
delta[c.idx()]+=m*(1+salt*(m!=0.0));
665659
}
666660
});
667661

668662
array<int> ssum(species.size(),0);
669663
size_t totalMigration=0;
670-
hostForAll([&,this](EcolabCell& c) {
671-
// adjust delta so that density remains +ve
672-
array<int> adjust=delta[c.idx()]+c.density;
673-
adjust*=-(adjust<0);
674-
if (sum(adjust)>0)
675-
{
676-
// distribute adjust among neighbours
677-
array<int> totalDiff(c.density.size(),0);
678-
for (auto& n: c)
679-
{
680-
auto& nbr=*n->as<EcolabCell>();
681-
totalDiff+=nbr.density-c.density;
682-
}
683-
// adjust adjust to be divisible by totalDiff
684-
adjust-=adjust%totalDiff;
685-
for (auto& n: c)
686-
{
687-
auto& nbr=*n->as<EcolabCell>();
688-
delta[nbr.idx()]+=((nbr.density-c.density)/totalDiff)*adjust;
689-
}
690-
delta[c.idx()]-=adjust;
691-
}
692664

693-
c.density+=delta[c.idx()];
694-
totalMigration+=sum(abs(delta[c.idx()]));
665+
vector<size_t> negativeDensityIdx;
666+
size_t numCells=size();
667+
#ifdef _OPENMP
668+
#pragma omp parallel for reduction(+:totalMigration)
669+
#endif
670+
for (size_t i=0; i<numCells; ++i)
671+
{
672+
auto& c=*(*this)[i]->as<EcolabCell>();
673+
c.density+=delta[c.idx()];
674+
totalMigration+=sum(abs(delta[i]));
675+
if (sum(c.density<0))
676+
#ifdef _OPENMP
677+
#pragma omp critical
678+
#endif
679+
negativeDensityIdx.push_back(c.idx());
695680
#if !defined(NDEBUG)
681+
#ifdef _OPENMP
696682
#pragma omp critical
697-
ssum+=delta[c.idx()];
698683
#endif
699-
});
684+
ssum+=delta[c.idx()];
685+
#endif
686+
}
700687
last_mig_tstep=tstep;
701688

689+
// if any density values are -ve, then adjust migration from neighbours.
690+
// loop run sequentially to resolve race condition
691+
for (auto i: negativeDensityIdx)
692+
{
693+
auto& c=*(*this)[i]->as<EcolabCell>();
694+
for (auto j=0; j<c.density.size(); ++j)
695+
while (c.density[j]<0)
696+
{
697+
assert(c.size()>0);
698+
int adjust=-(c.density[j]+c.size()-1)/c.size();
699+
for (auto& n: c)
700+
{
701+
auto& nbr=*n->as<EcolabCell>();
702+
auto nbrAdjust=std::min(nbr.density[j], adjust);
703+
c.density[j]+=nbrAdjust;
704+
nbr.density[j]-=nbrAdjust;
705+
}
706+
}
707+
}
708+
702709
#ifdef MPI_SUPPORT
703710
if (myid()==0)
704711
MPI_Reduce(MPI_IN_PLACE, &totalMigration,1,MPI_UNSIGNED,MPI_SUM,0,MPI_COMM_WORLD);
@@ -734,7 +741,7 @@ unsigned SpatialModel::migrate()
734741
}
735742
if (myid()==0) assert(sum(ssum==0)==int(ssum.size()));
736743
#endif
737-
return totalMigration;
744+
return totalMigration/2;
738745
}
739746

740747
void ModelData::makeConsistent(size_t nsp)

0 commit comments

Comments
 (0)