update after pull request comments; addition of OUTPUTDIR variable to Damaris XML configuration

This commit is contained in:
josh bowden
2024-05-17 17:36:18 +02:00
parent 3630177e3e
commit 2744614f9c
4 changed files with 53 additions and 38 deletions

View File

@@ -42,6 +42,7 @@ int setPosition(const char* field, int rank, int64_t pos)
{ {
int dam_err = damaris_set_position(field, &pos); int dam_err = damaris_set_position(field, &pos);
if (dam_err != DAMARIS_OK) { if (dam_err != DAMARIS_OK) {
// OpmLog::error only prints from rank 0
OpmLog::error(fmt::format("damariswriter::setPosition() : ( rank:{}) " OpmLog::error(fmt::format("damariswriter::setPosition() : ( rank:{}) "
"damaris_set_position({}, ...), Damaris Error: {} ", "damaris_set_position({}, ...), Damaris Error: {} ",
rank, field, damaris_error_string(dam_err))); rank, field, damaris_error_string(dam_err)));
@@ -54,6 +55,7 @@ int setParameter(const char* field, int rank, int value)
{ {
int dam_err = damaris_parameter_set(field, &value, sizeof(int)); int dam_err = damaris_parameter_set(field, &value, sizeof(int));
if (dam_err != DAMARIS_OK) { if (dam_err != DAMARIS_OK) {
// OpmLog::error only prints from rank 0
OpmLog::error(fmt::format("damariswriter::setParameter() (rank:{}) " OpmLog::error(fmt::format("damariswriter::setParameter() (rank:{}) "
"damaris_parameter_set(\"{}\",...)", rank, field)); "damaris_parameter_set(\"{}\",...)", rank, field));
} }
@@ -65,6 +67,7 @@ int write(const char* field, int rank, const void* data)
{ {
int dam_err = damaris_write(field, data); int dam_err = damaris_write(field, data);
if (dam_err != DAMARIS_OK) { if (dam_err != DAMARIS_OK) {
// OpmLog::error only prints from rank 0
OpmLog::error(fmt::format("damariswriter::write() : ( rank:{}) " OpmLog::error(fmt::format("damariswriter::write() : ( rank:{}) "
"damaris_write({}, ...), Damaris Error: {} ", "damaris_write({}, ...), Damaris Error: {} ",
rank, field, damaris_error_string(dam_err))); rank, field, damaris_error_string(dam_err)));

View File

@@ -158,10 +158,10 @@ public:
"the same node/server as it is used for the Damaris shmem name and by " "the same node/server as it is used for the Damaris shmem name and by "
"the Python Dask library to locate sections of variables."); "the Python Dask library to locate sections of variables.");
Parameters::registerParam<TypeTag, Properties::DamarisLimitVariables> Parameters::registerParam<TypeTag, Properties::DamarisLimitVariables>
("A comma separated list of variable names that a user wants to pass" ("A comma separated list of variable names that a user wants to pass "
"through via DamarisOutput::DamarisWriter::writeOutput)() to the " "through via DamarisOutput::DamarisWriter::writeOutput)() to the "
"damaris_write() call. This can be used to limit the number of" "damaris_write() call. This can be used to limit the number of "
"variables being passed to the Daamis plugins (Paraview, Python and HDF5)"); "variables being passed to the Damaris plugins (Paraview, Python and HDF5)");
} }
// The Simulator object should preferably have been const - the // The Simulator object should preferably have been const - the
@@ -269,39 +269,26 @@ public:
this->damarisUpdate_ = false; this->damarisUpdate_ = false;
} }
/*if (this->damarisOutputModule_->getPRESSURE_ptr() != nullptr)
{
dam_err_ = DamarisOutput::setPosition("PRESSURE", rank_,
this->elements_rank_offsets_[rank_]);
dam_err_ = DamarisOutput::write("PRESSURE", rank_,
this->damarisOutputModule_->getPRESSURE_ptr());
dam_err_ = DamarisOutput::endIteration(rank_);
}*/
int cell_data_written = 0 ;
// Call damaris_set_position() for all available variables
// There is an assumption that all variables are the same size, with the same offset.
// see initDamarisTemplateXmlFile.cpp for the Damaris XML descriptions.
for ( auto damVar : localCellData ) {
// std::map<std::string, data::CellData>
const std::string name = damVar.first ;
dam_err_ = DamarisOutput::setPosition(name.c_str(), rank_,
this->elements_rank_offsets_[rank_]);
}
// Call damaris_write() for all available variables // Call damaris_write() for all available variables
for ( auto damVar : localCellData ) for ( const auto& damVar : localCellData )
{ {
// std::map<std::string, data::CellData> // std::map<std::string, data::CellData>
const std::string& name = damVar.first ; const std::string& name = damVar.first ;
// If the wanted_vars_set_ set is empty then we default to passing through
std::unordered_set<std::string>::const_iterator is_in_set = wanted_vars_set_.find ( name ); // all the variables/
if (wanted_vars_set_.count(name) || wanted_vars_set_.empty())
if ((is_in_set != wanted_vars_set_.end() ) || (wanted_vars_set_.size() == 0)) { {
data::CellData dataCol = damVar.second ; const data::CellData& dataCol = damVar.second ;
OpmLog::debug(fmt::format("Name of Damaris Variable : ( rank:{}) name: {} ", rank_, name)); OpmLog::debug(fmt::format("Name of Damaris Variable : ( rank:{}) name: {} ", rank_, name));
// Call damaris_set_position() for all available variables
// There is an assumption that all variables are the same size, with the same offset.
// see initDamarisTemplateXmlFile.cpp for the Damaris XML descriptions.
dam_err_ = DamarisOutput::setPosition(name.c_str(), rank_,
this->elements_rank_offsets_[rank_]);
// It does not seem I can test for what type of data is present (double or int) // It does not seem I can test for what type of data is present (double or int)
// in the std::variant within the data::CellData, so I will use a try catch block. // in the std::variant within the data::CellData, so I will use a try catch block.
// Although, only MPI_RANK and GLOBAL_CELL_INDEX are set as integer types (in the // Although, only MPI_RANK and GLOBAL_CELL_INDEX are set as integer types (in the
@@ -312,6 +299,8 @@ public:
if (dataCol.data<double>().size() >= this->numElements_) { if (dataCol.data<double>().size() >= this->numElements_) {
dam_err_ = DamarisOutput::write(name.c_str(), rank_, dam_err_ = DamarisOutput::write(name.c_str(), rank_,
dataCol.data<double>().data()) ; dataCol.data<double>().data()) ;
} else {
OpmLog::info(fmt::format("( rank:{}) The variable \"{}\" was found to be of a different size {} (not {}).", rank_, name, dataCol.data<double>().size(), this->numElements_ ));
} }
} }
catch (std::bad_variant_access const& ex) { catch (std::bad_variant_access const& ex) {
@@ -319,13 +308,20 @@ public:
if (dataCol.data<int>().size() >= this->numElements_) { if (dataCol.data<int>().size() >= this->numElements_) {
dam_err_ = DamarisOutput::write(name.c_str(), rank_, dam_err_ = DamarisOutput::write(name.c_str(), rank_,
dataCol.data<int>().data()) ; dataCol.data<int>().data()) ;
} else {
OpmLog::info(fmt::format("( rank:{}) The variable \"{}\" was found to be of a different size {} (not {}).", rank_, name, dataCol.data<int>().size(), this->numElements_ ));
} }
} }
++cell_data_written ;
} }
} }
if (!cell_data_written) {
OpmLog::info(fmt::format("( rank:{}) No simulation data written to the Damaris server - check --damaris-limit-variables command line option (if used) has valid variable name(s) and that the Damaris XML file contains variable names that are available in your simulation.", rank_));
} else {
OpmLog::debug(fmt::format("( rank:{}) {} Damaris Variables written to the Damaris servers", rank_, cell_data_written));
}
/* /*
Code for when we want to pass to Damaris the single cell 'block' data variables Code for when we want to pass to Damaris the single cell 'block' data variables
auto mybloc = damarisOutputModule_->getBlockData() ; auto mybloc = damarisOutputModule_->getBlockData() ;
@@ -399,7 +395,13 @@ private:
// Fill the created memory area // Fill the created memory area
std::fill(mpi_rank_var.data(), mpi_rank_var.data() + numElements_, rank_); std::fill(mpi_rank_var.data(), mpi_rank_var.data() + numElements_, rank_);
// Pass the output directory string through as a Damaris variable so that
// Python code (as an example) can use the path as required.
const auto& outputDir = simulator_.vanguard().eclState().cfg().io().getOutputDir();
if (outputDir.size() > 0) {
dam_err_ = DamarisOutput::setParameter("path_string_length", rank_, outputDir.size()) ;
dam_err_ = DamarisOutput::write("OUTPUTDIR", rank_, outputDir.c_str());
}
} }
void writeDamarisGridOutput() void writeDamarisGridOutput()

View File

@@ -85,6 +85,8 @@ struct DamarisSettings {
* Damaris and perform checks and logic so as to create a valid XML file. * Damaris and perform checks and logic so as to create a valid XML file.
* N.B. The created XML file can be overridden using an environment variable * N.B. The created XML file can be overridden using an environment variable
* FLOW_DAMARIS_XML_FILE that points to a Damaris XML file. * FLOW_DAMARIS_XML_FILE that points to a Damaris XML file.
*
* N.B. This needs to be called before damaris_init()
*/ */
template<class TypeTag> template<class TypeTag>
std::map<std::string, std::string> std::map<std::string, std::string>
@@ -116,6 +118,7 @@ getSetOfIncludedVariables(void)
{ {
std::unordered_set<std::string> resuset ; std::unordered_set<std::string> resuset ;
std::string tstr; std::string tstr;
// The --damaris-limit-variables command line option (defaults to empty string)
std::string damarisLimitVars = Parameters::get<TypeTag, Properties::DamarisLimitVariables>(); std::string damarisLimitVars = Parameters::get<TypeTag, Properties::DamarisLimitVariables>();
std::stringstream ss(damarisLimitVars); std::stringstream ss(damarisLimitVars);
@@ -125,8 +128,10 @@ getSetOfIncludedVariables(void)
// tstr.erase(std::remove_if(tstr.begin(), tstr.end(), ::isspace), tstr.end()); // tstr.erase(std::remove_if(tstr.begin(), tstr.end(), ::isspace), tstr.end());
std::string::iterator end_pos = std::remove(tstr.begin(), tstr.end(), ' '); std::string::iterator end_pos = std::remove(tstr.begin(), tstr.end(), ' ');
tstr.erase(end_pos, tstr.end()); tstr.erase(end_pos, tstr.end());
// place in set (no duplicates possible in set) // place in set (no duplicates possible in set and no empty string)
resuset.insert(tstr) ; if (tstr != "") {
resuset.insert(tstr) ;
}
} }
return (resuset) ; return (resuset) ;
} }

