From 757a96941a5f126bfbfb6d064dfac786b26a2ad7 Mon Sep 17 00:00:00 2001 From: Josh Bowden Date: Tue, 12 Dec 2023 21:48:17 +0100 Subject: [PATCH] final review changes from PR 4889 and added extra command line argument to output mesh data --damaris-save-mesh-to-hdf --- ebos/damariswriter.hh | 56 +- ebos/eclproblem_properties.hh | 6 +- opm/simulators/utils/DamarisKeywords.cpp | 62 +- opm/simulators/utils/DamarisKeywords.hpp | 44 +- opm/simulators/utils/DamarisOutputModule.cpp | 12 +- opm/simulators/utils/DamarisOutputModule.hpp | 8 +- opm/simulators/utils/DamarisVar.hpp | 1255 +++++++++--------- opm/simulators/utils/GridDataOutput.hpp | 1196 ++++++++--------- opm/simulators/utils/initDamarisXmlFile.cpp | 12 +- 9 files changed, 1326 insertions(+), 1325 deletions(-) diff --git a/ebos/damariswriter.hh b/ebos/damariswriter.hh index 1d94b5d26..c6d405ccd 100644 --- a/ebos/damariswriter.hh +++ b/ebos/damariswriter.hh @@ -50,6 +50,7 @@ #include #include #include +#include #include @@ -66,7 +67,11 @@ struct EnableDamarisOutput { using type = UndefinedProperty; }; template -struct EnableDamarisOutputCollective { +struct DamarisOutputHdfCollective { + using type = UndefinedProperty; +}; +template +struct DamarisSaveMeshToHdf { using type = UndefinedProperty; }; template @@ -145,11 +150,16 @@ class DamarisWriter : public EclGenericWriter>( - // 1, {std::string("n_elements_local")}, std::string("MPI_RANK"), rank_)) ; - // std::unique_ptr> + // This is an example of writing to the Damaris shared memory directly (i.e. not using + // damaris_write() to copy data there) + // We will add the MPI rank value directly into shared memory using the DamarisVar + // wrapper of the C based Damaris API. + // The shared memory is given back to Damaris on object deletion - i.e. when the + // unique_ptr goes out of scope. std::unique_ptr mpi_rank_var( new DamarisVarInt(1, {std::string("n_elements_local")}, - std::string("MPI_RANK"), rank_) ) ; + std::string("MPI_RANK"), rank_) ); + // N.B. we have not set any offset values, so HDF5 collective and Dask arrays cannot be used. mpi_rank_var->setDamarisParameterAndShmem( {this->numElements_ } ) ; // Fill the created memory area @@ -406,11 +417,6 @@ private: "damaris_set_position(\"GLOBAL_CELL_INDEX\", temp_int64_t);"); } - //auto mpi_rank_var = std::make_unique>( - // 1, {std::string("n_elements_local")}, std::string("MPI_RANK"), rank_)) ; - - // std::unique_ptr> - // mpi_rank_var(new Opm::DamarisOutput::DamarisVar(1, {std::string("n_elements_local")}, std::string("MPI_RANK"), rank_)) ; std::unique_ptr mpi_rank_var( new DamarisVarInt(1, {std::string("n_elements_local")}, std::string("MPI_RANK"), rank_) ) ; @@ -442,19 +448,17 @@ private: // // - std::unique_ptr> var_x(new Opm::DamarisOutput::DamarisVar(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/x"), rank_)) ; + std::unique_ptr var_x(new DamarisVarDbl(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/x"), rank_)) ; // N.B. We have not set any position/offset values (using DamarisVar::SetDamarisPosition). // They are not needed for mesh data as each process has a local geometric model. // However, HDF5 collective and Dask arrays cannot be used for this data. var_x->setDamarisParameterAndShmem( { geomData.getNVertices() } ) ; - std::unique_ptr> var_y(new Opm::DamarisOutput::DamarisVar(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/y"), rank_)) ; - var_y->parameterIsSet() ; - var_y->setPointersToDamarisShmem() ; + std::unique_ptr var_y(new DamarisVarDbl(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/y"), rank_)) ; + var_y->setDamarisParameterAndShmem( { geomData.getNVertices() } ) ; - std::unique_ptr> var_z(new Opm::DamarisOutput::DamarisVar(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/z"), rank_)) ; - var_z->parameterIsSet() ; - var_z->setPointersToDamarisShmem() ; + std::unique_ptr var_z(new DamarisVarDbl(1, {std::string("n_coords_local")}, std::string("coordset/coords/values/z"), rank_)) ; + var_z->setDamarisParameterAndShmem( { geomData.getNVertices() } ) ; // Now we can return the memory that Damaris has allocated in shmem and use it to write the X,y,z coordinates double itime, ftime, exec_time; @@ -462,8 +466,8 @@ private: if ( geomData.writeGridPoints(*var_x,*var_y,*var_z) < 0) DUNE_THROW(Dune::IOError, geomData.getError() ); - //if ( geomData.writeGridPoints(var_x->data(),var_y->data(),var_z->data()) < 0) - // DUNE_THROW(Dune::IOError, geomData.getError() ); + if ( geomData.writeGridPoints(var_x->data(),var_y->data(),var_z->data(), geomData.getNVertices()) < 0) + DUNE_THROW(Dune::IOError, geomData.getError() ); ftime = omp_get_wtime(); exec_time = ftime - itime; @@ -489,8 +493,7 @@ private: std::unique_ptr var_offsets(new DamarisVarInt(1, {std::string("n_offsets_types_ph")}, std::string("topologies/topo/elements/offsets"), rank_)) ; var_offsets->setDamarisParameterAndShmem({ geomData.getNCells()}) ; std::unique_ptr var_types(new DamarisVarChar(1, {std::string("n_offsets_types_ph")}, std::string("topologies/topo/elements/types"), rank_)) ; - var_types->parameterIsSet() ; - var_types->setPointersToDamarisShmem() ; + var_types->setDamarisParameterAndShmem({ geomData.getNCells()}) ; // Copy the mesh data from the Durne grid long i = 0 ; @@ -507,6 +510,7 @@ private: i = geomData.writeCellTypes(*var_types) ; if ( i != geomData.getNCells()) DUNE_THROW(Dune::IOError,geomData.getError()); + } catch (std::exception& e) { diff --git a/ebos/eclproblem_properties.hh b/ebos/eclproblem_properties.hh index 1782b0daa..b18518363 100644 --- a/ebos/eclproblem_properties.hh +++ b/ebos/eclproblem_properties.hh @@ -394,10 +394,14 @@ struct EnableDamarisOutput { }; // If Damaris is available, write specific variable output in parallel template -struct EnableDamarisOutputCollective { +struct DamarisOutputHdfCollective { static constexpr bool value = true; }; template +struct DamarisSaveMeshToHdf { + static constexpr bool value = false; +}; +template struct DamarisSaveToHdf { static constexpr bool value = true; }; diff --git a/opm/simulators/utils/DamarisKeywords.cpp b/opm/simulators/utils/DamarisKeywords.cpp index 4d8f2f771..6b335de93 100644 --- a/opm/simulators/utils/DamarisKeywords.cpp +++ b/opm/simulators/utils/DamarisKeywords.cpp @@ -83,7 +83,7 @@ DamarisSettings::getKeywords([[maybe_unused]] const Parallel::Communication& com const std::string& OutputDir) { std::string saveToHDF5_str("MyStore"); - if (! saveToDamarisHDF5 ){ + if (! saveToDamarisHDF5_ ){ saveToHDF5_str = "#"; } @@ -96,43 +96,43 @@ DamarisSettings::getKeywords([[maybe_unused]] const Parallel::Communication& com std::string publishToPython_str("#"); // to be changed to the name of the PyScript XML element #ifdef HAVE_PYTHON_ENABLED // Test if input Python file exists and set the name of the script for )XML elements - if (pythonFilename != ""){ - if (FileExists(pythonFilename, comm)) { + if (pythonFilename_ != ""){ + if (FileExists(pythonFilename_, comm)) { publishToPython_str="PythonScript"; // the name of the PyScript XML element disablePythonXMLstart.clear(); disablePythonXMLfin.clear(); } else { - pythonFilename.clear(); // set to empty if it does not exist + pythonFilename_.clear(); // set to empty if it does not exist disablePythonXMLstart = std::string("!--"); disablePythonXMLfin = std::string("--"); } } #else OpmLog::info(fmt::format("INFO: Opm::DamarisOutput::DamarisKeywords() : Python is not enabled in the Damaris library. " - "The commandline --damaris-python-script={} will be set to empty string", pythonFilename)); - pythonFilename.clear(); + "The commandline --damaris-python-script={} will be set to empty string", pythonFilename_)); + pythonFilename_.clear(); #endif #ifdef HAVE_PARAVIEW_ENABLED // Test if input Paraview Python file exists - if (paraviewPythonFilename != ""){ - if (FileExists(paraviewPythonFilename, comm)) { + if (paraviewPythonFilename_ != ""){ + if (FileExists(paraviewPythonFilename_, comm)) { disableParaviewXMLstart.clear(); disableParaviewXMLfin.clear(); } else { - paraviewPythonFilename.clear(); // set to empty if it does not exist + paraviewPythonFilename_.clear(); // set to empty if it does not exist disableParaviewXMLstart = std::string("!--"); disableParaviewXMLfin = std::string("--"); } } #else OpmLog::info(fmt::format("INFO: Opm::DamarisOutput::DamarisKeywords() : Paraview is not enabled in the Damaris library. " - "The commandline --damaris-python-paraview-script={} will be set to empty string", paraviewPythonFilename)); - paraviewPythonFilename.clear(); + "The commandline --damaris-python-paraview-script={} will be set to empty string", paraviewPythonFilename_)); + paraviewPythonFilename_.clear(); #endif // Flag error if both scripts are enabled - if ((pythonFilename.size() > 0) && (paraviewPythonFilename.size() > 0) ) + if ((pythonFilename_.size() > 0) && (paraviewPythonFilename_.size() > 0) ) { // A work around of this issue is to remove the Paraview mpi4py library (use print(inspect.getfile(mpi4py))) // and then possibly not use mpi4py in the Paraview script code. OR try to install paraview mpi4py with headers. @@ -142,16 +142,21 @@ DamarisSettings::getKeywords([[maybe_unused]] const Parallel::Communication& com "locally and without header files). " "Please choose one or the other method of analysis for now. Exiting." ); } - + + std::string saveMeshToHDF5_str("#"); + if (saveMeshToHDF5_ == true) { + enableDamarisOutputCollective_ = false ; + saveMeshToHDF5_str = "MyStore" ; + } std::string damarisOutputCollective_str; - if (enableDamarisOutputCollective) { + if (enableDamarisOutputCollective_) { damarisOutputCollective_str = "Collective"; } else { damarisOutputCollective_str = "FilePerCore"; } std::string simName_str; - if (damarisSimName.empty()) { + if (damarisSimName_.empty()) { // Having a different simulation name is important if multiple simulations // are running on the same node, as it is used to name the simulations shmem area // and when one sim finishes it removes its shmem file. @@ -169,35 +174,35 @@ DamarisSettings::getKeywords([[maybe_unused]] const Parallel::Communication& com simName_str = "opm-flow-" + simName_str; } } else { - simName_str = damarisSimName; + simName_str = damarisSimName_; } - if ((nDamarisCores > 0) && (nDamarisNodes > 0)) + if ((nDamarisCores_ > 0) && (nDamarisNodes_ > 0)) { - nDamarisNodes = 0; // Default is to use Damaris Cores + nDamarisNodes_ = 0; // Default is to use Damaris Cores } std::string nDamarisCores_str; - if ( nDamarisCores != 0 ) { - nDamarisCores_str = std::to_string(nDamarisCores); + if ( nDamarisCores_ != 0 ) { + nDamarisCores_str = std::to_string(nDamarisCores_); } else { nDamarisCores_str = "0"; } std::string nDamarisNodes_str; - if ( nDamarisNodes != 0 ) { - nDamarisNodes_str = std::to_string(nDamarisNodes); + if ( nDamarisNodes_ != 0 ) { + nDamarisNodes_str = std::to_string(nDamarisNodes_); } else { nDamarisNodes_str = "0"; } std::string shmemSizeBytes_str; - if (shmemSizeBytes != 0) { - shmemSizeBytes_str = std::to_string(shmemSizeBytes); + if (shmemSizeBytes_ != 0) { + shmemSizeBytes_str = std::to_string(shmemSizeBytes_); } else { shmemSizeBytes_str = "536870912"; // 512 MB } - std::string logLevel_str(damarisLogLevel); + std::string logLevel_str(damarisLogLevel_); std::string logFlush_str("false"); if ((logLevel_str == "debug") || (logLevel_str == "trace") ) { logFlush_str = "true"; @@ -211,8 +216,9 @@ DamarisSettings::getKeywords([[maybe_unused]] const Parallel::Communication& com {"_MORE_VARIABLES_REGEX_", ""}, {"_PATH_REGEX_", OutputDir}, /* Do Not change the string "_PATH_REGEX_" as it is used to search for the output path */ {"_MYSTORE_OR_EMPTY_REGEX_", saveToHDF5_str}, - {"_PARAVIEW_PYTHON_SCRIPT_",paraviewPythonFilename}, /* this has to be before _PYTHON_SCRIPT_ entry */ - {"_PYTHON_SCRIPT_",pythonFilename}, /* if a Python script is specified then assume that we want to publish the data to Python */ + {"_MYSTORE_MESH_OR_EMPTY_REGEX_", saveMeshToHDF5_str}, + {"_PARAVIEW_PYTHON_SCRIPT_",paraviewPythonFilename_}, /* this has to be before _PYTHON_SCRIPT_ entry */ + {"_PYTHON_SCRIPT_",pythonFilename_}, /* if a Python script is specified then assume that we want to publish the data to Python */ {"_PRESSURE_UNIT_","Pa"}, {"_MAKE_AVAILABLE_IN_PYTHON_",publishToPython_str}, /* must match - std::string damarisLogLevel = "info"; - std::string damarisDaskFile = ""; - int nDamarisCores = 1; - int nDamarisNodes = 0; - long shmemSizeBytes = 536870912; // 512 MB + std::string damarisSimName_; // empty defaults to opm-sim- + std::string damarisLogLevel_ = "info"; + std::string damarisDaskFile_ = ""; + int nDamarisCores_ = 1; // this is the number of (Damaris server) cores per node + int nDamarisNodes_ = 0; + long shmemSizeBytes_ = 536870912; // 512 MB std::map getKeywords(const Parallel::Communication& comm, @@ -81,16 +84,17 @@ getDamarisKeywords(const Parallel::Communication& comm, const std::string& Outpu DamarisSettings settings; // Get all of the Damaris keywords (except for --enable-damaris, which is used in simulators/flow/Main.hpp) // These command line arguments are defined in ebos/damariswriter.hh and defaults are set in ebos/eclproblem_properties.hh - settings.enableDamarisOutputCollective = EWOMS_GET_PARAM(TypeTag, bool, EnableDamarisOutputCollective); - settings.saveToDamarisHDF5 = EWOMS_GET_PARAM(TypeTag, bool, DamarisSaveToHdf); - settings.pythonFilename = EWOMS_GET_PARAM(TypeTag, std::string, DamarisPythonScript); - settings.paraviewPythonFilename = EWOMS_GET_PARAM(TypeTag, std::string, DamarisPythonParaviewScript); - settings.damarisSimName = EWOMS_GET_PARAM(TypeTag, std::string, DamarisSimName); - settings.nDamarisCores = EWOMS_GET_PARAM(TypeTag, int, DamarisDedicatedCores); - settings.nDamarisNodes = EWOMS_GET_PARAM(TypeTag, int, DamarisDedicatedNodes); - settings.shmemSizeBytes = EWOMS_GET_PARAM(TypeTag, long, DamarisSharedMemorySizeBytes); - settings.damarisLogLevel = EWOMS_GET_PARAM(TypeTag, std::string, DamarisLogLevel); - settings.damarisDaskFile = EWOMS_GET_PARAM(TypeTag, std::string, DamarisDaskFile); + settings.enableDamarisOutputCollective_ = EWOMS_GET_PARAM(TypeTag, bool, DamarisOutputHdfCollective); + settings.saveMeshToHDF5_ = EWOMS_GET_PARAM(TypeTag, bool, DamarisSaveMeshToHdf); + settings.saveToDamarisHDF5_ = EWOMS_GET_PARAM(TypeTag, bool, DamarisSaveToHdf); + settings.pythonFilename_ = EWOMS_GET_PARAM(TypeTag, std::string, DamarisPythonScript); + settings.paraviewPythonFilename_ = EWOMS_GET_PARAM(TypeTag, std::string, DamarisPythonParaviewScript); + settings.damarisSimName_ = EWOMS_GET_PARAM(TypeTag, std::string, DamarisSimName); + settings.nDamarisCores_ = EWOMS_GET_PARAM(TypeTag, int, DamarisDedicatedCores); + settings.nDamarisNodes_ = EWOMS_GET_PARAM(TypeTag, int, DamarisDedicatedNodes); + settings.shmemSizeBytes_ = EWOMS_GET_PARAM(TypeTag, long, DamarisSharedMemorySizeBytes); + settings.damarisLogLevel_ = EWOMS_GET_PARAM(TypeTag, std::string, DamarisLogLevel); + settings.damarisDaskFile_ = EWOMS_GET_PARAM(TypeTag, std::string, DamarisDaskFile); return settings.getKeywords(comm, OutputDir); } diff --git a/opm/simulators/utils/DamarisOutputModule.cpp b/opm/simulators/utils/DamarisOutputModule.cpp index 3e75852e4..bafda99fb 100644 --- a/opm/simulators/utils/DamarisOutputModule.cpp +++ b/opm/simulators/utils/DamarisOutputModule.cpp @@ -21,6 +21,8 @@ #define XSD_CXX11_TEMPLATE_ALIAS 1 +#include + #include #include #include @@ -37,10 +39,10 @@ std::string initDamarisXmlFile(); // Defined in initDamarisXMLFile.cpp, to avoid /** * Initialize Damaris by either reading a file specified by the environment variable FLOW_DAMARIS_XML_FILE or - * by filling in th XML file and storing it in the chosen directory + * by filling in the XML file and storing it in the chosen directory */ void -initializeDamaris(MPI_Comm comm, int mpiRank, std::map& find_replace_map ) +initializeDamaris(const MPI_Comm comm, const int mpiRank, const std::map& find_replace_map ) { int dam_err; @@ -63,14 +65,16 @@ initializeDamaris(MPI_Comm comm, int mpiRank, std::map // std::map find_replace_map = DamarisKeywords(outputDir, enableDamarisOutputCollective); myMod.RepalceWithRegEx(find_replace_map); - std::string outputDir = find_replace_map["_PATH_REGEX_"]; + std::string outputDir = find_replace_map.at("_PATH_REGEX_"); std::string damaris_xml_filename_str = outputDir + "/damaris_config.xml"; if (mpiRank == 0) { myMod.SaveXMLStringToFile(damaris_xml_filename_str); } - OpmLog::info("Initializing Damaris using internally built file: " + damaris_xml_filename_str + " (N.B. use environment variable FLOW_DAMARIS_XML_FILE to override)"); + OpmLog::info("Initializing Damaris using internally built file: " + damaris_xml_filename_str + + " (N.B. use environment variable FLOW_DAMARIS_XML_FILE to override)"); + dam_err = damaris_initialize(damaris_xml_filename_str.c_str(), comm); if (dam_err != DAMARIS_OK) { OpmLog::error(fmt::format("damariswriter::initializeDamaris() : ( rank:{}) " diff --git a/opm/simulators/utils/DamarisOutputModule.hpp b/opm/simulators/utils/DamarisOutputModule.hpp index e8b950ceb..f480b7230 100644 --- a/opm/simulators/utils/DamarisOutputModule.hpp +++ b/opm/simulators/utils/DamarisOutputModule.hpp @@ -18,8 +18,6 @@ along with OPM. If not, see . */ -#include - #include #include @@ -28,10 +26,6 @@ #include -#if HAVE_MPI -#include -#endif - #include #include @@ -54,6 +48,6 @@ namespace Opm::DamarisOutput * 2/ Reading a file specified by the environment variable FLOW_DAMARIS_XML_FILE * */ - void initializeDamaris(MPI_Comm comm, int mpiRank, std::map& find_replace_map ); + void initializeDamaris(const MPI_Comm comm, const int mpiRank, const std::map& find_replace_map ); } // namespace Opm::DamarisOutput diff --git a/opm/simulators/utils/DamarisVar.hpp b/opm/simulators/utils/DamarisVar.hpp index ff2116a48..f81c3cb2a 100644 --- a/opm/simulators/utils/DamarisVar.hpp +++ b/opm/simulators/utils/DamarisVar.hpp @@ -1,3 +1,5 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: /* Copyright 2023 Inria, Bretagne–Atlantique Research Center @@ -20,682 +22,685 @@ #ifndef DAMARISVAR_HPP #define DAMARISVAR_HPP -#include +#include #include #include -#include +#include #include #define BOOST_BIND_GLOBAL_PLACEHOLDERS 1 #include -#include -#include -#include /* File: DamarisVar.hpp Author: Joshua Bowden, Inria Date: 06/02/2023 - The DamarisVar class can be used to allocate memory in the Damaris shared memory region and a user can supply - the data required for the variable. This data will then be directly available to the Damaris server side (server core) plugin code. + The DamarisVar class can be used to allocate memory in the Damaris shared + memory region and a user can supply the data required for the variable via the data_ptr_ + or data() method. The data will then be directly available on the Damaris server side + (server cores) plugin code. The templated type used should match the one specified + in the Damaris XML file for the variable name, if not an error is raised. */ +namespace Opm { +namespace DamarisOutput { +/** + * This class contains the extra elements that need to be part of a Damaris + * type. They are simple string values that may reference other XML + * elements (and could be checked for existence etc.) + */ +class DamarisVarXMLAttributes { + std::string layout_; //!< Reference string to the XML attribute layout being + //!< used to describe the shape of the variable. This is + //!< a required attribute. + std::string + mesh_; //!< Reference string to the XML attribute mesh element - the mesh + //!< is used to define the spatial layout of data and is used by + //!< visualization backends to generate 2D/3D model images + std::string + type_; //!< Reference string to the XML attribute type of data - "scalar" + //!< or "vector" (others tensor maybe). TODO: check if this + //!< attribute is used by the Damaris library anywhere. + std::string + visualizable_; //!< Reference string to the XML attribute property that + //!< data can be sent to vis backends - "true" | "false" + std::string unit_; //!< Reference string to the XML attribute element denoting + //!< unit of the data + std::string + time_varying_; //!< Reference string to the XML attribute to indicate if + //!< data changes over iterations - "true" | "false" + std::string centering_; //!< Reference string to the XML attribute to indicate + //!< where data aligns on a mesh - "zonal" | "nodal" + std::string + store_; //!< Reference string to the XML attribute to indicate if data + //!< should be passed to I/O store (e.g. to HDF5 plugin) + std::string script_; //!< Reference string to the XML attribute to indicate if + //!< data should be published as Python NumPy data + std::string + select_mem_; //!< Reference string to the XML attribute select. The + //!< referenced variables data is used as indices to select + //!< dat from memory to reorder output in the collective HDF5 + //!< data writer (Damaris version 1.8+) + std::string + select_file_; //!< Reference string to the XML attribute select. The + //!< referenced variables data is used as indices to select + //!< positions in the dataset file to reorder output in the + //!< collective HDF5 data writer (Damaris version 1.8+) + std::string + select_subset_; //!< Reference string to the XML attribute select. Used to + //!< specify the output dataset shape and how much data + //!< each rank contributes to it and the global offsets to + //!< the ranks data (Damaris version 1.8+) -namespace Opm -{ - namespace DamarisOutput - { - /** - * This class contains the extra elements that need to be part of a Damaris type. - * They are simple string values that may reference other XML elements (and could be checked for existence etc.) +public: + DamarisVarXMLAttributes() { + // Additional data needed to complete an XML element + layout_ = ""; + mesh_ = ""; + type_ = + "scalar"; // This is probably not needed as vector data is defined using + // the Layout paramter. Could be useful for cross checking + visualizable_ = "false"; + unit_ = ""; + time_varying_ = "true"; + centering_ = "zonal"; + store_ = ""; + script_ = ""; + select_mem_ = ""; + } + + /** + * Creates the XML representation of the variable from the available strings + */ + std::string ReturnXMLForVariable(void) { + std::ostringstream var_sstr; + + var_sstr << " layout=\"" << this->layout_ << "\""; + if (this->mesh_ != "") + var_sstr << " mesh=\"" << this->mesh_ << "\""; + if (this->type_ != "") + var_sstr << " type=\"" << this->type_ << "\""; + if (this->visualizable_ != "") + var_sstr << " visualizable=\"" << this->visualizable_ << "\""; + if (this->unit_ != "") + var_sstr << " unit=\"" << this->unit_ << "\""; + if (this->time_varying_ != "") + var_sstr << " time_varying=\"" << this->time_varying_ << "\""; + if (this->centering_ != "") + var_sstr << " centering=\"" << this->centering_ << "\""; + if (this->store_ != "") + var_sstr << " store=\"" << this->store_ << "\""; + if (this->script_ != "") + var_sstr << " script=\"" << this->script_ << "\""; + if (this->select_mem_ != "") + var_sstr << " select-mem=\"" << this->select_mem_ << "\""; + if (this->select_file_ != "") + var_sstr << " select-file=\"" << this->select_file_ << "\""; + if (this->select_subset_ != "") + var_sstr << " select-subset=\"" << this->select_subset_ << "\""; + + return (var_sstr.str()); + } +}; + +class DamarisVarBase { +public: + virtual ~DamarisVarBase(void){}; + virtual void printError(void) = 0; + virtual bool hasError(void) = 0; + virtual void + setDamarisParameterAndShmem(const std::vector ¶mSizeVal) = 0; + virtual void setDamarisParameter(const std::vector ¶mSizeVal) = 0; + virtual void + setDamarisPosition(const std::vector &positionsVals) = 0; + virtual void setPointersToDamarisShmem(void) = 0; + virtual void commitVariableDamarisShmem(void) = 0; + virtual void clearVariableDamarisShmem(void) = 0; + virtual std::string &variable_name(void) = 0; +}; // class DamarisVarBase + +/** + * class to store a Damaris variable representation for the XML file (can be + * used with /ref class DamarisKeywords). + * + * It is thought that the details stored in the object can be used to pass into + * an XML generation function e.g. DamarisKeywords + * + * Should be instantiated with something like the following: + * // The following needs to be defined in the Damaris XML file: + * // + * // + * // damaris::model::DamarisVar dam_var = new + * damaris::model::DamarisVar(1, {std::string("n_connectivity_ph")}, + * std::string("topologies/topo/elements/connectivity"), rank_); + * dam_var->SetDamarisParameterAndShmem( { geomData.getNCorners() } ); + * + * int * shmem_mpi_ptr = dam_var->data_ptr(); + * // Fill the created memory area + * for (int i = 0; i <; i++ ) + * { + * shmem_mpi_ptr[i] = rank_; + * } + * delete dam_var; // this tells Damaris that the shared memory that it + * supplied is at its disposal. It will print error messages too. + * + */ +template class DamarisVar : public DamarisVarBase { + int dims_; + int num_params_; //!< Each paramater name string will need a value and they + //!< are set in SetDamarisParameter() + std::vector + param_sizes_; //!< The value for any paramaters that are being used to + //!< describe the size of the variables data array + std::vector + positions_; //!< The offsets into the array that the data in the Variable + //!< starts from for this rank. + int rank_; //!< Rank of process - used for error reporting. + bool parameters_set_; //!< set to true after SetDamarisParameter() is call to + //!< ensure the variable has correct size for memory + //!< allocation in SetPointersToDamarisShmem() + std::vector + param_names_; //!< Contains one paramater name for each paramater that a + //!< variable depends on (via it's Layout) + std::string variable_name_; //!< Reference string to the XML attribute name of + //!< the variable. + int dam_err_; //!< Set to != DAMARIS_OK if a Damaris error was returned by a + //!< Damaris API function call + bool has_error_; + std::ostringstream dam_err_sstr_; //!< Use dam_err_sstr.str() to return an + //!< error string describing detected error + DamarisVarXMLAttributes + xml_attributes_; //!< The extra elements that need to be part of a Damaris + //!< type. They are simple string values that + //!< may reference other XML elements (and could be + //!< checked for existence etc.) + T *data_ptr_; //!< This pointer will be mapped to the Damaris shared memory + //!< area for the variable in the SetPointersToDamarisShmem() + //!< method. The type T will match the Layout type + size_t + current_size_; //!< The total number of elements that may be held by this + //!< part of the variable - returned by the size() method. + +public: + /** + * Constructor - sets private data values and dos not initialise the shared memory area. + * + * Two usages: + * Example XML definition: + * + * + * + * + * + * 1/ The variable's layout needs to be initialised via parameters : + * // Create the DamarisVar object: + * damaris::model::DamarisVar* MYVARNAME_2d = new damaris::model::DamarisVar(2, + * {std::string("my_param_name1"), std::string("my_param_name2")}, + * {100, 25}, + * std::string("MYVARNAME"), rank_); + * // sets the paramater sizes (so, here, my_param_name1 == 25 and my_param_name2 == 100) + * MYVARNAME_2d->SetDamarisParameterAndShmem( {25, 100 } }; + * // Get a pointer to the memeory and use it + * T * mymemory = MYVARNAME_2d->data(); + * ... write data to mymemory .... + * delete MYVARNAME_2d; + * or, + * 2/ The variable's layout has been initialised via parameters in another variable + * (i.e. "my_param_name1" and "my_param_name2" have been previously set in the code) + * // Create the DamarisVar object: + * damaris::model::DamarisVar* MYVARNAME_2d = new damaris::model::DamarisVar(2, + * {std::string("my_param_name1"), std::string("my_param_name2")}, + * std::string("MYVARNAME"), rank_); + * // explicitly state that the paramater values have been set somewhere else in the code previously. + * MYVARNAME_2d->ParameterIsSet(); + * MYVARNAME_2d->SetPointersToDamarisShmem() + * // Get a pointer to the memeory and use it + * T * mymemory = MYVARNAME_2d->data(); + * ... write data to mymemory .... + * delete MYVARNAME_2d; + * + * /param [IN] dims Used to check that the inputs to SetDamarisPosition() + * have the same number of values - one value for each dimension + * /param [IN] param_names The name the Damaris paramaters. These names (in typical use) control + * a Damaris variables size (names are defined in the Damaris XML file). + * /param [IN] variable_name The name of the Damaris variable (defined in the Damaris XML file) + * /param [IN] rank The rank of the process. Used for error output. */ - class DamarisVarXMLAttributes { - std::string layout_; //!< Reference string to the XML attribute layout being used to describe the shape of the variable. This is a required attribute. - std::string mesh_; //!< Reference string to the XML attribute mesh element - the mesh is used to define the spatial layout of data and is used by visualization backends to generate 2D/3D model images - std::string type_; //!< Reference string to the XML attribute type of data - "scalar" or "vector" (others tensor maybe). TODO: check if this attribute is used by the Damaris library anywhere. - std::string visualizable_; //!< Reference string to the XML attribute property that data can be sent to vis backends - "true" | "false" - std::string unit_; //!< Reference string to the XML attribute element denoting unit of the data - std::string time_varying_; //!< Reference string to the XML attribute to indicate if data changes over iterations - "true" | "false" - std::string centering_; //!< Reference string to the XML attribute to indicate where data aligns on a mesh - "zonal" | "nodal" - std::string store_; //!< Reference string to the XML attribute to indicate if data should be passed to I/O store (e.g. to HDF5 plugin) - std::string script_; //!< Reference string to the XML attribute to indicate if data should be published as Python NumPy data - std::string select_mem_; //!< Reference string to the XML attribute select. The referenced variables data is used as indices to select dat from memory to reorder output in the collective HDF5 data writer (Damaris version 1.8+) - std::string select_file_; //!< Reference string to the XML attribute select. The referenced variables data is used as indices to select positions in the dataset file to reorder output in the collective HDF5 data writer (Damaris version 1.8+) - std::string select_subset_; //!< Reference string to the XML attribute select. Used to specify the output dataset shape and how much data each rank contributes to it and the global offsets to the ranks data (Damaris version 1.8+) + DamarisVar(int dims, std::vector param_names, + std::string variable_name, int rank) + : dims_(dims), param_names_(param_names), variable_name_(variable_name), + rank_(rank) { + dam_err_ = DAMARIS_OK; - public: - DamarisVarXMLAttributes(){ - // Additional data needed to complete an XML element - layout_ = ""; - mesh_ = ""; - type_ = "scalar"; // This is probably not needed as vector data is defined using the Layout paramter. Could be useful for cross checking - visualizable_ = "false"; - unit_ = ""; - time_varying_ = "true"; - centering_ = "zonal"; - store_ = ""; - script_ = ""; - select_mem_ = ""; - } + assert(param_names_.size() == dims); + assert(dims > 0); - /** - * Creates the XML representation of the variable from the available strings - */ - std::string ReturnXMLForVariable ( void ) - { - std::ostringstream var_sstr; + has_error_ = false; - var_sstr << " layout=\"" << this->layout_ << "\""; - if (this->mesh_ != "") var_sstr << " mesh=\"" << this->mesh_ << "\""; - if (this->type_ != "") var_sstr << " type=\"" << this->type_ << "\""; - if (this->visualizable_ != "") var_sstr << " visualizable=\"" << this->visualizable_ << "\""; - if (this->unit_ != "") var_sstr << " unit=\"" << this->unit_ << "\""; - if (this->time_varying_ != "") var_sstr << " time_varying=\"" << this->time_varying_ << "\""; - if (this->centering_ != "") var_sstr << " centering=\"" << this->centering_ << "\""; - if (this->store_ != "") var_sstr << " store=\"" << this->store_ << "\""; - if (this->script_ != "") var_sstr << " script=\"" << this->script_ << "\""; - if (this->select_mem_ != "") var_sstr << " select-mem=\"" << this->select_mem_ << "\""; - if (this->select_file_ != "") var_sstr << " select-file=\"" << this->select_file_ << "\""; - if (this->select_subset_ != "") var_sstr << " select-subset=\"" << this->select_subset_ << "\""; + // Check that our template type T matches out Damaris XML type + TestType(variable_name); + if (hasError()) { + printError(); // throws a runtime error, with error message from + // dam_err_sstr_ + } - return (var_sstr.str()); - } - }; + current_size_ = 0; + num_params_ = param_names_.size(); + param_sizes_.resize(num_params_); + positions_.resize(dims); - class DamarisVarBase { - public: - virtual ~DamarisVarBase( void ) {}; - virtual void printError ( void ) = 0; - virtual bool hasError( void ) = 0; - virtual void setDamarisParameterAndShmem( std::vector paramSizeVal ) = 0; - virtual void setDamarisParameter( std::vector& paramSizeVal ) = 0; - virtual void setDamarisPosition( std::vector positionsVals ) = 0; - virtual void setPointersToDamarisShmem( void ) = 0; - virtual void commitVariableDamarisShmem( void ) = 0; - virtual void clearVariableDamarisShmem( void ) = 0; - virtual std::string & variable_name( void ) = 0; - }; // class DamarisVarBase + data_ptr_ = nullptr; + parameters_set_ = false; + has_error_ = false; + } - /** - * class to store a Damaris variable representation for the XML file (can be used with /ref class DamarisKeywords). - * - * It is thought that the details stored in the object can be used to pass into an XML generation function e.g. DamarisKeywords - * - * Should be instantiated with something like the following: - * // The following needs to be defined in the Damaris XML file: - * // - * // - * // - * damaris::model::DamarisVar dam_var = new damaris::model::DamarisVar(1, {std::string("n_connectivity_ph")}, std::string("topologies/topo/elements/connectivity"), rank_); - * dam_var->SetDamarisParameterAndShmem( { geomData.getNCorners() } ); - * - * int * shmem_mpi_ptr = dam_var->data_ptr(); - * // Fill the created memory area - * for (int i = 0; i <; i++ ) - * { - * shmem_mpi_ptr[i] = rank_; - * } - * delete dam_var; // this tells Damaris that the shared memory that it supplied is at its disposal. It will print error messages too. - * + /** + * Constructor - Sets private data values and also initialises the Damaris shared memory area for writing (and reading) + * by specifying the values for the variables parameters . i.e. makes the data_ptr() + * + * Example use: + * Example XML definition: + * + * + * + * + * // The paramaters are intialized in the constructor code + * damaris::model::DamarisVar* MYVARNAME_2d = new damaris::model::DamarisVar(2, + * {std::string("my_param_name1"), std::string("my_param_name2")}, + * {100, 25}, + * std::string("MYVARNAME"), rank_); + * T * mymemory = MYVARNAME_2d->data(); + * ... write data to mymemory .... + * delete MYVARNAME_2d; + * + * /param [IN] dims Used to check that the inputs to SetDamarisPosition() have + * the same number of values - one value for each dimension + * /param [IN] param_names The name the Damaris paramaters. These names (in typical use) + * control a Damaris variables size (names are defined in the Damaris XML file). + * /param [IN] param_values The values of the paramaters - this defines how much memory we will + * have access to in the shared memory area (on the current and ongoing iterations, + * until later modified to new values) + * /param [IN] variable_name The name of the Damaris variable (defined in the Damaris XML file) + * /param [IN] rank The rank of the process. Used for error output. */ - template - class DamarisVar : - public DamarisVarBase { - int dims_; - int num_params_; //!< Each paramater name string will need a value and they are set in SetDamarisParameter() - int * param_sizes_; //!< The value for any paramaters that are being used to describe the size of the variables data array - int64_t * positions_; //!< The offsets into the array that the data in the Variable starts from for this rank. - int rank_; //!< Rank of process - used for error reporting. - bool paramaters_set_; //!< set to true after SetDamarisParameter() is call to ensure the variable has correct size for memory allocation in SetPointersToDamarisShmem() - std::vector param_names_; //!< Contains one paramater name for each paramater that a variable depends on (via it's Layout) - std::string variable_name_; //!< Reference string to the XML attribute name of the variable. - int dam_err_; //!< Set to != DAMARIS_OK if a Daamris error was returned by a Damaris API function call - bool has_error_; - std::ostringstream dam_err_sstr_; //!< Use dam_err_sstr.str() to return an error string describing detected error - DamarisVarXMLAttributes xml_attributes_; //!< The extra elements that need to be part of a Damaris type. They are simple string values that may reference other XML elements (and could be checked for existence etc.) - T * data_ptr_; //!< This pointer will be mapped to the Damaris shared memory area for the variable in the SetPointersToDamarisShmem() method. The type T will match the Layout type - size_t current_size_ ; //!< The total number of elements that may be held by this part of the variable - returned by the size() method. + DamarisVar(int dims, std::vector param_names, + std::vector param_values, std::string variable_name, int rank) + : dims_(dims), param_names_(param_names), variable_name_(variable_name), + rank_(rank) { + DamarisVar(dims, param_names, variable_name, rank); + setDamarisParameterAndShmem( + param_values); // Initialise the memory size in the constructor. + } - public: + ~DamarisVar(void) { + if (data_ptr_ != nullptr) { + commitVariableDamarisShmem(); + clearVariableDamarisShmem(); + } + if (this->hasError()) + printError(); // flush out any error messages + } - /** - * Constructor - sets private data values and dos not initialise the shared memory area. - * - * Two usages: - * Example XML definition: - * - * - * - * - * - * 1/ The variable's layout needs to be initialised via parameters : - * // Create the DamarisVar object: - * damaris::model::DamarisVar MYVARNAME_2d = new damaris::model::DamarisVar(2, {std::string("my_param_name1"), std::string("my_param_name2")}, std::string("MYVARNAME"), rank_); - * // Set the paramter sizes - * MYVARNAME_2d->SetDamarisParameterAndShmem( {25, 100 } }; // sets the paramaters (here, my_param_name1 == 25 and my_param_name2 == 100) - * // Get a pointer to the memeory and use it - * T * mymemory = MYVARNAME_2d->data_ptr(); - * ... write data to mymemory .... - * delete MYVARNAME_2d; - * or, - * 2/ The variable's layout has been initialised via parameters in another variable (i.e. "my_param_name1" and "my_param_name2" have been previously set in the code) - * // Create the DamarisVar object: - * damaris::model::DamarisVar MYVARNAME_2d = new damaris::model::DamarisVar(2, {std::string("my_param_name1"), std::string("my_param_name2")}, std::string("MYVARNAME"), rank_); - * // explicitly state that the paramater values have been set somewhere else in the code previously. - * MYVARNAME_2d->ParameterIsSet(); - * MYVARNAME_2d->SetPointersToDamarisShmem() - * // Get a pointer to the memeory and use it - * T * mymemory = MYVARNAME_2d->data_ptr(); - * ... write data to mymemory .... - * delete MYVARNAME_2d; - * - * /param [IN] dims Used to check that the inputs to SetDamarisPosition() have the same number of values - one value for each dimension - * /param [IN] param_names The name the Damaris paramaters. These names (in typical use) control a Damaris variables size (names are defined in the Damaris XML file). - * /param [IN] variable_name The name of the Damaris variable (defined in the Dmaaris XML file) - * /param [IN] rank The rank of the process. Used for error output. - */ - DamarisVar(int dims, std::vector param_names, std::string variable_name, int rank) - : dims_( dims ), - param_names_( param_names ), - variable_name_( variable_name ), - rank_(rank) - { - dam_err_ = DAMARIS_OK; - - assert( param_names_.size() == dims ); - assert( dims > 0 ); - - // Check that our template type T matches out Damaris XML type - if ( !TestType(variable_name) ) { - std::exit(-1); - } - - current_size_ = 0 ; - num_params_ = param_names_.size(); - param_sizes_ = new int(num_params_); - positions_ = new int64_t(dims); + /** + * Method to check that the template paramater T is the same as the requested + * type for the variable in the XML file + */ + bool TestType(std::string variable_name) { + bool resbool = true; + // This gets the type of the Damaris XML 's + DAMARIS_TYPE_STR vartype; + dam_err_ = damaris_get_type(variable_name.c_str(), &vartype); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ + << " ERROR rankDamarisVar::DamarisVar () damaris_get_type(\"" + << variable_name_ + << "\", vartype); Damaris error = " << damaris_error_string(dam_err_) + << std::endl; + has_error_ = true; + return (false); + } + T test_id; + const std::type_info &t1 = typeid(test_id); - data_ptr_ = nullptr; - paramaters_set_ = false; - has_error_ = false; - } + if (vartype == DAMARIS_TYPE_DOUBLE) { + double td = 0.0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_FLOAT) { + float td = 0.0f; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_CHAR) { + char td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_UCHAR) { + unsigned char td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_SHORT) { + short td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_USHORT) { + unsigned short td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_INT) { + int td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_UINT) { + unsigned int td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_LONG) { + long td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_ULONG) { + unsigned long td = 0; + const std::type_info &t2 = typeid(td); + if (t1 != t2) { + formatTypeError(variable_name, t1.name(), t2.name()); + resbool = false; + } + } else if (vartype == DAMARIS_TYPE_UNDEFINED) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : DamarisVar::DamarisVar():: \"" << variable_name + << "\" has type DAMARIS_TYPE_UNDEFINED" << std::endl; + has_error_ = true; + resbool = false; + } else { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : DamarisVar::DamarisVar():: \"" << variable_name + << "\" is not of available type " << std::endl; + has_error_ = true; + resbool = false; + } - /** - * Constructor - Sets private data values and also initialises the Damaris shared memory area for writing (and reading) - * by specifying the values for the variables parameters . i.e. makes the data_ptr() - * - * Example use: - * Example XML definition: - * - * - * - * - * // The paramaters are intialized in the constructor code - * damaris::model::DamarisVar MYVARNAME_2d = new damaris::model::DamarisVar(2, {std::string("my_param_name1"), std::string("my_param_name2")}, {100, 25}, std::string("MYVARNAME"), rank_); - * T * mymemory = MYVARNAME_2d->data_ptr(); - * ... write data to mymemory .... - * delete MYVARNAME_2d; - * - * /param [IN] dims Used to check that the inputs to SetDamarisPosition() have the same number of values - one value for each dimension - * /param [IN] param_names The name the Damaris paramaters. These names (in typical use) control a Damaris variables size (names are defined in the Damaris XML file). - * /param [IN] param_values The values of the paramaters - this defines how much memory we will have access to in the shared memory area (on the current and ongoing iterations, until later modified to new values) - * /param [IN] variable_name The name of the Damaris variable (defined in the Dmaaris XML file) - * /param [IN] rank The rank of the process. Used for error output. - */ - DamarisVar(int dims, std::vector param_names, std::vector param_values, std::string variable_name, int rank) - : dims_( dims ), - param_names_( param_names ), - variable_name_( variable_name ), - rank_(rank) - { - dam_err_ = DAMARIS_OK; - - assert( param_names_.size() == dims ); - assert( dims > 0 ); - - // Check that our template type T matches out Damaris XML type - if ( !TestType(variable_name) ) { - std::exit(-1); - } + return resbool; + } - num_params_ = param_names_.size(); - param_sizes_ = new int(num_params_); - positions_ = new int64_t(dims); + /** + * Allow a user to indicate that the Damaris variable has allocated a size - + * This method is usefull as a single parameter can control one or more + * layouts and a single layout can describe the size of multiple + * elements. i.e. Use when the current variable has had it's paramater(s) set + * through via another variable. + */ + void parameterIsSet() { parameters_set_ = true; } - data_ptr_ = nullptr; - paramaters_set_ = false; - has_error_ = false; - - setDamarisParameterAndShmem( param_values ); // Initialise the memory size in the constructor. - } + void printError(void) { + OPM_THROW(std::runtime_error, dam_err_sstr_.str()); + } - ~DamarisVar( void ) { - delete [] param_sizes_; - delete [] positions_; - if (data_ptr_ != nullptr) - { - commitVariableDamarisShmem(); - clearVariableDamarisShmem(); - } - if (this->hasError()) - printError(); // flush out any error messages - } + bool hasError(void) { return (has_error_); } - /** - * Method to check that the template paramater T is the same as the requested type for the variable in the XML file - */ - bool TestType(std::string variable_name) - { - bool resbool = true; - // This gets the type of the Damaris XML 's - DAMARIS_TYPE_STR vartype; - dam_err_ = damaris_get_type(variable_name.c_str(), &vartype); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rankDamarisVar::DamarisVar () damaris_get_type(\"" - << variable_name_ << "\", vartype); Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - return( false ); - } - T test_id; - const std::type_info& t1 = typeid(test_id); - - if (vartype == DAMARIS_TYPE_DOUBLE) - { - double td = 0.0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_FLOAT) - { - float td = 0.0f; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_CHAR) - { - char td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_UCHAR) - { - unsigned char td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_SHORT) - { - short td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_USHORT) - { - unsigned short td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_INT) - { - int td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_UINT) - { - unsigned int td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_LONG) - { - long td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_ULONG) - { - unsigned long td = 0; - const std::type_info& t2 = typeid(td); - if (t1 != t2) { - outputErrorAndAssert(variable_name, t1.name(), t2.name()); - resbool = false; - } - } - else if (vartype == DAMARIS_TYPE_UNDEFINED) - { - std::cerr << "ERROR rank =" << rank_ << " : DamarisVar::DamarisVar():: \"" << variable_name << "\" has type DAMARIS_TYPE_UNDEFINED"<< std::endl; - resbool = false; - } - else - { - std::cerr << "ERROR rank =" << rank_ << " : DamarisVar::DamarisVar():: \"" << variable_name << "\" is not of available type "<< std::endl; - resbool = false; - } - - return resbool; - } + /** + * Returns the data pointer to shared memory, or nullptr if it has not been + * allocated + */ + T *data(void) { + if (parameters_set_ == true) { + return (data_ptr_); // This still could be nullptr + } else { + return (nullptr); + } + } - /** - * Allow a user to indicate that the Damaris variable has allocated a size - - * This method is usefull as a single parameter can control one or more layouts and - * a single layout can describe the size of multiple elements. - * i.e. Use when the current variable has had it's paramater(s) set through via another variable. - */ - void parameterIsSet() - { - paramaters_set_ = true; - getDataStoreBlockSize() ; - } - - long getDataStoreBlockSize( void ) - { - long total_size = 1 ; - if (paramaters_set_ == true) - { - std::shared_ptr v = damaris::VariableManager::Search(this->variable_name_.c_str()); - - damaris::BlocksByIteration::iterator begin; - damaris::BlocksByIteration::iterator end; - int iteration = 0 ; - v->GetBlocksByIteration(iteration, begin, end); - - for (damaris::BlocksByIteration::iterator bid = begin; bid != end; bid++) { - std::shared_ptr b = *bid; + std::string &variable_name(void) { return (variable_name_); } - // possibly multi-dimensional, so we need a value for each dimension - int blockDimension = b->GetDimensions(); - // Compute the size in each dimension - for (int i = 0 ; i < blockDimension ; i++) - { - total_size *= ( b->GetEndIndex(i) - b->GetStartIndex(i) + 1 ); // This includes a variables Ghost zones. - } - } - } - - if (total_size > 0) { - current_size_ = total_size ; - } else { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar::getDataStoreBlockSize() " << - "The total size of the variable is 0 - please check input paramSizeVal array." << std::endl; - has_error_ = true; - } - - return total_size ; - - } - + /** + * Creates the XML representation of the variable from the available strings + */ + std::string returnXMLForVariable(void) { + std::ostringstream var_sstr; - void printError ( void ) - { - std::cerr << dam_err_sstr_.str(); - } + var_sstr << " "; - bool hasError( void ) - { - return (has_error_); - } + return var_sstr.str(); + } - /** - * Returns the data pointer to shared memory, or nullptr if it has not been allocated - */ - T * data( void ) - { - if (paramaters_set_ == true ) - { - return (data_ptr_); // This still could be nullptr - } else { - return (nullptr); - } - } + /** + * Method to set the Damaris paramater values and set the shmem region \ref + * data_ptr_ + * + * /param [IN] paramSizeVal : A vector of values to set the Damaris paramters + * to. One element per param_names_ string + * + * + */ + void setDamarisParameterAndShmem(const std::vector ¶mSizeVal) { + this->setDamarisParameter(paramSizeVal); + this->setPointersToDamarisShmem(); + } - std::string & variable_name( void ) - { - return (variable_name_); - } + /** + * Returns the number of elements in the memory area. + * Used as a method for compatibility with std::vector + */ + size_t size() { + if (parameters_set_ == true) { + return current_size_; + } else { + return 0; + } + } - /** - * Creates the XML representation of the variable from the available strings - */ - std::string returnXMLForVariable ( void ) - { - std::ostringstream var_sstr; + /** + * Method to set the Damaris paramater values. Also calculates the total + * number of elements in the variable (current_size_) that is returned bt + * size() method. + * + * /param [IN] paramSizeVal : An pointer to a value or array of values to + * set. One element per param_names_ string + * + * /implicit : Implicitly uses the array of paramater names: + * \ref param_names_ + */ + void setDamarisParameter(const std::vector ¶mSizeVal) { + assert(paramSizeVal.size() == num_params_); - var_sstr << " "; + bool resbool = true; + size_t total_size = 1; + for (int varnum = 0; varnum < num_params_; varnum++) { + param_sizes_[varnum] = paramSizeVal[varnum]; + total_size *= param_sizes_[varnum]; - return var_sstr.str(); - } + dam_err_ = damaris_parameter_set(param_names_[varnum].c_str(), + ¶mSizeVal[varnum], sizeof(int)); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : damaris_parameter_set(\"" + << param_names_[varnum] + << "\", paramSizeVal, sizeof(int)); Damaris error = " + << damaris_error_string(dam_err_) << std::endl; + resbool = false; + has_error_ = true; + } + } - /** - * Method to set the Damaris paramater values and set the shmem region \ref data_ptr_ - * - * /param [IN] paramSizeVal : A vector of values to set the Damaris paramters to. One element per param_names_ string - * - * - */ - void setDamarisParameterAndShmem( std::vector paramSizeVal ) - { - this->setDamarisParameter( paramSizeVal ); - this->setPointersToDamarisShmem(); - } + if (resbool == true) { + parameterIsSet(); // sets parameters_set_ and gets the size of the + // variables block storage (as number of elemnts) + } - /** - * Returns the number of elements in the memory area. - * Used as a method for compatibility with std::vector - */ - size_t size() - { - if (paramaters_set_ == true ) - { - return current_size_ ; - } else { - return 0 ; - } - } - - /** - * Method to set the Damaris paramater values. Also calculates the total number - * of elements in the variable (current_size_) that is returned bt size() method. - * - * /param [IN] paramSizeVal : An pointer to a value or array of values to set. One element per param_names_ string - * - * /implicit : Implicitly uses the array of paramater names: \ref param_names_ - */ - void setDamarisParameter( std::vector& paramSizeVal ) - { - assert(paramSizeVal.size() == num_params_); + if (total_size > 0) { + current_size_ = total_size; + } else { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar::getDataStoreBlockSize() " + << "The total size of the variable is 0 - please check " + "input paramSizeVal array." + << std::endl; + has_error_ = true; + } - bool resbool = true; - // size_t total_size = 1 ; - for (int varnum = 0; varnum < num_params_; varnum++) - { - param_sizes_[varnum] = paramSizeVal[varnum]; - // total_size *= param_sizes_[varnum] ; - - dam_err_ = damaris_parameter_set(param_names_[varnum].c_str(), ¶mSizeVal[varnum], sizeof(int)); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_parameter_set(\"" << param_names_[varnum] - << "\", paramSizeVal, sizeof(int)); Damaris error = " << damaris_error_string(dam_err_) << std::endl; - resbool = false; - has_error_ = true; - } - } + if (hasError()) { + printError(); + } + } - if (resbool == true) - { - parameterIsSet() ; // sets paramaters_set_ and gets the size of the variables block storage (as number of elemnts) - } - - if (hasError()) { - printError() - } - } + /** + * Method to set the Damaris position values. + * + * /param [IN] positionsVals : An pointer to a value or array of values to + * set as the offset into the array. One element per dimension (one value for + * each dim_) + * + * /implicit : Implicitly uses the variable name: \ref + * variable_name_ + */ + void setDamarisPosition(const std::vector &positionsVals) { + assert(positionsVals.size() == dims_); - /** - * Method to set the Damaris position values. - * - * /param [IN] positionsVals : An pointer to a value or array of values to set as the offset into the array. - * One element per dimension (one value for each dim_) - * - * /implicit : Implicitly uses the variable name: \ref variable_name_ - */ - void setDamarisPosition( std::vector positionsVals ) - { - assert(positionsVals.size() == dims_); + for (int pos_dim = 0; pos_dim < dims_; pos_dim++) { + positions_[pos_dim] = positionsVals[pos_dim]; + } + dam_err_ = + damaris_set_position(variable_name_.c_str(), positionsVals.data()); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : damaris_set_position(\"" + << variable_name_ << "\", positionsVals); Damaris error = " + << damaris_error_string(dam_err_) << std::endl; + has_error_ = true; + } - for (int pos_dim = 0; pos_dim < dims_; pos_dim++) - { - positions_[pos_dim] = positionsVals[pos_dim]; - } - dam_err_ = damaris_set_position(variable_name_.c_str(), positionsVals.data()); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_set_position(\"" - << variable_name_ << "\", positionsVals); Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - } - - if (hasError()) { - printError() - } - } + if (hasError()) { + printError(); + } + } - /** - * Method to set the internal pointer (data_ptr_) to the Damaris shared memory area. - * - * /implicit : Implicitly uses the Damaris variable name string \ref variable_name_ - * /implicit : Implicitly uses the class data element : \ref data_ptr_ - */ - void setPointersToDamarisShmem( void ) - { - if (paramaters_set_ == true ) - { - // Allocate memory in the shared memory section... - dam_err_ = damaris_alloc(variable_name_.c_str(), (void **) &data_ptr_); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_alloc(\"" - << variable_name_ <<"\", (void **) &ret_ptr)" << ", Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - } - } else { - dam_err_ = -1; - dam_err_sstr_ << "ERROR rank =" << rank_ << " : class DamarisVar : setDamarisParameter() should be called first so as to define the size of the memory block required for variable : " << variable_name_ << std::endl; - has_error_ = true; - } - - if (hasError()) { - printError() - } - } + /** + * Method to set the internal pointer (data_ptr_) to the Damaris shared + * memory area. + * + * /implicit : Implicitly uses the Damaris variable name + * string \ref variable_name_ /implicit : Implicitly uses the + * class data element : \ref data_ptr_ + */ + void setPointersToDamarisShmem(void) { + if (parameters_set_ == true) { + // Allocate memory in the shared memory section... + dam_err_ = damaris_alloc(variable_name_.c_str(), (void **)&data_ptr_); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : damaris_alloc(\"" + << variable_name_ << "\", (void **) &ret_ptr)" + << ", Damaris error = " << damaris_error_string(dam_err_) + << std::endl; + has_error_ = true; + } + } else { + dam_err_ = -1; + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : setDamarisParameter() should be " + "called first so as to define the size of the memory " + "block required for variable : " + << variable_name_ << std::endl; + has_error_ = true; + } - /** - * Method to set the an externaly sourced pointer to point to the Damaris shared memory. - * - * /implicit : Implicitly uses the Damaris variable name string \ref variable_name_ - * /implicit : Implicitly uses the class data element : \ref data_ptr_ - */ - void setPointersToDamarisShmem( T ** ptr_in ) - { - if (paramaters_set_ == true ) - { - T * temp_ptr; - // Allocate memory in the shared memory section... - dam_err_ = damaris_alloc(variable_name_.c_str(), (void **) &temp_ptr); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_alloc(\"" - << variable_name_ <<"\", (void **) &ret_ptr)" << ", Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - } + if (hasError()) { + printError(); + } + } - *ptr_in = temp_ptr; - data_ptr_ = temp_ptr; - } else { - dam_err_ = -1; - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : setDamarisParameter() should be called first so as to define the size of the memory block required for variable : " << variable_name_ << std::endl; - has_error_ = true; - } - - if (hasError()) { - printError() - } - } + /** + * Method to commit the memory of the data written to the Damaris variable - + * Indicates that we will not write any more data to \ref data_ptr_ + * + * /implicit : Implicitly uses the variable name string \ref + * variable_name_ + */ + void commitVariableDamarisShmem(void) { + // Signal to Damaris we are done writing data for this iteration + dam_err_ = damaris_commit(variable_name_.c_str()); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : damaris_commit(\"" + << variable_name_ << "\")" + << ", Damaris error = " << damaris_error_string(dam_err_) + << std::endl; + has_error_ = true; + } + } - /** - * Method to commit the memory of the data written to the Damaris variable - - * Indicates that we will not write any more data to \ref data_ptr_ - * - * /implicit : Implicitly uses the variable name string \ref variable_name_ - */ - void commitVariableDamarisShmem( void ) - { - // Signal to Damaris we are done writing data for this iteration - dam_err_ = damaris_commit (variable_name_.c_str()); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_commit(\"" - << variable_name_ <<"\")" << ", Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - } - } + /** + * Method to release the memory of the data written to the Damaris variable - + * Indicates that Damaris may take control of the shared memory area that was + * used for the variable \ref data_ptr_ + * + * /implicit : Implicitly uses the variable name string \ref + * variable_name_ + */ + void clearVariableDamarisShmem(void) { + // Signal to Damaris it has complete charge of the memory area + dam_err_ = damaris_clear(variable_name_.c_str()); + if (dam_err_ != DAMARIS_OK) { + dam_err_sstr_ << " ERROR rank =" << rank_ + << " : class DamarisVar : damaris_clear(\"" + << variable_name_ << "\")" + << ", Damaris error = " << damaris_error_string(dam_err_) + << std::endl; + has_error_ = true; + } + data_ptr_ = nullptr; + } - /** - * Method to release the memory of the data written to the Damaris variable - - * Indicates that Damaris may take control of the shared memory area that was used for the variable \ref data_ptr_ - * - * /implicit : Implicitly uses the variable name string \ref variable_name_ - */ - void clearVariableDamarisShmem( void ) - { - // Signal to Damaris it has complete charge of the memory area - dam_err_ = damaris_clear(variable_name_.c_str()); - if (dam_err_ != DAMARIS_OK) { - dam_err_sstr_ << " ERROR rank =" << rank_ << " : class DamarisVar : damaris_clear(\"" - << variable_name_ << "\")" << ", Damaris error = " << damaris_error_string(dam_err_) << std::endl; - has_error_ = true; - } - data_ptr_ = nullptr; - } - private: - void outputErrorAndAssert(std::string& var_name, std::string type_name1, std::string type_name2) - { - dam_err_sstr_ << "ERROR rank =" << rank_ << " : DamarisVar::DamarisVar () variable_name_: \"" << var_name - << "\" The template type of Type of DamarisVar in the code: " << type_name1 << " does not match type in XML (float)" << std::endl; - printError(); - assert( type_name1 == type_name2 ); - } - }; // class DamarisVar +private: + void formatTypeError(std::string &var_name, std::string type_name1, + std::string type_name2) { + dam_err_sstr_ + << " ERROR rank =" << rank_ + << " : DamarisVar::DamarisVar () variable_name_: \"" << var_name + << "\" The template type of Type of DamarisVar in the code: " + << type_name1 << " does not match type in XML:" << type_name2 + << std::endl; + has_error_ = true; + } +}; // class DamarisVar - } // namespace DamarisOutput +} // namespace DamarisOutput -} // namespace OPM +} // namespace Opm -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/opm/simulators/utils/GridDataOutput.hpp b/opm/simulators/utils/GridDataOutput.hpp index 7572103dc..35f00223f 100644 --- a/opm/simulators/utils/GridDataOutput.hpp +++ b/opm/simulators/utils/GridDataOutput.hpp @@ -22,32 +22,36 @@ #ifndef OPM_GRID_DATA_OUTPUT_HPP #define OPM_GRID_DATA_OUTPUT_HPP -#include #include #include +#include /** @file - @brief Allows model geometry data to be passed to external code - via a copy direct to input pointers. - - This data extractor provides the full set of vertices (corresponding to Dune::Partition::all) and then - allows a user to specify Dune sub-partitions to get the references into the vertex array and element - (aka cell) types for the sub-partition. This allows the full set of vertices to be reused for - visualisation of the various sub-partitions, at the expense of copying all the vertices. Typically - a user is interested in the interiorBoarder elements which make use of the bulk (~80%) of the vertices. - This saves having to renumber the indexes to the vertices for the sub-partitions. - The vertex data can be retrieved as seperate x, y and z arrays, or as a single array of structures, - or as a single structure of arrays based + @brief Allows model geometry data to be passed to external code - via a copy + direct to input pointers. + + This data extractor provides the full set of vertices (corresponding to + Dune::Partition::all) and then allows a user to specify Dune sub-partitions + to get the references into the vertex array and element (aka cell) types for + the sub-partition. This allows the full set of vertices to be reused for + visualisation of the various sub-partitions, at the expense of copying all + the vertices. Typically a user is interested in the interiorBoarder elements + which make use of the bulk (~80%) of the vertices. This saves having to + renumber the indexes to the vertices for the sub-partitions. The vertex data + can be retrieved as seperate x, y and z arrays, or as a single array of + structures, or as a single structure of arrays based Example: // From the opm-simulators repository #include - + // N.B. does not seem to be able to be allocated with new operator. - Opm::GridDataOutput::SimMeshDataAccessor geomData(gridView, Dune::Partition::interior ); + Opm::GridDataOutput::SimMeshDataAccessor geomData(gridView, + Dune::Partition::interior ); geomData.printGridDetails(); - + int nvert = geomData.getNVertices(); // example using seperate x, y and z arrays int nvert = geomData.getNVertices(); @@ -61,653 +65,629 @@ delete [] x_vert; delete [] y_vert; delete [] z_vert; - - // example using AOS + + // example using AOS double * xyz_vert_aos = new double[nvert*3]; geomData.writeGridPoints_AOS(xyz_vert_aos); ... do something with vertex data xyz_vert_aos.... delete [] xyz_vert_aos; - + */ -namespace Opm::GridDataOutput -{ - /** - * Allows selection of order of vertices in writeConnectivity() +namespace Opm::GridDataOutput { +/** + * Allows selection of order of vertices in writeConnectivity() + */ +enum ConnectivityVertexOrder { DUNE = 0, VTK = 1 }; + +template class SimMeshDataAccessor { +public: + /** + * @brief Construct a SimMeshDataAccessor working on a specific GridView and + * specialize to a Dune::PartitionSet<>. + * + * @param gridView The gridView + * @param PartitionSet<> the set of cells from which to extract geometric data + * + * The PartitionSet of the data can be specified from one of: + * Dune::Partitions::all + * Dune::Partitions::interior + * Dune::Partitions::border + * Dune::Partitions::overlap + * Dune::Partitions::front + * Dune::Partitions::ghost + * Dune::Partitions::interiorBorder + * Dune::Partitions::interiorBorderOverlap + * Dune::Partitions::interiorBorderOverlapFront + * Dune::Partitions::all + * + * N.B. To visualise 'field' data on the extracted grid mesh then the field + * variable should contain at least as many vlaues as the mesh has cells + * (ncells_) or vertices (nvertices_) depending on if data is cell centred or + * vertex centred, respectively. + * + * As we are templated on the Dune::PartitionSet, values for + * ncorners_, nvertices_ and ncells_ cannot change + * + * This class does not work with grids containing polyhedral cells (well, it + * has not been tested with this kind of grid data). The user should call + * polyhedralCellPresent() to test if polyhedral cells are present and decide + * what they want to do before copying data using the data accessor methods. */ - enum ConnectivityVertexOrder { DUNE = 0 , VTK = 1 }; + explicit SimMeshDataAccessor(const GridView &gridView, + Dune::PartitionSet dunePartition) + : gridView_(gridView), dunePartition_(dunePartition) { + dimw_ = GridView::dimension; // this is an enum + partition_value_ = dunePartition.value; + countEntities(); + } - template< class GridView, unsigned int partitions > - class SimMeshDataAccessor { - public: - /** - * @brief Construct a SimMeshDataAccessor working on a specific GridView and specialize to a Dune::PartitionSet<>. - * - * @param gridView The gridView - * @param PartitionSet<> the set of cells from which to extract geometric data - * - * The PartitionSet of the data can be specified from one of: - * Dune::Partitions::all - * Dune::Partitions::interior - * Dune::Partitions::border - * Dune::Partitions::overlap - * Dune::Partitions::front - * Dune::Partitions::ghost - * Dune::Partitions::interiorBorder - * Dune::Partitions::interiorBorderOverlap - * Dune::Partitions::interiorBorderOverlapFront - * Dune::Partitions::all - * - * N.B. To visualise 'field' data on the extracted grid mesh then the field variable - * should contain at least as many vlaues as the mesh has cells (ncells_) or vertices (nvertices_) - * depending on if data is cell centred or vertex centred, respectively. - * - * As we are templated on the Dune::PartitionSet, values for ncorners_, nvertices_ and ncells_ cannot change - * - * This class does not work with grids containing polyhedral cells (well, it has not been tested - * with this kind of grid data). The user should call polyhedralCellPresent() to test if polyhedral - * cells are present and decide what they want to do before copying data using the data accessor methods. - */ - explicit SimMeshDataAccessor ( const GridView &gridView, - Dune::PartitionSet dunePartition) - : gridView_( gridView ), - dunePartition_(dunePartition) - { - dimw_ = GridView::dimension; // this is an enum - partition_value_ = dunePartition.value; - countEntities(); + /** + Checks for cells that have polyhedral type within the current partition of + cells + + Returns true if a polyhedral sell is found. If this is the case then this + partition is not going to be available for visualisation as this class does + not yet handle polyhedral cells. + */ + bool polyhedralCellPresent() { + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto corner_geom = cit.geometry(); + if (Dune::VTK::geometryType(corner_geom.type()) == + Dune::VTK::polyhedron) { + return true; + } + } + return false; + } + + /** + Count the vertices, cells and corners. + + Count all the vertices ( the Dune::Partitions::all partition ) as then we + do not need to renumber the vertices as all the subsets use references to + the full set. + */ + void countEntities() { + // We include all the vertices for this ranks partition + const auto &vert_partition = vertices(gridView_, Dune::Partitions::all); + nvertices_ = std::distance(vert_partition.begin(), vert_partition.end()); + + const auto &cell_partition = elements(gridView_, dunePartition_); + ncells_ = 0; + ncorners_ = 0; + for (const auto &cit : cell_partition) { + auto corner_geom = cit.geometry(); + ncorners_ += corner_geom.corners(); + ++ncells_; + } + } + + template + long writeGridPoints(T *x_inout, T *y_inout, T *z_inout, long max_size = 0) { + if (max_size < nvertices_) { + // assert(max_size >= nvertices_); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeGridPoints( T& x_inout, T& " + "y_inout, T& z_inout ) " + + " Input objects max_size (" + std::to_string(max_size) + + ") is not sufficient to fit the nvertices_ values (" + + std::to_string(nvertices_) + ")"); } - /** - Checks for cells that have polyhedral type within the current partition of cells - - Returns true if a polyhedral sell is found. If this is the case then this partition - is not going to be available for visualisation as this class does not yet handle - polyhedral cells. - */ - bool polyhedralCellPresent() - { - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto corner_geom = cit.geometry(); - if( Dune::VTK::geometryType( corner_geom.type() ) == Dune::VTK::polyhedron ) - { - return true; - } - } - return false; + long i = 0; + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = + vit.geometry().corner(0); // vertices only have one corner + x_inout[i] = static_cast(xyz_local[0]); + y_inout[i] = static_cast(xyz_local[1]); + z_inout[i] = static_cast(xyz_local[2]); + i++; + } + } else if (dimw_ == 2) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = + vit.geometry().corner(0); // vertices only have one corner + x_inout[i] = static_cast(xyz_local[0]); + y_inout[i] = static_cast(xyz_local[1]); + z_inout[i] = static_cast(0.0); + i++; + } + } + assert(i == + nvertices_); // As we are templated on the + // Dune::PartitionSet, this cannot change + return i; + } + + /** + Write the positions of vertices - directly to the pointers given in + parameters + + Returns the number of vertices written + */ + template + long writeGridPoints(T &x_inout, T &y_inout, T &z_inout) { + size_t check_size = x_inout.size(); + + using VT = decltype(x_inout.data()[0]); + + if (check_size < nvertices_) { + // assert(check_size >= nvertices_); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeGridPoints( T& x_inout, T& " + "y_inout, T& z_inout ) " + + " Input objects size " + std::to_string(check_size) + + " is not sufficient to fit the nvertices_ values( " + + std::to_string(nvertices_) + " )"); } - /** - Count the vertices, cells and corners. + long i = 0; + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = + vit.geometry().corner(0); // vertices only have one corner + x_inout.data()[i] = static_cast(xyz_local[0]); + y_inout.data()[i] = static_cast(xyz_local[1]); + z_inout.data()[i] = static_cast(xyz_local[2]); + i++; + } + } else if (dimw_ == 2) { + double td = 0.0; + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = + vit.geometry().corner(0); // vertices only have one corner + x_inout.data()[i] = static_cast(xyz_local[0]); + y_inout.data()[i] = static_cast(xyz_local[1]); + z_inout.data()[i] = static_cast(td); + i++; + } + } + assert(i == + nvertices_); // As we are templated on the + // Dune::PartitionSet, this cannot change + return i; + } - Count all the vertices ( the Dune::Partitions::all partition ) as then we do not need to renumber - the vertices as all the subsets use references to the full set. - */ - void countEntities( ) - { - // We include all the vertices for this ranks partition - const auto& vert_partition = vertices(gridView_, Dune::Partitions::all); - nvertices_ = std::distance(vert_partition.begin(), vert_partition.end()); + /** + Write positions of vertices as array of structures : x,y,z,x,y,z,x,y,z,... - const auto& cell_partition = elements(gridView_, dunePartition_); - ncells_ = 0; - ncorners_ = 0; - for (const auto& cit : cell_partition) - { - auto corner_geom = cit.geometry(); - ncorners_ += corner_geom.corners(); - ++ncells_; - } + Returns the number of vertices written + */ + template + long writeGridPoints_AOS(T *xyz_inout, long max_size = 0) { + if (max_size < nvertices_ * 3) { + assert(max_size >= nvertices_ * 3); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeGridPoints_AOS( T* xyz_inout ) " + + " Input objects max_size (" + std::to_string(max_size) + + ") is not sufficient to fit the nvertices_ * 3 values (" + + std::to_string(nvertices_ * 3) + ")"); } - template - long writeGridPoints( T* x_inout, T* y_inout, T* z_inout, long max_size=0 ) - { - if (max_size < nvertices_) { - assert(max_size >= nvertices_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints( T& x_inout, T& y_inout, T& z_inout ) " - + " Input objects max_size (" + std::to_string(max_size) + ") is not sufficient to fit the nvertices_ values (" - + std::to_string(nvertices_) + ")" ); - } - - long i = 0; - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all) ) - { - auto xyz_local = vit.geometry().corner(0); // vertices only have one corner - x_inout[i] = static_cast(xyz_local[0]); - y_inout[i] = static_cast(xyz_local[1]); - z_inout[i] = static_cast(xyz_local[2]); - i++; - } - } else if (dimw_ == 2) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all) ) - { - auto xyz_local = vit.geometry().corner(0); // vertices only have one corner - x_inout[i] = static_cast(xyz_local[0]); - y_inout[i] = static_cast(xyz_local[1]); - z_inout[i] = static_cast(0.0); - i++; - } - } - assert(i == nvertices_); // As we are templated on the Dune::PartitionSet, this cannot change - return i; + long i = 0; + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout[i++] = static_cast(xyz_local[0]); + xyz_inout[i++] = static_cast(xyz_local[1]); + xyz_inout[i++] = static_cast(xyz_local[2]); + } + } else if (dimw_ == 2) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout[i++] = static_cast(xyz_local[0]); + xyz_inout[i++] = static_cast(xyz_local[1]); + xyz_inout[i++] = static_cast(0.0); + } } - + return ((i) / 3); + } - - - /** - Write the positions of vertices - directly to the pointers given in parameters + /** + Write positions of vertices as array of structures : x,y,z,x,y,z,x,y,z,... - Returns the number of vertices written - */ - template - long writeGridPoints( T& x_inout, T& y_inout, T& z_inout ) - { - size_t check_size = x_inout.size() ; - - using VT = decltype(x_inout.data()[0]); - - if (check_size < nvertices_) { - // assert(check_size >= nvertices_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints( T& x_inout, T& y_inout, T& z_inout ) " - + " Input objects size " + std::to_string(check_size) + " is not sufficient to fit the nvertices_ values( " - + std::to_string(nvertices_) + " )" ); - } - - long i = 0; - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all) ) - { - auto xyz_local = vit.geometry().corner(0); // vertices only have one corner - x_inout.data()[i] = static_cast(xyz_local[0]); - y_inout.data()[i] = static_cast(xyz_local[1]); - z_inout.data()[i] = static_cast(xyz_local[2]); - i++; - } - } else if (dimw_ == 2) { - double td = 0.0 ; - for (const auto& vit : vertices(gridView_, Dune::Partitions::all) ) - { - auto xyz_local = vit.geometry().corner(0); // vertices only have one corner - x_inout.data()[i] = static_cast(xyz_local[0]); - y_inout.data()[i] = static_cast(xyz_local[1]); - z_inout.data()[i] = static_cast(td); - i++; - } - } - assert(i == nvertices_); // As we are templated on the Dune::PartitionSet, this cannot change - return i; - } - - - /** - Write positions of vertices as array of structures : x,y,z,x,y,z,x,y,z,... + Returns the number of vertices written + */ + template long writeGridPoints_AOS(VectType &xyz_inout) { + size_t check_size = xyz_inout.size(); - Returns the number of vertices written - */ - template - long writeGridPoints_AOS( T* xyz_inout, long max_size=0 ) - { - if (max_size < nvertices_ * 3) { - assert(max_size >= nvertices_ * 3); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints_AOS( T* xyz_inout ) " - + " Input objects max_size (" + std::to_string(max_size) + ") is not sufficient to fit the nvertices_ * 3 values (" - + std::to_string(nvertices_ * 3) + ")" ); - } - - long i = 0; - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout[i++] = static_cast(xyz_local[0]); - xyz_inout[i++] = static_cast(xyz_local[1]); - xyz_inout[i++] = static_cast(xyz_local[2]); - - } - } else if (dimw_ == 2) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout[i++] = static_cast(xyz_local[0]); - xyz_inout[i++] = static_cast(xyz_local[1]); - xyz_inout[i++] = static_cast(0.0); - } - } - return ( (i) / 3 ); - } - - /** - Write positions of vertices as array of structures : x,y,z,x,y,z,x,y,z,... + using VT = decltype(xyz_inout.data()[0]); - Returns the number of vertices written - */ - template - long writeGridPoints_AOS( VectType& xyz_inout ) - { - size_t check_size = xyz_inout.size() ; - - using VT = decltype(xyz_inout.data()[0]); - - if (check_size < nvertices_ * 3) { - assert(check_size >= nvertices_ * 3); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints_AOS( VectType& xyz_inout ) " - + " Input objects check_size (" + std::to_string(check_size) + ") is not sufficient to fit the nvertices_ * 3 values (" - + std::to_string(nvertices_ * 3) + ")" ); - } - - long i = 0; - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout.data()[i++] = static_cast(xyz_local[0]); - xyz_inout[i++] = static_cast(xyz_local[1]); - xyz_inout[i++] = static_cast(xyz_local[2]); - - } - } else if (dimw_ == 2) { - double td = 0.0 ; - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout[i++] = static_cast(xyz_local[0]); - xyz_inout[i++] = static_cast(xyz_local[1]); - xyz_inout[i++] = static_cast(td); - } - } - return ( (i) / 3 ); - } - - - /** - Write positions of vertices as structure of arrays : x,x,x,...,y,y,y,...,z,z,z,... - - Returns the number of vertices written - */ - template - long writeGridPoints_SOA( T* xyz_inout, long max_size=0 ) - { - if (max_size < nvertices_ * 3) { - assert(max_size >= nvertices_ * 3); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints_SOA( T& xyz_inout ) " - + " Input objects max_size (" + std::to_string(max_size) + ") is not sufficient to fit the nvertices_ * 3 values (" - + std::to_string(nvertices_ * 3) + ")" ); - } - - long i = 0; - // Get offsets into structure - T* xyz_inout_y = xyz_inout + nvertices_; - T* xyz_inout_z = xyz_inout + (2 * nvertices_); - - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout[i] = static_cast(xyz_local[0]); - xyz_inout_y[i]= static_cast(xyz_local[1]); - xyz_inout_z[i] = static_cast(xyz_local[2]); - i++; - } - } else if (dimw_ == 2) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout[i] = static_cast(xyz_local[0]); - xyz_inout_y[i]= static_cast(xyz_local[1]); - xyz_inout_z[i] = static_cast(0.0); - i++; - } - } - return (i); - } - - /** - Write positions of vertices as structure of arrays : x,x,x,...,y,y,y,...,z,z,z,... - - Returns the number of vertices written - */ - template - long writeGridPoints_SOA( VectType& xyz_inout ) - { - size_t check_size = xyz_inout.size() ; - - if (check_size < nvertices_ * 3) { - assert(check_size >= nvertices_ * 3); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeGridPoints_SOA( VectType& xyz_inout ) " - + " Input objects check_size (" + std::to_string(check_size) + ") is not sufficient to fit the nvertices_ * 3 values (" - + std::to_string(nvertices_ * 3) + ")" ); - } - - using VT = decltype(xyz_inout.data()[0]); - - long i = 0; - // Get offsets into structure - VT* xyz_inout_y = xyz_inout.data() + nvertices_; - VT* xyz_inout_z = xyz_inout.data() + (2 * nvertices_); - - if (dimw_ == 3) { - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout.data()[i] = static_cast(xyz_local[0]); - xyz_inout_y[i]= static_cast(xyz_local[1]); - xyz_inout_z[i] = static_cast(xyz_local[2]); - i++; - } - } else if (dimw_ == 2) { - double td = 0.0 ; - for (const auto& vit : vertices(gridView_, Dune::Partitions::all)) - { - auto xyz_local = vit.geometry().corner(0); - xyz_inout.data()[i] = static_cast(xyz_local[0]); - xyz_inout_y[i]= static_cast(xyz_local[1]); - xyz_inout_z[i] = static_cast(td); - i++; - } - } - return (i); + if (check_size < nvertices_ * 3) { + assert(check_size >= nvertices_ * 3); + OPM_THROW( + std::runtime_error, + "Opm::GridDataOutput::writeGridPoints_AOS( VectType& xyz_inout ) " + + " Input objects check_size (" + std::to_string(check_size) + + ") is not sufficient to fit the nvertices_ * 3 values (" + + std::to_string(nvertices_ * 3) + ")"); } - /** - * Write the connectivity array - directly to the pointer given in parameter 1 - Reorders the indecies as selected either in DUNE order or VTK order. + long i = 0; + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout.data()[i++] = static_cast(xyz_local[0]); + xyz_inout[i++] = static_cast(xyz_local[1]); + xyz_inout[i++] = static_cast(xyz_local[2]); + } + } else if (dimw_ == 2) { + double td = 0.0; + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout[i++] = static_cast(xyz_local[0]); + xyz_inout[i++] = static_cast(xyz_local[1]); + xyz_inout[i++] = static_cast(td); + } + } + return ((i) / 3); + } - Returns the number of corner indices written. - */ - template - long writeConnectivity(Integer * connectivity_inout, ConnectivityVertexOrder whichOrder, long max_size=0 ) - { - if (max_size < ncorners_ ) { - assert(max_size >= ncorners_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeConnectivity( T* connectivity_inout ) " - + " Input objects size (" + std::to_string(max_size) + ") is not sufficient to fit the ncorners_ values (" - + std::to_string(ncorners_) + ")" ); + /** + Write positions of vertices as structure of arrays : + x,x,x,...,y,y,y,...,z,z,z,... + + Returns the number of vertices written + */ + template + long writeGridPoints_SOA(T *xyz_inout, long max_size = 0) { + if (max_size < nvertices_ * 3) { + // assert(max_size >= nvertices_ * 3); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeGridPoints_SOA( T& xyz_inout ) " + + " Input objects max_size (" + std::to_string(max_size) + + ") is not sufficient to fit the nvertices_ * 3 values (" + + std::to_string(nvertices_ * 3) + ")"); + } + + long i = 0; + // Get offsets into structure + T *xyz_inout_y = xyz_inout + nvertices_; + T *xyz_inout_z = xyz_inout + (2 * nvertices_); + + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout[i] = static_cast(xyz_local[0]); + xyz_inout_y[i] = static_cast(xyz_local[1]); + xyz_inout_z[i] = static_cast(xyz_local[2]); + i++; + } + } else if (dimw_ == 2) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout[i] = static_cast(xyz_local[0]); + xyz_inout_y[i] = static_cast(xyz_local[1]); + xyz_inout_z[i] = static_cast(0.0); + i++; + } + } + return (i); + } + + /** + Write positions of vertices as structure of arrays : + x,x,x,...,y,y,y,...,z,z,z,... + + Returns the number of vertices written + */ + template long writeGridPoints_SOA(VectType &xyz_inout) { + size_t check_size = xyz_inout.size(); + + if (check_size < nvertices_ * 3) { + // assert(check_size >= nvertices_ * 3); + OPM_THROW( + std::runtime_error, + "Opm::GridDataOutput::writeGridPoints_SOA( VectType& xyz_inout ) " + + " Input objects check_size (" + std::to_string(check_size) + + ") is not sufficient to fit the nvertices_ * 3 values (" + + std::to_string(nvertices_ * 3) + ")"); + } + + using VT = decltype(xyz_inout.data()[0]); + + long i = 0; + // Get offsets into structure + VT *xyz_inout_y = xyz_inout.data() + nvertices_; + VT *xyz_inout_z = xyz_inout.data() + (2 * nvertices_); + + if (dimw_ == 3) { + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout.data()[i] = static_cast(xyz_local[0]); + xyz_inout_y[i] = static_cast(xyz_local[1]); + xyz_inout_z[i] = static_cast(xyz_local[2]); + i++; + } + } else if (dimw_ == 2) { + double td = 0.0; + for (const auto &vit : vertices(gridView_, Dune::Partitions::all)) { + auto xyz_local = vit.geometry().corner(0); + xyz_inout.data()[i] = static_cast(xyz_local[0]); + xyz_inout_y[i] = static_cast(xyz_local[1]); + xyz_inout_z[i] = static_cast(td); + i++; + } + } + return (i); + } + + /** + * Write the connectivity array - directly to the pointer given in parameter 1 + Reorders the indices as selected either in DUNE order or VTK order. + + Returns the number of corner indices written. + */ + template + long writeConnectivity(Integer *connectivity_inout, + ConnectivityVertexOrder whichOrder, + long max_size = 0) { + if (max_size < ncorners_) { + // assert(max_size >= ncorners_); + OPM_THROW( + std::runtime_error, + "Opm::GridDataOutput::writeConnectivity( T* connectivity_inout ) " + + " Input objects size (" + std::to_string(max_size) + + ") is not sufficient to fit the ncorners_ values (" + + std::to_string(ncorners_) + ")"); + } + + long i = 0; + if (whichOrder == DUNE) { + // DUNE order + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + for (auto vx = 0; vx < cell_corners; ++vx) { + const int vxIdx = gridView_.indexSet().subIndex(cit, vx, 3); + connectivity_inout[i + vx] = vxIdx; } - - long i = 0; - if ( whichOrder == DUNE ) { - // DUNE order - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - for( auto vx = 0; vx < cell_corners; ++ vx ) - { - const int vxIdx = gridView_.indexSet().subIndex( cit, vx, 3 ); - connectivity_inout[i + vx] = vxIdx; - } - i += cell_corners; - } - } else { - // VTK order - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - for( auto vx = 0; vx < cell_corners; ++ vx ) - { - const int vxIdx = gridView_.indexSet().subIndex( cit, vx, 3 ); - int vtkOrder; - vtkOrder = Dune::VTK::renumber(cit.type(), vx); - connectivity_inout[i + vtkOrder] = vxIdx; - } - i += cell_corners; - } + i += cell_corners; + } + } else { + // VTK order + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + for (auto vx = 0; vx < cell_corners; ++vx) { + const int vxIdx = gridView_.indexSet().subIndex(cit, vx, 3); + int vtkOrder; + vtkOrder = Dune::VTK::renumber(cit.type(), vx); + connectivity_inout[i + vtkOrder] = vxIdx; } - return (i); + i += cell_corners; + } } - - /** - * Write the connectivity array - directly to the pointer given in parameter 1 - Reorders the indecies as selected either in DUNE order or VTK order. + return (i); + } - Returns the number of corner indices written. - */ - template - long writeConnectivity(VectType & connectivity_inout, ConnectivityVertexOrder whichOrder) - { - size_t check_size = connectivity_inout.size() ; - - if (check_size < ncorners_ ) { - assert(check_size >= ncorners_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeConnectivity( VectType& connectivity_inout ) " - + " Input objects size (" + std::to_string(check_size) + ") is not sufficient to fit the ncorners_ values (" - + std::to_string(ncorners_) + ")" ); + /** + * Write the connectivity array - directly to the pointer given in parameter 1 + Reorders the indices as selected either in DUNE order or VTK order. + + Returns the number of corner indices written. + */ + template + long writeConnectivity(VectType &connectivity_inout, + ConnectivityVertexOrder whichOrder) { + size_t check_size = connectivity_inout.size(); + + if (check_size < ncorners_) { + // assert(check_size >= ncorners_); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeConnectivity( VectType& " + "connectivity_inout ) " + + " Input objects size (" + std::to_string(check_size) + + ") is not sufficient to fit the ncorners_ values (" + + std::to_string(ncorners_) + ")"); + } + + using VT = decltype(connectivity_inout.data()[0]); + + long i = 0; + if (whichOrder == DUNE) { + // DUNE order + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + for (auto vx = 0; vx < cell_corners; ++vx) { + const int vxIdx = gridView_.indexSet().subIndex(cit, vx, 3); + connectivity_inout.data()[i + vx] = vxIdx; } - - using VT = decltype(connectivity_inout.data()[0]); - - long i = 0; - if ( whichOrder == DUNE ) { - // DUNE order - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - for( auto vx = 0; vx < cell_corners; ++ vx ) - { - const int vxIdx = gridView_.indexSet().subIndex( cit, vx, 3 ); - connectivity_inout.data()[i + vx] = vxIdx; - } - i += cell_corners; - } - } else { - // VTK order - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - for( auto vx = 0; vx < cell_corners; ++ vx ) - { - const int vxIdx = gridView_.indexSet().subIndex( cit, vx, 3 ); - int vtkOrder; - vtkOrder = Dune::VTK::renumber(cit.type(), vx); - connectivity_inout.data()[i + vtkOrder] = vxIdx; - } - i += cell_corners; - } + i += cell_corners; + } + } else { + // VTK order + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + for (auto vx = 0; vx < cell_corners; ++vx) { + const int vxIdx = gridView_.indexSet().subIndex(cit, vx, 3); + int vtkOrder; + vtkOrder = Dune::VTK::renumber(cit.type(), vx); + connectivity_inout.data()[i + vtkOrder] = vxIdx; } - return (i); + i += cell_corners; + } + } + return (i); + } + + /** + * Write the offsets values - directly to the pointer given in parameter 1 + Returns the (number of offset values written + 1) + */ + template + long writeOffsetsCells(Integer *offsets_inout, long max_size = 0) { + if (max_size < ncells_) { + // assert(max_size >= ncells_); + OPM_THROW( + std::runtime_error, + "Opm::GridDataOutput::writeOffsetsCells( T* offsets_inout ) " + + " Input objects max_size (" + std::to_string(max_size) + + ") is not sufficient to fit the ncells_ values (" + + std::to_string(ncells_) + ")"); + } + long i = 1; + offsets_inout[0] = 0; + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + offsets_inout[i] = offsets_inout[i - 1] + cell_corners; + i++; + } + return (i); // This should be 1 greater than ncells_ + } + + /** + * Write the offsets values - directly to the pointer given in parameter 1 + Returns the (number of offset values written + 1) + */ + template long writeOffsetsCells(VectType &offsets_inout) { + size_t check_size = offsets_inout.size(); + if (check_size < ncells_) { + // assert(check_size >= ncells_); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeOffsetsCells( VectType& " + "offsets_inout ) " + + " Input objects check_size (" + std::to_string(check_size) + + ") is not sufficient to fit the ncells_ values (" + + std::to_string(ncells_) + ")"); } + // using VT = decltype(offsets_inout.data()[0]); - /** - * Write the offsets values - directly to the pointer given in parameter 1 - Returns the (number of offset values written + 1) - */ - template - long writeOffsetsCells( Integer* offsets_inout, long max_size=0 ) - { - if (max_size < ncells_ ) { - assert(max_size >= ncells_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeOffsetsCells( T* offsets_inout ) " - + " Input objects max_size (" + std::to_string(max_size) + ") is not sufficient to fit the ncells_ values (" - + std::to_string(ncells_) + ")" ); - } - long i = 1; - offsets_inout[0] = 0; - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - offsets_inout[i] = offsets_inout[i-1] + cell_corners; - i++; - } - return (i); // This should be 1 greater than ncells_ + long i = 1; + offsets_inout.data()[0] = 0; + for (const auto &cit : elements(gridView_, dunePartition_)) { + auto cell_corners = cit.geometry().corners(); + offsets_inout.data()[i] = offsets_inout.data()[i - 1] + cell_corners; + i++; } - - /** - * Write the offsets values - directly to the pointer given in parameter 1 - Returns the (number of offset values written + 1) - */ - template - long writeOffsetsCells( VectType& offsets_inout ) - { - size_t check_size = offsets_inout.size() ; - if (check_size < ncells_ ) { - assert(check_size >= ncells_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeOffsetsCells( VectType& offsets_inout ) " - + " Input objects check_size (" + std::to_string(check_size) + ") is not sufficient to fit the ncells_ values (" - + std::to_string(ncells_) + ")" ); - } - - // using VT = decltype(offsets_inout.data()[0]); - - long i = 1; - offsets_inout.data()[0] = 0; - for (const auto& cit : elements(gridView_, dunePartition_)) - { - auto cell_corners = cit.geometry().corners(); - offsets_inout.data()[i] = offsets_inout.data()[i-1] + cell_corners; - i++; - } - return (i); // This should be 1 greater than ncells_ + return (i); // This should be 1 greater than ncells_ + } + + /** + * Write the Cell types array - directly to the pointer given in parameter 1 + */ + template + long writeCellTypes(Integer *types_inout, long max_size = 0) { + if (max_size < ncells_) { + // assert(max_size >= ncells_); + OPM_THROW(std::runtime_error, + "Opm::GridDataOutput::writeCellTypes( T* types_inout ) " + + " Input objects max_size (" + std::to_string(max_size) + + ") is not sufficient to fit the ncells_ values (" + + std::to_string(ncells_) + ")"); } - - - /** - * Write the Cell types array - directly to the pointer given in parameter 1 - */ - template - long writeCellTypes( Integer* types_inout, long max_size=0) - { - if (max_size < ncells_ ) { - assert(max_size >= ncells_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeCellTypes( T* types_inout ) " - + " Input objects max_size (" + std::to_string(max_size) + ") is not sufficient to fit the ncells_ values (" - + std::to_string(ncells_) + ")" ); - } - int i = 0; - for (const auto& cit : elements(gridView_, dunePartition_)) - { - Integer vtktype = static_cast(Dune::VTK::geometryType(cit.type())); - types_inout[i++] = vtktype; - } - return (i); + int i = 0; + for (const auto &cit : elements(gridView_, dunePartition_)) { + Integer vtktype = + static_cast(Dune::VTK::geometryType(cit.type())); + types_inout[i++] = vtktype; } - - /** - * Write the Cell types array - directly to the pointer given in parameter 1 - */ - template - long writeCellTypes( VectType& types_inout) - { - size_t check_size = types_inout.size() ; - - if (check_size < ncells_ ) { - assert(check_size >= ncells_); - OPM_THROW(std::runtime_error, "Opm::GridDataOutput::writeCellTypes( VectType& types_inout ) " - + " Input objects check_size (" + std::to_string(check_size) + ") is not sufficient to fit the ncells_ values (" - + std::to_string(ncells_) + ")" ); - } - using VT = decltype(types_inout.data()[0]); - int i = 0; - for (const auto& cit : elements(gridView_, dunePartition_)) - { - int vtktype = static_cast(Dune::VTK::geometryType(cit.type())); - types_inout.data()[i++] = vtktype; - } - return (i); + return (i); + } + + /** + * Write the Cell types array - directly to the pointer given in parameter 1 + */ + template long writeCellTypes(VectType &types_inout) { + size_t check_size = types_inout.size(); + + if (check_size < ncells_) { + // assert(check_size >= ncells_); + OPM_THROW( + std::runtime_error, + "Opm::GridDataOutput::writeCellTypes( VectType& types_inout ) " + + " Input objects check_size (" + std::to_string(check_size) + + ") is not sufficient to fit the ncells_ values (" + + std::to_string(ncells_) + ")"); } - - std::string getPartitionTypeString ( ) - { - if (this->dunePartition_ == Dune::Partitions::all) - return (std::string("Dune::Partitions::all")); - if (this->dunePartition_ == Dune::Partitions::interior) - return (std::string("Dune::Partitions::interior")); - if (this->dunePartition_ == Dune::Partitions::interiorBorder) - return (std::string("Dune::Partitions::interiorBorder")); - if (this->dunePartition_ == Dune::Partitions::interiorBorderOverlap) - return (std::string("Dune::Partitions::interiorBorderOverlap")); - if (this->dunePartition_ == Dune::Partitions::front) - return (std::string("Dune::Partitions::front")); - if (this->dunePartition_ == Dune::Partitions::interiorBorderOverlapFront) - return (std::string("Dune::Partitions::InteriorBorderOverlapFront")); - if (this->dunePartition_ == Dune::Partitions::border) - return (std::string("Dune::Partitions::border")); - if (this->dunePartition_ == Dune::Partitions::ghost) - return (std::string("Dune::Partitions::ghost")); - - return (std::string("Unknown Dune::PartitionSet<>")); + using VT = decltype(types_inout.data()[0]); + int i = 0; + for (const auto &cit : elements(gridView_, dunePartition_)) { + int vtktype = static_cast(Dune::VTK::geometryType(cit.type())); + types_inout.data()[i++] = vtktype; } + return (i); + } - Dune::PartitionSet getPartition ( void ) - { - return ( this->dunePartition_ ); - } + std::string getPartitionTypeString() { + if (this->dunePartition_ == Dune::Partitions::all) + return (std::string("Dune::Partitions::all")); + if (this->dunePartition_ == Dune::Partitions::interior) + return (std::string("Dune::Partitions::interior")); + if (this->dunePartition_ == Dune::Partitions::interiorBorder) + return (std::string("Dune::Partitions::interiorBorder")); + if (this->dunePartition_ == Dune::Partitions::interiorBorderOverlap) + return (std::string("Dune::Partitions::interiorBorderOverlap")); + if (this->dunePartition_ == Dune::Partitions::front) + return (std::string("Dune::Partitions::front")); + if (this->dunePartition_ == Dune::Partitions::interiorBorderOverlapFront) + return (std::string("Dune::Partitions::InteriorBorderOverlapFront")); + if (this->dunePartition_ == Dune::Partitions::border) + return (std::string("Dune::Partitions::border")); + if (this->dunePartition_ == Dune::Partitions::ghost) + return (std::string("Dune::Partitions::ghost")); - void printGridDetails(std::ostream& outstr ) - { - outstr << "Dune Partition = " << partition_value_ << ", " << getPartitionTypeString() << std::endl; - outstr << "ncells_: " << getNCells() << std::endl; - outstr << "nvertices_: " << getNVertices() << std::endl; - outstr << "ncorners_: " << getNCorners() << std::endl; - } + return (std::string("Unknown Dune::PartitionSet<>")); + } + Dune::PartitionSet getPartition(void) { + return (this->dunePartition_); + } - int getNCells() - { - return(ncells_); - } + void printGridDetails(std::ostream &outstr) { + outstr << "Dune Partition = " << partition_value_ << ", " + << getPartitionTypeString() << std::endl; + outstr << "ncells_: " << getNCells() << std::endl; + outstr << "nvertices_: " << getNVertices() << std::endl; + outstr << "ncorners_: " << getNCorners() << std::endl; + } - int getNVertices() - { - return(nvertices_); - } + int getNCells() { return (ncells_); } - int getNCorners() - { - return(ncorners_); - } + int getNVertices() { return (nvertices_); } - std::string getError() - { - return error_strm_.str(); - } + int getNCorners() { return (ncorners_); } - void clearError() - { - error_strm_.str(""); - } + std::string getError() { return error_strm_.str(); } - bool hasError() - { - if ( error_strm_.str().length() > 0 ) - return true; - else - return false; - } + void clearError() { error_strm_.str(""); } - protected: + bool hasError() { + if (error_strm_.str().length() > 0) + return true; + else + return false; + } - GridView gridView_; // the grid - - Dune::PartitionSet dunePartition_; - unsigned int partition_value_; +protected: + GridView gridView_; // the grid - /** - Current partition grid information - */ - int ncells_; - /** - Current partition grid information - */ - int nvertices_; - /** - Current partition grid information - */ - int ncorners_; - - int dimw_; // dimensions of the input grid - - private: - std::stringstream error_strm_; + Dune::PartitionSet dunePartition_; + unsigned int partition_value_; - }; + /** + Current partition grid information + */ + int ncells_; + /** + Current partition grid information + */ + int nvertices_; + /** + Current partition grid information + */ + int ncorners_; -} + int dimw_; // dimensions of the input grid -#endif +private: + std::stringstream error_strm_; +}; + +} // namespace Opm::GridDataOutput + +#endif diff --git a/opm/simulators/utils/initDamarisXmlFile.cpp b/opm/simulators/utils/initDamarisXmlFile.cpp index 3c7cd7154..fbc6e11a0 100644 --- a/opm/simulators/utils/initDamarisXmlFile.cpp +++ b/opm/simulators/utils/initDamarisXmlFile.cpp @@ -108,9 +108,9 @@ std::string initDamarisXmlFile() - - - + + + @@ -119,9 +119,9 @@ std::string initDamarisXmlFile() - - - + + +