diff options
Diffstat (limited to 'CarpetDev/CarpetIOF5/src/iof5.cc.old')
-rw-r--r-- | CarpetDev/CarpetIOF5/src/iof5.cc.old | 643 |
1 files changed, 643 insertions, 0 deletions
diff --git a/CarpetDev/CarpetIOF5/src/iof5.cc.old b/CarpetDev/CarpetIOF5/src/iof5.cc.old new file mode 100644 index 000000000..fe780030b --- /dev/null +++ b/CarpetDev/CarpetIOF5/src/iof5.cc.old @@ -0,0 +1,643 @@ +#include <cctk.h> +#include <cctk_Arguments.h> +#include <cctk_Parameters.h> + +#include <cassert> +#include <cstdlib> +#include <cstring> +#include <iomanip> +#include <iostream> +#include <limits> +#include <sstream> +#include <string> + +#include <hdf5.h> +#include <F5/F5F.h> +#include <F5/F5R.h> +#include <F5/F5iterate.h> +#include <F5/F5uniform.h> + +#include <bbox.hh> +#include <vect.hh> + +#include <carpet.hh> + + + +namespace CarpetIOF5 { + + using namespace std; + using namespace Carpet; + + + + // File mode for creating directories + int const mode = 0755; + + // A nan + CCTK_REAL const nan = numeric_limits<CCTK_REAL>::quiet_NaN(); + + // Indentation + inline string indent (int const n) + { + int const width = 3; + return string(width*n, ' '); + } + + + + typedef vect<hsize_t,dim> hvect; + typedef vect<float,dim> fvect; + + + + static inline + hvect v2h (ivect const& a) + { + return hvect(a); + } + + static inline + F5_vec3_point_t v2p (rvect const& a) + { + F5_vec3_point_t res; + res.x = a[0]; + res.y = a[1]; + res.z = a[2]; + return res; + } + + static inline + F5_vec3_float_t v2f (rvect const& a) + { + F5_vec3_float_t res; + res.x = a[0]; + res.y = a[1]; + res.z = a[2]; + return res; + } + + static inline + F5_vec3_double_t v2d (rvect const& a) + { + F5_vec3_double_t res; + res.x = a[0]; + res.y = a[1]; + res.z = a[2]; + return res; + } + + + + // Generate a good grid name (simulation name) + string + generate_gridname (cGH const *const cctkGH) + { +#if 0 + char const *const gridname = (char const*) UniqueSimulationID(cctkGH); + assert (gridname); + return gridname; +#endif + // Use the parameter file name, since the simulation ID is too + // long and doesn't look nice + char parfilename[10000]; + CCTK_ParameterFilename (sizeof parfilename, parfilename); + char *const p = strstr(parfilename, ".par"); + if (p) *p = '\0'; + char *const s = strrchr(parfilename, '/'); + char *const gridname = s ? s+1 : parfilename; + return gridname; + } + + + + // Generate a good file name ("alias") for a variable + string + generate_basename (cGH const *const cctkGH, + int const variable) + { + DECLARE_CCTK_PARAMETERS; + + assert (variable >= 0); + + ostringstream filename_buf; + + if (CCTK_EQUALS (file_content, "variable")) { + char *const varname = CCTK_FullName(variable); + assert (varname); + for (char *p = varname; *p; ++p) { + *p = tolower(*p); + } + filename_buf << varname; + free (varname); + } + else if (CCTK_EQUALS (file_content, "group")) { + char *const groupname = CCTK_GroupNameFromVarI(variable); + assert (groupname); + for (char *p = groupname; *p; ++p) { + *p = tolower(*p); + } + filename_buf << groupname; + free (groupname); + } + else if (CCTK_EQUALS (file_content, "thorn")) { + char const *const impname = CCTK_ImpFromVarI(variable); + char *const thornname = strdup(impname); + assert (thornname); + char *const colon = strchr(thornname, ':'); + assert (colon); + *colon = '\0'; + for (char *p = thornname; *p; ++p) { + *p = tolower(*p); + } + filename_buf << thornname; + free (thornname); + } + else if (CCTK_EQUALS (file_content, "everything")) { + filename_buf << out_filename; + } + else { + assert (0); + } + + if (out_timesteps_per_file > 0) { + int const iteration = (cctkGH->cctk_iteration + / out_timesteps_per_file * out_timesteps_per_file); + filename_buf << ".it" + << setw (iteration_digits) << setfill ('0') << iteration; + } + + return filename_buf.str(); + } + + + + // Create the final file name on a particular processor + string + create_filename (cGH const *const cctkGH, + string const basename, + bool const create_directories) + { + DECLARE_CCTK_PARAMETERS; + + int const proc = CCTK_MyProc(cctkGH); + int const nprocs = CCTK_nProcs(cctkGH); + + bool const use_IO_out_dir = strcmp(out_dir, "") == 0; + string path = use_IO_out_dir ? IO_out_dir : out_dir; + + if (create_subdirs) { + if (nprocs >= 10000) { + ostringstream buf; + buf << path + "/" + << basename + << ".p" << setw (max (0, processor_digits - 4)) << setfill ('0') + << proc / 10000 + << "nnnn/"; + path = buf.str(); + if (create_directories) { + check (CCTK_CreateDirectory (mode, path.c_str()) >= 0); + } + } + if (nprocs >= 100) { + ostringstream buf; + buf << path + "/" + << basename + << ".p" << setw (max (0, processor_digits - 2)) << setfill ('0') + << proc / 100 + << "nn/"; + path = buf.str(); + if (create_directories) { + check (CCTK_CreateDirectory (mode, path.c_str()) >= 0); + } + } + } + if (one_dir_per_file and nprocs >= 1) { + ostringstream buf; + buf << path + << basename + << ".p" << setw (processor_digits) << setfill ('0') + << proc + << "/"; + path = buf.str(); + if (create_directories) { + check (CCTK_CreateDirectory (mode, path.c_str()) >= 0); + } + } + ostringstream buf; + buf << path + "/" + << basename + << ".p" << setw (processor_digits) << setfill ('0') << proc + << out_extension; + return buf.str(); + } + + + + extern "C" + void F5_Output (CCTK_ARGUMENTS) + { + DECLARE_CCTK_ARGUMENTS; + DECLARE_CCTK_PARAMETERS; + + herr_t herr; + + + + assert (is_global_mode()); + CCTK_VInfo (CCTK_THORNSTRING, "F5_Output: iteration=%d", cctk_iteration); + + string const gridname = generate_gridname(cctkGH); + + + + // Open file + static bool first_time = true; + + string const basename = + generate_basename (cctkGH, CCTK_VarIndex("grid::r")); + string const name = + create_filename (cctkGH, basename, first_time); + + bool const truncate_file = first_time and IO_TruncateOutputFiles(cctkGH); + hid_t const file = + truncate_file ? + H5Fcreate (name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT) : + H5Fopen (name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + assert (file >= 0); + first_time = false; + + + + BEGIN_REFLEVEL_LOOP (cctkGH) { + DECLARE_CCTK_ARGUMENTS; + +#if 0 + // Write data +#warning "TODO: Save the coordinates in double precision" + F5Path *const path = + F5Fwrite_uniform_cartesian3D + (file, cctk_time, gridname, &v2p(lower), &v2f(delta), &v2h(lsh)[0], + "radius" /* group name */, H5T_NATIVE_DOUBLE, r, NULL, F5P_DEFAULT); +#endif + + // Define grid hierarchy + ivect const reffact = spacereffacts.AT(reflevel); + F5Path *const path = F5Rcreate_vertex_refinement3D + (file, cctk_time, gridname.c_str(), &v2h(reffact)[0], NULL); + + // Define iteration + F5Rset_timestep (path, cctk_iteration); + +#if 0 + F5Path *refpath = NULL; + static CCTK_REAL last_root_time = -1; + if (reflevel == 0) { + last_root_time = cctk_time; + } else { + refpath = F5Rcreate_relative_vertex_Qrefinement3D + (file, cctk_time, gridname, &v2h(reffact)[0], + last_root_time, &v2h(ivect(1))[0]); + } +#endif + + + + BEGIN_LOCAL_MAP_LOOP (cctkGH, CCTK_GF) { + DECLARE_CCTK_ARGUMENTS; + + // Determine level coordinates + ivect gsh; + rvect origin, delta; + rvect lower, upper; + for (int d=0; d<dim; ++d) { + gsh[d] = cctk_gsh[d]; + origin[d] = CCTK_ORIGIN_SPACE(d); + delta[d] = CCTK_DELTA_SPACE(d); + lower[d] = origin[d]; + upper[d] = lower[d] + (gsh[d]-1) * delta[d]; + } + + // Define level topology + if (reflevel == 0) { + // Choose (arbitrarily) the root level as default topology, + // for readers which don't understand AMR + F5Rlink_default_vertex_topology (path, &v2h(reffact)[0]); + } + + // Define level geometry + F5Fwrite_linear (path, FIBER_HDF5_POSITIONS_STRING, + dim, &v2h(gsh)[0], + F5T_COORD3_DOUBLE, &v2d(lower), &v2d(delta)); + F5Fset_range (path, &v2d(lower), &v2d(upper)); + + + + BEGIN_LOCAL_COMPONENT_LOOP (cctkGH, CCTK_GF) { + DECLARE_CCTK_ARGUMENTS; + + // Determine component coordinates + ivect lbnd, lsh, lghosts, ughosts; + rvect clower, cupper; +#if 0 + F5_refinement3D_point_t iorigin, idelta; +#endif + 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 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]; + clower[d] = origin[d] + cctk_lbnd[d] * delta[d]; + cupper[d] = clower[d] + (lsh[d]-1) * delta[d]; +#if 0 + iorigin.d[d].num = + cctk_levoff[d] + cctk_lbnd[d] * cctk_levoffdenom[d]; + iorigin.d[d].denom = cctk_levoffdenom[d] * reffact[d]; + idelta .d[d].num = 1; + idelta .d[d].denom = reffact[d]; +#endif + } + ostringstream buf2; + buf2 << "component=" << component; + string const cname = buf2.str(); + +#if 0 + if (reflevel > 0) { + F5Fwrite_linear_fraction (refpath, FIBER_HDF5_POSITIONS_STRING, + cctk_dim, &v2h(gsh)[0], &v2h(lsh)[0], + F5T_COORD3_INT_FRACTION32, + &iorigin, &idelta, &v2h(lbnd)[0], + cname.c_str()); + } +#endif + + // Define coordinates + // (This is redundant, since the level's overall bounding + // box was already defined above, but it provides the + // individual components' bounding boxes.) + F5Fwrite_linear_fraction (path, FIBER_HDF5_POSITIONS_STRING, + cctk_dim, &v2h(gsh)[0], &v2h(lsh)[0], + F5T_COORD3_DOUBLE, + &clower, &delta, &v2h(lbnd)[0], + cname.c_str()); + + // Write data + // scalar field + F5Fwrite_fraction (path, "radius" /* group name */, + cctk_dim, &v2h(gsh)[0], &v2h(lsh)[0], + H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE, + r, + &v2h(lbnd)[0], &v2h(lghosts)[0], &v2h(ughosts)[0], + cname.c_str(), H5P_DEFAULT); + + // vector field + void const* data[dim]; + data[0] = x; + data[1] = y; + data[2] = z; + F5FSwrite_fraction (path, "coordinates" /* group name */, + cctk_dim, &v2h(gsh)[0], &v2h(lsh)[0], + F5T_VEC3_DOUBLE, F5T_VEC3_DOUBLE, + data, + &v2h(lbnd)[0], &v2h(lghosts)[0], &v2h(ughosts)[0], + cname.c_str(), H5P_DEFAULT, 0); + + } END_LOCAL_COMPONENT_LOOP; + + } END_LOCAL_MAP_LOOP; + + // Close topology + F5close (path); + + } END_REFLEVEL_LOOP; + + // Close file + herr = H5Fclose (file); + assert (not herr); + } + + + + // Use a class for reading data, so that we have an easy way to pass + // variables between the various iterators + class iterator_t { + cGH *cctkGH; + double time; + char const *gridname; + char const *topologyname; + int index_depth; // 0=vertex, 1=cell + int topological_dimension; + char const *fieldname; + char const *fragmentname; + + public: + iterator_t (cGH *const cctkGH_) + : cctkGH(cctkGH_), + time(nan), + gridname(NULL), + topologyname(NULL), index_depth(-1), topological_dimension(-1), + fieldname(NULL), + fragmentname(NULL) + { + } + + + + private: + + void read_timeslice (F5Path *const path) + { + cout << indent(1) << "time=" << time << "\n"; + F5iterate_grids (path, NULL, grid_iterator, this, NULL, NULL); + } + + void read_grid (F5Path *const path) + { + cout << indent(2) << "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) + { + herr_t herr; + + cout << indent(3) << "topology=\"" << topologyname << "\"" + << " (" << (index_depth==0 ? "vertex" : "cell") << ")\n"; + + // 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); + if (stat.type == H5G_LINK) { + char linkval[100000]; + herr = H5Gget_linkval + (path->Grid_hid, topologyname, sizeof linkval, linkval); + assert (not herr); + cout << indent(4) << "alias for topology \"" << linkval << "\"\n" + << indent(4) << "ignoring this topology\n"; + return; + } + + F5iterate_topology_fields (path, NULL, field_iterator, this, NULL, NULL); + } + + void read_field (F5Path *const path) + { + cout << indent(4) << "field=\"" << fieldname << "\"\n"; + F5iterate_field_fragments (path, NULL, fragment_iterator, this); + } + + void read_fragment (F5Path *const path) + { + herr_t herr; + + cout << indent(5) << "fragment=\"" << fragmentname << "\"\n"; + + if (strcmp(fieldname, "radius") == 0) { + + hid_t const group = path->Field_hid; + read_variable (group, fragmentname, CCTK_VarIndex("grid::r")); + + } else if (strcmp(fieldname, "coordinates") == 0) { + + hid_t const group = + H5Gopen (path->Field_hid, fragmentname, H5P_DEFAULT); + assert (group); + read_variable (group, "x", CCTK_VarIndex("grid::x")); + read_variable (group, "y", CCTK_VarIndex("grid::y")); + read_variable (group, "z", CCTK_VarIndex("grid::z")); + herr = H5Gclose (group); + assert (not herr); + + } else { + // do nothing + } + } + + void read_variable (hid_t const group, char const *const name, + int const var) + { + assert (group >= 0); + assert (name); + assert (var >= 0); + + cout << indent(6) << "dataset=\"" << name << "\"\n"; + // hid_t const fragment = H5Dopen(group, name); + // assert (fragment); + // + // hid_t const space = H5Dget_space(fragment); + // assert (space); + // int const rank = H5Sget_simple_extent_dims(space, NULL, NULL); + // assert (rank>=0); + // + // assert (rank == cctk_dim); + // + // H5Sclose(space_id); + } + + + + public: + + void iterate (hid_t const object) + { + F5iterate_timeslices (object, NULL, timeslice_iterator, this); + } + + static + herr_t timeslice_iterator (F5Path *const path, double const time, + void *const userdata) + { + iterator_t* const iterator = (iterator_t*)userdata; + iterator->time = time; + iterator->read_timeslice (path); + return 0; + } + + static + herr_t grid_iterator (F5Path *const path, char const *const gridname, + void *const userdata) + { + iterator_t* const iterator = (iterator_t*)userdata; + iterator->gridname = gridname; + 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) + { + iterator_t* const iterator = (iterator_t*)userdata; + iterator->topologyname = topologyname; + iterator->index_depth = index_depth; + iterator->topological_dimension = topological_dimension; + iterator->read_topology (path); + return 0; + } + + static + herr_t field_iterator (F5Path *const path, char const *const fieldname, + void *const userdata) + { + iterator_t* const iterator = (iterator_t*)userdata; + iterator->fieldname = fieldname; + iterator->read_field (path); + return 0; + } + + static + herr_t fragment_iterator (F5Path *const path, + char const *const fragmentname, + void *const userdata) + { + iterator_t* const iterator = (iterator_t*)userdata; + iterator->fragmentname = fragmentname; + iterator->read_fragment (path); + return 0; + } + + }; + + + + extern "C" + void F5_Input (CCTK_ARGUMENTS) + { + DECLARE_CCTK_ARGUMENTS; + DECLARE_CCTK_PARAMETERS; + + herr_t herr; + + + + assert (is_global_mode()); + CCTK_VInfo (CCTK_THORNSTRING, "F5_Input: iteration=%d", cctk_iteration); + + + + // Open file + string const basename = + generate_basename (cctkGH, CCTK_VarIndex("grid::r")); + string const name = + create_filename (cctkGH, basename, false); + + hid_t const file = H5Fopen (name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); + assert (file >= 0); + + // Iterate over all time slices + iterator_t iterator(cctkGH); + iterator.iterate (file); + + // Close file + herr = H5Fclose (file); + assert (not herr); + } + +} // end namespace CarpetIOF5 |