这个提交包含在:
jasminium
2019-08-23 18:06:03 +01:00
父节点 910d2752a0
当前提交 d9c5ed34f9
共有 38 个文件被更改,包括 9310 次插入9390 次删除

查看文件

@@ -17,12 +17,11 @@
# along with gprMax. If not, see <http://www.gnu.org/licenses/>. # along with gprMax. If not, see <http://www.gnu.org/licenses/>.
from gprMax.updates import CPUUpdates from gprMax.updates import CPUUpdates
from gprMax.updates import GPUUpdates from gprMax.updates import GPUUpdates
from .subgrids.updates import create_updates as create_subgrid_updates
from gprMax.utilities import timer from gprMax.utilities import timer
from .grid import FDTDGrid from .grid import FDTDGrid
from .grid import GPUGrid from .grid import GPUGrid
import gprMax.config as config import gprMax.config as config
from .subgrids.solver import create_updates as create_subgrid_updates
from .subgrids.solver import SubGridSolver
def create_G(sim_config): def create_G(sim_config):
@@ -44,7 +43,7 @@ def create_solver(G, sim_config):
solver = Solver(updates) solver = Solver(updates)
elif sim_config.subgrid: elif sim_config.subgrid:
updates = create_subgrid_updates(G) updates = create_subgrid_updates(G)
solver = SubGridSolver(G, updates) solver = Solver(updates, hsg=True)
else: else:
updates = CPUUpdates(G) updates = CPUUpdates(G)
solver = Solver(updates) solver = Solver(updates)
@@ -61,7 +60,7 @@ class Solver:
"""Generic solver for Update objects""" """Generic solver for Update objects"""
def __init__(self, updates): def __init__(self, updates, hsg=False):
"""Context for the model to run in. Sub-class this with contexts """Context for the model to run in. Sub-class this with contexts
i.e. an MPI context. i.e. an MPI context.
@@ -70,6 +69,7 @@ class Solver:
iterator (iterator): can be range() or tqdm() iterator (iterator): can be range() or tqdm()
""" """
self.updates = updates self.updates = updates
self.hsg = hsg
def get_G(self): def get_G(self):
return self.updates.G return self.updates.G
@@ -78,15 +78,18 @@ class Solver:
"""Time step the FDTD model.""" """Time step the FDTD model."""
tsolvestart = timer() tsolvestart = timer()
for iteration in iterator: for iteration in iterator:
self.updates.grid.iteration = iteration
self.updates.store_outputs() self.updates.store_outputs()
self.updates.store_snapshots(iteration) self.updates.store_snapshots(iteration)
self.updates.update_magnetic() self.updates.update_magnetic()
self.updates.update_magnetic_pml() self.updates.update_magnetic_pml()
self.updates.update_magnetic_sources(iteration) self.updates.update_magnetic_sources()
if self.hsg:
self.updates.hsg_2()
self.updates.update_electric_a() self.updates.update_electric_a()
self.updates.update_electric_pml() self.updates.update_electric_pml()
self.updates.update_electric_sources(iteration) self.updates.update_electric_sources()
if self.hsg:
self.updates.hsg_1()
self.updates.update_electric_b() self.updates.update_electric_b()
tsolve = timer() - tsolvestart tsolve = timer() - tsolvestart

查看文件

