diff options
Diffstat (limited to 'CarpetDev/CarpetIOF5/src/input.cc')
-rw-r--r-- | CarpetDev/CarpetIOF5/src/input.cc | 462 |
1 files changed, 205 insertions, 257 deletions
diff --git a/CarpetDev/CarpetIOF5/src/input.cc b/CarpetDev/CarpetIOF5/src/input.cc index da0d7dc00..d42cbd076 100644 --- a/CarpetDev/CarpetIOF5/src/input.cc +++ b/CarpetDev/CarpetIOF5/src/input.cc @@ -10,6 +10,7 @@ #include <limits> #include <sstream> #include <string> +#include <vector> #include <hdf5.h> #include <F5/F5F.h> @@ -30,7 +31,7 @@ // F5 helper namespace { - char const* + char const * ArrayTypeName(ArrayType const array_type) { switch (array_type) { @@ -64,6 +65,8 @@ namespace CarpetIOF5 { cGH const *cctkGH; vector<bool> const input_var; // whether to input this variable + bool const input_past_timelevels; + bool const input_metadata; double time; char const *gridname; @@ -79,11 +82,18 @@ namespace CarpetIOF5 { // string chartname; + scatter_t& scatter; + public: - input_iterator_t (cGH const *const cctkGH_, - vector<bool> const& input_var_) + input_iterator_t(cGH const *const cctkGH_, + vector<bool> const& input_var_, + bool const input_past_timelevels_, + bool const input_metadata_, + scatter_t& scatter_) : cctkGH(cctkGH_), input_var(input_var_), + input_past_timelevels(input_past_timelevels_), + input_metadata(input_metadata_), time(nan), gridname(NULL), topologyname(NULL), index_depth(-1), topological_dimension(-1), @@ -91,7 +101,8 @@ namespace CarpetIOF5 { fieldname(NULL), fieldtype(UnknownArrayType), varindex(-1), fragmentname(NULL), - map(-1), component(-1) + map(-1), component(-1), + scatter(scatter_) { } @@ -99,76 +110,32 @@ namespace CarpetIOF5 { private: - void read_timeslice (F5Path *const path) + void read_timeslice(F5Path *const path) { indent_t indent; cout << indent << "time=" << time << "\n"; -#if 0 - // TODO: Loop over all charts that exist for the grid, or at - // least remember how many maps there are. (This is also written - // as part of the grid structure.) - // F5iterate_grid_atlas? - for (int m=0; m<maps; ++m) { - indent_t indent; - chartname = generate_chartname(cctkGH, m); - cout << indent << "chart=\"" << chartname << "\"\n"; - F5iterate_grids - (path, NULL, grid_iterator, this, NULL, chartname.c_str()); - } -#endif - - F5iterate_grids (path, NULL, grid_iterator, this, NULL, NULL); + F5iterate_grids(path, NULL, grid_iterator, this, NULL, NULL); - // Synchronise - BEGIN_REFLEVEL_LOOP(cctkGH) { -#if 0 - int groups[] = { - CCTK_GroupIndex("GRID::COORDINATES") - }; - int const ngroups = sizeof groups / sizeof *groups; - for (int i=0; i<ngroups; ++i) { - assert (groups[i]>=0); - } - iret = CCTK_SyncGroupsI (cctkGH, ngroups, groups); - assert (iret >= 0); -#endif -#warning "TODO: don't modify boundaries" - BEGIN_LOCAL_MAP_LOOP(cctkGH, CCTK_GF) { - BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { - DECLARE_CCTK_ARGUMENTS; -#pragma omp parallel - CCTK_LOOP3_BOUNDARIES(boundaries, cctkGH, - i,j,k, 1,1,1, - cctk_lsh[0]-1,cctk_lsh[1]-1,cctk_lsh[2]-1) - { - int const ind3d = CCTK_GFINDEX3D(cctkGH, i,j,k); - x[ind3d] = 0.0; - y[ind3d] = 0.0; - z[ind3d] = 0.0; - r[ind3d] = 0.0; - } CCTK_ENDLOOP3_BOUNDARIES(boundaries); - } END_LOCAL_COMPONENT_LOOP; - } END_LOCAL_MAP_LOOP; - } END_REFLEVEL_LOOP; +#warning "TODO: synchronise all read grid functions" } - void read_grid (F5Path *const path) + void read_grid(F5Path *const path) { indent_t indent; - cout << indent << "grid=\"" << gridname << "\"\n"; - // F5iterate_vertex_fields (path, NULL, field_iterator, this, NULL, NULL); - F5iterate_topologies (path, NULL, topology_iterator, this); + cout << indent << "grid=" << gridname << "\n"; + // F5iterate_vertex_fields(path, NULL, field_iterator, this, NULL, NULL); + F5iterate_topologies(path, NULL, topology_iterator, this); } - void read_topology (F5Path *const path) + void read_topology(F5Path *const path) { indent_t indent; herr_t herr; cout << indent - << "topology=\"" << topologyname << "\"" + << "topology=" << topologyname << "" << " (" << (index_depth==0 ? "vertex" : "cell") << ")\n" << indent << "topological dimension=" << topological_dimension << "\n"; @@ -177,13 +144,13 @@ namespace CarpetIOF5 { // Ignore topologies that are only an alias for another topology H5G_stat_t stat; - herr = H5Gget_objinfo (path->Grid_hid, topologyname, false, &stat); - assert (not herr); + herr = H5Gget_objinfo(path->Grid_hid, topologyname, false, &stat); + assert(not herr); if (stat.type == H5G_LINK) { char linkval[100000]; herr = H5Gget_linkval (path->Grid_hid, topologyname, sizeof linkval, linkval); - assert (not herr); + assert(not herr); indent_t indent; cout << indent << "alias for topology \"" << linkval << "\"\n" << indent << "ignoring this topology\n"; @@ -198,16 +165,16 @@ namespace CarpetIOF5 { int const iret = F5LAget_dimensions(path->Topology_hid, FIBER_HDF5_REFINEMENT_INFO, hreffact); - assert (iret == dim); + assert(iret == dim); hsize_t hreffact2[FIBER_MAX_RANK]; void *const pret = F5Tpermute_dimensions(path, dim, hreffact2, hreffact); - assert (pret); + assert(pret); ivect const reffact = h2v(hreffact2); int rl; for (rl=0; rl<reflevels; ++rl) { if (all(reffact == Carpet::spacereffacts.AT(rl))) break; } - assert (rl<reflevels); + assert(rl<reflevels); reflevel = rl; cout << indent << "refinement level " << reflevel << "\n"; @@ -215,13 +182,13 @@ namespace CarpetIOF5 { // F5iterate_topology_fields // (path, NULL, field_iterator, this, chartname.c_str(), NULL); - F5iterate_topology_fields (path, NULL, field_iterator, this, NULL, NULL); + F5iterate_topology_fields(path, NULL, field_iterator, this, NULL, NULL); } - void read_field (F5Path *const path) + void read_field(F5Path *const path) { indent_t indent; - cout << indent << "field=\"" << fieldname << "\"\n"; + cout << indent << "field=" << fieldname << "\n"; interpret_fieldname(cctkGH, fieldname, varindex); #warning "TODO: check all variables in the group" @@ -238,13 +205,14 @@ namespace CarpetIOF5 { assert(iret); // Do we need to iterate over fragments? +#warning "TODO: Should instead check whether attribute FIBER_HDF5_TYPEID_ATTRIB exists (existence indicates fragmentation)" int const is_fragmented = F5Fis_fragmented(path, fieldname); cout << indent << (is_fragmented ? "fragmented" : "not fragmented") << "\n"; if (is_fragmented) { - F5iterate_field_fragments (path, NULL, fragment_iterator, this); + F5iterate_field_fragments(path, NULL, fragment_iterator, this); } else { - read_fragment (path); + read_fragment(path); } F5Fclose(path); @@ -253,17 +221,16 @@ namespace CarpetIOF5 { indent_t indent; cout << indent << "ignoring this field\n"; } +#warning "TODO: keep track of which fields have been read, and complain about unread ones" +#warning "TODO: keep track of which part of a field has been read, and complain about unread parts" } - void read_fragment (F5Path *const path) + void read_fragment(F5Path *const path) { indent_t indent; - int iret; - void *pret; - if (fragmentname) { - cout << indent << "fragment=\"" << fragmentname << "\"\n"; + cout << indent << "fragment=" << fragmentname << "\n"; } else { cout << indent << "no fragment\n"; } @@ -278,7 +245,7 @@ namespace CarpetIOF5 { // Determine map and component from fragment name if (fragmentname) { - interpret_fragmentname (cctkGH, fragmentname, map, component); + interpret_fragmentname(cctkGH, fragmentname, map, component); } else { map = 0; component = CCTK_MyProc(cctkGH); @@ -296,45 +263,51 @@ namespace CarpetIOF5 { hid_t const type_id = F5Fget_type(path); if (F5Tis_convertible(type_id, H5T_NATIVE_DOUBLE)) { cout << indent << "compound type: scalar\n"; - read_variable (path, NULL, varindex); + read_variable(path, NULL, varindex); } else if (F5Tis_convertible(type_id, F5T_VEC3_DOUBLE)) { cout << indent << "compound type: vector\n"; - // This assumes a separated vector; we don't support - // contiguous vectors + // This assumes separated storage; we don't support contiguous + // storage yet assert(is_separated); - read_variable (path, "Dx", varindex+0); - read_variable (path, "Dy", varindex+1); - read_variable (path, "Dz", varindex+2); + read_variable(path, "Dx", varindex+0); + read_variable(path, "Dy", varindex+1); + read_variable(path, "Dz", varindex+2); } else if (F5Tis_convertible(type_id, F5T_METRIC33_DOUBLE)) { cout << indent << "compound type: symmetric tensor\n"; - // Not yet implemented - assert(0); + // This assumes separated storage; we don't support contiguous + // storage yet + assert(is_separated); + read_variable(path, "gxx", varindex+0); + read_variable(path, "gxy", varindex+1); + read_variable(path, "gxz", varindex+2); + read_variable(path, "gyy", varindex+3); + read_variable(path, "gyz", varindex+4); + read_variable(path, "gzz", varindex+5); } else { // Unknown tensor type assert(0); } } - void read_variable (F5Path *const path, char const *const name, - int const var) + void read_variable(F5Path *const path, char const *const name, + int const var) { indent_t indent; herr_t herr; - int ierr; int iret; void *pret; - assert (path); - assert (var >= 0); + assert(path); + assert(var >= 0); - cout << indent << "dataset=\"" << (name ? name : "(null)") << "\"\n"; + cout << indent << "dataset=" << (name ? name : "(null)") << "\n"; - assert (var >= 0); + assert(var >= 0); { char *const fullname = CCTK_FullName(var); - cout << indent << "variable=\"" << fullname << "\"\n"; - free (fullname); + cout << indent << "variable=" << fullname << "\n"; + free(fullname); } @@ -366,16 +339,16 @@ namespace CarpetIOF5 { bool fragment_is_group = false; if (fragmentname) { H5O_info_t info; - herr = H5Oget_info_by_name (path->Field_hid, fragmentname, - &info, H5P_DEFAULT); - assert (not herr); + herr = H5Oget_info_by_name(path->Field_hid, fragmentname, + &info, H5P_DEFAULT); + assert(not herr); fragment_is_group = info.type == H5O_TYPE_GROUP; } cout << indent << "fragment_is_group=" << fragment_is_group << "\n"; hid_t fragment; if (fragment_is_group) { - fragment = H5Gopen (path->Field_hid, fragmentname, H5P_DEFAULT); - assert (fragment >= 0); + fragment = H5Gopen(path->Field_hid, fragmentname, H5P_DEFAULT); + assert(fragment >= 0); } else { fragment = path->Field_hid; } @@ -393,7 +366,7 @@ namespace CarpetIOF5 { H5E_BEGIN_TRY { element = H5Dopen(fragment, datasetname, H5P_DEFAULT); } H5E_END_TRY; - assert (element >= 0); + assert(element >= 0); } bool const field_is_dataset = element < 0; cout << indent << "field_is_dataset=" << field_is_dataset << "\n"; @@ -402,13 +375,13 @@ namespace CarpetIOF5 { // a single element and has already been opened element = fragment; } - assert (element>=0); + assert(element>=0); // Check index depth int index_depth_; iret = F5Tget_index_depth(path, &index_depth_); - assert (iret); - assert (index_depth_ == index_depth); + assert(iret); + assert(index_depth_ == index_depth); // Read the fragment offset. This is stored with the dataset // group. @@ -417,13 +390,13 @@ namespace CarpetIOF5 { hsize_t hoff[FIBER_MAX_RANK]; iret = F5LAget_dimensions(fragment_is_group ? fragment : element, FIBER_FRAGMENT_OFFSET_ATTRIBUTE, hoff); - assert (iret == dim); + assert(iret == dim); hsize_t hoff2[FIBER_MAX_RANK]; pret = F5Tpermute_dimensions(path, dim, hoff2, hoff); - assert (pret); + assert(pret); foff = h2v(hoff2); } - assert (all(foff>=0)); + assert(all(foff>=0)); #if 0 // Read the fragment size. This is stored with the field -- why @@ -432,28 +405,28 @@ namespace CarpetIOF5 { iret = F5LAget_dimensions(path->Field_hid, FIBER_FIELD_DATASPACE_DIMENSIONS_ATTRIBUTE, hlen); - assert (iret == dim); + assert(iret == dim); hsize_t hlen2[FIBER_MAX_RANK]; pret = F5Tpermute_dimensions(path, dim, hlen2, hlen); - assert (pret); + assert(pret); ivect const flen = h2v(hlen2); - assert (all(flen>=0)); + assert(all(flen>=0)); #endif hid_t const space = H5Dget_space(element); - assert (space>=0); + assert(space>=0); iret = H5Sget_simple_extent_ndims(space); - assert (iret == dim); + assert(iret == dim); hsize_t hlen[dim]; iret = H5Sget_simple_extent_dims(space, hlen, NULL); hsize_t hlen2[dim]; pret = F5Tpermute_dimensions(path, dim, hlen2, hlen); - assert (pret); + assert(pret); ivect const flen = h2v(hlen2); - assert (all(flen>=0)); - herr = H5Sclose (space); - assert (not herr); + assert(all(flen>=0)); + herr = H5Sclose(space); + assert(not herr); - ibbox const fbox (foff, foff+flen-1, 1); + ibbox const fbox(foff, foff+flen-1, 1); { indent_t indent; cout << indent @@ -462,131 +435,43 @@ namespace CarpetIOF5 { - // Examine Cactus variable - int const group = CCTK_GroupIndexFromVarI(var); - cGroup groupdata; - ierr = CCTK_GroupData(group, &groupdata); - assert (not ierr); - - // TODO - assert (groupdata.grouptype == CCTK_GF); - assert (groupdata.vartype == CCTK_VARIABLE_REAL); - assert (groupdata.disttype == CCTK_DISTRIB_DEFAULT); - assert (groupdata.stagtype == 0); - assert (groupdata.dim == dim); - - // TODO: This does not work; we need to read the data, and later - // distribute it onto the respective Cactus variables - ENTER_LEVEL_MODE(cctkGH, reflevel) { - ENTER_SINGLEMAP_MODE(cctkGH, map, CCTK_GF) { - ENTER_LOCAL_MODE(cctkGH, component, CCTK_GF) { - DECLARE_CCTK_ARGUMENTS; - - ivect lbnd, lsh, lghosts, ughosts; - ivect imin, imax, ioff, ilen; - for (int d=0; d<dim; ++d) { - lbnd[d] = cctk_lbnd[d]; - lsh[d] = cctk_lsh[d]; - // F5 counts the total overlap, which is the sum of the - // ghost zones on this and on the adjacent component - lghosts[d] = cctk_bbox[2*d ] ? 0 : 2*cctk_nghostzones[d]; - ughosts[d] = cctk_bbox[2*d+1] ? 0 : 2*cctk_nghostzones[d]; - imin[d] = 0; - imax[d] = lsh[d]; - // Do not read in ghost zones - imin[d] += lghosts[d] / 2; - imax[d] -= ughosts[d] / 2; - ioff[d] = lbnd[d] + imin[d]; - ilen[d] = imax[d] - imin[d]; - } - ibbox const lbox (lbnd, lbnd+lsh-1, 1); - ibbox const ibox (ioff, ioff+ilen-1, 1); - ibbox const ovlp = ibox & fbox; - - if (ovlp.empty()) { - indent_t indent; - cout << indent << "dataset does not intersect component " << component << "; skipping component\n"; - continue; - } - - indent_t indent; - cout << indent << "dataset intersects component " << component << "\n" - << indent << "reading bbox " << ovlp.lower() << ":" << ovlp.upper() << " of " << ibox.lower() << ":" << ibox.upper() << "\n"; - - #warning "TODO: assert the whole component is read" - - int const proc = vhh.AT(Carpet::map)->processor(reflevel, component); -#warning "TODO: send dataset to destination process" - assert (proc == dist::rank()); - - int const timelevel = 0; - void *const data = CCTK_VarDataPtrI(cctkGH, timelevel, var); - assert (data); - - - - hvect const hzero(0); - hvect mlsh; - pret = F5Tpermute_dimensions - (path, dim, &mlsh[0], &v2h(lbox.shape())[0]); - assert (pret); - hid_t const memspace = H5Screate_simple(dim, &mlsh[0], NULL); - assert (memspace >= 0); - hvect mmin; - pret = F5Tpermute_dimensions - (path, dim, &mmin[0], &v2h(ovlp.lower()-lbox.lower())[0]); - assert (pret); - hvect mlen; - pret = F5Tpermute_dimensions - (path, dim, &mlen[0], &v2h(ovlp.shape())[0]); - assert (pret); - assert (all(mmin >= hzero)); - assert (all(mmin+mlen <= mlsh)); - herr = H5Sselect_hyperslab - (memspace, H5S_SELECT_SET, &mmin[0], NULL, &mlen[0], NULL); - assert (not herr); - // cout << "mlsh=" << mlsh << " mmin=" << mmin << " mlen=" << mlen << "\n"; - - hvect flsh; - pret = F5Tpermute_dimensions - (path, dim, &flsh[0], &v2h(fbox.shape())[0]); - assert (pret); - hid_t const filespace = H5Screate_simple(dim, &flsh[0], NULL); - assert (filespace >= 0); - hvect fmin; - pret = F5Tpermute_dimensions - (path, dim, &fmin[0], &v2h(ovlp.lower()-fbox.lower())[0]); - assert (pret); - hvect const flen = mlen; - assert (all(fmin >= hzero)); - assert (all(fmin+flen <= flsh)); - herr = H5Sselect_hyperslab - (filespace, H5S_SELECT_SET, &fmin[0], NULL, &flen[0], NULL); - // cout << "flsh=" << flsh << " fmin=" << fmin << " flen=" << flen << "\n"; - - herr = H5Dread (element, H5T_NATIVE_DOUBLE, memspace, filespace, - H5P_DEFAULT, data); - assert (not herr); - - herr = H5Sclose(memspace); - assert (not herr); - herr = H5Sclose(filespace); - assert (not herr); - - } LEAVE_LOCAL_MODE; - } LEAVE_SINGLEMAP_MODE; - } LEAVE_LEVEL_MODE; + fragdesc_t fragdesc; + fragdesc.varindex = var; + fragdesc.reflevel = reflevel; + fragdesc.map = map; + fragdesc.component = component; +#warning "TODO: set timelevel correctly" + fragdesc.timelevel = 0; + fragdesc.imin = fbox.lower(); + fragdesc.imax = fbox.upper(); + + vector<char> data(fragdesc.npoints() * fragdesc.vartypesize()); + + int const vartype = CCTK_VarTypeI(var); + hid_t type; + switch (vartype) { + case CCTK_VARIABLE_INT: type = H5T_NATIVE_INT; break; + case CCTK_VARIABLE_REAL: type = H5T_NATIVE_DOUBLE; break; + default: assert(0); + } + assert(type >= 0); + assert(CCTK_VarTypeSize(vartype) == (int)H5Tget_size(type)); + + herr = H5Dread(element, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, &data[0]); + assert(not herr); + + scatter.send(fragdesc, &data[0]); if (not field_is_dataset) { herr = H5Dclose(element); - assert (not herr); + assert(not herr); } if (fragment_is_group) { herr = H5Gclose(fragment); - assert (not herr); + assert(not herr); } } @@ -594,45 +479,49 @@ namespace CarpetIOF5 { public: - void iterate (hid_t const object) + void iterate(hid_t const object) { - F5iterate_timeslices (object, NULL, timeslice_iterator, this); + F5iterate_timeslices(object, NULL, timeslice_iterator, this); } static - herr_t timeslice_iterator (F5Path *const path, double const time, - void *const userdata) + herr_t timeslice_iterator(F5Path *const path, double const time, + void *const userdata) { input_iterator_t *const iterator = (input_iterator_t*)userdata; iterator->time = time; - iterator->read_timeslice (path); + iterator->read_timeslice(path); + + if (iterator->input_past_timelevels) { + return 0; // continue + } else { + return 1; // done + } return 0; - // finish (successfully) after the first timeslice - // return 1; } static - herr_t grid_iterator (F5Path *const path, char const *const gridname, - void *const userdata) + herr_t grid_iterator(F5Path *const path, char const *const gridname, + void *const userdata) { input_iterator_t *const iterator = (input_iterator_t*)userdata; iterator->gridname = gridname; - iterator->read_grid (path); + iterator->read_grid(path); return 0; } static - herr_t topology_iterator (F5Path *const path, - char const *const topologyname, - int const index_depth, - int const topological_dimension, - void *const userdata) + herr_t topology_iterator(F5Path *const path, + char const *const topologyname, + int const index_depth, + int const topological_dimension, + void *const userdata) { input_iterator_t *const iterator = (input_iterator_t*)userdata; iterator->topologyname = topologyname; iterator->index_depth = index_depth; iterator->topological_dimension = topological_dimension; - iterator->read_topology (path); + iterator->read_topology(path); iterator->topologyname = NULL; iterator->index_depth = -1; iterator->topological_dimension = -1; @@ -640,24 +529,24 @@ namespace CarpetIOF5 { } static - herr_t field_iterator (F5Path *const path, char const *const fieldname, - void *const userdata) + herr_t field_iterator(F5Path *const path, char const *const fieldname, + void *const userdata) { input_iterator_t *const iterator = (input_iterator_t*)userdata; iterator->fieldname = fieldname; - iterator->read_field (path); + iterator->read_field(path); iterator->fieldname = NULL; return 0; } static - herr_t fragment_iterator (F5Path *const path, - char const *const fragmentname, - void *const userdata) + herr_t fragment_iterator(F5Path *const path, + char const *const fragmentname, + void *const userdata) { input_iterator_t *const iterator = (input_iterator_t*)userdata; iterator->fragmentname = fragmentname; - iterator->read_fragment (path); + iterator->read_fragment(path); iterator->fragmentname = NULL; return 0; } @@ -666,12 +555,71 @@ namespace CarpetIOF5 { - void input (cGH const *const cctkGH, - hid_t const file, - vector<bool> const& input_var) + void read_metadata(cGH const *const cctkGH, hid_t const file) + { + DECLARE_CCTK_PARAMETERS; + + assert(cctkGH); + assert(file >= 0); + + herr_t herr; + + + + CCTK_INFO("Reading simulation metadata..."); + + // Open a group holding all metadata + hid_t const group = H5Gopen(file, metadata_group, H5P_DEFAULT); + assert(group >= 0); + + // General information + string fullversion; + ReadAttribute(group, "Cactus version", fullversion); + cout << "Cactus version: " << fullversion << "\n"; + + // Unique identifiers + string config_id; + ReadAttribute(group, "config id", config_id); + cout << "UniqueConfigID: " << config_id << "\n"; + string build_id; + ReadAttribute(group, "build id", build_id); + cout << "UniqueBuildID: " << build_id << "\n"; + string simulation_id; + ReadAttribute(group, "simulation id", simulation_id); + cout << "UniqueSimulationID: " << simulation_id << "\n"; + string run_id; + ReadAttribute(group, "run id", run_id); + cout << "UniqueRunID: " << run_id << "\n"; + + // Parameters + string parameters; + ReadLargeAttribute(group, all_parameters, parameters); + IOUtil_SetAllParameters(parameters.c_str()); + + // Grid structure + string gs; + ReadLargeAttribute(group, grid_structure, gs); +#warning "TODO: set grid structure" + + herr = H5Gclose(group); + assert(not herr); + } + + + + void input(cGH const *const cctkGH, + hid_t const file, + vector<bool> const& input_var, + bool const input_past_timelevels, + bool const input_metadata, + scatter_t& scatter) { - input_iterator_t iterator(cctkGH, input_var); - iterator.iterate (file); +#warning "TODO: not yet implemented" + assert (not input_metadata); + input_iterator_t iterator(cctkGH, input_var, + input_past_timelevels, input_metadata, + scatter); + iterator.iterate(file); } } // end namespace CarpetIOF5 |