OGS
AddProcessDataToMesh.cpp File Reference
Include dependency graph for AddProcessDataToMesh.cpp:

Go to the source code of this file.

Namespaces

namespace  ProcessLib

Functions

static void addOgsVersion (MeshLib::Mesh &mesh)
static void addSecondaryVariableNodes (NumLib::Time const &t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, ProcessLib::SecondaryVariable const &var, std::string const &output_name, MeshLib::Mesh &mesh)
static void addSecondaryVariableResiduals (NumLib::Time const &t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, ProcessLib::SecondaryVariable const &var, std::string const &output_name, MeshLib::Mesh &mesh)
static std::vector< double > copySolutionVector (GlobalVector const &x)
MeshLib::PropertyVector< std::size_t > const * getBulkNodeIdMapForPetscIfNecessary (MeshLib::Mesh const &mesh, NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::LocalToGlobalIndexMap const &bulk_mesh_dof_table)
static GlobalIndexType getIndexForComponentInSolutionVector (std::size_t const mesh_id, std::size_t const node_id, bool const is_ghost_node, int const global_component_id, GlobalVector const &x, NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::LocalToGlobalIndexMap const &bulk_mesh_dof_table, MeshLib::PropertyVector< std::size_t > const *const bulk_node_id_map)
static bool isGhostNode (MeshLib::Mesh const &mesh, std::size_t const node_id)
static std::set< std::string > addPrimaryVariablesToMesh (MeshLib::Mesh &mesh, GlobalVector const &x, std::vector< std::reference_wrapper< ProcessLib::ProcessVariable > > const &process_variables, std::set< std::string > const &output_variables, NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::LocalToGlobalIndexMap const &bulk_mesh_dof_table)
static void addSecondaryVariablesToMesh (ProcessLib::SecondaryVariableCollection const &secondary_variables, std::set< std::string > &names_of_already_output_variables, NumLib::Time const &t, std::vector< GlobalVector * > const &xs, MeshLib::Mesh &mesh, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, bool const output_residuals)
void ProcessLib::addProcessDataToMesh (NumLib::Time const &t, std::vector< GlobalVector * > const &xs, int const process_id, ProcessOutputData const &process_output_data, bool const output_secondary_variables, OutputDataSpecification const &process_output)

Function Documentation

◆ addOgsVersion()

void addOgsVersion ( MeshLib::Mesh & mesh)
static

Copies the ogs_version string containing the release number and the git hash.

Definition at line 21 of file AddProcessDataToMesh.cpp.