@@ -1,3 +1,20 @@
# Copyright (C) 2015-2019: The University of Edinburgh
# Authors: Craig Warren and Antonis Giannopoulos
#
# This file is part of gprMax.
#
# gprMax is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# gprMax is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
from ..cython.fields_updates_normal import update_electric from ..cython.fields_updates_normal import update_electric
from ..cython.fields_updates_normal import update_magnetic from ..cython.fields_updates_normal import update_magnetic
from ..fields_outputs import store_outputs from ..fields_outputs import store_outputs
@@ -16,8 +33,6 @@ import sys
from ..updates import CPUUpdates from ..updates import CPUUpdates
def create_updates(G): def create_updates(G):
"""Return the solver for the given subgrids.""" """Return the solver for the given subgrids."""
updaters = [] updaters = []
@@ -54,79 +69,6 @@ class SubgridUpdates(CPUUpdates):
for sg_updater in self.updaters: for sg_updater in self.updaters:
sg_updater.hsg_2() sg_updater.hsg_2()
class SubGridSolver:
"""Solver for subgridding simulations."""
"""Class to call the various update methods required for an HSG-Subgrid simulation.
Multiple subgrids can be updated by adding more subgrid_updater objects to the subgrid_updater
array.
"""
def __init__(self, G, updates, hsg=True):
"""
Args:
G (G): Grid class instance - holds essential parameters
describing the model.
updates: (list): list of subgrid_updaters used for updating
the subgrids
hsg (bool): HSG methods for subgrids will not be called if False.
"""
self.G = G
self.updates = updates
self.hsg = hsg
def store_snapshots(self):
"""Store any snapshots."""
for snap in self.G.snapshots:
if snap.time == self.G.iteration + 1:
snap.store(self.G)
def solve(self, iterations):
"""Run timestepping."""
tsolvestart = perf_counter()
self.iterations = iterations
# for time step in range(self.G.iterations):
# The main grid FDTD loop
for iteration in self.iterations:
self.updates.grid.iteration = iteration
self.updates.store_outputs()
#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
self.G.iteration = iteration
# Return the elapsed time
tsolve = perf_counter() - tsolvestart
return tsolve
def write_snapshots(self, iteration):
# Write any snapshots to file
for i, snap in enumerate(self.G.snapshots):
if snap.time == iteration + 1:
snapiters = 36 * (((snap.xf - snap.xs) / snap.dx) * ((snap.yf - snap.ys) / snap.dy) * ((snap.zf - snap.zs) / snap.dz))
pbar = tqdm(total=snapiters, leave=False, unit='byte', unit_scale=True, desc=' Writing snapshot file {} of {}, {}'.format(i + 1, len(self.G.snapshots), os.path.split(snap.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=self.G.tqdmdisable)
# Use this call to print out main grid and subgrids
snap.write_vtk_imagedata(self.G.Ex, self.G.Ey, self.G.Ez, self.G.Hx, self.G.Hy, self.G.Hz, self.G, pbar, sub_grids=self.G.subgrids)
# Use this call to print out the standard grid without subgrid
# snap.write_vtk_imagedata(self.G.Ex, self.G.Ey, self.G.Ez, self.G.Hx, self.G.Hy, self.G.Hz, self.G, pbar)
# Use this call to print out only the subgrid - use in combination with commented code in .multi_cmds/snapshots.py
# snap.write_vtk_imagedata_fast(self.grid)
pbar.close()
class SubgridUpdater(CPUUpdates): 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
@@ -139,7 +81,7 @@ class SubgridUpdater(CPUUpdates):
Args: Args:
subgrid (SubGrid3d): Subgrid to be updated subgrid (SubGrid3d): Subgrid to be updated
precursors (PrecursorNodes): Precursor nodes associated with precursors (PrecursorNodes): Precursor nodes associated with
the subgrid the subgrid - contain interpolated fields
G (class): Grid class instance - holds essential parameters G (class): Grid class instance - holds essential parameters
describing the model. describing the model.
""" """
@@ -169,14 +111,14 @@ class SubgridUpdater(CPUUpdates):
sub_grid.update_electric_is(precursors) sub_grid.update_electric_is(precursors)
self.update_electric_b() self.update_electric_b()
self.update_sub_grid_electric_sources() self.update_electric_sources()
# STD update, interpolate inc. field in time, apply correction # STD update, interpolate inc. field in time, apply correction
self.update_magnetic() self.update_magnetic()
self.update_magnetic_pml() self.update_magnetic_pml()
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_magnetic_sources()
self.store_outputs() self.store_outputs()
self.update_electric_a() self.update_electric_a()
@@ -184,7 +126,7 @@ class SubgridUpdater(CPUUpdates):
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_electric_b() self.update_electric_b()
self.update_sub_grid_electric_sources() self.update_electric_sources()
sub_grid.update_electric_os(G) sub_grid.update_electric_os(G)
def hsg_2(self): def hsg_2(self):
@@ -205,7 +147,7 @@ class SubgridUpdater(CPUUpdates):
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_magnetic_sources()
self.store_outputs() self.store_outputs()
self.update_electric_a() self.update_electric_a()
@@ -215,27 +157,11 @@ class SubgridUpdater(CPUUpdates):
sub_grid.update_electric_is(precursors) sub_grid.update_electric_is(precursors)
self.update_electric_b() self.update_electric_b()
self.update_sub_grid_electric_sources() self.update_electric_sources()
self.update_magnetic() self.update_magnetic()
self.update_magnetic_pml() 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_magnetic_sources()
sub_grid.update_magnetic_os(G) sub_grid.update_magnetic_os(G)
def update_sub_grid_electric_sources(self):
"""Update any electric sources in the subgrid"""
sg = self.grid
for source in sg.voltagesources + sg.transmissionlines + sg.hertziandipoles:
source.update_electric(self.source_iteration, sg.updatecoeffsE, sg.ID,
sg.Ex, sg.Ey, sg.Ez, sg)
self.source_iteration += 1
self.grid.iteration = self.source_iteration
def update_sub_grid_magnetic_sources(self):
"""Update any magnetic sources in the subgrid"""
sg = self.grid
for source in sg.transmissionlines + sg.magneticdipoles:
source.update_magnetic(self.source_iteration, sg.updatecoeffsH, sg.ID,
sg.Hx, sg.Hy, sg.Hz, sg)

查看文件

@@ -45,22 +45,12 @@ class SubGridBase(UserObjectMulti):
def set_main_grid_indices(self, sg, grid, uip, p1, p2): def set_main_grid_indices(self, sg, grid, uip, p1, p2):
"""Set subgrid indices related to main grid placement.""" """Set subgrid indices related to main grid placement."""
# Main grid indices of the sub grid. These are dummy indices. They are # location of the IS
# not user internal except for printing to the user sg.i0, sg.j0, sg.k0 = p1
sg.i0_u, sg.j0_u, sg.k0_u = p1 sg.i1, sg.j1, sg.k1 = p2
sg.i1_u, sg.j1_u, sg.k1_u = p2
# The actual sub gridded area (IS index) is 4 cells in sg.x1, sg.y1, sg.z1 = uip.round_to_grid(p1)
sg.i0, sg.j0, sg.k0 = np.add([sg.i0_u, sg.j0_u, sg.k0_u], sg.is_os_sep) sg.x2, sg.y2, sg.z2 = uip.round_to_grid(p2)
sg.i1, sg.j1, sg.k1 = np.subtract([sg.i1_u, sg.j1_u, sg.k1_u], sg.is_os_sep)
# Main grid indices of the sub grid. These are dummy indices. They are
# not user internal except for printing to the user
sg.x1_u, sg.y1_u, sg.z1_u = uip.round_to_grid(p1)
sg.x2_u, sg.y2_u, sg.z2_u = uip.round_to_grid(p2)
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)
def set_name(self, sg): def set_name(self, sg):
sg.name = self.kwargs['id'] sg.name = self.kwargs['id']

查看文件

@@ -59,10 +59,10 @@ class CPUUpdates:
for pml in self.grid.pmls: for pml in self.grid.pmls:
pml.update_magnetic(self.grid) pml.update_magnetic(self.grid)
def update_magnetic_sources(self, iteration): def update_magnetic_sources(self):
# Update magnetic field components from sources # Update magnetic field components from sources
for source in self.grid.transmissionlines + self.grid.magneticdipoles: for source in self.grid.transmissionlines + self.grid.magneticdipoles:
source.update_magnetic(iteration, source.update_magnetic(self.grid.iteration,
self.grid.updatecoeffsH, self.grid.updatecoeffsH,
self.grid.ID, self.grid.ID,
self.grid.Hx, self.grid.Hx,
@@ -113,10 +113,11 @@ class CPUUpdates:
for pml in self.grid.pmls: for pml in self.grid.pmls:
pml.update_electric(self.grid) pml.update_electric(self.grid)
def update_electric_sources(self, iteration): def update_electric_sources(self):
# Update electric field components from sources (update any Hertzian dipole sources last) # Update electric field components from sources (update any Hertzian dipole sources last)
for source in self.grid.voltagesources + self.grid.transmissionlines + self.grid.hertziandipoles: for source in self.grid.voltagesources + self.grid.transmissionlines + self.grid.hertziandipoles:
source.update_electric(iteration, self.grid.updatecoeffsE, self.grid.ID, self.grid.Ex, self.grid.Ey, self.grid.Ez, self.grid) source.update_electric(self.grid.iteration, self.grid.updatecoeffsE, self.grid.ID, self.grid.Ex, self.grid.Ey, self.grid.Ez, self.grid)
self.grid.iteration += 1
def update_electric_b(self): def update_electric_b(self):
# If there are any dispersive materials do 2nd part of dispersive update # If there are any dispersive materials do 2nd part of dispersive update