preCICE v3.1.2
Loading...
Searching...
No Matches
ParticipantState.cpp
Go to the documentation of this file.
2#include <algorithm>
3#include <ostream>
4#include <sstream>
5#include <string>
6#include <string_view>
7#include <utility>
8
9#include "MappingContext.hpp"
10#include "MeshContext.hpp"
11#include "WatchIntegral.hpp"
12#include "WatchPoint.hpp"
13#include "action/Action.hpp"
14#include "io/Export.hpp"
15#include "logging/LogMacros.hpp"
16#include "mesh/Data.hpp"
17#include "mesh/Mesh.hpp"
23#include "utils/String.hpp"
24#include "utils/assertion.hpp"
25#include "utils/fmt.hpp"
26
27namespace precice::impl {
28
35
37{
38 for (MeshContext *context : _usedMeshContexts) {
39 delete context;
40 }
41 _usedMeshContexts.clear();
42}
43
45
47{
48 auto &context = meshContext(action->getMesh()->getName());
49 context.require(action->getMeshRequirement());
50 _actions.push_back(std::move(action));
51}
52
57
59 const PtrWatchPoint &watchPoint)
60{
61 _watchPoints.push_back(watchPoint);
62}
63
65 const PtrWatchIntegral &watchIntegral)
66{
67 _watchIntegrals.push_back(watchIntegral);
68}
69
71{
72 std::string meshName = mesh->getName();
73 PRECICE_TRACE(_name, meshName);
74 checkDuplicatedUse(meshName);
75
76 auto context = new MeshContext();
77 context->mesh = mesh;
78 context->provideMesh = true;
79 _meshContexts[std::move(meshName)] = context;
80 _usedMeshContexts.push_back(context);
81}
82
84 const std::string & fromParticipant,
85 double safetyFactor,
87 const bool allowDirectAccess)
88{
89 std::string meshName = mesh->getName();
90 PRECICE_TRACE(_name, meshName);
91 checkDuplicatedUse(meshName);
92 PRECICE_ASSERT(!fromParticipant.empty());
93 PRECICE_ASSERT(safetyFactor >= 0);
94 auto context = new MeshContext();
95 context->mesh = mesh;
96 context->receiveMeshFrom = fromParticipant;
97 context->safetyFactor = safetyFactor;
98 context->provideMesh = false;
99 context->geoFilter = geoFilter;
100 context->allowDirectAccess = allowDirectAccess;
101
102 _meshContexts[std::move(meshName)] = context;
103
105}
106
108 const mesh::PtrData &data,
109 const mesh::PtrMesh &mesh)
110{
111 checkDuplicatedData(mesh->getName(), data->getName());
112 _writeDataContexts.emplace(MeshDataKey{mesh->getName(), data->getName()}, WriteDataContext(data, mesh));
113}
114
116 const mesh::PtrData &data,
117 const mesh::PtrMesh &mesh)
118{
119 checkDuplicatedData(mesh->getName(), data->getName());
120 _readDataContexts.emplace(MeshDataKey{mesh->getName(), data->getName()}, ReadDataContext(data, mesh));
121}
122
124 const MappingContext &mappingContext)
125{
126 _readMappingContexts.push_back(mappingContext);
127}
128
130 const MappingContext &mappingContext)
131{
132 _writeMappingContexts.push_back(mappingContext);
133}
134
135// Data queries
137{
138 auto it = _readDataContexts.find(MeshDataKey{mesh, data});
139 PRECICE_CHECK(it != _readDataContexts.end(), "Data \"{}\" does not exist for mesh \"{}\".", data, mesh);
140 return it->second;
141}
142
144{
145 auto it = _readDataContexts.find(MeshDataKey{mesh, data});
146 PRECICE_CHECK(it != _readDataContexts.end(), "Data \"{}\" does not exist for mesh \"{}\".", data, mesh);
147 return it->second;
148}
149
151{
152 for (const auto &meshContext : _meshContexts) {
153 const auto & mesh = meshContext.second->mesh->getName();
154 MeshDataKey<std::string> key{mesh, std::string{data}};
155 const auto it = _readDataContexts.find(key);
156 if (it != _readDataContexts.end()) {
157 return meshContext.second->mesh;
158 }
159 }
160 return nullptr;
161}
162
164{
165 auto it = _writeDataContexts.find(MeshDataKey{mesh, data});
166 PRECICE_CHECK(it != _writeDataContexts.end(), "Data \"{}\" does not exist in write direction.", data);
167 return it->second;
168}
169
171{
172 auto it = _writeDataContexts.find(MeshDataKey{mesh, data});
173 PRECICE_CHECK(it != _writeDataContexts.end(), "Data \"{}\" does not exist in write direction.", data);
174 return it->second;
175}
176
178{
179 return std::any_of(
180 _meshContexts.begin(), _meshContexts.end(),
181 [data](const auto &mckv) {
182 const auto &meshData = mckv.second->mesh->data();
183 return std::any_of(meshData.begin(), meshData.end(), [data](const auto &dptr) {
184 return dptr->getName() == data;
185 });
186 });
187}
188
189bool ParticipantState::isDataUsed(std::string_view mesh, std::string_view data) const
190{
191 const auto &meshData = meshContext(mesh).mesh->data();
192 const auto match = std::find_if(meshData.begin(), meshData.end(), [data](auto &dptr) { return dptr->getName() == data; });
193 return match != meshData.end();
194}
195
196bool ParticipantState::isDataRead(std::string_view mesh, std::string_view data) const
197{
198 return _readDataContexts.count(MeshDataKey{mesh, data}) > 0;
199}
200
201bool ParticipantState::isDataWrite(std::string_view mesh, std::string_view data) const
202{
203 return _writeDataContexts.count(MeshDataKey{mesh, data}) > 0;
204}
205
207
208const MeshContext &ParticipantState::meshContext(std::string_view mesh) const
209{
210 auto pos = _meshContexts.find(mesh);
211 PRECICE_ASSERT(pos != _meshContexts.end());
212 return *pos->second;
213}
214
215MeshContext &ParticipantState::meshContext(std::string_view mesh)
216{
217 auto pos = _meshContexts.find(mesh);
218 PRECICE_ASSERT(pos != _meshContexts.end());
219 return *pos->second;
220}
221
222const std::vector<MeshContext *> &ParticipantState::usedMeshContexts() const
223{
224 return _usedMeshContexts;
225}
226
227std::vector<MeshContext *> &ParticipantState::usedMeshContexts()
228{
229 return _usedMeshContexts;
230}
231
232MeshContext &ParticipantState::usedMeshContext(std::string_view mesh)
233{
234 auto pos = std::find_if(_usedMeshContexts.begin(), _usedMeshContexts.end(),
235 [mesh](MeshContext const *context) {
236 return context->mesh->getName() == mesh;
237 });
238 PRECICE_ASSERT(pos != _usedMeshContexts.end());
239 return **pos;
240}
241
242MeshContext const &ParticipantState::usedMeshContext(std::string_view mesh) const
243{
244 auto pos = std::find_if(_usedMeshContexts.begin(), _usedMeshContexts.end(),
245 [mesh](MeshContext const *context) {
246 return context->mesh->getName() == mesh;
247 });
248 PRECICE_ASSERT(pos != _usedMeshContexts.end());
249 return **pos;
250}
251
252bool ParticipantState::hasMesh(std::string_view mesh) const
253{
254 return _meshContexts.count(mesh) > 0;
255}
256
257bool ParticipantState::isMeshUsed(std::string_view mesh) const
258{
259 return std::any_of(
260 _usedMeshContexts.begin(), _usedMeshContexts.end(),
261 [mesh](const MeshContext *mcptr) {
262 return mcptr->mesh->getName() == mesh;
263 });
264}
265
266bool ParticipantState::isMeshProvided(std::string_view mesh) const
267{
268 PRECICE_ASSERT(hasMesh(mesh));
269 return usedMeshContext(mesh).provideMesh;
270}
271
272bool ParticipantState::isMeshReceived(std::string_view mesh) const
273{
274 PRECICE_ASSERT(hasMesh(mesh));
275 return !usedMeshContext(mesh).provideMesh;
276}
277
278bool ParticipantState::isDirectAccessAllowed(std::string_view mesh) const
279{
280 PRECICE_ASSERT(hasMesh(mesh));
281 return meshContext(mesh).allowDirectAccess;
282}
283
284// Other queries
285
286std::vector<MappingContext> &ParticipantState::readMappingContexts()
287{
288 return _readMappingContexts;
289}
290
291std::vector<MappingContext> &ParticipantState::writeMappingContexts()
292{
293 return _writeMappingContexts;
294}
295
296std::vector<action::PtrAction> &ParticipantState::actions()
297{
298 return _actions;
299}
300
301const std::vector<action::PtrAction> &ParticipantState::actions() const
302{
303 return _actions;
304}
305
306void ParticipantState::addExportContext(
307 const io::ExportContext &exportContext)
308{
309 _exportContexts.push_back(exportContext);
310}
311
312const std::vector<io::ExportContext> &ParticipantState::exportContexts() const
313{
314 return _exportContexts;
315}
316
317std::vector<PtrWatchPoint> &ParticipantState::watchPoints()
318{
319 return _watchPoints;
320}
321
322std::vector<PtrWatchIntegral> &ParticipantState::watchIntegrals()
323{
324 return _watchIntegrals;
325}
326
327bool ParticipantState::useIntraComm() const
328{
329 return _useIntraComm;
330}
331
332const std::string &ParticipantState::getName() const
333{
334 return _name;
335}
336
337void ParticipantState::exportInitial()
338{
339 for (const io::ExportContext &context : exportContexts()) {
340 if (context.everyNTimeWindows < 1) {
341 continue;
342 }
343
344 for (const MeshContext *meshContext : usedMeshContexts()) {
345 auto &mesh = *meshContext->mesh;
346 PRECICE_DEBUG("Exporting initial mesh {} to location \"{}\"", mesh.getName(), context.location);
347 context.exporter->doExport(fmt::format("{}-{}.init", mesh.getName(), getName()), context.location, mesh);
348 }
349 }
350}
351
352void ParticipantState::exportIntermediate(IntermediateExport exp)
353{
354 for (const io::ExportContext &context : exportContexts()) {
355 if (exp.complete && (context.everyNTimeWindows > 0) && (exp.timewindow % context.everyNTimeWindows == 0)) {
356 for (const MeshContext *meshContext : usedMeshContexts()) {
357 auto &mesh = *meshContext->mesh;
358 PRECICE_DEBUG("Exporting mesh {} for timewindow {} to location \"{}\"", mesh.getName(), exp.timewindow, context.location);
359 context.exporter->doExport(fmt::format("{}-{}.dt{}", mesh.getName(), getName(), exp.timewindow), context.location, mesh);
360 }
361 }
362
363 if (context.everyIteration) {
364 for (const MeshContext *meshContext : usedMeshContexts()) {
365 auto &mesh = *meshContext->mesh;
366 PRECICE_DEBUG("Exporting mesh {} for iteration {} to location \"{}\"", meshContext->mesh->getName(), exp.iteration, context.location);
368 context.exporter->doExport(fmt::format("{}-{}.it{}", mesh.getName(), getName(), exp.iteration), context.location, mesh);
369 }
370 }
371 }
372
373 if (exp.complete) {
374 // Export watch point data
375 for (const PtrWatchPoint &watchPoint : watchPoints()) {
376 watchPoint->exportPointData(exp.time);
377 }
378
379 for (const PtrWatchIntegral &watchIntegral : watchIntegrals()) {
380 watchIntegral->exportIntegralData(exp.time);
381 }
382 }
383}
384
385// private
386
387void ParticipantState::checkDuplicatedUse(std::string_view mesh)
388{
389 PRECICE_CHECK(_meshContexts.count(mesh) == 0,
390 "Mesh \"{} cannot be used twice by participant {}. "
391 "Please remove one of the provide/receive-mesh nodes with name=\"{}\"./>",
392 mesh, _name, mesh);
393}
394
395void ParticipantState::checkDuplicatedData(std::string_view mesh, std::string_view data)
396{
397 PRECICE_CHECK(!isDataWrite(mesh, data) && !isDataRead(mesh, data),
398 "ParticipantState \"{}\" can read/write data \"{}\" from/to mesh \"{}\" only once. "
399 "Please remove any duplicate instances of write-data/read-data nodes.",
400 _name, mesh, data);
401}
402
403std::string ParticipantState::hintForMesh(std::string_view mesh) const
404{
405 PRECICE_ASSERT(!hasMesh(mesh));
406 PRECICE_ASSERT(!_meshContexts.empty());
407
408 if (_meshContexts.size() == 1) {
409 return " This participant only knows mesh \"" + _meshContexts.begin()->first + "\".";
410 }
411
412 auto matches = utils::computeMatches(mesh, _meshContexts | boost::adaptors::map_keys);
413 if (matches.front().distance < 3) {
414 return " Did you mean mesh \"" + matches.front().name + "\"?";
415 } else {
416 return fmt::format(" Available meshes are: {}", fmt::join(_meshContexts | boost::adaptors::map_keys, ", "));
417 }
418}
419
420std::string ParticipantState::hintForMeshData(std::string_view mesh, std::string_view data) const
421{
422 PRECICE_ASSERT(hasMesh(mesh));
423 PRECICE_ASSERT(!hasData(mesh, data));
424 PRECICE_ASSERT(!_meshContexts.empty());
425
426 // Is there such data in other meshes?
427 std::vector<std::string> otherMeshes;
428 for (const auto &[_, mc] : _meshContexts) {
429 if (mc->mesh->hasDataName(data)) {
430 return " Did you mean the data of mesh \"" + mc->mesh->getName() + "\"?";
431 }
432 }
433
434 // Is there other data in the given mesh?
435 auto localData = meshContext(mesh).mesh->availableData();
436
437 if (localData.size() == 1) {
438 return " This mesh only knows data \"" + localData.front() + "\".";
439 }
440
441 // Was the data typoed?
442 auto matches = utils::computeMatches(mesh, localData);
443 if (matches.front().distance < 3) {
444 return " Did you mean data \"" + matches.front().name + "\"?";
445 }
446
447 return fmt::format(" Available data are: {}", fmt::join(localData, ", "));
448}
449
450} // namespace precice::impl
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:64
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:95
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:35
std::string name
T any_of(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
void receiveMesh(const mesh::PtrMesh &mesh, const std::string &fromParticipant, double safetyFactor, partition::ReceivedPartition::GeometricFilter geoFilter, const bool allowDirectAccess)
Adds a mesh to be received by the participant.
MeshMap< MeshContext * > _meshContexts
All mesh contexts involved in a simulation.
const ReadDataContext & readDataContext(std::string_view mesh, std::string_view data) const
DataMap< ReadDataContext > _readDataContexts
void addAction(action::PtrAction &&action)
Adds a configured Action to the participant.
std::vector< MeshContext * > _usedMeshContexts
Mesh contexts used by the participant.
const MeshContext & meshContext(std::string_view mesh) const
Mesh queries.
void checkDuplicatedData(std::string_view mesh, std::string_view data)
void addWatchPoint(const PtrWatchPoint &watchPoint)
Adds a configured WatchPoint to the ParticipantState.
std::vector< MappingContext > _readMappingContexts
Read mapping contexts used by the participant.
void addWriteMappingContext(const MappingContext &mappingContext)
Adds a configured write Mapping to the ParticipantState.
ParticipantState(std::string name, mesh::PtrMeshConfiguration &meshConfig)
Constructor.
std::vector< action::PtrAction > _actions
std::vector< PtrWatchIntegral > _watchIntegrals
void setUsePrimaryRank(bool useIntraComm)
Sets weather the participant was configured with a primary tag.
mesh::PtrMesh findMesh(std::string_view data) const
Returns the mesh associated with ReadDataContext with given data name in _readDataContexts of this Pa...
void addReadMappingContext(const MappingContext &mappingContext)
Adds a configured read Mapping to the ParticipantState.
DataMap< WriteDataContext > _writeDataContexts
void addWatchIntegral(const PtrWatchIntegral &watchIntegral)
Adds a configured WatchIntegral to the ParticipantState.
std::vector< MappingContext > _writeMappingContexts
Write mapping contexts used by the participant.
bool hasData(std::string_view mesh, std::string_view data) const
Is the dataID know to preCICE?
void addWriteData(const mesh::PtrData &data, const mesh::PtrMesh &mesh)
void addReadData(const mesh::PtrData &data, const mesh::PtrMesh &mesh)
Adds a configured read Data to the ParticipantState.
std::vector< PtrWatchPoint > _watchPoints
bool useIntraComm() const
Returns true, if the participant uses a primary tag.
void provideMesh(const mesh::PtrMesh &mesh)
Adds a mesh to be provided by the participant.
const WriteDataContext & writeDataContext(std::string_view mesh, std::string_view data) const
void checkDuplicatedUse(std::string_view mesh)
Stores one Data object with related mesh. Context stores data to be read from and potentially provide...
Stores one Data object with related mesh. Context stores data to be written to and potentially provid...
GeometricFilter
Defines the type of geometric filter used.
T empty(T... args)
T find_if(T... args)
T front(T... args)
std::vector< StringMatch > computeMatches(std::string_view given, const Container &expected)
Definition String.hpp:95
STL namespace.
T push_back(T... args)
Holds a data mapping and related information.
Stores a mesh and related objects and data.
mesh::PtrMesh mesh
Mesh holding the geometry data structure.
Type that represent a compound key of two values.