22{
23 auto& ogs_version_field = *MeshLib::getOrCreateMeshProperty<char>(
26
27 ogs_version_field.assign(GitInfoLib::GitInfo::ogs_version);
28}
const std::string OGS_VERSION
Definition GitInfo.cpp:11
GITINFOLIB_EXPORT const std::string ogs_version
PropertyVector< T > * getOrCreateMeshProperty(Mesh &mesh, std::string const &property_name, MeshItemType const item_type, int const number_of_components)

References MeshLib::getOrCreateMeshProperty(), MeshLib::IntegrationPoint, GitInfoLib::GitInfo::OGS_VERSION, and GitInfoLib::GitInfo::ogs_version.

Referenced by ProcessLib::addProcessDataToMesh().

◆ addPrimaryVariablesToMesh()

std::set< std::string > addPrimaryVariablesToMesh ( MeshLib::Mesh & mesh,
GlobalVector const & x,
std::vector< std::reference_wrapper< ProcessLib::ProcessVariable > > const & process_variables,
std::set< std::string > const & output_variables,
NumLib::LocalToGlobalIndexMap const & dof_table,
NumLib::LocalToGlobalIndexMap const & bulk_mesh_dof_table )
static

Adds data for the given process_variables to the given mesh, if they occur in output_variables.

Parameters
meshthe mesh the data is added to.
xthe global solution vector providing the data.
process_variablesthe primary variables comprising x.
output_variablesthe names of variables that can be added to the mesh.
dof_tablethe d.o.f. table related to the passed mesh and solution vector x.
bulk_mesh_dof_tablethe d.o.f. table related to the entire simulation domain and the passed solution vector x.
Note
Usually mesh and the full simulation domain are the same. But if output should be written to a sub mesh, they will differ. In that case, also the two d.o.f. tables will be different from each other.
The dof_table must correspond to the mesh, to the solution vector x and to the process_variables. I.e., if there are, e.g., two primary variables in x, there must also be two variables in the dof_table and two entries in process_variables and so on.
The dof_table must correspond to the bulk_mesh_dof_table, i.e., the former must have been derived from the latter. In particular, both must have the same number of variables and components.
Returns
The names of all variables that have been written to the mesh.

Definition at line 233 of file AddProcessDataToMesh.cpp.

241{
242 if (dof_table.getNumberOfVariables() !=
243 bulk_mesh_dof_table.getNumberOfVariables() ||
244 dof_table.getNumberOfGlobalComponents() !=
245 bulk_mesh_dof_table.getNumberOfGlobalComponents())
246 {
247 OGS_FATAL(
248 "The d.o.f. table for the passed mesh must have the same number of "
249 "variables and global components as the d.o.f. table for the full "
250 "simulation domain. But the values differ: {} != {} (variables) or "
251 "{} != {} (global components).",
252 dof_table.getNumberOfVariables(),
253 bulk_mesh_dof_table.getNumberOfVariables(),
254 dof_table.getNumberOfGlobalComponents(),
255 bulk_mesh_dof_table.getNumberOfGlobalComponents());
256 }
257
258 auto const number_of_dof_variables = dof_table.getNumberOfVariables();
259
260 if (number_of_dof_variables != static_cast<int>(process_variables.size()))
261 {
262 OGS_FATAL(
263 "The number of variables in the d.o.f. table differs from the "
264 "number of primary variables of the process {} != {}.",
265 number_of_dof_variables, process_variables.size());
266 }
267
268 auto const x_copy = copySolutionVector(x);
269 std::set<std::string> names_of_already_output_variables;
270
271 int global_component_offset_next = 0;
272
273 auto const* const bulk_node_id_map = getBulkNodeIdMapForPetscIfNecessary(
274 mesh, dof_table, bulk_mesh_dof_table);
275
276 for (int variable_id = 0; variable_id < number_of_dof_variables;
277 ++variable_id)
278 {
279 auto const& pv = process_variables[variable_id].get();
280 auto const n_components = pv.getNumberOfGlobalComponents();
281
282 // increase global component offset even if we do not add anything in
283 // this iteration
284 int global_component_offset = global_component_offset_next;
285 global_component_offset_next += n_components;
286
287 if (!output_variables.empty() &&
288 !output_variables.contains(pv.getName()))
289 {
290 continue;
291 }
292
293 names_of_already_output_variables.insert(pv.getName());
294
295 DBUG(" process variable {:s}", pv.getName());
296
297 auto& output_data = *MeshLib::getOrCreateMeshProperty<double>(
298 mesh, pv.getName(), MeshLib::MeshItemType::Node, n_components);
299
300 // mesh subsets are the same for all components
301 int const dummy_component_id = 0;
302 auto const& mesh_subset =
303 dof_table.getMeshSubset(variable_id, dummy_component_id);
304 auto const mesh_id = mesh_subset.getMeshID();
305
306 for (auto const* node : mesh_subset.getNodes())
307 {
308 auto const node_id = node->getID();
309 auto const is_ghost_node = isGhostNode(mesh, node_id);
310
311 for (int component_id = 0; component_id < n_components;
312 ++component_id)
313 {
314 auto const global_component_id =
315 global_component_offset + component_id;
316
317 auto const in_index = getIndexForComponentInSolutionVector(
318 mesh_id, node_id, is_ghost_node, global_component_id, x,
319 dof_table, bulk_mesh_dof_table, bulk_node_id_map);
320
321 // per node ordering of components
322 auto const out_index = node_id * n_components + component_id;
323
324 // request for index of linear quantities at higher order nodes
325 // results in returning NumLib::MeshComponentMap::nop
326 if (in_index == NumLib::MeshComponentMap::nop)
327 {
328 output_data[out_index] = 0;
329 continue;
330 }
331
332 output_data[out_index] = x_copy[in_index];
333 }
334 }
335 }
336
337 return names_of_already_output_variables;
338}
static std::vector< double > copySolutionVector(GlobalVector const &x)
static GlobalIndexType getIndexForComponentInSolutionVector(std::size_t const mesh_id, std::size_t const node_id, bool const is_ghost_node, int const global_component_id, GlobalVector const &x, NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::LocalToGlobalIndexMap const &bulk_mesh_dof_table, MeshLib::PropertyVector< std::size_t > const *const bulk_node_id_map)
MeshLib::PropertyVector< std::size_t > const * getBulkNodeIdMapForPetscIfNecessary(MeshLib::Mesh const &mesh, NumLib::LocalToGlobalIndexMap const &dof_table, NumLib::LocalToGlobalIndexMap const &bulk_mesh_dof_table)
static bool isGhostNode(MeshLib::Mesh const &mesh, std::size_t const node_id)
#define OGS_FATAL(...)
Definition Error.h:19
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
static constexpr NUMLIB_EXPORT GlobalIndexType const nop

References copySolutionVector(), DBUG(), getBulkNodeIdMapForPetscIfNecessary(), getIndexForComponentInSolutionVector(), MeshLib::MeshSubset::getMeshID(), NumLib::LocalToGlobalIndexMap::getMeshSubset(), MeshLib::Mesh::getName(), NumLib::LocalToGlobalIndexMap::getNumberOfGlobalComponents(), NumLib::LocalToGlobalIndexMap::getNumberOfVariables(), MeshLib::getOrCreateMeshProperty(), isGhostNode(), MeshLib::Node, NumLib::MeshComponentMap::nop, and OGS_FATAL.

Referenced by ProcessLib::addProcessDataToMesh().

◆ addSecondaryVariableNodes()

void addSecondaryVariableNodes ( NumLib::Time const & t,
std::vector< GlobalVector * > const & x,
std::vector< NumLib::LocalToGlobalIndexMap const * > const & dof_tables,
ProcessLib::SecondaryVariable const & var,
std::string const & output_name,
MeshLib::Mesh & mesh )
static

Definition at line 30 of file AddProcessDataToMesh.cpp.

37{
38 DBUG(" secondary variable {:s}", output_name);
39
40 auto& nodal_values_mesh = *MeshLib::getOrCreateMeshProperty<double>(
41 mesh, output_name, MeshLib::MeshItemType::Node,
42 var.fcts.num_components);
43 if (nodal_values_mesh.size() !=
44 mesh.getNumberOfNodes() * var.fcts.num_components)
45 {
47 "Nodal property `{:s}' does not have the right number of "
48 "components. Expected: {:d}, actual: {:d}",
49 output_name,
50 mesh.getNumberOfNodes() * var.fcts.num_components,
51 nodal_values_mesh.size());
52 }
53
54 std::unique_ptr<GlobalVector> result_cache;
55 auto const& nodal_values =
56 var.fcts.eval_field(t(), x, dof_tables, result_cache);
57
58#ifdef USE_PETSC
59 std::size_t const global_vector_size =
60 nodal_values.getLocalSize() + nodal_values.getGhostSize();
61#else
62 std::size_t const global_vector_size = nodal_values.size();
63#endif
64 if (nodal_values_mesh.size() != global_vector_size)
65 {
67 "Secondary variable `{:s}' did not evaluate to the right number of "
68 "components. Expected: {:d}, actual: {:d}.",
69 var.name, nodal_values_mesh.size(), global_vector_size);
70 }
71
72 // Copy result
73 nodal_values.copyValues(std::span{nodal_values_mesh});
74}
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:91

