Skip to content

Commit 31e934a

Browse files
committed
Add Python code for couple your code section
1 parent e6388b6 commit 31e934a

8 files changed

+696
-25
lines changed

pages/docs/couple-your-code/couple-your-code-defining-mesh-connectivity.md

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ For surface coupling in 2D, mesh connectivity boils down to defining edges betwe
1414
For volume coupling in 2D, mesh connectivity boils down to defining triangles and / or quads between vertices. In 3D, you need to define tetrahedra introduced in version `2.5.0`.
1515

1616
All kind of connectivity can be built up directly from vertices. Triangles and quads also allow us to define them using edge IDs.
17+
<ul id="apiTabs" class="nav nav-tabs">
18+
<li class="active"><a href="#cpp-1" data-toggle="tab">C++</a></li>
19+
<li><a href="#python-1" data-toggle="tab">Python</a></li>
20+
</ul>
21+
<div class="tab-content">
22+
<div role="tabpanel" class="tab-pane active" id="cpp-1" markdown="1">
1723

1824
```cpp
1925
void setMeshEdge(precice::string_view meshName, VertexID firstVertexID, VertexID secondVertexID);
@@ -22,7 +28,25 @@ void setMeshQuad(precice::string_view meshName, VertexID firstVertexID, VertexID
2228
void setMeshTetrahedron(precice::string_view meshName, VertexID firstVertexID, VertexID secondVertexID, VertexID thirdVertexID, VertexID fourthVertexID);
2329
```
2430
31+
</div>
32+
<div role="tabpanel" class="tab-pane" id="python-1" markdown="1">
33+
34+
```python
35+
set_mesh_edge(mesh_name, first_vertex_id, second_vertex_id)
36+
set_mesh_triangle(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id)
37+
set_mesh_quad(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id, fourth_vertex_id)
38+
set_mesh_tetrahedron(mesh_name, first_vertex_id, second_vertex_id, third_vertex_id, fourth_vertex_id)
39+
```
40+
41+
</div>
42+
</div>
2543
There are also bulk versions of these methods, which can be easier to handle in some cases:
44+
<ul id="apiTabs" class="nav nav-tabs">
45+
<li class="active"><a href="#cpp-2" data-toggle="tab">C++</a></li>
46+
<li><a href="#python-2" data-toggle="tab">Python</a></li>
47+
</ul>
48+
<div class="tab-content">
49+
<div role="tabpanel" class="tab-pane active" id="cpp-2" markdown="1">
2650

