你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-07 23:14:03 +08:00
changes
这个提交包含在:
@@ -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
|
||||||
|
在新工单中引用
屏蔽一个用户