Skip to content

Commit a977a22

Browse files
committed
Added growing mesh case
1 parent 4792c08 commit a977a22

File tree

5 files changed

+206
-0
lines changed

5 files changed

+206
-0
lines changed

growing-mesh/precice-config.xml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<precice-configuration experimental="True" allow-remeshing="True">
3+
<log>
4+
<sink
5+
filter="%Severity% >= debug and %Rank% = 0"
6+
format="---[precice] %ColorizedSeverity% %Message%"
7+
enabled="true" />
8+
</log>
9+
10+
<profiling mode="all" />
11+
12+
<data:scalar name="Data-Left" />
13+
<data:scalar name="Data-Right" />
14+
15+
<mesh name="Left-Mesh" dimensions="3">
16+
<use-data name="Data-Left" />
17+
<use-data name="Data-Right" />
18+
</mesh>
19+
20+
<mesh name="Right-Mesh" dimensions="3">
21+
<use-data name="Data-Left" />
22+
<use-data name="Data-Right" />
23+
</mesh>
24+
25+
<participant name="Left">
26+
<provide-mesh name="Left-Mesh" />
27+
<write-data name="Data-Left" mesh="Left-Mesh" />
28+
<read-data name="Data-Right" mesh="Left-Mesh" />
29+
<receive-mesh name="Right-Mesh" from="Right" />
30+
<mapping:nearest-neighbor
31+
direction="read"
32+
from="Right-Mesh"
33+
to="Left-Mesh"
34+
constraint="consistent" />
35+
</participant>
36+
37+
<participant name="Right">
38+
<provide-mesh name="Right-Mesh" />
39+
<read-data name="Data-Left" mesh="Right-Mesh" />
40+
<write-data name="Data-Right" mesh="Right-Mesh" />
41+
<receive-mesh name="Left-Mesh" from="Left" />
42+
<mapping:nearest-neighbor
43+
direction="read"
44+
from="Left-Mesh"
45+
to="Right-Mesh"
46+
constraint="consistent" />
47+
</participant>
48+
49+
<m2n:sockets acceptor="Left" connector="Right" exchange-directory=".." />
50+
51+
<coupling-scheme:parallel-explicit>
52+
<time-window-size value="1" />
53+
<max-time-windows value="12" />
54+
<participants first="Left" second="Right" />
55+
<exchange data="Data-Left" mesh="Left-Mesh" from="Left" to="Right" />
56+
<exchange data="Data-Right" mesh="Right-Mesh" from="Right" to="Left" />
57+
</coupling-scheme:parallel-explicit>
58+
</precice-configuration>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mpi4py
2+
pyprecice @ git+https://github.com/precice/python-bindings.git@develop

