diff --git a/src/comm.cpp b/src/comm.cpp index 33e4b894d5..d729545dba 100644 --- a/src/comm.cpp +++ b/src/comm.cpp @@ -58,6 +58,7 @@ Comm::Comm(LAMMPS *lmp) : Pointers(lmp) bordergroup = 0; cutghostuser = 0.0; cutusermulti = nullptr; + cutusermultiflag = 0; cutusermultiold = nullptr; ncollections_prior = 0; ghost_velocity = 0; @@ -348,6 +349,7 @@ void Comm::modify_params(int narg, char **arg) // ncollections can be changed by neigh_modify commands cut = utils::numeric(FLERR,arg[iarg+2],false,lmp); cutghostuser = MAX(cutghostuser,cut); + cutusermultiflag = 1; if (cut < 0.0) error->all(FLERR,"Invalid cutoff in comm_modify command"); usermultiargs.emplace_back(arg[iarg+1], cut); diff --git a/src/comm.h b/src/comm.h index 2afdfd8765..418983b6e6 100644 --- a/src/comm.h +++ b/src/comm.h @@ -33,6 +33,7 @@ class Comm : protected Pointers { double cutghost[3]; // cutoffs used for acquiring ghost atoms double cutghostuser; // user-specified ghost cutoff (mode == 0) double *cutusermulti; // per collection user ghost cutoff (mode == 1) + int cutusermultiflag; std::vector> usermultiargs; // collection args for custom ghost cutoffs double *cutusermultiold; // per type user ghost cutoff (mode == 2) diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 58c6a65837..160ecf2c3d 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -142,6 +142,7 @@ void CommBrick::init() // allocate in setup if (mode == Comm::MULTI && multilo == nullptr) { + ncollections = neighbor->ncollections; allocate_multi(maxswap); memory->create(cutghostmulti,ncollections,3,"comm:cutghostmulti"); ncollections_prior = ncollections; @@ -205,10 +206,12 @@ void CommBrick::setup() allocate_multi(maxswap); memory->create(cutghostmulti,ncollections,3,"comm:cutghostmulti"); - memory->grow(cutusermulti,ncollections,"comm:cutusermulti"); - for(i = ncollections_prior; i < ncollections; i++) - cutusermulti[i] = -1.0; - + if(cutusermultiflag) { + memory->grow(cutusermulti,ncollections,"comm:cutusermulti"); + for(i = ncollections_prior; i < ncollections; i++) + cutusermulti[i] = -1.0; + } + ncollections_prior = ncollections; } diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index c06ad52d6c..0a09dc830d 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -104,6 +104,11 @@ void CommTiled::init_buffers() cutghostmultiold = nullptr; sendbox_multi = nullptr; sendbox_multiold = nullptr; + + // initialize ncollections so grow_swap_send_multi() will not + // construct arrays in init() but will wait for setup() + ncollections = 0; + ncollections_prior = 0; maxswap = 6; allocate_swap(maxswap); @@ -194,10 +199,12 @@ void CommTiled::setup() for(i = 0; i < maxswap; i ++) grow_swap_send_multi(i,DELTA_PROCS); - memory->grow(cutusermulti,ncollections,"comm:cutusermulti"); - for(i = ncollections_prior; i < ncollections; i++) - cutusermulti[i] = -1.0; - + if(cutusermultiflag){ + memory->grow(cutusermulti,ncollections,"comm:cutusermulti"); + for(i = ncollections_prior; i < ncollections; i++) + cutusermulti[i] = -1.0; + } + ncollections_prior = ncollections; } diff --git a/src/nbin_multi.cpp b/src/nbin_multi.cpp index bbc69dc2d6..a39f10d074 100644 --- a/src/nbin_multi.cpp +++ b/src/nbin_multi.cpp @@ -146,7 +146,7 @@ void NBinMulti::setup_bins(int /*style*/) // Identify smallest collection int icollectionmin = 0; - for (n = 0; n < maxcollections; n++) + for (n = 0; n < ncollections; n++) if (cutcollectionsq[n][n] < cutcollectionsq[icollectionmin][icollectionmin]) icollectionmin = n; @@ -188,7 +188,7 @@ void NBinMulti::setup_bins(int /*style*/) double binsize_optimal, binsizeinv, coord; int mbinxhi,mbinyhi,mbinzhi; - for (n = 0; n < maxcollections; n++) { + for (n = 0; n < ncollections; n++) { // binsize_user only relates to smallest collection // optimal bin size is roughly 1/2 the collection-collection cutoff // special case of all cutoffs = 0.0, binsize = box size @@ -296,7 +296,7 @@ void NBinMulti::bin_atoms() int i,ibin,n; last_bin = update->ntimestep; - for (n = 0; n < maxcollections; n++) { + for (n = 0; n < ncollections; n++) { for (i = 0; i < mbins_multi[n]; i++) binhead_multi[n][i] = -1; } // bin in reverse order so linked list will be in forward order diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 2671553a07..e8f9798df8 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -426,7 +426,7 @@ void Neighbor::init() for(i = 1; i <= n; i++){ cuttmp = sqrt(cutneighsq[i][i]); for(icollection = 0; icollection < ncollections; icollection ++){ - if(collection2cut[icollection] > cuttmp) { + if(collection2cut[icollection] >= cuttmp) { type2collection[i] = icollection; break; } @@ -2503,6 +2503,8 @@ void Neighbor::modify_params(int narg, char **arg) if(iarg+2 > narg) error->all(FLERR,"Invalid collection/interval command"); ncollections = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + if(ncollections < 1) + error->all(FLERR,"Invalid collection/interval command"); if(iarg+1+ncollections > narg) error->all(FLERR,"Invalid collection/interval command"); @@ -2511,8 +2513,7 @@ void Neighbor::modify_params(int narg, char **arg) interval_collection_flag = 1; custom_collection_flag = 1; - if(not collection2cut) - memory->create(collection2cut,ncollections,"neigh:collection2cut"); + memory->grow(collection2cut,ncollections,"neigh:collection2cut"); // Set upper cutoff for each collection char *id; @@ -2534,6 +2535,8 @@ void Neighbor::modify_params(int narg, char **arg) if(iarg+2 > narg) error->all(FLERR,"Invalid collection/type command"); ncollections = utils::inumeric(FLERR,arg[iarg+1],false,lmp); + if(ncollections < 1) + error->all(FLERR,"Invalid collection/interval command"); if(iarg+1+ncollections > narg) error->all(FLERR,"Invalid collection/type command"); diff --git a/src/nstencil.cpp b/src/nstencil.cpp index 3cf75d8d68..ba7259a9fc 100644 --- a/src/nstencil.cpp +++ b/src/nstencil.cpp @@ -82,6 +82,8 @@ NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp) flag_half_multi = nullptr; flag_skip_multi = nullptr; bin_collection_multi = nullptr; + + maxcollections = 0; dimension = domain->dimension; } @@ -105,15 +107,12 @@ NStencil::~NStencil() delete [] distsq_multi_old; } - if (stencil_multi) { + if (maxstencil_multi) { - int n = ncollections; memory->destroy(nstencil_multi); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (! flag_skip_multi[i][j]) - memory->destroy(stencil_multi[i][j]); - } + for (int i = 0; i < maxcollections; i++) { + for (int j = 0; j < maxcollections; j++) + memory->destroy(stencil_multi[i][j]); delete [] stencil_multi[i]; } delete [] stencil_multi; @@ -275,47 +274,60 @@ void NStencil::create_setup() if(nb) copy_bin_info_multi(); - // Allocate arrays to store stencil information - memory->create(flag_half_multi, n, n, - "neighstencil:flag_half_multi"); - memory->create(flag_skip_multi, n, n, - "neighstencil:flag_skip_multi"); - memory->create(bin_collection_multi, n, n, - "neighstencil:bin_collection_multi"); - - memory->create(stencil_sx_multi, n, n, - "neighstencil:stencil_sx_multi"); - memory->create(stencil_sy_multi, n, n, - "neighstencil:stencil_sy_multi"); - memory->create(stencil_sz_multi, n, n, - "neighstencil:stencil_sz_multi"); - - memory->create(stencil_binsizex_multi, n, n, - "neighstencil:stencil_binsizex_multi"); - memory->create(stencil_binsizey_multi, n, n, - "neighstencil:stencil_binsizey_multi"); - memory->create(stencil_binsizez_multi, n, n, - "neighstencil:stencil_binsizez_multi"); - - memory->create(stencil_mbinx_multi, n, n, - "neighstencil:stencil_mbinx_multi"); - memory->create(stencil_mbiny_multi, n, n, - "neighstencil:stencil_mbiny_multi"); - memory->create(stencil_mbinz_multi, n, n, - "neighstencil:stencil_mbinz_multi"); - - // Skip all stencils by default, initialize smax - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - flag_skip_multi[i][j] = 1; + // Deallocate arrays if previously allocated + if(n > maxcollections and stencil_multi){ + memory->destroy(nstencil_multi); + for (i = 0; i < maxcollections; i++) { + for (j = 0; j < maxcollections; j++) + memory->destroy(stencil_multi[i][j]); + delete [] stencil_multi[i]; } - } + delete [] stencil_multi; + memory->destroy(maxstencil_multi); + memory->destroy(flag_half_multi); + memory->destroy(flag_skip_multi); + memory->destroy(bin_collection_multi); + memory->destroy(stencil_sx_multi); + memory->destroy(stencil_sy_multi); + memory->destroy(stencil_sz_multi); + memory->destroy(stencil_binsizex_multi); + memory->destroy(stencil_binsizey_multi); + memory->destroy(stencil_binsizez_multi); + memory->destroy(stencil_mbinx_multi); + memory->destroy(stencil_mbiny_multi); + memory->destroy(stencil_mbinz_multi); + } - // Determine which stencils need to be built - set_stencil_properties(); - - // Allocate arrays to store stencils - if (!maxstencil_multi) { + // Allocate arrays + if(!maxstencil_multi) { + memory->create(flag_half_multi, n, n, + "neighstencil:flag_half_multi"); + memory->create(flag_skip_multi, n, n, + "neighstencil:flag_skip_multi"); + memory->create(bin_collection_multi, n, n, + "neighstencil:bin_collection_multi"); + + memory->create(stencil_sx_multi, n, n, + "neighstencil:stencil_sx_multi"); + memory->create(stencil_sy_multi, n, n, + "neighstencil:stencil_sy_multi"); + memory->create(stencil_sz_multi, n, n, + "neighstencil:stencil_sz_multi"); + + memory->create(stencil_binsizex_multi, n, n, + "neighstencil:stencil_binsizex_multi"); + memory->create(stencil_binsizey_multi, n, n, + "neighstencil:stencil_binsizey_multi"); + memory->create(stencil_binsizez_multi, n, n, + "neighstencil:stencil_binsizez_multi"); + + memory->create(stencil_mbinx_multi, n, n, + "neighstencil:stencil_mbinx_multi"); + memory->create(stencil_mbiny_multi, n, n, + "neighstencil:stencil_mbiny_multi"); + memory->create(stencil_mbinz_multi, n, n, + "neighstencil:stencil_mbinz_multi"); + memory->create(maxstencil_multi, n, n, "neighstencil::maxstencil_multi"); memory->create(nstencil_multi, n, n, "neighstencil::nstencil_multi"); stencil_multi = new int**[n](); @@ -326,12 +338,22 @@ void NStencil::create_setup() nstencil_multi[i][j] = 0; stencil_multi[i][j] = nullptr; } + } + maxcollections = n; + } + + // Skip all stencils by default, initialize smax + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + flag_skip_multi[i][j] = 1; } - } + } + + // Determine which stencils need to be built + set_stencil_properties(); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { - // Skip creation of unused stencils if (flag_skip_multi[i][j]) continue; @@ -364,7 +386,8 @@ void NStencil::create_setup() if (smax > maxstencil_multi[i][j]) { maxstencil_multi[i][j] = smax; - memory->destroy(stencil_multi[i][j]); + if(stencil_multi[i][j]) + memory->destroy(stencil_multi[i][j]); memory->create(stencil_multi[i][j], smax, "neighstencil::stencil_multi"); } diff --git a/src/nstencil.h b/src/nstencil.h index 37cedec045..6e8c2da97c 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -33,6 +33,7 @@ class NStencil : protected Pointers { int ** nstencil_multi; // # bins bins in each igroup-jgroup multi stencil int *** stencil_multi; // list of bin offsets in each multi stencil int ** maxstencil_multi; // max stencil size for each multi stencil + int maxcollections; // size of multi arrays int sx,sy,sz; // extent of stencil in each dim int **stencil_sx_multi; // analogs for each multi stencil @@ -42,7 +43,7 @@ class NStencil : protected Pointers { double cutoff_custom; // cutoff set by requestor // Arrays to store options for multi itype-jtype stencils - bool **flag_half_multi; // flag creation of a half stencil for igroup-jgroup + bool **flag_half_multi; // flag creation of a half stencil for icollection-jcollection bool **flag_skip_multi; // skip creation of icollection-jcollection stencils (for newton on) int **bin_collection_multi; // what collection to use for bin information diff --git a/src/nstencil_half_multi_2d.cpp b/src/nstencil_half_multi_2d.cpp index 57352c7c6f..32ee0297ff 100644 --- a/src/nstencil_half_multi_2d.cpp +++ b/src/nstencil_half_multi_2d.cpp @@ -71,7 +71,7 @@ void NStencilHalfMulti2d::create() if (flag_skip_multi[icollection][jcollection]) continue; ns = 0; - + sx = stencil_sx_multi[icollection][jcollection]; sy = stencil_sy_multi[icollection][jcollection];