From 0c0e0d9208603c7c9a2c8031700a01d8451399d2 Mon Sep 17 00:00:00 2001 From: nmannall Date: Fri, 19 Apr 2024 10:23:10 +0100 Subject: [PATCH] Split build_obj into seperate functions to build Model and FDTDGrid objects --- gprMax/cmds_singleuse.py | 3 ++- gprMax/scene.py | 28 +++++++++++++++++++++++----- gprMax/user_inputs.py | 26 +++++++++++++++++++++----- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/gprMax/cmds_singleuse.py b/gprMax/cmds_singleuse.py index 53cdd2c6..8062224b 100644 --- a/gprMax/cmds_singleuse.py +++ b/gprMax/cmds_singleuse.py @@ -23,6 +23,7 @@ import numpy as np import gprMax.config as config from gprMax.grid.fdtd_grid import FDTDGrid +from gprMax.model import Model from gprMax.user_inputs import MainGridUserInput from .pml import PML @@ -51,7 +52,7 @@ class UserObjectSingle(ABC): setattr(self.props, k, v) @abstractmethod - def build(self, grid: FDTDGrid, uip: MainGridUserInput): + def build(self, model: Model, uip: MainGridUserInput): pass # TODO: Check if this is actually needed diff --git a/gprMax/scene.py b/gprMax/scene.py index 57d3fdc3..7fc0f44b 100644 --- a/gprMax/scene.py +++ b/gprMax/scene.py @@ -26,6 +26,7 @@ from gprMax.cmds_geometry.cmds_geometry import UserObjectGeometry from gprMax.cmds_geometry.fractal_box import FractalBox from gprMax.cmds_multiuse import UserObjectMulti from gprMax.cmds_singleuse import Discretisation, Domain, TimeWindow, UserObjectSingle +from gprMax.grid.fdtd_grid import FDTDGrid from gprMax.materials import create_built_in_materials from gprMax.model import Model from gprMax.subgrids.grid import SubGridBaseGrid @@ -61,8 +62,8 @@ class Scene: logger.exception("This object is unknown to gprMax") raise ValueError - def build_obj(self, obj, grid): - """Builds objects. + def build_grid_obj(self, obj: Union[UserObjectMulti, UserObjectGeometry], grid: FDTDGrid): + """Builds objects in FDTDGrids. Args: obj: user object @@ -75,6 +76,20 @@ class Scene: logger.exception("Error creating user input object") raise + def build_model_obj(self, obj: UserObjectSingle, model: Model): + """Builds objects in models. + + Args: + obj: user object + model: Model being built + """ + uip = create_user_input_points(model.G, obj) + try: + obj.build(model, uip) + except ValueError: + logger.exception("Error creating user input object") + raise + def process_subgrid_cmds(self, model: Model): """Process all commands in any sub-grids.""" @@ -102,7 +117,10 @@ class Scene: grid = model.G if subgrid is None else subgrid cmds_sorted = sorted(commands, key=lambda cmd: cmd.order) for obj in cmds_sorted: - self.build_obj(obj, grid) + if isinstance(obj, UserObjectSingle): + self.build_model_obj(obj, model) + else: + self.build_grid_obj(obj, grid) return self @@ -111,7 +129,7 @@ class Scene: proc_cmds = [] for obj in commands: if isinstance(obj, (FractalBox, AddGrass, AddSurfaceRoughness, AddSurfaceWater)): - self.build_obj(obj, grid) + self.build_grid_obj(obj, grid) if isinstance(obj, (FractalBox)): proc_cmds.append(obj) else: @@ -119,7 +137,7 @@ class Scene: # Process all geometry commands for obj in proc_cmds: - self.build_obj(obj, grid) + self.build_grid_obj(obj, grid) return self diff --git a/gprMax/user_inputs.py b/gprMax/user_inputs.py index f80ba032..759776d9 100644 --- a/gprMax/user_inputs.py +++ b/gprMax/user_inputs.py @@ -15,12 +15,18 @@ # # You should have received a copy of the GNU General Public License # along with gprMax. If not, see . +from __future__ import annotations import logging +from typing import Union import numpy as np import gprMax.config as config +from gprMax.cmds_geometry.cmds_geometry import UserObjectGeometry +from gprMax.cmds_multiuse import UserObjectMulti +from gprMax.cmds_singleuse import UserObjectSingle +from gprMax.grid.fdtd_grid import FDTDGrid from .subgrids.grid import SubGridBaseGrid from .utilities.utilities import round_value @@ -37,7 +43,9 @@ logger = logging.getLogger(__name__) """ -def create_user_input_points(grid, user_obj): +def create_user_input_points( + grid: FDTDGrid, user_obj: Union[UserObjectSingle, UserObjectMulti, UserObjectGeometry] +) -> Union[MainGridUserInput, SubgridUserInput]: """Returns a point checker class based on the grid supplied.""" if isinstance(grid, SubGridBaseGrid): @@ -108,7 +116,9 @@ class MainGridUserInput(UserInput): p = self.check_point(p, cmd_str, name) if self.grid.within_pml(p): - logger.warning(f"'{cmd_str}' sources and receivers should not normally be positioned within the PML.") + logger.warning( + f"'{cmd_str}' sources and receivers should not normally be positioned within the PML." + ) return p @@ -117,7 +127,9 @@ class MainGridUserInput(UserInput): p2 = self.check_point(p2, cmd_str, name="upper") if np.greater(p1, p2).any(): - logger.exception(f"'{cmd_str}' the lower coordinates should be less than the upper coordinates.") + logger.exception( + f"'{cmd_str}' the lower coordinates should be less than the upper coordinates." + ) raise ValueError return p1, p2 @@ -152,7 +164,9 @@ class SubgridUserInput(MainGridUserInput): super().__init__(grid) # Defines the region exposed to the user - self.inner_bound = np.array([grid.n_boundary_cells_x, grid.n_boundary_cells_y, grid.n_boundary_cells_z]) + self.inner_bound = np.array( + [grid.n_boundary_cells_x, grid.n_boundary_cells_y, grid.n_boundary_cells_z] + ) self.outer_bound = np.subtract([grid.nx, grid.ny, grid.nz], self.inner_bound) @@ -186,7 +200,9 @@ class SubgridUserInput(MainGridUserInput): # Provide user within a warning if they have placed objects within # the OS non-working region. if np.less(p_t, self.inner_bound).any() or np.greater(p_t, self.outer_bound).any(): - logger.warning(f"'{cmd_str}' this object traverses the Outer Surface. This is an advanced feature.") + logger.warning( + f"'{cmd_str}' this object traverses the Outer Surface. This is an advanced feature." + ) return p_t def discretise_static_point(self, p):