aboutsummaryrefslogtreecommitdiff
path: root/Carpet
diff options
context:
space:
mode:
authorswhite <schnetter@cct.lsu.edu>2004-12-07 21:47:00 +0000
committerswhite <schnetter@cct.lsu.edu>2004-12-07 21:47:00 +0000
commit9222506d2a3f26a4f0f4cbe4d331c24e935dbf57 (patch)
tree1a1ee8cf1e8e017555062e980f67490a44c79768 /Carpet
parent27642f841969f3ad3d821db9cbb5e5778dcf102f (diff)
SetupGH.cc decomposed long SetupGH function
Broke up SetupGH function into smaller subroutines. Got it down to a single page, but its offspring 'allocate_map' needs further work. darcs-hash:20041207214705-32473-16294512e93ed1ad45e85b57285e2cf9f0b7da3c.gz
Diffstat (limited to 'Carpet')
-rw-r--r--Carpet/Carpet/src/SetupGH.cc1348
1 files changed, 755 insertions, 593 deletions
diff --git a/Carpet/Carpet/src/SetupGH.cc b/Carpet/Carpet/src/SetupGH.cc
index b2793943c..71df9289d 100644
--- a/Carpet/Carpet/src/SetupGH.cc
+++ b/Carpet/Carpet/src/SetupGH.cc
@@ -36,7 +36,7 @@ namespace Carpet {
- static bool CanTransferVariableType (const cGH * const cgh, const int group)
+ static bool CanTransferVariableType (const cGH* const cgh, const int group)
{
// Find out which types correspond to the default types
#if CCTK_INTEGER_PRECISION_1
@@ -64,11 +64,13 @@ namespace Carpet {
# error "Unsupported default real type"
#endif
- if (CCTK_NumVarsInGroupI(group) == 0) return true;
+ if (CCTK_NumVarsInGroupI(group) == 0)
+ return true;
const int var0 = CCTK_FirstVarIndexI(group);
const int type0 = CCTK_VarTypeI(var0);
int type1;
+
switch (type0) {
case CCTK_VARIABLE_INT:
type1 = CCTK_DEFAULT_INTEGER_TYPE;
@@ -136,10 +138,9 @@ namespace Carpet {
// not reached
return false;
}
+
-
-
- static operator_type GetTransportOperator (const cGH * const cgh,
+ static operator_type GetTransportOperator (const cGH* const cgh,
const int group)
{
assert (group>=0 && group<CCTK_NumGroups());
@@ -192,7 +193,8 @@ namespace Carpet {
if (have_prolong_string && have_prolong_param_string) {
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has both the tags \"Prolongation\" and \"ProlongationParameter\". This is not possible.",
+ "Group \"%s\" has both the tags \"Prolongation\" and "
+ "\"ProlongationParameter\". This is not possible.",
groupname);
free (groupname);
}
@@ -205,7 +207,8 @@ namespace Carpet {
if (ierr < 0) {
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\". This is not a valid parameter name.",
+ "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\"."
+ " This is not a valid parameter name.",
groupname, prolong_param_string);
free (groupname);
}
@@ -216,14 +219,16 @@ namespace Carpet {
if (! value || ! *value) {
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\". This parameter does not exist.",
+ "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\"."
+ " This parameter does not exist.",
groupname, prolong_param_string);
free (groupname);
}
if (type != PARAMETER_KEYWORD && type != PARAMETER_STRING) {
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\". This parameter has the wrong type; it must be either KEYWORD or STRING.",
+ "Group \"%s\" has the \"ProlongationParameter\" tag \"%s\"." " This parameter has the wrong type; "
+ "it must be either KEYWORD or STRING.",
groupname, prolong_param_string);
free (groupname);
}
@@ -242,7 +247,8 @@ namespace Carpet {
// Only one time level: do not prolongate
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has only one time level; therefore it will not be prolongated or restricted.",
+ "Group \"%s\" has only one time level; therefore it "
+ "will not be prolongated or restricted.",
groupname);
free (groupname);
return op_none;
@@ -254,7 +260,8 @@ namespace Carpet {
if (gp.grouptype == CCTK_GF) {
char * const groupname = CCTK_GroupName (group);
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has the variable type \"%s\" which cannot be prolongated or restricted.",
+ "Group \"%s\" has the variable type \"%s\" which cannot "
+ "be prolongated or restricted.",
groupname, CCTK_VarTypeName(gp.vartype));
free (groupname);
return op_none;
@@ -286,270 +293,682 @@ namespace Carpet {
}
+ static void initialise_current_position ();
+ static void finalise_current_position ();
+ static void setup_multigrid_info (cGH* cgh, CCTK_INT convergence_level,
+ CCTK_INT convergence_factor,
+ CCTK_INT num_convergence_levels);
+ static void setup_refinement_level_info (CCTK_INT max_refinement_levels,
+ CCTK_INT refinement_factor);
+ static void allocate_map(cGH* cgh, int m,
+ CCTK_INT domain_from_coordbase,
+ CCTK_INT convergence_factor, CCTK_INT refinement_factor,
+ CCTK_STRING base_outerbounds, CCTK_STRING base_extents,
+ CCTK_INT max_refinement_levels,
+ CCTK_INT buffer_width, CCTK_INT prolongation_order_space,
+ ivect & lghosts, ivect & ughosts, ivect & npoints);
+ static ivect make_ghost_zone_vect (CCTK_INT ghost_size,
+ CCTK_INT ghost_size_x, CCTK_INT ghost_size_y,
+ CCTK_INT ghost_size_z);
+ static ivect make_global_number_of_grid_points (CCTK_INT global_nsize,
+ CCTK_INT global_nx, CCTK_INT global_ny, CCTK_INT global_nz);
+ static void check_time_hierarchy (const vector<dh<dim>*> &vdd, int m,
+ CCTK_INT max_refinement_levels,
+ CCTK_INT refinement_factor,
+ CCTK_INT prolongation_order_space,
+ const ivect & lghosts, const ivect & ughosts);
+ static void read_explicit_grid_components (CCTK_STRING base_extents,
+ CCTK_STRING base_outerbounds,
+ vector<ibbox> & bbs, vector<bbvect> & obs);
+ static void check_domain_size (const rvect &npoints,
+ const rvect &real_npoints, int m,
+ CCTK_INT basemglevel, CCTK_INT convergence_factor);
+ static void Sanity_check (const ivect & npoints);
+ static void print_map_base_grid_spec (int m, const rvect & real_npoints,
+ ivect &lghosts);
+ static void print_map_coordbase_boundary_specs (int m,
+ jjvect &nboundaryzones, jjvect & is_internal,
+ jjvect &is_staggered, jjvect & shiftout);
+ static void print_map_domain_specs (int m,
+ rvect & physical_min, rvect & physical_max,
+ rvect & interior_min, rvect & interior_max,
+ rvect & exterior_min, rvect & exterior_max,
+ rvect & base_spacing);
+ static void print_map_adapted_domain_specs (int m,
+ CCTK_INT convergence_factor,
+ CCTK_INT basemglevel,
+ rvect & physical_min, rvect & physical_max,
+ rvect & interior_min, rvect & interior_max,
+ rvect & exterior_min, rvect & exterior_max,
+ const rvect & spacing);
+ static void allocate_group_variables (cGH* cgh, int group,
+ CCTK_INT convergence_factor, CCTK_INT refinement_factor);
+ static void handle_group_tags_table (cGH* cgh, int group, cGroup &gp,
+ jvect &convpowers, jvect &convoffsets);
+ static void finish_initialisation (cGH* cgh);
+ static void print_grid_structure (vector<gh<dim>*> & vhh, int m);
+ static void print_some_statistics (cGH* cgh);
+ static void enable_storage_for_all_groups (cGH* cgh);
+ static void leave_all_modes (cGH* cgh);
+
void* SetupGH (tFleshConfig* fc, int convLevel, cGH* cgh)
{
DECLARE_CCTK_PARAMETERS;
- int ierr;
-
assert (cgh->cctk_dim == dim);
// Not sure what to do with that
assert (convLevel==0);
dist::pseudoinit();
-
- // Initialise current position
- mglevel = -1;
- reflevel = -1;
- map = -1;
- component = -1;
-
-
+
+ initialise_current_position ();
Waypoint ("Setting up the grid hierarchy");
// Processor information
Output ("Carpet is running on %d processors", CCTK_nProcs(cgh));
- // Multigrid information
+ setup_multigrid_info ( cgh, convergence_level, convergence_factor,
+ num_convergence_levels );
+
+ setup_refinement_level_info ( max_refinement_levels, refinement_factor );
+
+ // Map information
+ carpetGH.maps = maps = num_maps;
+
+ // Allocate space for groups
+ groupdata.resize (CCTK_NumGroups());
+ arrdata.resize (CCTK_NumGroups());
+
+ vhh.resize (maps);
+ vdd.resize (maps);
+ vtt.resize (maps);
+
+ // Loop over maps
+ for (int m=0; m<maps; ++m) {
+ ivect lghosts = make_ghost_zone_vect (ghost_size,
+ ghost_size_x, ghost_size_y, ghost_size_z);
+ ivect ughosts = lghosts;
+ ivect npoints = make_global_number_of_grid_points (global_nsize,
+ global_nx, global_ny, global_nz);
+
+ allocate_map (cgh, m, domain_from_coordbase,
+ convergence_factor, refinement_factor,
+ base_outerbounds, base_extents,
+ max_refinement_levels, buffer_width, prolongation_order_space,
+ lghosts, ughosts, npoints);
+ }
+
+ reflevels = 1;
+ for (int m=0; m<maps; ++m) {
+ assert (vhh.at(m)->reflevels() == reflevels);
+ }
+
+ for (int group=0; group<CCTK_NumGroups(); ++group) {
+ allocate_group_variables (cgh, group,
+ convergence_factor, refinement_factor);
+ }
+
+ // Allocate level times
+ leveltimes.resize (mglevels);
+ for (int ml=0; ml<mglevels; ++ml) {
+ leveltimes.at(ml).resize (maxreflevels);
+ }
+ origin_space.resize (mglevels);
+
+ // Enable prolongating
+ do_prolongate = true;
+
+ finish_initialisation (cgh);
+
+ finalise_current_position ();
+
+ leave_all_modes (cgh);
+
+ if (verbose || veryverbose) {
+ print_some_statistics (cgh);
+ }
+
+ if (enable_all_storage) {
+ enable_storage_for_all_groups (cgh);
+ }
+
+ Waypoint ("Done with setting up the grid hierarchy");
+
+ return &carpetGH;
+ }
+
+ void initialise_current_position () {
+ mglevel = -1;
+ reflevel = -1;
+ map = -1;
+ component = -1;
+ }
+
+ void finalise_current_position () {
+ mglevel = 0;
+ reflevel = 0;
+ map = 0;
+ component = 0;
+ }
+
+ void finish_initialisation (cGH* cgh) {
+ mglevelfact = 1;
+ cgh->cctk_time = 0;
+ cgh->cctk_delta_time = 1.0;
+ for (int d=0; d<dim; ++d) {
+ cgh->cctk_origin_space[d] = 0.0;
+ cgh->cctk_delta_space[d] = 1.0;
+ }
+ }
+
+ void setup_multigrid_info (cGH* cgh, CCTK_INT convergence_level,
+ CCTK_INT convergence_factor,
+ CCTK_INT num_convergence_levels) {
basemglevel = convergence_level;
mglevels = num_convergence_levels;
mgfact = convergence_factor;
maxmglevelfact = ipow(mgfact, mglevels-1);
cgh->cctk_convfac = mgfact;
-
- // Refinement information
+ }
+
+ void setup_refinement_level_info (CCTK_INT max_refinement_levels,
+ CCTK_INT refinement_factor) {
maxreflevels = max_refinement_levels;
reffact = refinement_factor;
maxreflevelfact = ipow(reffact, maxreflevels-1);
+ }
+
+ void allocate_map (cGH* cgh, int m,
+ CCTK_INT domain_from_coordbase,
+ CCTK_INT convergence_factor, CCTK_INT refinement_factor,
+ CCTK_STRING base_outerbounds, CCTK_STRING base_extents,
+ CCTK_INT max_refinement_levels,
+ CCTK_INT buffer_width, CCTK_INT prolongation_order_space,
+ ivect & lghosts, ivect & ughosts, ivect & a_npoints) {
+ // Get boundary description
+ jjvect nboundaryzones, is_internal, is_staggered, shiftout;
+ int ierr = GetBoundarySpecification (2*dim, &nboundaryzones[0][0],
+ &is_internal[0][0], &is_staggered[0][0], &shiftout[0][0]);
+ assert (!ierr);
- // Map information
- carpetGH.maps = maps = num_maps;
+ print_map_coordbase_boundary_specs (m, nboundaryzones, is_internal,
+ is_staggered, shiftout);
+ // Grid size
+ rvect physical_min, physical_max;
+ rvect interior_min, interior_max;
+ rvect exterior_min, exterior_max;
+ rvect base_spacing;
+ if (domain_from_coordbase) {
+
+ ierr = GetDomainSpecification (dim, &physical_min[0], &physical_max[0],
+ &interior_min[0], &interior_max[0],
+ &exterior_min[0], &exterior_max[0], &base_spacing[0]);
+ assert (!ierr);
+
+ } else {
+ // Legacy code
+ ivect & npoints = a_npoints;
+ ostringstream buf;
+ buf << "Standard grid specification for map " << m << ":" << endl
+ << " number of grid points: " << npoints;
+ Output (buf.str().c_str());
+
+ // reduce to physical domain
+ exterior_min = 0.0;
+ exterior_max = rvect (npoints - 1);
+ base_spacing = 1.0;
+ ierr = ConvertFromExteriorBoundary
+ (dim, &physical_min[0], &physical_max[0],
+ &interior_min[0], &interior_max[0],
+ &exterior_min[0], &exterior_max[0], &base_spacing[0]);
+ assert (!ierr);
+
+ }
- // Allocate space for groups
- groupdata.resize(CCTK_NumGroups());
- arrdata.resize(CCTK_NumGroups());
+ print_map_domain_specs (m, physical_min, physical_max,
+ interior_min, interior_max, exterior_min, exterior_max, base_spacing);
+
+ // Adapt for convergence level
+ rvect const spacing
+ = base_spacing * pow (CCTK_REAL (convergence_factor), basemglevel);
+
+ // Calculate global number of grid points
+ // SW note this and other examples break the encapsulation of vect class
+ // besides being ugly. ConvertFromPhysicalBoundary is from CarpetRegrid
+ ierr = ConvertFromPhysicalBoundary (dim, &physical_min[0], &physical_max[0],
+ &interior_min[0], &interior_max[0],
+ &exterior_min[0], &exterior_max[0], &spacing[0]);
+ assert (!ierr);
- vhh.resize(maps);
- vdd.resize(maps);
- vtt.resize(maps);
+ print_map_adapted_domain_specs (m, convergence_factor, basemglevel,
+ physical_min, physical_max, interior_min, interior_max,
+ exterior_min, exterior_max, spacing);
- // Loop over maps
- for (int m=0; m<maps; ++m) {
+ rvect const real_npoints = (exterior_max - exterior_min) / spacing + 1;
+
+ print_map_base_grid_spec (m, real_npoints, lghosts);
+
+ const ivect npoints = floor (real_npoints + 0.5);
+ check_domain_size (npoints, real_npoints,
+ m, basemglevel, convergence_factor);
+
+ Sanity_check (npoints);
+
+ // Base grid extent
+ const int stride = maxreflevelfact;
+ const ivect str (stride);
+ const ivect lb (0);
+ const ivect ub ((npoints - 1) * str);
+ const ibbox baseext (lb, ub, str);
+
+ // Allocate grid hierarchy
+ vhh.at(m) = new gh<dim> (refinement_factor, vertex_centered,
+ convergence_factor, vertex_centered, baseext);
+
+ // Allocate data hierarchy
+ vdd.at(m) = new dh<dim> (*vhh.at(m), lghosts, ughosts,
+ prolongation_order_space, buffer_width);
+
+ // Allocate time hierarchy
+ vtt.at(m) = new th<dim> (*vhh.at(m), 1.0);
- // Get boundary description
- jjvect nboundaryzones, is_internal, is_staggered, shiftout;
- ierr = GetBoundarySpecification
- (2*dim, &nboundaryzones[0][0], &is_internal[0][0],
- &is_staggered[0][0], &shiftout[0][0]);
- assert (!ierr);
+ check_time_hierarchy (vdd, m, max_refinement_levels, refinement_factor,
+ prolongation_order_space, lghosts, ughosts);
+
+ // Set initial refinement structure
- {
- ostringstream buf;
- buf << "CoordBase boundary specification for map " << m << ":" << endl
- << " nboundaryzones: " << nboundaryzones << endl
- << " is_internal : " << is_internal << endl
- << " is_staggered : " << is_staggered << endl
- << " shiftout : " << shiftout;
- Output (buf.str().c_str());
- }
+ vector<ibbox> bbs;
+ vector<bbvect> obs;
+ if (strcmp(base_extents, "") == 0) {
- // Ghost zones
- ivect lghosts, ughosts;
- if (ghost_size == -1) {
- lghosts = ivect(ghost_size_x, ghost_size_y, ghost_size_z);
- ughosts = ivect(ghost_size_x, ghost_size_y, ghost_size_z);
- } else {
- lghosts = ivect(ghost_size, ghost_size, ghost_size);
- ughosts = ivect(ghost_size, ghost_size, ghost_size);
- }
+ // default: one grid component covering everything
+ bbs.push_back (vhh.at(m)->baseextent);
+ obs.push_back (bbvect(true));
- // Grid size
- rvect physical_min, physical_max;
- rvect interior_min, interior_max;
- rvect exterior_min, exterior_max;
- rvect base_spacing;
+ } else {
- if (domain_from_coordbase) {
-
- ierr = GetDomainSpecification
- (dim, &physical_min[0], &physical_max[0],
- &interior_min[0], &interior_max[0],
- &exterior_min[0], &exterior_max[0], &base_spacing[0]);
- assert (!ierr);
+ read_explicit_grid_components (base_extents, base_outerbounds, bbs, obs);
+ }
+
+ // Distribute onto the processors
+ // (TODO: this should be done globally for all maps)
+ vector<int> ps;
+ SplitRegions (cgh, bbs, obs, ps);
+
+ // Create all multigrid levels
+ vector<vector<ibbox> > bbss;
+ MakeMultigridBoxes (cgh, bbs, obs, bbss);
+
+ // Only one refinement level
+ vector<vector<vector<ibbox> > > bbsss(1);
+ vector<vector<bbvect> > obss(1);
+ vector<vector<int> > pss(1);
+ bbsss.at(0) = bbss;
+ obss.at(0) = obs;
+ pss.at(0) = ps;
+
+ // Check the regions
+ CheckRegions (bbsss, obss, pss);
+
+#if 0
+ // Do this later, because CactusBase/IO might not yet be initialised
+ // Write grid structure to file
+ OutputGridStructure (cgh, m, bbsss, obss, pss);
+#endif
+
+ // Recompose grid hierarchy
+ vhh.at(m)->recompose (bbsss, obss, pss, false);
+
+ CCTK_INFO ("Grid structure (grid points):");
+ print_grid_structure (vhh, m);
+
+ }
+
+ ivect make_global_number_of_grid_points (CCTK_INT global_nsize,
+ CCTK_INT global_nx, CCTK_INT global_ny, CCTK_INT global_nz) {
+ if (global_nsize == -1) {
+ return ivect (global_nx, global_ny, global_nz);
+ } else {
+ return ivect (global_nsize, global_nsize, global_nsize);
+ }
+ }
+
+ ivect make_ghost_zone_vect (CCTK_INT ghost_size,
+ CCTK_INT ghost_size_x, CCTK_INT ghost_size_y, CCTK_INT ghost_size_z) {
+ if( ghost_size == -1 )
+ return ivect (ghost_size_x, ghost_size_y, ghost_size_z);
+ else
+ return ivect (ghost_size, ghost_size, ghost_size);
+ }
+
+ void print_map_base_grid_spec (int m,
+ const rvect & real_npoints, ivect &lghosts) {
+ ostringstream buf;
+ buf << "Base grid specification for map " << m << ":" << endl
+ << " number of grid points : " << real_npoints << endl
+ << " number of ghost points: " << lghosts;
+ Output (buf.str().c_str());
+ }
+
+ void print_map_coordbase_boundary_specs (int m, jjvect &nboundaryzones,
+ jjvect & is_internal, jjvect &is_staggered, jjvect & shiftout) {
+ ostringstream buf;
+ buf << "CoordBase boundary specification for map " << m << ":" << endl
+ << " nboundaryzones: " << nboundaryzones << endl
+ << " is_internal : " << is_internal << endl
+ << " is_staggered : " << is_staggered << endl
+ << " shiftout : " << shiftout;
+ Output (buf.str().c_str());
+ }
+
+ void print_map_domain_specs(int m,
+ rvect & physical_min, rvect & physical_max,
+ rvect & interior_min, rvect & interior_max,
+ rvect & exterior_min, rvect & exterior_max,
+ rvect & base_spacing) {
+ ostringstream buf;
+ buf << "CoordBase domain specification for map " << m << ":" << endl
+ << " physical extent: " << physical_min << " : " << physical_max
+ << " (" << physical_max - physical_min << ")" << endl
+ << " interior extent: " << interior_min << " : " << interior_max
+ << " (" << interior_max - interior_min << ")" << endl
+ << " exterior extent: " << exterior_min << " : " << exterior_max
+ << " (" << exterior_max - exterior_min << ")" << endl
+ << " base_spacing : " << base_spacing;
+ Output (buf.str().c_str());
+ }
+
+ void print_map_adapted_domain_specs (int m, CCTK_INT convergence_factor,
+ CCTK_INT basemglevel,
+ rvect & physical_min, rvect & physical_max,
+ rvect & interior_min, rvect & interior_max,
+ rvect & exterior_min, rvect & exterior_max,
+ const rvect & spacing) {
+ ostringstream buf;
+ buf << "Adapted domain specification for map " << m << ":" << endl
+ << " convergence factor: " << convergence_factor << endl
+ << " convergence level : " << basemglevel << endl
+ << " physical extent : " << physical_min << " : " << physical_max
+ << " (" << physical_max - physical_min << ")" << endl
+ << " interior extent : " << interior_min << " : " << interior_max
+ << " (" << interior_max - interior_min << ")" << endl
+ << " exterior extent : " << exterior_min << " : " << exterior_max
+ << " (" << exterior_max - exterior_min << ")" << endl
+ << " spacing : " << spacing;
+ Output (buf.str().c_str());
+ }
+
+ void check_domain_size (const rvect &npoints, const rvect &real_npoints,
+ int m, CCTK_INT basemglevel, CCTK_INT convergence_factor) {
+ if (any (abs (rvect (npoints) - real_npoints) > 0.001)) {
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The domain size for map %d scaled for convergence level %d "
+ "with convergence factor %d is not integer",
+ m, basemglevel, convergence_factor);
+ }
+ }
+
+ // If this fails, someone requested an insane amount of memory
+ void Sanity_check (const ivect & npoints) {
+ assert (all(npoints <= INT_MAX));
+ int max = INT_MAX;
+ for (int d=0; d<dim; ++d) {
+ assert (npoints[d] <= max);
+ max /= npoints[d];
+ }
+ }
+
+ void check_time_hierarchy (const vector<dh<dim>*> &vdd, int m,
+ CCTK_INT max_refinement_levels,
+ CCTK_INT refinement_factor,
+ CCTK_INT prolongation_order_space,
+ const ivect & lghosts, const ivect & ughosts) {
+ if (max_refinement_levels > 1) {
+ const int prolongation_stencil_size
+ = vdd.at(m)->prolongation_stencil_size();
+ const int min_nghosts
+ = ((prolongation_stencil_size + refinement_factor - 1)
+ / (refinement_factor-1));
+ if (any(min(lghosts,ughosts) < min_nghosts)) {
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "There are not enough ghost zones for the desired "
+ "spatial prolongation order on map %d. "
+ "With Carpet::prolongation_order_space=%d, you need at "
+ "least %d ghost zones.",
+ m, prolongation_order_space, min_nghosts);
+ }
+
+ }
+ }
+
+ void read_explicit_grid_components (CCTK_STRING base_extents,
+ CCTK_STRING base_outerbounds,
+ vector<ibbox> & bbs, vector<bbvect> & obs) {
+ // TODO: invent something for the other convergence levels
+ istringstream ext_str (base_extents);
+ try {
+ ext_str >> bbs;
+ } catch (input_error) {
+ CCTK_WARN (0, "Could not parse parameter \"base_extents\"");
+ }
+ CCTK_VInfo (CCTK_THORNSTRING, "Using %d grid patches", bbs.size());
+ cout << "grid-patches-are " << bbs << endl;
+ if (bbs.size()<=0) {
+ CCTK_WARN (0, "Cannot evolve with 0 grid patches");
+ }
+ istringstream ob_str (base_outerbounds);
+ try {
+ ob_str >> obs;
+ } catch (input_error) {
+ CCTK_WARN (0, "Could not parse parameter \"base_outerbounds\"");
+ }
+ assert (obs.size() == bbs.size());
+ }
+
+ void print_grid_structure (vector<gh<dim>*> & vhh, int m) {
+ const int rl = 0;
+ for (int c=0; c<vhh.at(m)->components(rl); ++c) {
+ for (int ml=0; ml<vhh.at(m)->mglevels(rl,c); ++ml) {
+ const ivect lower = vhh.at(m)->extents.at(rl).at(c).at(ml).lower();
+ const ivect upper = vhh.at(m)->extents.at(rl).at(c).at(ml).upper();
+ const int convfact = ipow(mgfact, ml);
+ assert (all(lower % maxreflevelfact == 0));
+ assert (all(upper % maxreflevelfact == 0));
+ assert (all(((upper - lower) / maxreflevelfact) % convfact == 0));
+ cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]"
+ << " exterior extent: " << lower / maxreflevelfact
+ << " : " << upper / maxreflevelfact
+ << " (" << (upper - lower) / maxreflevelfact / convfact + 1
+ << ")" << endl;
+ }
+ }
+ }
+
+ // Allocate space for variables in group (but don't enable storage
+ // yet)
+ static void allocate_group_variables (cGH* cgh, int group,
+ CCTK_INT convergence_factor, CCTK_INT refinement_factor) {
+ cGroup gp;
+ int ierr = CCTK_GroupData (group, &gp);
+ assert (!ierr);
+
+ switch (gp.grouptype) {
+
+ case CCTK_GF: {
+ assert (gp.dim == dim);
+ arrdata.at(group).resize(maps);
+ for (int m=0; m<maps; ++m) {
+ arrdata.at(group).at(m).hh = vhh.at(m);
+ arrdata.at(group).at(m).dd = vdd.at(m);
+ arrdata.at(group).at(m).tt = vtt.at(m);
+ }
+ break;
+ }
- } else {
- // Legacy code
+ case CCTK_SCALAR:
+ case CCTK_ARRAY: {
- // specify global number of grid points
- ivect npoints;
- if (global_nsize == -1) {
- npoints = ivect(global_nx, global_ny, global_nz);
- } else {
- npoints = ivect(global_nsize, global_nsize, global_nsize);
+ arrdata.at(group).resize(1);
+
+ ivect sizes(1), ghostsizes(0);
+
+ switch (gp.grouptype) {
+
+ case CCTK_SCALAR:
+ // treat scalars as DIM=0, DISTRIB=const arrays
+ assert (gp.dim==0);
+ assert (gp.disttype == CCTK_DISTRIB_CONSTANT);
+ break;
+
+ case CCTK_ARRAY: {
+ assert (gp.dim>=1 || gp.dim<=dim);
+ const CCTK_INT * const * const sz = CCTK_GroupSizesI (group);
+ const CCTK_INT * const * const gsz = CCTK_GroupGhostsizesI (group);
+ for (int d=0; d<gp.dim; ++d) {
+ if (sz)
+ sizes[d] = *sz[d];
+ if (gsz)
+ ghostsizes[d] = *gsz[d];
}
- ostringstream buf;
- buf << "Standard grid specification for map " << m << ":" << endl
- << " number of grid points: " << npoints;
- Output (buf.str().c_str());
-
- // reduce to physical domain
- exterior_min = 0.0;
- exterior_max = rvect(npoints - 1);
- base_spacing = 1.0;
- ierr = ConvertFromExteriorBoundary
- (dim, &physical_min[0], &physical_max[0],
- &interior_min[0], &interior_max[0],
- &exterior_min[0], &exterior_max[0], &base_spacing[0]);
- assert (!ierr);
+ break;
+ }
+
+ default:
+ assert (0);
+ }
+ ivect alghosts(0), aughosts(0);
+ for (int d=0; d<gp.dim; ++d) {
+ alghosts[d] = ghostsizes[d];
+ aughosts[d] = ghostsizes[d];
}
-
- {
- ostringstream buf;
- buf << "CoordBase domain specification for map " << m << ":" << endl
- << " physical extent: " << physical_min << " : " << physical_max << " (" << physical_max - physical_min << ")" << endl
- << " interior extent: " << interior_min << " : " << interior_max << " (" << interior_max - interior_min << ")" << endl
- << " exterior extent: " << exterior_min << " : " << exterior_max << " (" << exterior_max - exterior_min << ")" << endl
- << " base_spacing : " << base_spacing;
- Output (buf.str().c_str());
+
+ // Adapt array sizes for convergence level
+ jvect convpowers (0);
+ jvect convoffsets (0);
+
+ if (gp.tagstable >= 0) {
+ handle_group_tags_table (cgh, group, gp, convpowers, convoffsets);
}
-
- // Adapt for convergence level
- rvect const spacing
- = base_spacing * pow (CCTK_REAL(convergence_factor), basemglevel);
-
- // Calculate global number of grid points
- ierr = ConvertFromPhysicalBoundary
- (dim, &physical_min[0], &physical_max[0],
- &interior_min[0], &interior_max[0],
- &exterior_min[0], &exterior_max[0], &spacing[0]);
- assert (!ierr);
-
- {
- ostringstream buf;
- buf << "Adapted domain specification for map " << m << ":" << endl
- << " convergence factor: " << convergence_factor << endl
- << " convergence level : " << basemglevel << endl
- << " physical extent : " << physical_min << " : " << physical_max << " (" << physical_max - physical_min << ")" << endl
- << " interior extent : " << interior_min << " : " << interior_max << " (" << interior_max - interior_min << ")" << endl
- << " exterior extent : " << exterior_min << " : " << exterior_max << " (" << exterior_max - exterior_min << ")" << endl
- << " spacing : " << spacing;
- Output (buf.str().c_str());
+
+ rvect real_sizes
+ = ((sizes - convoffsets)
+ / pow (rvect (convergence_factor), convpowers * basemglevel)
+ + convoffsets);
+ for (int d=gp.dim; d<dim; ++d) {
+ real_sizes[d] = sizes[d];
}
-
- rvect const real_npoints = (exterior_max - exterior_min) / spacing + 1;
-
- {
- ostringstream buf;
- buf << "Base grid specification for map " << m << ":" << endl
- << " number of grid points : " << real_npoints << endl
- << " number of ghost points: " << lghosts;
- Output (buf.str().c_str());
+ sizes = floor (real_sizes + 0.5);
+ if (any(sizes < 0)) {
+ char * const groupname = CCTK_GroupName (group);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The shape of group \"%s\" scaled for convergence level %d "
+ "with convergence factor %d is negative",
+ groupname, basemglevel, convergence_factor);
+ free (groupname);
}
-
- const ivect npoints = floor(real_npoints + 0.5);
- if (any(abs(rvect(npoints) - real_npoints) > 0.001)) {
+ if (any(abs(rvect(sizes) - real_sizes) > 0.001)) {
+ char * const groupname = CCTK_GroupName(group);
CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The domain size for map %d scaled for convergence level %d with convergence factor %d is not integer",
- m, basemglevel, convergence_factor);
+ "The shape of group \"%s\" scaled for convergence level %d "
+ "with convergence factor %d is not integer",
+ groupname, basemglevel, convergence_factor);
+ free (groupname);
}
-
- // Sanity check
- // (if this fails, someone requested an insane amount of memory)
- assert (all(npoints <= INT_MAX));
- {
- int max = INT_MAX;
- for (int d=0; d<dim; ++d) {
- assert (npoints[d] <= max);
- max /= npoints[d];
+
+ assert (gp.disttype==CCTK_DISTRIB_CONSTANT
+ || gp.disttype==CCTK_DISTRIB_DEFAULT);
+
+ if (gp.disttype==CCTK_DISTRIB_CONSTANT) {
+ if (! all (ghostsizes == 0)) {
+ char * const groupname = CCTK_GroupName (group);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The group \"%s\" has DISTRIB=constant, but its "
+ "ghostsize is not 0",
+ groupname);
+ free (groupname);
}
+ assert (all (ghostsizes == 0));
+ const int d = gp.dim==0 ? 0 : gp.dim-1;
+ sizes[d] = (sizes[d] - 2*ghostsizes[d]) * CCTK_nProcs (cgh)
+ + 2*ghostsizes[d];
+ assert (sizes[d] >= 0);
}
+
+ const ivect alb(0);
+ const ivect aub(sizes-1);
+ const ivect astr(1);
+ const ibbox abaseext(alb, aub, astr);
+ assert (all(convpowers == convpowers[0]));
+ const int amgfact1 = ipow(mgfact, convpowers[0]);
+ arrdata.at (group).at (0).hh
+ = new gh<dim> (refinement_factor, vertex_centered,
+ amgfact1, vertex_centered,
+ abaseext);
- // Base grid extent
- const int stride = maxreflevelfact;
- const ivect str(stride);
- const ivect lb(0);
- const ivect ub((npoints - 1) * str);
- const ibbox baseext(lb, ub, str);
-
- // Allocate grid hierarchy
- vhh.at(m) = new gh<dim>(refinement_factor, vertex_centered,
- convergence_factor, vertex_centered, baseext);
-
- // Allocate data hierarchy
- vdd.at(m) = new dh<dim>(*vhh.at(m), lghosts, ughosts,
- prolongation_order_space, buffer_width);
-
- // Allocate time hierarchy
- vtt.at(m) = new th<dim>(*vhh.at(m), 1.0);
-
- if (max_refinement_levels > 1) {
- const int prolongation_stencil_size
- = vdd.at(m)->prolongation_stencil_size();
- const int min_nghosts
- = ((prolongation_stencil_size + refinement_factor - 1)
- / (refinement_factor-1));
- if (any(min(lghosts,ughosts) < min_nghosts)) {
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "There are not enough ghost zones for the desired spatial prolongation order on map %d. With Carpet::prolongation_order_space=%d, you need at least %d ghost zones.",
- m, prolongation_order_space, min_nghosts);
- }
-
- }
-
+ arrdata.at (group).at (0).dd
+ = new dh<dim> (*arrdata.at (group).at (0).hh, alghosts, aughosts, 0, 0);
+ arrdata.at (group).at (0).tt
+ = new th<dim> (*arrdata.at (group).at (0).hh, 1.0);
+
- // Set initial refinement structure
+ // Set refinement structure for scalars and arrays
vector<ibbox> bbs;
vector<bbvect> obs;
- if (strcmp(base_extents, "") == 0) {
-
- // default: one grid component covering everything
- bbs.push_back (vhh.at(m)->baseextent);
- obs.push_back (bbvect(true));
-
- } else {
-
- // explicit grid components
- // TODO: invent something for the other convergence levels
- istringstream ext_str(base_extents);
- try {
- ext_str >> bbs;
- } catch (input_error) {
- CCTK_WARN (0, "Could not parse parameter \"base_extents\"");
- }
- CCTK_VInfo (CCTK_THORNSTRING, "Using %d grid patches", bbs.size());
- cout << "grid-patches-are " << bbs << endl;
- if (bbs.size()<=0) {
- CCTK_WARN (0, "Cannot evolve with 0 grid patches");
- }
- istringstream ob_str (base_outerbounds);
- try {
- ob_str >> obs;
- } catch (input_error) {
- CCTK_WARN (0, "Could not parse parameter \"base_outerbounds\"");
- }
- assert (obs.size() == bbs.size());
-
- }
+ bbs.push_back (abaseext);
+ obs.push_back (bbvect (true));
- // Distribute onto the processors
- // (TODO: this should be done globally for all maps)
+ // Split it into components, one for each processor
vector<int> ps;
- SplitRegions (cgh, bbs, obs, ps);
+ if (gp.disttype==CCTK_DISTRIB_CONSTANT) {
+ SplitRegions_AlongDir (cgh, bbs, obs, ps, gp.dim==0 ? 0 : gp.dim-1);
+ } else {
+ SplitRegions_Automatic (cgh, bbs, obs, ps);
+ }
// Create all multigrid levels
- vector<vector<ibbox> > bbss;
- MakeMultigridBoxes (cgh, bbs, obs, bbss);
-
+ vector<vector<ibbox> > bbss (bbs.size());
+ ivect amgfact;
+ iivect aoffset;
+ for (int d=0; d<dim; ++d) {
+ amgfact[d] = ipow (mgfact, convpowers[d]);
+ aoffset[d][0] = 0;
+ aoffset[d][1] = convoffsets[d];
+ }
+ for (size_t c=0; c<bbs.size(); ++c) {
+ bbss.at(c).resize (mglevels);
+ bbss.at(c).at(0) = bbs.at(c);
+ for (int ml=1; ml<mglevels; ++ml) {
+ // this base
+ ivect const baselo = ivect(0);
+ ivect const baselo1 = baselo;
+ // next finer grid
+ ivect const flo = bbss.at(c).at(ml-1).lower();
+ ivect const fhi = bbss.at(c).at(ml-1).upper();
+ ivect const fstr = bbss.at(c).at(ml-1).stride();
+ // this grid
+ ivect const str = fstr * amgfact;
+ ivect const lo = flo + xpose(obs.at(c))[0].ifthen
+ ( (xpose(aoffset)[0] - amgfact * xpose(aoffset)[0]) * fstr,
+ ivect(0));
+ ivect const hi = fhi + xpose(obs.at(c))[1].ifthen
+ ( - (xpose(aoffset)[1] - amgfact * xpose(aoffset)[1]) * fstr,
+ ivect(0));
+ ivect const lo1 = baselo1 + (lo - baselo1 + str - 1) / str * str;
+ ivect const hi1 = lo1 + (hi - lo1) / str * str;
+ bbss.at(c).at(ml) = ibbox(lo1, hi1, str);
+ }
+ }
+
// Only one refinement level
vector<vector<vector<ibbox> > > bbsss(1);
vector<vector<bbvect> > obss(1);
@@ -557,404 +976,147 @@ namespace Carpet {
bbsss.at(0) = bbss;
obss.at(0) = obs;
pss.at(0) = ps;
+
+ // Recompose for this map
+ char * const groupname = CCTK_GroupName (group);
+ assert (groupname);
+ Checkpoint ("Recomposing grid array group \"%s\"", groupname);
+ free (groupname);
+ arrdata.at(group).at(0).hh->recompose (bbsss, obss, pss, false);
+
+ break;
+ } // case of scalar or array
+
+ default:
+ assert (0);
+ } // switch on group type
- // Check the regions
- CheckRegions (bbsss, obss, pss);
+ // Initialise group information
+ groupdata.at(group).info.dim = gp.dim;
+ groupdata.at(group).info.gsh = new int [dim];
+ groupdata.at(group).info.lsh = new int [dim];
+ groupdata.at(group).info.lbnd = new int [dim];
+ groupdata.at(group).info.ubnd = new int [dim];
+ groupdata.at(group).info.bbox = new int [2*dim];
+ groupdata.at(group).info.nghostzones = new int [dim];
-#if 0
- // Do this later, because CactusBase/IO might not yet be initialised
- // Write grid structure to file
- OutputGridStructure (cgh, m, bbsss, obss, pss);
-#endif
+ groupdata.at(group).transport_operator = GetTransportOperator (cgh, group);
- // Recompose grid hierarchy
- vhh.at(m)->recompose (bbsss, obss, pss, false);
-
- CCTK_INFO ("Grid structure (grid points):");
- const int rl = 0;
- for (int c=0; c<vhh.at(m)->components(rl); ++c) {
- for (int ml=0; ml<vhh.at(m)->mglevels(rl,c); ++ml) {
- const ivect lower = vhh.at(m)->extents.at(rl).at(c).at(ml).lower();
- const ivect upper = vhh.at(m)->extents.at(rl).at(c).at(ml).upper();
- const int convfact = ipow(mgfact, ml);
- assert (all(lower % maxreflevelfact == 0));
- assert (all(upper % maxreflevelfact == 0));
- assert (all(((upper - lower) / maxreflevelfact) % convfact == 0));
- cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]"
- << " exterior extent: " << lower / maxreflevelfact
- << " : " << upper / maxreflevelfact
- << " (" << (upper - lower) / maxreflevelfact / convfact + 1
- << ")" << endl;
- }
+ // Initialise group variables
+ for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
+
+ arrdata.at(group).at(m).data.resize(CCTK_NumVarsInGroupI(group));
+ for (int var=0; var<(int)arrdata.at(group).at(m).data.size(); ++var) {
+ arrdata.at(group).at(m).data.at(var) = 0;
}
- } // loop over maps
-
- reflevels = 1;
- for (int m=0; m<maps; ++m) {
- assert (vhh.at(m)->reflevels() == reflevels);
}
+
+ }
+
+ void handle_group_tags_table (cGH* cgh, int group, cGroup &gp,
+ jvect &convpowers, jvect &convoffsets) {
+ int status = Util_TableGetIntArray
+ (gp.tagstable, gp.dim, &convpowers[0], "convergence_power");
+ if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
+ // keep default: independent of convergence level
+ } else if (status == 1) {
+ // a scalar was given
+ convpowers = convpowers[0];
+ } else if (status == gp.dim) {
+ // do nothing
+ } else {
+ char * const groupname = CCTK_GroupName (group);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The key \"convergence_power\" in the tags table of group "
+ "\"%s\" is wrong",
+ groupname);
+ free (groupname);
+ }
+ assert (all (convpowers >= 0));
-
-
- // Allocate space for variables in group (but don't enable storage
- // yet)
- for (int group=0; group<CCTK_NumGroups(); ++group) {
+ status = Util_TableGetIntArray
+ (gp.tagstable, gp.dim, &convoffsets[0], "convergence_offset");
+ if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
+ // keep default: offset is 0
+ } else if (status == 1) {
+ // a scalar was given
+ convoffsets = convoffsets[0];
+ } else if (status == gp.dim) {
+ // do nothing
+ } else {
+ char * const groupname = CCTK_GroupName (group);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "The key \"convergence_offset\" in the tags table of group "
+ "\"%s\" is wrong",
+ groupname);
+ free (groupname);
+ }
+ }
+
+ void print_some_statistics (cGH* cgh) {
+ int num_gf_groups = 0;
+ int num_gf_vars = 0;
+ vector<int> num_array_groups(dim+1), num_array_vars(dim+1);
+ for (int d=0; d<=dim; ++d) {
+ num_array_groups.at(d) = 0;
+ num_array_vars.at(d) = 0;
+ }
- cGroup gp;
- ierr = CCTK_GroupData (group, &gp);
+ for (int group=0; group<CCTK_NumGroups(); ++group) {
+
+ cGroup data;
+ int ierr = CCTK_GroupData (group, &data);
assert (!ierr);
- switch (gp.grouptype) {
-
- case CCTK_GF: {
- assert (gp.dim == dim);
- arrdata.at(group).resize(maps);
- for (int m=0; m<maps; ++m) {
- arrdata.at(group).at(m).hh = vhh.at(m);
- arrdata.at(group).at(m).dd = vdd.at(m);
- arrdata.at(group).at(m).tt = vtt.at(m);
- }
- break;
- }
-
+ switch (data.grouptype) {
+ case CCTK_GF:
+ num_gf_groups += 1;
+ num_gf_vars += data.numvars * data.numtimelevels;
+ break;
case CCTK_SCALAR:
- case CCTK_ARRAY: {
-
- arrdata.at(group).resize(1);
-
- ivect sizes(1), ghostsizes(0);
-
- switch (gp.grouptype) {
-
- case CCTK_SCALAR:
- // treat scalars as DIM=0, DISTRIB=const arrays
- assert (gp.dim==0);
- assert (gp.disttype == CCTK_DISTRIB_CONSTANT);
- break;
-
- case CCTK_ARRAY: {
- assert (gp.dim>=1 || gp.dim<=dim);
- const CCTK_INT * const * const sz = CCTK_GroupSizesI(group);
- const CCTK_INT * const * const gsz = CCTK_GroupGhostsizesI(group);
- for (int d=0; d<gp.dim; ++d) {
- if (sz) sizes[d] = *sz[d];
- if (gsz) ghostsizes[d] = *gsz[d];
- }
- break;
- }
-
- default:
- assert (0);
- }
-
- ivect alghosts(0), aughosts(0);
- for (int d=0; d<gp.dim; ++d) {
- alghosts[d] = ghostsizes[d];
- aughosts[d] = ghostsizes[d];
- }
-
-
-
- // Adapt array sizes for convergence level
- jvect convpowers (0);
- jvect convoffsets (0);
-
- if (gp.tagstable >= 0) {
- int status;
-
- status = Util_TableGetIntArray
- (gp.tagstable, gp.dim, &convpowers[0], "convergence_power");
- if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
- // keep default: independent of convergence level
- } else if (status == 1) {
- // a scalar was given
- convpowers = convpowers[0];
- } else if (status == gp.dim) {
- // do nothing
- } else {
- char * const groupname = CCTK_GroupName(group);
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The key \"convergence_power\" in the tags table of group \"%s\" is wrong",
- groupname);
- free (groupname);
- }
- assert (all (convpowers >= 0));
-
- status = Util_TableGetIntArray
- (gp.tagstable, gp.dim, &convoffsets[0], "convergence_offset");
- if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
- // keep default: offset is 0
- } else if (status == 1) {
- // a scalar was given
- convoffsets = convoffsets[0];
- } else if (status == gp.dim) {
- // do nothing
- } else {
- char * const groupname = CCTK_GroupName(group);
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The key \"convergence_offset\" in the tags table of group \"%s\" is wrong",
- groupname);
- free (groupname);
- }
-
- } // if there is a group tags table
-
- rvect real_sizes
- = ((sizes - convoffsets)
- / pow(rvect(convergence_factor), convpowers * basemglevel)
- + convoffsets);
- for (int d=gp.dim; d<dim; ++d) {
- real_sizes[d] = sizes[d];
- }
- sizes = floor(real_sizes + 0.5);
- if (any(sizes < 0)) {
- char * const groupname = CCTK_GroupName(group);
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The shape of group \"%s\" scaled for convergence level %d with convergence factor %d is negative",
- groupname, basemglevel, convergence_factor);
- free (groupname);
- }
- if (any(abs(rvect(sizes) - real_sizes) > 0.001)) {
- char * const groupname = CCTK_GroupName(group);
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The shape of group \"%s\" scaled for convergence level %d with convergence factor %d is not integer",
- groupname, basemglevel, convergence_factor);
- free (groupname);
- }
-
-
-
- assert (gp.disttype==CCTK_DISTRIB_CONSTANT
- || gp.disttype==CCTK_DISTRIB_DEFAULT);
-
- if (gp.disttype==CCTK_DISTRIB_CONSTANT) {
- if (! all (ghostsizes == 0)) {
- char * const groupname = CCTK_GroupName(group);
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "The group \"%s\" has DISTRIB=constant, but its ghostsize is not 0",
- groupname);
- free (groupname);
- }
- assert (all (ghostsizes == 0));
- const int d = gp.dim==0 ? 0 : gp.dim-1;
- sizes[d] = (sizes[d] - 2*ghostsizes[d]) * CCTK_nProcs(cgh) + 2*ghostsizes[d];
- assert (sizes[d] >= 0);
- }
-
-
-
- const ivect alb(0);
- const ivect aub(sizes-1);
- const ivect astr(1);
- const ibbox abaseext(alb, aub, astr);
-
- assert (all(convpowers == convpowers[0]));
- const int amgfact1 = ipow(mgfact, convpowers[0]);
-
- arrdata.at(group).at(0).hh
- = new gh<dim>(refinement_factor, vertex_centered,
- amgfact1, vertex_centered,
- abaseext);
-
- arrdata.at(group).at(0).dd
- = new dh<dim>(*arrdata.at(group).at(0).hh, alghosts, aughosts, 0, 0);
-
- arrdata.at(group).at(0).tt
- = new th<dim>(*arrdata.at(group).at(0).hh, 1.0);
-
-
-
- // Set refinement structure for scalars and arrays
- vector<ibbox> bbs;
- vector<bbvect> obs;
- bbs.push_back (abaseext);
- obs.push_back (bbvect(true));
-
- // Split it into components, one for each processor
- vector<int> ps;
- if (gp.disttype==CCTK_DISTRIB_CONSTANT) {
- SplitRegions_AlongDir (cgh, bbs, obs, ps, gp.dim==0 ? 0 : gp.dim-1);
- } else {
- SplitRegions_Automatic (cgh, bbs, obs, ps);
- }
-
- // Create all multigrid levels
- vector<vector<ibbox> > bbss (bbs.size());
- ivect amgfact;
- iivect aoffset;
- for (int d=0; d<dim; ++d) {
- amgfact[d] = ipow(mgfact, convpowers[d]);
- aoffset[d][0] = 0;
- aoffset[d][1] = convoffsets[d];
- }
- for (size_t c=0; c<bbs.size(); ++c) {
- bbss.at(c).resize (mglevels);
- bbss.at(c).at(0) = bbs.at(c);
- for (int ml=1; ml<mglevels; ++ml) {
- // this base
- ivect const baselo = ivect(0);
- ivect const baselo1 = baselo;
- // next finer grid
- ivect const flo = bbss.at(c).at(ml-1).lower();
- ivect const fhi = bbss.at(c).at(ml-1).upper();
- ivect const fstr = bbss.at(c).at(ml-1).stride();
- // this grid
- ivect const str = fstr * amgfact;
- ivect const lo = flo + xpose(obs.at(c))[0].ifthen ( (xpose(aoffset)[0] - amgfact * xpose(aoffset)[0]) * fstr, ivect(0));
- ivect const hi = fhi + xpose(obs.at(c))[1].ifthen ( - (xpose(aoffset)[1] - amgfact * xpose(aoffset)[1]) * fstr, ivect(0));
- ivect const lo1 = baselo1 + (lo - baselo1 + str - 1) / str * str;
- ivect const hi1 = lo1 + (hi - lo1) / str * str;
- bbss.at(c).at(ml) = ibbox(lo1, hi1, str);
- }
- }
-
- // Only one refinement level
- vector<vector<vector<ibbox> > > bbsss(1);
- vector<vector<bbvect> > obss(1);
- vector<vector<int> > pss(1);
- bbsss.at(0) = bbss;
- obss.at(0) = obs;
- pss.at(0) = ps;
-
- // Recompose for this map
- char * const groupname = CCTK_GroupName (group);
- assert (groupname);
- Checkpoint ("Recomposing grid array group \"%s\"", groupname);
- free (groupname);
- arrdata.at(group).at(0).hh->recompose (bbsss, obss, pss, false);
-
- break;
- } // case of scalar or array
-
+ case CCTK_ARRAY:
+ assert (data.dim<=dim);
+ num_array_groups.at(data.dim) += 1;
+ num_array_vars.at(data.dim) += data.numvars * data.numtimelevels;
+ break;
default:
- assert (0);
- } // switch on group type
-
- // Initialise group information
- groupdata.at(group).info.dim = gp.dim;
- groupdata.at(group).info.gsh = new int [dim];
- groupdata.at(group).info.lsh = new int [dim];
- groupdata.at(group).info.lbnd = new int [dim];
- groupdata.at(group).info.ubnd = new int [dim];
- groupdata.at(group).info.bbox = new int [2*dim];
- groupdata.at(group).info.nghostzones = new int [dim];
-
- groupdata.at(group).transport_operator = GetTransportOperator (cgh, group);
-
- // Initialise group variables
- for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
-
- arrdata.at(group).at(m).data.resize(CCTK_NumVarsInGroupI(group));
- for (int var=0; var<(int)arrdata.at(group).at(m).data.size(); ++var) {
- arrdata.at(group).at(m).data.at(var) = 0;
- }
-
+ assert (0);
}
-
- } // for group
-
-
-
- // Allocate level times
- leveltimes.resize (mglevels);
- for (int ml=0; ml<mglevels; ++ml) {
- leveltimes.at(ml).resize (maxreflevels);
}
- origin_space.resize (mglevels);
-
- // Enable prolongating
- do_prolongate = true;
-
-
-
- // Finish initialisation
- mglevelfact = 1;
- cgh->cctk_time = 0;
- cgh->cctk_delta_time = 1.0;
- for (int d=0; d<dim; ++d) {
- cgh->cctk_origin_space[d] = 0.0;
- cgh->cctk_delta_space[d] = 1.0;
+ CCTK_INFO ("Group and variable statistics:");
+ CCTK_VInfo (CCTK_THORNSTRING,
+ " There are %d grid functions in %d groups",
+ num_gf_vars, num_gf_groups);
+ CCTK_VInfo (CCTK_THORNSTRING,
+ " There are %d grid scalars in %d groups",
+ num_array_vars.at(0), num_array_groups.at(0));
+ for (int d=1; d<=3; ++d) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ " There are %d %d-dimensional grid arrays in %d groups",
+ num_array_vars.at(d), d, num_array_groups.at(d));
}
+ CCTK_VInfo (CCTK_THORNSTRING,
+ " (The number of variables counts all time levels)");
+ }
- mglevel = 0;
- reflevel = 0;
- map = 0;
- component = 0;
-
+ void enable_storage_for_all_groups (cGH* cgh) {
+ BEGIN_MGLEVEL_LOOP(cgh) {
+ BEGIN_REFLEVEL_LOOP(cgh) {
+ for (int group=0; group<CCTK_NumGroups(); ++group) {
+ char * const groupname = CCTK_GroupName(group);
+ EnableGroupStorage (cgh, groupname);
+ free (groupname);
+ }
+ } END_REFLEVEL_LOOP;
+ } END_MGLEVEL_LOOP;
+ }
+
+ void leave_all_modes (cGH* cgh) {
leave_local_mode (cgh);
leave_singlemap_mode (cgh);
leave_level_mode (cgh);
leave_global_mode (cgh);
-
-
-
- // Some statistics
- if (verbose || veryverbose) {
-
- int num_gf_groups = 0;
- int num_gf_vars = 0;
- vector<int> num_array_groups(dim+1), num_array_vars(dim+1);
- for (int d=0; d<=dim; ++d) {
- num_array_groups.at(d) = 0;
- num_array_vars.at(d) = 0;
- }
-
- for (int group=0; group<CCTK_NumGroups(); ++group) {
-
- cGroup data;
- ierr = CCTK_GroupData (group, &data);
- assert (!ierr);
-
- switch (data.grouptype) {
- case CCTK_GF:
- num_gf_groups += 1;
- num_gf_vars += data.numvars * data.numtimelevels;
- break;
- case CCTK_SCALAR:
- case CCTK_ARRAY:
- assert (data.dim<=dim);
- num_array_groups.at(data.dim) += 1;
- num_array_vars.at(data.dim) += data.numvars * data.numtimelevels;
- break;
- default:
- assert (0);
- }
- }
- CCTK_INFO ("Group and variable statistics:");
- CCTK_VInfo (CCTK_THORNSTRING,
- " There are %d grid functions in %d groups",
- num_gf_vars, num_gf_groups);
- CCTK_VInfo (CCTK_THORNSTRING,
- " There are %d grid scalars in %d groups",
- num_array_vars.at(0), num_array_groups.at(0));
- for (int d=1; d<=3; ++d) {
- CCTK_VInfo (CCTK_THORNSTRING,
- " There are %d %d-dimensional grid arrays in %d groups",
- num_array_vars.at(d), d, num_array_groups.at(d));
- }
- CCTK_VInfo (CCTK_THORNSTRING,
- " (The number of variables counts all time levels)");
- }
-
-
-
- // Enable storage for all groups if desired
- if (enable_all_storage) {
- BEGIN_MGLEVEL_LOOP(cgh) {
- BEGIN_REFLEVEL_LOOP(cgh) {
- for (int group=0; group<CCTK_NumGroups(); ++group) {
- char * const groupname = CCTK_GroupName(group);
- EnableGroupStorage (cgh, groupname);
- free (groupname);
- }
- } END_REFLEVEL_LOOP;
- } END_MGLEVEL_LOOP;
- }
-
- Waypoint ("Done with setting up the grid hierarchy");
-
- return &carpetGH;
}
} // namespace Carpet