你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
Refactor geometry cmds to use new user object class
这个提交包含在:
@@ -21,15 +21,18 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.fractals import FractalSurface, Grass
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
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 .cmds_geometry import UserObjectGeometry, rotate_2point_object
|
||||
from .cmds_geometry import rotate_2point_object
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddGrass(UserObjectGeometry):
|
||||
class AddGrass(GeometryUserObject, Rotatable):
|
||||
"""Adds grass with roots to a FractalBox class in the model.
|
||||
|
||||
Attributes:
|
||||
@@ -47,25 +50,21 @@ class AddGrass(UserObjectGeometry):
|
||||
grass should be applied to.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#add_grass"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#add_grass"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Perform rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
"""Add Grass to fractal box."""
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
@@ -89,7 +88,7 @@ class AddGrass(UserObjectGeometry):
|
||||
seed = None
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
# Get the correct fractal volume
|
||||
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}")
|
||||
raise
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p1, p2 = uip.check_box_points(p1, p2, self.__str__())
|
||||
xs, ys, zs = p1
|
||||
xf, yf, zf = p2
|
||||
|
@@ -21,14 +21,17 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
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 .cmds_geometry import UserObjectGeometry, rotate_2point_object
|
||||
from .cmds_geometry import rotate_2point_object
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddSurfaceRoughness(UserObjectGeometry):
|
||||
class AddSurfaceRoughness(GeometryUserObject, Rotatable):
|
||||
"""Adds surface roughness to a FractalBox class in the model.
|
||||
|
||||
Attributes:
|
||||
@@ -48,25 +51,21 @@ class AddSurfaceRoughness(UserObjectGeometry):
|
||||
number generator used to create the fractals.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#add_surface_roughness"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#add_surface_roughness"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Perform rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -89,7 +88,7 @@ class AddSurfaceRoughness(UserObjectGeometry):
|
||||
seed = None
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
# Get the correct fractal volume
|
||||
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}")
|
||||
raise ValueError
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p1, p2 = uip.check_box_points(p1, p2, self.__str__())
|
||||
xs, ys, zs = p1
|
||||
xf, yf, zf = p2
|
||||
|
@@ -20,15 +20,18 @@ import logging
|
||||
|
||||
import numpy as np
|
||||
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
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 .cmds_geometry import UserObjectGeometry, rotate_2point_object
|
||||
from .cmds_geometry import rotate_2point_object
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AddSurfaceWater(UserObjectGeometry):
|
||||
class AddSurfaceWater(GeometryUserObject, Rotatable):
|
||||
"""Adds surface water to a FractalBox class in the model.
|
||||
|
||||
Attributes:
|
||||
@@ -43,25 +46,21 @@ class AddSurfaceWater(UserObjectGeometry):
|
||||
surface water should be applied to.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#add_surface_water"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#add_surface_water"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Perform rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
""" "Create surface water on fractal box."""
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
@@ -73,7 +72,7 @@ class AddSurfaceWater(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
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]:
|
||||
volume = volumes[0]
|
||||
@@ -81,6 +80,7 @@ class AddSurfaceWater(UserObjectGeometry):
|
||||
logger.exception(f"{self.__str__()} cannot find FractalBox {fractal_box_id}")
|
||||
raise ValueError
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p1, p2 = uip.check_box_points(p1, p2, self.__str__())
|
||||
xs, ys, zs = p1
|
||||
xf, yf, zf = p2
|
||||
|
@@ -22,14 +22,17 @@ import numpy as np
|
||||
|
||||
import gprMax.config as config
|
||||
from gprMax.cython.geometry_primitives import build_box
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
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__)
|
||||
|
||||
|
||||
class Box(UserObjectGeometry):
|
||||
class Box(GeometryUserObject, Rotatable):
|
||||
"""Introduces an orthogonal parallelepiped with specific properties into
|
||||
the model.
|
||||
|
||||
@@ -42,25 +45,21 @@ class Box(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#box"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#box"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Perform rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -69,7 +68,7 @@ class Box(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
# Check materials have been specified
|
||||
# Isotropic case
|
||||
@@ -91,6 +90,7 @@ class Box(UserObjectGeometry):
|
||||
# Otherwise go with the grid default
|
||||
averagebox = grid.averagevolumeobjects
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3, p4 = uip.check_box_points(p1, p2, self.__str__())
|
||||
# Find nearest point on grid without translation
|
||||
p5 = uip.round_to_grid_static_point(p1)
|
||||
|
@@ -26,44 +26,6 @@ import gprMax.config as config
|
||||
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):
|
||||
"""Check and set material averaging value.
|
||||
|
||||
|
@@ -21,14 +21,14 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_cone
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
from gprMax.materials import Material
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry, check_averaging
|
||||
from gprMax.user_objects.user_objects import GeometryUserObject
|
||||
|
||||
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
|
||||
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.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#cone"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#cone"
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid) -> None:
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -79,6 +82,7 @@ class Cone(UserObjectGeometry):
|
||||
logger.exception(f"{self.__str__()} no materials have been specified")
|
||||
raise
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3 = uip.round_to_grid_static_point(p1)
|
||||
p4 = uip.round_to_grid_static_point(p2)
|
||||
|
||||
|
@@ -21,14 +21,14 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_cylinder
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
from gprMax.materials import Material
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry, check_averaging
|
||||
from gprMax.user_objects.user_objects import GeometryUserObject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Cylinder(UserObjectGeometry):
|
||||
class Cylinder(GeometryUserObject):
|
||||
"""Introduces a circular cylinder into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -43,11 +43,14 @@ class Cylinder(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#cylinder"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#cylinder"
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -76,6 +79,7 @@ class Cylinder(UserObjectGeometry):
|
||||
logger.exception(f"{self.__str__()} no materials have been specified")
|
||||
raise
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3 = uip.round_to_grid_static_point(p1)
|
||||
p4 = uip.round_to_grid_static_point(p2)
|
||||
|
||||
|
@@ -21,14 +21,14 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_cylindrical_sector
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
from gprMax.materials import Material
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry, check_averaging
|
||||
from gprMax.user_objects.user_objects import GeometryUserObject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CylindricalSector(UserObjectGeometry):
|
||||
class CylindricalSector(GeometryUserObject):
|
||||
"""Introduces a cylindrical sector (shaped like a slice of pie) into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -52,11 +52,14 @@ class CylindricalSector(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#cylindrical_sector"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#cylindrical_sector"
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
normal = self.kwargs["normal"].lower()
|
||||
ctr1 = self.kwargs["ctr1"]
|
||||
@@ -159,6 +162,7 @@ class CylindricalSector(UserObjectGeometry):
|
||||
numIDy = materials[1].numID
|
||||
numIDz = materials[2].numID
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
# yz-plane cylindrical sector
|
||||
if normal == "x":
|
||||
level, ctr1, ctr2 = uip.round_to_grid((extent1, ctr1, ctr2))
|
||||
|
@@ -21,13 +21,16 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
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__)
|
||||
|
||||
|
||||
class Edge(UserObjectGeometry):
|
||||
class Edge(GeometryUserObject, Rotatable):
|
||||
"""Introduces a wire with specific properties into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -37,25 +40,21 @@ class Edge(UserObjectGeometry):
|
||||
to material that has already been defined.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#edge"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#edge"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Performs rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
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."""
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
@@ -66,8 +65,9 @@ class Edge(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3 = uip.round_to_grid_static_point(p1)
|
||||
p4 = uip.round_to_grid_static_point(p2)
|
||||
|
||||
|
@@ -21,14 +21,14 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_ellipsoid
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
from gprMax.materials import Material
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry, check_averaging
|
||||
from gprMax.user_objects.user_objects import GeometryUserObject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Ellipsoid(UserObjectGeometry):
|
||||
class Ellipsoid(GeometryUserObject):
|
||||
"""Introduces an ellipsoidal object with specific parameters into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -42,11 +42,14 @@ class Ellipsoid(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#ellipsoid"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#ellipsoid"
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
xr = self.kwargs["xr"]
|
||||
@@ -78,6 +81,7 @@ class Ellipsoid(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
# Centre of ellipsoid
|
||||
uip = self._create_uip(grid)
|
||||
p2 = uip.round_to_grid_static_point(p1)
|
||||
xc, yc, zc = uip.discretise_point(p1)
|
||||
|
||||
|
@@ -23,13 +23,16 @@ import numpy as np
|
||||
import gprMax.config as config
|
||||
from gprMax.cython.geometry_primitives import build_voxels_from_array, build_voxels_from_array_mask
|
||||
from gprMax.fractals import FractalVolume
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
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__)
|
||||
|
||||
|
||||
class FractalBox(UserObjectGeometry):
|
||||
class FractalBox(GeometryUserObject, Rotatable):
|
||||
"""Introduces an orthogonal parallelepiped with fractal distributed
|
||||
properties which are related to a mixing model or normal material into
|
||||
the model.
|
||||
@@ -53,26 +56,22 @@ class FractalBox(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#fractal_box"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.do_pre_build = True
|
||||
self.hash = "#fractal_box"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Performs rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def pre_build(self, grid, uip):
|
||||
def pre_build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -96,7 +95,7 @@ class FractalBox(UserObjectGeometry):
|
||||
seed = None
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
# Check averaging
|
||||
try:
|
||||
@@ -107,6 +106,7 @@ class FractalBox(UserObjectGeometry):
|
||||
# a fractal box.
|
||||
averagefractalbox = False
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3 = uip.round_to_grid_static_point(p1)
|
||||
p4 = uip.round_to_grid_static_point(p2)
|
||||
|
||||
@@ -187,9 +187,9 @@ class FractalBox(UserObjectGeometry):
|
||||
)
|
||||
grid.fractalvolumes.append(self.volume)
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
if self.do_pre_build:
|
||||
self.pre_build(grid, uip)
|
||||
self.pre_build(grid)
|
||||
self.do_pre_build = False
|
||||
else:
|
||||
if self.volume.fractalsurfaces:
|
||||
|
@@ -23,23 +23,23 @@ import h5py
|
||||
|
||||
import gprMax.config as config
|
||||
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.user_objects.user_objects import GeometryUserObject
|
||||
from gprMax.utilities.utilities import round_value
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GeometryObjectsRead(UserObjectGeometry):
|
||||
class GeometryObjectsRead(GeometryUserObject):
|
||||
@property
|
||||
def hash(self):
|
||||
return "#geometry_objects_read"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#geometry_objects_read"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
pass
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
"""Creates the object and adds it to the grid."""
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
@@ -52,6 +52,7 @@ class GeometryObjectsRead(UserObjectGeometry):
|
||||
# Discretise the point using uip object. This has different behaviour
|
||||
# depending on the type of uip object. So we can use it for
|
||||
# the main grid or the subgrid.
|
||||
uip = self._create_uip(grid)
|
||||
xs, ys, zs = uip.discretise_point(p1)
|
||||
|
||||
# See if material file exists at specified path and if not try input
|
||||
@@ -82,7 +83,7 @@ class GeometryObjectsRead(UserObjectGeometry):
|
||||
scene.add(material_obj)
|
||||
|
||||
# Creates the internal simulation objects
|
||||
scene.process_cmds(material_objs, grid)
|
||||
scene.build_grid_objects(material_objs, grid)
|
||||
|
||||
# Update material type
|
||||
for material in grid.materials:
|
||||
|
@@ -21,13 +21,16 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
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__)
|
||||
|
||||
|
||||
class Plate(UserObjectGeometry):
|
||||
class Plate(GeometryUserObject, Rotatable):
|
||||
"""Introduces a plate with specific properties into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -38,25 +41,21 @@ class Plate(UserObjectGeometry):
|
||||
material_ids: list of material identifiers in the x, y, z directions.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#plate"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#plate"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Set parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Performs rotation."""
|
||||
pts = np.array([self.kwargs["p1"], self.kwargs["p2"]])
|
||||
rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin)
|
||||
self.kwargs["p1"] = tuple(rot_pts[0, :])
|
||||
self.kwargs["p2"] = tuple(rot_pts[1, :])
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
p2 = self.kwargs["p2"]
|
||||
@@ -76,8 +75,9 @@ class Plate(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p3 = uip.round_to_grid_static_point(p1)
|
||||
p4 = uip.round_to_grid_static_point(p2)
|
||||
|
||||
|
@@ -21,14 +21,14 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_sphere
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
from gprMax.materials import Material
|
||||
|
||||
from .cmds_geometry import UserObjectGeometry, check_averaging
|
||||
from gprMax.user_objects.user_objects import GeometryUserObject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Sphere(UserObjectGeometry):
|
||||
class Sphere(GeometryUserObject):
|
||||
"""Introduces a spherical object with specific parameters into the model.
|
||||
|
||||
Attributes:
|
||||
@@ -40,11 +40,14 @@ class Sphere(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#sphere"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#sphere"
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
p1 = self.kwargs["p1"]
|
||||
r = self.kwargs["r"]
|
||||
@@ -73,6 +76,7 @@ class Sphere(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
# Centre of sphere
|
||||
uip = self._create_uip(grid)
|
||||
p2 = uip.round_to_grid_static_point(p1)
|
||||
xc, yc, zc = uip.discretise_point(p1)
|
||||
|
||||
|
@@ -21,14 +21,17 @@ import logging
|
||||
import numpy as np
|
||||
|
||||
from gprMax.cython.geometry_primitives import build_triangle
|
||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
||||
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__)
|
||||
|
||||
|
||||
class Triangle(UserObjectGeometry):
|
||||
class Triangle(GeometryUserObject, Rotatable):
|
||||
"""Introduces a triangular patch or a triangular prism with specific
|
||||
properties into the model.
|
||||
|
||||
@@ -44,18 +47,14 @@ class Triangle(UserObjectGeometry):
|
||||
averaging: string (y or n) used to switch on and off dielectric smoothing.
|
||||
"""
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
return "#triangle"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.hash = "#triangle"
|
||||
|
||||
def rotate(self, axis, angle, origin=None):
|
||||
"""Sets parameters for rotation."""
|
||||
self.axis = axis
|
||||
self.angle = angle
|
||||
self.origin = origin
|
||||
self.do_rotate = True
|
||||
|
||||
def _do_rotate(self):
|
||||
def _do_rotate(self, grid: FDTDGrid):
|
||||
"""Performs rotation."""
|
||||
p1 = rotate_point(self.kwargs["p1"], 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["p3"] = tuple(p3)
|
||||
|
||||
def build(self, grid, uip):
|
||||
def build(self, grid: FDTDGrid):
|
||||
try:
|
||||
up1 = self.kwargs["p1"]
|
||||
up2 = self.kwargs["p2"]
|
||||
@@ -75,7 +74,7 @@ class Triangle(UserObjectGeometry):
|
||||
raise
|
||||
|
||||
if self.do_rotate:
|
||||
self._do_rotate()
|
||||
self._do_rotate(grid)
|
||||
|
||||
# Check averaging
|
||||
try:
|
||||
@@ -97,6 +96,7 @@ class Triangle(UserObjectGeometry):
|
||||
logger.exception(f"{self.__str__()} no materials have been specified")
|
||||
raise
|
||||
|
||||
uip = self._create_uip(grid)
|
||||
p4 = uip.round_to_grid_static_point(up1)
|
||||
p5 = uip.round_to_grid_static_point(up2)
|
||||
p6 = uip.round_to_grid_static_point(up3)
|
||||
|
@@ -145,4 +145,10 @@ class OutputUserObject(UserObject):
|
||||
class GeometryUserObject(GridUserObject):
|
||||
"""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
|
||||
|
在新工单中引用
屏蔽一个用户