Refactor geometry cmds to use new user object class

这个提交包含在:
nmannall
2024-12-11 18:59:23 +00:00
父节点 2cc52708c4
当前提交 70151168fa
共有 16 个文件被更改,包括 168 次插入179 次删除

查看文件

@@ -21,15 +21,18 @@ import logging
import numpy as np import numpy as np
from gprMax.fractals import FractalSurface, Grass from gprMax.fractals import FractalSurface, Grass
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import create_grass from gprMax.materials import create_grass
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from gprMax.utilities.utilities import round_value from gprMax.utilities.utilities import round_value
from .cmds_geometry import UserObjectGeometry, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AddGrass(UserObjectGeometry): class AddGrass(GeometryUserObject, Rotatable):
"""Adds grass with roots to a FractalBox class in the model. """Adds grass with roots to a FractalBox class in the model.
Attributes: Attributes:
@@ -47,25 +50,21 @@ class AddGrass(UserObjectGeometry):
grass should be applied to. grass should be applied to.
""" """
@property
def hash(self):
return "#add_grass"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#add_grass"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Perform rotation.""" """Perform rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
"""Add Grass to fractal box.""" """Add Grass to fractal box."""
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
@@ -89,7 +88,7 @@ class AddGrass(UserObjectGeometry):
seed = None seed = None
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
# Get the correct fractal volume # Get the correct fractal volume
volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id]
@@ -99,6 +98,7 @@ class AddGrass(UserObjectGeometry):
logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}") logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}")
raise raise
uip = self._create_uip(grid)
p1, p2 = uip.check_box_points(p1, p2, self.__str__()) p1, p2 = uip.check_box_points(p1, p2, self.__str__())
xs, ys, zs = p1 xs, ys, zs = p1
xf, yf, zf = p2 xf, yf, zf = p2

查看文件

@@ -21,14 +21,17 @@ import logging
import numpy as np import numpy as np
from gprMax.fractals import FractalSurface from gprMax.fractals import FractalSurface
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from gprMax.utilities.utilities import round_value from gprMax.utilities.utilities import round_value
from .cmds_geometry import UserObjectGeometry, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AddSurfaceRoughness(UserObjectGeometry): class AddSurfaceRoughness(GeometryUserObject, Rotatable):
"""Adds surface roughness to a FractalBox class in the model. """Adds surface roughness to a FractalBox class in the model.
Attributes: Attributes:
@@ -48,25 +51,21 @@ class AddSurfaceRoughness(UserObjectGeometry):
number generator used to create the fractals. number generator used to create the fractals.
""" """
@property
def hash(self):
return "#add_surface_roughness"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#add_surface_roughness"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Perform rotation.""" """Perform rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -89,7 +88,7 @@ class AddSurfaceRoughness(UserObjectGeometry):
seed = None seed = None
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
# Get the correct fractal volume # Get the correct fractal volume
volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id]
@@ -99,6 +98,7 @@ class AddSurfaceRoughness(UserObjectGeometry):
logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}") logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}")
raise ValueError raise ValueError
uip = self._create_uip(grid)
p1, p2 = uip.check_box_points(p1, p2, self.__str__()) p1, p2 = uip.check_box_points(p1, p2, self.__str__())
xs, ys, zs = p1 xs, ys, zs = p1
xf, yf, zf = p2 xf, yf, zf = p2

查看文件

@@ -20,15 +20,18 @@ import logging
import numpy as np import numpy as np
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import create_water from gprMax.materials import create_water
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from gprMax.utilities.utilities import round_value from gprMax.utilities.utilities import round_value
from .cmds_geometry import UserObjectGeometry, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class AddSurfaceWater(UserObjectGeometry): class AddSurfaceWater(GeometryUserObject, Rotatable):
"""Adds surface water to a FractalBox class in the model. """Adds surface water to a FractalBox class in the model.
Attributes: Attributes:
@@ -43,25 +46,21 @@ class AddSurfaceWater(UserObjectGeometry):
surface water should be applied to. surface water should be applied to.
""" """
@property
def hash(self):
return "#add_surface_water"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#add_surface_water"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Perform rotation.""" """Perform rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
""" "Create surface water on fractal box.""" """ "Create surface water on fractal box."""
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
@@ -73,7 +72,7 @@ class AddSurfaceWater(UserObjectGeometry):
raise raise
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
if volumes := [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id]: if volumes := [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id]:
volume = volumes[0] volume = volumes[0]
@@ -81,6 +80,7 @@ class AddSurfaceWater(UserObjectGeometry):
logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}") logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}")
raise ValueError raise ValueError
uip = self._create_uip(grid)
p1, p2 = uip.check_box_points(p1, p2, self.__str__()) p1, p2 = uip.check_box_points(p1, p2, self.__str__())
xs, ys, zs = p1 xs, ys, zs = p1
xf, yf, zf = p2 xf, yf, zf = p2