growing-mesh/solver/run_left.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
set -e -u
3+
4+
python3 -m venv .venvl
5+
. .venvl/bin/activate
6+
pip install -r requirements.txt
7+
8+
if [ $# -eq 0 ]; then
9+
python3 solver.py Left
10+
else
11+
mpirun -n "$@" python3 solver.py Left
12+
fi

growing-mesh/solver/run_right.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/sh
2+
set -e -u
3+
4+
python3 -m venv .venvr
5+
. .venvr/bin/activate
6+
pip install -r requirements.txt
7+
8+
if [ $# -eq 0 ]; then
9+
python3 solver.py Right
10+
else
11+
mpirun -n "$@" python3 solver.py Right
12+
fi

growing-mesh/solver/solver.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/bin/python3
2+
3+
import precice
4+
import numpy as np
5+
import math
6+
import sys
7+
from mpi4py import MPI
8+
9+
import argparse
10+
11+
parser = argparse.ArgumentParser()
12+
parser.add_argument("participant", choices=["Left", "Right"])
13+
parser.add_argument("--config", "-c", default="../precice-config.xml")
14+
parser.add_argument("--no-remesh", dest="remesh", action="store_false")
15+
args = parser.parse_args()
16+
17+
participant_name = args.participant
18+
remote_name = "Left" if participant_name == "Right" else "Right"
19+
20+
# x is partitioned per rank and doesn't change
21+
nx = 256 * 3
22+
x = 0.0, 1.0
23+
ny = 256 * 3
24+
y = 0.0, 1.0
25+
26+
# y grows over time
27+
newNodesPerEvent = 2
28+
eventFrequency = 3 # time windows
29+
dz = 0.1
30+
31+
32+
# Handle partitioning
33+
world = MPI.COMM_WORLD
34+
size: int = world.size
35+
rank: int = world.rank
36+
37+
parts: int = int(math.sqrt(size))
38+
assert parts**2 == size, "size must be a square value"
39+
assert math.remainder(nx, parts) == 0, f"{nx=} must be dividable by {parts=}"
40+
41+
# current parition in x, y
42+
px = rank % parts
43+
py = rank // parts
44+
45+
# nodes per parition
46+
nxp = nx // parts
47+
nyp = ny // parts
48+
49+
# node slide per partition
50+
nxps = slice(nxp * px, nxp * (px + 1))
51+
nyps = slice(nyp * py, nyp * (py + 1))
52+
53+
print(f"{rank=} {nxps=} {nyps=}")
54+
55+
56+
def requiresEvent(tw):
57+
return tw % eventFrequency == 0
58+
59+
60+
assert not requiresEvent(eventFrequency - 1)
61+
assert requiresEvent(eventFrequency)
62+
assert not requiresEvent(eventFrequency + 1)
63+
64+
65+
def eventsAt(tw):
66+
# First event block at tw=0, second at eventFrequency
67+
return 1 + math.floor(tw / eventFrequency)
68+
69+
70+
assert eventsAt(0) == 1
71+
assert eventsAt(eventFrequency - 1) == 1
72+
assert eventsAt(eventFrequency) == 2
73+
assert eventsAt(eventFrequency + 1) == 2
74+
75+
76+
def getMeshAtTimeWindow(tw):
77+
znodes = eventsAt(tw) * newNodesPerEvent
78+
79+
xs = np.linspace(x[0], x[1], nx)[nxps]
80+
ys = np.linspace(y[0], y[1], ny)[nyps]
81+
zs = np.array(range(znodes)) * dz
82+
83+
return np.reshape([(x, y, z) for z in zs for y in ys for x in xs], (-1, 3))
84+
85+
86+
participant = precice.Participant(participant_name, args.config, rank, size)
87+
88+
mesh_name = participant_name + "-Mesh"
89+
read_data_name = "Data-" + remote_name
90+
write_data_name = "Data-" + participant_name
91+
92+
coords = getMeshAtTimeWindow(0)
93+
vertex_ids = participant.set_mesh_vertices(mesh_name, coords)
94+
participant.initialize()
95+
96+
tw = 1
97+
while participant.is_coupling_ongoing():
98+
dt = participant.get_max_time_step_size()
99+
100+
data = participant.read_data(mesh_name, read_data_name, vertex_ids, dt)
101+
if rank == 0:
102+
print(data)
103+
104+
if args.remesh and requiresEvent(tw):
105+
oldCount = len(coords)
106+
coords = getMeshAtTimeWindow(tw)
107+
if rank == 0:
108+
print(
109+
f"Event grows local mesh from {oldCount} to {
110+
len(coords)} and global mesh from {
111+
oldCount *
112+
size} to {
113+
len(coords) *
114+
size}")
115+
participant.reset_mesh(mesh_name)
116+
vertex_ids = participant.set_mesh_vertices(mesh_name, coords)
117+
118+
data = np.full(len(coords), tw)
119+
participant.write_data(mesh_name, write_data_name, vertex_ids, data)
120+
121+
participant.advance(dt)
122+
tw += 1

0 commit comments

Comments
 (0)