preCICE v3.3.0
Loading...
Searching...
No Matches
Configuration.cpp
Go to the documentation of this file.
1#include "Configuration.hpp"
2#include <map>
3#include <memory>
4#include <ostream>
5#include <vector>
10#include "math/differences.hpp"
11#include "mesh/Mesh.hpp"
20#include "utils/assertion.hpp"
21#include "xml/ConfigParser.hpp"
22#include "xml/XMLAttribute.hpp"
23
24namespace precice::config {
25
27 : _tag(*this, "precice-configuration", xml::XMLTag::OCCUR_ONCE),
28 _logConfig(_tag), // This must be the first configuration to be constructed
30{
31 _tag.setDocumentation("Main tag containing preCICE configuration.");
32 _tag.addNamespace("data");
33 _tag.addNamespace("communication");
34 _tag.addNamespace("mapping");
35 _tag.addNamespace("export");
36 _tag.addNamespace("action");
37 _tag.addNamespace("coupling-scheme");
38 _tag.addNamespace("acceleration");
39
40 auto attrExperimental = xml::makeXMLAttribute("experimental", false)
41 .setDocumentation("Enable experimental features.");
42 _tag.addAttribute(attrExperimental);
43
44 auto attrRemeshing = xml::makeXMLAttribute("allow-remeshing", false)
45 .setDocumentation("Enable experimental remeshing feature, requires experimental to be true.");
46 _tag.addAttribute(attrRemeshing);
47
48 auto attrWaitInFinalize = xml::makeXMLAttribute("wait-in-finalize", false)
49 .setDocumentation("Connected participants wait for each other in finalize, which can be helpful in SLURM sessions.");
50 _tag.addAttribute(attrWaitInFinalize);
52 _tag);
56 _tag);
61}
62
67
69{
71 if (tag.getName() == "precice-configuration") {
72 _experimental = tag.getBooleanAttributeValue("experimental");
73 _remeshing = tag.getBooleanAttributeValue("allow-remeshing");
74
75 PRECICE_CHECK(!_remeshing || _experimental, "Remeshing is considered an experimental feature. Please enable <precice-configuration experimental=\"1\" >.");
79 _waitInFinalize = tag.getBooleanAttributeValue("wait-in-finalize");
80 } else {
81 PRECICE_UNREACHABLE("Received callback from unknown tag '{}'.", tag.getName());
82 }
83}
84
86 const xml::ConfigurationContext &context,
87 xml::XMLTag &tag)
88{
90 PRECICE_ASSERT(tag.getName() == "precice-configuration");
91
92 // test if both participants do have the exchange meshes
93 typedef std::map<std::string, std::vector<std::string>>::value_type neededMeshPair;
94 for (const neededMeshPair &neededMeshes : _meshConfiguration->getNeededMeshes()) {
95 bool participantFound = false;
96 for (const impl::PtrParticipant &participant : _participantConfiguration->getParticipants()) {
97 if (participant->getName() == neededMeshes.first) {
98 for (const std::string &neededMesh : neededMeshes.second) {
99 PRECICE_CHECK(participant->isMeshUsed(neededMesh),
100 "Participant \"{}\" needs to use the mesh \"{}\" to be able to use it in the coupling scheme. "
101 "Please either add a provide-mesh or a receive-mesh tag in this participant's configuration, or use a different mesh in the coupling scheme.",
102 neededMeshes.first, neededMesh);
103 }
104 participantFound = true;
105 break;
106 }
107 }
108 PRECICE_ASSERT(participantFound);
109 }
110
111 // test if all M2Ns use participants that exist
112 for (const auto &m2n : _m2nConfiguration->m2ns()) {
113 PRECICE_CHECK(_participantConfiguration->hasParticipant(m2n.acceptor),
114 "The acceptor in <m2n:... acceptor=\"{}\" connector=\"{}\" /> is an unknown. {}",
115 m2n.acceptor, m2n.connector, _participantConfiguration->hintFor(m2n.acceptor));
116
117 PRECICE_CHECK(_participantConfiguration->hasParticipant(m2n.connector),
118 "The connector in <m2n:... acceptor=\"{}\" connector=\"{}\" /> is an unknown. {}",
119 m2n.acceptor, m2n.connector, _participantConfiguration->hintFor(m2n.connector));
120 }
121}
122
128
130{
132
133 for (const auto &m2nConf : _m2nConfiguration->m2ns()) {
134 if (m2nConf.acceptor != participantName && m2nConf.connector != participantName) {
135 continue;
136 }
137
138 std::string comPartner("");
139 bool isRequesting;
140 if (m2nConf.acceptor == participantName) {
141 comPartner = m2nConf.connector;
142 isRequesting = true;
143 } else {
144 comPartner = m2nConf.acceptor;
145 isRequesting = false;
146 }
147
148 PRECICE_ASSERT(!comPartner.empty());
149 for (const impl::PtrParticipant &participant : _participantConfiguration->getParticipants()) {
150 if (participant->getName() == comPartner) {
151 PRECICE_ASSERT(not utils::contained(comPartner, result), comPartner);
152 PRECICE_ASSERT(m2nConf.m2n);
153
154 result[comPartner] = [&] {
155 m2n::BoundM2N bound;
156 bound.m2n = m2nConf.m2n;
157 bound.localName = participantName;
158 bound.remoteName = comPartner;
159 bound.isRequesting = isRequesting;
160 return bound;
161 }();
162 }
163 }
164 }
165 return result;
166}
167
169{
171 PRECICE_ASSERT(_participantConfiguration->hasParticipant(participantName));
172
173 auto participant = _participantConfiguration->getParticipant(participantName);
174 for (precice::impl::MeshContext *context : participant->usedMeshContexts()) {
175
176 if (context->provideMesh) { // Accessor provides mesh
177 PRECICE_CHECK(context->receiveMeshFrom.empty(),
178 "Participant \"{}\" cannot provide and receive mesh {}!",
179 participantName, context->mesh->getName());
180
181 context->partition = partition::PtrPartition(new precice::partition::ProvidedPartition(context->mesh));
182
183 for (auto &receiver : _participantConfiguration->getParticipants()) {
184 for (auto &receiverContext : receiver->usedMeshContexts()) {
185 if (receiverContext->receiveMeshFrom == participantName && receiverContext->mesh->getName() == context->mesh->getName()) {
186 // meshRequirement has to be copied from "from" to provide", since
187 // mapping are only defined at "provide"
188 if (receiverContext->meshRequirement > context->meshRequirement) {
189 context->meshRequirement = receiverContext->meshRequirement;
190 }
191
192 m2n::PtrM2N m2n = _m2nConfiguration->getM2N(receiver->getName(), std::string(participantName));
193 m2n->createDistributedCommunication(context->mesh);
194 context->partition->addM2N(m2n);
195 }
196 }
197 }
198
199 } else { // Accessor receives mesh
200 std::string receiver(participantName);
201 std::string provider(context->receiveMeshFrom);
202
203 PRECICE_DEBUG("Receiving mesh from {}", provider);
204
205 context->partition = partition::PtrPartition(new precice::partition::ReceivedPartition(context->mesh, context->geoFilter, context->safetyFactor, context->allowDirectAccess));
206
207 m2n::PtrM2N m2n = _m2nConfiguration->getM2N(receiver, provider);
208 m2n->createDistributedCommunication(context->mesh);
209 context->partition->addM2N(m2n);
210 for (const precice::impl::MappingContext &mappingContext : context->fromMappingContexts) {
211 context->partition->addFromMapping(mappingContext.mapping);
212 }
213 for (const precice::impl::MappingContext &mappingContext : context->toMappingContexts) {
214 context->partition->addToMapping(mappingContext.mapping);
215 }
216 }
217 }
218}
219
220} // namespace precice::config
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:61
#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
const PtrParticipantConfiguration & getParticipantConfiguration() const
void xmlTagCallback(const xml::ConfigurationContext &context, xml::XMLTag &tag) override
Callback function required for use of automatic configuration.
mesh::PtrMeshConfiguration _meshConfiguration
logging::LogConfiguration _logConfig
bool _remeshing
Allow the use of experimental remeshing features.
std::map< std::string, m2n::BoundM2N > getBoundM2NsFor(std::string_view participant) const
precice::profiling::ProfilingConfiguration _profilingConfig
void configurePartitionsFor(std::string_view participantName)
bool _experimental
Allow the use of experimental features.
m2n::M2NConfiguration::SharedPointer _m2nConfiguration
PtrParticipantConfiguration _participantConfiguration
void xmlEndTagCallback(const xml::ConfigurationContext &context, xml::XMLTag &tag) override
Callback function required for use of automatic configuration.
xml::XMLTag & getXMLTag()
Returns root xml tag to start the automatic configuration process.
bool _waitInFinalize
Synchronize participants in finalize.
cplscheme::PtrCouplingSchemeConfiguration _couplingSchemeConfiguration
mesh::PtrDataConfiguration _dataConfiguration
An M2N between participants with a configured direction.
Definition BoundM2N.hpp:12
std::string remoteName
Definition BoundM2N.hpp:31
std::string localName
Definition BoundM2N.hpp:30
A partition that is provided by the participant.
A partition that is computed from a mesh received from another participant.
Represents an XML tag to be configured automatically.
Definition XMLTag.hpp:28
bool getBooleanAttributeValue(const std::string &name, std::optional< bool > default_value=std::nullopt) const
Definition XMLTag.cpp:159
const std::string & getName() const
Returns name (without namespace).
Definition XMLTag.hpp:153
T empty(T... args)
T make_shared(T... args)
std::shared_ptr< ParticipantConfiguration > PtrParticipantConfiguration
std::shared_ptr< ParticipantState > PtrParticipant
contains the logic of the parallel communication between participants.
Definition BoundM2N.cpp:12
std::shared_ptr< M2N > PtrM2N
std::shared_ptr< Partition > PtrPartition
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.
XMLAttribute< std::string > makeXMLAttribute(std::string name, const char *defaultValue)
Holds a data mapping and related information.
mapping::PtrMapping mapping
Data mapping.
Stores a mesh and related objects and data.
Tightly coupled to the parameters of Participant()
Definition XMLTag.hpp:21