References DBUG(), ProcessLib::SecondaryVariableFunctions::eval_field, ProcessLib::SecondaryVariable::fcts, MeshLib::Mesh::getNumberOfNodes(), MeshLib::getOrCreateMeshProperty(), ProcessLib::SecondaryVariable::name, MeshLib::Node, ProcessLib::SecondaryVariableFunctions::num_components, and OGS_FATAL.

Referenced by addSecondaryVariablesToMesh().

◆ addSecondaryVariableResiduals()

void addSecondaryVariableResiduals ( NumLib::Time const & t,
std::vector< GlobalVector * > const & x,
std::vector< NumLib::LocalToGlobalIndexMap const * > const & dof_table,
ProcessLib::SecondaryVariable const & var,
std::string const & output_name,
MeshLib::Mesh & mesh )
static

Definition at line 76 of file AddProcessDataToMesh.cpp.

83{
84 if (!var.fcts.eval_residuals)
85 {
86 return;
87 }
88
89 DBUG(" secondary variable {:s} residual", output_name);
90 auto const& property_name_res = output_name + "_residual";
91
92 auto& residuals_mesh = *MeshLib::getOrCreateMeshProperty<double>(
93 mesh, property_name_res, MeshLib::MeshItemType::Cell,
94 var.fcts.num_components);
95 if (residuals_mesh.size() !=
96 mesh.getNumberOfElements() * var.fcts.num_components)
97 {
99 "Cell property `{:s}' does not have the right number of "
100 "components. Expected: {:d}, actual: {:d}",
101 property_name_res,
102 mesh.getNumberOfElements() * var.fcts.num_components,
103 residuals_mesh.size());
104 }
105
106 std::unique_ptr<GlobalVector> result_cache;
107 auto const& residuals =
108 var.fcts.eval_residuals(t(), x, dof_table, result_cache);
109#ifdef USE_PETSC
110 std::size_t const global_vector_size =
111 residuals.getLocalSize() + residuals.getGhostSize();
112#else
113 std::size_t const global_vector_size = residuals.size();
114#endif
115 if (residuals_mesh.size() != global_vector_size)
116 {
117 OGS_FATAL(
118 "The residual of secondary variable `{:s}' did not evaluate to the "
119 "right number of components. Expected: {:d}, actual: {:d}.",
120 var.name, residuals_mesh.size(), global_vector_size);
121 }
122
123 // Copy result
124 residuals.copyValues(std::span{residuals_mesh});
125}
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:88

