preCICE v3.3.0
Loading...
Searching...
No Matches
MeshConfiguration.cpp
Go to the documentation of this file.
2#include <memory>
3
4#include <sstream>
5#include <stdexcept>
6#include <utility>
7
9#include "mesh/Data.hpp"
10#include "mesh/Mesh.hpp"
12#include "utils/Helpers.hpp"
13#include "utils/assertion.hpp"
14#include "xml/ConfigParser.hpp"
15#include "xml/XMLAttribute.hpp"
16
17namespace precice::mesh {
18
20 xml::XMLTag &parent,
22 : TAG("mesh"),
23 ATTR_NAME("name"),
24 ATTR_DIMENSIONS("dimensions"),
25 TAG_DATA("use-data"),
26 ATTR_SIDE_INDEX("side"),
28 _dataConfig(std::move(config)),
29 _meshes(),
31{
32 using namespace xml;
33 std::string doc;
34 XMLTag tag(*this, TAG, xml::XMLTag::OCCUR_ONCE_OR_MORE);
35 doc = "Surface mesh consisting of vertices and optional connectivity information. "
36 "The vertices of a mesh can carry data, "
37 "configured by tags <use-data>. The mesh coordinates have to be "
38 "defined by a participant (see tag <provide-mesh>).";
39 tag.setDocumentation(doc);
40
41 auto attrName = XMLAttribute<std::string>(ATTR_NAME)
42 .setDocumentation("Unique name for the mesh.");
43 tag.addAttribute(attrName);
44
45 auto attrDimensions = XMLAttribute<int>(ATTR_DIMENSIONS)
46 .setDocumentation("Spatial dimensions of mesh")
47 .setOptions({2, 3});
48 tag.addAttribute(attrDimensions);
49
50 XMLTag subtagData(*this, TAG_DATA, XMLTag::OCCUR_ARBITRARY);
51 doc = "Assigns a before defined data set (see tag <data>) to the mesh.";
52 subtagData.setDocumentation(doc);
53 attrName.setDocumentation("Name of the data set.");
54 subtagData.addAttribute(attrName);
55 tag.addSubtag(subtagData);
56
57 parent.addSubtag(tag);
58}
59
61 const xml::ConfigurationContext &context,
62 xml::XMLTag &tag)
63{
65 if (tag.getName() == TAG) {
67 int dimensions = tag.getIntAttributeValue(ATTR_DIMENSIONS);
68 insertMeshToMeshDimensionsMap(name, dimensions);
69 PRECICE_ASSERT(dimensions != 0);
70 _meshes.push_back(std::make_shared<Mesh>(name, dimensions, _meshIdManager.getFreeID()));
71 } else if (tag.getName() == TAG_DATA) {
73 bool found = false;
74 for (const DataConfiguration::ConfiguredData &data : _dataConfig->data()) {
75 auto dataDimensions = getDataDimensions(_meshes.back()->getName(), data.typeName);
76 if (data.name == name) {
77 _meshes.back()->createData(data.name, dataDimensions, _dataIDManager.getFreeID(), data.waveformDegree);
78 found = true;
79 break;
80 }
81 }
82 PRECICE_CHECK(found,
83 "Data with name \"{}\" used by mesh \"{}\" is not defined. "
84 "Please define a data tag with name=\"{}\".",
85 name, _meshes.back()->getName(), name);
86 }
87}
88
94
99
101{
102 return std::make_shared<mesh::Mesh>("(just-in-time mapping)", dimension, mesh::Mesh::MESH_ID_UNDEFINED, true);
103}
104
106 const mesh::PtrMesh &mesh)
107{
108 for (const PtrData &dataNewMesh : mesh->data()) {
109 bool found = false;
110 for (const DataConfiguration::ConfiguredData &data : _dataConfig->data()) {
111 if (dataNewMesh->getName() == data.name && dataNewMesh->getDimensions() == getDataDimensions(mesh->getName(), data.typeName)) {
112 found = true;
113 break;
114 }
115 }
116 PRECICE_CHECK(found, "Data {0} is not defined. Please define a data tag with name=\"{0}\".", dataNewMesh->getName());
117 }
118 _meshes.push_back(mesh);
119}
120
122{
123 return _meshes;
124}
125
130
132{
133 auto iter = std::find_if(_meshes.begin(), _meshes.end(), [&meshName](const auto &mptr) {
134 return mptr->getName() == meshName;
135 });
136 return iter != _meshes.end(); // if name was not found in _meshes, iter == _meshes.end()
137}
138
140 const std::string &meshName) const
141{
142 for (const mesh::PtrMesh &mesh : _meshes) {
143 if (mesh->getName() == meshName) {
144 return mesh;
145 }
146 }
147 return mesh::PtrMesh();
148}
149
151 const std::string &participant,
152 const std::string &mesh)
153{
154 PRECICE_TRACE(participant, mesh);
155 if (_neededMeshes.count(participant) == 0) {
157 meshes.push_back(mesh);
159 } else if (not utils::contained(mesh, _neededMeshes.find(participant)->second)) {
160 _neededMeshes.find(participant)->second.push_back(mesh);
161 }
162}
163
165 const std::string &mesh,
166 int dimensions)
167{
168 PRECICE_ASSERT(_meshDimensionsMap.count(mesh) == 0, "Mesh {} already exists in the mesh-dimensions map.", mesh);
170}
171
172int MeshConfiguration::getDataDimensions(const std::string &meshName, const Data::typeName dataTypeName) const
173{
174 if (dataTypeName == Data::typeName::VECTOR) {
175 PRECICE_ASSERT(_meshDimensionsMap.count(meshName) > 0, "Mesh {} does not exist in the mesh-dimensions map.", meshName);
176 return _meshDimensionsMap.at(meshName);
177 } else if (dataTypeName == Data::typeName::SCALAR) {
178 return 1;
179 }
180 // We should never reach this point
181 PRECICE_UNREACHABLE("Unknown data type defined on mesh \"{}\".", meshName);
182};
183
184} // namespace precice::mesh
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:92
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:32
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
#define PRECICE_UNREACHABLE(...)
Definition assertion.hpp:93
std::map< std::string, std::vector< std::string > > _neededMeshes
to check later if all meshes that any coupling scheme needs are actually used by the participants
std::vector< PtrMesh > _meshes
Configured meshes.
void xmlTagCallback(const xml::ConfigurationContext &context, xml::XMLTag &callingTag) override
Callback at begin of XML tag.
void addNeededMesh(const std::string &participant, const std::string &mesh)
utils::ManageUniqueIDs _meshIdManager
void addMesh(const mesh::PtrMesh &mesh)
mesh::PtrMesh getMesh(const std::string &meshName) const
Returns the configured mesh with given name, or NULL.
MeshConfiguration(xml::XMLTag &parent, PtrDataConfiguration config)
Constructor, takes a valid data configuration as argument.
const PtrDataConfiguration & getDataConfiguration() const
utils::ManageUniqueIDs _dataIDManager
void xmlEndTagCallback(const xml::ConfigurationContext &context, xml::XMLTag &callingTag) override
Callback at end of XML tag and at end of subtag.
bool hasMeshName(const std::string &meshName) const
Returns whether Mesh has Data with the dataName.
std::map< std::string, int > _meshDimensionsMap
static mesh::PtrMesh getJustInTimeMappingMesh(int dimension)
int getDataDimensions(const std::string &meshName, const Data::typeName typeName) const
Get the number of dimensions that data values of this type (scalar/vector) have on this mesh.
PtrDataConfiguration _dataConfig
Data configuration.
void insertMeshToMeshDimensionsMap(const std::string &mesh, int dimensions)
Initialize the map between meshes and dimensions, for unit tests that directly create mesh objects wi...
const std::vector< PtrMesh > & meshes() const
Returns all configured meshes.
static constexpr MeshID MESH_ID_UNDEFINED
Use if the id of the mesh is not necessary.
Definition Mesh.hpp:57
Represents an XML tag to be configured automatically.
Definition XMLTag.hpp:28
std::string getStringAttributeValue(const std::string &name, std::optional< std::string > default_value=std::nullopt) const
Definition XMLTag.cpp:145
const std::string & getName() const
Returns name (without namespace).
Definition XMLTag.hpp:153
int getIntAttributeValue(const std::string &name, std::optional< int > default_value=std::nullopt) const
Definition XMLTag.cpp:131
XMLTag & addSubtag(const XMLTag &tag)
Adds an XML tag as subtag by making a copy of the given tag.
Definition XMLTag.cpp:41
T find_if(T... args)
T make_shared(T... args)
provides Mesh, Data and primitives.
std::shared_ptr< Data > PtrData
std::shared_ptr< DataConfiguration > PtrDataConfiguration
std::shared_ptr< Mesh > PtrMesh
bool contained(const ELEMENT_T &element, const std::vector< ELEMENT_T > &vec)
Returns true, if given element is in vector, otherwise false.
Definition Helpers.hpp:38
contains the XML configuration parser.
STL namespace.
Tightly coupled to the parameters of Participant()
Definition XMLTag.hpp:21