preCICE v3.2.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 _meshIdManager(new utils::ManageUniqueIDs())
32{
33 using namespace xml;
34 std::string doc;
35 XMLTag tag(*this, TAG, xml::XMLTag::OCCUR_ONCE_OR_MORE);
36 doc = "Surface mesh consisting of vertices and optional connectivity information. "
37 "The vertices of a mesh can carry data, "
38 "configured by tags <use-data>. The mesh coordinates have to be "
39 "defined by a participant (see tag <provide-mesh>).";
40 tag.setDocumentation(doc);
41
42 auto attrName = XMLAttribute<std::string>(ATTR_NAME)
43 .setDocumentation("Unique name for the mesh.");
44 tag.addAttribute(attrName);
45
46 auto attrDimensions = XMLAttribute<int>(ATTR_DIMENSIONS)
47 .setDocumentation("Spatial dimensions of mesh")
48 .setOptions({2, 3});
49 tag.addAttribute(attrDimensions);
50
51 XMLTag subtagData(*this, TAG_DATA, XMLTag::OCCUR_ARBITRARY);
52 doc = "Assigns a before defined data set (see tag <data>) to the mesh.";
53 subtagData.setDocumentation(doc);
54 attrName.setDocumentation("Name of the data set.");
55 subtagData.addAttribute(attrName);
56 tag.addSubtag(subtagData);
57
58 parent.addSubtag(tag);
59}
60
62 const xml::ConfigurationContext &context,
63 xml::XMLTag &tag)
64{
66 if (tag.getName() == TAG) {
68 int dimensions = tag.getIntAttributeValue(ATTR_DIMENSIONS);
69 insertMeshToMeshDimensionsMap(name, dimensions);
70 PRECICE_ASSERT(dimensions != 0);
72 _meshes.push_back(std::make_shared<Mesh>(name, dimensions, _meshIdManager->getFreeID()));
73 } else if (tag.getName() == TAG_DATA) {
75 bool found = false;
76 for (const DataConfiguration::ConfiguredData &data : _dataConfig->data()) {
77 auto dataDimensions = getDataDimensions(_meshes.back()->getName(), data.typeName);
78 if (data.name == name) {
79 _meshes.back()->createData(data.name, dataDimensions, _dataIDManager.getFreeID(), data.waveformDegree);
80 found = true;
81 break;
82 }
83 }
84 PRECICE_CHECK(found,
85 "Data with name \"{}\" used by mesh \"{}\" is not defined. "
86 "Please define a data tag with name=\"{}\".",
87 name, _meshes.back()->getName(), name);
88 }
89}
90
96
101
103{
104 return std::make_shared<mesh::Mesh>("(just-in-time mapping)", dimension, mesh::Mesh::MESH_ID_UNDEFINED, true);
105}
106
108 const mesh::PtrMesh &mesh)
109{
110 for (const PtrData &dataNewMesh : mesh->data()) {
111 bool found = false;
112 for (const DataConfiguration::ConfiguredData &data : _dataConfig->data()) {
113 if (dataNewMesh->getName() == data.name && dataNewMesh->getDimensions() == getDataDimensions(mesh->getName(), data.typeName)) {
114 found = true;
115 break;
116 }
117 }
118 PRECICE_CHECK(found, "Data {0} is not defined. Please define a data tag with name=\"{0}\".", dataNewMesh->getName());
119 }
120 _meshes.push_back(mesh);
121}
122
124{
125 return _meshes;
126}
127
132
134{
135 auto iter = std::find_if(_meshes.begin(), _meshes.end(), [&meshName](const auto &mptr) {
136 return mptr->getName() == meshName;
137 });
138 return iter != _meshes.end(); // if name was not found in _meshes, iter == _meshes.end()
139}
140
142 const std::string &meshName) const
143{
144 for (const mesh::PtrMesh &mesh : _meshes) {
145 if (mesh->getName() == meshName) {
146 return mesh;
147 }
148 }
149 return mesh::PtrMesh();
150}
151
153 const std::string &participant,
154 const std::string &mesh)
155{
156 PRECICE_TRACE(participant, mesh);
157 if (_neededMeshes.count(participant) == 0) {
159 meshes.push_back(mesh);
161 } else if (not utils::contained(mesh, _neededMeshes.find(participant)->second)) {
162 _neededMeshes.find(participant)->second.push_back(mesh);
163 }
164}
165
167 const std::string &mesh,
168 int dimensions)
169{
170 PRECICE_ASSERT(_meshDimensionsMap.count(mesh) == 0, "Mesh {} already exists in the mesh-dimensions map.", mesh);
172}
173
174int MeshConfiguration::getDataDimensions(const std::string &meshName, const Data::typeName dataTypeName) const
175{
176 if (dataTypeName == Data::typeName::VECTOR) {
177 PRECICE_ASSERT(_meshDimensionsMap.count(meshName) > 0, "Mesh {} does not exist in the mesh-dimensions map.", meshName);
178 return _meshDimensionsMap.at(meshName);
179 } else if (dataTypeName == Data::typeName::SCALAR) {
180 return 1;
181 }
182 // We should never reach this point
183 PRECICE_UNREACHABLE("Unknown data type defined on mesh \"{}\".", meshName);
184};
185
186} // 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)
void addMesh(const mesh::PtrMesh &mesh)
mesh::PtrMesh getMesh(const std::string &meshName) const
Returns the configured mesh with given name, or NULL.
std::unique_ptr< utils::ManageUniqueIDs > _meshIdManager
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
contains precice-related utilities.
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