diff --git a/gprMax/cmds_geometry/add_grass.py b/gprMax/cmds_geometry/add_grass.py index 377fea97..551d4063 100644 --- a/gprMax/cmds_geometry/add_grass.py +++ b/gprMax/cmds_geometry/add_grass.py @@ -78,8 +78,13 @@ class AddGrass(UserObjectGeometry): raise try: - seed = self.kwargs["seed"] + seed = int(self.kwargs["seed"]) except KeyError: + logger.warning( + f"{self.__str__()} no value for seed detected. This " + "means you will get a different fractal distribution " + "every time the model runs." + ) seed = None if self.do_rotate: @@ -183,10 +188,9 @@ class AddGrass(UserObjectGeometry): logger.exception(f"{self.__str__()} dimensions are not specified correctly") raise ValueError - surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim) + surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim, seed) surface.ID = "grass" surface.surfaceID = requestedsurface - surface.seed = seed # Set the fractal range to scale the fractal distribution between zero and one surface.fractalrange = (0, 1) @@ -230,8 +234,7 @@ class AddGrass(UserObjectGeometry): ) # Create grass geometry parameters - g = Grass(n_blades) - g.seed = surface.seed + g = Grass(n_blades, surface.seed) surface.grass.append(g) # Check to see if grass has been already defined as a material diff --git a/gprMax/cmds_geometry/add_surface_roughness.py b/gprMax/cmds_geometry/add_surface_roughness.py index a0755230..77e29ddf 100644 --- a/gprMax/cmds_geometry/add_surface_roughness.py +++ b/gprMax/cmds_geometry/add_surface_roughness.py @@ -78,7 +78,7 @@ class AddSurfaceRoughness(UserObjectGeometry): raise try: - seed = self.kwargs["seed"] + seed = int(self.kwargs["seed"]) except KeyError: logger.warning( f"{self.__str__()} no value for seed detected. This " @@ -213,14 +213,10 @@ class AddSurfaceRoughness(UserObjectGeometry): logger.exception(f"{self.__str__()} dimensions are not specified correctly") raise ValueError - surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim) + surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim, seed) surface.surfaceID = requestedsurface surface.fractalrange = fractalrange surface.operatingonID = volume.ID - if seed is not None: - surface.seed = int(seed) - else: - surface.seed = seed surface.weighting = weighting # List of existing surfaces IDs diff --git a/gprMax/cmds_geometry/fractal_box.py b/gprMax/cmds_geometry/fractal_box.py index 57a2c045..6f42ae31 100644 --- a/gprMax/cmds_geometry/fractal_box.py +++ b/gprMax/cmds_geometry/fractal_box.py @@ -83,7 +83,7 @@ class FractalBox(UserObjectGeometry): raise try: - seed = self.kwargs["seed"] + seed = int(self.kwargs["seed"]) except KeyError: logger.warning( f"{self.__str__()} no value for seed detected. This " @@ -148,14 +148,10 @@ class FractalBox(UserObjectGeometry): logger.exception(f"{self.__str__()} mixing model or material with " + "ID {mixing_model_id} does not exist") raise ValueError - volume = FractalVolume(xs, xf, ys, yf, zs, zf, frac_dim) + volume = FractalVolume(xs, xf, ys, yf, zs, zf, frac_dim, seed) volume.ID = ID volume.operatingonID = mixing_model_id volume.nbins = nbins - if seed is not None: - volume.seed = int(seed) - else: - volume.seed = seed volume.weighting = weighting volume.averaging = averagefractalbox volume.mixingmodel = mixingmodel diff --git a/gprMax/fractals.py b/gprMax/fractals.py index 607e247a..ffb2109e 100644 --- a/gprMax/fractals.py +++ b/gprMax/fractals.py @@ -32,7 +32,7 @@ class FractalSurface: surfaceIDs = ["xminus", "xplus", "yminus", "yplus", "zminus", "zplus"] - def __init__(self, xs, xf, ys, yf, zs, zf, dimension): + def __init__(self, xs, xf, ys, yf, zs, zf, dimension, seed): """ Args: xs, xf, ys, yf, zs, zf: floats for the extent of the fractal surface @@ -40,6 +40,7 @@ class FractalSurface: to correctly define a surface). dimension: float for the fractal dimension that controls the fractal distribution. + seed: int for seed value for random number generator. """ self.ID = None @@ -54,7 +55,7 @@ class FractalSurface: self.ny = yf - ys self.nz = zf - zs self.dtype = np.dtype(np.complex128) - self.seed = None + self.seed = seed self.dimension = dimension # Constant related to fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695 self.b = -(2 * self.dimension - 7) / 2 @@ -129,12 +130,13 @@ class FractalSurface: class FractalVolume: """Fractal volumes.""" - def __init__(self, xs, xf, ys, yf, zs, zf, dimension): + def __init__(self, xs, xf, ys, yf, zs, zf, dimension, seed): """ Args: xs, xf, ys, yf, zs, zf: floats for the extent of the fractal volume. dimension: float for the fractal dimension that controls the fractal distribution. + seed: int for seed value for random number generator. """ self.ID = None @@ -156,7 +158,7 @@ class FractalVolume: self.originalzf = zf self.averaging = False self.dtype = np.dtype(np.complex128) - self.seed = None + self.seed = seed self.dimension = dimension # Constant related to fractal dimension from: http://dx.doi.org/10.1017/CBO9781139174695 self.b = -(2 * self.dimension - 7) / 2 @@ -248,17 +250,22 @@ class FractalVolume: class Grass: """Geometry information for blades of grass.""" - def __init__(self, numblades): + def __init__(self, numblades, seed): """ Args: numblades: int for the number of blades of grass. + seed: int for seed value for random number generator. """ self.numblades = numblades self.geometryparams = np.zeros((self.numblades, 6), dtype=config.sim_config.dtypes["float_or_double"]) - self.seed = None + self.seed = seed + + def set_geometry_parameters(self): + """Sets randomly defined parameters that will be used to calculate + blade and root geometries. + """ - # Randomly defined parameters that will be used to calculate geometry self.R1 = np.random.default_rng(seed=self.seed) self.R2 = np.random.default_rng(seed=self.seed) self.R3 = np.random.default_rng(seed=self.seed)