aboutsummaryrefslogtreecommitdiff
path: root/CarpetDev/CarpetIOF5_standalone/src/writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'CarpetDev/CarpetIOF5_standalone/src/writer.cc')
-rw-r--r--CarpetDev/CarpetIOF5_standalone/src/writer.cc400
1 files changed, 400 insertions, 0 deletions
diff --git a/CarpetDev/CarpetIOF5_standalone/src/writer.cc b/CarpetDev/CarpetIOF5_standalone/src/writer.cc
new file mode 100644
index 000000000..a07e1d94f
--- /dev/null
+++ b/CarpetDev/CarpetIOF5_standalone/src/writer.cc
@@ -0,0 +1,400 @@
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include <hdf5.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "carpet.hh"
+#include "modes.hh"
+
+#include "data_region.hh"
+#include "file.hh"
+#include "meta_data_region.hh"
+#include "physical_quantity.hh"
+#include "simulation.hh"
+#include "tensor_component.hh"
+#include "timestep.hh"
+#include "topology.hh"
+#include "utils.hh"
+#include "writer.hh"
+
+
+
+namespace CarpetIOF5 {
+
+ writer_t::
+ writer_t (cGH const * const cctkGH,
+ int const variable)
+ : m_cctkGH (cctkGH),
+ m_variable (variable)
+ {
+ }
+
+
+
+ void writer_t::
+ write (F5::file_t & file)
+ const
+ {
+ write_meta (file);
+ }
+
+
+
+ void writer_t::
+ write_meta (F5::file_t & file)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_meta");
+ }
+
+ F5::timestep_t timestep (file, m_cctkGH->cctk_time);
+
+ if (Carpet::is_meta_mode())
+ {
+ BEGIN_MGLEVEL_LOOP (m_cctkGH)
+ {
+ write_one_mglevel (timestep);
+ }
+ END_MGLEVEL_LOOP;
+ }
+ else
+ {
+ write_one_mglevel (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_mglevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_mglevel mglevel=%d",
+ Carpet::mglevel);
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype >= 0);
+ switch (grouptype)
+ {
+ case CCTK_ARRAY:
+ case CCTK_SCALAR:
+ {
+ if (Carpet::is_global_mode())
+ {
+ ENTER_LEVEL_MODE (m_cctkGH, 0)
+ {
+ write_global (timestep);
+ }
+ LEAVE_LEVEL_MODE;
+ }
+ else
+ {
+ if (Carpet::do_global_mode)
+ {
+ write_global (timestep);
+ }
+ }
+ }
+ break;
+ case CCTK_GF:
+ {
+ if (Carpet::is_global_mode())
+ {
+ BEGIN_REFLEVEL_LOOP (m_cctkGH)
+ {
+ write_one_reflevel (timestep);
+ }
+ END_REFLEVEL_LOOP;
+ }
+ else
+ {
+ write_one_reflevel (timestep);
+ }
+ }
+ break;
+ default:
+ assert (0);
+ }
+ }
+
+
+
+ void writer_t::
+ write_global (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_global");
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype == CCTK_SCALAR or grouptype == CCTK_ARRAY);
+
+ BEGIN_MAP_LOOP (m_cctkGH, grouptype)
+ {
+
+ // Name the grid after the variable group
+ ostringstream namebuf;
+ char * const c_name = CCTK_GroupNameFromVarI (m_variable);
+ namebuf << "Cactus-" << c_name;
+ free (c_name);
+ string const name = namebuf.str();
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::unigrid_topology_t topology (simulation);
+
+ vect<CCTK_REAL, dim> const level_origin (0.0), level_delta (1.0);
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ int const myproc = CCTK_MyProc (m_cctkGH);
+
+ F5::file_t & file = timestep.get_file();
+ bool const write_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (write_metafile)
+ {
+
+ BEGIN_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ dh * const dd = Carpet::arrdata.at(group).at(Carpet::map).dd;
+ dh::light_dboxes const & light_boxes
+ = dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (light_boxes);
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+ END_COMPONENT_LOOP;
+
+ }
+ else // if not write_metafile
+ {
+
+ BEGIN_LOCAL_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ dh * const dd = Carpet::arrdata.at(group).at(Carpet::map).dd;
+ dh::light_dboxes const & light_boxes
+ = dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel).at(myproc);
+ bbox<int, dim> const & region = determine_region (light_boxes);
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ END_LOCAL_COMPONENT_LOOP;
+
+ } // if not write_metafile
+
+ }
+ END_MAP_LOOP;
+ }
+
+
+
+ void writer_t::
+ write_one_reflevel (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_reflevel reflevel=%d",
+ Carpet::reflevel);
+ }
+
+ int const grouptype = CCTK_GroupTypeFromVarI (m_variable);
+ assert (grouptype == CCTK_GF);
+
+ if (Carpet::is_level_mode())
+ {
+ BEGIN_MAP_LOOP (m_cctkGH, grouptype)
+ {
+ write_one_map (timestep);
+ }
+ END_MAP_LOOP;
+ }
+ else
+ {
+ write_one_map (timestep);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_map (F5::timestep_t & timestep)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_map map=%d", Carpet::map);
+ }
+
+ // Name the grid after the map number
+ ostringstream namebuf;
+ namebuf << "Carpet";
+ if (Carpet::maps > 1)
+ {
+ namebuf << "-map" << Carpet::map;
+ }
+ string const name = namebuf.str();
+ F5::simulation_t simulation (timestep, name.c_str());
+
+ F5::mesh_refinement_topology_t topology
+ (simulation,
+ Carpet::map, Carpet::maps, Carpet::reflevel, Carpet::maxreflevels,
+ Carpet::spacereflevelfact, Carpet::maxspacereflevelfact);
+
+ vect<CCTK_REAL, dim> level_origin, level_delta;
+ for (int d=0; d<dim; ++d)
+ {
+ cGH const * const cctkGH = m_cctkGH;
+ DECLARE_CCTK_ARGUMENTS;
+ level_origin[d] = CCTK_ORIGIN_SPACE(d);
+ level_delta[d] = CCTK_DELTA_SPACE(d);
+ }
+ F5::Cartesian_coordinate_system_t coordinate_system
+ (topology, level_origin, level_delta);
+
+ int const group = CCTK_GroupIndexFromVarI (m_variable);
+ assert (group >= 0 and group < CCTK_NumGroups());
+ F5::physical_quantity_t physical_quantity (coordinate_system, group);
+
+ if (Carpet::is_singlemap_mode())
+ {
+ int const grouptype = CCTK_GroupTypeI (group);
+ assert (grouptype >= 0);
+
+ BEGIN_COMPONENT_LOOP (m_cctkGH, grouptype)
+ {
+ write_one_component (physical_quantity);
+ }
+ END_COMPONENT_LOOP;
+ }
+ else
+ {
+ write_one_component (physical_quantity);
+ }
+ }
+
+
+
+ void writer_t::
+ write_one_component (F5::physical_quantity_t & physical_quantity)
+ const
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose or veryverbose)
+ {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "OutputVarAs/write_one_component component=%d",
+ Carpet::component);
+ }
+
+ gh * const hh = Carpet::vhh.at(Carpet::map);
+ bool const is_local = hh->is_local (Carpet::reflevel, Carpet::component);
+
+ F5::file_t & file
+ = (physical_quantity.get_coordinate_system().get_topology()
+ .get_simulation().get_timestep().get_file());
+ bool const write_metafile
+ = file.get_is_metafile() and not file.get_is_datafile();
+ if (write_metafile or is_local)
+ {
+ dh * const dd = Carpet::vdd.at(Carpet::map);
+ bbox<int, dim> const & region
+ = (dd->light_boxes.at(Carpet::mglevel).at(Carpet::reflevel)
+ .at(Carpet::component).exterior);
+
+ if (write_metafile)
+ {
+ F5::meta_data_region_t meta_data_region (physical_quantity, region);
+ int const proc = hh->processor (Carpet::reflevel, Carpet::component);
+ meta_data_region.write (proc);
+ }
+ else if (is_local)
+ {
+ F5::data_region_t data_region (physical_quantity, region);
+
+ F5::tensor_component_t tensor_component (data_region, m_variable);
+ int const timelevel = 0;
+ void const * const varptr
+ = CCTK_VarDataPtrI (m_cctkGH, timelevel, m_variable);
+ assert (varptr != 0);
+ int const vartype = CCTK_VarTypeI (m_variable);
+ assert (vartype >= 0);
+ tensor_component.write (varptr, vartype);
+ }
+ }
+ }
+
+
+
+ bbox<int,dim> const & writer_t::
+ determine_region (dh::light_dboxes const & light_boxes)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ // TODO: use superregions instead of regions (? only if the
+ // regions are on the same processor?)
+
+ bbox<int,dim> dh::light_dboxes::* boxptr;
+ if (CCTK_EQUALS (output_regions, "exterior"))
+ {
+ boxptr = & dh::light_dboxes::exterior;
+ }
+ else if (CCTK_EQUALS (output_regions, "owned"))
+ {
+ boxptr = & dh::light_dboxes::owned;
+ }
+ else if (CCTK_EQUALS (output_regions, "interior"))
+ {
+ boxptr = & dh::light_dboxes::interior;
+ }
+ else
+ {
+ assert (0);
+ }
+
+ return light_boxes.*boxptr;
+ }
+
+} // namespace CarpetIOF5