66#include "precice/impl/versions.hpp"
85 std::string_view participantName,
86 std::string_view configurationFileName,
87 int solverProcessIndex,
88 int solverProcessSize,
89 std::optional<void *> communicator)
96 "This participant's name is an empty string. "
97 "When constructing a preCICE interface you need to pass the name of the "
98 "participant as first argument to the constructor.");
101 PRECICE_CHECK(!communicator || communicator.value() !=
nullptr,
102 "Passing \"nullptr\" as \"communicator\" to Participant constructor is not allowed. "
103 "Please use the Participant constructor without the \"communicator\" argument, if you don't want to pass an MPI communicator.");
105 "The solver process index needs to be a non-negative number, not: {}. "
106 "Please check the value given when constructing a preCICE interface.",
109 "The solver process size needs to be a positive number, not: {}. "
110 "Please check the value given when constructing a preCICE interface.",
113 "The solver process index, currently: {} needs to be smaller than the solver process size, currently: {}. "
114 "Please check the values given when constructing a preCICE interface.",
123#ifndef PRECICE_NO_MPI
125 if (communicator.has_value()) {
135 "The solver process index given in the preCICE interface constructor({}) does not match the rank of the passed MPI communicator ({}).",
139 "The solver process size given in the preCICE interface constructor({}) does not match the size of the passed MPI communicator ({}).",
144 PRECICE_WARN_IF(communicator.has_value(),
"preCICE was configured without MPI but you passed an MPI communicator. preCICE ignores the communicator and continues.");
152 Event e2(
"startProfilingBackend");
174 std::string_view configurationFileName)
185 PRECICE_INFO(
"This is preCICE version {}", PRECICE_VERSION);
186 PRECICE_INFO(
"Revision info: {}", precice::preciceRevision);
187 constexpr std::string_view buildTypeStr =
"Build type: "
192#ifndef PRECICE_NO_DEBUG_LOG
195 " (without debug log)"
197#ifndef PRECICE_NO_TRACE_LOG
200#ifndef PRECICE_NO_ASSERTIONS
207 PRECICE_INFO(
"Working directory \"{}\"", std::filesystem::current_path().
string());
208 }
catch (std::filesystem::filesystem_error &fse) {
209 PRECICE_INFO(
"Working directory unknown due to error \"{}\"", fse.what());
211 PRECICE_INFO(
"Configuring preCICE with configuration \"{}\"", configurationFileName);
218 "In the preCICE configuration, only one participant is defined. "
219 "One participant makes no coupled simulation. "
220 "Please add at least another one.");
232 "A parallel participant needs an intra-participant communication");
234 "You cannot use an intra-participant communication with a serial participant. "
235 "If you do not know exactly what an intra-participant communication is and why you want to use it "
236 "you probably just want to remove the intraComm tag from the preCICE configuration.");
243 for (
const auto &variant :
_accessor->usedMeshContexts()) {
257 "Initial data has to be written to preCICE before calling initialize(). "
258 "After defining your mesh, call requiresInitialData() to check if the participant is required to write initial data using the writeData() function.");
261 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling initialize().");
266 for (
const auto &context :
_accessor->providedMeshContexts()) {
267 e.
addData(
"meshSize" + context.mesh->getName(), context.mesh->nVertices());
275 for (
auto &context :
_accessor->writeDataContexts()) {
276 const double startTime = 0.0;
277 context.storeBufferedData(startTime);
310 for (
const auto &context :
_accessor->providedMeshContexts()) {
311 e.
addData(
"meshSize" + context.mesh->getName(), context.mesh->nVertices());
327 for (
auto &context :
_accessor->providedMeshContexts()) {
328 auto &
mesh = *context.mesh;
335 PRECICE_INFO(
"Setting up primary communication to coupling partner/s");
336 Event e2(
"connectPrimaries");
337 for (
auto &m2nPair :
_m2ns) {
338 auto &bm2n = m2nPair.second;
339 bool requesting = bm2n.isRequesting;
340 if (bm2n.m2n->isConnected()) {
341 PRECICE_DEBUG(
"Primary connection {} {} already connected.", (requesting ?
"from" :
"to"), bm2n.remoteName);
343 PRECICE_DEBUG((requesting ?
"Awaiting primary connection from {}" :
"Establishing primary connection to {}"), bm2n.remoteName);
344 bm2n.prepareEstablishment();
346 PRECICE_DEBUG(
"Established primary connection {} {}", (requesting ?
"from " :
"to "), bm2n.remoteName);
353 Event e3(
"repartitioning");
357 PRECICE_INFO(
"Setting up preliminary secondary communication to coupling partner/s");
358 for (
auto &m2nPair :
_m2ns) {
359 auto &bm2n = m2nPair.second;
360 bm2n.preConnectSecondaryRanks();
366 PRECICE_INFO(
"Setting up secondary communication to coupling partner/s");
367 Event e4(
"connectSecondaries");
368 for (
auto &m2nPair :
_m2ns) {
369 auto &bm2n = m2nPair.second;
370 bm2n.connectSecondaryRanks();
371 PRECICE_DEBUG(
"Established secondary connection {} {}", (bm2n.isRequesting ?
"from " :
"to "), bm2n.remoteName);
375 for (
auto &m2nPair :
_m2ns) {
376 m2nPair.second.cleanupEstablishment();
385 watchPoint->initialize();
388 watchIntegral->initialize();
393 double computedTimeStepSize)
399 PRECICE_CHECK(
_userEvents.empty(),
"There are unstopped user defined events. Please stop them using stopLastProfilingSection() before calling advance().");
414 PRECICE_CHECK(std::isfinite(computedTimeStepSize),
"advance() cannot be called with an infinite time step size.");
416 PRECICE_CHECK(computedTimeStepSize > 0.0,
"advance() cannot be called with a negative time step size {}.", computedTimeStepSize);
428 const bool isAtWindowEnd =
_couplingScheme->addComputedTime(computedTimeStepSize);
435 int sumOfChanges = std::accumulate(totalMeshChanges.begin(), totalMeshChanges.end(), 0);
453 const bool timeWindowComplete =
_couplingScheme->isTimeWindowComplete();
455 handleDataAfterAdvance(isAtWindowEnd, timeWindowComplete, timeSteppedTo, timeAfterAdvance, dataToReceive);
459 PRECICE_DEBUG(
"Mapped {} samples in write mappings and {} samples in read mappings",
490 if (reachedTimeWindowEnd) {
498 if (!reachedTimeWindowEnd) {
505 PRECICE_ASSERT(
math::greaterEquals(timeAfterAdvance, timeSteppedTo),
"We must have stayed or moved forwards in time (min-time-step-size).", timeAfterAdvance, timeSteppedTo);
516 if (reachedTimeWindowEnd) {
523 for (
auto &context :
_accessor->readDataContexts()) {
524 context.invalidateMappingCache();
528 for (
auto &context :
_accessor->writeDataContexts()) {
529 context.invalidateMappingCache();
534 for (
auto &context :
_accessor->readDataContexts()) {
535 context.resetInitialGuesses();
537 for (
auto &context :
_accessor->writeDataContexts()) {
538 context.resetInitialGuesses();
548 for (
auto &context :
_accessor->writeDataContexts()) {
565 context.completeJustInTimeMapping();
566 context.storeBufferedData(
time);
572 for (
auto &variant :
_accessor->usedMeshContexts()) {
574 for (
const auto &name :
mesh.availableData()) {
575 mesh.data(name)->waveform().trimBefore(
time);
582 for (
auto &context :
_accessor->writeDataContexts()) {
583 context.trimAfter(
time);
629#if !defined(PRECICE_NO_GINKGO) || !defined(PRECICE_NO_KOKKOS_KERNELS)
643 return _accessor->meshContext(meshName).mesh->getDimensions();
651 return _accessor->meshContext(meshName).mesh->data(dataName)->getDimensions();
674 const double nextTimeStepSize =
_couplingScheme->getNextTimeStepMaxSize();
682 "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.",
684 return nextTimeStepSize;
728 std::string_view dataName)
const
732 if (!
_accessor->isDataWrite(meshName, dataName))
740 std::string_view meshName)
const
747 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
751 if (
_accessor->isMeshReceived(meshName) &&
_accessor->isDirectAccessAllowed(meshName)) {
752 auto &receivedContext =
_accessor->receivedMeshContext(meshName);
755 PRECICE_CHECK(receivedContext.userDefinedAccessRegion,
"The function getMeshVertexSize was called on the received mesh \"{0}\", "
756 "but no access region was defined although this is necessary for parallel runs. "
757 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexSize()\".",
762 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);
768 "You are calling \"getMeshVertexSize()\" on a received mesh without api-access enabled (<receive-mesh name=\"{0}\" ... api-access=\"false\"/>). "
769 "Note that enabling api-access is required for this function to work properly with direct mesh access and just-in-time mappings.",
771 return _accessor->meshContext(meshName).mesh->nVertices();
776 std::string_view meshName)
779 PRECICE_CHECK(
_allowsRemeshing,
"Cannot reset meshes. This feature needs to be enabled using <precice-configuration experimental=\"1\" allow-remeshing=\"1\">.");
784 PRECICE_CHECK(
_couplingScheme->isTimeWindowComplete(),
"Cannot remesh while subcycling or iterating. Remeshing is only allowed when the time window is completed.");
793 std::string_view meshName,
801 "Cannot set vertex for mesh \"{}\". Expected {} position components but found {}.", meshName,
mesh.getDimensions(), position.
size());
803 auto index =
mesh.createVertex(Eigen::Map<const Eigen::VectorXd>{position.
data(),
mesh.getDimensions()}).getID();
804 mesh.allocateDataValues();
806 const auto newSize =
mesh.nVertices();
807 for (
auto &context :
_accessor->writeDataContexts()) {
808 if (context.getMeshName() ==
mesh.getName()) {
809 context.resizeBufferTo(newSize);
817 std::string_view meshName,
826 const auto meshDims =
mesh.getDimensions();
827 const auto expectedPositionSize = ids.
size() * meshDims;
829 "Input sizes are inconsistent attempting to set vertices on {}D mesh \"{}\". "
830 "You passed {} vertex indices and {} position components, but we expected {} position components ({} x {}).",
831 meshDims, meshName, ids.
size(), positions.
size(), expectedPositionSize, ids.
size(), meshDims);
834 const Eigen::Map<const Eigen::MatrixXd> posMatrix{
835 positions.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
836 for (
unsigned long i = 0; i < ids.
size(); ++i) {
837 ids[i] =
mesh.createVertex(posMatrix.col(i)).getID();
839 mesh.allocateDataValues();
841 const auto newSize =
mesh.nVertices();
842 for (
auto &context :
_accessor->writeDataContexts()) {
843 if (context.getMeshName() ==
mesh.getName()) {
844 context.resizeBufferTo(newSize);
850 std::string_view meshName,
868 mesh.createEdge(v0, v1);
872 std::string_view meshName,
884 "Cannot interpret passed vertex IDs attempting to set edges of mesh \"{}\" . "
885 "You passed {} vertex indices, but we expected an even number.",
886 meshName, vertices.
size());
888 auto end = vertices.
end();
890 return !mesh.isValidVertexID(vid);
894 std::distance(vertices.
begin(), first),
895 std::distance(vertices.
begin(), last));
900 for (
unsigned long i = 0; i < vertices.
size() / 2; ++i) {
901 auto aid = vertices[2 * i];
902 auto bid = vertices[2 * i + 1];
908 std::string_view meshName,
926 "setMeshTriangle() was called with repeated Vertex IDs ({}, {}, {}).",
927 first, second, third);
933 mesh.createTriangle(A, B, C);
937 std::string_view meshName,
949 "Cannot interpret passed vertex IDs attempting to set triangles of mesh \"{}\" . "
950 "You passed {} vertex indices, which isn't dividable by 3.",
951 meshName, vertices.
size());
953 auto end = vertices.
end();
955 return !mesh.isValidVertexID(vid);
959 std::distance(vertices.
begin(), first),
960 std::distance(vertices.
begin(), last));
965 for (
unsigned long i = 0; i < vertices.
size() / 3; ++i) {
966 auto aid = vertices[3 * i];
967 auto bid = vertices[3 * i + 1];
968 auto cid = vertices[3 * i + 2];
969 mesh.createTriangle(
mesh.vertex(aid),
976 std::string_view meshName,
983 second, third, fourth);
1003 "The four vertices that form the quad are not unique. The resulting shape may be a point, line or triangle. "
1004 "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.");
1007 PRECICE_CHECK(convexity.convex,
"The given quad is not convex. "
1008 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.");
1016 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1017 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1020 if (distance02 <= distance13) {
1021 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1022 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1024 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1025 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1030 std::string_view meshName,
1042 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1043 "You passed {} vertex indices, which isn't dividable by 4.",
1044 meshName, vertices.
size());
1046 auto end = vertices.
end();
1048 return !mesh.isValidVertexID(vid);
1052 std::distance(vertices.
begin(), first),
1053 std::distance(vertices.
begin(), last));
1056 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1057 auto aid = vertices[4 * i];
1058 auto bid = vertices[4 * i + 1];
1059 auto cid = vertices[4 * i + 2];
1060 auto did = vertices[4 * i + 3];
1063 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);
1067 "The four vertices that form the quad nr {} are not unique. The resulting shape may be a point, line or triangle. "
1068 "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.",
1072 PRECICE_CHECK(convexity.convex,
"The given quad nr {} is not convex. "
1073 "Please check that the adapter send the four correct vertices or that the interface is composed of quads.",
1081 double distance02 = (reordered[0]->getCoords() - reordered[2]->getCoords()).norm();
1082 double distance13 = (reordered[1]->getCoords() - reordered[3]->getCoords()).norm();
1084 if (distance02 <= distance13) {
1085 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[1]);
1086 mesh.createTriangle(*reordered[0], *reordered[2], *reordered[3]);
1088 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[0]);
1089 mesh.createTriangle(*reordered[1], *reordered[3], *reordered[2]);
1095 std::string_view meshName,
1105 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1123 mesh.createTetrahedron(A, B, C, D);
1127 std::string_view meshName,
1134 "Please set the mesh dimension to 3 in the preCICE configuration file.");
1141 "Cannot interpret passed vertex IDs attempting to set quads of mesh \"{}\" . "
1142 "You passed {} vertex indices, which isn't dividable by 4.",
1143 meshName, vertices.
size());
1145 auto end = vertices.
end();
1147 return !mesh.isValidVertexID(vid);
1151 std::distance(vertices.
begin(), first),
1152 std::distance(vertices.
begin(), last));
1157 for (
unsigned long i = 0; i < vertices.
size() / 4; ++i) {
1158 auto aid = vertices[4 * i];
1159 auto bid = vertices[4 * i + 1];
1160 auto cid = vertices[4 * i + 2];
1161 auto did = vertices[4 * i + 3];
1162 mesh.createTetrahedron(
mesh.vertex(aid),
1170 std::string_view meshName,
1171 std::string_view dataName,
1177 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.");
1187 const auto expectedDataSize = vertices.
size() * dataDims;
1189 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1190 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1191 dataDims, dataName, meshName,
1192 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1198 PRECICE_ERROR(
"Cannot write data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1199 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1200 dataName, meshName, *index);
1207 std::string_view meshName,
1208 std::string_view dataName,
1210 double relativeReadTime,
1217 PRECICE_CHECK(relativeReadTime >= 0,
"readData(...) cannot sample data before the current time.");
1218 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);
1223 "Cannot read from mesh \"{}\" after it has been reset. Please read data before calling resetMesh().",
1233 "This is typically a configuration issue of the data flow. "
1234 "Check if the data is correctly exchanged to this participant \"{}\" and mapped to mesh \"{}\".",
1238 const auto expectedDataSize = vertices.
size() * dataDims;
1240 "Input/Output sizes are inconsistent attempting to read {}D data \"{}\" from mesh \"{}\". "
1241 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1242 dataDims, dataName, meshName,
1243 vertices.
size(), values.
size(), expectedDataSize, dataDims, vertices.
size());
1246 PRECICE_ERROR(
"Cannot read data \"{}\" from mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1247 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1248 dataName, meshName, *index);
1254 context.
readValues(vertices, readTime, values);
1258 std::string_view meshName,
1259 std::string_view dataName,
1261 double relativeReadTime,
1269 PRECICE_CHECK(relativeReadTime >= 0,
"mapAndReadData(...) cannot sample data before the current time.");
1270 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);
1276 "This participant attempteded to map and read data (via \"mapAndReadData\") from mesh \"{0}\", "
1277 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1278 "mapAndReadData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1282 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1283 "The function \"mapAndReadData\" was called on mesh \"{0}\", "
1284 "but no access region was defined although this is necessary for parallel runs. "
1285 "Please define an access region using \"setMeshAccessRegion()\" before calling \"mapAndReadData()\".",
1288 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. "
1289 "How should the provided data values be read? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1290 dataName, meshName);
1294 "The function \"mapAndReadData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1295 "Please define a mapping in read direction from the mesh \"{0}\" and omit the \"to\" attribute from the definition. "
1296 "Example \"<mapping:nearest-neighbor direction=\"read\" from=\"{0}\" constraint=\"consistent\" />",
1309 const auto nVertices = (coordinates.
size() / dim);
1312 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"mapAndReadData");
1316 "Input sizes are inconsistent attempting to mapAndRead {}D data \"{}\" from mesh \"{}\". "
1317 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1318 dataDims, dataName, meshName,
1319 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1326 std::string_view meshName,
1327 std::string_view dataName,
1335 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.");
1341 "This participant attempteded to map and read data (via \"writeAndMapData\") from mesh \"{0}\", "
1342 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1343 "writeAndMapData({0}, ...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1347 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1348 "The function \"writeAndMapData\" was called on mesh \"{0}\", "
1349 "but no access region was defined although this is necessary for parallel runs. "
1350 "Please define an access region using \"setMeshAccessRegion()\" before calling \"writeAndMapData()\".",
1355 "The function \"writeAndMapData\" was called on mesh \"{0}\", but no matching just-in-time mapping was configured. "
1356 "Please define a mapping in write direction to the mesh \"{0}\" and omit the \"from\" attribute from the definition. "
1357 "Example \"<mapping:nearest-neighbor direction=\"write\" to=\"{0}\" constraint=\"conservative\" />",
1370 const auto nVertices = (coordinates.
size() / dim);
1374 _accessor->receivedMeshContext(meshName).checkVerticesInsideAccessRegion(coordinates, dim,
"writeAndMapData");
1377 "Input sizes are inconsistent attempting to write {}D data \"{}\" to mesh \"{}\". "
1378 "You passed {} vertex indices and {} data components, but we expected {} data components ({} x {}).",
1379 dataDims, dataName, meshName,
1380 nVertices, values.
size(), nVertices * dataDims, dataDims, nVertices);
1382 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. "
1383 "Where should the provided data go? Please make sure the mesh \"{1}\" is non-empty within the access region.",
1384 dataName, meshName);
1389 std::string_view meshName,
1390 std::string_view dataName,
1410 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);
1413 PRECICE_ERROR(
"Cannot write gradient data \"{}\" to mesh \"{}\" due to invalid Vertex ID at vertices[{}]. "
1414 "Please make sure you only use the results from calls to setMeshVertex/Vertices().",
1415 dataName, meshName, *index);
1420 const auto gradientComponents = meshDims * dataDims;
1421 const auto expectedComponents = vertices.
size() * gradientComponents;
1423 "Input sizes are inconsistent attempting to write gradient for data \"{}\" to mesh \"{}\". "
1424 "A single gradient/Jacobian for {}D data on a {}D mesh has {} components. "
1425 "You passed {} vertex indices and {} gradient components, but we expected {} gradient components. ",
1427 dataDims, meshDims, gradientComponents,
1428 vertices.
size(), gradients.
size(), expectedComponents);
1438 const std::string_view meshName,
1444 "This participant attempteded to set an access region (via \"setMeshAccessRegion\") on mesh \"{0}\", "
1445 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1446 "setMeshAccessRegion(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1456 int dim =
mesh.getDimensions();
1458 "Incorrect amount of bounding box components attempting to set the bounding box of {}D mesh \"{}\" . "
1459 "You passed {} limits, but we expected {} ({}x2).",
1460 dim, meshName, boundingBox.
size(), dim * 2, dim);
1464 std::vector<double> bounds(dim * 2);
1466 for (
int d = 0; d < dim; ++d) {
1468 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...]");
1469 bounds[2 * d] = boundingBox[2 * d];
1470 bounds[2 * d + 1] = boundingBox[2 * d + 1];
1479 const std::string_view meshName,
1486 "This participant attempteded to get mesh vertex IDs and coordinates (via \"getMeshVertexIDsAndCoordinates\") from mesh \"{0}\", "
1487 "but mesh \"{0}\" is either not a received mesh or its api access was not enabled in the configuration. "
1488 "getMeshVertexIDsAndCoordinates(...) is only valid for (<receive-mesh name=\"{0}\" ... api-access=\"true\"/>).",
1492 PRECICE_CHECK(!requiresBB || (requiresBB &&
_accessor->receivedMeshContext(meshName).userDefinedAccessRegion),
1493 "The function \"getMeshVertexIDsAndCoordinates\" was called on mesh \"{0}\", "
1494 "but no access region was defined although this is necessary for parallel runs. "
1495 "Please define an access region using \"setMeshAccessRegion()\" before calling \"getMeshVertexIDsAndCoordinates()\".",
1502 "initialize() has to be called before accessing data of the received mesh \"{}\" on participant \"{}\".",
1513 auto filteredVertices =
_accessor->receivedMeshContext(meshName).filterVerticesToLocalAccessRegion(requiresBB);
1514 const auto meshSize = filteredVertices.size();
1517 const auto meshDims =
mesh.getDimensions();
1519 "Output size is incorrect attempting to get vertex ids of {}D mesh \"{}\". "
1520 "You passed {} vertex indices, but we expected {}. "
1521 "Use getMeshVertexSize(\"{}\") to receive the required amount of vertices.",
1522 meshDims, meshName, ids.
size(), meshSize, meshName);
1523 const auto expectedCoordinatesSize =
static_cast<unsigned long>(meshDims * meshSize);
1525 "Output size is incorrect attempting to get vertex coordinates of {}D mesh \"{}\". "
1526 "You passed {} coordinate components, but we expected {} ({}x{}). "
1527 "Use getMeshVertexSize(\"{}\") and getMeshDimensions(\"{}\") to receive the required amount components",
1528 meshDims, meshName, coordinates.
size(), expectedCoordinatesSize, meshSize, meshDims, meshName, meshName);
1530 PRECICE_ASSERT(ids.
size() <=
mesh.nVertices(),
"The queried size exceeds the number of available points.");
1532 Eigen::Map<Eigen::MatrixXd> posMatrix{
1533 coordinates.
data(),
mesh.getDimensions(),
static_cast<EIGEN_DEFAULT_DENSE_INDEX_TYPE
>(ids.
size())};
1535 for (
unsigned long i = 0; i < ids.
size(); i++) {
1536 auto localID = filteredVertices[i].get().getID();
1539 posMatrix.col(i) = filteredVertices[i].get().getCoords();
1546 std::sort(
_accessor->usedMeshContexts().begin(),
_accessor->usedMeshContexts().end(),
1548 return getMesh(lhs).getName() < getMesh(rhs).getName();
1552 for (
auto &context :
_accessor->providedMeshContexts()) {
1553 context.mesh->computeBoundingBox();
1557 for (
auto &variant :
_accessor->usedMeshContexts()) {
1562 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1573 auto &contexts =
_accessor->usedMeshContexts();
1575 std::sort(contexts.begin(), contexts.end(),
1577 return getMesh(lhs).getName() < getMesh(rhs).getName();
1580 for (
const auto &variant : contexts) {
1588 for (
auto &m2nPair :
_m2ns) {
1589 if (m2nPair.second.m2n->usesTwoLevelInitialization()) {
1597 std::stable_partition(contexts.begin(), contexts.end(),
1599 return std::holds_alternative<ProvidedMeshContext *>(variant);
1603 for (
const auto &variant : contexts) {
1608 if (std::holds_alternative<ReceivedMeshContext *>(variant)) {
1609 mesh.computeBoundingBox();
1612 mesh.allocateDataValues();
1615 const auto requiredSize =
mesh.nVertices();
1616 for (
auto &context :
_accessor->writeDataContexts()) {
1617 if (context.getMeshName() ==
mesh.getName()) {
1618 context.resizeBufferTo(requiredSize, std::holds_alternative<ReceivedMeshContext *>(variant));
1627 bool anyMappingChanged =
false;
1629 if (not context.mapping->hasComputedMapping()) {
1631 "Automatic RBF mapping alias from mesh \"{}\" to mesh \"{}\" in \"{}\" direction resolves to \"{}\" .",
1632 context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType, context.mapping->getName());
1633 PRECICE_INFO(
"Computing \"{}\" mapping from mesh \"{}\" to mesh \"{}\" in \"{}\" direction.",
1634 context.mapping->getName(), context.mapping->getInputMesh()->getName(), context.mapping->getOutputMesh()->getName(), mappingType);
1635 context.mapping->computeMapping();
1636 anyMappingChanged =
true;
1639 if (anyMappingChanged) {
1640 _accessor->initializeMappingDataCache(mappingType);
1653 for (
auto &context :
_accessor->writeDataContexts()) {
1654 if (context.hasMapping()) {
1655 PRECICE_DEBUG(
"Map initial write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1670 for (
auto &context :
_accessor->writeDataContexts()) {
1671 if (context.hasMapping()) {
1672 PRECICE_DEBUG(
"Map write data \"{}\" from mesh \"{}\"", context.getDataName(), context.getMeshName());
1681 for (
auto &context :
_accessor->readDataContexts()) {
1682 if (context.hasMapping()) {
1687 context.clearToDataFor(fromData);
1689 context.trimToDataAfterFor(fromData, startOfTimeWindow);
1704 for (
auto &context :
_accessor->readDataContexts()) {
1705 if (context.hasMapping()) {
1706 PRECICE_DEBUG(
"Map initial read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1722 for (
auto &context :
_accessor->readDataContexts()) {
1723 if (context.hasMapping()) {
1724 PRECICE_DEBUG(
"Map read data \"{}\" to mesh \"{}\"", context.getDataName(), context.getMeshName());
1735 if (timings.find(
action->getTiming()) != timings.end()) {
1767 for (
auto &context :
_accessor->writeDataContexts()) {
1769 context.resetBufferedData();
1776 const auto &partConfig = *
config.getParticipantConfiguration();
1778 "This participant's name, which was specified in the constructor of the preCICE interface as \"{}\", "
1779 "is not defined in the preCICE configuration. "
1780 "Please double-check the correct spelling.",
1808 "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 {}.",
1809 secondaryRank, dt, computedTimeStepSize);
1819 std::vector<MeshID> localChanges;
1821 [[maybe_unused]]
auto remoteChanges1 =
_couplingScheme->firstSynchronization(localChanges);
1824 [[maybe_unused]]
auto remoteChanges2 =
_couplingScheme->secondSynchronization();
1835 std::string ping =
"ping";
1836 std::string pong =
"pong";
1837 for (
auto &iter :
_m2ns) {
1838 auto bm2n = iter.second;
1839 if (!bm2n.m2n->isConnected()) {
1840 PRECICE_DEBUG(
"Skipping closure of defective connection with {}", bm2n.remoteName);
1844 auto comm = bm2n.m2n->getPrimaryRankCommunication();
1845 PRECICE_DEBUG(
"Synchronizing primary rank with {}", bm2n.remoteName);
1846 if (bm2n.isRequesting) {
1847 comm->send(ping, 0);
1848 std::string receive =
"init";
1849 comm->receive(receive, 0);
1852 std::string receive =
"init";
1853 comm->receive(receive, 0);
1855 comm->send(pong, 0);
1859 PRECICE_DEBUG(
"Closing distributed communication with {}", bm2n.remoteName);
1860 bm2n.m2n->closeDistributedConnections();
1862 PRECICE_DEBUG(
"Closing communication with {}", bm2n.remoteName);
1863 bm2n.m2n->closeConnection();
1876 return *
_accessor->meshContext(meshName).mesh;
1896 std::vector<double> localMeshChanges;
1897 for (
const auto &variant :
_accessor->usedMeshContexts()) {
1898 localMeshChanges.push_back(
_meshLock.check(
getMesh(variant).getName()) ? 0.0 : 1.0);
1900 PRECICE_DEBUG(
"Mesh changes of rank: {}", localMeshChanges);
1903 std::vector<double> totalMeshChanges(localMeshChanges.size(), 0.0);
1907 MeshChanges totalMeshChangesInt(totalMeshChanges.begin(), totalMeshChanges.end());
1908 PRECICE_DEBUG(
"Mesh changes of participant: {}", totalMeshChangesInt);
1909 return totalMeshChangesInt;
1916 for (
auto &variant :
_accessor->usedMeshContexts()) {
1917 if (totalMeshChanges[i] > 0.0) {
1931 PRECICE_DEBUG(
"Remeshing is{} required by this participant.", (requestReinit ?
"" :
" not"));
1933 bool swarmReinitRequired = requestReinit;
1934 for (
auto &iter :
_m2ns) {
1935 PRECICE_DEBUG(
"Coordinating remeshing with {}", iter.first);
1936 bool received =
false;
1937 auto &comm = *iter.second.m2n->getPrimaryRankCommunication();
1938 if (iter.second.isRequesting) {
1939 comm.send(requestReinit, 0);
1940 comm.receive(received, 0);
1942 comm.receive(received, 0);
1943 comm.send(requestReinit, 0);
1945 swarmReinitRequired |= received;
1947 PRECICE_DEBUG(
"Coordinated that overall{} remeshing is required.", (swarmReinitRequired ?
"" :
" no"));
1950 return swarmReinitRequired;
1952 bool swarmReinitRequired =
false;
1954 return swarmReinitRequired;
1960 PRECICE_CHECK(std::find(sectionName.begin(), sectionName.end(),
'/') == sectionName.end(),
1961 "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()