查看文件

@@ -22,14 +22,17 @@ import numpy as np
import gprMax.config as config import gprMax.config as config
from gprMax.cython.geometry_primitives import build_box from gprMax.cython.geometry_primitives import build_box
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Box(UserObjectGeometry): class Box(GeometryUserObject, Rotatable):
"""Introduces an orthogonal parallelepiped with specific properties into """Introduces an orthogonal parallelepiped with specific properties into
the model. the model.
@@ -42,25 +45,21 @@ class Box(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#box"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#box"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Perform rotation.""" """Perform rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -69,7 +68,7 @@ class Box(UserObjectGeometry):
raise raise
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
# Check materials have been specified # Check materials have been specified
# Isotropic case # Isotropic case
@@ -91,6 +90,7 @@ class Box(UserObjectGeometry):
# Otherwise go with the grid default # Otherwise go with the grid default
averagebox = grid.averagevolumeobjects averagebox = grid.averagevolumeobjects
uip = self._create_uip(grid)
p3, p4 = uip.check_box_points(p1, p2, self.__str__()) p3, p4 = uip.check_box_points(p1, p2, self.__str__())
# Find nearest point on grid without translation # Find nearest point on grid without translation
p5 = uip.round_to_grid_static_point(p1) p5 = uip.round_to_grid_static_point(p1)

查看文件

@@ -26,44 +26,6 @@ import gprMax.config as config
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class UserObjectGeometry:
"""Specific Geometry object."""
def __init__(self, **kwargs):
self.kwargs = kwargs
self.hash = "#example"
self.autotranslate = True
self.do_rotate = False
def __str__(self):
"""Readable string of parameters given to object."""
s = ""
for _, v in self.kwargs.items():
if isinstance(v, (tuple, list)):
v = " ".join([str(el) for el in v])
s += f"{str(v)} "
return f"{self.hash}: {s[:-1]}"
def build(self, grid, uip):
"""Creates object and adds it to the grid."""
pass
def rotate(self, axis, angle, origin=None):
"""Rotates object - specialised for each object."""
pass
def grid_name(self, grid):
"""Returns subgrid name for use with logging info. Returns an empty
string if the grid is the main grid.
"""
if config.sim_config.general["subgrid"] and grid.name != "main_grid":
return f"[{grid.name}] "
else:
return ""
def check_averaging(averaging): def check_averaging(averaging):
"""Check and set material averaging value. """Check and set material averaging value.

查看文件

@@ -21,14 +21,14 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_cone from gprMax.cython.geometry_primitives import build_cone
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Cone(UserObjectGeometry): class Cone(GeometryUserObject):
"""Introduces a circular cone into the model. The difference with the cylinder is that the faces of the cone """Introduces a circular cone into the model. The difference with the cylinder is that the faces of the cone
can have different radii and one of them can be zero. can have different radii and one of them can be zero.
@@ -45,11 +45,14 @@ class Cone(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#cone"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#cone"
def build(self, grid, uip): def build(self, grid: FDTDGrid) -> None:
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -79,6 +82,7 @@ class Cone(UserObjectGeometry):
logger.exception(f"{self.__str__()} no materials have been specified") logger.exception(f"{self.__str__()} no materials have been specified")
raise raise
uip = self._create_uip(grid)
p3 = uip.round_to_grid_static_point(p1) p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2) p4 = uip.round_to_grid_static_point(p2)

查看文件

@@ -21,14 +21,14 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_cylinder from gprMax.cython.geometry_primitives import build_cylinder
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Cylinder(UserObjectGeometry): class Cylinder(GeometryUserObject):
"""Introduces a circular cylinder into the model. """Introduces a circular cylinder into the model.
Attributes: Attributes:
@@ -43,11 +43,14 @@ class Cylinder(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#cylinder"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#cylinder"
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -76,6 +79,7 @@ class Cylinder(UserObjectGeometry):
logger.exception(f"{self.__str__()} no materials have been specified") logger.exception(f"{self.__str__()} no materials have been specified")
raise raise
uip = self._create_uip(grid)
p3 = uip.round_to_grid_static_point(p1) p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2) p4 = uip.round_to_grid_static_point(p2)

查看文件

@@ -21,14 +21,14 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_cylindrical_sector from gprMax.cython.geometry_primitives import build_cylindrical_sector
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class CylindricalSector(UserObjectGeometry): class CylindricalSector(GeometryUserObject):
"""Introduces a cylindrical sector (shaped like a slice of pie) into the model. """Introduces a cylindrical sector (shaped like a slice of pie) into the model.
Attributes: Attributes:
@@ -52,11 +52,14 @@ class CylindricalSector(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#cylindrical_sector"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#cylindrical_sector"
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
normal = self.kwargs["normal"].lower() normal = self.kwargs["normal"].lower()
ctr1 = self.kwargs["ctr1"] ctr1 = self.kwargs["ctr1"]
@@ -159,6 +162,7 @@ class CylindricalSector(UserObjectGeometry):
numIDy = materials[1].numID numIDy = materials[1].numID
numIDz = materials[2].numID numIDz = materials[2].numID
uip = self._create_uip(grid)
# yz-plane cylindrical sector # yz-plane cylindrical sector
if normal == "x": if normal == "x":
level, ctr1, ctr2 = uip.round_to_grid((extent1, ctr1, ctr2)) level, ctr1, ctr2 = uip.round_to_grid((extent1, ctr1, ctr2))

查看文件

@@ -21,13 +21,16 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_edge_x, build_edge_y, build_edge_z from gprMax.cython.geometry_primitives import build_edge_x, build_edge_y, build_edge_z
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Edge(UserObjectGeometry): class Edge(GeometryUserObject, Rotatable):
"""Introduces a wire with specific properties into the model. """Introduces a wire with specific properties into the model.
Attributes: Attributes:
@@ -37,25 +40,21 @@ class Edge(UserObjectGeometry):
to material that has already been defined. to material that has already been defined.
""" """
@property
def hash(self):
return "#edge"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#edge"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Performs rotation.""" """Performs rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
"""Creates edge and adds it to the grid.""" """Creates edge and adds it to the grid."""
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
@@ -66,8 +65,9 @@ class Edge(UserObjectGeometry):
raise raise
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
uip = self._create_uip(grid)
p3 = uip.round_to_grid_static_point(p1) p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2) p4 = uip.round_to_grid_static_point(p2)

查看文件

@@ -21,14 +21,14 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_ellipsoid from gprMax.cython.geometry_primitives import build_ellipsoid
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Ellipsoid(UserObjectGeometry): class Ellipsoid(GeometryUserObject):
"""Introduces an ellipsoidal object with specific parameters into the model. """Introduces an ellipsoidal object with specific parameters into the model.
Attributes: Attributes:
@@ -42,11 +42,14 @@ class Ellipsoid(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#ellipsoid"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#ellipsoid"
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
xr = self.kwargs["xr"] xr = self.kwargs["xr"]
@@ -78,6 +81,7 @@ class Ellipsoid(UserObjectGeometry):
raise raise
# Centre of ellipsoid # Centre of ellipsoid
uip = self._create_uip(grid)
p2 = uip.round_to_grid_static_point(p1) p2 = uip.round_to_grid_static_point(p1)
xc, yc, zc = uip.discretise_point(p1) xc, yc, zc = uip.discretise_point(p1)

查看文件

@@ -23,13 +23,16 @@ import numpy as np
import gprMax.config as config import gprMax.config as config
from gprMax.cython.geometry_primitives import build_voxels_from_array, build_voxels_from_array_mask from gprMax.cython.geometry_primitives import build_voxels_from_array, build_voxels_from_array_mask
from gprMax.fractals import FractalVolume from gprMax.fractals import FractalVolume
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import ListMaterial from gprMax.materials import ListMaterial
from gprMax.user_objects.cmds_geometry.cmds_geometry import UserObjectGeometry, rotate_2point_object from gprMax.user_objects.cmds_geometry.cmds_geometry import rotate_2point_object
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class FractalBox(UserObjectGeometry): class FractalBox(GeometryUserObject, Rotatable):
"""Introduces an orthogonal parallelepiped with fractal distributed """Introduces an orthogonal parallelepiped with fractal distributed
properties which are related to a mixing model or normal material into properties which are related to a mixing model or normal material into
the model. the model.
@@ -53,26 +56,22 @@ class FractalBox(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#fractal_box"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.do_pre_build = True self.do_pre_build = True
self.hash = "#fractal_box"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Performs rotation.""" """Performs rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def pre_build(self, grid, uip): def pre_build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -96,7 +95,7 @@ class FractalBox(UserObjectGeometry):
seed = None seed = None
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
# Check averaging # Check averaging
try: try:
@@ -107,6 +106,7 @@ class FractalBox(UserObjectGeometry):
# a fractal box. # a fractal box.
averagefractalbox = False averagefractalbox = False
uip = self._create_uip(grid)
p3 = uip.round_to_grid_static_point(p1) p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2) p4 = uip.round_to_grid_static_point(p2)
@@ -187,9 +187,9 @@ class FractalBox(UserObjectGeometry):
) )
grid.fractalvolumes.append(self.volume) grid.fractalvolumes.append(self.volume)
def build(self, grid, uip): def build(self, grid: FDTDGrid):
if self.do_pre_build: if self.do_pre_build:
self.pre_build(grid, uip) self.pre_build(grid)
self.do_pre_build = False self.do_pre_build = False
else: else:
if self.volume.fractalsurfaces: if self.volume.fractalsurfaces:

查看文件

@@ -23,23 +23,23 @@ import h5py
import gprMax.config as config import gprMax.config as config
from gprMax.cython.geometry_primitives import build_voxels_from_array from gprMax.cython.geometry_primitives import build_voxels_from_array
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.hash_cmds_file import get_user_objects from gprMax.hash_cmds_file import get_user_objects
from gprMax.user_objects.user_objects import GeometryUserObject
from gprMax.utilities.utilities import round_value from gprMax.utilities.utilities import round_value
from .cmds_geometry import UserObjectGeometry
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GeometryObjectsRead(UserObjectGeometry): class GeometryObjectsRead(GeometryUserObject):
@property
def hash(self):
return "#geometry_objects_read"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#geometry_objects_read"
def rotate(self, axis, angle, origin=None): def build(self, grid: FDTDGrid):
pass
def build(self, grid, uip):
"""Creates the object and adds it to the grid.""" """Creates the object and adds it to the grid."""
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
@@ -52,6 +52,7 @@ class GeometryObjectsRead(UserObjectGeometry):
# Discretise the point using uip object. This has different behaviour # Discretise the point using uip object. This has different behaviour
# depending on the type of uip object. So we can use it for # depending on the type of uip object. So we can use it for
# the main grid or the subgrid. # the main grid or the subgrid.
uip = self._create_uip(grid)
xs, ys, zs = uip.discretise_point(p1) xs, ys, zs = uip.discretise_point(p1)
# See if material file exists at specified path and if not try input # See if material file exists at specified path and if not try input
@@ -82,7 +83,7 @@ class GeometryObjectsRead(UserObjectGeometry):
scene.add(material_obj) scene.add(material_obj)
# Creates the internal simulation objects # Creates the internal simulation objects
scene.process_cmds(material_objs, grid) scene.build_grid_objects(material_objs, grid)
# Update material type # Update material type
for material in grid.materials: for material in grid.materials:

查看文件

@@ -21,13 +21,16 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_face_xy, build_face_xz, build_face_yz from gprMax.cython.geometry_primitives import build_face_xy, build_face_xz, build_face_yz
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, rotate_2point_object from .cmds_geometry import rotate_2point_object
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Plate(UserObjectGeometry): class Plate(GeometryUserObject, Rotatable):
"""Introduces a plate with specific properties into the model. """Introduces a plate with specific properties into the model.
Attributes: Attributes:
@@ -38,25 +41,21 @@ class Plate(UserObjectGeometry):
material_ids: list of material identifiers in the x, y, z directions. material_ids: list of material identifiers in the x, y, z directions.
""" """
@property
def hash(self):
return "#plate"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#plate"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Set parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Performs rotation.""" """Performs rotation."""
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]]) pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
self.kwargs["p1"] = tuple(rot_pts[0, :]) self.kwargs["p1"] = tuple(rot_pts[0, :])
self.kwargs["p2"] = tuple(rot_pts[1, :]) self.kwargs["p2"] = tuple(rot_pts[1, :])
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
p2 = self.kwargs["p2"] p2 = self.kwargs["p2"]
@@ -76,8 +75,9 @@ class Plate(UserObjectGeometry):
raise raise
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
uip = self._create_uip(grid)
p3 = uip.round_to_grid_static_point(p1) p3 = uip.round_to_grid_static_point(p1)
p4 = uip.round_to_grid_static_point(p2) p4 = uip.round_to_grid_static_point(p2)

