#include #include #include #include #include #include "cctk.h" #include "util_Table.h" #include "bbox.hh" #include "bboxset.hh" #include "dh.hh" #include "gdata.hh" #include "gh.hh" #include "ggf.hh" #include "vect.hh" #include "carpet.hh" #include "mapping.hh" #include "slab.hh" namespace CarpetSlab { using namespace std; using namespace Carpet; void FillSlab (const cGH* const cgh, const int dest_proc, const int n, const int ti, const int hdim, const int origin[/*vdim*/], const int dirs[/*hdim*/], const int stride[/*hdim*/], const int length[/*hdim*/], void* const hdata) { int ierr; // Check Cactus grid hierarchy assert (cgh); // Check destination processor assert (dest_proc>=-1 && dest_proc=0 && n=0); const int n0 = CCTK_FirstVarIndexI(group); assert (n0>=0); const int var = n - n0; assert (var>=0); // Get info about group cGroup gp; ierr = CCTK_GroupData (group, &gp); assert (! ierr); assert (gp.dim<=dim); assert (CCTK_QueryGroupStorageI(cgh, group)); const int typesize = CCTK_VarTypeSize(gp.vartype); assert (typesize>0); if (gp.grouptype==CCTK_GF && reflevel==-1) { CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in meta mode or global mode (use singlemap mode instead)"); } const int rl = gp.grouptype==CCTK_GF ? reflevel : 0; assert (rl>=0); if (gp.grouptype==CCTK_GF && Carpet::map==-1 && maps>1) { CCTK_WARN (0, "It is not possible to use hyperslabbing for a grid function in level mode when there are multiple maps (use singlemap mode instead, or make sure that there is only one map)"); } const int m = gp.grouptype==CCTK_GF ? (maps>1 ? Carpet::map : 0) : 0; assert (m>=0); const int oldmap = Carpet::map; if (gp.grouptype==CCTK_GF && oldmap==-1) { enter_singlemap_mode(const_cast(cgh), m); } // Check dimension assert (hdim>=0 && hdim<=gp.dim); // Get more info about group cGroupDynamicData gd; ierr = CCTK_GroupDynamicData (cgh, group, &gd); assert (! ierr); const vect sizes = vect::ref(gd.gsh); for (int d=0; d= 0); } // Check timelevel const int num_tl = gp.numtimelevels; assert (ti>=0 && ti=0 && origin[d]<=sizes[d]); } // Check directions for (int dd=0; dd=1 && dirs[dd]<=dim); } // Check stride for (int dd=0; dd0); } // Check length for (int dd=0; dd=0); } // Check extent for (int dd=0; dd* myhh; const dh* mydd; const ggf* myff; assert (group < (int)arrdata.size()); myhh = arrdata.at(group).at(m).hh; assert (myhh); mydd = arrdata.at(group).at(m).dd; assert (mydd); assert (var < (int)arrdata.at(group).at(m).data.size()); myff = arrdata.at(group).at(m).data.at(var); assert (myff); // Detemine collecting processor const int collect_proc = dest_proc<0 ? 0 : dest_proc; // Determine own rank const int rank = CCTK_MyProc(cgh); // Sanity check // (if this fails, someone requested an insane number of grid points) { int max = INT_MAX; for (int dd=0; dd= 0 && length[dd] <= max); if (length[dd] > 0) max /= length[dd]; } assert (typesize <= max); } // Calculate global size int totalsize = 1; for (int dd=0; dd* mydata; mydata = (*myff)(tl, rl, 0, 0); // Stride of data in memory const vect str = mydata->extent().stride(); // Stride of collected data vect hstr = str; for (int dd=0; dd hlb(0); for (int d=0; d hub = hlb; for (int dd=0; dd hextent (hlb, hub, hstr); assert (hextent.size() == totalsize); // Create collector data object void* myhdata = rank==collect_proc ? hdata : 0; gdata* const alldata = mydata->make_typed(-1); alldata->allocate (hextent, collect_proc, myhdata); // Done with the temporary stuff mydata = 0; for (comm_state state; !state.done(); state.step()) { // Loop over all components, copying data from them BEGIN_LOCAL_COMPONENT_LOOP (cgh, gp.grouptype) { // Get data object mydata = (*myff)(tl, rl, component, mglevel); // Calculate overlapping extents const bboxset myextents = ((mydd->boxes.at(rl).at(component).at(mglevel).sync_not | mydd->boxes.at(rl).at(component).at(mglevel).interior) & hextent); // Loop over overlapping extents for (bboxset::const_iterator ext_iter = myextents.begin(); ext_iter != myextents.end(); ++ext_iter) { // Copy data alldata->copy_from (state, mydata, *ext_iter); } } END_LOCAL_COMPONENT_LOOP; } // for step // Copy result to all processors if (dest_proc == -1) { vector*> tmpdata(CCTK_nProcs(cgh)); vector > state; for (int proc=0; procmake_typed(-1); tmpdata.at(proc)->allocate (alldata->extent(), proc, myhdata); tmpdata.at(proc)->copy_from (state.at(proc), alldata, alldata->extent()); } } for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); } } for (int proc=0; proccopy_from (state.at(proc), alldata, alldata->extent()); delete tmpdata.at(proc); } } } // Copy result if (gp.grouptype==CCTK_GF && oldmap==-1) { leave_singlemap_mode(const_cast(cgh)); } delete alldata; } } // namespace CarpetSlab