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);
434 int sumOfChanges = std::accumulate(totalMeshChanges.begin(), totalMeshChanges.end(), 0);
452 const bool timeWindowComplete =
_couplingScheme->isTimeWindowComplete();
454 handleDataAfterAdvance(isAtWindowEnd, timeWindowComplete, timeSteppedTo, timeAfterAdvance, dataToReceive);
458 PRECICE_DEBUG(
"Mapped {} samples in write mappings and {} samples in read mappings",
489 if (reachedTimeWindowEnd) {
497 if (!reachedTimeWindowEnd) {
504 PRECICE_ASSERT(
math::greaterEquals(timeAfterAdvance, timeSteppedTo),
"We must have stayed or moved forwards in time (min-time-step-size).", timeAfterAdvance, timeSteppedTo);
515 if (reachedTimeWindowEnd) {
522 for (
auto &context :
_accessor->readDataContexts()) {
523 context.invalidateMappingCache();
527 for (
auto &context :
_accessor->writeDataContexts()) {
528 context.invalidateMappingCache();
533 for (
auto &context :
_accessor->readDataContexts()) {
534 context.resetInitialGuesses();
536 for (
auto &context :
_accessor->writeDataContexts()) {
537 context.resetInitialGuesses();
547 for (
auto &context :
_accessor->writeDataContexts()) {
564 context.completeJustInTimeMapping();
565 context.storeBufferedData(
time);
571 for (
auto &variant :
_accessor->usedMeshContexts()) {
573 for (
const auto &name :
mesh.availableData()) {
574 mesh.data(name)->waveform().trimBefore(
time);
581 for (
auto &context :
_accessor->writeDataContexts()) {
582 context.trimAfter(
time);
628#if !defined(PRECICE_NO_GINKGO) || !defined(PRECICE_NO_KOKKOS_KERNELS)
642 return _accessor->meshContext(meshName).mesh->getDimensions();
650 return _accessor->meshContext(meshName).mesh->data(dataName)->getDimensions();
673 const double nextTimeStepSize =
_couplingScheme->getNextTimeStepMaxSize();
681 "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.",
683 return nextTimeStepSize;
727 std::string_view dataName)
const
731 if (!
_accessor->isDataWrite(meshName, dataName))
739 std::string_view meshName)
const
746 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
750 if (
_accessor->isMeshReceived(meshName) &&
_accessor->isDirectAccessAllowed(meshName)) {
751 auto &receivedContext =
_accessor->receivedMeshContext(meshName);
754 PRECICE_CHECK(receivedContext.userDefinedAccessRegion,
"The function getMeshVertexSize was called on the received mesh \"{0}\", "
755 "but no access region was defined although this is necessary for parallel runs. "
756 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexSize()\".",
761 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);
767 "You are calling \"getMeshVertexSize()\" on a received mesh without api-access enabled (<receive-mesh name=\"{0}\" ... api-access=\"false\"/>). "
768 "Note that enabling api-access is required for this function to work properly with direct mesh access and just-in-time mappings.",
770 return _accessor->meshContext(meshName).mesh->nVertices();
775 std::string_view meshName)
778 PRECICE_CHECK(
_allowsRemeshing,
"Cannot reset meshes. This feature needs to be enabled using <precice-configuration experimental=\"1\" allow-remeshing=\"1\">.");
783 PRECICE_CHECK(
_couplingScheme->isTimeWindowComplete(),
"Cannot remesh while subcycling or iterating. Remeshing is only allowed when the time window is completed.");
792 std::string_view meshName,
800 "Cannot set vertex for mesh \"{}\". Expected {} position components but found {}.", meshName,
mesh.getDimensions(), position.
size());
802 auto index =
mesh.createVertex(Eigen::Map<const Eigen::VectorXd>{position.
data(),
mesh.getDimensions()}).getID();
803 mesh.allocateDataValues();
805 const auto newSize =
mesh.nVertices();
806 for (
auto &context :
_accessor->writeDataContexts()) {
807 if (context.getMeshName() ==
mesh.getName()) {
808 context.resizeBufferTo(newSize);
816 std::string_view meshName,
825 const auto meshDims =
mesh.getDimensions();
826 const auto expectedPositionSize = ids.
size() * meshDims;
828 "Input sizes are inconsistent attempting to set vertices on {}D mesh \"{}\". "
829 "You passed {} vertex indices and {} position components, but we expected {} position components ({} x {}).",
830 meshDims, meshName, ids.
size(), positions.
size(), expectedPositionSize, ids.
size(), meshDims);
833 const Eigen::Map<const Eigen::MatrixXd> posMatrix{
834 positions.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
835 for (
unsigned long i = 0; i < ids.
size(); ++i) {
836 ids[i] =
mesh.createVertex(posMatrix.col(i)).getID();
838 mesh.allocateDataValues();
840 const auto newSize =
mesh.nVertices();
841 for (
auto &context :
_accessor->writeDataContexts()) {
842 if (context.getMeshName() ==
mesh.getName()) {
843 context.resizeBufferTo(newSize);
849 std::string_view meshName,
867 mesh.createEdge(v0, v1);
871 std::string_view meshName,
883 "Cannot interpret passed vertex IDs attempting to set edges of mesh \"{}\" . "
884 "You passed {} vertex indices, but we expected an even number.",
885 meshName, vertices.
size());
887 auto end = vertices.
end();
889 return !mesh.isValidVertexID(vid);
893 std::distance(vertices.
begin(), first),
894 std::distance(vertices.
begin(), last));
899 for (
unsigned long i = 0; i < vertices.
size() / 2; ++i) {
900 auto aid = vertices[2 * i];
901 auto bid = vertices[2 * i + 1];
907 std::string_view meshName,
925 "setMeshTriangle() was called with repeated Vertex IDs ({}, {}, {}).",
926 first, second, third);
932 mesh.createTriangle(A, B, C);
936 std::string_view meshName,
948 "Cannot interpret passed vertex IDs attempting to set triangles of mesh \"{}\" . "
949 "You passed {} vertex indices, which isn't dividable by 3.",
950 meshName, vertices.
size());
952 auto end = vertices.
end();
954 return !mesh.isValidVertexID(vid);
958 std::distance(vertices.
begin(), first),
959 std::distance(vertices.
begin(), last));
964 for (
unsigned long i = 0; i < vertices.
size() / 3; ++i) {
965 auto aid = vertices[3 * i];
966 auto bid = vertices[3 * i + 1];
967 auto cid = vertices[3 * i + 2];
968 mesh.createTriangle(
mesh.vertex(aid),
975 std::string_view meshName,
982 second, third, fourth);
1002 "The four vertices that form the quad are not unique. The resulting shape may be a point, line or triangle. "
1003 "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.");
1006 PRECICE_CHECK(convexity.convex,
"The given quad is not convex. "
1007 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.");
1015 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1016 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1019 if (distance02 <= distance13) {
1020 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1021 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1023 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1024 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1029 std::string_view meshName,
1041 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1042 "You passed {} vertex indices, which isn't dividable by 4.",
1043 meshName, vertices.
size());
1045 auto end = vertices.
end();
1047 return !mesh.isValidVertexID(vid);
1051 std::distance(vertices.
begin(), first),
1052 std::distance(vertices.
begin(), last));
1055 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1056 auto aid = vertices[4 * i];
1057 auto bid = vertices[4 * i + 1];
1058 auto cid = vertices[4 * i + 2];
1059 auto did = vertices[4 * i + 3];
1062 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);
1066 "The four vertices that form the quad nr {} are not unique. The resulting shape may be a point, line or triangle. "
1067 "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.",
1071 PRECICE_CHECK(convexity.convex,
"The given quad nr {} is not convex. "
1072 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.",
1080 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1081 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1083 if (distance02 <= distance13) {
1084 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1085 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1087 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1088 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1094 std::string_view meshName,
1104 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1122 mesh.createTetrahedron(A, B, C, D);
1126 std::string_view meshName,
1133 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1140 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1141 "You passed {} vertex indices, which isn't dividable by 4.",
1142 meshName, vertices.
size());
1144 auto end = vertices.
end();
1146 return !mesh.isValidVertexID(vid);
1150 std::distance(vertices.
begin(), first),
1151 std::distance(vertices.
begin(), last));
1156 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1157 auto aid = vertices[4 * i];
1158 auto bid = vertices[4 * i + 1];
1159 auto cid = vertices[4 * i + 2];
1160 auto did = vertices[4 * i + 3];
1161 mesh.createTetrahedron(
mesh.vertex(aid),
1169 std::string_view meshName,
1170 std::string_view dataName,
1176 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.");
1186 const auto expectedDataSize = vertices.
size() * dataDims;
1188 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1189 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1190 dataDims, dataName, meshName,
1191 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1197 PRECICE_ERROR(
"Cannot write data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1198 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1199 dataName, meshName, *index);
1206 std::string_view meshName,
1207 std::string_view dataName,
1209 double relativeReadTime,
1216 PRECICE_CHECK(relativeReadTime >= 0,
"readData(...) cannot sample data before the current time.");
1217 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);
1222 "Cannot read from mesh \"{}\" after it has been reset. Please read data before calling resetMesh().",
1232 "This is typically a configuration issue of the data flow. "
1233 "Check if the data is correctly exchanged to this participant \"{}\" and mapped to mesh \"{}\".",
1237 const auto expectedDataSize = vertices.
size() * dataDims;
1239 "Input/Output sizes are inconsistent attempting to read {}D data \"{}\" from mesh \"{}\". "
1240 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1241 dataDims, dataName, meshName,
1242 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1245 PRECICE_ERROR(
"Cannot read data \"{}\" from mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1246 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1247 dataName, meshName, *index);
1253 context.
readValues(vertices, readTime, values);
1257 std::string_view meshName,
1258 std::string_view dataName,
1260 double relativeReadTime,
1268 PRECICE_CHECK(relativeReadTime >= 0,
"mapAndReadData(...) cannot sample data before the current time.");
1269 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);
1275 "This participant attempteded to map and read data (via \"mapAndReadData\") from mesh \"{0}\", "
1276 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1277 "mapAndReadData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1281 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1282 "The function \"mapAndReadData\" was called on mesh \"{0}\", "
1283 "but no access region was defined although this is necessary for parallel runs. "
1284 "Please define an access region using \"setMeshAccessRegion()\" before calling \"mapAndReadData()\".",
1287 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. "
1288 "How should the provided data values be read? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1289 dataName, meshName);
1293 "The function \"mapAndReadData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1294 "Please define a mapping in read direction from the mesh \"{0}\" and omit the \"to\" attribute from the definition. "
1295 "Example \"<mapping:nearest-neighbor direction=\"read\" from=\"{0}\" constraint=\"consistent\" />",
1308 const auto nVertices = (coordinates.
size() / dim);
1311 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"mapAndReadData");
1315 "Input sizes are inconsistent attempting to mapAndRead {}D data \"{}\" from mesh \"{}\". "
1316 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1317 dataDims, dataName, meshName,
1318 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1325 std::string_view meshName,
1326 std::string_view dataName,
1334 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.");
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\"/>).",
1346 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
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()\".",
1354 "The function \"writeAndMapData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1355 "Please define a mapping in write direction to the mesh \"{0}\" and omit the \"from\" attribute from the definition. "
1356 "Example \"<mapping:nearest-neighbor direction=\"write\" to=\"{0}\" constraint=\"conservative\" />",
1369 const auto nVertices = (coordinates.
size() / dim);
1373 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"writeAndMapData");
1376 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1377 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1378 dataDims, dataName, meshName,
1379 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1381 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. "
1382 "Where should the provided data go? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1383 dataName, meshName);
1388 std::string_view meshName,
1389 std::string_view dataName,
1409 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);
1412 PRECICE_ERROR(
"Cannot write gradient data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1413 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1414 dataName, meshName, *index);
1419 const auto gradientComponents = meshDims * dataDims;
1420 const auto expectedComponents = vertices.
size() * gradientComponents;
1422 "Input sizes are inconsistent attempting to write gradient for data \"{}\" to mesh \"{}\". "
1423 "A single gradient/Jacobian for {}D data on a {}D mesh has {} components. "
1424 "You passed {} vertex indices and {} gradient components, but we expected {} gradient components. ",
1426 dataDims, meshDims, gradientComponents,
1427 vertices.
size(), gradients.
size(), expectedComponents);
1437 const std::string_view meshName,
1443 "This participant attempteded to set an access region (via \"setMeshAccessRegion\") on mesh \"{0}\", "
1444 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1445 "setMeshAccessRegion(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1455 int dim =
mesh.getDimensions();
1457 "Incorrect amount of bounding box components attempting to set the bounding box of {}D mesh \"{}\" . "
1458 "You passed {} limits, but we expected {} ({}x2).",
1459 dim, meshName, boundingBox.
size(), dim * 2, dim);
1463 std::vector<double> bounds(dim * 2);
1465 for (
int d = 0; d < dim; ++d) {
1467 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...]");
1468 bounds[2 * d] = boundingBox[2 * d];
1469 bounds[2 * d + 1] = boundingBox[2 * d + 1];
1478 const std::string_view meshName,
1485 "This participant attempteded to get mesh vertex IDs and coordinates (via \"getMeshVertexIDsAndCoordinates\") from mesh \"{0}\", "
1486 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1487 "getMeshVertexIDsAndCoordinates(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1491 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1492 "The function \"getMeshVertexIDsAndCoordinates\" was called on mesh \"{0}\", "
1493 "but no access region was defined although this is necessary for parallel runs. "
1494 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexIDsAndCoordinates()\".",
1501 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
1512 auto filteredVertices =
_accessor->receivedMeshContext(meshName).filterVerticesToLocalAccessRegion(requiresBB);
1513 const auto meshSize = filteredVertices.size();
1516 const auto meshDims =
mesh.getDimensions();
1518 "Output size is incorrect attempting to get vertex ids of {}D mesh \"{}\". "
1519 "You passed {} vertex indices, but we expected {}. "
1520 "Use getMeshVertexSize(\"{}\") to receive the required amount of vertices.",
1521 meshDims, meshName, ids.
size(), meshSize, meshName);
1522 const auto expectedCoordinatesSize =
static_cast<unsigned long>(meshDims * meshSize);
1524 "Output size is incorrect attempting to get vertex coordinates of {}D mesh \"{}\". "
1525 "You passed {} coordinate components, but we expected {} ({}x{}). "
1526 "Use getMeshVertexSize(\"{}\") and getMeshDimensions(\"{}\") to receive the required amount components",
1527 meshDims, meshName, coordinates.
size(), expectedCoordinatesSize, meshSize, meshDims, meshName, meshName);
1529 PRECICE_ASSERT(ids.
size() <=
mesh.nVertices(),
"The queried size exceeds the number of available points.");
1531 Eigen::Map<Eigen::MatrixXd> posMatrix{
1532 coordinates.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
1534 for (
unsigned long i = 0; i < ids.
size(); i++) {
1535 auto localID = filteredVertices[i].get().getID();
1538 posMatrix.col(i) = filteredVertices[i].get().getCoords();
1545 std::sort(
_accessor->usedMeshContexts().begin(),
_accessor->usedMeshContexts().end(),
1547 return getMesh(lhs).getName() < getMesh(rhs).getName();
1551 for (
auto &context :
_accessor->providedMeshContexts()) {
1552 context.mesh->computeBoundingBox();
1556 for (
auto &variant :
_accessor->usedMeshContexts()) {
1561 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1572 auto &contexts =
_accessor->usedMeshContexts();
1574 std::sort(contexts.begin(), contexts.end(),
1576 return getMesh(lhs).getName() < getMesh(rhs).getName();
1579 for (
const auto &variant : contexts) {
1587 for (
auto &m2nPair :
_m2ns) {
1588 if (m2nPair.second.m2n->usesTwoLevelInitialization()) {
1596 std::stable_partition(contexts.begin(), contexts.end(),
1598 return std::holds_alternative<ProvidedMeshContext *>(variant);
1602 for (
const auto &variant : contexts) {
1607 if (std::holds_alternative<ReceivedMeshContext *>(variant)) {
1608 mesh.computeBoundingBox();
1611 mesh.allocateDataValues();
1614 const auto requiredSize =
mesh.nVertices();
1615 for (
auto &context :
_accessor->writeDataContexts()) {
1616 if (context.getMeshName() ==
mesh.getName()) {
1617 context.resizeBufferTo(requiredSize, std::holds_alternative<ReceivedMeshContext *>(variant));
1626 bool anyMappingChanged =
false;
1628 if (not context.mapping->hasComputedMapping()) {
1630 "Automatic RBF mapping alias from mesh \"{}\" to mesh \"{}\" in \"{}\" direction resolves to \"{}\" .",
1631 context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType, context.mapping->getName());
1632 PRECICE_INFO(
"Computing \"{}\" mapping from mesh \"{}\" to mesh \"{}\" in \"{}\" direction.",
1633 context.mapping->getName(), context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType);
1634 context.mapping->computeMapping();
1635 anyMappingChanged =
true;
1638 if (anyMappingChanged) {
1639 _accessor->initializeMappingDataCache(mappingType);
1652 for (
auto &context :
_accessor->writeDataContexts()) {
1653 if (context.hasMapping()) {
1654 PRECICE_DEBUG(
"Map initial write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1669 for (
auto &context :
_accessor->writeDataContexts()) {
1670 if (context.hasMapping()) {
1671 PRECICE_DEBUG(
"Map write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1680 for (
auto &context :
_accessor->readDataContexts()) {
1681 if (context.hasMapping()) {
1686 context.clearToDataFor(fromData);
1688 context.trimToDataAfterFor(fromData, startOfTimeWindow);
1703 for (
auto &context :
_accessor->readDataContexts()) {
1704 if (context.hasMapping()) {
1705 PRECICE_DEBUG(
"Map initial read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1721 for (
auto &context :
_accessor->readDataContexts()) {
1722 if (context.hasMapping()) {
1723 PRECICE_DEBUG(
"Map read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1734 if (timings.find(
action->getTiming()) != timings.end()) {
1766 for (
auto &context :
_accessor->writeDataContexts()) {
1768 context.resetBufferedData();
1775 const auto &partConfig = *
config.getParticipantConfiguration();
1777 "This participant's name, which was specified in the constructor of the preCICE interface as \"{}\", "
1778 "is not defined in the preCICE configuration. "
1779 "Please double-check the correct spelling.",
1807 "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 {}.",
1808 secondaryRank, dt, computedTimeStepSize);
1818 std::vector<MeshID> localChanges;
1820 [[maybe_unused]]
auto remoteChanges1 =
_couplingScheme->firstSynchronization(localChanges);
1823 [[maybe_unused]]
auto remoteChanges2 =
_couplingScheme->secondSynchronization();
1834 std::string ping =
"ping";
1835 std::string pong =
"pong";
1836 for (
auto &iter :
_m2ns) {
1837 auto bm2n = iter.second;
1838 if (!bm2n.m2n->isConnected()) {
1839 PRECICE_DEBUG(
"Skipping closure of defective connection with {}", bm2n.remoteName);
1843 auto comm = bm2n.m2n->getPrimaryRankCommunication();
1844 PRECICE_DEBUG(
"Synchronizing primary rank with {}", bm2n.remoteName);
1845 if (bm2n.isRequesting) {
1846 comm->send(ping, 0);
1847 std::string receive =
"init";
1848 comm->receive(receive, 0);
1851 std::string receive =
"init";
1852 comm->receive(receive, 0);
1854 comm->send(pong, 0);
1858 PRECICE_DEBUG(
"Closing distributed communication with {}", bm2n.remoteName);
1859 bm2n.m2n->closeDistributedConnections();
1861 PRECICE_DEBUG(
"Closing communication with {}", bm2n.remoteName);
1862 bm2n.m2n->closeConnection();
1875 return *
_accessor->meshContext(meshName).mesh;
1895 std::vector<double> localMeshChanges;
1896 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1897 localMeshChanges.push_back(
_meshLock.check(
getMesh(variant).getName()) ? 0.0 : 1.0);
1899 PRECICE_DEBUG(
"Mesh changes of rank: {}", localMeshChanges);
1902 std::vector<double> totalMeshChanges(localMeshChanges.size(), 0.0);
1906 MeshChanges totalMeshChangesInt(totalMeshChanges.begin(), totalMeshChanges.end());
1907 PRECICE_DEBUG(
"Mesh changes of participant: {}", totalMeshChangesInt);
1908 return totalMeshChangesInt;
1915 for (
auto &variant :
_accessor->usedMeshContexts()) {
1916 if (totalMeshChanges[i] > 0.0) {
1930 PRECICE_DEBUG(
"Remeshing is{} required by this participant.", (requestReinit ?
"" :
" not"));
1932 bool swarmReinitRequired = requestReinit;
1933 for (
auto &iter :
_m2ns) {
1934 PRECICE_DEBUG(
"Coordinating remeshing with {}", iter.first);
1935 bool received =
false;
1936 auto &comm = *iter.second.m2n->getPrimaryRankCommunication();
1937 if (iter.second.isRequesting) {
1938 comm.send(requestReinit, 0);
1939 comm.receive(received, 0);
1941 comm.receive(received, 0);
1942 comm.send(requestReinit, 0);
1944 swarmReinitRequired |= received;
1946 PRECICE_DEBUG(
"Coordinated that overall{} remeshing is required.", (swarmReinitRequired ?
"" :
" no"));
1949 return swarmReinitRequired;
1951 bool swarmReinitRequired =
false;
1953 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)
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.
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().