查看文件

@@ -21,14 +21,14 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_sphere from gprMax.cython.geometry_primitives import build_sphere
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Sphere(UserObjectGeometry): class Sphere(GeometryUserObject):
"""Introduces a spherical object with specific parameters into the model. """Introduces a spherical object with specific parameters into the model.
Attributes: Attributes:
@@ -40,11 +40,14 @@ class Sphere(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#sphere"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#sphere"
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
p1 = self.kwargs["p1"] p1 = self.kwargs["p1"]
r = self.kwargs["r"] r = self.kwargs["r"]
@@ -73,6 +76,7 @@ class Sphere(UserObjectGeometry):
raise raise
# Centre of sphere # Centre of sphere
uip = self._create_uip(grid)
p2 = uip.round_to_grid_static_point(p1) p2 = uip.round_to_grid_static_point(p1)
xc, yc, zc = uip.discretise_point(p1) xc, yc, zc = uip.discretise_point(p1)

查看文件

@@ -21,14 +21,17 @@ import logging
import numpy as np import numpy as np
from gprMax.cython.geometry_primitives import build_triangle from gprMax.cython.geometry_primitives import build_triangle
from gprMax.grid.fdtd_grid import FDTDGrid
from gprMax.materials import Material from gprMax.materials import Material
from gprMax.user_objects.rotatable import Rotatable
from gprMax.user_objects.user_objects import GeometryUserObject
from .cmds_geometry import UserObjectGeometry, check_averaging, rotate_point from .cmds_geometry import rotate_point
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Triangle(UserObjectGeometry): class Triangle(GeometryUserObject, Rotatable):
"""Introduces a triangular patch or a triangular prism with specific """Introduces a triangular patch or a triangular prism with specific
properties into the model. properties into the model.
@@ -44,18 +47,14 @@ class Triangle(UserObjectGeometry):
averaging: string (y or n) used to switch on and off dielectric smoothing. averaging: string (y or n) used to switch on and off dielectric smoothing.
""" """
@property
def hash(self):
return "#triangle"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.hash = "#triangle"
def rotate(self, axis, angle, origin=None): def _do_rotate(self, grid: FDTDGrid):
"""Sets parameters for rotation."""
self.axis = axis
self.angle = angle
self.origin = origin
self.do_rotate = True
def _do_rotate(self):
"""Performs rotation.""" """Performs rotation."""
p1 = rotate_point(self.kwargs["p1"], self.axis, self.angle, self.origin) p1 = rotate_point(self.kwargs["p1"], self.axis, self.angle, self.origin)
p2 = rotate_point(self.kwargs["p2"], self.axis, self.angle, self.origin) p2 = rotate_point(self.kwargs["p2"], self.axis, self.angle, self.origin)
@@ -64,7 +63,7 @@ class Triangle(UserObjectGeometry):
self.kwargs["p2"] = tuple(p2) self.kwargs["p2"] = tuple(p2)
self.kwargs["p3"] = tuple(p3) self.kwargs["p3"] = tuple(p3)
def build(self, grid, uip): def build(self, grid: FDTDGrid):
try: try:
up1 = self.kwargs["p1"] up1 = self.kwargs["p1"]
up2 = self.kwargs["p2"] up2 = self.kwargs["p2"]
@@ -75,7 +74,7 @@ class Triangle(UserObjectGeometry):
raise raise
if self.do_rotate: if self.do_rotate:
self._do_rotate() self._do_rotate(grid)
# Check averaging # Check averaging
try: try:
@@ -97,6 +96,7 @@ class Triangle(UserObjectGeometry):
logger.exception(f"{self.__str__()} no materials have been specified") logger.exception(f"{self.__str__()} no materials have been specified")
raise raise
uip = self._create_uip(grid)
p4 = uip.round_to_grid_static_point(up1) p4 = uip.round_to_grid_static_point(up1)
p5 = uip.round_to_grid_static_point(up2) p5 = uip.round_to_grid_static_point(up2)
p6 = uip.round_to_grid_static_point(up3) p6 = uip.round_to_grid_static_point(up3)

查看文件

@@ -145,4 +145,10 @@ class OutputUserObject(UserObject):
class GeometryUserObject(GridUserObject): class GeometryUserObject(GridUserObject):
"""User defined object that adds geometry to a grid.""" """User defined object that adds geometry to a grid."""
pass @property
def order(self):
"""Geometry Objects do not have an ordering.
They should be built in the order they were added to the scene.
"""
return 1