View File

@@ -48,13 +48,18 @@ std::string initDamarisXmlFile()
<parameter name="n_elements_total" type="int" value="1" /> <parameter name="n_elements_total" type="int" value="1" />
<parameter name="n_elements_local" type="int" value="1" /> <parameter name="n_elements_local" type="int" value="1" />
<parameter name="n" type="int" value="1" /> <parameter name="n" type="int" value="1" />
<parameter name="path_string_length" type="int" value="1" />
<layout name="path_string_layout" type="char" dimensions="path_string_length" comment="The length of the output directory path string" />
<variable name="OUTPUTDIR" layout="path_string_layout" type="scalar" visualizable="false" mesh="#" unit="" time-varying="false" store="#" script="_MAKE_AVAILABLE_IN_PYTHON_" />
<layout name="zonal_layout_usmesh_integer" type="int" dimensions="n_elements_local" global="n_elements_total" comment="For the field data e.g. Pressure" /> <layout name="zonal_layout_usmesh_integer" type="int" dimensions="n_elements_local" global="n_elements_total" comment="For the field data e.g. Pressure" />
<variable name="GLOBAL_CELL_INDEX" layout="zonal_layout_usmesh_integer" type="scalar" visualizable="false" time-varying="false" centering="zonal" store="_MYSTORE_OR_EMPTY_REGEX_" script="_MAKE_AVAILABLE_IN_PYTHON_" /> <variable name="GLOBAL_CELL_INDEX" layout="zonal_layout_usmesh_integer" type="scalar" visualizable="false" time-varying="false" centering="zonal" store="_MYSTORE_OR_EMPTY_REGEX_" script="_MAKE_AVAILABLE_IN_PYTHON_" />
<layout name="zonal_layout_usmesh" type="double" dimensions="n_elements_local" global="n_elements_total" comment="For the field data e.g. Pressure" /> <layout name="zonal_layout_usmesh" type="double" dimensions="n_elements_local" global="n_elements_total" comment="For the field data e.g. Pressure" />
<variable name="PRESSURE" layout="zonal_layout_usmesh" type="scalar" visualizable="true" mesh="us_mesh" unit="_PRESSURE_UNIT_" centering="zonal" select-file="GLOBAL_CELL_INDEX" store="_MYSTORE_OR_EMPTY_REGEX_" script="_MAKE_AVAILABLE_IN_PYTHON_" /> <variable name="PRESSURE" layout="zonal_layout_usmesh" type="scalar" visualizable="true" mesh="us_mesh" unit="_PRESSURE_UNIT_" centering="zonal" select-file="GLOBAL_CELL_INDEX" store="_MYSTORE_OR_EMPTY_REGEX_" script="_MAKE_AVAILABLE_IN_PYTHON_" />
<variable name="MY_TEST_VAR" layout="zonal_layout_usmesh" type="scalar" visualizable="true" mesh="us_mesh" unit="" centering="zonal" time-varying="true" select-file="GLOBAL_CELL_INDEX" store="_MYSTORE_OR_EMPTY_REGEX_" script="_MAKE_AVAILABLE_IN_PYTHON_" />
_MORE_VARIABLES_REGEX_ _MORE_VARIABLES_REGEX_
<variable name="MPI_RANK" layout="zonal_layout_usmesh_integer" type="scalar" visualizable="true" mesh="us_mesh" unit="rank" centering="zonal" store="_MYSTORE_MESH_OR_EMPTY_REGEX_" time-varying="false" select-file="GLOBAL_CELL_INDEX" script="_MAKE_AVAILABLE_IN_PYTHON_" comment="The MPI rank of each cell"/> <variable name="MPI_RANK" layout="zonal_layout_usmesh_integer" type="scalar" visualizable="true" mesh="us_mesh" unit="rank" centering="zonal" store="_MYSTORE_MESH_OR_EMPTY_REGEX_" time-varying="false" select-file="GLOBAL_CELL_INDEX" script="_MAKE_AVAILABLE_IN_PYTHON_" comment="The MPI rank of each cell"/>