simplified field update calls with inheritance

这个提交包含在:
John Hartley
2019-08-23 15:35:16 +01:00
父节点 57d307acf9
当前提交 2d16ccc1f6
共有 2 个文件被更改,包括 63 次插入178 次删除

查看文件

@@ -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