Update multiuse cmds to new user object classes

这个提交包含在:
nmannall
2024-12-10 14:14:18 +00:00
父节点 e818441730
当前提交 b401f1d00d
共有 6 个文件被更改,包括 490 次插入355 次删除

查看文件

@@ -110,7 +110,7 @@ class Snapshot:
filename: str, filename: str,
fileext: str, fileext: str,
outputs: Dict[str, bool], outputs: Dict[str, bool],
grid_dl: npt.NDArray[np.float32], grid_dl: npt.NDArray[np.float64],
grid_dt: float, grid_dt: float,
): ):
""" """
@@ -358,7 +358,7 @@ class MPISnapshot(Snapshot):
filename: str, filename: str,
fileext: str, fileext: str,
outputs: Dict[str, bool], outputs: Dict[str, bool],
grid_dl: npt.NDArray[np.float32], grid_dl: npt.NDArray[np.float64],
grid_dt: float, grid_dt: float,
): ):
super().__init__( super().__init__(

文件差异内容过多而无法显示 加载差异

查看文件

@@ -0,0 +1,180 @@
import logging
from gprMax.geometry_outputs import GeometryObjects as GeometryObjectsUser
from gprMax.geometry_outputs import MPIGeometryObjects as MPIGeometryObjectsUser
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.grid.mpi_grid import MPIGrid
from gprMax.model import Model
from gprMax.subgrids.grid import SubGridBaseGrid
from gprMax.user_objects.user_objects import OutputUserObject
logger = logging.getLogger(__name__)
class GeometryView(OutputUserObject):
"""Outputs to file(s) information about the geometry (mesh) of model.
The geometry information is saved in Visual Toolkit (VTK) formats.
Attributes:
p1: tuple required for lower left (x,y,z) coordinates of volume of
geometry view in metres.
p2: tuple required for upper right (x,y,z) coordinates of volume of
geometry view in metres.
dl: tuple required for spatial discretisation of geometry view in metres.
output_tuple: string required for per-cell 'n' (normal) or per-cell-edge
'f' (fine) geometry views.
filename: string required for filename where geometry view will be
stored in the same directory as input file.
"""
@property
def order(self):
return 17
@property
def hash(self):
return "#geometry_view"
def __init__(self, **kwargs):
super().__init__(**kwargs)
def geometry_view_constructor(self, output_type):
"""Selects appropriate class for geometry view dependent on geometry
view type, i.e. normal or fine.
"""
if output_type == "n":
from gprMax.geometry_outputs import GeometryViewVoxels as GeometryViewUser
else:
from gprMax.geometry_outputs import GeometryViewLines as GeometryViewUser
return GeometryViewUser
def build(self, model: Model, grid: FDTDGrid):
try:
p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"]
dl = self.kwargs["dl"]
output_type = self.kwargs["output_type"].lower()
filename = self.kwargs["filename"]
except KeyError:
logger.exception(f"{self.params_str()} requires exactly eleven parameters.")
raise
GeometryViewUser = self.geometry_view_constructor(output_type)
uip = self._create_uip(grid)
try:
p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2)
p1, p2 = uip.check_box_points(p1, p2, self.params_str())
except ValueError:
logger.exception(f"{self.params_str()} point is outside the domain.")
raise
xs, ys, zs = p1
xf, yf, zf = p2
dx, dy, dz = uip.discretise_static_point(dl)
if dx < 0 or dy < 0 or dz < 0:
logger.exception(f"{self.params_str()} the step size should not be less than zero.")
raise ValueError
if dx > grid.nx or dy > grid.ny or dz > grid.nz:
logger.exception(
f"{self.params_str()} the step size should be less than the domain size."
)
raise ValueError
if dx < 1 or dy < 1 or dz < 1:
logger.exception(
f"{self.params_str()} the step size should not be less than the spatial discretisation."
)
raise ValueError
if output_type not in ["n", "f"]:
logger.exception(
f"{self.params_str()} requires type to be either n (normal) or f (fine)."
)
raise ValueError
if output_type == "f" and (
dx * grid.dx != grid.dx or dy * grid.dy != grid.dy or dz * grid.dz != grid.dz
):
logger.exception(
f"{self.params_str()} requires the spatial "
"discretisation for the geometry view to be the "
"same as the model for geometry view of "
"type f (fine)"
)
raise ValueError
g = GeometryViewUser(xs, ys, zs, xf, yf, zf, dx, dy, dz, filename, grid)
logger.info(
f"{self.grid_name(grid)}Geometry view from {p3[0]:g}m, "
f"{p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, "
f"{p4[2]:g}m, discretisation {dx * grid.dx:g}m, "
f"{dy * grid.dy:g}m, {dz * grid.dz:g}m, with filename "
f"base {g.filename} created."
)
model.geometryviews.append(g)
class GeometryObjectsWrite(OutputUserObject):
"""Writes geometry generated in a model to file which can be imported into
other models.
Attributes:
p1: tuple required for lower left (x,y,z) coordinates of volume of
output in metres.
p2: tuple required for upper right (x,y,z) coordinates of volume of
output in metres.
filename: string required for filename where output will be stored in
the same directory as input file.
"""
@property
def order(self):
return 18
@property
def hash(self):
return "#geometry_objects_write"
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self, model: Model, grid: FDTDGrid):
if isinstance(grid, SubGridBaseGrid):
logger.exception(f"{self.params_str()} do not add geometry objects to subgrids.")
raise ValueError
try:
p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"]
basefilename = self.kwargs["filename"]
except KeyError:
logger.exception(f"{self.params_str()} requires exactly seven parameters.")
raise
uip = self._create_uip(grid)
p1, p2 = uip.check_box_points(p1, p2, self.params_str())
x0, y0, z0 = p1
x1, y1, z1 = p2
# TODO: Remove these when add parallel build
if isinstance(grid, MPIGrid):
geometry_object_type = MPIGeometryObjectsUser
else:
geometry_object_type = GeometryObjectsUser
g = geometry_object_type(x0, y0, z0, x1, y1, z1, basefilename)
logger.info(
f"Geometry objects in the volume from {p1[0] * grid.dx:g}m, "
f"{p1[1] * grid.dy:g}m, {p1[2] * grid.dz:g}m, to "
f"{p2[0] * grid.dx:g}m, {p2[1] * grid.dy:g}m, "
f"{p2[2] * grid.dz:g}m, will be written to "
f"{g.filename_hdf5}, with materials written to "
f"{g.filename_materials}"
)
model.geometryobjects.append(g)

