Skip to content

Commit a56a42d

Browse files
committed
fix: MPI test failing fix: re-compute z with the final subdomain samples
1 parent 9d7a27c commit a56a42d

File tree

2 files changed

+49
-46
lines changed

2 files changed

+49
-46
lines changed

tests/test_007_mpi_lossy_cavity.py

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
from scipy.constants import c
1010

1111
from wakis import SolverFIT3D
12-
from wakis import GridFIT3D
12+
from wakis import GridFIT3D
1313
from wakis import WakeSolver
1414
from wakis.sources import Beam
1515

16-
import pytest
16+
import pytest
1717

1818
# Turn true when running local
19-
flag_plot_3D = False
19+
flag_plot_3D = True
2020

2121
@pytest.mark.slow
2222
class TestMPILossyCavity:
@@ -89,7 +89,7 @@ def test_mpi_import(self):
8989
global use_mpi
9090
try:
9191
# can be skipped since it is handled inside GridFIT3D
92-
from mpi4py import MPI
92+
from mpi4py import MPI
9393

9494
comm = MPI.COMM_WORLD # Get MPI communicator
9595
rank = comm.Get_rank() # Process ID
@@ -98,9 +98,10 @@ def test_mpi_import(self):
9898
use_mpi = True
9999
else:
100100
use_mpi = False
101-
except:
101+
except Exception as e:
102+
print(f"[!] MPI not available: {e}")
102103
use_mpi = False
103-
104+
104105
print(f"Using mpi: {use_mpi}")
105106

106107
def test_mpi_simulation(self):
@@ -111,11 +112,11 @@ def test_mpi_simulation(self):
111112
solid_1 = 'tests/stl/007_vacuum_cavity.stl'
112113
solid_2 = 'tests/stl/007_lossymetal_shell.stl'
113114

