OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
coupling_c_interface.cpp
Go to the documentation of this file.
1//Copyright> OpenRadioss
2//Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3//Copyright>
4//Copyright> This program is free software: you can redistribute it and/or modify
5//Copyright> it under the terms of the GNU Affero General Public License as published by
6//Copyright> the Free Software Foundation, either version 3 of the License, or
7//Copyright> (at your option) any later version.
8//Copyright>
9//Copyright> This program is distributed in the hope that it will be useful,
10//Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11//Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12//Copyright> GNU Affero General Public License for more details.
13//Copyright>
14//Copyright> You should have received a copy of the GNU Affero General Public License
15//Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16//Copyright>
17//Copyright>
18//Copyright> Commercial Alternative: Altair Radioss Software
19//Copyright>
20//Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21//Copyright> software under a commercial license. Contact Altair to discuss further if the
22//Copyright> commercial version may interest you: https://www.altair.com/radioss/.
24#include "coupling_factory.h"
25#include "coupling.h"
26#include <string>
27#include <vector>
28#include <iostream>
29#ifdef WITH_CWIPI
31#endif
32
33extern "C" {
34
35// Factory function: creates and returns a new coupling adapter instance.
36// - If WITH_PRECICE: returns new PreciceCouplingAdapter()
37// - If WITH_CWIPI: returns new CwipiCouplingAdapter()
38// - Otherwise: returns DummyCouplingAdapter()
39// No direct preCICE or CWIPI function is called here; just object construction.
43
44// Deletes the adapter instance created by coupling_adapter_create.
45// - For both preCICE and CWIPI: calls the destructor of the adapter, which in turn calls finalize() if active.
46// - PreciceCouplingAdapter::~PreciceCouplingAdapter(): finalize()
47// - CwipiCouplingAdapter::~CwipiCouplingAdapter(): finalize()
48void coupling_adapter_destroy(void* adapter) {
49 delete static_cast<CouplingAdapter*>(adapter);
50}
51
52// Configures the adapter using a configuration file.
53// - preCICE: calls PreciceCouplingAdapter::configure(const std::string& configFile)
54// - Parses config, sets up participant, mesh, data types, etc.
55// - CWIPI: calls CwipiCouplingAdapter::configure(const std::string& configFile)
56// - Parses config, sets up application/coupling names, data types, etc.
57// cwipi_init
58int coupling_adapter_configure(void* adapter, const char* filename) {
59 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
60 return ca->configure(std::string(filename)) ? 1 : 0;
61}
62
63// Sets the list of node IDs to be used for coupling.
64// - preCICE: calls PreciceCouplingAdapter::setNodes(const std::vector<int>& nodeIds)
65// - Allocates buffers, stores node IDs, prepares for mesh setup.
66// - CWIPI: calls CwipiCouplingAdapter::setNodes(const std::vector<int>& nodeIds)
67// - Allocates buffers, stores node IDs, prepares for mesh setup.
68
69
70void coupling_adapter_set_nodes(void* adapter, const int* nodeIds, int numNodes) {
71 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
72 std::vector<int> nodes(nodeIds, nodeIds + numNodes);
73 ca->setNodes(nodes);
74}
75
76// Initializes the coupling adapter with node coordinates and MPI info.
77// - preCICE: calls PreciceCouplingAdapter::initialize(const double* coordinates, int totalNodes, int mpiRank, int mpiSize)
78// - Creates preCICE participant, sets mesh vertices, initializes coupling.
79// PreciceCouplingAdapter::initialize()
80// precice::Participant constructor
81// precice_->setMeshVertices()
82// precice_->writeData() (if initial data required)
83// precice_->initialize()
84// precice_->getMaxTimeStepSize()
85// - CWIPI: calls CwipiCouplingAdapter::initialize(const double* coordinates, int totalNodes, int mpiRank, int mpiSize)
86// - Initializes CWIPI, creates coupling, defines mesh, locates points.
87// CwipiCouplingAdapter::initialize()
88// cwipi_create_coupling()
89// cwipi_define_mesh() or cwipi_ho_define_mesh()
90// cwipi_locate()
91// cwipi_get_n_not_located_points()
92int coupling_adapter_initialize(void* adapter, const double* coordinates,
93 int totalNodes, int mpiRank, int mpiSize) {
94 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
95 return ca->initialize(coordinates, totalNodes, mpiRank, mpiSize) ? 1 : 0;
96}
97
98// Writes data (e.g., displacements, forces, positions) to the coupling interface.
99// - preCICE: calls PreciceCouplingAdapter::writeData(const double* values, int totalNodes, double dt, int dataType)
100// - Extracts node data, calls preCICE::writeData() for the mesh/data type.
101// - CWIPI: calls CwipiCouplingAdapter::writeData(const double* values, int totalNodes, double dt, int dataType)
102// - Extracts node data, calls cwipi_issend() and cwipi_wait_issend() for async send.
103void coupling_adapter_write_data(void* adapter, const double* values,
104 int totalNodes, double dt, int dataType) {
105 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
106 ca->writeData(values, totalNodes, dt, dataType);
107}
108
109// Reads data (e.g., displacements, forces, positions) from the coupling interface.
110// - preCICE: calls PreciceCouplingAdapter::readData(double* values, int totalNodes, double dt, int dataType)
111// - Calls preCICE::readData() for the mesh/data type, injects into global arrays.
112// - CWIPI: calls CwipiCouplingAdapter::readData(double* values, int totalNodes, double dt, int dataType)
113// - Calls cwipi_irecv() and cwipi_wait_irecv() for async receive, injects into global arrays.
114void coupling_adapter_read_data(void* adapter, double* values,
115 int totalNodes, double dt, int dataType) {
116 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
117 ca->readData(values, totalNodes, dt, dataType);
118}
119
120// Advances the coupling interface by a time step.
121// - preCICE: calls PreciceCouplingAdapter::advance(double& dt)
122// - Calls preCICE::advance(), updates max time step size.
123// - CWIPI: calls CwipiCouplingAdapter::advance(double& dt)
124// - Calls cwipi_locate(), checks for not located points.
125void coupling_adapter_advance(void* adapter, double* dt) {
126 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
127 ca->advance(*dt);
128}
129
130// Checks if the coupling is still ongoing.
131// - preCICE: calls PreciceCouplingAdapter::isCouplingOngoing()
132// - Returns preCICE::isCouplingOngoing().
133// - CWIPI: calls CwipiCouplingAdapter::isCouplingOngoing()
134// - Returns true if active and initialized (CWIPI does not have a strict ongoing state).
136 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
137 return ca->isCouplingOngoing() ? 1 : 0;
138}
139
140// Checks if a checkpoint write is required.
141// - preCICE: calls PreciceCouplingAdapter::requiresWritingCheckpoint()
142// - Returns preCICE::requiresWritingCheckpoint().
143// - CWIPI: calls CwipiCouplingAdapter::requiresWritingCheckpoint()
144// - Always returns false (not required for CWIPI).
146 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
147 return ca->requiresWritingCheckpoint() ? 1 : 0;
148}
149
150// Checks if a checkpoint read is required.
151// - preCICE: calls PreciceCouplingAdapter::requiresReadingCheckpoint()
152// - Returns preCICE::requiresReadingCheckpoint().
153// - CWIPI: calls CwipiCouplingAdapter::requiresReadingCheckpoint()
154// - Always returns false (not required for CWIPI).
156 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
157 return ca->requiresReadingCheckpoint() ? 1 : 0;
158}
159
160// Finalizes and cleans up the coupling adapter.
161// preCICE: PreciceCouplingAdapter::finalize() → precice_->finalize()
162// CWIPI: CwipiCouplingAdapter::finalize() → cwipi_delete_coupling(), cwipi_finalize()
163void coupling_adapter_finalize(void* adapter) {
164 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
165 ca->finalize();
166}
167
168// Returns whether the adapter is active.
169int coupling_adapter_is_active(void* adapter) {
170 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
171 return ca->isActive() ? 1 : 0;
172}
173
174// Returns the maximum allowed time step size for the coupling.
175// - preCICE: calls PreciceCouplingAdapter::getMaxTimeStepSize()
177 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
178 return ca->getMaxTimeStepSize();
179}
180
181// Returns the number of coupling nodes.
183 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
184 return ca->getNumberOfCouplingNodes();
185}
186
187// Returns the group node ID used for coupling.
189 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
190 return ca->getGroupNodeId();
191}
192
193// Returns the surface ID used for coupling (not always used).
195 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
196 return ca->getSurfaceId();
197}
198
199// Returns the MPI communicator used by the adapter.
200// - preCICE: calls PreciceCouplingAdapter::getCommunicator()
201// - Returns 0 (default, not used).
202// - CWIPI: calls CwipiCouplingAdapter::getCommunicator()
203// - Returns Fortran MPI communicator handle (via MPI_Comm_c2f).
205 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
206 return ca->getCommunicator();
207}
208
209
210// Sets the mesh connectivity for the coupling (only used for CWIPI).
211// - CWIPI: calls CwipiCouplingAdapter::setMesh(const int* elem_node_offsets, const int* elem_node_indices, int num_elements)
212// - Stores mesh connectivity for later use in mesh definition.
213void coupling_adapter_set_mesh(void* adapter, const int* elem_node_offsets, const int* elem_node_indices, int num_elements) {
214 CouplingAdapter* ca = static_cast<CouplingAdapter*>(adapter);
215
216 // Try to cast to CwipiCouplingAdapter to call setMesh
217#ifdef WITH_CWIPI
218 CwipiCouplingAdapter* cwipi_adapter = dynamic_cast<CwipiCouplingAdapter*>(ca);
219 if (cwipi_adapter) {
220 cwipi_adapter->setMesh(elem_node_offsets, elem_node_indices, num_elements);
221 return;
222 }
223#endif
224
225}
226
227} // extern "C"
virtual bool configure(const std::string &configFile)=0
virtual void setNodes(const std::vector< int > &nodeIds)=0
virtual double getMaxTimeStepSize() const =0
virtual void readData(double *values, int totalNodes, double dt, int dataType)=0
virtual void advance(double &dt)=0
virtual bool isCouplingOngoing() const =0
virtual void finalize()=0
virtual bool initialize(const double *coordinates, int totalNodes, int mpiRank, int mpiSize)=0
virtual void writeData(const double *values, int totalNodes, double dt, int dataType)=0
virtual int getNumberOfCouplingNodes() const =0
virtual bool isActive() const =0
virtual bool requiresReadingCheckpoint() const
Definition coupling.h:53
virtual int getCommunicator() const
Definition coupling.h:66
int getGroupNodeId() const
Definition coupling.h:62
virtual bool requiresWritingCheckpoint() const
Definition coupling.h:52
int getSurfaceId() const
Definition coupling.h:64
int coupling_adapter_initialize(void *adapter, const double *coordinates, int totalNodes, int mpiRank, int mpiSize)
int coupling_adapter_is_active(void *adapter)
void coupling_adapter_read_data(void *adapter, double *values, int totalNodes, double dt, int dataType)
void * coupling_adapter_create()
void coupling_adapter_finalize(void *adapter)
int coupling_adapter_get_num_coupling_nodes(void *adapter)
int coupling_adapter_get_surface_id(void *adapter)
int coupling_adapter_requires_writing_checkpoint(void *adapter)
void coupling_adapter_set_mesh(void *adapter, const int *elem_node_offsets, const int *elem_node_indices, int num_elements)
void coupling_adapter_destroy(void *adapter)
void coupling_adapter_write_data(void *adapter, const double *values, int totalNodes, double dt, int dataType)
int coupling_adapter_is_coupling_ongoing(void *adapter)
int coupling_adapter_get_communicator(void *adapter)
int coupling_adapter_configure(void *adapter, const char *filename)
int coupling_adapter_requires_reading_checkpoint(void *adapter)
void coupling_adapter_set_nodes(void *adapter, const int *nodeIds, int numNodes)
double coupling_adapter_get_max_time_step_size(void *adapter)
int coupling_adapter_get_group_node_id(void *adapter)
void coupling_adapter_advance(void *adapter, double *dt)
CouplingAdapter * createCouplingAdapter()