2751
```cpp
2852
void setMeshEdges(precice::string_view meshName, precice::span<const VertexID> vertices);
@@ -31,12 +55,39 @@ void setMeshQuads(precice::string_view meshName, precice::span<const VertexID> v
3155
void setMeshTetrahedra(precice::string_view meshName, precice::span<const VertexID> vertices);
3256
```
3357
58+
</div>
59+
<div role="tabpanel" class="tab-pane" id="python-2" markdown="1">
60+
61+
```python
62+
set_mesh_edges(mesh_name, vertices)
63+
set_mesh_triangles(mesh_name, vertices)
64+
set_mesh_quads(mesh_name, vertices)
65+
set_mesh_tetrahedra(mesh_name, vertices)
66+
```
67+
68+
</div>
69+
</div>
3470
If you do not configure any features in the preCICE configuration that require mesh connectivity, all these API functions are [no-ops](https://en.wikipedia.org/wiki/NOP_(code)). Thus, don't worry about performance. If you need a significant workload to already create this connectivity information in your adapter in the first place, you can also explicitly ask preCICE whether it is required:
71+
<ul id="apiTabs" class="nav nav-tabs">
72+
<li class="active"><a href="#cpp-3" data-toggle="tab">C++</a></li>
73+
<li><a href="#python-3" data-toggle="tab">Python</a></li>
74+
</ul>
75+
<div class="tab-content">
76+
<div role="tabpanel" class="tab-pane active" id="cpp-3" markdown="1">
3577

3678
```cpp
3779
bool requiresMeshConnectivityFor(precice::string_view meshName);
3880
```
3981
82+
</div>
83+
<div role="tabpanel" class="tab-pane" id="python-3" markdown="1">
84+
85+
```python
86+
requires_mesh_connectivity_for(mesh_name)
87+
```
88+
89+
</div>
90+
</div>
4091
{% warning %}
4192
The API function `isMeshConnectivityRequired` is only supported since v2.3.
4293
{% endwarning %}
@@ -52,6 +103,12 @@ Quads are only supported since v2.1. For older version, the methods only exist a
52103
{% endwarning %}
53104

54105
The following code shows how mesh connectivity can be defined in our example. For sake of simplification, let's only define one triangle and let's assume that it consists of the first three vertices.
106+
<ul id="apiTabs" class="nav nav-tabs">
107+
<li class="active"><a href="#cpp-4" data-toggle="tab">C++</a></li>
108+
<li><a href="#python-4" data-toggle="tab">Python</a></li>
109+
</ul>
110+
<div class="tab-content">
111+
<div role="tabpanel" class="tab-pane active" id="cpp-4" markdown="1">
55112

56113
```cpp
57114
/* ... */
@@ -83,6 +140,30 @@ if (precice.requiresMeshConnectivityFor(meshName)) {
83140
/* ... */
84141
```
85142
143+
</div>
144+
<div role="tabpanel" class="tab-pane" id="python-4" markdown="1">
145+
146+
```python
147+
# We define the unit square in 2D with vertices A, B, C, D
148+
coords = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
149+
vertex_ids = precice.set_mesh_vertices(mesh_name, coords)
150+
151+
if precice.requires_mesh_connectivity_for(mesh_name):
152+
153+
# Define triangles ABC and BCD separately
154+
precice.set_mesh_triangle(mesh_name, vertex_ids[0], vertex_ids[1], vertex_ids[2])
155+
precice.set_mesh_triangle(mesh_name, vertex_ids[1], vertex_ids[2], vertex_ids[3])
156+
157+
# Define triangles in one go
158+
triangles = np.array([
159+
[vertex_ids[0], vertex_ids[1], vertex_ids[2]],
160+
[vertex_ids[1], vertex_ids[2], vertex_ids[3]]
161+
])
162+
precice.set_mesh_triangles(mesh_name, triangles)
163+
```
164+
165+
</div>
166+
</div>
86167
## Mesh pre-processing
87168

88169
preCICE pre-processes all provided meshes during initialization, removing duplicates and adding missing hierarchical elements.
@@ -109,6 +190,12 @@ In this case you can save a mapping from Solver ID to preCICE Vertex ID, after d
109190
When iterating over the faces, get the vertex identifiers of defining points.
110191
For triangular faces, these would be the 3 corner points.
111192
Then map these Solver IDs to preCICE IDs, and use those to define your connectivity.
193+
<ul id="apiTabs" class="nav nav-tabs">
194+
<li class="active"><a href="#cpp-5" data-toggle="tab">C++</a></li>
195+
<li><a href="#python-5" data-toggle="tab">Python</a></li>
196+
</ul>
197+
<div class="tab-content">
198+
<div role="tabpanel" class="tab-pane active" id="cpp-5" markdown="1">
112199

113200
```cpp
114201
Participant participant(...);
@@ -131,6 +218,30 @@ for (auto& tri: solver.triangularFaces) {
131218
}
132219
```
133220
221+
</div>
222+
<div role="tabpanel" class="tab-pane" id="python-5" markdown="1">
223+
224+
```python
225+
participant = precice.Participant(...)
226+
227+
id_maps = dict()
228+
for vertex in solver.vertices:
229+
vertex_id = participant.set_mesh_vertex("MyMesh", vertex.coords)
230+
# Set the vertex_id as label
231+
id_maps[vertex._id] = vertex_id
232+
233+
for tri in solver.triangular_faces:
234+
# Lookup the precice vertex id using solver vertex id
235+
a = id_maps.get(tri.a._id)
236+
b = id_maps.get(tri.b._id)
237+
c = id_maps.get(tri.c._id)
238+
239+
participant.set_mesh_triangle(mesh_name, a, b, c)
240+
```
241+
242+
</div>
243+
</div>
244+
134245
### Solver supports custom attributes
135246

136247
You solver doesn't provide a unique identifier for each vertex.
@@ -145,6 +256,12 @@ Examples of such attributes:
145256
In this case you can save preCICE Vertex IDs as labels directly in the solver vertices.
146257
Define the vertices using the preCICE API, then iterate over them and apply the preCICE vertex IDs as labels.
147258
When iterating over faces, get the preCICE vertex IDs from the point labels, and use those to define your connectivity.
259+
<ul id="apiTabs" class="nav nav-tabs">
260+
<li class="active"><a href="#cpp-6" data-toggle="tab">C++</a></li>
261+
<li><a href="#python-6" data-toggle="tab">Python</a></li>
262+
</ul>
263+
<div class="tab-content">
264+
<div role="tabpanel" class="tab-pane active" id="cpp-6" markdown="1">
148265

149266
```cpp
150267
Participant participant(...);
@@ -164,6 +281,27 @@ for (auto& tri: solver.triangularFaces) {
164281
}
165282
```
166283
284+
</div>
285+
<div role="tabpanel" class="tab-pane" id="python-6" markdown="1">
286+
287+
```python
288+
participant = precice.Participant(...)
289+
290+
for vertex in solver.vertices:
291+
vertex_id = participant.set_mesh_vertex("MyMesh", vertex.coords)
292+
vertex.label = vertex_id
293+
294+
for tri in solver.triangular_faces:
295+
a = tri.a.label
296+
b = tri.b.label
297+
c = tri.c.label
298+
299+
participant.set_mesh_triangle("MyMesh", a, b, c)
300+
```
301+
302+
</div>
303+
</div>
304+
167305
### Solver supports coordinates only
168306

169307
Your solver provides coordinates only or labels are already used for another purpose.
@@ -173,6 +311,12 @@ Depending on your solver, coordinates available at various stages may be subject
173311
Hence, a C++ `std::map` without custom comparator, or python `dict` may not be sufficient.
174312

175313
An alternative would be to use a spatial index as a data structure to store this information.
314+
<ul id="apiTabs" class="nav nav-tabs">
315+
<li class="active"><a href="#cpp-7" data-toggle="tab">C++</a></li>
316+
<li><a href="#python-7" data-toggle="tab">Python</a></li>
317+
</ul>
318+
<div class="tab-content">
319+
<div role="tabpanel" class="tab-pane active" id="cpp-7" markdown="1">
176320

177321
```cpp
178322
Participant participant(...);
@@ -224,7 +368,8 @@ class IDLookup {
224368
};
225369
```
226370

227-
In python, you could use the rtree package:
371+
</div>
372+
<div role="tabpanel" class="tab-pane" id="python-7" markdown="1">
228373

229374
```py
230375
import rtree
@@ -242,3 +387,6 @@ for tri in solver.triangularFaces:
242387
c = index.nearest(tri.c.coords)
243388
participant.set_mesh_triangle("MyMesh", a, b, c)
244389
```
390+
391+
</div>
392+
</div>

pages/docs/couple-your-code/couple-your-code-gradient-data.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ This feature is available since version 2.4.0.
1111

1212
When using `nearest-neighbor-gradient` mapping, we require coupling data and additional gradient data. We have seen in [Step 3](couple-your-code-mesh-and-data-access.html) how to write data to the mesh.
1313
Now, we will learn how to write gradient data to the mesh. For this purpose, we use the following API method:
14+
<ul id="apiTabs" class="nav nav-tabs">
15+
<li class="active"><a href="#cpp-1" data-toggle="tab">C++</a></li>
16+
<li><a href="#python-1" data-toggle="tab">Python</a></li>
17+
</ul>
18+
<div class="tab-content">
19+
<div role="tabpanel" class="tab-pane active" id="cpp-1" markdown="1">
1420

1521
```cpp
1622
void writeGradientData(
@@ -20,6 +26,15 @@ void writeGradientData(
2026
precice::span<const double> gradients);
2127
```
2228
29+
</div>
30+
<div role="tabpanel" class="tab-pane" id="python-1" markdown="1">
31+
32+
```python
33+
write_gradient_data(mesh_name, data_name, vertex_ids, gradients)
34+
```
35+
36+
</div>
37+
</div>
2338
Let's consider an example for writing block vector gradient data corresponding to the vector data `v0 = (v0x, v0y) , v1 = (v1x, v1y), ... , vn = (vnx, vny)` differentiated in spatial directions x and y.
2439
The values are passed as following:
2540

@@ -31,12 +46,18 @@ The values are passed as following:
3146
```
3247

3348
Let's add gradient data to our example code:
49+
<ul id="apiTabs" class="nav nav-tabs">
50+
<li class="active"><a href="#cpp-2" data-toggle="tab">C++</a></li>
51+
<li><a href="#python-2" data-toggle="tab">Python</a></li>
52+
</ul>
53+
<div class="tab-content">
54+
<div role="tabpanel" class="tab-pane active" id="cpp-2" markdown="1">
3455

3556
```cpp
3657
precice::Participant precice("FluidSolver", "precice-config.xml", rank, size); // constructor
3758

3859
int meshDim = precice.getMeshDimensions("FluidMesh");
39-
int dataDim = precice.getMeshDimensions("FluidMesh", "Stress");
60+
int dataDim = precice.getDataDimensions("FluidMesh", "Stress");
4061
/* ... */
4162
precice.setMeshVertices("FluidMesh", coords, vertexIDs);
4263

@@ -69,6 +90,42 @@ while (not simulationDone()){ // time loop
6990
/* ... */
7091
```
7192
93+
</div>
94+
<div role="tabpanel" class="tab-pane" id="python-2" markdown="1">
95+
96+
```python
97+
precice = precice.Participant("FluidSolver", "precice-config.xml", rank, size)
98+
99+
mesh_dim = precice.get_mesh_dimensions("FluidMesh")
100+
data_dim = precice.get_data_dimensions("FluidMesh", "Stress")
101+
102+
vertex_ids = precice.set_mesh_vertices("FluidMesh", coords)
103+
104+
stress = np.zeros((vertex_size, data_dim))
105+
stress_gradient = np.zeros((vertex_size, data_dim, mesh_dim))
106+
precice.initialize()
107+
108+
while not simulation_done():
109+
precice_dt = precice.get_max_time_step_size()
110+
solver_dt = begin_time_step()
111+
dt = min(precice_dt, solver_dt)
112+
displacements = precice.read_data("FluidMesh", "Displacements", vertex_ids, dt)
113+
set_displacement(displacements)
114+
solve_time_step(dt)
115+
stress = compute_stress()
116+
117+
precice.write_data("FluidMesh", "Stress", vertex_ids, stress)
118+
119+
if precice.requires_gradient_data_for("FluidMesh", "Stress"):
120+
stress_gradient = compute_stress_gradient()
121+
precice.write_gradient_data("FluidMesh", "Stress", vertex_ids, stress_gradient)
122+
123+
precice.advance(dt)
124+
```
125+
126+
</div>
127+
</div>
128+
72129
{% experimental %}
73130
This is an experimental feature.
74131
{% endexperimental %}

0 commit comments

Comments
 (0)