cyprecice module¶
precice
The python module precice offers python language bindings to the C++ coupling library precice. Please refer to precice.org for further information.
- class cyprecice.Participant¶
Bases:
object
Main Application Programming Interface of preCICE. To adapt a solver to preCICE, follow the following main structure:
Create an object of Participant with Participant()
Initialize preCICE with Participant::initialize()
Advance to the next (time)step with Participant::advance()
Finalize preCICE with Participant::finalize()
We use solver, simulation code, and participant as synonyms.
The preferred name in the documentation is participant.
- advance(computed_timestep_length)¶
Advances preCICE after the solver has computed one timestep.
Parameters
- computed_timestep_lengthdouble
Length of timestep used by the solver.
Notes
- Previous calls:
initialize() has been called successfully. The solver has computed one timestep. The solver has written all coupling data. finalize() has not yet been called.
- Tasks completed:
Coupling data values specified in the configuration are exchanged. Coupling scheme state (computed time, computed timesteps, …) is updated. The coupling state is logged. Configured data mapping schemes are applied. [Second Participant] Configured post processing schemes are applied. Meshes with data are exported to files if configured.
- finalize()¶
Finalizes preCICE.
Notes
- Previous calls:
initialize() has been called successfully.
- Tasks completed:
Communication channels are closed. Meshes and data are deallocated.
- get_data_dimensions(mesh_name, data_name)¶
Returns the spatial dimensionality of the given data on the given mesh.
Parameters
- mesh_namestring
Name of the mesh.
- data_namestring
Name of the data.
Returns
- dimensionint
The dimensions of the given data.
- get_max_time_step_size()¶
Get the maximum allowed time step size of the current window.
Allows the user to query the maximum allowed time step size in the current window. This should be used to compute the actual time step that the solver uses.
Returns
- tagdouble
Maximum size of time step to be computed by solver.
Notes
- Previous calls:
initialize() has been called successfully.
- get_mesh_dimensions(mesh_name)¶
Returns the spatial dimensionality of the given mesh.
Parameters
- mesh_namestring
Name of the mesh.
Returns
- dimensionint
The dimensions of the given mesh.
- get_mesh_vertex_ids_and_coordinates(mesh_name)¶
Iterating over the region of interest defined by bounding boxes and reading the corresponding coordinates omitting the mapping. This function is still experimental.
Parameters
- mesh_namestr
Corresponding mesh name
Returns
- idsnumpy.ndarray
Vertex IDs corresponding to the coordinates
- coordinatesnumpy.ndarray
he coordinates associated to the IDs and corresponding data values (dim * size)
- get_mesh_vertex_size(mesh_name)¶
Returns the number of vertices of a mesh
Parameters
- mesh_namestr
Name of the mesh.
Returns
- sumint
Number of vertices of the mesh.
- initialize()¶
Fully initializes preCICE and initializes coupling data. The starting values for coupling data are zero by default. To provide custom values, first set the data using the Data Access methods before calling this method to finally exchange the data.
- This function handles:
Parallel communication to the coupling partner/s is setup.
Meshes are exchanged between coupling partners and the parallel partitions are created.
- [Serial Coupling Scheme] If the solver is not starting the simulation, coupling data is received
from the coupling partner’s first computation.
Returns
- max_timestepdouble
Maximum length of first timestep to be computed by the solver.
- is_coupling_ongoing()¶
Checks if the coupled simulation is still ongoing. A coupling is ongoing as long as
the maximum number of timesteps has not been reached, and
the final time has not been reached.
The user should call finalize() after this function returns false.
Returns
- tagbool
Whether the coupling is ongoing.
Notes
- Previous calls:
initialize() has been called successfully.
- is_time_window_complete()¶
Checks if the current coupling timewindow is completed. The following reasons require several solver time steps per coupling time step:
A solver chooses to perform subcycling.
An implicit coupling timestep iteration is not yet converged.
Returns
- tagbool
Whether the timestep is complete.
Notes
- Previous calls:
initialize() has been called successfully.
- read_data(mesh_name, data_name, vertex_ids, relative_read_time)¶
Reads data into a provided block. This function reads values of specified vertices from a dataID. Values are read into a block of continuous memory.
Parameters
- mesh_namestr
Name of the mesh to write to.
- data_namestr
ID to read from.
- vertex_idsarray_like
Indices of the vertices.
- relative_read_timedouble
Point in time where data is read relative to the beginning of the current time step
Returns
- valuesnumpy.ndarray
Contains the read data.
Notes
- Previous calls:
count of available elements at values matches the configured dimension * size count of available elements at vertex_ids matches the given size initialize() has been called
Examples
Read scalar data for a 2D problem with 5 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> dt = 1.0 >>> values = read_data(mesh_name, data_name, vertex_ids, dt) >>> values.shape >>> (5, )
Read vector data for a 2D problem with 5 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> dt = 1.0 >>> values = read_data(mesh_name, data_name, vertex_ids, dt) >>> values.shape >>> (5, 2)
Read vector data for a 3D system with 5 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> dt = 1.0 >>> values = read_data(mesh_name, data_name, vertex_ids, dt) >>> values.shape >>> (5, 3)
- requires_gradient_data_for(mesh_name, data_name)¶
Checks if the given data set requires gradient data. We check if the data object has been intialized with the gradient flag.
Parameters
- mesh_namestr
Mesh name to check.
- data_namestr
Data name to check.
Returns
- bool
True if gradient data is required for a data.
Examples
Check if gradient data is required for a data: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> participant.is_gradient_data_required(mesh_name, data_name)
- requires_initial_data()¶
Checks if the participant is required to provide initial data. If true, then the participant needs to write initial data to defined vertices prior to calling initialize().
Returns
- tagbool
Returns True if inital data is required.
Notes
- Previous calls:
initialize() has not yet been called
- requires_mesh_connectivity_for(mesh_name)¶
Checks if the given mesh requires connectivity.
Parameters
- mesh_namestring
Name of the mesh.
Returns
- tagbool
True if mesh connectivity is required.
- requires_reading_checkpoint()¶
Checks if the participant is required to read an iteration checkpoint.
If true, the participant is required to read an iteration checkpoint before calling advance().
preCICE refuses to proceed if reading a checkpoint is required, but this method isn’t called prior to advance().
Notes
This function returns false before the first call to advance().
- Previous calls:
initialize() has been called
- requires_writing_checkpoint()¶
Checks if the participant is required to write an iteration checkpoint.
If true, the participant is required to write an iteration checkpoint before calling advance().
preCICE refuses to proceed if writing a checkpoint is required, but this method isn’t called prior to advance().
Notes
- Previous calls:
initialize() has been called
- set_mesh_access_region(mesh_name, bounding_box)¶
This function is required if you don’t want to use the mapping schemes in preCICE, but rather want to use your own solver for data mapping. As opposed to the usual preCICE mapping, only a single mesh (from the other participant) is now involved in this situation since an ‘own’ mesh defined by the participant itself is not required any more. In order to re-partition the received mesh, the participant needs to define the mesh region it wants read data from and write data to. The mesh region is specified through an axis-aligned bounding box given by the lower and upper [min and max] bounding-box limits in each space dimension [x, y, z]. This function is still experimental
Parameters
- mesh_namestr
Name of the mesh you want to access through the bounding box
- bounding_boxarray_like
Axis aligned bounding box. Example for 3D the format: [x_min, x_max, y_min, y_max, z_min, z_max]
Notes
Defining a bounding box for serial runs of the solver (not to be confused with serial coupling mode) is valid. However, a warning is raised in case vertices are filtered out completely on the receiving side, since the associated data values of the filtered vertices are filled with zero data.
This function can only be called once per participant and rank and trying to call it more than once results in an error.
If you combine the direct access with a mapping (say you want to read data from a defined mesh, as usual, but you want to directly access and write data on a received mesh without a mapping) you may not need this function at all since the region of interest is already defined through the defined mesh used for data reading. This is the case if you define any mapping involving the directly accessed mesh on the receiving participant. (In parallel, only the cases read-consistent and write-conservative are relevant, as usual).
The safety factor scaling (see safety-factor in the configuration file) is not applied to the defined access region and a specified safety will be ignored in case there is no additional mapping involved. However, in case a mapping is in addition to the direct access involved, you will receive (and gain access to) vertices inside the defined access region plus vertices inside the safety factor region resulting from the mapping. The default value of the safety factor is 0.5, i.e. the defined access region as computed through the involved provided mesh is by 50% enlarged.
- set_mesh_edge(mesh_name, first_vertex_id, second_vertex_id)¶
Sets mesh edge from vertex IDs, returns edge ID.
Parameters
- mesh_namestr
Name of the mesh to add the edge to.
- first_vertex_idint
ID of the first vertex of the edge.
- second_vertex_idint
ID of the second vertex of the edge.
Returns
- edge_idint
ID of the edge.
Notes
- Previous calls:
vertices with firstVertexID and secondVertexID were added to the mesh with name mesh_name
- set_mesh_edges(mesh_name, vertices)¶
Creates multiple mesh edges
Parameters
- mesh_namestr
Name of the mesh to add the vertices to.
- verticesarray_like
The IDs of the vertices in a numpy array [N x 2] where N = number of edges and D = dimensions of geometry.
Examples
Set mesh edges for a problem with 4 mesh vertices in the form of a square with both diagonals which are fully interconnected.
>>> vertices = np.array([[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]) >>> vertices.shape (6, 2) >>> participant.set_mesh_edges(mesh_name, vertices)
- set_mesh_quad(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id, fourth_vertex_id)¶
Set a mesh Quad from vertex IDs.
Parameters
- mesh_namestr
Name of the mesh to add the quad to.
- first_vertex_idint
ID of the first vertex of the quad.
- second_vertex_idint
ID of the second vertex of the quad.
- third_vertex_idint
ID of the third vertex of the quad.
- fourth_vertex_idint
ID of the third vertex of the quad.
Notes
- Previous calls:
vertices with first_vertex_id, second_vertex_id, third_vertex_id, and fourth_vertex_id were added to the mesh with the name mesh_name
- set_mesh_quads(mesh_name, vertices)¶
Creates multiple mesh quads
Parameters
- mesh_namestr
Name of the mesh to add the quads to.
- verticesarray_like
The IDs of the vertices in a numpy array [N x 4] where N = number of quads and D = dimensions of geometry.
Examples
Set mesh quads for a problem with 4 mesh vertices in the form of a square with both diagonals which are fully interconnected.
>>> vertices = np.array([[1, 2, 3, 4]]) >>> vertices.shape (1, 2) >>> participant.set_mesh_quads(mesh_name, vertices)
- set_mesh_tetrahedra(mesh_name, vertices)¶
Creates multiple mesh tetdrahedrons
Parameters
- mesh_namestr
Name of the mesh to add the tetrahedrons to.
- verticesarray_like
The IDs of the vertices in a numpy array [N x 4] where N = number of quads and D = dimensions of geometry.
Examples
Set mesh tetrahedrons for a problem with 4 mesh vertices.
>>> vertices = np.array([[1, 2, 3, 4]]) >>> vertices.shape (1, 2) >>> participant.set_mesh_tetradehra(mesh_name, vertices)
- set_mesh_tetrahedron(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id, fourth_vertex_id)¶
Sets a mesh tetrahedron from vertex IDs.
Parameters
- mesh_namestr
Name of the mesh to add the tetrahedron to.
- first_vertex_idint
ID of the first vertex of the tetrahedron.
- second_vertex_idint
ID of the second vertex of the tetrahedron.
- third_vertex_idint
ID of the third vertex of the tetrahedron.
- fourth_vertex_idint
ID of the third vertex of the tetrahedron.
Notes
- Previous calls:
vertices with first_vertex_id, second_vertex_id, third_vertex_id, and fourth_vertex_id were added to the mesh with the name mesh_name
- set_mesh_triangle(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id)¶
Set a mesh triangle from edge IDs
Parameters
- mesh_namestr
Name of the mesh to add the triangle to.
- first_vertex_idint
ID of the first vertex of the triangle.
- second_vertex_idint
ID of the second vertex of the triangle.
- third_vertex_idint
ID of the third vertex of the triangle.
Notes
- Previous calls:
vertices with first_vertex_id, second_vertex_id, and third_vertex_id were added to the mesh with the name mesh_name
- set_mesh_triangles(mesh_name, vertices)¶
Creates multiple mesh triangles
Parameters
- mesh_namestr
Name of the mesh to add the triangles to.
- verticesarray_like
The IDs of the vertices in a numpy array [N x 3] where N = number of triangles and D = dimensions of geometry.
Examples
Set mesh triangles for a problem with 4 mesh vertices in the form of a square with both diagonals which are fully interconnected.
>>> vertices = np.array([[1, 2, 3], [1, 3, 4], [1, 2, 4], [1, 3, 4]]) >>> vertices.shape (4, 2) >>> participant.set_mesh_triangles(mesh_name, vertices)
- set_mesh_vertex(mesh_name, position)¶
Creates a mesh vertex
Parameters
- mesh_namestr
Name of the mesh to add the vertex to.
- positionarray_like
The coordinates of the vertex.
Returns
- vertex_idint
ID of the vertex which is set.
Notes
- Previous calls:
Count of available elements at position matches the configured dimension
- set_mesh_vertices(mesh_name, positions)¶
Creates multiple mesh vertices
Parameters
- mesh_namestr
Name of the mesh to add the vertices to.
- positionsarray_like
The coordinates of the vertices in a numpy array [N x D] where N = number of vertices and D = dimensions of geometry.
Returns
- vertex_idsnumpy.ndarray
IDs of the created vertices.
Notes
- Previous calls:
initialize() has not yet been called count of available elements at positions matches the configured dimension * size count of available elements at ids matches size
Examples
Set mesh vertices for a 2D problem with 5 mesh vertices.
>>> positions = np.array([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]]) >>> positions.shape (5, 2) >>> mesh_name = "MeshOne" >>> vertex_ids = participant.set_mesh_vertices(mesh_name, positions) >>> vertex_ids.shape (5,)
Set mesh vertices for a 3D problem with 5 mesh vertices.
>>> positions = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4], [5, 5, 5]]) >>> positions.shape (5, 3) >>> mesh_name = "MeshOne" >>> vertex_ids = participant.set_mesh_vertices(mesh_name, positions) >>> vertex_ids.shape (5,)
- write_data(mesh_name, data_name, vertex_ids, values)¶
This function writes values of specified vertices to data of a mesh. Values are provided as a block of continuous memory defined by values. Values are stored in a numpy array [N x D] where N = number of vertices and D = dimensions of geometry. The order of the provided data follows the order specified by vertices.
Parameters
- mesh_namestr
name of the mesh to write to.
- data_namestr
Data name to write to.
- vertex_idsarray_like
Indices of the vertices.
- valuesarray_like
Values of data
Notes
- Previous calls:
count of available elements at values matches the configured dimension * size count of available elements at vertex_ids matches the given size initialize() has been called
Examples
Write scalar data for a 2D problem with 5 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> values = np.array([v1, v2, v3, v4, v5]) >>> participant.write_data(mesh_name, data_name, vertex_ids, values)
Write vector data for a 2D problem with 5 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> values = np.array([[v1_x, v1_y], [v2_x, v2_y], [v3_x, v3_y], [v4_x, v4_y], [v5_x, v5_y]]) >>> participant.write_data(mesh_name, data_name, vertex_ids, values)
Write vector data for a 3D (D=3) problem with 5 (N=5) vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2, 3, 4, 5] >>> values = np.array([[v1_x, v1_y, v1_z], [v2_x, v2_y, v2_z], [v3_x, v3_y, v3_z], [v4_x, v4_y, v4_z], [v5_x, v5_y, v5_z]]) >>> participant.write_data(mesh_name, data_name, vertex_ids, values)
- write_gradient_data(mesh_name, data_name, vertex_ids, gradients)¶
Writes gradient data given as block. This function writes gradient values of specified vertices to a dataID. Values are provided as a block of continuous memory. Values are stored in a numpy array [N x D] where N = number of vertices and D = number of gradient components.
Parameters
- mesh_namestr
Name of the mesh to write to.
- data_namestr
Data name to write to.
- vertex_idsarray_like
Indices of the vertices.
- gradientsarray_like
Gradient values differentiated in the spacial direction (dx, dy) for 2D space, (dx, dy, dz) for 3D space
Notes
- Previous calls:
Count of available elements at values matches the configured dimension Count of available elements at vertex_ids matches the given size Initialize() has been called Data with dataID has attribute hasGradient = true
Examples
Write gradient vector data for a 2D problem with 2 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2] >>> gradients = np.array([[v1x_dx, v1y_dx, v1x_dy, v1y_dy], [v2x_dx, v2y_dx, v2x_dy, v2y_dy]]) >>> participant.write_gradient_data(mesh_name, data_name, vertex_ids, gradients)
Write vector data for a 3D problem with 2 vertices: >>> mesh_name = “MeshOne” >>> data_name = “DataOne” >>> vertex_ids = [1, 2] >>> gradients = np.array([[v1x_dx, v1y_dx, v1z_dx, v1x_dy, v1y_dy, v1z_dy, v1x_dz, v1y_dz, v1z_dz], [v2x_dx, v2y_dx, v2z_dx, v2x_dy, v2y_dy, v2z_dy, v2x_dz, v2y_dz, v2z_dz]]) >>> participant.write_gradient_data(mesh_name, data_name, vertex_ids, gradients)
- cyprecice.check_array_like(argument, argument_name, function_name)¶