65#include "precice/impl/versions.hpp"
84 std::string_view participantName,
85 std::string_view configurationFileName,
86 int solverProcessIndex,
87 int solverProcessSize,
88 std::optional<void *> communicator)
95 "This participant's name is an empty string. "
96 "When constructing a preCICE interface you need to pass the name of the "
97 "participant as first argument to the constructor.");
100 PRECICE_CHECK(!communicator || communicator.value() !=
nullptr,
101 "Passing \"nullptr\" as \"communicator\" to Participant constructor is not allowed. "
102 "Please use the Participant constructor without the \"communicator\" argument, if you don't want to pass an MPI communicator.");
104 "The solver process index needs to be a non-negative number, not: {}. "
105 "Please check the value given when constructing a preCICE interface.",
108 "The solver process size needs to be a positive number, not: {}. "
109 "Please check the value given when constructing a preCICE interface.",
112 "The solver process index, currently: {} needs to be smaller than the solver process size, currently: {}. "
113 "Please check the values given when constructing a preCICE interface.",
122#ifndef PRECICE_NO_MPI
124 if (communicator.has_value()) {
134 "The solver process index given in the preCICE interface constructor({}) does not match the rank of the passed MPI communicator ({}).",
138 "The solver process size given in the preCICE interface constructor({}) does not match the size of the passed MPI communicator ({}).",
143 PRECICE_WARN_IF(communicator.has_value(),
"preCICE was configured without MPI but you passed an MPI communicator. preCICE ignores the communicator and continues.");
151 Event e2(
"startProfilingBackend");
173 std::string_view configurationFileName)
184 PRECICE_INFO(
"This is preCICE version {}", PRECICE_VERSION);
185 PRECICE_INFO(
"Revision info: {}", precice::preciceRevision);
186 constexpr std::string_view buildTypeStr =
"Build type: "
191#ifndef PRECICE_NO_DEBUG_LOG
194 " (without debug log)"
196#ifndef PRECICE_NO_TRACE_LOG
199#ifndef PRECICE_NO_ASSERTIONS
206 PRECICE_INFO(
"Working directory \"{}\"", std::filesystem::current_path().
string());
207 }
catch (std::filesystem::filesystem_error &fse) {
208 PRECICE_INFO(
"Working directory unknown due to error \"{}\"", fse.what());
210 PRECICE_INFO(
"Configuring preCICE with configuration \"{}\"", configurationFileName);
217 "In the preCICE configuration, only one participant is defined. "
218 "One participant makes no coupled simulation. "
219 "Please add at least another one.");
231 "A parallel participant needs an intra-participant communication");
233 "You cannot use an intra-participant communication with a serial participant. "
234 "If you do not know exactly what an intra-participant communication is and why you want to use it "
235 "you probably just want to remove the intraComm tag from the preCICE configuration.");
242 for (
const auto &variant :
_accessor->usedMeshContexts()) {
256 "Initial data has to be written to preCICE before calling initialize(). "
257 "After defining your mesh, call requiresInitialData() to check if the participant is required to write initial data using the writeData() function.");
260 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling initialize().");
265 for (
const auto &context :
_accessor->providedMeshContexts()) {
266 e.
addData(
"meshSize" + context.mesh->getName(), context.mesh->nVertices());
274 for (
auto &context :
_accessor->writeDataContexts()) {
275 const double startTime = 0.0;
276 context.storeBufferedData(startTime);
309 for (
const auto &context :
_accessor->providedMeshContexts()) {
310 e.
addData(
"meshSize" + context.mesh->getName(), context.mesh->nVertices());
326 for (
auto &context :
_accessor->providedMeshContexts()) {
327 auto &
mesh = *context.mesh;
334 PRECICE_INFO(
"Setting up primary communication to coupling partner/s");
335 Event e2(
"connectPrimaries");
336 for (
auto &m2nPair :
_m2ns) {
337 auto &bm2n = m2nPair.second;
338 bool requesting = bm2n.isRequesting;
339 if (bm2n.m2n->isConnected()) {
340 PRECICE_DEBUG(
"Primary connection {} {} already connected.", (requesting ?
"from" :
"to"), bm2n.remoteName);
342 PRECICE_DEBUG((requesting ?
"Awaiting primary connection from {}" :
"Establishing primary connection to {}"), bm2n.remoteName);
343 bm2n.prepareEstablishment();
345 PRECICE_DEBUG(
"Established primary connection {} {}", (requesting ?
"from " :
"to "), bm2n.remoteName);
352 Event e3(
"repartitioning");
356 PRECICE_INFO(
"Setting up preliminary secondary communication to coupling partner/s");
357 for (
auto &m2nPair :
_m2ns) {
358 auto &bm2n = m2nPair.second;
359 bm2n.preConnectSecondaryRanks();
365 PRECICE_INFO(
"Setting up secondary communication to coupling partner/s");
366 Event e4(
"connectSecondaries");
367 for (
auto &m2nPair :
_m2ns) {
368 auto &bm2n = m2nPair.second;
369 bm2n.connectSecondaryRanks();
370 PRECICE_DEBUG(
"Established secondary connection {} {}", (bm2n.isRequesting ?
"from " :
"to "), bm2n.remoteName);
374 for (
auto &m2nPair :
_m2ns) {
375 m2nPair.second.cleanupEstablishment();
384 watchPoint->initialize();
387 watchIntegral->initialize();
392 double computedTimeStepSize)
398 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling advance().");
413 PRECICE_CHECK(std::isfinite(computedTimeStepSize),
"advance() cannot be called with an infinite time step size.");
415 PRECICE_CHECK(computedTimeStepSize > 0.0,
"advance() cannot be called with a negative time step size {}.", computedTimeStepSize);
427 const bool isAtWindowEnd =
_couplingScheme->addComputedTime(computedTimeStepSize);
435 int sumOfChanges = std::accumulate(totalMeshChanges.begin(), totalMeshChanges.end(), 0);
454 const bool timeWindowComplete =
_couplingScheme->isTimeWindowComplete();
456 handleDataAfterAdvance(isAtWindowEnd, timeWindowComplete, timeSteppedTo, timeAfterAdvance, dataToReceive);
460 PRECICE_DEBUG(
"Mapped {} samples in write mappings and {} samples in read mappings",
491 if (reachedTimeWindowEnd) {
499 if (!reachedTimeWindowEnd) {
506 PRECICE_ASSERT(
math::greaterEquals(timeAfterAdvance, timeSteppedTo),
"We must have stayed or moved forwards in time (min-time-step-size).", timeAfterAdvance, timeSteppedTo);
517 if (reachedTimeWindowEnd) {
524 for (
auto &context :
_accessor->readDataContexts()) {
525 context.invalidateMappingCache();
529 for (
auto &context :
_accessor->writeDataContexts()) {
530 context.invalidateMappingCache();
535 for (
auto &context :
_accessor->readDataContexts()) {
536 context.resetInitialGuesses();
538 for (
auto &context :
_accessor->writeDataContexts()) {
539 context.resetInitialGuesses();
549 for (
auto &context :
_accessor->writeDataContexts()) {
566 context.completeJustInTimeMapping();
567 context.storeBufferedData(
time);
573 for (
auto &variant :
_accessor->usedMeshContexts()) {
575 for (
const auto &name :
mesh.availableData()) {
576 mesh.data(name)->waveform().trimBefore(
time);
583 for (
auto &context :
_accessor->writeDataContexts()) {
584 context.trimAfter(
time);
630#if !defined(PRECICE_NO_GINKGO) || !defined(PRECICE_NO_KOKKOS_KERNELS)
644 return _accessor->meshContext(meshName).mesh->getDimensions();
652 return _accessor->meshContext(meshName).mesh->data(dataName)->getDimensions();
675 const double nextTimeStepSize =
_couplingScheme->getNextTimeStepMaxSize();
683 "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.",
685 return nextTimeStepSize;
729 std::string_view dataName)
const
733 if (!
_accessor->isDataWrite(meshName, dataName))
741 std::string_view meshName)
const
748 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
752 if (
_accessor->isMeshReceived(meshName) &&
_accessor->isDirectAccessAllowed(meshName)) {
753 auto &receivedContext =
_accessor->receivedMeshContext(meshName);
756 PRECICE_CHECK(receivedContext.userDefinedAccessRegion,
"The function getMeshVertexSize was called on the received mesh \"{0}\", "
757 "but no access region was defined although this is necessary for parallel runs. "
758 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexSize()\".",
763 PRECICE_DEBUG(
"Filtered {} of {} vertices out on mesh {} due to the local access region. Mesh size in the access region: {}", receivedContext.mesh->nVertices() - result, receivedContext.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 _accessor->meshContext(meshName).mesh->nVertices();
777 std::string_view meshName)
780 PRECICE_CHECK(
_allowsRemeshing,
"Cannot reset meshes. This feature needs to be enabled using <precice-configuration experimental=\"1\" allow-remeshing=\"1\">.");
785 PRECICE_CHECK(
_couplingScheme->isTimeWindowComplete(),
"Cannot remesh while subcycling or iterating. Remeshing is only allowed when the time window is completed.");
794 std::string_view meshName,
802 "Cannot set vertex for mesh \"{}\". Expected {} position components but found {}.", meshName,
mesh.getDimensions(), position.
size());
804 auto index =
mesh.createVertex(Eigen::Map<const Eigen::VectorXd>{position.
data(),
mesh.getDimensions()}).getID();
805 mesh.allocateDataValues();
807 const auto newSize =
mesh.nVertices();
808 for (
auto &context :
_accessor->writeDataContexts()) {
809 if (context.getMeshName() ==
mesh.getName()) {
810 context.resizeBufferTo(newSize);
818 std::string_view meshName,
827 const auto meshDims =
mesh.getDimensions();
828 const auto expectedPositionSize = ids.
size() * meshDims;
830 "Input sizes are inconsistent attempting to set vertices on {}D mesh \"{}\". "
831 "You passed {} vertex indices and {} position components, but we expected {} position components ({} x {}).",
832 meshDims, meshName, ids.
size(), positions.
size(), expectedPositionSize, ids.
size(), meshDims);
835 const Eigen::Map<const Eigen::MatrixXd> posMatrix{
836 positions.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
837 for (
unsigned long i = 0; i < ids.
size(); ++i) {
838 ids[i] =
mesh.createVertex(posMatrix.col(i)).getID();
840 mesh.allocateDataValues();
842 const auto newSize =
mesh.nVertices();
843 for (
auto &context :
_accessor->writeDataContexts()) {
844 if (context.getMeshName() ==
mesh.getName()) {
845 context.resizeBufferTo(newSize);
851 std::string_view meshName,
869 mesh.createEdge(v0, v1);
873 std::string_view meshName,
885 "Cannot interpret passed vertex IDs attempting to set edges of mesh \"{}\" . "
886 "You passed {} vertex indices, but we expected an even number.",
887 meshName, vertices.
size());
889 auto end = vertices.
end();
891 return !mesh.isValidVertexID(vid);
895 std::distance(vertices.
begin(), first),
896 std::distance(vertices.
begin(), last));
901 for (
unsigned long i = 0; i < vertices.
size() / 2; ++i) {
902 auto aid = vertices[2 * i];
903 auto bid = vertices[2 * i + 1];
909 std::string_view meshName,
927 "setMeshTriangle() was called with repeated Vertex IDs ({}, {}, {}).",
928 first, second, third);
934 mesh.createTriangle(A, B, C);
938 std::string_view meshName,
950 "Cannot interpret passed vertex IDs attempting to set triangles of mesh \"{}\" . "
951 "You passed {} vertex indices, which isn't dividable by 3.",
952 meshName, vertices.
size());
954 auto end = vertices.
end();
956 return !mesh.isValidVertexID(vid);
960 std::distance(vertices.
begin(), first),
961 std::distance(vertices.
begin(), last));
966 for (
unsigned long i = 0; i < vertices.
size() / 3; ++i) {
967 auto aid = vertices[3 * i];
968 auto bid = vertices[3 * i + 1];
969 auto cid = vertices[3 * i + 2];
970 mesh.createTriangle(
mesh.vertex(aid),
977 std::string_view meshName,
984 second, third, fourth);
1004 "The four vertices that form the quad are not unique. The resulting shape may be a point, line or triangle. "
1005 "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.");
1008 PRECICE_CHECK(convexity.convex,
"The given quad is not convex. "
1009 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.");
1017 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1018 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1021 if (distance02 <= distance13) {
1022 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1023 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1025 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1026 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1031 std::string_view meshName,
1043 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1044 "You passed {} vertex indices, which isn't dividable by 4.",
1045 meshName, vertices.
size());
1047 auto end = vertices.
end();
1049 return !mesh.isValidVertexID(vid);
1053 std::distance(vertices.
begin(), first),
1054 std::distance(vertices.
begin(), last));
1057 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1058 auto aid = vertices[4 * i];
1059 auto bid = vertices[4 * i + 1];
1060 auto cid = vertices[4 * i + 2];
1061 auto did = vertices[4 * i + 3];
1064 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);
1068 "The four vertices that form the quad nr {} are not unique. The resulting shape may be a point, line or triangle. "
1069 "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.",
1073 PRECICE_CHECK(convexity.convex,
"The given quad nr {} is not convex. "
1074 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.",
1082 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1083 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1085 if (distance02 <= distance13) {
1086 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1087 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1089 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1090 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1096 std::string_view meshName,
1106 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1124 mesh.createTetrahedron(A, B, C, D);
1128 std::string_view meshName,
1135 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1142 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1143 "You passed {} vertex indices, which isn't dividable by 4.",
1144 meshName, vertices.
size());
1146 auto end = vertices.
end();
1148 return !mesh.isValidVertexID(vid);
1152 std::distance(vertices.
begin(), first),
1153 std::distance(vertices.
begin(), last));
1158 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1159 auto aid = vertices[4 * i];
1160 auto bid = vertices[4 * i + 1];
1161 auto cid = vertices[4 * i + 2];
1162 auto did = vertices[4 * i + 3];
1163 mesh.createTetrahedron(
mesh.vertex(aid),
1171 std::string_view meshName,
1172 std::string_view dataName,
1178 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.");
1188 const auto expectedDataSize = vertices.
size() * dataDims;
1190 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1191 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1192 dataDims, dataName, meshName,
1193 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1199 PRECICE_ERROR(
"Cannot write data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1200 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1201 dataName, meshName, *index);
1208 std::string_view meshName,
1209 std::string_view dataName,
1211 double relativeReadTime,
1218 PRECICE_CHECK(relativeReadTime >= 0,
"readData(...) cannot sample data before the current time.");
1219 PRECICE_CHECK(
isCouplingOngoing() ||
math::isZero(relativeReadTime),
"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);
1224 "Cannot read from mesh \"{}\" after it has been reset. Please read data before calling resetMesh().",
1234 "This is typically a configuration issue of the data flow. "
1235 "Check if the data is correctly exchanged to this participant \"{}\" and mapped to mesh \"{}\".",
1239 const auto expectedDataSize = vertices.
size() * dataDims;
1241 "Input/Output sizes are inconsistent attempting to read {}D data \"{}\" from mesh \"{}\". "
1242 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1243 dataDims, dataName, meshName,
1244 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1247 PRECICE_ERROR(
"Cannot read data \"{}\" from mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1248 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1249 dataName, meshName, *index);
1255 context.
readValues(vertices, readTime, values);
1259 std::string_view meshName,
1260 std::string_view dataName,
1262 double relativeReadTime,
1270 PRECICE_CHECK(relativeReadTime >= 0,
"mapAndReadData(...) cannot sample data before the current time.");
1271 PRECICE_CHECK(
isCouplingOngoing() ||
math::isZero(relativeReadTime),
"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);
1277 "This participant attempteded to map and read data (via \"mapAndReadData\") from mesh \"{0}\", "
1278 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1279 "mapAndReadData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1283 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1284 "The function \"mapAndReadData\" was called on mesh \"{0}\", "
1285 "but no access region was defined although this is necessary for parallel runs. "
1286 "Please define an access region using \"setMeshAccessRegion()\" before calling \"mapAndReadData()\".",
1289 PRECICE_CHECK(!
_accessor->receivedMeshContext(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. "
1290 "How should the provided data values be read? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1291 dataName, meshName);
1295 "The function \"mapAndReadData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1296 "Please define a mapping in read direction from the mesh \"{0}\" and omit the \"to\" attribute from the definition. "
1297 "Example \"<mapping:nearest-neighbor direction=\"read\" from=\"{0}\" constraint=\"consistent\" />",
1310 const auto nVertices = (coordinates.
size() / dim);
1313 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"mapAndReadData");
1317 "Input sizes are inconsistent attempting to mapAndRead {}D data \"{}\" from mesh \"{}\". "
1318 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1319 dataDims, dataName, meshName,
1320 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1327 std::string_view meshName,
1328 std::string_view dataName,
1336 PRECICE_CHECK(
_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.");
1342 "This participant attempteded to map and read data (via \"writeAndMapData\") from mesh \"{0}\", "
1343 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1344 "writeAndMapData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1348 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1349 "The function \"writeAndMapData\" was called on mesh \"{0}\", "
1350 "but no access region was defined although this is necessary for parallel runs. "
1351 "Please define an access region using \"setMeshAccessRegion()\" before calling \"writeAndMapData()\".",
1356 "The function \"writeAndMapData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1357 "Please define a mapping in write direction to the mesh \"{0}\" and omit the \"from\" attribute from the definition. "
1358 "Example \"<mapping:nearest-neighbor direction=\"write\" to=\"{0}\" constraint=\"conservative\" />",
1371 const auto nVertices = (coordinates.
size() / dim);
1375 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"writeAndMapData");
1378 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1379 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1380 dataDims, dataName, meshName,
1381 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1383 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. "
1384 "Where should the provided data go? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1385 dataName, meshName);
1390 std::string_view meshName,
1391 std::string_view dataName,
1411 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);
1414 PRECICE_ERROR(
"Cannot write gradient data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1415 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1416 dataName, meshName, *index);
1421 const auto gradientComponents = meshDims * dataDims;
1422 const auto expectedComponents = vertices.
size() * gradientComponents;
1424 "Input sizes are inconsistent attempting to write gradient for data \"{}\" to mesh \"{}\". "
1425 "A single gradient/Jacobian for {}D data on a {}D mesh has {} components. "
1426 "You passed {} vertex indices and {} gradient components, but we expected {} gradient components. ",
1428 dataDims, meshDims, gradientComponents,
1429 vertices.
size(), gradients.
size(), expectedComponents);
1439 const std::string_view meshName,
1445 "This participant attempteded to set an access region (via \"setMeshAccessRegion\") on mesh \"{0}\", "
1446 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1447 "setMeshAccessRegion(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1457 int dim =
mesh.getDimensions();
1459 "Incorrect amount of bounding box components attempting to set the bounding box of {}D mesh \"{}\" . "
1460 "You passed {} limits, but we expected {} ({}x2).",
1461 dim, meshName, boundingBox.
size(), dim * 2, dim);
1465 std::vector<double> bounds(dim * 2);
1467 for (
int d = 0; d < dim; ++d) {
1469 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...]");
1470 bounds[2 * d] = boundingBox[2 * d];
1471 bounds[2 * d + 1] = boundingBox[2 * d + 1];
1480 const std::string_view meshName,
1487 "This participant attempteded to get mesh vertex IDs and coordinates (via \"getMeshVertexIDsAndCoordinates\") from mesh \"{0}\", "
1488 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1489 "getMeshVertexIDsAndCoordinates(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1493 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1494 "The function \"getMeshVertexIDsAndCoordinates\" was called on mesh \"{0}\", "
1495 "but no access region was defined although this is necessary for parallel runs. "
1496 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexIDsAndCoordinates()\".",
1503 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
1514 auto filteredVertices =
_accessor->receivedMeshContext(meshName).filterVerticesToLocalAccessRegion(requiresBB);
1515 const auto meshSize = filteredVertices.size();
1518 const auto meshDims =
mesh.getDimensions();
1520 "Output size is incorrect attempting to get vertex ids of {}D mesh \"{}\". "
1521 "You passed {} vertex indices, but we expected {}. "
1522 "Use getMeshVertexSize(\"{}\") to receive the required amount of vertices.",
1523 meshDims, meshName, ids.
size(), meshSize, meshName);
1524 const auto expectedCoordinatesSize =
static_cast<unsigned long>(meshDims * meshSize);
1526 "Output size is incorrect attempting to get vertex coordinates of {}D mesh \"{}\". "
1527 "You passed {} coordinate components, but we expected {} ({}x{}). "
1528 "Use getMeshVertexSize(\"{}\") and getMeshDimensions(\"{}\") to receive the required amount components",
1529 meshDims, meshName, coordinates.
size(), expectedCoordinatesSize, meshSize, meshDims, meshName, meshName);
1531 PRECICE_ASSERT(ids.
size() <=
mesh.nVertices(),
"The queried size exceeds the number of available points.");
1533 Eigen::Map<Eigen::MatrixXd> posMatrix{
1534 coordinates.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
1536 for (
unsigned long i = 0; i < ids.
size(); i++) {
1537 auto localID = filteredVertices[i].get().getID();
1540 posMatrix.col(i) = filteredVertices[i].get().getCoords();
1547 std::sort(
_accessor->usedMeshContexts().begin(),
_accessor->usedMeshContexts().end(),
1549 return getMesh(lhs).getName() < getMesh(rhs).getName();
1553 for (
auto &context :
_accessor->providedMeshContexts()) {
1554 context.mesh->computeBoundingBox();
1558 for (
auto &variant :
_accessor->usedMeshContexts()) {
1563 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1574 auto &contexts =
_accessor->usedMeshContexts();
1576 std::sort(contexts.begin(), contexts.end(),
1578 return getMesh(lhs).getName() < getMesh(rhs).getName();
1581 for (
const auto &variant : contexts) {
1589 for (
auto &m2nPair :
_m2ns) {
1590 if (m2nPair.second.m2n->usesTwoLevelInitialization()) {
1598 std::stable_partition(contexts.begin(), contexts.end(),
1600 return std::holds_alternative<ProvidedMeshContext *>(variant);
1604 for (
const auto &variant : contexts) {
1609 if (std::holds_alternative<ReceivedMeshContext *>(variant)) {
1610 mesh.computeBoundingBox();
1613 mesh.allocateDataValues();
1616 const auto requiredSize =
mesh.nVertices();
1617 for (
auto &context :
_accessor->writeDataContexts()) {
1618 if (context.getMeshName() ==
mesh.getName()) {
1619 context.resizeBufferTo(requiredSize, std::holds_alternative<ReceivedMeshContext *>(variant));
1628 bool anyMappingChanged =
false;
1630 if (not context.mapping->hasComputedMapping()) {
1632 "Automatic RBF mapping alias from mesh \"{}\" to mesh \"{}\" in \"{}\" direction resolves to \"{}\" .",
1633 context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType, context.mapping->getName());
1634 PRECICE_INFO(
"Computing \"{}\" mapping from mesh \"{}\" to mesh \"{}\" in \"{}\" direction.",
1635 context.mapping->getName(), context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType);
1636 context.mapping->computeMapping();
1637 anyMappingChanged =
true;
1640 if (anyMappingChanged) {
1641 _accessor->initializeMappingDataCache(mappingType);
1654 for (
auto &context :
_accessor->writeDataContexts()) {
1655 if (context.hasMapping()) {
1656 PRECICE_DEBUG(
"Map initial write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1671 for (
auto &context :
_accessor->writeDataContexts()) {
1672 if (context.hasMapping()) {
1673 PRECICE_DEBUG(
"Map write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1682 for (
auto &context :
_accessor->readDataContexts()) {
1683 if (context.hasMapping()) {
1688 context.clearToDataFor(fromData);
1690 context.trimToDataAfterFor(fromData, startOfTimeWindow);
1705 for (
auto &context :
_accessor->readDataContexts()) {
1706 if (context.hasMapping()) {
1707 PRECICE_DEBUG(
"Map initial read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1723 for (
auto &context :
_accessor->readDataContexts()) {
1724 if (context.hasMapping()) {
1725 PRECICE_DEBUG(
"Map read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1736 if (timings.find(
action->getTiming()) != timings.end()) {
1768 for (
auto &context :
_accessor->writeDataContexts()) {
1770 context.resetBufferedData();
1777 const auto &partConfig = *
config.getParticipantConfiguration();
1779 "This participant's name, which was specified in the constructor of the preCICE interface as \"{}\", "
1780 "is not defined in the preCICE configuration. "
1781 "Please double-check the correct spelling.",
1809 "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 {}.",
1810 secondaryRank, dt, computedTimeStepSize);
1820 std::vector<MeshID> localChanges;
1822 [[maybe_unused]]
auto remoteChanges1 =
_couplingScheme->firstSynchronization(localChanges);
1825 [[maybe_unused]]
auto remoteChanges2 =
_couplingScheme->secondSynchronization();
1836 std::string ping =
"ping";
1837 std::string pong =
"pong";
1838 for (
auto &iter :
_m2ns) {
1839 auto bm2n = iter.second;
1840 if (!bm2n.m2n->isConnected()) {
1841 PRECICE_DEBUG(
"Skipping closure of defective connection with {}", bm2n.remoteName);
1845 auto comm = bm2n.m2n->getPrimaryRankCommunication();
1846 PRECICE_DEBUG(
"Synchronizing primary rank with {}", bm2n.remoteName);
1847 if (bm2n.isRequesting) {
1848 comm->send(ping, 0);
1849 std::string receive =
"init";
1850 comm->receive(receive, 0);
1853 std::string receive =
"init";
1854 comm->receive(receive, 0);
1856 comm->send(pong, 0);
1860 PRECICE_DEBUG(
"Closing distributed communication with {}", bm2n.remoteName);
1861 bm2n.m2n->closeDistributedConnections();
1863 PRECICE_DEBUG(
"Closing communication with {}", bm2n.remoteName);
1864 bm2n.m2n->closeConnection();
1877 return *
_accessor->meshContext(meshName).mesh;
1897 std::vector<double> localMeshChanges;
1898 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1899 localMeshChanges.push_back(
_meshLock.check(
getMesh(variant).getName()) ? 0.0 : 1.0);
1901 PRECICE_DEBUG(
"Mesh changes of rank: {}", localMeshChanges);
1904 std::vector<double> totalMeshChanges(localMeshChanges.size(), 0.0);
1908 MeshChanges totalMeshChangesInt(totalMeshChanges.begin(), totalMeshChanges.end());
1909 PRECICE_DEBUG(
"Mesh changes of participant: {}", totalMeshChangesInt);
1910 return totalMeshChangesInt;
1917 for (
auto &variant :
_accessor->usedMeshContexts()) {
1918 if (totalMeshChanges[i] > 0.0) {
1930 bool swarmReinitRequired =
false;
1933 PRECICE_DEBUG(
"Remeshing is{} required by this participant.", (requestReinit ?
"" :
" not"));
1935 swarmReinitRequired = requestReinit;
1936 for (
auto &iter :
_m2ns) {
1937 PRECICE_DEBUG(
"Coordinating remeshing with {}", iter.first);
1938 bool received =
false;
1939 auto &comm = *iter.second.m2n->getPrimaryRankCommunication();
1940 if (iter.second.isRequesting) {
1941 comm.send(requestReinit, 0);
1942 comm.receive(received, 0);
1944 comm.receive(received, 0);
1945 comm.send(requestReinit, 0);
1947 swarmReinitRequired |= received;
1949 PRECICE_DEBUG(
"Coordinated that overall{} remeshing is required.", (swarmReinitRequired ?
"" :
" no"));
1954 return swarmReinitRequired;
1959 PRECICE_CHECK(std::find(sectionName.begin(), sectionName.end(),
'/') == sectionName.end(),
1960 "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(...)
int getDimensions() const
void clear()
Removes all mesh elements and data values (does not remove data or the bounding boxes).
const std::string & getName() const
Returns the name of the mesh, as set in the config file.
bool empty() const
Does the mesh contain any vertices?
Main class for preCICE XML configuration tree.
@ 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 hasJustInTimeMapping() const
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
std::deque< profiling::Event > _userEvents
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.
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()
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)
std::vector< int > MeshChanges
How many ranks have changed each used 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 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.
Container and creator for meshes.
void clearDataStamples()
Clears all data stamples.
virtual void compareBoundingBoxes()=0
Intersections between bounding boxes around each rank are computed.
virtual void compute()=0
The partition is computed, i.e. the mesh re-partitioned if required and all data structures are set u...
virtual void communicate()=0
The mesh is communicated between both primary ranks (if required).
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.
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.
contains actions to modify exchanged data.
std::unique_ptr< Action > PtrAction
std::shared_ptr< WatchPoint > PtrWatchPoint
std::string errorInvalidVertexID(int vid)
std::variant< ProvidedMeshContext *, ReceivedMeshContext * > MeshContextVariant
Type alias for variant holding either provided or received mesh context pointers.
static constexpr auto errorInvalidVertexIDRange
std::shared_ptr< ParticipantState > PtrParticipant
MeshContext * getMeshContext(const MeshContextVariant &variant)
Helper to extract base MeshContext pointer from variant.
partition::Partition & getPartition(const MeshContextVariant &variant)
Helper to extract partition from variant.
mesh::Mesh & getMesh(const MeshContextVariant &variant)
Helper to extract mesh from variant.
std::shared_ptr< WatchIntegral > PtrWatchIntegral
void setMPIRank(int const rank)
void setParticipant(std::string const &participant)
ConvexityResult isConvexQuad(std::array< Eigen::VectorXd, 4 > coords)
bool smallerEquals(double a, double b, double tolerance=NUMERICAL_ZERO_DIFFERENCE) noexcept
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.
bool greaterEquals(double a, double b, double tolerance=NUMERICAL_ZERO_DIFFERENCE) noexcept
bool greater(double a, double b, double tolerance=NUMERICAL_ZERO_DIFFERENCE) noexcept
constexpr double NUMERICAL_ZERO_DIFFERENCE
bool isZero(double a, double tolerance=NUMERICAL_ZERO_DIFFERENCE) noexcept
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.
static constexpr Group API
Convenience instance of the Cat::API.
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
static constexpr Group Fundamental
Convenience instance of the Cat::Fundamental.
contains the time interpolation logic.
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.
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.
Holds a data mapping and related information.
mesh::PtrMesh mesh
Mesh holding the geometry data structure.
mapping::Mapping::MeshRequirement meshRequirement
Determines which mesh type has to be provided by the accessor.
Context for a mesh provided by this participant.
Context for a mesh received from another participant.
std::shared_ptr< mesh::BoundingBox > userDefinedAccessRegion
Tightly coupled to the parameters of Participant().