你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
simplified field update calls with inheritance
这个提交包含在:
@@ -14,6 +14,9 @@ from time import perf_counter
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from ..updates import CPUUpdates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_solver(G):
|
def create_solver(G):
|
||||||
"""Return the solver for the given subgrids."""
|
"""Return the solver for the given subgrids."""
|
||||||
@@ -32,10 +35,33 @@ def create_solver(G):
|
|||||||
sgu = SubgridUpdater(sg, precursors, G)
|
sgu = SubgridUpdater(sg, precursors, G)
|
||||||
updaters.append(sgu)
|
updaters.append(sgu)
|
||||||
|
|
||||||
solver = SubGridSolver(G, updaters)
|
updates = SubgridUpdates(G, updaters)
|
||||||
|
solver = SubGridSolver(G, updates)
|
||||||
return solver
|
return solver
|
||||||
|
|
||||||
|
|
||||||
|
class SubgridUpdates(CPUUpdates):
|
||||||
|
|
||||||
|
def __init__(self, G, updaters):
|
||||||
|
super().__init__(G)
|
||||||
|
self.updaters = updaters
|
||||||
|
|
||||||
|
def hsg_1(self):
|
||||||
|
"""Method to update the subgrids over the first phase."""
|
||||||
|
for sg_updater in self.updaters:
|
||||||
|
sg_updater.hsg_1()
|
||||||
|
|
||||||
|
def hsg_2(self):
|
||||||
|
"""Method to update the subgrids over the second phase."""
|
||||||
|
for sg_updater in self.updaters:
|
||||||
|
sg_updater.hsg_2()
|
||||||
|
|
||||||
|
def store_outputs(self, iteration):
|
||||||
|
super().store_outputs(iteration)
|
||||||
|
"""Method to store field outputs for all grid for each main grid iteration."""
|
||||||
|
for updater in self.updaters:
|
||||||
|
updater.store_outputs(iteration)
|
||||||
|
|
||||||
class SubGridSolver:
|
class SubGridSolver:
|
||||||
"""Solver for subgridding simulations."""
|
"""Solver for subgridding simulations."""
|
||||||
|
|
||||||
@@ -44,47 +70,25 @@ class SubGridSolver:
|
|||||||
array.
|
array.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, G, subgrid_updaters, hsg=True):
|
def __init__(self, G, updates, hsg=True):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
G (G): Grid class instance - holds essential parameters
|
G (G): Grid class instance - holds essential parameters
|
||||||
describing the model.
|
describing the model.
|
||||||
subgrid_updaters: (list): list of subgrid_updaters used for updating
|
updates: (list): list of subgrid_updaters used for updating
|
||||||
the subgrids
|
the subgrids
|
||||||
iterations (int): number of iterations for the simulation.
|
|
||||||
hsg (bool): HSG methods for subgrids will not be called if False.
|
hsg (bool): HSG methods for subgrids will not be called if False.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.G = G
|
self.G = G
|
||||||
self.grids = [self.G] + G.subgrids
|
self.updates = updates
|
||||||
self.subgrid_updaters = subgrid_updaters
|
|
||||||
self.materials = G.materials
|
|
||||||
self.abs_time = 0
|
|
||||||
self.hsg = hsg
|
self.hsg = hsg
|
||||||
|
|
||||||
def store_outputs(self):
|
|
||||||
"""Method to store field outputs for all grid for each main grid iteration."""
|
|
||||||
for grid in self.grids:
|
|
||||||
store_outputs(self.G.iteration, grid.Ex, grid.Ey, grid.Ez,
|
|
||||||
grid.Hx, grid.Hy, grid.Hz, grid)
|
|
||||||
|
|
||||||
def store_snapshots(self):
|
def store_snapshots(self):
|
||||||
"""Store any snapshots."""
|
"""Store any snapshots."""
|
||||||
for snap in self.G.snapshots:
|
for snap in self.G.snapshots:
|
||||||
if snap.time == self.G.iteration + 1:
|
if snap.time == self.G.iteration + 1:
|
||||||
snap.store(self.G)
|
snap.store(self.G)
|
||||||
|
|
||||||
def hsg_1(self):
|
|
||||||
"""Method to update the subgrids over the first phase."""
|
|
||||||
for sg_updater in self.subgrid_updaters:
|
|
||||||
sg_updater.hsg_1()
|
|
||||||
|
|
||||||
def hsg_2(self):
|
|
||||||
"""Method to update the subgrids over the second phase."""
|
|
||||||
for sg_updater in self.subgrid_updaters:
|
|
||||||
sg_updater.hsg_2()
|
|
||||||
|
|
||||||
def solve(self, iterations):
|
def solve(self, iterations):
|
||||||
"""Run timestepping."""
|
"""Run timestepping."""
|
||||||
tsolvestart = perf_counter()
|
tsolvestart = perf_counter()
|
||||||
@@ -94,63 +98,26 @@ class SubGridSolver:
|
|||||||
# The main grid FDTD loop
|
# The main grid FDTD loop
|
||||||
for iteration in self.iterations:
|
for iteration in self.iterations:
|
||||||
|
|
||||||
|
self.updates.store_outputs(iteration)
|
||||||
|
#self.updates.store_snapshots(iteration)
|
||||||
|
self.updates.update_magnetic()
|
||||||
|
self.updates.update_magnetic_pml()
|
||||||
|
self.updates.update_magnetic_sources(iteration)
|
||||||
|
self.updates.hsg_2()
|
||||||
|
self.updates.update_electric_a()
|
||||||
|
self.updates.update_electric_pml()
|
||||||
|
self.updates.update_electric_sources(iteration)
|
||||||
|
self.updates.hsg_1()
|
||||||
|
self.updates.update_electric_b()
|
||||||
|
|
||||||
# Keep track of the index. Required for saving output correctly
|
# Keep track of the index. Required for saving output correctly
|
||||||
self.G.iteration = iteration
|
self.G.iteration = iteration
|
||||||
|
|
||||||
# Write any snapshots of the E, H, I fields/currents
|
|
||||||
self.write_snapshots(iteration)
|
|
||||||
|
|
||||||
self.store_outputs()
|
|
||||||
# Update main grid electric field components including sources
|
|
||||||
self.update_magnetic()
|
|
||||||
# Update the fields in the subgrids / main grid
|
|
||||||
if self.hsg:
|
|
||||||
self.hsg_2()
|
|
||||||
|
|
||||||
# Update main grid electric field components including sources
|
|
||||||
self.update_electric()
|
|
||||||
# Update the fields in the subgrids / main grid
|
|
||||||
if self.hsg:
|
|
||||||
self.hsg_1()
|
|
||||||
|
|
||||||
# Return the elapsed time
|
# Return the elapsed time
|
||||||
tsolve = perf_counter() - tsolvestart
|
tsolve = perf_counter() - tsolvestart
|
||||||
|
|
||||||
return tsolve
|
return tsolve
|
||||||
|
|
||||||
def update_electric(self):
|
|
||||||
"""Method to update E fields, PML and electric sources."""
|
|
||||||
# All materials are non-dispersive so do standard update
|
|
||||||
G = self.G
|
|
||||||
|
|
||||||
update_electric(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.ID,
|
|
||||||
G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
|
||||||
|
|
||||||
# Update electric field components with the PML correction
|
|
||||||
for pml in G.pmls:
|
|
||||||
pml.update_electric(G)
|
|
||||||
# Update electric field components from sources (update any Hertzian dipole sources last)
|
|
||||||
for source in G.voltagesources + G.transmissionlines + G.hertziandipoles:
|
|
||||||
source.update_electric(G.iteration, G.updatecoeffsE, G.ID, G.Ex,
|
|
||||||
G.Ey, G.Ez, G)
|
|
||||||
|
|
||||||
def update_magnetic(self):
|
|
||||||
"""Method to update H fields, PML and magnetic sources."""
|
|
||||||
# Update magnetic field components
|
|
||||||
G = self.G
|
|
||||||
|
|
||||||
update_magnetic(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsH, G.ID,
|
|
||||||
G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
|
|
||||||
|
|
||||||
# Update magnetic field components with the PML correction
|
|
||||||
for pml in G.pmls:
|
|
||||||
pml.update_magnetic(G)
|
|
||||||
|
|
||||||
# Update magnetic field components from sources
|
|
||||||
for source in G.transmissionlines + G.magneticdipoles:
|
|
||||||
source.update_magnetic(G.iteration, G.updatecoeffsH, G.ID,
|
|
||||||
G.Hx, G.Hy, G.Hz, G)
|
|
||||||
|
|
||||||
def write_snapshots(self, iteration):
|
def write_snapshots(self, iteration):
|
||||||
# Write any snapshots to file
|
# Write any snapshots to file
|
||||||
for i, snap in enumerate(self.G.snapshots):
|
for i, snap in enumerate(self.G.snapshots):
|
||||||
@@ -169,7 +136,7 @@ class SubGridSolver:
|
|||||||
pbar.close()
|
pbar.close()
|
||||||
|
|
||||||
|
|
||||||
class SubgridUpdater:
|
class SubgridUpdater(CPUUpdates):
|
||||||
"""Class to handle updating the electric and magnetic fields of an HSG
|
"""Class to handle updating the electric and magnetic fields of an HSG
|
||||||
subgrid. The IS, OS, subgrid region and the electric/magnetic sources are updated
|
subgrid. The IS, OS, subgrid region and the electric/magnetic sources are updated
|
||||||
using the precursor regions.
|
using the precursor regions.
|
||||||
@@ -184,7 +151,7 @@ class SubgridUpdater:
|
|||||||
G (class): Grid class instance - holds essential parameters
|
G (class): Grid class instance - holds essential parameters
|
||||||
describing the model.
|
describing the model.
|
||||||
"""
|
"""
|
||||||
self.subgrid = subgrid
|
super().__init__(subgrid)
|
||||||
self.precursors = precursors
|
self.precursors = precursors
|
||||||
self.G = G
|
self.G = G
|
||||||
self.source_iteration = 0
|
self.source_iteration = 0
|
||||||
@@ -193,7 +160,7 @@ class SubgridUpdater:
|
|||||||
"""This is the first half of the subgrid update. Takes the time step
|
"""This is the first half of the subgrid update. Takes the time step
|
||||||
up to the main grid magnetic update"""
|
up to the main grid magnetic update"""
|
||||||
G = self.G
|
G = self.G
|
||||||
sub_grid = self.subgrid
|
sub_grid = self.grid
|
||||||
precursors = self.precursors
|
precursors = self.precursors
|
||||||
|
|
||||||
precursors.update_electric()
|
precursors.update_electric()
|
||||||
@@ -202,73 +169,33 @@ class SubgridUpdater:
|
|||||||
|
|
||||||
for m in range(1, upper_m + 1):
|
for m in range(1, upper_m + 1):
|
||||||
|
|
||||||
# store_outputs(self.grid)
|
|
||||||
# STD update, interpolate inc. field in time, apply correction
|
# STD update, interpolate inc. field in time, apply correction
|
||||||
update_electric(sub_grid.nx,
|
self.update_electric_a()
|
||||||
sub_grid.ny,
|
self.update_electric_pml()
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsE,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_electric(sub_grid)
|
|
||||||
precursors.interpolate_magnetic_in_time(int(m + sub_grid.ratio / 2 - 0.5))
|
precursors.interpolate_magnetic_in_time(int(m + sub_grid.ratio / 2 - 0.5))
|
||||||
sub_grid.update_electric_is(precursors)
|
sub_grid.update_electric_is(precursors)
|
||||||
|
|
||||||
self.update_sub_grid_electric_sources()
|
self.update_sub_grid_electric_sources()
|
||||||
|
|
||||||
# STD update, interpolate inc. field in time, apply correction
|
# STD update, interpolate inc. field in time, apply correction
|
||||||
update_magnetic(sub_grid.nx,
|
self.update_magnetic()
|
||||||
sub_grid.ny,
|
self.update_magnetic_pml()
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsH,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_magnetic(sub_grid)
|
|
||||||
|
|
||||||
precursors.interpolate_electric_in_time(m)
|
precursors.interpolate_electric_in_time(m)
|
||||||
sub_grid.update_magnetic_is(precursors)
|
sub_grid.update_magnetic_is(precursors)
|
||||||
self.update_sub_grid_magnetic_sources()
|
self.update_sub_grid_magnetic_sources()
|
||||||
|
|
||||||
# store_outputs(self.grid)
|
self.update_electric_a()
|
||||||
update_electric(sub_grid.nx,
|
self.update_electric_pml()
|
||||||
sub_grid.ny,
|
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsE,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_electric(sub_grid)
|
|
||||||
precursors.calc_exact_magnetic_in_time()
|
precursors.calc_exact_magnetic_in_time()
|
||||||
sub_grid.update_electric_is(precursors)
|
sub_grid.update_electric_is(precursors)
|
||||||
self.update_sub_grid_electric_sources()
|
self.update_sub_grid_electric_sources()
|
||||||
|
|
||||||
sub_grid.update_electric_os(G)
|
sub_grid.update_electric_os(G)
|
||||||
|
|
||||||
def hsg_2(self):
|
def hsg_2(self):
|
||||||
"""This is the first half of the subgrid update. Takes the time step
|
"""This is the first half of the subgrid update. Takes the time step
|
||||||
up to the main grid electric update"""
|
up to the main grid electric update"""
|
||||||
G = self.G
|
G = self.G
|
||||||
sub_grid = self.subgrid
|
sub_grid = self.grid
|
||||||
precursors = self.precursors
|
precursors = self.precursors
|
||||||
|
|
||||||
precursors.update_magnetic()
|
precursors.update_magnetic()
|
||||||
@@ -277,71 +204,30 @@ class SubgridUpdater:
|
|||||||
|
|
||||||
for m in range(1, upper_m + 1):
|
for m in range(1, upper_m + 1):
|
||||||
|
|
||||||
update_magnetic(sub_grid.nx,
|
self.update_magnetic()
|
||||||
sub_grid.ny,
|
self.update_magnetic_pml()
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsH,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_magnetic(sub_grid)
|
|
||||||
|
|
||||||
precursors.interpolate_electric_in_time(int(m + sub_grid.ratio / 2 - 0.5))
|
precursors.interpolate_electric_in_time(int(m + sub_grid.ratio / 2 - 0.5))
|
||||||
sub_grid.update_magnetic_is(precursors)
|
sub_grid.update_magnetic_is(precursors)
|
||||||
self.update_sub_grid_magnetic_sources()
|
self.update_sub_grid_magnetic_sources()
|
||||||
|
|
||||||
# store_outputs(self.grid)
|
self.update_electric_a()
|
||||||
update_electric(sub_grid.nx,
|
self.update_electric_pml()
|
||||||
sub_grid.ny,
|
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsE,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_electric(sub_grid)
|
|
||||||
|
|
||||||
precursors.interpolate_magnetic_in_time(m)
|
precursors.interpolate_magnetic_in_time(m)
|
||||||
sub_grid.update_electric_is(precursors)
|
sub_grid.update_electric_is(precursors)
|
||||||
self.update_sub_grid_electric_sources()
|
self.update_sub_grid_electric_sources()
|
||||||
|
|
||||||
update_magnetic(sub_grid.nx,
|
|
||||||
sub_grid.ny,
|
|
||||||
sub_grid.nz,
|
|
||||||
G.nthreads,
|
|
||||||
sub_grid.updatecoeffsH,
|
|
||||||
sub_grid.ID,
|
|
||||||
sub_grid.Ex,
|
|
||||||
sub_grid.Ey,
|
|
||||||
sub_grid.Ez,
|
|
||||||
sub_grid.Hx,
|
|
||||||
sub_grid.Hy,
|
|
||||||
sub_grid.Hz)
|
|
||||||
for pml in sub_grid.pmls:
|
|
||||||
pml.update_magnetic(sub_grid)
|
|
||||||
|
|
||||||
|
self.update_magnetic()
|
||||||
|
self.update_magnetic_pml()
|
||||||
precursors.calc_exact_electric_in_time()
|
precursors.calc_exact_electric_in_time()
|
||||||
sub_grid.update_magnetic_is(precursors)
|
sub_grid.update_magnetic_is(precursors)
|
||||||
self.update_sub_grid_magnetic_sources()
|
self.update_sub_grid_magnetic_sources()
|
||||||
|
|
||||||
sub_grid.update_magnetic_os(G)
|
sub_grid.update_magnetic_os(G)
|
||||||
|
|
||||||
def update_sub_grid_electric_sources(self):
|
def update_sub_grid_electric_sources(self):
|
||||||
"""Update any electric sources in the subgrid"""
|
"""Update any electric sources in the subgrid"""
|
||||||
sg = self.subgrid
|
sg = self.grid
|
||||||
for source in sg.voltagesources + sg.transmissionlines + sg.hertziandipoles:
|
for source in sg.voltagesources + sg.transmissionlines + sg.hertziandipoles:
|
||||||
source.update_electric(self.source_iteration, sg.updatecoeffsE, sg.ID,
|
source.update_electric(self.source_iteration, sg.updatecoeffsE, sg.ID,
|
||||||
sg.Ex, sg.Ey, sg.Ez, sg)
|
sg.Ex, sg.Ey, sg.Ez, sg)
|
||||||
@@ -349,7 +235,7 @@ class SubgridUpdater:
|
|||||||
|
|
||||||
def update_sub_grid_magnetic_sources(self):
|
def update_sub_grid_magnetic_sources(self):
|
||||||
"""Update any magnetic sources in the subgrid"""
|
"""Update any magnetic sources in the subgrid"""
|
||||||
sg = self.subgrid
|
sg = self.grid
|
||||||
for source in sg.transmissionlines + sg.magneticdipoles:
|
for source in sg.transmissionlines + sg.magneticdipoles:
|
||||||
source.update_magnetic(self.source_iteration, sg.updatecoeffsH, sg.ID,
|
source.update_magnetic(self.source_iteration, sg.updatecoeffsH, sg.ID,
|
||||||
sg.Hx, sg.Hy, sg.Hz, sg)
|
sg.Hx, sg.Hy, sg.Hz, sg)
|
||||||
|
@@ -62,9 +62,8 @@ class SubGridBase(UserObjectMulti):
|
|||||||
sg.x1, sg.y1, sg.z1 = np.add([sg.x1_u, sg.y1_u, sg.z1_u], sg.is_os_sep * sg.dx)
|
sg.x1, sg.y1, sg.z1 = np.add([sg.x1_u, sg.y1_u, sg.z1_u], sg.is_os_sep * sg.dx)
|
||||||
sg.x2, sg.y2, sg.z2 = np.subtract([sg.x2_u, sg.y2_u, sg.z2_u], sg.is_os_sep * sg.dx)
|
sg.x2, sg.y2, sg.z2 = np.subtract([sg.x2_u, sg.y2_u, sg.z2_u], sg.is_os_sep * sg.dx)
|
||||||
|
|
||||||
def set_name(self):
|
def set_name(self, sg):
|
||||||
self.name = self.kwargs['id']
|
sg.name = self.kwargs['id']
|
||||||
|
|
||||||
|
|
||||||
def set_working_region_cells(self, sg):
|
def set_working_region_cells(self, sg):
|
||||||
"""Number of cells in each dimension for the working region."""
|
"""Number of cells in each dimension for the working region."""
|
||||||
@@ -115,7 +114,7 @@ class SubGridBase(UserObjectMulti):
|
|||||||
self.set_working_region_cells(sg)
|
self.set_working_region_cells(sg)
|
||||||
self.set_total_cells(sg)
|
self.set_total_cells(sg)
|
||||||
self.set_iterations(sg, grid)
|
self.set_iterations(sg, grid)
|
||||||
self.set_name()
|
self.set_name(sg)
|
||||||
|
|
||||||
# Copy a reference for the main grid to the sub grid
|
# Copy a reference for the main grid to the sub grid
|
||||||
sg.parent_grid = grid
|
sg.parent_grid = grid
|
||||||
|
在新工单中引用
屏蔽一个用户