From 05d56b316c1451c0010823026d490e66a9c42ab8 Mon Sep 17 00:00:00 2001 From: Craig Warren Date: Tue, 17 Nov 2020 16:44:30 +0000 Subject: [PATCH] Changes to rotate method to allow grid information (dx,dy,dz) to be passed in. --- gprMax/cmds_geometry/add_grass.py | 13 ++- gprMax/cmds_geometry/add_surface_roughness.py | 13 ++- gprMax/cmds_geometry/add_surface_water.py | 13 ++- gprMax/cmds_geometry/box.py | 13 ++- gprMax/cmds_geometry/cmds_geometry.py | 16 ++-- gprMax/cmds_geometry/cylindrical_sector.py | 3 - gprMax/cmds_geometry/edge.py | 13 ++- gprMax/cmds_geometry/fractal_box.py | 13 ++- gprMax/cmds_geometry/plate.py | 13 ++- gprMax/cmds_geometry/triangle.py | 17 +++- gprMax/cmds_multiuse.py | 94 ++++++++++++++++--- 11 files changed, 188 insertions(+), 33 deletions(-) diff --git a/gprMax/cmds_geometry/add_grass.py b/gprMax/cmds_geometry/add_grass.py index 1650c2db..9afdfd56 100644 --- a/gprMax/cmds_geometry/add_grass.py +++ b/gprMax/cmds_geometry/add_grass.py @@ -51,8 +51,16 @@ class AddGrass(UserObjectGeometry): 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.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -74,6 +82,9 @@ class AddGrass(UserObjectGeometry): except KeyError: seed = None + if self.dorotate: + self.__dorotate() + # Get the correct fractal volume volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] try: diff --git a/gprMax/cmds_geometry/add_surface_roughness.py b/gprMax/cmds_geometry/add_surface_roughness.py index 447550e0..0c8cb6ad 100644 --- a/gprMax/cmds_geometry/add_surface_roughness.py +++ b/gprMax/cmds_geometry/add_surface_roughness.py @@ -51,8 +51,16 @@ class AddSurfaceRoughness(UserObjectGeometry): 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.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -74,6 +82,9 @@ class AddSurfaceRoughness(UserObjectGeometry): except KeyError: seed = None + if self.dorotate: + self.__dorotate() + # Get the correct fractal volume volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] if volumes: diff --git a/gprMax/cmds_geometry/add_surface_water.py b/gprMax/cmds_geometry/add_surface_water.py index 1563e809..72265173 100644 --- a/gprMax/cmds_geometry/add_surface_water.py +++ b/gprMax/cmds_geometry/add_surface_water.py @@ -46,8 +46,16 @@ class AddSurfaceWater(UserObjectGeometry): 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.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -62,6 +70,9 @@ class AddSurfaceWater(UserObjectGeometry): logger.exception(self.__str__() + ' requires exactly eight parameters') raise + if self.dorotate: + self.__dorotate() + # Get the correct fractal volume volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] if volumes: diff --git a/gprMax/cmds_geometry/box.py b/gprMax/cmds_geometry/box.py index 431852a9..cddad936 100644 --- a/gprMax/cmds_geometry/box.py +++ b/gprMax/cmds_geometry/box.py @@ -47,8 +47,16 @@ class Box(UserObjectGeometry): self.hash = '#box' def rotate(self, axis, angle, origin=None): + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -60,6 +68,9 @@ class Box(UserObjectGeometry): logger.exception(self.__str__() + ' Please specify two points.') raise + if self.dorotate: + self.__dorotate() + # check materials have been specified # isotropic case try: diff --git a/gprMax/cmds_geometry/cmds_geometry.py b/gprMax/cmds_geometry/cmds_geometry.py index 1c44b81b..6387b490 100644 --- a/gprMax/cmds_geometry/cmds_geometry.py +++ b/gprMax/cmds_geometry/cmds_geometry.py @@ -32,6 +32,7 @@ class UserObjectGeometry: self.kwargs = kwargs self.hash = '#example' self.autotranslate = True + self.dorotate = False def __str__(self): """Readable string of parameters given to object.""" @@ -150,39 +151,38 @@ def rotate_2point_object(pts, axis, angle, origin=None): return new_pts -def rotate_polarisation(p, polarisation, axis, angle): - """Rotate a geometry object that is defined by 2 points. +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. Returns: pts (array): coordinates of points of rotated object new_polarisation (str): new polarisation (x, y, or z) """ - logger.debug('Need to get dxdydz into this function') - dxdydz = np.array([0.001, 0.001, 0.001]) - if polarisation.lower() == 'x': - new_pt = (p[0] + dxdydz[0], p[1], p[2]) + new_pt = (p[0] + G.dx, p[1], p[2]) if axis == 'y' and angle == 90 or angle == 270: new_polarisation = 'z' if axis == 'z' and angle == 90 or angle == 270: new_polarisation = 'y' elif polarisation.lower() == 'y': - new_pt = (p[0], p[1] + dxdydz[1], p[2]) + new_pt = (p[0], p[1] + G.dy, p[2]) if axis == 'x' and angle == 90 or angle == 270: new_polarisation = 'z' if axis == 'z' and angle == 90 or angle == 270: new_polarisation = 'x' elif polarisation.lower() == 'z': - new_pt = (p[0], p[1], p[2] + dxdydz[2]) + new_pt = (p[0], p[1], p[2] + G.dz) if axis == 'x' and angle == 90 or angle == 270: new_polarisation = 'y' if axis == 'y' and angle == 90 or angle == 270: diff --git a/gprMax/cmds_geometry/cylindrical_sector.py b/gprMax/cmds_geometry/cylindrical_sector.py index d33eb320..0a4fb77d 100644 --- a/gprMax/cmds_geometry/cylindrical_sector.py +++ b/gprMax/cmds_geometry/cylindrical_sector.py @@ -58,9 +58,6 @@ class CylindricalSector(UserObjectGeometry): super().__init__(**kwargs) self.hash = '#cylindrical_sector' - def rotate(self, axis, angle, origin=None): - pass - def create(self, grid, uip): try: diff --git a/gprMax/cmds_geometry/edge.py b/gprMax/cmds_geometry/edge.py index 62e18bba..77e1e89c 100644 --- a/gprMax/cmds_geometry/edge.py +++ b/gprMax/cmds_geometry/edge.py @@ -43,8 +43,16 @@ class Edge(UserObjectGeometry): self.hash = '#edge' def rotate(self, axis, angle, origin=None): + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -58,6 +66,9 @@ class Edge(UserObjectGeometry): logger.exception(self.__str__() + ' requires exactly 3 parameters') raise + if self.dorotate: + self.__dorotate() + p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 xf, yf, zf = p2 diff --git a/gprMax/cmds_geometry/fractal_box.py b/gprMax/cmds_geometry/fractal_box.py index da065519..947e4d33 100644 --- a/gprMax/cmds_geometry/fractal_box.py +++ b/gprMax/cmds_geometry/fractal_box.py @@ -54,8 +54,16 @@ class FractalBox(UserObjectGeometry): 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.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -77,6 +85,9 @@ class FractalBox(UserObjectGeometry): except KeyError: seed = None + if self.dorotate: + self.__dorotate() + # Default is no dielectric smoothing for a fractal box averagefractalbox = False diff --git a/gprMax/cmds_geometry/plate.py b/gprMax/cmds_geometry/plate.py index cd1868fa..4d896962 100644 --- a/gprMax/cmds_geometry/plate.py +++ b/gprMax/cmds_geometry/plate.py @@ -45,8 +45,16 @@ class Plate(UserObjectGeometry): self.hash = '#plate' def rotate(self, axis, angle, origin=None): + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self): + """Perform rotation.""" pts = np.array([self.kwargs['p1'], self.kwargs['p2']]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + 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, :]) @@ -69,6 +77,9 @@ class Plate(UserObjectGeometry): logger.exception(self.__str__() + ' No materials have been specified') raise + if self.dorotate: + self.__dorotate() + p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 xf, yf, zf = p2 diff --git a/gprMax/cmds_geometry/triangle.py b/gprMax/cmds_geometry/triangle.py index 085cfd0d..5a38ff3b 100644 --- a/gprMax/cmds_geometry/triangle.py +++ b/gprMax/cmds_geometry/triangle.py @@ -51,9 +51,17 @@ class Triangle(UserObjectGeometry): self.hash = '#triangle' def rotate(self, axis, angle, origin=None): - p1 = rotate_point(self.kwargs['p1'], axis, angle, origin) - p2 = rotate_point(self.kwargs['p2'], axis, angle, origin) - p3 = rotate_point(self.kwargs['p3'], axis, angle, origin) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self): + """Perform 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) + p3 = rotate_point(self.kwargs['p3'], self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(p1) self.kwargs['p2'] = tuple(p2) self.kwargs['p3'] = tuple(p3) @@ -67,6 +75,9 @@ class Triangle(UserObjectGeometry): except KeyError: logger.exception(self.__str__() + ' specify 3 points and a thickness') raise + + if self.dorotate: + self.__dorotate() # check averaging try: diff --git a/gprMax/cmds_multiuse.py b/gprMax/cmds_multiuse.py index c56d26ce..85462cb9 100644 --- a/gprMax/cmds_multiuse.py +++ b/gprMax/cmds_multiuse.py @@ -51,6 +51,7 @@ class UserObjectMulti: self.order = None self.hash = '#example' self.autotranslate = True + self.dorotate = False def __str__(self): """Readable user string as per hash commands.""" @@ -155,8 +156,20 @@ class VoltageSource(UserObjectMulti): self.hash = '#voltage_source' def rotate(self, axis, angle, origin=None): - rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle) - rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self, grid): + """Perform rotation.""" + rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], + self.kwargs['polarisation'], + self.axis, + self.angle, + grid) + rot_pts = rotate_2point_object(rot_pol_pts, self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(rot_pts[0, :]) def create(self, grid, uip): @@ -169,6 +182,9 @@ class VoltageSource(UserObjectMulti): logger.exception(self.params_str() + ' requires at least six parameters') raise + if self.dorotate: + self.__dorotate(grid) + # Check polarity & position parameters if polarisation not in ('x', 'y', 'z'): logger.exception(self.params_str() + ' polarisation must be x, y, or z') @@ -256,8 +272,20 @@ class HertzianDipole(UserObjectMulti): self.hash = '#hertzian_dipole' def rotate(self, axis, angle, origin=None): - rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle) - rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self, grid): + """Perform rotation.""" + rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], + self.kwargs['polarisation'], + self.axis, + self.angle, + grid) + rot_pts = rotate_2point_object(rot_pol_pts, self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(rot_pts[0, :]) def create(self, grid, uip): @@ -269,6 +297,9 @@ class HertzianDipole(UserObjectMulti): logger.exception(self.params_str() + ' requires at least 3 parameters') raise + if self.dorotate: + self.__dorotate(grid) + # Check polarity & position parameters if polarisation not in ('x', 'y', 'z'): logger.exception(self.params_str() + ' polarisation must be x, y, or z') @@ -366,8 +397,20 @@ class MagneticDipole(UserObjectMulti): self.hash = '#magnetic_dipole' def rotate(self, axis, angle, origin=None): - rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle) - rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self, grid): + """Perform rotation.""" + rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], + self.kwargs['polarisation'], + self.axis, + self.angle, + grid) + rot_pts = rotate_2point_object(rot_pol_pts, self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(rot_pts[0, :]) def create(self, grid, uip): @@ -379,6 +422,9 @@ class MagneticDipole(UserObjectMulti): logger.exception(self.params_str() + ' requires at least five parameters') raise + if self.dorotate: + self.__dorotate(grid) + # Check polarity & position parameters if polarisation not in ('x', 'y', 'z'): logger.exception(self.params_str() + ' polarisation must be x, y, or z') @@ -466,8 +512,20 @@ class TransmissionLine(UserObjectMulti): self.hash = '#transmission_line' def rotate(self, axis, angle, origin=None): - rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], self.kwargs['polarisation'], axis, angle) - rot_pts = rotate_2point_object(rot_pol_pts, axis, angle, origin) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self, grid): + """Perform rotation.""" + rot_pol_pts, self.kwargs['polarisation'] = rotate_polarisation(self.kwargs['p1'], + self.kwargs['polarisation'], + self.axis, + self.angle, + grid) + rot_pts = rotate_2point_object(rot_pol_pts, self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(rot_pts[0, :]) def create(self, grid, uip): @@ -480,6 +538,9 @@ class TransmissionLine(UserObjectMulti): logger.exception(self.params_str() + ' requires at least six parameters') raise + if self.dorotate: + self.__dorotate(grid) + # Warn about using a transmission line on GPU if config.sim_config.general['cuda']: logger.exception(self.params_str() + ' A #transmission_line cannot currently be used with GPU solving. Consider using a #voltage_source instead.') @@ -572,11 +633,17 @@ class Rx(UserObjectMulti): self.constructor = RxUser def rotate(self, axis, angle, origin=None): - logger.debug('Need to get dxdydz into this function') - dxdydz = np.array([0.001, 0.001, 0.001]) - new_pt = (self.kwargs['p1'][0] + dxdydz[0], self.kwargs['p1'][1] + dxdydz[1], self.kwargs['p1'][2] + dxdydz[2]) + """Set parameters for rotation.""" + self.axis = axis + self.angle = angle + self.origin = origin + self.dorotate = True + + def __dorotate(self, G): + """Perform rotation.""" + new_pt = (self.kwargs['p1'][0] + G.dx, self.kwargs['p1'][1] + G.dy, self.kwargs['p1'][2] + G.dz) pts = np.array([self.kwargs['p1'], new_pt]) - rot_pts = rotate_2point_object(pts, axis, angle, origin) + rot_pts = rotate_2point_object(pts, self.axis, self.angle, self.origin) self.kwargs['p1'] = tuple(rot_pts[0, :]) # If specific field components are specified, set to output all components @@ -596,6 +663,9 @@ class Rx(UserObjectMulti): logger.exception(self.params_str()) raise + if self.dorotate: + self.__dorotate(grid) + p = uip.check_src_rx_point(p1, self.params_str()) print(p1) print(p)