114-
stl_solids = {'cavity': solid_1,
115+
stl_solids = {'cavity': solid_1,
115116
'shell': solid_2
116117
}
117118

118-
stl_materials = {'cavity': 'vacuum',
119+
stl_materials = {'cavity': 'vacuum',
119120
'shell': [30, 1.0, 30] #[eps_r, mu_r, sigma[S/m]]
120121
}
121122

@@ -128,10 +129,10 @@ def test_mpi_simulation(self):
128129
Ny = 60
129130
NZ = 140
130131
global use_mpi
131-
grid = GridFIT3D(xmin, xmax, ymin, ymax, ZMIN, ZMAX,
132-
Nx, Ny, NZ,
132+
grid = GridFIT3D(xmin, xmax, ymin, ymax, ZMIN, ZMAX,
133+
Nx, Ny, NZ,
133134
use_mpi=use_mpi, # Enables MPI subdivision of the domain
134-
stl_solids=stl_solids,
135+
stl_solids=stl_solids,
135136
stl_materials=stl_materials,
136137
stl_scale=1.0,
137138
stl_rotate=[0,0,0],
@@ -144,7 +145,7 @@ def test_mpi_simulation(self):
144145
# Beam parameters
145146
sigmaz = 10e-2 #[m] -> 2 GHz
146147
q = 1e-9 #[C]
147-
beta = 1.0 # beam beta
148+
beta = 1.0 # beam beta
148149
xs = 0. # x source position [m]
149150
ys = 0. # y source position [m]
150151
ti = 3*sigmaz/c # injection time [s]
@@ -160,19 +161,19 @@ def test_mpi_simulation(self):
160161
# Solver setup
161162
global solver
162163
solver = SolverFIT3D(grid,
163-
bc_low=bc_low,
164-
bc_high=bc_high,
165-
use_stl=True,
164+
bc_low=bc_low,
165+
bc_high=bc_high,
166+
use_stl=True,
166167
use_mpi=use_mpi, # Activate MPI
167168
bg='pec' # Background material
168169
)
169-
170+
170171
# -------------- Output folder ---------------------
171172
if use_mpi and solver.rank == 0:
172-
if not os.path.exists(self.img_folder):
173+
if not os.path.exists(self.img_folder):
173174
os.mkdir(self.img_folder)
174175
elif not use_mpi:
175-
if not os.path.exists(self.img_folder):
176+
if not os.path.exists(self.img_folder):
176177
os.mkdir(self.img_folder)
177178

178179
# -------------- Custom time loop -----------------
@@ -193,7 +194,7 @@ def test_mpi_simulation(self):
193194

194195
beam.update(solver, n*solver.dt)
195196
solver.one_step()
196-
197+
197198
Ez = solver.E[int(Nx/2), int(Ny/2), np.s_[::5], 'z']
198199
#print(Ez)
199200
assert np.allclose(Ez, self.Ez, rtol=0.1), "Electric field Ez samples failed"
@@ -214,44 +215,44 @@ def test_mpi_gather_asField(self):
214215
plt.close(fig)
215216

216217
def test_mpi_plot2D(self):
217-
# Plot E abs in 2D every 20 timesteps
218+
# Plot E abs in 2D every 20 timesteps
218219
global solver
219-
solver.plot2D(field='E', component='Abs',
220-
plane='YZ', pos=0.5,
220+
solver.plot2D(field='E', component='Abs',
221+
plane='YZ', pos=0.5,
221222
cmap='rainbow', vmin=0, vmax=500., interpolation='hanning',
222223
off_screen=True, title=self.img_folder+'Ez2d', n=3000)
223224

224225
def test_mpi_plot1D(self):
225226
# Plot E z in 1D at diferent transverse positions `pos` every 20 timesteps
226227
global solver
227-
solver.plot1D(field='E', component='z',
228-
line='z', pos=[0.45, 0.5, 0.55],
228+
solver.plot1D(field='E', component='z',
229+
line='z', pos=[0.45, 0.5, 0.55],
229230
xscale='linear', yscale='linear',
230231
off_screen=True, title=self.img_folder+'Ez1d', n=3000)
231-
232+
232233
@pytest.mark.skipif(not flag_plot_3D, reason="Requires interactive plotting")
233234
def test_mpi_plot3D(self):
234235
# Plot Abs Electric field on domain
235236
# disabled when mpi = True
236237
global solver
237-
solver.plot3D('E', component='Abs',
238+
solver.plot3D('E', component='Abs',
238239
cmap='rainbow', clim=[0, 500],
239240
add_stl=['cavity', 'shell'], stl_opacity=0.1,
240241
clip_interactive=True, clip_normal='-y')
241-
242-
@pytest.mark.skipif(not flag_plot_3D, reason="Requires interactive plotting")
242+
243+
@pytest.mark.skipif(not flag_plot_3D, reason="Requires interactive plotting")
243244
def test_mpi_plot3DonSTL(self):
244245
# Plot Abs Electric field on STL solid `cavity`
245246
# disabled when mpi = True
246247
global solver
247-
solver.plot3DonSTL('E', component='Abs',
248+
solver.plot3DonSTL('E', component='Abs',
248249
cmap='rainbow', clim=[0, 500],
249250
stl_with_field='cavity', field_opacity=1.0,
250251
stl_transparent='shell', stl_opacity=0.1, stl_colors='white',
251-
clip_plane=True, clip_normal='-y', clip_origin=[0,0,0],
252+
clip_plane=True, clip_normal='-y', clip_origin=[0,0,0],
252253
off_screen=False, zoom=1.2, title=self.img_folder+'Ez3d')
253-
254-
254+
255+
255256
def test_mpi_wakefield(self):
256257
# Reset fields
257258
global solver
@@ -261,12 +262,12 @@ def test_mpi_wakefield(self):
261262
# Beam parameters
262263
sigmaz = 10e-2 #[m] -> 2 GHz
263264
q = 1e-9 #[C]
264-
beta = 1.0 # beam beta
265+
beta = 1.0 # beam beta
265266
xs = 0. # x source position [m]
266267
ys = 0. # y source position [m]
267268
xt = 0. # x test position [m]
268269
yt = 0. # y test position [m]
269-
# [DEFAULT] tinj = 8.53*sigmaz/c_light # injection time offset [s]
270+
# [DEFAULT] tinj = 8.53*sigmaz/c_light # injection time offset [s]
270271

271272
# ----------- Wake Solver setup ----------
272273
# Wakefield post-processor
@@ -282,9 +283,9 @@ def test_mpi_wakefield(self):
282283
Ez_file=results_folder+'Ez.h5',)
283284

284285
# Run simulation
285-
solver.wakesolve(wakelength=wakelength,
286+
solver.wakesolve(wakelength=wakelength,
286287
wake=wake)
287-
288+
288289
def test_long_wake_potential(self):
289290
global wake
290291
global solver
@@ -314,4 +315,3 @@ def test_long_impedance(self):
314315
assert np.allclose(np.real(wake.Z)[::20], np.real(self.Z), rtol=0.1), "Real Impedance samples failed"
315316
assert np.allclose(np.imag(wake.Z)[::20], np.imag(self.Z), rtol=0.1), "Imag Impedance samples failed"
316317
assert np.cumsum(np.abs(wake.Z))[-1] == pytest.approx(250910.51090497518, 0.1), "Abs Impedance cumsum failed"
317-

wakis/gridFIT3D.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,11 @@ def __init__(self, xmin=None, xmax=None,
119119
self.Nx = len(self.x) - 1
120120
self.Ny = len(self.y) - 1
121121
self.Nz = len(self.z) - 1
122-
self.dx = np.min(np.diff(self.x))
123-
self.dy = np.min(np.diff(self.y))
124-
self.dz = np.min(np.diff(self.z))
125122
self.xmin, self.xmax = self.x[0], self.x[-1]
126123
self.ymin, self.ymax = self.y[0], self.y[-1]
127124
self.zmin, self.zmax = self.z[0], self.z[-1]
125+
if self.use_mpi:
126+
raise ValueError("[!] Error: use_mpi=True is not compatible with custom x,y,z arrays.")
128127

129128
# generate from domain extents and number of cells [LEGACY]
130129
elif all(v is not None for v in [xmin, xmax, ymin, ymax, zmin, zmax]):
@@ -133,9 +132,6 @@ def __init__(self, xmin=None, xmax=None,
133132
self.ymin, self.ymax = ymin, ymax
134133
self.zmin, self.zmax = zmin, zmax
135134
self.Nx, self.Ny, self.Nz = Nx, Ny, Nz
136-
self.dx = (self.xmax - self.xmin) / self.Nx
137-
self.dy = (self.ymax - self.ymin) / self.Ny
138-
self.dz = (self.zmax - self.zmin) / self.Nz
139135
self.x = np.linspace(self.xmin, self.xmax, self.Nx+1)
140136
self.y = np.linspace(self.ymin, self.ymax, self.Ny+1)
141137
self.z = np.linspace(self.zmin, self.zmax, self.Nz+1)
@@ -148,6 +144,10 @@ def __init__(self, xmin=None, xmax=None,
148144
" - OR load from a HDF5 file using load_from_h5"
149145
)
150146

147+
self.dx = np.min(np.diff(self.x))
148+
self.dy = np.min(np.diff(self.y))
149+
self.dz = np.min(np.diff(self.z))
150+
151151
# refine self.x, self.y, self.z using snap points
152152
self.use_mesh_refinement = use_mesh_refinement
153153
self.refinement_method = refinement_method
@@ -171,9 +171,6 @@ def __init__(self, xmin=None, xmax=None,
171171
z:[{zmin:.3f}, {zmax:.3f}]')
172172
t0 = time.time()
173173

174-
# grid G and tilde grid ~G, lengths and inverse areas
175-
self.compute_grid()
176-
177174
# MPI subdivide domain
178175
if self.use_mpi:
179176
self.ZMIN = None
@@ -187,6 +184,9 @@ def __init__(self, xmin=None, xmax=None,
187184
else:
188185
raise ImportError("[!] mpi4py is required when use_mpi=True but was not found")
189186

187+
# grid G and tilde grid ~G, lengths and inverse areas
188+
self.compute_grid()
189+
190190
# tolerance for stl import tol*min(dx,dy,dz)
191191
if verbose:
192192
print('Importing STL solids...')
@@ -201,6 +201,7 @@ def __init__(self, xmin=None, xmax=None,
201201

202202

203203
def compute_grid(self):
204+
204205
X, Y, Z = np.meshgrid(self.x, self.y, self.z, indexing='ij')
205206
self.grid = pv.StructuredGrid(X.transpose(), Y.transpose(), Z.transpose())
206207

@@ -281,6 +282,8 @@ def mpi_initialize(self):
281282
self.zmax += self.n_ghosts * self.dz
282283
self.Nz += self.n_ghosts
283284

285+
self.z = np.linspace(self.zmin, self.zmax, self.Nz+1)
286+
284287
def mpi_gather_asGrid(self):
285288
_grid = None
286289
if self.rank == 0:

0 commit comments

Comments
 (0)