From 6b793f0d7d5674a28679c06bcbb3144135d28d36 Mon Sep 17 00:00:00 2001 From: Craig Warren Date: Thu, 3 Nov 2022 21:16:39 +0000 Subject: [PATCH] Updates docstrings and line lengths --- gprMax/cmds_geometry/add_grass.py | 67 +++++++++----- gprMax/cmds_geometry/add_surface_roughness.py | 88 +++++++++++++------ gprMax/cmds_geometry/add_surface_water.py | 42 +++++---- gprMax/cmds_geometry/box.py | 31 +++---- gprMax/cmds_geometry/cmds_geometry.py | 35 ++++---- gprMax/cmds_geometry/cylinder.py | 35 ++++---- gprMax/cmds_geometry/cylindrical_sector.py | 73 ++++++++------- gprMax/cmds_geometry/edge.py | 21 ++--- gprMax/cmds_geometry/fractal_box.py | 78 +++++++++------- gprMax/cmds_geometry/fractal_box_builder.py | 6 +- gprMax/cmds_geometry/geometry_objects_read.py | 26 ++++-- gprMax/cmds_geometry/plate.py | 27 +++--- gprMax/cmds_geometry/sphere.py | 29 +++--- gprMax/cmds_geometry/triangle.py | 46 +++++----- 14 files changed, 359 insertions(+), 245 deletions(-) diff --git a/gprMax/cmds_geometry/add_grass.py b/gprMax/cmds_geometry/add_grass.py index 762e4b61..a3b4b628 100644 --- a/gprMax/cmds_geometry/add_grass.py +++ b/gprMax/cmds_geometry/add_grass.py @@ -29,20 +29,21 @@ logger = logging.getLogger(__name__) class AddGrass(UserObjectGeometry): - """Allows you to add grass with roots to a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` in the model. + """Allows you to add grass with roots to a FractalBox class in the model. - :param p1: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p1: list, non-optional - :param p2: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p2: list, non-optional - :param frac_dim: is the fractal dimension which, for an orthogonal parallelepiped, should take values between zero and three. - :type frac_dim: float, non-optional - :param limits: Define lower and upper limits for a range over which the height of the blades of grass can vary. - :type limits: list, non-optional - :param n_blades: The number of blades of grass that should be applied to the surface area. - :type n_blades: int, non-optional - :param fractal_box_id: An identifier for the :class:`gprMax.cmds_geometry.fractal_box.FractalBox` that the grass should be applied to - :type fractal_box_id: list, non-optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of a surface on a + FractalBox class. + p2: a list of the upper right (x,y,z) coordinates of a surface on a + FractalBox class. + frac_dim: a float for the fractal dimension which, for an orthogonal + parallelepiped, should take values between zero and three. + limits: a list to define lower and upper limits for a range over which + the height of the blades of grass can vary. + n_blades: an int for the number of blades of grass that should be + applied to the surface area. + fractal_box_id: a string identifier for the FractalBox class that the + grass should be applied to. """ def __init__(self, **kwargs): @@ -97,10 +98,12 @@ class AddGrass(UserObjectGeometry): xf, yf, zf = p2 if frac_dim < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for ' + + 'the fractal dimension') raise ValueError if limits[0] < 0 or limits[1] < 0: - logger.exception(self.__str__() + ' requires a positive value for the minimum and maximum heights for grass blades') + logger.exception(self.__str__() + ' requires a positive value for ' + + 'the minimum and maximum heights for grass blades') raise ValueError # Check for valid orientations @@ -114,12 +117,15 @@ class AddGrass(UserObjectGeometry): fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx)) # xminus surface if xs == volume.xs: - logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified ' + + 'on surfaces in the positive axis direction') raise ValueError # xplus surface elif xf == volume.xf: if fractalrange[1] > grid.nx: - logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the x direction') + logger.exception(self.__str__() + ' cannot apply grass to ' + + 'fractal box as it would exceed the domain ' + + 'size in the x direction') raise ValueError requestedsurface = 'xplus' @@ -133,12 +139,15 @@ class AddGrass(UserObjectGeometry): fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy)) # yminus surface if ys == volume.ys: - logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified ' + + 'on surfaces in the positive axis direction') raise ValueError # yplus surface elif yf == volume.yf: if fractalrange[1] > grid.ny: - logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the y direction') + logger.exception(self.__str__() + ' cannot apply grass to ' + + 'fractal box as it would exceed the domain ' + + 'size in the y direction') raise ValueError requestedsurface = 'yplus' @@ -152,12 +161,15 @@ class AddGrass(UserObjectGeometry): fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz)) # zminus surface if zs == volume.zs: - logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified ' + + 'on surfaces in the positive axis direction') raise ValueError # zplus surface elif zf == volume.zf: if fractalrange[1] > grid.nz: - logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the z direction') + logger.exception(self.__str__() + ' cannot apply grass to ' + + 'fractal box as it would exceed the domain ' + + 'size in the z direction') raise ValueError requestedsurface = 'zplus' @@ -175,7 +187,8 @@ class AddGrass(UserObjectGeometry): surface.operatingonID = volume.ID surface.generate_fractal_surface() if n_blades > surface.fractalsurface.shape[0] * surface.fractalsurface.shape[1]: - logger.exception(self.__str__() + ' the specified surface is not large enough for the number of grass blades/roots specified') + logger.exception(self.__str__() + ' the specified surface is not large ' + + 'enough for the number of grass blades/roots specified') raise ValueError # Scale the distribution so that the summation is equal to one, i.e. a probability distribution @@ -213,9 +226,15 @@ class AddGrass(UserObjectGeometry): grass = next((x for x in grid.materials if x.ID == 'grass')) testgrass = next((x for x in grass.tau if x < grid.dt), None) if testgrass: - logger.exception(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model grass.') + logger.exception(self.__str__() + ' requires the time step for the ' + + 'model to be less than the relaxation time required to model grass.') raise ValueError volume.fractalsurfaces.append(surface) - logger.info(self.grid_name(grid) + f'{n_blades} blades of grass on surface from {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, {yf * grid.dy:g}m, {zf * grid.dz:g}m with fractal dimension {surface.dimension:g}, fractal seeding {surface.seed}, and range {limits[0]:g}m to {limits[1]:g}m, added to {surface.operatingonID}.') + logger.info(self.grid_name(grid) + f'{n_blades} blades of grass on surface from ' + + f'{xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, ' + + f'to {xf * grid.dx:g}m, {yf * grid.dy:g}m, {zf * grid.dz:g}m ' + + f'with fractal dimension {surface.dimension:g}, fractal seeding ' + + f'{surface.seed}, and range {limits[0]:g}m to {limits[1]:g}m, ' + + f'added to {surface.operatingonID}.') diff --git a/gprMax/cmds_geometry/add_surface_roughness.py b/gprMax/cmds_geometry/add_surface_roughness.py index 47db0a13..50f77024 100644 --- a/gprMax/cmds_geometry/add_surface_roughness.py +++ b/gprMax/cmds_geometry/add_surface_roughness.py @@ -28,22 +28,23 @@ logger = logging.getLogger(__name__) class AddSurfaceRoughness(UserObjectGeometry): - """Allows you to add grass with roots to a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` in the model. + """Allows you to add grass with roots to a FractalBox class in the model. - :param p1: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p1: list, non-optional - :param p2: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p2: list, non-optional - :param frac_dim: is the fractal dimension which, for an orthogonal parallelepiped, should take values between zero and three. - :type frac_dim: float, non-optional - :param weighting: Weightings in the first and second direction of the surface. - :type weighting: list, non-optional - :param limits: Define lower and upper limits for a range over which the roughness can vary. - :type limits: list, non-optional - :param fractal_box_id: An identifier for the :class:`gprMax.cmds_geometry.fractal_box.FractalBox` that the roughness should be applied to - :type fractal_box_id: list, non-optional - :param seed: Is an optional parameter which controls the seeding of the random number generator used to create the fractals. - :type seed: int, optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of a surface on a + FractalBox class. + p2: a list of the upper right (x,y,z) coordinates of a surface on a + FractalBox class. + frac_dim: a float for the fractal dimension which, for an orthogonal + parallelepiped, should take values between zero and three. + weighting: a list with weightings in the first and second direction of + the surface. + limits: a list to define lower and upper limits for a range over which + the surface roughness can vary. + fractal_box_id: a string identifier for the FractalBox class + that the surface roughness should be applied to. + seed: (optional) float parameter which controls the seeding of the random + number generator used to create the fractals. """ def __init__(self, **kwargs): @@ -65,7 +66,6 @@ class AddSurfaceRoughness(UserObjectGeometry): self.kwargs['p2'] = tuple(rot_pts[1, :]) def create(self, grid, uip): - try: p1 = self.kwargs['p1'] p2 = self.kwargs['p2'] @@ -98,13 +98,16 @@ class AddSurfaceRoughness(UserObjectGeometry): xf, yf, zf = p2 if frac_dim < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal dimension') raise ValueError if weighting[0] < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the first direction of the surface') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal weighting in the first direction of the surface') raise ValueError if weighting[1] < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the second direction of the surface') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal weighting in the second direction of the surface') raise ValueError # Check for valid orientations @@ -113,19 +116,26 @@ class AddSurfaceRoughness(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if xs != volume.xs and xs != volume.xf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external ' + + 'surfaces of a fractal box') raise ValueError fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx)) # xminus surface if xs == volume.xs: if fractalrange[0] < 0 or fractalrange[1] > volume.xf: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'upper coordinates of the fractal box or the ' + + 'domain in the x direction') raise ValueError requestedsurface = 'xminus' # xplus surface elif xf == volume.xf: if fractalrange[0] < volume.xs or fractalrange[1] > grid.nx: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'lower coordinates of the fractal box or the ' + + 'domain in the x direction') raise ValueError requestedsurface = 'xplus' @@ -134,19 +144,26 @@ class AddSurfaceRoughness(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if ys != volume.ys and ys != volume.yf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external ' + + 'surfaces of a fractal box') raise ValueError fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy)) # yminus surface if ys == volume.ys: if fractalrange[0] < 0 or fractalrange[1] > volume.yf: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the y direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'upper coordinates of the fractal box or the ' + + 'domain in the y direction') raise ValueError requestedsurface = 'yminus' # yplus surface elif yf == volume.yf: if fractalrange[0] < volume.ys or fractalrange[1] > grid.ny: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the y direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'lower coordinates of the fractal box or the ' + + 'domain in the y direction') raise ValueError requestedsurface = 'yplus' @@ -155,19 +172,26 @@ class AddSurfaceRoughness(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if zs != volume.zs and zs != volume.zf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external ' + + 'surfaces of a fractal box') raise ValueError fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz)) # zminus surface if zs == volume.zs: if fractalrange[0] < 0 or fractalrange[1] > volume.zf: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'upper coordinates of the fractal box or the ' + + 'domain in the x direction') raise ValueError requestedsurface = 'zminus' # zplus surface elif zf == volume.zf: if fractalrange[0] < volume.zs or fractalrange[1] > grid.nz: - logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the z direction') + logger.exception(self.__str__() + ' cannot apply fractal surface ' + + 'to fractal box as it would exceed either the ' + + 'lower coordinates of the fractal box or the ' + + 'domain in the z direction') raise ValueError requestedsurface = 'zplus' @@ -194,4 +218,10 @@ class AddSurfaceRoughness(UserObjectGeometry): surface.generate_fractal_surface() volume.fractalsurfaces.append(surface) - logger.info(self.grid_name(grid) + f'Fractal surface from {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, {yf * grid.dy:g}m, {zf * grid.dz:g}m with fractal dimension {surface.dimension:g}, fractal weightings {surface.weighting[0]:g}, {surface.weighting[1]:g}, fractal seeding {surface.seed}, and range {limits[0]:g}m to {limits[1]:g}m, added to {surface.operatingonID}.') + logger.info(self.grid_name(grid) + f'Fractal surface from {xs * grid.dx:g}m, ' + + f'{ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, ' + + f'{yf * grid.dy:g}m, {zf * grid.dz:g}m with fractal dimension ' + + f'{surface.dimension:g}, fractal weightings {surface.weighting[0]:g}, ' + + f'{surface.weighting[1]:g}, fractal seeding {surface.seed}, ' + + f'and range {limits[0]:g}m to {limits[1]:g}m, added to ' + + f'{surface.operatingonID}.') diff --git a/gprMax/cmds_geometry/add_surface_water.py b/gprMax/cmds_geometry/add_surface_water.py index efd9131d..6718a604 100644 --- a/gprMax/cmds_geometry/add_surface_water.py +++ b/gprMax/cmds_geometry/add_surface_water.py @@ -28,16 +28,18 @@ logger = logging.getLogger(__name__) class AddSurfaceWater(UserObjectGeometry): - """Allows you to add surface water to a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` in the model. + """Allows you to add surface water to a FractalBox class in the model. - :param p1: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p1: list, non-optional - :param p2: The lower left (x,y,z) coordinates of a surface on a :class:`gprMax.cmds_geometry.fractal_box.FractalBox` - :type p2: list, non-optional - :param depth: Defines the depth of the water, which should be specified relative to the dimensions of the #fractal_box that the surface water is being applied. - :type depth: float, non-optional - :param fractal_box_id: An identifier for the :class:`gprMax.cmds_geometry.fractal_box.FractalBox` that the water should be applied to - :type fractal_box_id: list, non-optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of a surface on a + FractalBox class. + p2: a list of the upper right (x,y,z) coordinates of a surface on a + FractalBox class. + depth: a float that defines the depth of the water, which should be + specified relative to the dimensions of the #fractal_box that + the surface water is being applied. + fractal_box_id: a string identifier for the FractalBox class that the + surface water should be applied to. """ def __init__(self, **kwargs): @@ -94,7 +96,8 @@ class AddSurfaceWater(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if xs != volume.xs and xs != volume.xf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the ' + + 'external surfaces of a fractal box') raise ValueError # xminus surface if xs == volume.xs: @@ -110,7 +113,8 @@ class AddSurfaceWater(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if ys != volume.ys and ys != volume.yf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the ' + + 'external surfaces of a fractal box') raise ValueError # yminus surface if ys == volume.ys: @@ -126,7 +130,8 @@ class AddSurfaceWater(UserObjectGeometry): logger.exception(self.__str__() + ' dimensions are not specified correctly') raise ValueError if zs != volume.zs and zs != volume.zf: - logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the ' + + 'external surfaces of a fractal box') raise ValueError # zminus surface if zs == volume.zs: @@ -150,7 +155,9 @@ class AddSurfaceWater(UserObjectGeometry): # Check that requested fill depth falls within range of surface roughness if surface.filldepth < surface.fractalrange[0] or surface.filldepth > surface.fractalrange[1]: - logger.exception(self.__str__() + ' requires a value for the depth of water that lies with the range of the requested surface roughness') + logger.exception(self.__str__() + ' requires a value for the depth ' + + 'of water that lies with the range of the requested ' + + 'surface roughness') raise ValueError # Check to see if water has been already defined as a material @@ -161,7 +168,12 @@ class AddSurfaceWater(UserObjectGeometry): water = next((x for x in grid.materials if x.ID == 'water')) testwater = next((x for x in water.tau if x < grid.dt), None) if testwater: - logger.exception(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model water.') + logger.exception(self.__str__() + ' requires the time step for the ' + + 'model to be less than the relaxation time required ' + + 'to model water.') raise ValueError - logger.info(self.grid_name(grid) + f'Water on surface from {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, {yf * grid.dy:g}m, {zf * grid.dz:g}m with depth {filldepth:g}m, added to {surface.operatingonID}.') + logger.info(self.grid_name(grid) + f'Water on surface from {xs * grid.dx:g}m, ' + + f'{ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, ' + + f'{yf * grid.dy:g}m, {zf * grid.dz:g}m with depth {filldepth:g}m, ' + + f'added to {surface.operatingonID}.') diff --git a/gprMax/cmds_geometry/box.py b/gprMax/cmds_geometry/box.py index d9af67a3..5fa2be69 100644 --- a/gprMax/cmds_geometry/box.py +++ b/gprMax/cmds_geometry/box.py @@ -28,18 +28,16 @@ logger = logging.getLogger(__name__) class Box(UserObjectGeometry): - """Allows you to introduce an orthogonal parallelepiped with specific properties into the model. + """Allows you to introduce an orthogonal parallelepiped with specific + properties into the model. - :param p1: The lower left (x,y,z) coordinates of a the box. - :type p1: list, non-optional - :param p2: The lower left (x,y,z) coordinates of the box. - :type p2: list, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of the parallelepiped. + p2: a list of the upper right (x,y,z) coordinates of the parallelepiped. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -71,8 +69,8 @@ class Box(UserObjectGeometry): if self.dorotate: self.__dorotate() - # check materials have been specified - # isotropic case + # Check materials have been specified + # Isotropic case try: materialsrequested = [self.kwargs['material_id']] except KeyError: @@ -92,7 +90,7 @@ class Box(UserObjectGeometry): averagebox = grid.averagevolumeobjects 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) p6 = uip.round_to_grid_static_point(p2) xs, ys, zs = p3 @@ -138,4 +136,7 @@ class Box(UserObjectGeometry): dielectricsmoothing = 'on' if averaging else 'off' - logger.info(self.grid_name(grid) + f"Box from {p5[0]:g}m, {p5[1]:g}m, {p5[2]:g}m, to {p6[0]:g}m, {p6[1]:g}m, {p6[2]:g}m of material(s) {', '.join(materialsrequested)} created, dielectric smoothing is {dielectricsmoothing}.") + logger.info(self.grid_name(grid) + f"Box from {p5[0]:g}m, {p5[1]:g}m, " + + f"{p5[2]:g}m, to {p6[0]:g}m, {p6[1]:g}m, {p6[2]:g}m of " + + f"material(s) {', '.join(materialsrequested)} created, " + + f"dielectric smoothing is {dielectricsmoothing}.") diff --git a/gprMax/cmds_geometry/cmds_geometry.py b/gprMax/cmds_geometry/cmds_geometry.py index e2246959..803d4959 100644 --- a/gprMax/cmds_geometry/cmds_geometry.py +++ b/gprMax/cmds_geometry/cmds_geometry.py @@ -67,13 +67,13 @@ def rotate_point(p, axis, angle, origin=(0, 0, 0)): """Rotate a point. Args: - p (array): coordinates of point (x, y, z) - axis (str): axis about which to perform rotation (x, y, or z) - angle (int): angle of rotation (degrees) - origin (tuple): point about which to perform rotation (x, y, z) + p: an array of coordinates of point (x, y, z). + axis: a string which defines the axis about which to perform rotation (x, y, or z). + angle: an int specifying the angle of rotation (degrees). + origin: a tuple defining the point about which to perform rotation (x, y, z). Returns: - p (array): coordinates of rotated point (x, y, z) + p: an array of coordinates of rotated point (x, y, z) """ origin = np.array(origin) @@ -97,13 +97,13 @@ def rotate_2point_object(pts, axis, angle, origin=None): """Rotate a geometry object that is defined by 2 points. Args: - pts (array): coordinates of points of object to be rotated - axis (str): axis about which to perform rotation (x, y, or z) - angle (int): angle of rotation (degrees) - origin (tuple): point about which to perform rotation (x, y, z) + pts: an array ofcoordinates of points of object to be rotated. + axis: a string which defines the axis about which to perform rotation (x, y, or z). + angle: an int specifying the angle of rotation (degrees). + origin: a tuple defining the point about which to perform rotation (x, y, z). Returns: - new_pts (array): coordinates of points of rotated object + new_pts: an array of coordinates of points of rotated object. """ # Use origin at centre of object if not given @@ -155,16 +155,15 @@ def rotate_polarisation(p, polarisation, axis, angle, G): """Rotate a geometry object that is defined by a point and polarisation. Args: - p (array): coordinates of point (x, y, z) - polarisation (str): current polarisation (x, y, or z) - axis (str): axis about which to perform rotation (x, y, or z) - angle (int): angle of rotation (degrees) - G (class): Grid class instance - holds essential parameters - describing the model. + p: an array of coordinates of point (x, y, z). + polarisation: a string defining the current polarisation (x, y, or z). + axis: a string which defines the axis about which to perform rotation (x, y, or z). + angle: an int specifying the angle of rotation (degrees). + G: FDTDGrid class describing a grid in a model. Returns: - pts (array): coordinates of points of rotated object - new_polarisation (str): new polarisation (x, y, or z) + pts: an array of coordinates of points of rotated object. + new_polarisation: a string defining the new polarisation (x, y, or z). """ if polarisation.lower() == 'x': diff --git a/gprMax/cmds_geometry/cylinder.py b/gprMax/cmds_geometry/cylinder.py index bf7a0d00..e1541a46 100644 --- a/gprMax/cmds_geometry/cylinder.py +++ b/gprMax/cmds_geometry/cylinder.py @@ -30,18 +30,16 @@ logger = logging.getLogger(__name__) class Cylinder(UserObjectGeometry): """Allows you to introduce a circular cylinder into the model. - :param p1: The coordinates (x,y,z) of the centre of the first face of the cylinder. - :type p1: list, non-optional - :param p2: The coordinates (x,y,z) of the centre of the second face of the cylinder. - :type p2: list, non-optional - :param r: is the radius of the cylinder. - :type r: float, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + p1: a list of the coordinates (x,y,z) of the centre of the first face + of the cylinder. + p2: a list of the coordinates (x,y,z) of the centre of the second face + of the cylinder. + r: float of the radius of the cylinder. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -65,8 +63,8 @@ class Cylinder(UserObjectGeometry): # Otherwise go with the grid default averagecylinder = grid.averagevolumeobjects - # check materials have been specified - # isotropic case + # Check materials have been specified + # Isotropic case try: materialsrequested = [self.kwargs['material_id']] except KeyError: @@ -123,7 +121,12 @@ class Cylinder(UserObjectGeometry): # Append the new material object to the materials list grid.materials.append(m) - build_cylinder(x1, y1, z1, x2, y2, z2, r, grid.dx, grid.dy, grid.dz, numID, numIDx, numIDy, numIDz, averaging, grid.solid, grid.rigidE, grid.rigidH, grid.ID) + build_cylinder(x1, y1, z1, x2, y2, z2, r, grid.dx, grid.dy, grid.dz, + numID, numIDx, numIDy, numIDz, averaging, grid.solid, + grid.rigidE, grid.rigidH, grid.ID) dielectricsmoothing = 'on' if averaging else 'off' - logger.info(self.grid_name(grid) + f"Cylinder with face centres {p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m and {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m, with radius {r:g}m, of material(s) {', '.join(materialsrequested)} created, dielectric smoothing is {dielectricsmoothing}.") + logger.info(self.grid_name(grid) + f"Cylinder with face centres {p3[0]:g}m, " + + f"{p3[1]:g}m, {p3[2]:g}m and {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m, " + + f"with radius {r:g}m, of material(s) {', '.join(materialsrequested)} " + + f"created, dielectric smoothing is {dielectricsmoothing}.") diff --git a/gprMax/cmds_geometry/cylindrical_sector.py b/gprMax/cmds_geometry/cylindrical_sector.py index 037f644a..88f6dce2 100644 --- a/gprMax/cmds_geometry/cylindrical_sector.py +++ b/gprMax/cmds_geometry/cylindrical_sector.py @@ -28,30 +28,28 @@ logger = logging.getLogger(__name__) class CylindricalSector(UserObjectGeometry): - """Allows you to introduce a cylindrical sector (shaped like a slice of pie) into the model. + """Allows you to introduce a cylindrical sector (shaped like a slice of pie) + into the model. - :param normal: Direction of the axis of the cylinder from which the sector is defined and can be x, y, or z.. - :type normal: str, non-optional - :param ctr1: First coordinate of the centre of the cylindrical sector. - :type ctr1: float, non-optional - :param ctr2: Second coordinate of the centre of the cylindrical sector. - :type ctr2: Float, non-optional - :param extent1: First thickness from the centre of the cylindrical sector. - :type extent1: float, non-optional - :param extent2: Second thickness from the centre of the cylindrical sector. - :type extent2: float, non-optional - :param r: is the radius of the cylindrical sector. - :type r: float, non-optional - :param start: The starting angle (in degrees) for the cylindrical sector. - :type start: float, non-optional - :param end: The angle (in degrees) swept by the cylindrical sector - :type end: float, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + normal: a string for the direction of the axis of the cylinder from which + the sector is defined and can be x, y, or z. + ctr1: a float for the first coordinate of the centre of the cylindrical + sector. + ctr2: a float for the second coordinate of the centre of the cylindrical + sector. + extent1: a float for the first thickness from the centre of the + cylindrical sector. + extent2: a float for the second thickness from the centre of the + cylindrical sector. + r: a float for the radius of the cylindrical sector. + start: a float for the starting angle (in degrees) for the cylindrical + sector. + end: a float for the angle (in degrees) swept by the cylindrical sector. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -82,8 +80,8 @@ class CylindricalSector(UserObjectGeometry): # Otherwise go with the grid default averagecylindricalsector = grid.averagevolumeobjects - # check materials have been specified - # isotropic case + # Check materials have been specified + # Isotropic case try: materialsrequested = [self.kwargs['material_id']] except KeyError: @@ -103,10 +101,12 @@ class CylindricalSector(UserObjectGeometry): if r <= 0: logger.exception(self.__str__() + f' the radius {r:g} should be a positive value.') if sectorstartangle < 0 or sectorangle <= 0: - logger.exception(self.__str__() + ' the starting angle and sector angle should be a positive values.') + logger.exception(self.__str__() + ' the starting angle and sector ' + + 'angle should be a positive values.') raise ValueError if sectorstartangle >= 2 * np.pi or sectorangle >= 2 * np.pi: - logger.exception(self.__str__() + ' the starting angle and sector angle must be less than 360 degrees.') + logger.exception(self.__str__() + ' the starting angle and sector ' + + 'angle must be less than 360 degrees.') raise ValueError # Look up requested materials in existing list of material instances @@ -171,10 +171,23 @@ class CylindricalSector(UserObjectGeometry): elif normal == 'z': ctr1, ctr2, level = uip.round_to_grid((ctr1, ctr2, extent1)) - build_cylindrical_sector(ctr1, ctr2, level, sectorstartangle, sectorangle, r, normal, thickness, grid.dx, grid.dy, grid.dz, numID, numIDx, numIDy, numIDz, averaging, grid.solid, grid.rigidE, grid.rigidH, grid.ID) + build_cylindrical_sector(ctr1, ctr2, level, sectorstartangle, sectorangle, + r, normal, thickness, grid.dx, grid.dy, grid.dz, + numID, numIDx, numIDy, numIDz, averaging, + grid.solid, grid.rigidE, grid.rigidH, grid.ID) if thickness > 0: dielectricsmoothing = 'on' if averaging else 'off' - logger.info(self.grid_name(grid) + f"Cylindrical sector with centre {ctr1:g}m, {ctr2:g}m, radius {r:g}m, starting angle {(sectorstartangle / (2 * np.pi)) * 360:.1f} degrees, sector angle {(sectorangle / (2 * np.pi)) * 360:.1f} degrees, thickness {thickness:g}m, of material(s) {', '.join(materialsrequested)} created, dielectric smoothing is {dielectricsmoothing}.") + logger.info(self.grid_name(grid) + f"Cylindrical sector with centre " + + f"{ctr1:g}m, {ctr2:g}m, radius {r:g}m, starting angle " + + f"{(sectorstartangle / (2 * np.pi)) * 360:.1f} degrees, " + + f"sector angle {(sectorangle / (2 * np.pi)) * 360:.1f} degrees, " + + f"thickness {thickness:g}m, of material(s) {', '.join(materialsrequested)} " + + f"created, dielectric smoothing is {dielectricsmoothing}.") else: - logger.info(self.grid_name(grid) + f"Cylindrical sector with centre {ctr1:g}m, {ctr2:g}m, radius {r:g}m, starting angle {(sectorstartangle / (2 * np.pi)) * 360:.1f} degrees, sector angle {(sectorangle / (2 * np.pi)) * 360:.1f} degrees, of material(s) {', '.join(materialsrequested)} created.") + logger.info(self.grid_name(grid) + f"Cylindrical sector with centre " + + f"{ctr1:g}m, {ctr2:g}m, radius {r:g}m, starting angle " + + f"{(sectorstartangle / (2 * np.pi)) * 360:.1f} degrees, " + + f"sector angle {(sectorangle / (2 * np.pi)) * 360:.1f} " + + f"degrees, of material(s) {', '.join(materialsrequested)} " + + f"created.") diff --git a/gprMax/cmds_geometry/edge.py b/gprMax/cmds_geometry/edge.py index e465283b..5f8940da 100644 --- a/gprMax/cmds_geometry/edge.py +++ b/gprMax/cmds_geometry/edge.py @@ -30,12 +30,11 @@ logger = logging.getLogger(__name__) class Edge(UserObjectGeometry): """Allows you to introduce a wire with specific properties into the model. - :param p1: Starting point of the edge. - :type p1: list, non-optional - :param p2: Ending point of the edge. - :type p2: list, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional + Attributes: + p1: a list of the coordinates (x,y,z) of the starting point of the edge. + p2: a list of the coordinates (x,y,z) of the ending point of the edge. + material_id: a string for the material identifier that must correspond + to material that has already been defined. """ def __init__(self, **kwargs): @@ -83,7 +82,7 @@ class Edge(UserObjectGeometry): raise ValueError # Check for valid orientations - # x-orientated wire + # x-orientated edge if xs != xf: if ys != yf or zs != zf: logger.exception(self.__str__() + ' the edge is not specified correctly') @@ -92,7 +91,7 @@ class Edge(UserObjectGeometry): for i in range(xs, xf): build_edge_x(i, ys, zs, material.numID, grid.rigidE, grid.rigidH, grid.ID) - # y-orientated wire + # y-orientated edge elif ys != yf: if xs != xf or zs != zf: logger.exception(self.__str__() + ' the edge is not specified correctly') @@ -101,7 +100,7 @@ class Edge(UserObjectGeometry): for j in range(ys, yf): build_edge_y(xs, j, zs, material.numID, grid.rigidE, grid.rigidH, grid.ID) - # z-orientated wire + # z-orientated edge elif zs != zf: if xs != xf or ys != yf: logger.exception(self.__str__() + ' the edge is not specified correctly') @@ -110,4 +109,6 @@ class Edge(UserObjectGeometry): for k in range(zs, zf): build_edge_z(xs, ys, k, material.numID, grid.rigidE, grid.rigidH, grid.ID) - logger.info(self.grid_name(grid) + f'Edge from {p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m of material {material_id} created.') + logger.info(self.grid_name(grid) + f'Edge from {p3[0]:g}m, {p3[1]:g}m, ' + + f'{p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m of ' + + f'material {material_id} created.') diff --git a/gprMax/cmds_geometry/fractal_box.py b/gprMax/cmds_geometry/fractal_box.py index da576998..f03725bc 100644 --- a/gprMax/cmds_geometry/fractal_box.py +++ b/gprMax/cmds_geometry/fractal_box.py @@ -27,26 +27,27 @@ logger = logging.getLogger(__name__) class FractalBox(UserObjectGeometry): - """Allows you to introduce an orthogonal parallelepiped with fractal distributed properties which are related to a mixing model or normal material into the model. + """Allows you to introduce an orthogonal parallelepiped with fractal + distributed properties which are related to a mixing model or + normal material into the model. - :param p1: The lower left (x,y,z) coordinates of the parallelepiped - :type p1: list, non-optional - :param p2: The upper right (x,y,z) coordinates of the parallelepiped - :type p2: list, non-optional - :param frac_dim: The fractal dimension which, for an orthogonal parallelepiped, should take values between zero and three. - :type frac_dim: float, non-optional - :param weighting: Weightings in the x, y, z direction of the surface. - :type weighting: list, non-optional - :param n_materials: Number of materials to use for the fractal distribution (defined according to the associated mixing model). This should be set to one if using a normal material instead of a mixing model. - :type n_materials: list, non-optional - :param mixing_model_id: Is an identifier for the associated mixing model or material. - :type mixing_model_id: list, non-optional - :param id: Identifier for the fractal box itself. - :type id: list, non-optional - :param seed: Controls the seeding of the random number generator used to create the fractals.. - :type seed: float, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of the parallelepiped. + p2: a list of the upper right (x,y,z) coordinates of the parallelepiped. + frac_dim: a float for the fractal dimension which, for an orthogonal + parallelepiped, should take values between zero and three. + weighting: a list of the weightings in the x, y, z direction of the + parallelepiped. + n_materials: an int of the number of materials to use for the fractal + distribution (defined according to the associated + mixing model). This should be set to one if using a + normal material instead of a mixing model. + mixing_model_id: a string identifier for the associated mixing model or + material. + id: a string identifier for the fractal box itself. + seed: seed: (optional) float parameter which controls the seeding of the random + number generator used to create the fractals. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -88,15 +89,12 @@ class FractalBox(UserObjectGeometry): if self.dorotate: self.__dorotate() - # Default is no dielectric smoothing for a fractal box - averagefractalbox = False - - # check averaging + # Check averaging try: - # go with user specified averaging + # Go with user specified averaging averagefractalbox = self.kwargs['averaging'] except KeyError: - # if they havent specfied - go with the grid default + # If they havent specfied - default is no dielectric smoothing for a fractal box averagefractalbox = False p3 = uip.round_to_grid_static_point(p1) @@ -107,18 +105,23 @@ class FractalBox(UserObjectGeometry): xf, yf, zf = p2 if frac_dim < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal dimension') raise ValueError if weighting[0] < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the x direction') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal weighting in the x direction') raise ValueError if weighting[1] < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the y direction') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal weighting in the y direction') raise ValueError if weighting[2] < 0: - logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the z direction') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'fractal weighting in the z direction') if n_materials < 0: - logger.exception(self.__str__() + ' requires a positive value for the number of bins') + logger.exception(self.__str__() + ' requires a positive value for the ' + + 'number of bins') raise ValueError # Find materials to use to build fractal volume, either from mixing models or normal materials @@ -128,12 +131,14 @@ class FractalBox(UserObjectGeometry): if mixingmodel: if nbins == 1: - logger.exception(self.__str__() + ' must be used with more than one material from the mixing model.') + logger.exception(self.__str__() + ' must be used with more than ' + + 'one material from the mixing model.') raise ValueError # Create materials from mixing model as number of bins now known from fractal_box command mixingmodel.calculate_debye_properties(nbins, grid) elif not material: - logger.exception(self.__str__() + f' mixing model or material with ID {mixing_model_id} does not exist') + logger.exception(self.__str__() + f' mixing model or material with ' + + 'ID {mixing_model_id} does not exist') raise ValueError volume = FractalVolume(xs, xf, ys, yf, zs, zf, frac_dim) @@ -149,6 +154,13 @@ class FractalBox(UserObjectGeometry): volume.mixingmodel = mixingmodel dielectricsmoothing = 'on' if volume.averaging else 'off' - logger.info(self.grid_name(grid) + f'Fractal box {volume.ID} from {p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m with {volume.operatingonID}, fractal dimension {volume.dimension:g}, fractal weightings {volume.weighting[0]:g}, {volume.weighting[1]:g}, {volume.weighting[2]:g}, fractal seeding {volume.seed}, with {volume.nbins} material(s) created, dielectric smoothing is {dielectricsmoothing}.') + logger.info(self.grid_name(grid) + f'Fractal box {volume.ID} from ' + + f'{p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, ' + + f'{p4[1]:g}m, {p4[2]:g}m with {volume.operatingonID}, ' + + f'fractal dimension {volume.dimension:g}, fractal weightings ' + + f'{volume.weighting[0]:g}, {volume.weighting[1]:g}, ' + + f'{volume.weighting[2]:g}, fractal seeding {volume.seed}, ' + + f'with {volume.nbins} material(s) created, dielectric smoothing ' + + f'is {dielectricsmoothing}.') grid.fractalvolumes.append(volume) diff --git a/gprMax/cmds_geometry/fractal_box_builder.py b/gprMax/cmds_geometry/fractal_box_builder.py index 35946b9e..a8f10b42 100644 --- a/gprMax/cmds_geometry/fractal_box_builder.py +++ b/gprMax/cmds_geometry/fractal_box_builder.py @@ -30,7 +30,7 @@ logger = logging.getLogger(__name__) class FractalBoxBuilder(UserObjectGeometry): """Internal class for fractal box modifications. This class should be used - internally only when surface modification have been made to a fractal box""" + internally only when surface modification have been made to a fractal box.""" def __init__(self, **kwargs): super().__init__(**kwargs) @@ -303,7 +303,9 @@ class FractalBoxBuilder(UserObjectGeometry): else: if volume.nbins == 1: - logger.exception(self.__str__() + ' is being used with a single material and no modifications, therefore please use a #box command instead.') + logger.exception(self.__str__() + ' is being used with a ' + + 'single material and no modifications, ' + + 'therefore please use a #box command instead.') raise ValueError else: volume.generate_fractal_volume() diff --git a/gprMax/cmds_geometry/geometry_objects_read.py b/gprMax/cmds_geometry/geometry_objects_read.py index ea529320..9e6865d3 100644 --- a/gprMax/cmds_geometry/geometry_objects_read.py +++ b/gprMax/cmds_geometry/geometry_objects_read.py @@ -49,7 +49,7 @@ class GeometryObjectsRead(UserObjectGeometry): logger.exception(self.__str__() + 'requires exactly five parameters') raise - # 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 # the main grid or the subgrid. xs, ys, zs = uip.discretise_point(p1) @@ -70,7 +70,7 @@ class GeometryObjectsRead(UserObjectGeometry): # characters and comments that must begin with double hashes. materials = [line.rstrip() + '{' + matstr + '}\n' for line in f if(line.startswith('#') and not line.startswith('##') and line.rstrip('\n'))] - # build scene + # Build scene # API for multiple scenes / model runs scene = config.get_model_config().get_scene() material_objs = get_user_objects(materials, check=False) @@ -96,8 +96,12 @@ class GeometryObjectsRead(UserObjectGeometry): # Open geometry object file and read/check spatial resolution attribute f = h5py.File(geofile, 'r') dx_dy_dz = f.attrs['dx_dy_dz'] - if round_value(dx_dy_dz[0] / grid.dx) != 1 or round_value(dx_dy_dz[1] / grid.dy) != 1 or round_value(dx_dy_dz[2] / grid.dz) != 1: - logger.exception(self.__str__() + ' requires the spatial resolution of the geometry objects file to match the spatial resolution of the model') + if round_value((dx_dy_dz[0] / grid.dx) != 1 or + round_value(dx_dy_dz[1] / grid.dy) != 1 or + round_value(dx_dy_dz[2] / grid.dz) != 1): + logger.exception(self.__str__() + ' requires the spatial resolution ' + + 'of the geometry objects file to match the spatial ' + + 'resolution of the model') raise ValueError data = f['/data'][:] @@ -117,8 +121,16 @@ class GeometryObjectsRead(UserObjectGeometry): grid.rigidE[:, xs:xs + rigidE.shape[1], ys:ys + rigidE.shape[2], zs:zs + rigidE.shape[3]] = rigidE grid.rigidH[:, xs:xs + rigidH.shape[1], ys:ys + rigidH.shape[2], zs:zs + rigidH.shape[3]] = rigidH grid.ID[:, xs:xs + ID.shape[1], ys:ys + ID.shape[2], zs:zs + ID.shape[3]] = ID + numexistmaterials - logger.info(self.grid_name(grid) + f'Geometry objects from file {geofile} inserted at {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, with corresponding materials file {matfile}.') + logger.info(self.grid_name(grid) + f'Geometry objects from file {geofile} ' + + f'inserted at {xs * grid.dx:g}m, {ys * grid.dy:g}m, ' + + f'{zs * grid.dz:g}m, with corresponding materials file ' + + f'{matfile}.') except KeyError: averaging = False - build_voxels_from_array(xs, ys, zs, numexistmaterials, averaging, data, grid.solid, grid.rigidE, grid.rigidH, grid.ID) - logger.info(self.grid_name(grid) + f'Geometry objects from file (voxels only){geofile} inserted at {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, with corresponding materials file {matfile}.') + build_voxels_from_array(xs, ys, zs, numexistmaterials, averaging, + data, grid.solid, grid.rigidE, grid.rigidH, + grid.ID) + logger.info(self.grid_name(grid) + f'Geometry objects from file ' + + f'(voxels only){geofile} inserted at {xs * grid.dx:g}m, ' + + f'{ys * grid.dy:g}m, {zs * grid.dz:g}m, with corresponding ' + + f'materials file {matfile}.') diff --git a/gprMax/cmds_geometry/plate.py b/gprMax/cmds_geometry/plate.py index b3c0e974..81e226ff 100644 --- a/gprMax/cmds_geometry/plate.py +++ b/gprMax/cmds_geometry/plate.py @@ -30,14 +30,12 @@ logger = logging.getLogger(__name__) class Plate(UserObjectGeometry): """Allows you to introduce a plate with specific properties into the model. - :param p1: The lower left (x,y,z) coordinates of the plate. - :type p1: list, non-optional - :param p2: The upper right (x,y,z) coordinates of the plate. - :type p2: list, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional + Attributes: + p1: a list of the lower left (x,y,z) coordinates of the plate. + p2: a list of the upper right (x,y,z) coordinates of the plate. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. """ def __init__(self, **kwargs): @@ -128,7 +126,8 @@ class Plate(UserObjectGeometry): for j in range(ys, yf): for k in range(zs, zf): - build_face_yz(xs, j, k, numIDy, numIDz, grid.rigidE, grid.rigidH, grid.ID) + build_face_yz(xs, j, k, numIDy, numIDz, grid.rigidE, + grid.rigidH, grid.ID) # xz-plane plate elif ys == yf: @@ -143,7 +142,8 @@ class Plate(UserObjectGeometry): for i in range(xs, xf): for k in range(zs, zf): - build_face_xz(i, ys, k, numIDx, numIDz, grid.rigidE, grid.rigidH, grid.ID) + build_face_xz(i, ys, k, numIDx, numIDz, grid.rigidE, + grid.rigidH, grid.ID) # xy-plane plate elif zs == zf: @@ -158,6 +158,9 @@ class Plate(UserObjectGeometry): for i in range(xs, xf): for j in range(ys, yf): - build_face_xy(i, j, zs, numIDx, numIDy, grid.rigidE, grid.rigidH, grid.ID) + build_face_xy(i, j, zs, numIDx, numIDy, grid.rigidE, + grid.rigidH, grid.ID) - logger.info(self.grid_name(grid) + f"Plate from {p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m of material(s) {', '.join(materialsrequested)} created.") + logger.info(self.grid_name(grid) + f"Plate from {p3[0]:g}m, {p3[1]:g}m, " + + f"{p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m of " + + f"material(s) {', '.join(materialsrequested)} created.") diff --git a/gprMax/cmds_geometry/sphere.py b/gprMax/cmds_geometry/sphere.py index 0536cc07..e2303b8f 100644 --- a/gprMax/cmds_geometry/sphere.py +++ b/gprMax/cmds_geometry/sphere.py @@ -28,18 +28,16 @@ logger = logging.getLogger(__name__) class Sphere(UserObjectGeometry): - """Allows you to introduce a spherical object with specific parameters into the model. + """Allows you to introduce a spherical object with specific parameters + into the model. - :param p1: the coordinates (x,y,z) of the centre of the sphere. - :type p1: list, non-optional - :param r: The coordinates (x,y,z) of the centre of the sphere. - :type r: float, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + p1: a list of the coordinates (x,y,z) of the centre of the sphere. + r: a float of radius of the sphere. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -62,8 +60,8 @@ class Sphere(UserObjectGeometry): # Otherwise go with the grid default averagesphere = grid.averagevolumeobjects - # check materials have been specified - # isotropic case + # Check materials have been specified + # Isotropic case try: materialsrequested = [self.kwargs['material_id']] except KeyError: @@ -117,4 +115,7 @@ class Sphere(UserObjectGeometry): build_sphere(xc, yc, zc, r, grid.dx, grid.dy, grid.dz, numID, numIDx, numIDy, numIDz, averaging, grid.solid, grid.rigidE, grid.rigidH, grid.ID) dielectricsmoothing = 'on' if averaging else 'off' - logger.info(self.grid_name(grid) + f"Sphere with centre {p2[0]:g}m, {p2[1]:g}m, {p2[2]:g}m, radius {r:g}m, of material(s) {', '.join(materialsrequested)} created, dielectric smoothing is {dielectricsmoothing}.") + logger.info(self.grid_name(grid) + f"Sphere with centre {p2[0]:g}m, " + + f"{p2[1]:g}m, {p2[2]:g}m, radius {r:g}m, of material(s) " + + f"{', '.join(materialsrequested)} created, dielectric " + + f"smoothing is {dielectricsmoothing}.") diff --git a/gprMax/cmds_geometry/triangle.py b/gprMax/cmds_geometry/triangle.py index 9138e31d..141e6d7f 100644 --- a/gprMax/cmds_geometry/triangle.py +++ b/gprMax/cmds_geometry/triangle.py @@ -28,22 +28,19 @@ logger = logging.getLogger(__name__) class Triangle(UserObjectGeometry): - """Allows you to introduce a triangular patch or a triangular prism with specific properties into the model. + """Allows you to introduce a triangular patch or a triangular prism with + specific properties into the model. - :param p1: the coordinates (x,y,z) of the first apex of the triangle. - :type p1: list, non-optional - :param p2: the coordinates (x,y,z) of the second apex of the triangle - :type p2: list, non-optional - :param p3: the coordinates (x,y,z) of the third apex of the triangle. - :type p3: list, non-optional - :param thickness: The thickness of the triangular prism. If the thickness is zero then a triangular patch is created. - :type thickness: float, non-optional - :param material_id: Material identifier that must correspond to material that has already been defined. - :type material_id: str, non-optional - :param material_ids: Material identifiers in the x, y, z directions. - :type material_ids: list, non-optional - :param averaging: y or n, used to switch on and off dielectric smoothing. - :type averaging: str, non-optional + Attributes: + p1: a list of the coordinates (x,y,z) of the first apex of the triangle. + p2: a list of the coordinates (x,y,z) of the second apex of the triangle. + p3: a list of the coordinates (x,y,z) of the third apex of the triangle. + thickness: a float for the thickness of the triangular prism. If the + thickness is zero then a triangular patch is created. + material_id: a string for the material identifier that must correspond + to material that has already been defined. + material_ids: a list of material identifiers in the x, y, z directions. + averaging: a string (y or n) used to switch on and off dielectric smoothing. """ def __init__(self, **kwargs): @@ -87,8 +84,8 @@ class Triangle(UserObjectGeometry): # Otherwise go with the grid default averagetriangularprism = grid.averagevolumeobjects - # check materials have been specified - # isotropic case + # Check materials have been specified + # Isotropic case try: materialsrequested = [self.kwargs['material_id']] except KeyError: @@ -178,10 +175,19 @@ class Triangle(UserObjectGeometry): numIDy = materials[1].numID numIDz = materials[2].numID - build_triangle(x1, y1, z1, x2, y2, z2, x3, y3, z3, normal, thickness, grid.dx, grid.dy, grid.dz, numID, numIDx, numIDy, numIDz, averaging, grid.solid, grid.rigidE, grid.rigidH, grid.ID) + build_triangle(x1, y1, z1, x2, y2, z2, x3, y3, z3, normal, thickness, + grid.dx, grid.dy, grid.dz, numID, numIDx, numIDy, numIDz, + averaging, grid.solid, grid.rigidE, grid.rigidH, grid.ID) if thickness > 0: dielectricsmoothing = 'on' if averaging else 'off' - logger.info(self.grid_name(grid) + f"Triangle with coordinates {p4[0]:g}m {p4[1]:g}m {p4[2]:g}m, {p5[0]:g}m {p5[1]:g}m {p5[2]:g}m, {p6[0]:g}m {p6[1]:g}m {p6[2]:g}m and thickness {thickness:g}m of material(s) {', '.join(materialsrequested)} created, dielectric smoothing is {dielectricsmoothing}.") + logger.info(self.grid_name(grid) + f"Triangle with coordinates " + + f"{p4[0]:g}m {p4[1]:g}m {p4[2]:g}m, {p5[0]:g}m {p5[1]:g}m " + + f"{p5[2]:g}m, {p6[0]:g}m {p6[1]:g}m {p6[2]:g}m and thickness " + + f"{thickness:g}m of material(s) {', '.join(materialsrequested)} " + + f"created, dielectric smoothing is {dielectricsmoothing}.") else: - logger.info(self.grid_name(grid) + f"Triangle with coordinates {p4[0]:g}m {p4[1]:g}m {p4[2]:g}m, {p5[0]:g}m {p5[1]:g}m {p5[2]:g}m, {p6[0]:g}m {p6[1]:g}m {p6[2]:g}m of material(s) {', '.join(materialsrequested)} created.") + logger.info(self.grid_name(grid) + f"Triangle with coordinates " + + f"{p4[0]:g}m {p4[1]:g}m {p4[2]:g}m, {p5[0]:g}m {p5[1]:g}m " + + f"{p5[2]:g}m, {p6[0]:g}m {p6[1]:g}m {p6[2]:g}m of material(s) " + + f"{', '.join(materialsrequested)} created.")