preCICE
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
30 std::string name,
32 : _name(std::move(name))
33{
34}
35
37
39{
40 auto &context = meshContext(action->getMesh()->getName());
41 context.require(action->getMeshRequirement());
42 _actions.push_back(std::move(action));
43}
44
49
51 const PtrWatchPoint &watchPoint)
52{
53 _watchPoints.push_back(watchPoint);
54}
55
57 const PtrWatchIntegral &watchIntegral)
58{
59 _watchIntegrals.push_back(watchIntegral);
60}
61
63{
64 std::string meshName = mesh->getName();
65 PRECICE_TRACE(_name, meshName);
66 checkDuplicatedUse(meshName);
67
68 _providedMeshContexts.emplace_back();
69 _providedMeshContexts.back().mesh = std::move(mesh);
70 _meshContexts[meshName] = &_providedMeshContexts.back();
72}
73
75 const std::string &fromParticipant,
76 double safetyFactor,
78 const bool allowDirectAccess)
79{
80 std::string meshName = mesh->getName();
81 PRECICE_TRACE(_name, meshName);
82 checkDuplicatedUse(meshName);
83 PRECICE_ASSERT(!fromParticipant.empty());
84 PRECICE_ASSERT(safetyFactor >= 0);
85
86 _receivedMeshContexts.emplace_back();
87 auto &context = _receivedMeshContexts.back();
88 context.mesh = std::move(mesh);
89 context.receiveMeshFrom = fromParticipant;
90 context.safetyFactor = safetyFactor;
91 context.geoFilter = geoFilter;
92 context.allowDirectAccess = allowDirectAccess;
93
94 _meshContexts[meshName] = &context;
95 _usedMeshContexts.push_back(&context);
96}
97
99 const mesh::PtrData &data,
100 const mesh::PtrMesh &mesh)
101{
102 checkDuplicatedData(mesh->getName(), data->getName());
103 _writeDataContexts.emplace(MeshDataKey{mesh->getName(), data->getName()}, WriteDataContext(data, mesh));
104}
105
107 const mesh::PtrData &data,
108 const mesh::PtrMesh &mesh)
109{
110 checkDuplicatedData(mesh->getName(), data->getName());
111 _readDataContexts.emplace(MeshDataKey{mesh->getName(), data->getName()}, ReadDataContext(data, mesh));
112}
113
115 const MappingContext &mappingContext)
116{
117 _readMappingContexts.push_back(mappingContext);
118}
119
121 const MappingContext &mappingContext)
122{
123 _writeMappingContexts.push_back(mappingContext);
124}
125
126// Data queries
127const ReadDataContext &ParticipantState::readDataContext(std::string_view mesh, std::string_view data) const
128{
129 auto it = _readDataContexts.find(MeshDataKey{mesh, data});
130 PRECICE_CHECK(it != _readDataContexts.end(), "Data \"{}\" does not exist for mesh \"{}\".", data, mesh);
131 return it->second;
132}
133
134ReadDataContext &ParticipantState::readDataContext(std::string_view mesh, std::string_view data)
135{
136 auto it = _readDataContexts.find(MeshDataKey{mesh, data});
137 PRECICE_CHECK(it != _readDataContexts.end(), "Data \"{}\" does not exist for mesh \"{}\".", data, mesh);
138 return it->second;
139}
140
141mesh::PtrMesh ParticipantState::findMesh(std::string_view data) const
142{
143 for (const auto &meshContext : _meshContexts) {
144 const auto &mesh = meshContext.second->mesh->getName();
145 MeshDataKey<std::string> key{mesh, std::string{data}};
146 const auto it = _readDataContexts.find(key);
147 if (it != _readDataContexts.end()) {
148 return meshContext.second->mesh;
149 }
150 }
151 return nullptr;
152}
153
154const WriteDataContext &ParticipantState::writeDataContext(std::string_view mesh, std::string_view data) const
155{
156 auto it = _writeDataContexts.find(MeshDataKey{mesh, data});
157 PRECICE_CHECK(it != _writeDataContexts.end(), "Data \"{}\" does not exist in write direction.", data);
158 return it->second;
159}
160
161WriteDataContext &ParticipantState::writeDataContext(std::string_view mesh, std::string_view data)
162{
163 auto it = _writeDataContexts.find(MeshDataKey{mesh, data});
164 PRECICE_CHECK(it != _writeDataContexts.end(), "Data \"{}\" does not exist in write direction.", data);
165 return it->second;
166}
167
168bool ParticipantState::hasData(std::string_view mesh, std::string_view data) const
169{
170 return std::any_of(
171 _meshContexts.begin(), _meshContexts.end(),
172 [data](const auto &mckv) {
173 const auto &meshData = mckv.second->mesh->data();
174 return std::any_of(meshData.begin(), meshData.end(), [data](const auto &dptr) {
175 return dptr->getName() == data;
176 });
177 });
178}
179
180bool ParticipantState::isDataUsed(std::string_view mesh, std::string_view data) const
181{
182 const auto &meshData = meshContext(mesh).mesh->data();
183 const auto match = std::find_if(meshData.begin(), meshData.end(), [data](auto &dptr) { return dptr->getName() == data; });
184 return match != meshData.end();
185}
186
187bool ParticipantState::isDataRead(std::string_view mesh, std::string_view data) const
188{
189 return _readDataContexts.count(MeshDataKey{mesh, data}) > 0;
190}
191
192bool ParticipantState::isDataWrite(std::string_view mesh, std::string_view data) const
193{
194 return _writeDataContexts.count(MeshDataKey{mesh, data}) > 0;
195}
196
198
199const MeshContext &ParticipantState::meshContext(std::string_view mesh) const
200{
201 auto pos = _meshContexts.find(mesh);
202 PRECICE_ASSERT(pos != _meshContexts.end());
203 return *pos->second;
204}
205
207{
208 auto pos = _meshContexts.find(mesh);
209 PRECICE_ASSERT(pos != _meshContexts.end());
210 return *pos->second;
211}
212
213const std::vector<MeshContextVariant> &ParticipantState::usedMeshContexts() const
214{
215 return _usedMeshContexts;
216}
217
218std::vector<MeshContextVariant> &ParticipantState::usedMeshContexts()
219{
220 return _usedMeshContexts;
221}
222
223bool ParticipantState::hasMesh(std::string_view mesh) const
224{
225 return _meshContexts.count(mesh) > 0;
226}
227
228bool ParticipantState::isMeshUsed(std::string_view mesh) const
229{
230 return std::any_of(
232 [mesh](const MeshContextVariant &variant) {
233 return getMesh(variant).getName() == mesh;
234 });
235}
236
237bool ParticipantState::isMeshProvided(std::string_view mesh) const
238{
239 return std::any_of(_providedMeshContexts.begin(), _providedMeshContexts.end(),
240 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
241}
242
243bool ParticipantState::isMeshReceived(std::string_view mesh) const
244{
245 return std::any_of(_receivedMeshContexts.begin(), _receivedMeshContexts.end(),
246 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
247}
248
250{
251 auto it = std::find_if(_receivedMeshContexts.begin(), _receivedMeshContexts.end(),
252 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
253 if (it != _receivedMeshContexts.end()) {
254 return it->allowDirectAccess;
255 }
256 return false;
257}
258
260{
261 auto it = std::find_if(_receivedMeshContexts.begin(), _receivedMeshContexts.end(),
262 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
263 PRECICE_ASSERT(it != _receivedMeshContexts.end(), "Mesh \"{}\" is not a received mesh", mesh);
264 return *it;
265}
266
268{
269 auto it = std::find_if(_receivedMeshContexts.begin(), _receivedMeshContexts.end(),
270 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
271 PRECICE_ASSERT(it != _receivedMeshContexts.end(), "Mesh \"{}\" is not a received mesh", mesh);
272 return *it;
273}
274
276{
277 auto it = std::find_if(_providedMeshContexts.begin(), _providedMeshContexts.end(),
278 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
279 PRECICE_ASSERT(it != _providedMeshContexts.end(), "Mesh \"{}\" is not a provided mesh", mesh);
280 return *it;
281}
282
284{
285 auto it = std::find_if(_providedMeshContexts.begin(), _providedMeshContexts.end(),
286 [mesh](const auto &ctx) { return ctx.mesh->getName() == mesh; });
287 PRECICE_ASSERT(it != _providedMeshContexts.end(), "Mesh \"{}\" is not a provided mesh", mesh);
288 return *it;
289}
290
291std::deque<ProvidedMeshContext> &ParticipantState::providedMeshContexts()
292{
294}
295
296const std::deque<ProvidedMeshContext> &ParticipantState::providedMeshContexts() const
297{
299}
300
301std::deque<ReceivedMeshContext> &ParticipantState::receivedMeshContexts()
302{
304}
305
306const std::deque<ReceivedMeshContext> &ParticipantState::receivedMeshContexts() const
307{
309}
310
311// Other queries
312
314{
315 return !_readMappingContexts.empty();
316}
317
319{
320 return !_writeMappingContexts.empty();
321}
322
323std::vector<MappingContext> &ParticipantState::readMappingContexts()
324{
326}
327
328std::vector<MappingContext> &ParticipantState::writeMappingContexts()
329{
331}
332
333std::vector<action::PtrAction> &ParticipantState::actions()
334{
335 return _actions;
336}
337
338const std::vector<action::PtrAction> &ParticipantState::actions() const
339{
340 return _actions;
341}
342
344 const io::ExportContext &exportContext)
345{
346 _exportContexts.push_back(exportContext);
347}
348
349const std::vector<io::ExportContext> &ParticipantState::exportContexts() const
350{
351 return _exportContexts;
352}
353
354std::vector<PtrWatchPoint> &ParticipantState::watchPoints()
355{
356 return _watchPoints;
357}
358
359std::vector<PtrWatchIntegral> &ParticipantState::watchIntegrals()
360{
361 return _watchIntegrals;
362}
363
365{
366 return _useIntraComm;
367}
368
369const std::string &ParticipantState::getName() const
370{
371 return _name;
372}
373
375{
376 for (const io::ExportContext &context : exportContexts()) {
377 if (context.everyNTimeWindows < 1) {
378 continue;
379 }
380
381 PRECICE_DEBUG("Exporting initial mesh {} to location \"{}\"", context.meshName, context.location);
382 context.exporter->doExport(0, 0.0);
383
384 if (context.updateSeries) {
385 PRECICE_DEBUG("Exporting series file of mesh {} to location \"{}\"", context.meshName, context.location);
386 context.exporter->exportSeries();
387 }
388 }
389
390 for (const PtrWatchPoint &watchPoint : watchPoints()) {
391 watchPoint->exportPointData(0.0);
392 }
393
394 for (const PtrWatchIntegral &watchIntegral : watchIntegrals()) {
395 watchIntegral->exportIntegralData(0.0);
396 }
397}
398
400{
401 return !_exportContexts.empty() || !_watchPoints.empty() || !_watchIntegrals.empty();
402}
403
405{
406 for (const io::ExportContext &context : exportContexts()) {
407 if (context.everyIteration) {
408 PRECICE_DEBUG("Exporting mesh {} for iteration {} to location \"{}\"", context.meshName, exp.iteration, context.location);
409 context.exporter->doExport(exp.iteration, exp.time);
410 continue;
411 }
412 if (exp.complete) {
413 PRECICE_DEBUG("Exporting mesh {} for timewindow {} to location \"{}\"", context.meshName, exp.timewindow, context.location);
414 context.exporter->doExport(exp.timewindow, exp.time);
415 }
416
417 if (exp.final || (exp.complete && context.updateSeries)) {
418 PRECICE_DEBUG("Exporting series file of mesh {} to location \"{}\"", context.meshName, context.location);
419 context.exporter->exportSeries();
420 }
421 }
422
423 if (exp.complete) {
424 // Export watch point data
425 for (const PtrWatchPoint &watchPoint : watchPoints()) {
426 watchPoint->exportPointData(exp.time);
427 }
428
429 for (const PtrWatchIntegral &watchIntegral : watchIntegrals()) {
430 watchIntegral->exportIntegralData(exp.time);
431 }
432 }
433}
434
435// private
436
438{
439 PRECICE_CHECK(_meshContexts.count(mesh) == 0,
440 "Mesh \"{} cannot be used twice by participant {}. "
441 "Please remove one of the provide/receive-mesh nodes with name=\"{}\"./>",
442 mesh, _name, mesh);
443}
444
445void ParticipantState::checkDuplicatedData(std::string_view mesh, std::string_view data)
446{
447 PRECICE_CHECK(!isDataWrite(mesh, data) && !isDataRead(mesh, data),
448 "ParticipantState \"{}\" can read/write data \"{}\" from/to mesh \"{}\" only once. "
449 "Please remove any duplicate instances of write-data/read-data nodes.",
450 _name, mesh, data);
451}
452
453std::string ParticipantState::hintForMesh(std::string_view mesh) const
454{
457
458 if (_meshContexts.size() == 1) {
459 return " This participant only knows mesh \"" + _meshContexts.begin()->first + "\".";
460 }
461
462 auto matches = utils::computeMatches(mesh, _meshContexts | boost::adaptors::map_keys);
463 if (matches.front().distance < 3) {
464 return " Did you mean mesh \"" + matches.front().name + "\"?";
465 } else {
466 return fmt::format(" Available meshes are: {}", fmt::join(_meshContexts | boost::adaptors::map_keys, ", "));
467 }
468}
469
470std::string ParticipantState::hintForMeshData(std::string_view mesh, std::string_view data) const
471{
473 PRECICE_ASSERT(!hasData(mesh, data));
475
476 // Is there such data in other meshes?
477 std::vector<std::string> otherMeshes;
478 for (const auto &[_, mc] : _meshContexts) {
479 if (mc->mesh->hasDataName(data)) {
480 return " Did you mean the data of mesh \"" + mc->mesh->getName() + "\"?";
481 }
482 }
483
484 // Is there other data in the given mesh?
485 auto localData = meshContext(mesh).mesh->availableData();
486
487 if (localData.size() == 1) {
488 return " This mesh only knows data \"" + localData.front() + "\".";
489 }
490
491 // Was the data typoed?
492 auto matches = utils::computeMatches(data, localData);
493 if (matches.front().distance < 3) {
494 return " Did you mean data \"" + matches.front().name + "\"?";
495 }
496
497 return fmt::format(" Available data are: {}", fmt::join(localData, ", "));
498}
499
500void ParticipantState::initializeMappingDataCache(std::string_view mappingType)
501{
502 if (mappingType == "write") {
503 for (auto &context : writeDataContexts()) {
504 context.initializeMappingDataCache();
505 }
506 } else {
507 for (auto &context : readDataContexts()) {
508 context.initializeMappingDataCache();
509 }
510 }
511}
512
514{
515 meshContext(fromMesh).meshRequirement = std::max(meshContext(fromMesh).meshRequirement, requirement);
516 meshContext(fromMesh).fromMappingContexts.push_back(mappingContext);
517}
518
520{
521 meshContext(toMesh).toMappingContexts.push_back(mappingContext);
522 meshContext(toMesh).meshRequirement = std::max(meshContext(toMesh).meshRequirement, requirement);
523}
524
525} // namespace precice::impl
#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
bool isMeshReceived(std::string_view mesh) const
Is a mesh with this name received by this participant?
ProvidedMeshContext & providedMeshContext(std::string_view mesh)
std::string hintForMeshData(std::string_view mesh, std::string_view data) const
bool isDataUsed(std::string_view mesh, std::string_view data) const
Is the data used by this participant?
bool isMeshUsed(std::string_view mesh) const
Is a mesh with this name used by this participant?
std::vector< io::ExportContext > _exportContexts
Export contexts to export meshes, data, and more.
MeshMap< MeshContext * > _meshContexts
All mesh contexts involved in a simulation (for name-based lookup)
bool isDataWrite(std::string_view mesh, std::string_view data) const
Is the participant allowed to write the data?
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.
bool isDataRead(std::string_view mesh, std::string_view data) const
Is the participant allowed to read the data?
std::string hintForMesh(std::string_view mesh) const
std::vector< PtrWatchPoint > & watchPoints()
Provided access to all WatchPoints.
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.
std::deque< ProvidedMeshContext > & providedMeshContexts()
ParticipantState(std::string name, mesh::PtrMeshConfiguration &meshConfig)
Constructor.
std::vector< action::PtrAction > _actions
std::vector< MeshContextVariant > _usedMeshContexts
Mesh contexts used by the participant.
bool hasExports() const
Returns true, if the participant has any exports enabled.
std::vector< action::PtrAction > & actions()
Provided access to all Action.
std::vector< PtrWatchIntegral > _watchIntegrals
bool hasWriteMappings() const
Returns true, if the participant has at least one write mapping.
void setUsePrimaryRank(bool useIntraComm)
Sets weather the participant was configured with a primary tag.
void exportIntermediate(IntermediateExport exp)
Exports timewindows and iterations of meshes and watchpoints.
ReceivedMeshContext & receivedMeshContext(std::string_view mesh)
std::deque< ProvidedMeshContext > _providedMeshContexts
Provided mesh contexts (owning container)
void provideMesh(mesh::PtrMesh mesh)
Adds a mesh to be provided by the participant.
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.
bool hasMesh(std::string_view mesh) const
Does preCICE know a mesh with this name?
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.
void receiveMesh(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.
const std::vector< MeshContextVariant > & usedMeshContexts() const
bool hasData(std::string_view mesh, std::string_view data) const
Is the dataID know to preCICE?
void configureOutputMeshContext(std::string_view toMesh, impl::MappingContext &mappingContext, mapping::Mapping::MeshRequirement requirement)
Configures the mesh context with connectivity requirements and adds it to the mappingcontext.
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.
const std::string & getName() const
std::deque< ReceivedMeshContext > _receivedMeshContexts
Received mesh contexts (owning container)
std::vector< PtrWatchPoint > _watchPoints
bool isDirectAccessAllowed(std::string_view mesh) const
void addExportContext(const io::ExportContext &context)
Adds a configured ExportContext to export meshes and data.
std::deque< ReceivedMeshContext > & receivedMeshContexts()
bool useIntraComm() const
Returns true, if the participant uses a primary tag.
bool isMeshProvided(std::string_view mesh) const
Is a mesh with this name provided by this participant?
void configureInputMeshContext(std::string_view fromMesh, impl::MappingContext &mappingContext, mapping::Mapping::MeshRequirement requirement)
Configures the mesh context with connectivity requirements and adds it to the mappingcontext.
std::vector< MappingContext > & writeMappingContexts()
Provided access to all write MappingContext.
const std::vector< io::ExportContext > & exportContexts() const
Returns all ExportContext for exporting meshes and data.
bool hasReadMappings() const
Returns true, if the participant has at least one read mapping.
std::vector< MappingContext > & readMappingContexts()
Provided access to all read MappingContext.
const WriteDataContext & writeDataContext(std::string_view mesh, std::string_view data) const
void initializeMappingDataCache(std::string_view mappingType)
Initializes the MappingDataCache in the DataContext after having computed the mappings.
void checkDuplicatedUse(std::string_view mesh)
std::vector< PtrWatchIntegral > & watchIntegrals()
Provided access to all WatchIntegrals.
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...
MeshRequirement
Specifies requirements for the input and output meshes of a mapping.
Definition Mapping.hpp:46
GeometricFilter
Defines the type of geometric filter used.
contains actions to modify exchanged data.
Definition Action.hpp:6
std::unique_ptr< Action > PtrAction
std::shared_ptr< WatchPoint > PtrWatchPoint
std::variant< ProvidedMeshContext *, ReceivedMeshContext * > MeshContextVariant
Type alias for variant holding either provided or received mesh context pointers.
std::shared_ptr< WatchIntegral > PtrWatchIntegral
provides Mesh, Data and primitives.
std::shared_ptr< Data > PtrData
std::shared_ptr< Mesh > PtrMesh
std::shared_ptr< MeshConfiguration > PtrMeshConfiguration
std::vector< StringMatch > computeMatches(std::string_view given, const Container &expected)
Definition String.hpp:95
STL namespace.
Holds a data mapping and related information.
Type that represent a compound key of two values.
Context for a mesh provided by this participant.
Context for a mesh received from another participant.