你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 15:27:57 +08:00
Refactor AddGress UserObject build process
这个提交包含在:
@@ -64,7 +64,7 @@ class AddGrass(UserObjectGeometry):
|
|||||||
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, model, uip):
|
||||||
"""Add Grass to fractal box."""
|
"""Add Grass to fractal box."""
|
||||||
try:
|
try:
|
||||||
p1 = self.kwargs["p1"]
|
p1 = self.kwargs["p1"]
|
||||||
@@ -91,7 +91,7 @@ class AddGrass(UserObjectGeometry):
|
|||||||
self._do_rotate()
|
self._do_rotate()
|
||||||
|
|
||||||
# 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 model.fractalvolumes if volume.ID == fractal_box_id]
|
||||||
try:
|
try:
|
||||||
volume = volumes[0]
|
volume = volumes[0]
|
||||||
except NameError:
|
except NameError:
|
||||||
@@ -103,7 +103,9 @@ class AddGrass(UserObjectGeometry):
|
|||||||
xf, yf, zf = p2
|
xf, yf, zf = p2
|
||||||
|
|
||||||
if frac_dim < 0:
|
if frac_dim < 0:
|
||||||
logger.exception(f"{self.__str__()} requires a positive value for the fractal dimension")
|
logger.exception(
|
||||||
|
f"{self.__str__()} requires a positive value for the fractal dimension"
|
||||||
|
)
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if limits[0] < 0 or limits[1] < 0:
|
if limits[0] < 0 or limits[1] < 0:
|
||||||
logger.exception(
|
logger.exception(
|
||||||
@@ -112,12 +114,15 @@ class AddGrass(UserObjectGeometry):
|
|||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
# Check for valid orientations
|
# Check for valid orientations
|
||||||
|
grid = uip.grid
|
||||||
if xs == xf:
|
if xs == xf:
|
||||||
if ys == yf or zs == zf:
|
if ys == yf or zs == zf:
|
||||||
logger.exception(f"{self.__str__()} dimensions are not specified correctly")
|
logger.exception(f"{self.__str__()} dimensions are not specified correctly")
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if xs not in [volume.xs, volume.xf]:
|
if xs not in [volume.xs, volume.xf]:
|
||||||
logger.exception(f"{self.__str__()} must specify external surfaces on a fractal box")
|
logger.exception(
|
||||||
|
f"{self.__str__()} must specify external surfaces on a fractal box"
|
||||||
|
)
|
||||||
raise ValueError
|
raise ValueError
|
||||||
fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx))
|
fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx))
|
||||||
# xminus surface
|
# xminus surface
|
||||||
@@ -142,7 +147,9 @@ class AddGrass(UserObjectGeometry):
|
|||||||
logger.exception(f"{self.__str__()} dimensions are not specified correctly")
|
logger.exception(f"{self.__str__()} dimensions are not specified correctly")
|
||||||
raise ValueError
|
raise ValueError
|
||||||
if ys not in [volume.ys, volume.yf]:
|
if ys not in [volume.ys, volume.yf]:
|
||||||
logger.exception(f"{self.__str__()} must specify external surfaces on a fractal box")
|
logger.exception(
|
||||||
|
f"{self.__str__()} must specify external surfaces on a fractal box"
|
||||||
|
)
|
||||||
raise ValueError
|
raise ValueError
|
||||||
fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy))
|
fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy))
|
||||||
# yminus surface
|
# yminus surface
|
||||||
@@ -164,7 +171,9 @@ class AddGrass(UserObjectGeometry):
|
|||||||
|
|
||||||
elif zs == zf:
|
elif zs == zf:
|
||||||
if zs not in [volume.zs, volume.zf]:
|
if zs not in [volume.zs, volume.zf]:
|
||||||
logger.exception(f"{self.__str__()} must specify external surfaces on a fractal box")
|
logger.exception(
|
||||||
|
f"{self.__str__()} must specify external surfaces on a fractal box"
|
||||||
|
)
|
||||||
raise ValueError
|
raise ValueError
|
||||||
fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz))
|
fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz))
|
||||||
# zminus surface
|
# zminus surface
|
||||||
@@ -219,7 +228,8 @@ class AddGrass(UserObjectGeometry):
|
|||||||
# probability values, and convert the 1D index back into a x, y index
|
# probability values, and convert the 1D index back into a x, y index
|
||||||
# for the original surface.
|
# for the original surface.
|
||||||
bladesindex = np.unravel_index(
|
bladesindex = np.unravel_index(
|
||||||
np.digitize(A, probability1D), (surface.fractalsurface.shape[0], surface.fractalsurface.shape[1])
|
np.digitize(A, probability1D),
|
||||||
|
(surface.fractalsurface.shape[0], surface.fractalsurface.shape[1]),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set the fractal range to minimum and maximum heights of the grass blades
|
# Set the fractal range to minimum and maximum heights of the grass blades
|
||||||
@@ -227,7 +237,9 @@ class AddGrass(UserObjectGeometry):
|
|||||||
|
|
||||||
# Set the fractal surface using the pre-calculated spatial distribution
|
# Set the fractal surface using the pre-calculated spatial distribution
|
||||||
# and a random height
|
# and a random height
|
||||||
surface.fractalsurface = np.zeros((surface.fractalsurface.shape[0], surface.fractalsurface.shape[1]))
|
surface.fractalsurface = np.zeros(
|
||||||
|
(surface.fractalsurface.shape[0], surface.fractalsurface.shape[1])
|
||||||
|
)
|
||||||
for i in range(len(bladesindex[0])):
|
for i in range(len(bladesindex[0])):
|
||||||
surface.fractalsurface[bladesindex[0][i], bladesindex[1][i]] = R.randint(
|
surface.fractalsurface[bladesindex[0][i], bladesindex[1][i]] = R.randint(
|
||||||
surface.fractalrange[0], surface.fractalrange[1], size=1
|
surface.fractalrange[0], surface.fractalrange[1], size=1
|
||||||
@@ -238,11 +250,11 @@ class AddGrass(UserObjectGeometry):
|
|||||||
surface.grass.append(g)
|
surface.grass.append(g)
|
||||||
|
|
||||||
# Check to see if grass has been already defined as a material
|
# Check to see if grass has been already defined as a material
|
||||||
if not any(x.ID == "grass" for x in grid.materials):
|
if not any(x.ID == "grass" for x in model.materials):
|
||||||
create_grass(grid)
|
create_grass(model)
|
||||||
|
|
||||||
# Check if time step for model is suitable for using grass
|
# Check if time step for model is suitable for using grass
|
||||||
grass = next((x for x in grid.materials if x.ID == "grass"))
|
grass = next((x for x in model.materials if x.ID == "grass"))
|
||||||
testgrass = next((x for x in grass.tau if x < grid.dt), None)
|
testgrass = next((x for x in grass.tau if x < grid.dt), None)
|
||||||
if testgrass:
|
if testgrass:
|
||||||
logger.exception(
|
logger.exception(
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy import fftpack
|
from scipy import fftpack
|
||||||
|
|
||||||
@@ -32,7 +34,17 @@ class FractalSurface:
|
|||||||
|
|
||||||
surfaceIDs = ["xminus", "xplus", "yminus", "yplus", "zminus", "zplus"]
|
surfaceIDs = ["xminus", "xplus", "yminus", "yplus", "zminus", "zplus"]
|
||||||
|
|
||||||
def __init__(self, xs, xf, ys, yf, zs, zf, dimension, seed):
|
def __init__(
|
||||||
|
self,
|
||||||
|
xs: float,
|
||||||
|
xf: float,
|
||||||
|
ys: float,
|
||||||
|
yf: float,
|
||||||
|
zs: float,
|
||||||
|
zf: float,
|
||||||
|
dimension: float,
|
||||||
|
seed: Optional[int] = None,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
xs, xf, ys, yf, zs, zf: floats for the extent of the fractal surface
|
xs, xf, ys, yf, zs, zf: floats for the extent of the fractal surface
|
||||||
@@ -43,8 +55,9 @@ class FractalSurface:
|
|||||||
seed: int for seed value for random number generator.
|
seed: int for seed value for random number generator.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ID = None
|
self.ID: str
|
||||||
self.surfaceID = None
|
self.surfaceID: str
|
||||||
|
self.operatingonID: str
|
||||||
self.xs = xs
|
self.xs = xs
|
||||||
self.xf = xf
|
self.xf = xf
|
||||||
self.ys = ys
|
self.ys = ys
|
||||||
@@ -56,9 +69,11 @@ class FractalSurface:
|
|||||||
self.nz = zf - zs
|
self.nz = zf - zs
|
||||||
self.dtype = np.dtype(np.complex128)
|
self.dtype = np.dtype(np.complex128)
|
||||||
self.seed = seed
|
self.seed = seed
|
||||||
self.dimension = dimension # Fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695
|
self.dimension = (
|
||||||
|
dimension # Fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695
|
||||||
|
)
|
||||||
self.weighting = np.array([1, 1], dtype=np.float64)
|
self.weighting = np.array([1, 1], dtype=np.float64)
|
||||||
self.fractalrange = (0, 0)
|
self.fractalrange: Tuple[int, int] = (0, 0)
|
||||||
self.filldepth = 0
|
self.filldepth = 0
|
||||||
self.grass = []
|
self.grass = []
|
||||||
|
|
||||||
@@ -82,7 +97,9 @@ class FractalSurface:
|
|||||||
self.fractalsurface = np.zeros(surfacedims, dtype=self.dtype)
|
self.fractalsurface = np.zeros(surfacedims, dtype=self.dtype)
|
||||||
|
|
||||||
# Positional vector at centre of array, scaled by weighting
|
# Positional vector at centre of array, scaled by weighting
|
||||||
v1 = np.array([self.weighting[0] * (surfacedims[0]) / 2, self.weighting[1] * (surfacedims[1]) / 2])
|
v1 = np.array(
|
||||||
|
[self.weighting[0] * (surfacedims[0]) / 2, self.weighting[1] * (surfacedims[1]) / 2]
|
||||||
|
)
|
||||||
|
|
||||||
# 2D array of random numbers to be convolved with the fractal function
|
# 2D array of random numbers to be convolved with the fractal function
|
||||||
rng = np.random.default_rng(seed=self.seed)
|
rng = np.random.default_rng(seed=self.seed)
|
||||||
@@ -137,8 +154,8 @@ class FractalVolume:
|
|||||||
seed: int for seed value for random number generator.
|
seed: int for seed value for random number generator.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.ID = None
|
self.ID: str
|
||||||
self.operatingonID = None
|
self.operatingonID: str
|
||||||
self.xs = xs
|
self.xs = xs
|
||||||
self.xf = xf
|
self.xf = xf
|
||||||
self.ys = ys
|
self.ys = ys
|
||||||
@@ -157,7 +174,9 @@ class FractalVolume:
|
|||||||
self.averaging = False
|
self.averaging = False
|
||||||
self.dtype = np.dtype(np.complex128)
|
self.dtype = np.dtype(np.complex128)
|
||||||
self.seed = seed
|
self.seed = seed
|
||||||
self.dimension = dimension # Fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695
|
self.dimension = (
|
||||||
|
dimension # Fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695
|
||||||
|
)
|
||||||
self.weighting = np.array([1, 1, 1], dtype=np.float64)
|
self.weighting = np.array([1, 1, 1], dtype=np.float64)
|
||||||
self.nbins = 0
|
self.nbins = 0
|
||||||
self.fractalsurfaces = []
|
self.fractalsurfaces = []
|
||||||
@@ -176,7 +195,9 @@ class FractalVolume:
|
|||||||
filterscaling = np.amin(np.array([self.nx, self.ny])) / np.array([self.nx, self.ny])
|
filterscaling = np.amin(np.array([self.nx, self.ny])) / np.array([self.nx, self.ny])
|
||||||
filterscaling = np.insert(filterscaling, 2, 1)
|
filterscaling = np.insert(filterscaling, 2, 1)
|
||||||
else:
|
else:
|
||||||
filterscaling = np.amin(np.array([self.nx, self.ny, self.nz])) / np.array([self.nx, self.ny, self.nz])
|
filterscaling = np.amin(np.array([self.nx, self.ny, self.nz])) / np.array(
|
||||||
|
[self.nx, self.ny, self.nz]
|
||||||
|
)
|
||||||
|
|
||||||
# Adjust weighting to account for filter scaling
|
# Adjust weighting to account for filter scaling
|
||||||
self.weighting = np.multiply(self.weighting, filterscaling)
|
self.weighting = np.multiply(self.weighting, filterscaling)
|
||||||
@@ -185,7 +206,11 @@ class FractalVolume:
|
|||||||
|
|
||||||
# Positional vector at centre of array, scaled by weighting
|
# Positional vector at centre of array, scaled by weighting
|
||||||
v1 = np.array(
|
v1 = np.array(
|
||||||
[self.weighting[0] * self.nx / 2, self.weighting[1] * self.ny / 2, self.weighting[2] * self.nz / 2]
|
[
|
||||||
|
self.weighting[0] * self.nx / 2,
|
||||||
|
self.weighting[1] * self.ny / 2,
|
||||||
|
self.weighting[2] * self.nz / 2,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# 3D array of random numbers to be convolved with the fractal function
|
# 3D array of random numbers to be convolved with the fractal function
|
||||||
@@ -225,7 +250,9 @@ class FractalVolume:
|
|||||||
bins = np.linspace(np.amin(self.fractalvolume), np.amax(self.fractalvolume), self.nbins)
|
bins = np.linspace(np.amin(self.fractalvolume), np.amax(self.fractalvolume), self.nbins)
|
||||||
for j in range(self.ny):
|
for j in range(self.ny):
|
||||||
for k in range(self.nz):
|
for k in range(self.nz):
|
||||||
self.fractalvolume[:, j, k] = np.digitize(self.fractalvolume[:, j, k], bins, right=True)
|
self.fractalvolume[:, j, k] = np.digitize(
|
||||||
|
self.fractalvolume[:, j, k], bins, right=True
|
||||||
|
)
|
||||||
|
|
||||||
def generate_volume_mask(self):
|
def generate_volume_mask(self):
|
||||||
"""Generate a 3D volume to use as a mask for adding rough surfaces,
|
"""Generate a 3D volume to use as a mask for adding rough surfaces,
|
||||||
@@ -254,7 +281,9 @@ class Grass:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self.numblades = numblades
|
self.numblades = numblades
|
||||||
self.geometryparams = np.zeros((self.numblades, 6), dtype=config.sim_config.dtypes["float_or_double"])
|
self.geometryparams = np.zeros(
|
||||||
|
(self.numblades, 6), dtype=config.sim_config.dtypes["float_or_double"]
|
||||||
|
)
|
||||||
self.seed = seed
|
self.seed = seed
|
||||||
self.set_geometry_parameters()
|
self.set_geometry_parameters()
|
||||||
|
|
||||||
|
@@ -73,9 +73,7 @@ class FDTDGrid:
|
|||||||
# corrections will be different.
|
# corrections will be different.
|
||||||
self.pmls["thickness"] = OrderedDict((key, 10) for key in PML.boundaryIDs)
|
self.pmls["thickness"] = OrderedDict((key, 10) for key in PML.boundaryIDs)
|
||||||
|
|
||||||
# TODO: Add type information.
|
|
||||||
self.averagevolumeobjects = True
|
self.averagevolumeobjects = True
|
||||||
self.fractalvolumes = []
|
|
||||||
self.waveforms: List[Waveform] = []
|
self.waveforms: List[Waveform] = []
|
||||||
self.voltagesources: List[VoltageSource] = []
|
self.voltagesources: List[VoltageSource] = []
|
||||||
self.hertziandipoles: List[HertzianDipole] = []
|
self.hertziandipoles: List[HertzianDipole] = []
|
||||||
|
@@ -26,6 +26,7 @@ import numpy as np
|
|||||||
import psutil
|
import psutil
|
||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
|
|
||||||
|
from gprMax.fractals import FractalVolume
|
||||||
from gprMax.grid.cuda_grid import CUDAGrid
|
from gprMax.grid.cuda_grid import CUDAGrid
|
||||||
from gprMax.grid.opencl_grid import OpenCLGrid
|
from gprMax.grid.opencl_grid import OpenCLGrid
|
||||||
from gprMax.materials import ListMaterial, Material, PeplinskiSoil, RangeMaterial
|
from gprMax.materials import ListMaterial, Material, PeplinskiSoil, RangeMaterial
|
||||||
@@ -67,6 +68,7 @@ class Model:
|
|||||||
self.subgrids: List[SubGridBaseGrid] = []
|
self.subgrids: List[SubGridBaseGrid] = []
|
||||||
self.materials: List[Material] = []
|
self.materials: List[Material] = []
|
||||||
self.mixingmodels: List[Union[PeplinskiSoil, RangeMaterial, ListMaterial]] = []
|
self.mixingmodels: List[Union[PeplinskiSoil, RangeMaterial, ListMaterial]] = []
|
||||||
|
self.fractalvolumes: List[FractalVolume] = []
|
||||||
|
|
||||||
self.geometryviews: List[GeometryView] = []
|
self.geometryviews: List[GeometryView] = []
|
||||||
self.geometryobjects: List[GeometryObjects] = []
|
self.geometryobjects: List[GeometryObjects] = []
|
||||||
|
在新工单中引用
屏蔽一个用户