References MeshLib::Cell, DBUG(), ProcessLib::SecondaryVariableFunctions::eval_residuals, ProcessLib::SecondaryVariable::fcts, MeshLib::Mesh::getNumberOfElements(), MeshLib::getOrCreateMeshProperty(), ProcessLib::SecondaryVariable::name, ProcessLib::SecondaryVariableFunctions::num_components, and OGS_FATAL.

Referenced by addSecondaryVariablesToMesh().

◆ addSecondaryVariablesToMesh()

void addSecondaryVariablesToMesh ( ProcessLib::SecondaryVariableCollection const & secondary_variables,
std::set< std::string > & names_of_already_output_variables,
NumLib::Time const & t,
std::vector< GlobalVector * > const & xs,
MeshLib::Mesh & mesh,
std::vector< NumLib::LocalToGlobalIndexMap const * > const & dof_tables,
bool const output_residuals )
static

Definition at line 340 of file AddProcessDataToMesh.cpp.

347{
348 for (auto const& external_variable_name : secondary_variables)
349 {
350 auto const& name = external_variable_name.first;
351 if (!names_of_already_output_variables.insert(name).second)
352 {
353 // no insertion took place, output already done
354 continue;
355 }
356
357 addSecondaryVariableNodes(t, xs, dof_tables,
358 secondary_variables.get(name), name, mesh);
359
360 if (output_residuals)
361 {
363 t, xs, dof_tables, secondary_variables.get(name), name, mesh);
364 }
365 }
366}
static void addSecondaryVariableNodes(NumLib::Time const &t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_tables, ProcessLib::SecondaryVariable const &var, std::string const &output_name, MeshLib::Mesh &mesh)
static void addSecondaryVariableResiduals(NumLib::Time const &t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, ProcessLib::SecondaryVariable const &var, std::string const &output_name, MeshLib::Mesh &mesh)

References addSecondaryVariableNodes(), addSecondaryVariableResiduals(), and ProcessLib::SecondaryVariableCollection::get().

