你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 15:27:57 +08:00
@@ -17,21 +17,16 @@
|
|||||||
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.spatial.transform import Rotation as R
|
from scipy.spatial.transform import Rotation as R
|
||||||
|
|
||||||
import gprMax.config as config
|
import gprMax.config as config
|
||||||
from gprMax.grid.fdtd_grid import FDTDGrid
|
|
||||||
from gprMax.model import Model
|
|
||||||
from gprMax.subgrids.grid import SubGridBaseGrid
|
|
||||||
from gprMax.user_inputs import MainGridUserInput
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class UserObjectGeometry(ABC):
|
class UserObjectGeometry:
|
||||||
"""Specific Geometry object."""
|
"""Specific Geometry object."""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
@@ -50,8 +45,7 @@ class UserObjectGeometry(ABC):
|
|||||||
|
|
||||||
return f"{self.hash}: {s[:-1]}"
|
return f"{self.hash}: {s[:-1]}"
|
||||||
|
|
||||||
@abstractmethod
|
def build(self, grid, uip):
|
||||||
def build(self, model: Model, uip: MainGridUserInput):
|
|
||||||
"""Creates object and adds it to the grid."""
|
"""Creates object and adds it to the grid."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -59,20 +53,16 @@ class UserObjectGeometry(ABC):
|
|||||||
"""Rotates object - specialised for each object."""
|
"""Rotates object - specialised for each object."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def grid_name(self, grid: FDTDGrid) -> str:
|
def grid_name(self, grid):
|
||||||
"""Returns subgrid name for use with logging info. Returns an empty
|
"""Returns subgrid name for use with logging info. Returns an empty
|
||||||
string if the grid is the main grid.
|
string if the grid is the main grid.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(grid, SubGridBaseGrid):
|
if config.sim_config.general["subgrid"] and grid.name != "main_grid":
|
||||||
return f"[{grid.name}] "
|
return f"[{grid.name}] "
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def model_name(self, model: Model) -> str:
|
|
||||||
"""Returns model name for use with logging info."""
|
|
||||||
return f"[{model.title}] "
|
|
||||||
|
|
||||||
|
|
||||||
def rotate_point(p, axis, angle, origin=(0, 0, 0)):
|
def rotate_point(p, axis, angle, origin=(0, 0, 0)):
|
||||||
"""Rotates a point.
|
"""Rotates a point.
|
||||||
|
@@ -62,21 +62,28 @@ class Scene:
|
|||||||
logger.exception("This object is unknown to gprMax")
|
logger.exception("This object is unknown to gprMax")
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def build_obj(
|
def build_grid_obj(self, obj: Union[UserObjectMulti, UserObjectGeometry], grid: FDTDGrid):
|
||||||
self,
|
"""Builds objects in FDTDGrids.
|
||||||
obj: Union[UserObjectSingle, UserObjectMulti, UserObjectGeometry],
|
|
||||||
model: Model,
|
Args:
|
||||||
subgrid: Optional[FDTDGrid] = None,
|
obj: user object
|
||||||
):
|
grid: FDTDGrid class describing a grid in a model.
|
||||||
|
"""
|
||||||
|
uip = create_user_input_points(grid, obj)
|
||||||
|
try:
|
||||||
|
obj.build(grid, uip)
|
||||||
|
except ValueError:
|
||||||
|
logger.exception("Error creating user input object")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def build_model_obj(self, obj: UserObjectSingle, model: Model):
|
||||||
"""Builds objects in models.
|
"""Builds objects in models.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
obj: user object
|
obj: user object
|
||||||
model: Model being built
|
model: Model being built
|
||||||
subgrid: Optional subgrid if building an object in a subgrid
|
|
||||||
"""
|
"""
|
||||||
grid = model.G if subgrid is None else subgrid
|
uip = create_user_input_points(model.G, obj)
|
||||||
uip = create_user_input_points(grid, obj)
|
|
||||||
try:
|
try:
|
||||||
obj.build(model, uip)
|
obj.build(model, uip)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -98,7 +105,7 @@ class Scene:
|
|||||||
# to build in the correct subgrid.
|
# to build in the correct subgrid.
|
||||||
sg = sg_cmd.subgrid
|
sg = sg_cmd.subgrid
|
||||||
self.process_cmds(sg_cmd.children_multiple, model, sg)
|
self.process_cmds(sg_cmd.children_multiple, model, sg)
|
||||||
self.process_geocmds(sg_cmd.children_geometry, model, sg)
|
self.process_geocmds(sg_cmd.children_geometry, sg)
|
||||||
|
|
||||||
def process_cmds(
|
def process_cmds(
|
||||||
self,
|
self,
|
||||||
@@ -107,23 +114,22 @@ class Scene:
|
|||||||
subgrid: Optional[SubGridBaseGrid] = None,
|
subgrid: Optional[SubGridBaseGrid] = None,
|
||||||
):
|
):
|
||||||
"""Process list of commands."""
|
"""Process list of commands."""
|
||||||
|
grid = model.G if subgrid is None else subgrid
|
||||||
cmds_sorted = sorted(commands, key=lambda cmd: cmd.order)
|
cmds_sorted = sorted(commands, key=lambda cmd: cmd.order)
|
||||||
for obj in cmds_sorted:
|
for obj in cmds_sorted:
|
||||||
self.build_obj(obj, model, subgrid)
|
if isinstance(obj, UserObjectSingle):
|
||||||
|
self.build_model_obj(obj, model)
|
||||||
|
else:
|
||||||
|
self.build_grid_obj(obj, grid)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def process_geocmds(
|
def process_geocmds(self, commands, grid):
|
||||||
self,
|
|
||||||
commands: List[UserObjectGeometry],
|
|
||||||
model: Model,
|
|
||||||
subgrid: Optional[SubGridBaseGrid] = None,
|
|
||||||
):
|
|
||||||
# Check for fractal boxes and modifications and pre-process them first
|
# Check for fractal boxes and modifications and pre-process them first
|
||||||
proc_cmds = []
|
proc_cmds = []
|
||||||
for obj in commands:
|
for obj in commands:
|
||||||
if isinstance(obj, (FractalBox, AddGrass, AddSurfaceRoughness, AddSurfaceWater)):
|
if isinstance(obj, (FractalBox, AddGrass, AddSurfaceRoughness, AddSurfaceWater)):
|
||||||
self.build_obj(obj, model, subgrid)
|
self.build_grid_obj(obj, grid)
|
||||||
if isinstance(obj, (FractalBox)):
|
if isinstance(obj, (FractalBox)):
|
||||||
proc_cmds.append(obj)
|
proc_cmds.append(obj)
|
||||||
else:
|
else:
|
||||||
@@ -131,7 +137,7 @@ class Scene:
|
|||||||
|
|
||||||
# Process all geometry commands
|
# Process all geometry commands
|
||||||
for obj in proc_cmds:
|
for obj in proc_cmds:
|
||||||
self.build_obj(obj, model, subgrid)
|
self.build_grid_obj(obj, grid)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -160,8 +166,11 @@ class Scene:
|
|||||||
presents the user with UserObjects in order to build the internal
|
presents the user with UserObjects in order to build the internal
|
||||||
Rx(), Cylinder() etc... objects.
|
Rx(), Cylinder() etc... objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
G = model.G
|
||||||
|
|
||||||
# Create pre-defined (built-in) materials
|
# Create pre-defined (built-in) materials
|
||||||
create_built_in_materials(model.G)
|
create_built_in_materials(G)
|
||||||
|
|
||||||
# Process commands that can only have a single instance
|
# Process commands that can only have a single instance
|
||||||
self.process_singlecmds(model)
|
self.process_singlecmds(model)
|
||||||
@@ -170,11 +179,11 @@ class Scene:
|
|||||||
self.process_cmds(self.multiple_cmds, model)
|
self.process_cmds(self.multiple_cmds, model)
|
||||||
|
|
||||||
# Initialise geometry arrays for main and subgrids
|
# Initialise geometry arrays for main and subgrids
|
||||||
for grid in [model.G] + model.subgrids:
|
for grid in [G] + G.subgrids:
|
||||||
grid.initialise_geometry_arrays()
|
grid.initialise_geometry_arrays()
|
||||||
|
|
||||||
# Process the main grid geometry commands
|
# Process the main grid geometry commands
|
||||||
self.process_geocmds(self.geometry_cmds, model)
|
self.process_geocmds(self.geometry_cmds, G)
|
||||||
|
|
||||||
# Process all the commands for subgrids
|
# Process all the commands for subgrids
|
||||||
self.process_subgrid_cmds(model)
|
self.process_subgrid_cmds(model)
|
||||||
|
在新工单中引用
屏蔽一个用户