查看文件

@@ -253,7 +253,7 @@ class TimeWindow(ModelUserObject):
if self.time is not None and self.iterations is not None: if self.time is not None and self.iterations is not None:
logger.warning( logger.warning(
f"{self._params_str()} Time and iterations were both specified, using 'time'" f"{self.params_str()} Time and iterations were both specified, using 'time'"
) )
logger.info(f"Time window: {model.timewindow:g} secs ({model.iterations} iterations)") logger.info(f"Time window: {model.timewindow:g} secs ({model.iterations} iterations)")

查看文件

@@ -1,6 +1,8 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional, Tuple from typing import Optional, Tuple
from gprMax.grid.fdtd_grid import FDTDGrid
class Rotatable(ABC): class Rotatable(ABC):
"""Stores parameters and defines an interface for rotatable objects. """Stores parameters and defines an interface for rotatable objects.
@@ -38,6 +40,6 @@ class Rotatable(ABC):
self.do_rotate = True self.do_rotate = True
@abstractmethod @abstractmethod
def _do_rotate(self): def _do_rotate(self, grid: FDTDGrid):
"""Performs the rotation.""" """Performs the rotation."""
pass pass

查看文件

@@ -3,7 +3,6 @@ from typing import List, Union
from gprMax import config from gprMax import config
from gprMax.grid.fdtd_grid import FDTDGrid from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.grid.mpi_grid import MPIGrid
from gprMax.model import Model from gprMax.model import Model
from gprMax.subgrids.grid import SubGridBaseGrid from gprMax.subgrids.grid import SubGridBaseGrid
from gprMax.user_inputs import MainGridUserInput, SubgridUserInput from gprMax.user_inputs import MainGridUserInput, SubgridUserInput
@@ -60,7 +59,7 @@ class UserObject(ABC):
return f"{self.hash}: {' '.join(args)}" return f"{self.hash}: {' '.join(args)}"
def _params_str(self) -> str: def params_str(self) -> str:
"""Readable string of parameters given to object.""" """Readable string of parameters given to object."""
return f"{self.hash}: {str(self.kwargs)}" return f"{self.hash}: {str(self.kwargs)}"
@@ -115,10 +114,42 @@ class GridUserObject(MultiUserObject):
def build(self, grid: FDTDGrid): def build(self, grid: FDTDGrid):
pass pass
def grid_name(self, grid: FDTDGrid) -> str:
"""Format grid name for use with logging info.
Returns an empty string if the grid is the main grid.
Args:
grid: Grid to get the name of.
Returns:
grid_name: Formatted version of the grid name.
"""
if isinstance(grid, SubGridBaseGrid):
return f"[{grid.name}] "
else:
return ""
class OutputUserObject(MultiUserObject): class OutputUserObject(MultiUserObject):
"""User defined object that controls the output of data.""" """User defined object that controls the output of data."""
def grid_name(self, grid: FDTDGrid) -> str:
"""Format grid name for use with logging info.
Returns an empty string if the grid is the main grid.
Args:
grid: Grid to get the name of.
Returns:
grid_name: Formatted version of the grid name.
"""
if isinstance(grid, SubGridBaseGrid):
return f"[{grid.name}] "
else:
return ""
@abstractmethod @abstractmethod
def build(self, model: Model, grid: FDTDGrid): def build(self, model: Model, grid: FDTDGrid):
pass pass