Referenced by ProcessLib::addProcessDataToMesh().

◆ copySolutionVector()

std::vector< double > copySolutionVector ( GlobalVector const & x)
static

Definition at line 127 of file AddProcessDataToMesh.cpp.

128{
129 std::vector<double> x_copy;
130 x.copyValues(x_copy);
131 return x_copy;
132}

References MathLib::EigenVector::copyValues().

Referenced by addPrimaryVariablesToMesh().

◆ getBulkNodeIdMapForPetscIfNecessary()

MeshLib::PropertyVector< std::size_t > const * getBulkNodeIdMapForPetscIfNecessary ( MeshLib::Mesh const & mesh,
NumLib::LocalToGlobalIndexMap const & dof_table,
NumLib::LocalToGlobalIndexMap const & bulk_mesh_dof_table )

Definition at line 134 of file AddProcessDataToMesh.cpp.

138{
139#ifdef USE_PETSC
140
141 if (&bulk_mesh_dof_table != &dof_table)
142 {
143 auto const bulk_id_string =
145 if (!mesh.getProperties().existsPropertyVector<std::size_t>(
146 bulk_id_string))
147 {
148 OGS_FATAL(
149 "The required bulk node ids map does not exist in "
150 "the boundary mesh '{:s}' or has the wrong data "
151 "type (should be equivalent to C++ data type "
152 "std::size_t which is an unsigned integer of size "
153 "{:d} or UInt64 in vtk terminology).",
154 mesh.getName(), sizeof(std::size_t));
155 }
156 return mesh.getProperties().getPropertyVector<std::size_t>(
157 bulk_id_string);
158 }
159#endif
160
161 return nullptr;
162}
constexpr std::string_view getBulkIDString(MeshItemType mesh_item_type)

References MeshLib::getBulkIDString(), MeshLib::Node, and OGS_FATAL.

Referenced by addPrimaryVariablesToMesh().

◆ getIndexForComponentInSolutionVector()

GlobalIndexType getIndexForComponentInSolutionVector ( std::size_t const mesh_id,
std::size_t const node_id,
bool const is_ghost_node,
int const global_component_id,
GlobalVector const & x,
NumLib::LocalToGlobalIndexMap const & dof_table,
NumLib::LocalToGlobalIndexMap const & bulk_mesh_dof_table,
MeshLib::PropertyVector< std::size_t > const *const bulk_node_id_map )
static

Definition at line 164 of file AddProcessDataToMesh.cpp.

171{
172#ifdef USE_PETSC
173 if (is_ghost_node && &bulk_mesh_dof_table != &dof_table)
174 {
175 auto const bulk_node_id = (*bulk_node_id_map)[node_id];
176 std::size_t const bulk_mesh_id = 0;
177
178 MeshLib::Location const loc(bulk_mesh_id, MeshLib::MeshItemType::Node,
179 bulk_node_id);
180
181 // early return!
182 return bulk_mesh_dof_table.getLocalIndex(
183 loc, global_component_id, x.getRangeBegin(), x.getRangeEnd());
184 }
185#endif
186
187 MeshLib::Location const loc(mesh_id, MeshLib::MeshItemType::Node, node_id);
188
189 return dof_table.getLocalIndex(loc, global_component_id, x.getRangeBegin(),
190 x.getRangeEnd());
191}

References NumLib::LocalToGlobalIndexMap::getLocalIndex(), MathLib::EigenVector::getRangeBegin(), MathLib::EigenVector::getRangeEnd(), and MeshLib::Node.

Referenced by addPrimaryVariablesToMesh().

◆ isGhostNode()

bool isGhostNode ( MeshLib::Mesh const & mesh,
std::size_t const node_id )
static

Definition at line 193 of file AddProcessDataToMesh.cpp.

195{
196#ifndef USE_PETSC
197 return false;
198#else
199 return static_cast<MeshLib::NodePartitionedMesh const&>(mesh).isGhostNode(
200 node_id);
201#endif
202}

References isGhostNode().

Referenced by addPrimaryVariablesToMesh(), and isGhostNode().