2#include <Eigen/src/Core/util/Meta.h>
64#include "precice/impl/versions.hpp"
85 int solverProcessIndex,
86 int solverProcessSize,
88 : _accessorName(participantName),
89 _accessorProcessRank(solverProcessIndex),
90 _accessorCommunicatorSize(solverProcessSize)
94 "This participant's name is an empty string. "
95 "When constructing a preCICE interface you need to pass the name of the "
96 "participant as first argument to the constructor.");
100 "Passing \"nullptr\" as \"communicator\" to Participant constructor is not allowed. "
101 "Please use the Participant constructor without the \"communicator\" argument, if you don't want to pass an MPI communicator.");
103 "The solver process index needs to be a non-negative number, not: {}. "
104 "Please check the value given when constructing a preCICE interface.",
107 "The solver process size needs to be a positive number, not: {}. "
108 "Please check the value given when constructing a preCICE interface.",
111 "The solver process index, currently: {} needs to be smaller than the solver process size, currently: {}. "
112 "Please check the values given when constructing a preCICE interface.",
121#ifndef PRECICE_NO_MPI
133 "The solver process index given in the preCICE interface constructor({}) does not match the rank of the passed MPI communicator ({}).",
137 "The solver process size given in the preCICE interface constructor({}) does not match the size of the passed MPI communicator ({}).",
148 Event e2(
"startProfilingBackend");
181 PRECICE_INFO(
"This is preCICE version {}", PRECICE_VERSION);
182 PRECICE_INFO(
"Revision info: {}", precice::preciceRevision);
188#ifndef PRECICE_NO_DEBUG_LOG
191 " (without debug log)"
193#ifndef PRECICE_NO_TRACE_LOG
196#ifndef PRECICE_NO_ASSERTIONS
206 PRECICE_INFO(
"Configuring preCICE with configuration \"{}\"", configurationFileName);
221 "A parallel participant needs an intra-participant communication");
223 "You cannot use an intra-participant communication with a serial participant. "
224 "If you do not know exactly what an intra-participant communication is and why you want to use it "
225 "you probably just want to remove the intraComm tag from the preCICE configuration.");
233 "In the preCICE configuration, only one participant is defined. "
234 "One participant makes no coupled simulation. "
235 "Please add at least another one.");
258 "Initial data has to be written to preCICE before calling initialize(). "
259 "After defining your mesh, call requiresInitialData() to check if the participant is required to write initial data using the writeData() function.");
262 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling initialize().");
267 for (
const auto &context :
_accessor->usedMeshContexts()) {
268 if (context->provideMesh) {
269 e.
addData(
"meshSize" + context->mesh->getName(), context->mesh->nVertices());
278 for (
auto &context :
_accessor->writeDataContexts()) {
279 const double startTime = 0.0;
280 context.storeBufferedData(startTime);
313 for (
const auto &context :
_accessor->usedMeshContexts()) {
314 if (context->provideMesh) {
315 e.
addData(
"meshSize" + context->mesh->getName(), context->mesh->nVertices());
333 if (meshContext->provideMesh) {
334 auto &
mesh = *(meshContext->mesh);
336 meshContext->mesh->preprocess();
342 PRECICE_INFO(
"Setting up primary communication to coupling partner/s");
343 Event e2(
"connectPrimaries");
344 for (
auto &m2nPair :
_m2ns) {
345 auto &bm2n = m2nPair.second;
346 bool requesting = bm2n.isRequesting;
347 if (bm2n.m2n->isConnected()) {
348 PRECICE_DEBUG(
"Primary connection {} {} already connected.", (requesting ?
"from" :
"to"), bm2n.remoteName);
350 PRECICE_DEBUG((requesting ?
"Awaiting primary connection from {}" :
"Establishing primary connection to {}"), bm2n.remoteName);
351 bm2n.prepareEstablishment();
353 PRECICE_DEBUG(
"Established primary connection {} {}", (requesting ?
"from " :
"to "), bm2n.remoteName);
360 Event e3(
"repartitioning");
364 PRECICE_INFO(
"Setting up preliminary secondary communication to coupling partner/s");
365 for (
auto &m2nPair :
_m2ns) {
366 auto &bm2n = m2nPair.second;
367 bm2n.preConnectSecondaryRanks();
373 PRECICE_INFO(
"Setting up secondary communication to coupling partner/s");
374 Event e4(
"connectSecondaries");
375 for (
auto &m2nPair :
_m2ns) {
376 auto &bm2n = m2nPair.second;
377 bm2n.connectSecondaryRanks();
378 PRECICE_DEBUG(
"Established secondary connection {} {}", (bm2n.isRequesting ?
"from " :
"to "), bm2n.remoteName);
382 for (
auto &m2nPair :
_m2ns) {
383 m2nPair.second.cleanupEstablishment();
392 watchPoint->initialize();
395 watchIntegral->initialize();
400 double computedTimeStepSize)
406 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling advance().");
420 PRECICE_CHECK(computedTimeStepSize > 0.0,
"advance() cannot be called with a negative time step size {}.", computedTimeStepSize);
431 const bool isAtWindowEnd =
_couplingScheme->addComputedTime(computedTimeStepSize);
438 int sumOfChanges =
std::accumulate(totalMeshChanges.begin(), totalMeshChanges.end(), 0);
456 const bool timeWindowComplete =
_couplingScheme->isTimeWindowComplete();
458 handleDataAfterAdvance(isAtWindowEnd, timeWindowComplete, timeSteppedTo, timeAfterAdvance, dataToReceive);
462 PRECICE_DEBUG(
"Mapped {} samples in write mappings and {} samples in read mappings",
493 if (reachedTimeWindowEnd) {
501 if (!reachedTimeWindowEnd) {
508 PRECICE_ASSERT(
math::greaterEquals(timeAfterAdvance, timeSteppedTo),
"We must have stayed or moved forwards in time (min-time-step-size).", timeAfterAdvance, timeSteppedTo);
519 if (reachedTimeWindowEnd) {
526 for (
auto &context :
_accessor->readDataContexts()) {
527 context.invalidateMappingCache();
531 for (
auto &context :
_accessor->writeDataContexts()) {
532 context.invalidateMappingCache();
537 for (
auto &context :
_accessor->readDataContexts()) {
538 context.resetInitialGuesses();
540 for (
auto &context :
_accessor->writeDataContexts()) {
541 context.resetInitialGuesses();
551 for (
auto &context :
_accessor->writeDataContexts()) {
568 context.completeJustInTimeMapping();
569 context.storeBufferedData(time);
575 for (
auto &context :
_accessor->usedMeshContexts()) {
576 for (
const auto &
name : context->mesh->availableData()) {
577 context->mesh->data(
name)->timeStepsStorage().trimBefore(time);
584 for (
auto &context :
_accessor->writeDataContexts()) {
585 context.trimAfter(time);
631#ifndef PRECICE_NO_GINKGO
645 return _accessor->usedMeshContext(meshName).mesh->getDimensions();
653 return _accessor->usedMeshContext(meshName).mesh->data(dataName)->getDimensions();
676 const double nextTimeStepSize =
_couplingScheme->getNextTimeStepMaxSize();
684 "preCICE just returned a maximum time step size of {}. Such a small value can happen if you use many substeps per time window over multiple time windows due to added-up differences of machine precision.",
686 return nextTimeStepSize;
734 if (!
_accessor->isDataWrite(meshName, dataName))
749 " data of the received mesh \"{}\" on participant \"{}\".",
758 "but no access region was defined although this is necessary for parallel runs. "
759 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexSize()\".",
764 PRECICE_DEBUG(
"Filtered {} of {} vertices out on mesh {} due to the local access region. Mesh size in the access region: {}", context.
mesh->nVertices() - result, context.
mesh->nVertices(), meshName, result);
769 "You are calling \"getMeshVertexSize()\" on a received mesh without api-access enabled (<receive-mesh name=\"{0}\" ... api-access=\"false\"/>). "
770 "Note that enabling api-access is required for this function to work properly with direct mesh access and just-in-time mappings.",
772 return context.
mesh->nVertices();
781 PRECICE_CHECK(
_allowsRemeshing,
"Cannot reset meshes. This feature needs to be enabled using <precice-configuration experimental=\"1\" allow-remeshing=\"1\">.");
786 PRECICE_CHECK(
_couplingScheme->isTimeWindowComplete(),
"Cannot remesh while subcycling or iterating. Remeshing is only allowed when the time window is completed.");
791 context.
mesh->clear();
803 "Cannot set vertex for mesh \"{}\". Expected {} position components but found {}.", meshName,
mesh.
getDimensions(), position.
size());
809 for (
auto &context :
_accessor->writeDataContexts()) {
811 context.resizeBufferTo(newSize);
829 const auto expectedPositionSize = ids.
size() * meshDims;
831 "Input sizes are inconsistent attempting to set vertices on {}D mesh \"{}\". "
832 "You passed {} vertex indices and {} position components, but we expected {} position components ({} x {}).",
833 meshDims, meshName, ids.
size(), positions.
size(), expectedPositionSize, ids.
size(), meshDims);
836 const Eigen::Map<const Eigen::MatrixXd> posMatrix{
838 for (
unsigned long i = 0; i < ids.
size(); ++i) {
844 for (
auto &context :
_accessor->writeDataContexts()) {
846 context.resizeBufferTo(newSize);
867 mesh->createEdge(v0, v1);
884 "Cannot interpret passed vertex IDs attempting to set edges of mesh \"{}\" . "
885 "You passed {} vertex indices, but we expected an even number.",
886 meshName, vertices.
size());
888 auto end = vertices.
end();
890 return !mesh->isValidVertexID(vid);
900 for (
unsigned long i = 0; i < vertices.
size() / 2; ++i) {
901 auto aid = vertices[2 * i];
902 auto bid = vertices[2 * i + 1];
903 mesh->createEdge(mesh->vertex(aid), mesh->vertex(bid));
925 "setMeshTriangle() was called with repeated Vertex IDs ({}, {}, {}).",
926 first, second, third);
928 vertices[0] = &mesh->vertex(first);
929 vertices[1] = &mesh->vertex(second);
930 vertices[2] = &mesh->vertex(third);
932 vertices[1]->getCoords(), vertices[2]->getCoords())),
933 "setMeshTriangle() was called with vertices located at identical coordinates (IDs: {}, {}, {}).",
934 first, second, third);
937 edges[0] = &mesh->createEdge(*vertices[0], *vertices[1]);
938 edges[1] = &mesh->createEdge(*vertices[1], *vertices[2]);
939 edges[2] = &mesh->createEdge(*vertices[2], *vertices[0]);
941 mesh->createTriangle(*edges[0], *edges[1], *edges[2]);
958 "Cannot interpret passed vertex IDs attempting to set triangles of mesh \"{}\" . "
959 "You passed {} vertex indices, which isn't dividable by 3.",
960 meshName, vertices.
size());
962 auto end = vertices.
end();
964 return !mesh->isValidVertexID(vid);
974 for (
unsigned long i = 0; i < vertices.
size() / 3; ++i) {
975 auto aid = vertices[3 * i];
976 auto bid = vertices[3 * i + 1];
977 auto cid = vertices[3 * i + 2];
978 mesh->createTriangle(mesh->vertex(aid),
992 second, third, fourth);
995 PRECICE_CHECK(context.
mesh->getDimensions() == 3,
"setMeshQuad is only possible for 3D meshes."
996 " Please set the mesh dimension to 3 in the preCICE configuration file.");
1011 "The four vertices that form the quad are not unique. The resulting shape may be a point, line or triangle."
1012 "Please check that the adapter sends the four unique vertices that form the quad, or that the mesh on the interface is composed of quads.");
1015 PRECICE_CHECK(convexity.convex,
"The given quad is not convex. "
1016 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.");
1024 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1025 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1028 if (distance02 <= distance13) {
1029 mesh.
createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1030 mesh.
createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1032 mesh.
createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1033 mesh.
createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1051 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1052 "You passed {} vertex indices, which isn't dividable by 4.",
1053 meshName, vertices.
size());
1055 auto end = vertices.
end();
1057 return !mesh.isValidVertexID(vid);
1065 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1066 auto aid = vertices[4 * i];
1067 auto bid = vertices[4 * i + 1];
1068 auto cid = vertices[4 * i + 2];
1069 auto did = vertices[4 * i + 3];
1072 PRECICE_CHECK(
utils::unique_elements(vertexIDs),
"The four vertex ID's of the quad nr {} are not unique. Please check that the vertices that form the quad are correct.", i);
1076 "The four vertices that form the quad nr {} are not unique. The resulting shape may be a point, line or triangle."
1077 "Please check that the adapter sends the four unique vertices that form the quad, or that the mesh on the interface is composed of quads.",
1081 PRECICE_CHECK(convexity.convex,
"The given quad nr {} is not convex. "
1082 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.",
1090 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1091 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1093 if (distance02 <= distance13) {
1094 mesh.
createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1095 mesh.
createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1097 mesh.
createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1098 mesh.
createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1113 PRECICE_CHECK(context.
mesh->getDimensions() == 3,
"setMeshTetrahedron is only possible for 3D meshes."
1114 " Please set the mesh dimension to 3 in the preCICE configuration file.");
1129 mesh->createTetrahedron(A, B, C, D);
1146 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1147 "You passed {} vertex indices, which isn't dividable by 4.",
1148 meshName, vertices.
size());
1150 auto end = vertices.
end();
1152 return !mesh->isValidVertexID(vid);
1162 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1163 auto aid = vertices[4 * i];
1164 auto bid = vertices[4 * i + 1];
1165 auto cid = vertices[4 * i + 2];
1166 auto did = vertices[4 * i + 3];
1167 mesh->createTetrahedron(mesh->vertex(aid),
1182 PRECICE_CHECK(
_state ==
State::Constructed || (
_state ==
State::Initialized &&
isCouplingOngoing()),
"Calling writeData(...) is forbidden if coupling is not ongoing, because the data you are trying to write will not be used anymore. You can fix this by always calling writeData(...) before the advance(...) call in your simulation loop or by using Participant::isCouplingOngoing() to implement a safeguard.");
1192 const auto expectedDataSize = vertices.
size() * dataDims;
1194 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1195 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1196 dataDims, dataName, meshName,
1197 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1203 PRECICE_ERROR(
"Cannot write data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1204 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1205 dataName, meshName, *
index);
1215 double relativeReadTime,
1222 PRECICE_CHECK(relativeReadTime >= 0,
"readData(...) cannot sample data before the current time.");
1223 PRECICE_CHECK(
isCouplingOngoing() ||
math::equals(relativeReadTime, 0.0),
"Calling readData(...) with relativeReadTime = {} is forbidden if coupling is not ongoing. If coupling finished, only data for relativeReadTime = 0 is available. Please always use precice.getMaxTimeStepSize() to obtain the maximum allowed relativeReadTime.", relativeReadTime);
1228 "Cannot read from mesh \"{}\" after it has been reset. Please read data before calling resetMesh().",
1238 "This is typically a configuration issue of the data flow. "
1239 "Check if the data is correctly exchanged to this participant \"{}\" and mapped to mesh \"{}\".",
1243 const auto expectedDataSize = vertices.
size() * dataDims;
1245 "Input/Output sizes are inconsistent attempting to read {}D data \"{}\" from mesh \"{}\". "
1246 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1247 dataDims, dataName, meshName,
1248 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1251 PRECICE_ERROR(
"Cannot read data \"{}\" from mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1252 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1253 dataName, meshName, *
index);
1259 context.
readValues(vertices, readTime, values);
1266 double relativeReadTime,
1274 PRECICE_CHECK(relativeReadTime >= 0,
"mapAndReadData(...) cannot sample data before the current time.");
1275 PRECICE_CHECK(
isCouplingOngoing() ||
math::equals(relativeReadTime, 0.0),
"Calling mapAndReadData(...) with relativeReadTime = {} is forbidden if coupling is not ongoing. If coupling finished, only data for relativeReadTime = 0 is available. Please always use precice.getMaxTimeStepSize() to obtain the maximum allowed relativeReadTime.", relativeReadTime);
1281 "This participant attempteded to map and read data (via \"mapAndReadData\") from mesh \"{0}\", "
1282 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1283 "mapAndReadData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1288 "The function \"mapAndReadData\" was called on mesh \"{0}\", "
1289 "but no access region was defined although this is necessary for parallel runs. "
1290 "Please define an access region using \"setMeshAccessRegion()\" before calling \"mapAndReadData()\".",
1293 PRECICE_CHECK(!
_accessor->meshContext(meshName).mesh->empty(),
"This participant tries to mapAndRead data values for data \"{0}\" on mesh \"{1}\", but the mesh \"{1}\" is empty within the defined access region on this rank. "
1294 "How should the provided data values be read? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1295 dataName, meshName);
1308 const auto nVertices = (coordinates.
size() / dim);
1316 "Input sizes are inconsistent attempting to mapAndRead {}D data \"{}\" from mesh \"{}\". "
1317 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1318 dataDims, dataName, meshName,
1319 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1334 PRECICE_CHECK(
_state ==
State::Constructed || (
_state ==
State::Initialized &&
isCouplingOngoing()),
"Calling writeAndMapData(...) is forbidden if coupling is not ongoing, because the data you are trying to write will not be used anymore. You can fix this by always calling writeAndMapData(...) before the advance(...) call in your simulation loop or by using Participant::isCouplingOngoing() to implement a safeguard.");
1340 "This participant attempteded to map and read data (via \"writeAndMapData\") from mesh \"{0}\", "
1341 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1342 "writeAndMapData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1347 "The function \"writeAndMapData\" was called on mesh \"{0}\", "
1348 "but no access region was defined although this is necessary for parallel runs. "
1349 "Please define an access region using \"setMeshAccessRegion()\" before calling \"writeAndMapData()\".",
1363 const auto nVertices = (coordinates.
size() / dim);
1370 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1371 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1372 dataDims, dataName, meshName,
1373 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1375 PRECICE_CHECK(!context.
mesh->empty(),
"This participant tries to mapAndWrite data values for data \"{0}\" on mesh \"{1}\", but the mesh \"{1}\" is empty within the defined access region on this rank. "
1376 "Where should the provided data go? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1377 dataName, meshName);
1403 PRECICE_CHECK(context.
hasGradient(),
"Data \"{}\" has no gradient values available. Please set the gradient flag to true under the data attribute in the configuration file.", dataName);
1406 PRECICE_ERROR(
"Cannot write gradient data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1407 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1408 dataName, meshName, *
index);
1413 const auto gradientComponents = meshDims * dataDims;
1414 const auto expectedComponents = vertices.
size() * gradientComponents;
1416 "Input sizes are inconsistent attempting to write gradient for data \"{}\" to mesh \"{}\". "
1417 "A single gradient/Jacobian for {}D data on a {}D mesh has {} components. "
1418 "You passed {} vertex indices and {} gradient components, but we expected {} gradient components. ",
1420 dataDims, meshDims, gradientComponents,
1421 vertices.
size(), gradients.
size(), expectedComponents);
1437 "This participant attempteded to set an access region (via \"setMeshAccessRegion\") on mesh \"{0}\", "
1438 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1439 "setMeshAccessRegion(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1449 int dim = mesh->getDimensions();
1451 "Incorrect amount of bounding box components attempting to set the bounding box of {}D mesh \"{}\" . "
1452 "You passed {} limits, but we expected {} ({}x2).",
1453 dim, meshName, boundingBox.
size(), dim * 2, dim);
1459 for (
int d = 0; d < dim; ++d) {
1461 PRECICE_CHECK(boundingBox[2 * d] <= boundingBox[2 * d + 1],
"Your bounding box is ill defined, i.e. it has a negative volume. The required format is [x_min, x_max...]");
1462 bounds[2 * d] = boundingBox[2 * d];
1463 bounds[2 * d + 1] = boundingBox[2 * d + 1];
1479 "This participant attempteded to get mesh vertex IDs and coordinates (via \"getMeshVertexIDsAndCoordinates\") from mesh \"{0}\", "
1480 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1481 "getMeshVertexIDsAndCoordinates(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1486 "The function \"getMeshVertexIDsAndCoordinates\" was called on mesh \"{0}\", "
1487 "but no access region was defined although this is necessary for parallel runs. "
1488 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexIDsAndCoordinates()\".",
1495 " data of the received mesh \"{}\" on participant \"{}\".",
1507 const auto meshSize = filteredVertices.size();
1510 const auto meshDims = mesh->getDimensions();
1512 "Output size is incorrect attempting to get vertex ids of {}D mesh \"{}\". "
1513 "You passed {} vertex indices, but we expected {}. "
1514 "Use getMeshVertexSize(\"{}\") to receive the required amount of vertices.",
1515 meshDims, meshName, ids.
size(), meshSize, meshName);
1516 const auto expectedCoordinatesSize =
static_cast<unsigned long>(meshDims * meshSize);
1518 "Output size is incorrect attempting to get vertex coordinates of {}D mesh \"{}\". "
1519 "You passed {} coordinate components, but we expected {} ({}x{}). "
1520 "Use getMeshVertexSize(\"{}\") and getMeshDimensions(\"{}\") to receive the required amount components",
1521 meshDims, meshName, coordinates.
size(), expectedCoordinatesSize, meshSize, meshDims, meshName, meshName);
1523 PRECICE_ASSERT(ids.
size() <= mesh->nVertices(),
"The queried size exceeds the number of available points.");
1525 Eigen::Map<Eigen::MatrixXd> posMatrix{
1526 coordinates.
data(), mesh->getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
1528 for (
unsigned long i = 0; i < ids.
size(); i++) {
1529 auto localID = filteredVertices[i].
get().getID();
1532 posMatrix.col(i) = filteredVertices[i].get().getCoords();
1540 for (
const auto &m2nConf : config->m2ns()) {
1548 comPartner = m2nConf.connector;
1549 isRequesting =
true;
1551 comPartner = m2nConf.acceptor;
1552 isRequesting =
false;
1557 if (participant->getName() == comPartner) {
1561 _m2ns[comPartner] = [&] {
1563 bound.
m2n = m2nConf.m2n;
1580 if (context->provideMesh) {
1582 "Participant \"{}\" cannot provide and receive mesh {}!",
1588 for (
auto &receiverContext : receiver->usedMeshContexts()) {
1589 if (receiverContext->receiveMeshFrom ==
_accessorName && receiverContext->mesh->getName() == context->mesh->getName()) {
1592 if (receiverContext->meshRequirement > context->meshRequirement) {
1593 context->meshRequirement = receiverContext->meshRequirement;
1597 m2n->createDistributedCommunication(context->mesh);
1598 context->partition->addM2N(m2n);
1611 m2n::PtrM2N m2n = m2nConfig->getM2N(receiver, provider);
1612 m2n->createDistributedCommunication(context->mesh);
1613 context->partition->addM2N(m2n);
1614 for (
const MappingContext &mappingContext : context->fromMappingContexts) {
1615 context->partition->addFromMapping(mappingContext.mapping);
1617 for (
const MappingContext &mappingContext : context->toMappingContexts) {
1618 context->partition->addToMapping(mappingContext.mapping);
1629 return lhs->mesh->getName() < rhs->mesh->getName();
1633 if (meshContext->provideMesh)
1634 meshContext->mesh->computeBoundingBox();
1636 meshContext->clearMappings();
1640 meshContext->partition->compareBoundingBoxes();
1650 auto &contexts =
_accessor->usedMeshContexts();
1652 std::sort(contexts.begin(), contexts.end(),
1654 return lhs->mesh->getName() < rhs->mesh->getName();
1658 meshContext->partition->communicate();
1665 for (
auto &m2nPair :
_m2ns) {
1666 if (m2nPair.second.m2n->usesTwoLevelInitialization()) {
1675 [](
MeshContext const *
const meshContext) ->
bool {
1676 return meshContext->provideMesh;
1681 meshContext->partition->compute();
1682 if (not meshContext->provideMesh) {
1683 meshContext->mesh->computeBoundingBox();
1686 meshContext->mesh->allocateDataValues();
1688 const auto requiredSize = meshContext->mesh->nVertices();
1689 for (
auto &context :
_accessor->writeDataContexts()) {
1690 if (context.getMeshName() == meshContext->mesh->getName()) {
1691 context.resizeBufferTo(requiredSize);
1700 bool anyMappingChanged =
false;
1702 if (not context.mapping->hasComputedMapping()) {
1704 "Automatic RBF mapping alias from mesh \"{}\" to mesh \"{}\" in \"{}\" direction resolves to \"{}\" .",
1705 context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType, context.mapping->getName());
1706 PRECICE_INFO(
"Computing \"{}\" mapping from mesh \"{}\" to mesh \"{}\" in \"{}\" direction.",
1707 context.mapping->getName(), context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType);
1708 context.mapping->computeMapping();
1709 anyMappingChanged =
true;
1712 if (anyMappingChanged) {
1713 _accessor->initializeMappingDataCache(mappingType);
1726 for (
auto &context :
_accessor->writeDataContexts()) {
1727 if (context.hasMapping()) {
1728 PRECICE_DEBUG(
"Map initial write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1743 for (
auto &context :
_accessor->writeDataContexts()) {
1744 if (context.hasMapping()) {
1745 PRECICE_DEBUG(
"Map write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1754 for (
auto &context :
_accessor->readDataContexts()) {
1755 if (context.hasMapping()) {
1760 context.clearToDataFor(fromData);
1762 context.trimToDataAfterFor(fromData, startOfTimeWindow);
1777 for (
auto &context :
_accessor->readDataContexts()) {
1778 if (context.hasMapping()) {
1779 PRECICE_DEBUG(
"Map initial read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1795 for (
auto &context :
_accessor->readDataContexts()) {
1796 if (context.hasMapping()) {
1797 PRECICE_DEBUG(
"Map read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1808 if (timings.
find(action->getTiming()) != timings.
end()) {
1809 action->performAction();
1840 for (
auto &context :
_accessor->writeDataContexts()) {
1842 context.resetBufferedData();
1850 for (
const PtrParticipant &participant : partConfig->getParticipants()) {
1855 PRECICE_ERROR(
"This participant's name, which was specified in the constructor of the preCICE interface as \"{}\", "
1856 "is not defined in the preCICE configuration. "
1857 "Please double-check the correct spelling.",
1884 "Found ambiguous values for the time step size passed to preCICE in \"advance\". On rank {}, the value is {}, while on rank 0, the value is {}.",
1885 secondaryRank, dt, computedTimeStepSize);
1897 [[maybe_unused]]
auto remoteChanges1 =
_couplingScheme->firstSynchronization(localChanges);
1900 [[maybe_unused]]
auto remoteChanges2 =
_couplingScheme->secondSynchronization();
1913 for (
auto &iter :
_m2ns) {
1914 auto bm2n = iter.second;
1915 if (!bm2n.m2n->isConnected()) {
1916 PRECICE_DEBUG(
"Skipping closure of defective connection with {}", bm2n.remoteName);
1920 auto comm = bm2n.m2n->getPrimaryRankCommunication();
1921 PRECICE_DEBUG(
"Synchronizing primary rank with {}", bm2n.remoteName);
1922 if (bm2n.isRequesting) {
1923 comm->send(ping, 0);
1925 comm->receive(receive, 0);
1929 comm->receive(receive, 0);
1931 comm->send(pong, 0);
1935 PRECICE_DEBUG(
"Closing distributed communication with {}", bm2n.remoteName);
1936 bm2n.m2n->closeDistributedConnections();
1938 PRECICE_DEBUG(
"Closing communication with {}", bm2n.remoteName);
1939 bm2n.m2n->closeConnection();
1952 return *
_accessor->usedMeshContext(meshName).mesh;
1973 for (
auto context :
_accessor->usedMeshContexts()) {
1976 PRECICE_DEBUG(
"Mesh changes of rank: {}", localMeshChanges);
1984 PRECICE_DEBUG(
"Mesh changes of participant: {}", totalMeshChangesInt);
1985 return totalMeshChangesInt;
1990 auto meshContexts =
_accessor->usedMeshContexts();
1992 if (totalMeshChanges[i] > 0.0) {
1993 meshContexts[i]->mesh->clearDataStamples();
2005 PRECICE_DEBUG(
"Remeshing is{} required by this participant.", (requestReinit ?
"" :
" not"));
2007 bool swarmReinitRequired = requestReinit;
2008 for (
auto &iter :
_m2ns) {
2009 PRECICE_DEBUG(
"Coordinating remeshing with {}", iter.first);
2010 bool received =
false;
2011 auto &comm = *iter.second.m2n->getPrimaryRankCommunication();
2012 if (iter.second.isRequesting) {
2013 comm.send(requestReinit, 0);
2014 comm.receive(received, 0);
2016 comm.receive(received, 0);
2017 comm.send(requestReinit, 0);
2019 swarmReinitRequired |= received;
2021 PRECICE_DEBUG(
"Coordinated that overall{} remeshing is required.", (swarmReinitRequired ?
"" :
" no"));
2024 return swarmReinitRequired;
2026 bool swarmReinitRequired =
false;
2028 return swarmReinitRequired;
2035 "The provided section name \"{}\" may not contain a forward-slash \"/\"",
#define PRECICE_ERROR(...)
#define PRECICE_WARN_IF(condition,...)
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_INFO_IF(condition,...)
#define PRECICE_INFO(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_VALIDATE_DATA_NAME(mesh, data)
#define PRECICE_REQUIRE_DATA_WRITE(mesh, data)
#define PRECICE_REQUIRE_MESH_USE(name)
#define PRECICE_REQUIRE_DATA_READ(mesh, data)
#define PRECICE_REQUIRE_MESH_MODIFY(name)
#define PRECICE_VALIDATE_DATA(data, size)
#define PRECICE_EXPERIMENTAL_API()
#define PRECICE_VALIDATE_MESH_NAME(name)
#define PRECICE_ASSERT(...)
Main class for preCICE XML configuration tree.
const PtrParticipantConfiguration & getParticipantConfiguration() const
const mesh::PtrMeshConfiguration getMeshConfiguration() const
const m2n::M2NConfiguration::SharedPointer getM2NConfiguration() const
bool waitInFinalize() const
Returns whether participants wait for each other in finalize.
const cplscheme::PtrCouplingSchemeConfiguration getCouplingSchemeConfiguration() const
bool allowsExperimental() const
Returns whether experimental features are allowed or not.
bool allowsRemeshing() const
Returns whether experimental remeshing is allowed or not.
xml::XMLTag & getXMLTag()
Returns root xml tag to start the automatic configuration process.
@ WriteCheckpoint
Is the participant required to write a checkpoint?
@ ReadCheckpoint
Is the participant required to read a previously written checkpoint?
@ InitializeData
Is the initialization of coupling data required?
bool hasGradient() const
Returns whether _providedData has gradient.
int getDataDimensions() const
Get the dimensions of _providedData.
int getSpatialDimensions() const
Get the spatial dimensions of _providedData.
std::optional< std::size_t > locateInvalidVertexID(const Container &c)
CloseChannels
Which channels to close in closeCommunicationChannels()
void writeGradientData(std::string_view meshName, std::string_view dataName, ::precice::span< const VertexID > vertices, ::precice::span< const double > gradients)
Writes vector gradient data to a mesh.
int getMeshVertexSize(std::string_view meshName) const
Returns the number of vertices of a mesh.
utils::MultiLock< std::string > _meshLock
void setMeshQuad(std::string_view meshName, VertexID first, VertexID second, VertexID third, VertexID fourth)
Sets a planar surface mesh quadrangle from vertex IDs.
bool requiresInitialData()
void setMeshTetrahedra(std::string_view meshName, ::precice::span< const VertexID > vertices)
Sets multiple mesh tetrahedra from vertex IDs.
bool requiresGradientDataFor(std::string_view meshName, std::string_view dataName) const
Checks if the given data set requires gradient data. We check if the data object has been initialized...
int getDataDimensions(std::string_view meshName, std::string_view dataName) const
Returns the spatial dimensionality of the given data on the given mesh.
impl::PtrParticipant determineAccessingParticipant(const config::Configuration &config)
Determines participant accessing this interface from the configuration.
MeshChanges getTotalMeshChanges() const
void advanceCouplingScheme()
Advances the coupling schemes.
void computePartitions()
Communicate meshes and create partitions.
void setMeshEdge(std::string_view meshName, VertexID first, VertexID second)
Sets a mesh edge from vertex IDs.
std::vector< impl::PtrParticipant > _participants
Holds information about solvers participating in the coupled simulation.
bool requiresMeshConnectivityFor(std::string_view meshName) const
Checks if the given mesh requires connectivity.
void setMeshTriangles(std::string_view meshName, ::precice::span< const VertexID > vertices)
Sets multiple mesh triangles from vertex IDs.
int _executedReadMappings
Counts the amount of samples mapped in read mappings executed in the latest advance.
void clearStamplesOfChangedMeshes(MeshChanges totalMeshChanges)
Clears stample of changed meshes to make them consistent after the reinitialization.
void performDataActions(const std::set< action::Action::Timing > &timings)
Performs all data actions with given timing.
void setMeshTriangle(std::string_view meshName, VertexID first, VertexID second, VertexID third)
Sets mesh triangle from vertex IDs.
void configurePartitions(const m2n::M2NConfiguration::SharedPointer &m2nConfig)
Determines participants providing meshes to other participants.
bool requiresWritingCheckpoint()
double getMaxTimeStepSize() const
Get the maximum allowed time step size of the current window.
cplscheme::PtrCouplingScheme _couplingScheme
long int _numberAdvanceCalls
Counts calls to advance for plotting.
bool _allowsExperimental
Are experimental API calls allowed?
void handleDataBeforeAdvance(bool reachedTimeWindowEnd, double timeSteppedTo)
Completes everything data-related between adding time to and advancing the coupling scheme.
void setMeshTetrahedron(std::string_view meshName, VertexID first, VertexID second, VertexID third, VertexID fourth)
Set tetrahedron in 3D mesh from vertex ID.
void handleDataAfterAdvance(bool reachedTimeWindowEnd, bool isTimeWindowComplete, double timeSteppedTo, double timeAfterAdvance, const cplscheme::ImplicitData &receivedData)
Completes everything data-related after advancing the coupling scheme.
void samplizeWriteData(double time)
Creates a Stample at the given time for each write Data and zeros the buffers.
void setMeshQuads(std::string_view meshName, ::precice::span< const VertexID > vertices)
Sets multiple mesh quads from vertex IDs.
void getMeshVertexIDsAndCoordinates(std::string_view meshName, ::precice::span< VertexID > ids, ::precice::span< double > coordinates) const
getMeshVertexIDsAndCoordinates Iterates over the region of interest defined by bounding boxes and rea...
int _accessorCommunicatorSize
void closeCommunicationChannels(CloseChannels cc)
Syncs the primary ranks of all connected participants.
bool reinitHandshake(bool requestReinit) const
void trimSendDataAfter(double time)
Discards send (currently write) data of a participant after a given time when another iteration is re...
std::unique_ptr< profiling::Event > _solverInitEvent
ParticipantImpl(std::string_view participantName, std::string_view configurationFileName, int solverProcessIndex, int solverProcessSize, std::optional< void * > communicator)
Generic constructor for ParticipantImpl.
void advance(double computedTimeStepSize)
Advances preCICE after the solver has computed one time step.
std::string _accessorName
void setMeshAccessRegion(std::string_view meshName, ::precice::span< const double > boundingBox) const
setMeshAccessRegion Define a region of interest on a received mesh (<receive-mesh ....
void writeData(std::string_view meshName, std::string_view dataName, ::precice::span< const VertexID > vertices, ::precice::span< const double > values)
Writes data to a mesh.
void mapInitialReadData()
std::vector< profiling::Event > _userEvents
void handleExports(ExportTiming timing)
~ParticipantImpl()
Destructor.
bool isCouplingOngoing() const
Checks if the coupled simulation is still ongoing.
State _state
The current State of the Participant.
void mapInitialWrittenData()
Computes, and performs write mappings of the initial data in initialize.
impl::PtrParticipant _accessor
void setMeshVertices(std::string_view meshName, ::precice::span< const double > positions, ::precice::span< VertexID > ids)
Creates multiple mesh vertices.
void resetMesh(std::string_view meshName)
Removes all vertices and connectivity information from the mesh.
MappedSamples mappedSamples() const
Returns the amount of mapped read and write samples in the last call to advance.
void finalize()
Finalizes preCICE.
bool requiresReadingCheckpoint()
int _executedWriteMappings
Counts the amount of samples mapped in write mappings executed in the latest advance.
void configureM2Ns(const m2n::M2NConfiguration::SharedPointer &config)
void trimReadMappedData(double timeAfterAdvance, bool isTimeWindowComplete, const cplscheme::ImplicitData &fromData)
Removes samples in mapped to data connected to received data via a mapping.
std::map< std::string, m2n::BoundM2N > _m2ns
void reinitialize()
Reinitializes preCICE.
void setupWatcher()
Setup mesh watcher such as WatchPoints.
bool isTimeWindowComplete() const
Checks if the current coupling window is completed.
void setMeshEdges(std::string_view meshName, ::precice::span< const VertexID > vertices)
Sets multiple mesh edges from vertex IDs.
std::string _configHash
The hash of the configuration file used to configure this participant.
void setupCommunication()
Connect participants including repartitioning.
bool _allowsRemeshing
Are experimental remeshing API calls allowed?
VertexID setMeshVertex(std::string_view meshName, ::precice::span< const double > position)
Creates a mesh vertex.
void syncTimestep(double computedTimeStepSize)
Syncs the time step size between all ranks (all time steps sizes should be the same!...
void readData(std::string_view meshName, std::string_view dataName, ::precice::span< const VertexID > vertices, double relativeReadTime, ::precice::span< double > values) const
Reads data values from a mesh. Values correspond to a given point in time relative to the beginning o...
const mesh::Mesh & mesh(const std::string &meshName) const
Allows to access a registered mesh.
void compareBoundingBoxes()
Communicate bounding boxes and look for overlaps.
bool _waitInFinalize
Are participants waiting for each other in finalize?
void startProfilingSection(std::string_view eventName)
void initializeIntraCommunication()
Initializes intra-participant communication.
void resetWrittenData()
Resets written data.
void trimOldDataBefore(double time)
Discards data before the given time for all meshes and data known by this participant.
void mapAndReadData(std::string_view meshName, std::string_view dataName, ::precice::span< const double > coordinates, double relativeReadTime, ::precice::span< double > values) const
Reads data values from a mesh using a just-in-time data mapping. Values correspond to a given point i...
std::unique_ptr< profiling::Event > _solverAdvanceEvent
bool requiresUserDefinedAccessRegion(std::string_view meshName) const
void configure(std::string_view configurationFileName)
Configures the coupling interface from the given xml file.
void mapWrittenData(std::optional< double > after=std::nullopt)
Computes, and performs suitable write mappings either entirely or after given time.
void initialize()
Fully initializes preCICE and coupling data.
void writeAndMapData(std::string_view meshName, std::string_view dataName, ::precice::span< const double > coordinates, ::precice::span< const double > values)
Writes data values to a mesh using a just-in-time mapping (experimental).
void computeMappings(std::vector< MappingContext > &contexts, const std::string &mappingType)
Helper for mapWrittenData and mapReadData.
int getMeshDimensions(std::string_view meshName) const
Returns the spatial dimensionality of the given mesh.
void stopLastProfilingSection()
Stores one Data object with related mesh. Context stores data to be read from and potentially provide...
bool hasSamples() const
Are there samples to read from?
void readValues(::precice::span< const VertexID > vertices, double time, ::precice::span< double > values) const
Samples data at a given point in time within the current time window for given indices.
void mapAndReadValues(::precice::span< const double > coordinates, double readTime, ::precice::span< double > values)
Forwards the just-in-time mapping API call for reading data to the data context.
Stores one Data object with related mesh. Context stores data to be written to and potentially provid...
void writeGradientsIntoDataBuffer(::precice::span< const VertexID > vertices, ::precice::span< const double > gradients)
Store gradients in _writeDataBuffer.
void writeAndMapValues(::precice::span< const double > coordinates, ::precice::span< const double > values)
Forwards the just-in-time mapping API call for writing data to the data context.
void writeValuesIntoDataBuffer(::precice::span< const VertexID > vertices, ::precice::span< const double > values)
Store values in _writeDataBuffer.
An M2N between participants with a configured direction.
Linear edge of a mesh, defined by two Vertex objects.
Container and creator for meshes.
Triangle & createTriangle(Edge &edgeOne, Edge &edgeTwo, Edge &edgeThree)
Creates and initializes a Triangle object.
int getDimensions() const
const std::string & getName() const
Returns the name of the mesh, as set in the config file.
std::size_t nVertices() const
Returns the number of vertices.
bool isValidVertexID(VertexID vertexID) const
Returns true if the given vertexID is valid.
Vertex & createVertex(const Eigen::Ref< const Eigen::VectorXd > &coords)
Creates and initializes a Vertex object.
void allocateDataValues()
Allocates memory for the vertex data values and corresponding gradient values.
A partition that is provided by the participant.
A partition that is computed from a mesh received from another participant.
static EventRegistry & instance()
Returns the only instance (singleton) of the EventRegistry class.
void startBackend()
Create the file and starts the filestream if profiling is turned on.
void initialize(std::string_view applicationName, int rank=0, int size=1)
Sets the global start time.
void finalize()
Sets the global end time and flushes buffers.
void stop()
Stops a running event.
void addData(std::string_view key, int value)
Adds named integer data, associated to an event.
A C++ 11 implementation of the non-owning C++20 std::span type.
constexpr pointer data() const noexcept
PRECICE_SPAN_NODISCARD constexpr bool empty() const noexcept
constexpr iterator begin() const noexcept
constexpr iterator end() const noexcept
constexpr size_type size() const noexcept
static void barrier()
Synchronizes all ranks.
static void allreduceSum(precice::span< const double > sendData, precice::span< double > rcvData)
static bool isPrimary()
True if this process is running the primary rank.
static void broadcast(bool &value)
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
static bool isParallel()
True if this process is running in parallel.
static bool isSecondary()
True if this process is running a secondary rank.
static com::PtrCommunication & getCommunication()
Intra-participant communication.
static void configure(Rank rank, int size)
Configures the intra-participant communication.
bool check(const K &name) const
Checks the status of a lock.
void add(Key name, bool state)
Adds a lock with a given state.
void clear() noexcept
Removes all known locks.
void lockAll() noexcept
Locks all known locks.
bool checkAll() const noexcept
Checks whether all locks are locked.
void unlock(const K &name)
Unlocks a given lock.
static void finalizeOrCleanupMPI()
Finalized a managed MPI environment or cleans up after an non-managed session.
static CommStatePtr current()
Returns an owning pointer to the current CommState.
static void initializeOrDetectMPI(std::optional< Communicator > userProvided=std::nullopt)
static void finalize()
Finalizes Petsc environment.
T current_path(T... args)
std::string errorInvalidVertexID(int vid)
static constexpr auto errorInvalidVertexIDRange
void setMPIRank(int const rank)
void setParticipant(std::string const &participant)
ConvexityResult isConvexQuad(std::array< Eigen::VectorXd, 4 > coords)
constexpr bool equals(const Eigen::MatrixBase< DerivedA > &A, const Eigen::MatrixBase< DerivedB > &B, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares two Eigen::MatrixBase for equality up to tolerance.
std::enable_if< std::is_arithmetic< Scalar >::value, bool >::type smallerEquals(Scalar A, Scalar B, Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
constexpr double NUMERICAL_ZERO_DIFFERENCE
std::enable_if< std::is_arithmetic< Scalar >::value, bool >::type greaterEquals(Scalar A, Scalar B, Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
std::enable_if< std::is_arithmetic< Scalar >::value, bool >::type greater(Scalar A, Scalar B, Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
std::array< Eigen::VectorXd, n > coordsFor(const Mesh &mesh, const std::array< int, n > &vertexIDs)
Given a mesh and an array of vertexIDS, this function returns an array of coordinates of the vertices...
std::array< Vertex *, n > vertexPtrsFor(Mesh &mesh, const std::array< int, n > &vertexIDs)
Given a mesh and an array of vertexIDS, this function returns an array of pointers to vertices.
std::size_t countVerticesInBoundingBox(mesh::PtrMesh mesh, const mesh::BoundingBox &bb)
Given a Mesh and a bounding box, counts all vertices within the bounding box.
std::shared_ptr< Partition > PtrPartition
static constexpr FundamentalTag Fundamental
Convenience instance of the FundamentalTag.
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
auto reorder_array(const std::array< Index, n > &order, const std::array< T, n > &elements) -> std::array< T, n >
Reorders an array given an array of unique indices.
bool contained(const ELEMENT_T &element, const std::vector< ELEMENT_T > &vec)
Returns true, if given element is in vector, otherwise false.
std::pair< InputIt, InputIt > find_first_range(InputIt first, InputIt last, Predicate p)
Finds the first range in [first, last[ that fulfills a predicate.
bool unique_elements(const Container &c, BinaryPredicate p={})
auto make_array(Elements &&...elements) -> std::array< typename std::common_type< Elements... >::type, sizeof...(Elements)>
Function that generates an array from given elements.
std::string configure(XMLTag &tag, const precice::xml::ConfigurationContext &context, std::string_view configurationFilename)
Configures the given configuration from file configurationFilename.
T stable_partition(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.
mapping::Mapping::MeshRequirement meshRequirement
Determines which mesh type has to be provided by the accessor.
void checkVerticesInsideAccessRegion(precice::span< const double > coordinates, const int meshDim, std::string_view functionName) const
std::shared_ptr< mesh::BoundingBox > userDefinedAccessRegion
std::vector< std::reference_wrapper< const mesh::Vertex > > filterVerticesToLocalAccessRegion(bool requiresBB) const
Tightly coupled to the parameters of Participant()