Skip to content

Commit c275e02

Browse files
committed
3D initial conditions in Gray-Scott
1 parent 1196767 commit c275e02

File tree

3 files changed

+54
-23
lines changed

3 files changed

+54
-23
lines changed

pySDC/implementations/problem_classes/GrayScott_MPIFFT.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ def u_exact(self, t, seed=10700000):
200200
Exact solution.
201201
"""
202202
assert t == 0.0, 'Exact solution only valid as initial condition'
203-
assert self.ndim == 2, 'The initial conditions are 2D for now..'
204203

205204
xp = self.xp
206205

@@ -222,12 +221,13 @@ def u_exact(self, t, seed=10700000):
222221
_v[...] = xp.sqrt(F) * (A + xp.sqrt(A**2 - 4)) / 2
223222

224223
for _ in range(-self.num_blobs):
225-
x0, y0 = rng.random(size=2) * self.L[0] - self.L[0] / 2
226-
lx, ly = rng.random(size=2) * self.L[0] / self.nvars[0] * 30
224+
x0 = rng.random(size=self.ndim) * self.L[0] - self.L[0] / 2
225+
l = rng.random(size=self.ndim) * self.L[0] / self.nvars[0] * 30
227226

228-
mask_x = xp.logical_and(self.X[0] > x0, self.X[0] < x0 + lx)
229-
mask_y = xp.logical_and(self.X[1] > y0, self.X[1] < y0 + ly)
230-
mask = xp.logical_and(mask_x, mask_y)
227+
masks = [xp.logical_and(self.X[i] > x0[i], self.X[i] < x0[i] + l[i]) for i in range(self.ndim)]
228+
mask = masks[0]
229+
for m in masks[1:]:
230+
mask = xp.logical_and(mask, m)
231231

232232
_u[mask] = rng.random()
233233
_v[mask] = rng.random()
@@ -236,6 +236,7 @@ def u_exact(self, t, seed=10700000):
236236
"""
237237
Blobs as in https://www.chebfun.org/examples/pde/GrayScott.html
238238
"""
239+
assert self.ndim == 2, 'The initial conditions are 2D for now..'
239240

240241
inc = self.L[0] / (self.num_blobs + 1)
241242

pySDC/implementations/problem_classes/generic_MPIFFT_Laplacian.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class IMEX_Laplacian_MPIFFT(Problem):
1111
r"""
1212
Generic base class for IMEX problems using a spectral method to solve the Laplacian implicitly and a possible rest
1313
explicitly. The FFTs are done with``mpi4py-fft`` [1]_.
14+
Works in two and three dimensions.
1415
1516
Parameters
1617
----------

pySDC/projects/GPU/configs/GS_configs.py

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class GrayScott(Config):
2727
num_frames = 200
2828
sweeper_type = 'IMEX'
2929
res_per_blob = 2**7
30+
ndim = 3
3031

3132
def get_LogToFile(self, ranks=None):
3233
import numpy as np
@@ -49,16 +50,14 @@ def process_solution(L):
4950
't': L.time + L.dt,
5051
'u': uend[0].get().view(np.ndarray),
5152
'v': uend[1].get().view(np.ndarray),
52-
'X': L.prob.X[0].get().view(np.ndarray),
53-
'Y': L.prob.X[1].get().view(np.ndarray),
53+
'X': L.prob.X.get().view(np.ndarray),
5454
}
5555
else:
5656
return {
5757
't': L.time + L.dt,
5858
'u': uend[0],
5959
'v': uend[1],
60-
'X': L.prob.X[0],
61-
'Y': L.prob.X[1],
60+
'X': L.prob.X,
6261
}
6362

6463
def logging_condition(L):
@@ -75,7 +74,7 @@ def logging_condition(L):
7574
LogToFile.logging_condition = logging_condition
7675
return LogToFile
7776

78-
def plot(self, P, idx, n_procs_list): # pragma: no cover
77+
def plot(self, P, idx, n_procs_list, projection='xy'): # pragma: no cover
7978
import numpy as np
8079
from matplotlib import ticker as tkr
8180

@@ -99,19 +98,49 @@ def plot(self, P, idx, n_procs_list): # pragma: no cover
9998
vmax['u'] = max([vmax['u'], buffer[f'u-{rank}']['u'].real.max()])
10099

101100
for rank in range(n_procs_list[2]):
102-
im = ax.pcolormesh(
103-
buffer[f'u-{rank}']['X'],
104-
buffer[f'u-{rank}']['Y'],
105-
buffer[f'u-{rank}']['v'].real,
106-
vmin=vmin['v'],
107-
vmax=vmax['v'],
108-
cmap='binary',
109-
)
101+
if len(buffer[f'u-{rank}']['X']) == 2:
102+
ax.set_xlabel('$x$')
103+
ax.set_ylabel('$y$')
104+
im = ax.pcolormesh(
105+
buffer[f'u-{rank}']['X'][0],
106+
buffer[f'u-{rank}']['X'][1],
107+
buffer[f'u-{rank}']['v'].real,
108+
vmin=vmin['v'],
109+
vmax=vmax['v'],
110+
cmap='binary',
111+
)
112+
else:
113+
v3d = buffer[f'u-{rank}']['v'].real
114+
115+
if projection == 'xy':
116+
slices = [slice(None), slice(None), v3d.shape[2] // 2]
117+
x = buffer[f'u-{rank}']['X'][0][*slices]
118+
y = buffer[f'u-{rank}']['X'][1][*slices]
119+
ax.set_xlabel('$x$')
120+
ax.set_ylabel('$y$')
121+
elif projection == 'xz':
122+
slices = [slice(None), v3d.shape[1] // 2, slice(None)]
123+
x = buffer[f'u-{rank}']['X'][0][*slices]
124+
y = buffer[f'u-{rank}']['X'][2][*slices]
125+
ax.set_xlabel('$x$')
126+
ax.set_ylabel('$z$')
127+
elif projection == 'yz':
128+
slices = [v3d.shape[0] // 2, slice(None), slice(None)]
129+
x = buffer[f'u-{rank}']['X'][1][*slices]
130+
y = buffer[f'u-{rank}']['X'][2][*slices]
131+
ax.set_xlabel('$y$')
132+
ax.set_ylabel('$z$')
133+
134+
im = ax.pcolormesh(
135+
x,
136+
y,
137+
v3d[*slices],
138+
vmin=vmin['v'],
139+
vmax=vmax['v'],
140+
cmap='binary',
141+
)
110142
fig.colorbar(im, cax, format=tkr.FormatStrFormatter('%.1f'))
111143
ax.set_title(f't={buffer[f"u-{rank}"]["t"]:.2f}')
112-
ax.set_xlabel('$x$')
113-
ax.set_ylabel('$y$')
114-
ax.set_aspect(1.0)
115144
ax.set_aspect(1.0)
116145
return fig
117146

@@ -130,7 +159,7 @@ def get_description(self, *args, res=-1, **kwargs):
130159
desc['sweeper_params']['QI'] = 'MIN-SR-S'
131160
desc['sweeper_params']['QE'] = 'PIC'
132161

133-
desc['problem_params']['nvars'] = (2**8 if res == -1 else res,) * 2
162+
desc['problem_params']['nvars'] = (2**8 if res == -1 else res,) * self.ndim
134163
desc['problem_params']['Du'] = 0.00002
135164
desc['problem_params']['Dv'] = 0.00001
136165
desc['problem_params']['A'] = 0.04

0 commit comments

Comments
 (0)