From a0e7ff1fa1e9b4cd9f0621caf705036f4f41e87b Mon Sep 17 00:00:00 2001 From: Craig Warren Date: Thu, 31 Oct 2019 14:27:22 +0000 Subject: [PATCH] Updates to get antenna models working with revised antenna library. --- .gitignore | 5 ++ gprMax/__init__.py | 1 + gprMax/cmds_geometry/geometry_objects_read.py | 24 +++-- gprMax/cmds_multiple.py | 7 +- gprMax/cmds_single_use.py | 89 ++++++++++--------- gprMax/config.py | 6 +- gprMax/fields_outputs.py | 4 +- gprMax/geometry_outputs.py | 42 ++++----- gprMax/hash_cmds_file.py | 2 +- gprMax/sources.py | 12 +-- user_libs/antennas/MALA.py | 6 +- user_models/antenna_like_GSSI_1500_fs.in | 9 -- user_models/antenna_like_GSSI_1500_fs.py | 35 ++++++++ .../antenna_like_GSSI_1500_patterns_E.in | 48 ---------- .../antenna_like_GSSI_1500_patterns_H.in | 48 ---------- user_models/antenna_like_GSSI_400_fs.in | 9 -- user_models/antenna_like_GSSI_400_fs.py | 35 ++++++++ user_models/antenna_like_MALA_1200_fs.in | 9 -- user_models/antenna_like_MALA_1200_fs.py | 35 ++++++++ user_models/cylinder_2D_py.in | 53 ----------- user_models/cylinder_Bscan_GSSI_1500.in | 16 ---- user_models/heterogeneous_soil.py | 42 --------- 22 files changed, 214 insertions(+), 323 deletions(-) delete mode 100644 user_models/antenna_like_GSSI_1500_fs.in create mode 100644 user_models/antenna_like_GSSI_1500_fs.py delete mode 100755 user_models/antenna_like_GSSI_1500_patterns_E.in delete mode 100755 user_models/antenna_like_GSSI_1500_patterns_H.in delete mode 100644 user_models/antenna_like_GSSI_400_fs.in create mode 100644 user_models/antenna_like_GSSI_400_fs.py delete mode 100644 user_models/antenna_like_MALA_1200_fs.in create mode 100644 user_models/antenna_like_MALA_1200_fs.py delete mode 100644 user_models/cylinder_2D_py.in delete mode 100644 user_models/cylinder_Bscan_GSSI_1500.in delete mode 100644 user_models/heterogeneous_soil.py diff --git a/.gitignore b/.gitignore index 9406c811..1d1bde0a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,8 @@ dist/ # Jupyter notebook checkpoints .ipynb_checkpoints/ + +# Craig's files +user_models/GPU-paper-landmines/ +user_models/IWAGPR2017-challenge/ +user_models/to-update/ diff --git a/gprMax/__init__.py b/gprMax/__init__.py index 15cfe14e..65153178 100644 --- a/gprMax/__init__.py +++ b/gprMax/__init__.py @@ -49,6 +49,7 @@ from .cmds_geometry.fractal_box import FractalBox from .cmds_geometry.add_surface_roughness import AddSurfaceRoughness from .cmds_geometry.add_surface_water import AddSurfaceWater from .cmds_geometry.add_grass import AddGrass +from .cmds_geometry.geometry_objects_read import GeometryObjectsRead from .hash_cmds_file import user_libs_fn_to_scene_obj diff --git a/gprMax/cmds_geometry/geometry_objects_read.py b/gprMax/cmds_geometry/geometry_objects_read.py index d56615d6..ab8f0ed2 100644 --- a/gprMax/cmds_geometry/geometry_objects_read.py +++ b/gprMax/cmds_geometry/geometry_objects_read.py @@ -17,11 +17,17 @@ # along with gprMax. If not, see . import logging -import os +from pathlib import Path + +import h5py import gprMax.config as config from .cmds_geometry import UserObjectGeometry +from ..cython.geometry_primitives import build_voxels_from_array from ..exceptions import CmdInputError +from ..hash_cmds_file import check_cmd_names +from ..hash_cmds_multiuse import process_multicmds +from ..utilities import round_value log = logging.getLogger(__name__) @@ -31,6 +37,7 @@ class GeometryObjectsRead(UserObjectGeometry): log.debug('More work required here.') def __init__(self, **kwargs): + super().__init__(**kwargs) self.order = 1 self.hash = '#geometry_objects_read' @@ -49,10 +56,12 @@ class GeometryObjectsRead(UserObjectGeometry): xs, ys, zs = uip.discretise_point(p1) # See if material file exists at specified path and if not try input file directory - if not os.path.isfile(matfile): - matfile = os.path.abspath(os.path.join(G.inputdirectory, matfile)) + matfile = Path(matfile) - matstr = os.path.splitext(os.path.split(matfile)[1])[0] + if not matfile.exists(): + matfile = Path(config.sim_config.input_file_path.parent, matfile) + + matstr = matfile.with_suffix('').name numexistmaterials = len(G.materials) # Read materials from file @@ -64,7 +73,7 @@ class GeometryObjectsRead(UserObjectGeometry): singlecmdsimport, multicmdsimport, geometryimport = check_cmd_names(materials, checkessential=False) # Process parameters for commands that can occur multiple times in the model - process_multicmds(multicmdsimport, G) + process_multicmds(multicmdsimport) # Update material type for material in G.materials: @@ -75,8 +84,9 @@ class GeometryObjectsRead(UserObjectGeometry): material.type = 'imported' # See if geometry object file exists at specified path and if not try input file directory - if not os.path.isfile(geofile): - geofile = os.path.abspath(os.path.join(G.inputdirectory, geofile)) + geofile = Path(geofile) + if not geofile.exists(): + geofile = Path(config.sim_config.input_file_path.parent, geofile) # Open geometry object file and read/check spatial resolution attribute f = h5py.File(geofile, 'r') diff --git a/gprMax/cmds_multiple.py b/gprMax/cmds_multiple.py index 5663c147..07d75b50 100644 --- a/gprMax/cmds_multiple.py +++ b/gprMax/cmds_multiple.py @@ -17,7 +17,6 @@ # along with gprMax. If not, see . import logging -import sys import numpy as np @@ -415,7 +414,7 @@ class TransmissionLine(UserObjectMulti): raise CmdInputError(f"'{self.params_str()}' requires at least six parameters") # Warn about using a transmission line on GPU - if grid.gpu is not None: + if config.sim_config.general['cuda']: raise CmdInputError(f"'{self.params_str()}' A #transmission_line cannot currently be used with GPU solving. Consider using a #voltage_source instead.") # Check polarity & position parameters @@ -430,12 +429,12 @@ class TransmissionLine(UserObjectMulti): xcoord, ycoord, zcoord = uip.check_src_rx_point(p1, self.params_str()) - if resistance <= 0 or resistance >= z0: + if resistance <= 0 or resistance >= config.sim_config.em_consts['z0']: raise CmdInputError(f"'{self.params_str()}' requires a resistance greater than zero and less than the impedance of free space, i.e. 376.73 Ohms") # Check if there is a waveformID in the waveforms list if not any(x.ID == waveform_id for x in grid.waveforms): - raise CmdInputError(f"'{self.params_str()}' there is no waveform with the identifier {tmp[5]}") + raise CmdInputError(f"'{self.params_str()}' there is no waveform with the identifier {waveform_id}") t = TransmissionLineUser(grid) t.polarisation = polarisation diff --git a/gprMax/cmds_single_use.py b/gprMax/cmds_single_use.py index b273c1d7..cebb902b 100644 --- a/gprMax/cmds_single_use.py +++ b/gprMax/cmds_single_use.py @@ -18,7 +18,7 @@ import inspect import logging -import os +from pathlib import Path from colorama import init from colorama import Fore @@ -427,6 +427,10 @@ class ExcitationFile(UserObjectSingle): :type fill_value: float, optional """ + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.order = 11 + def create(self, G, uip): try: kwargs = dict() @@ -442,55 +446,56 @@ class ExcitationFile(UserObjectSingle): except KeyError: raise CmdInputError('#excitation_file: requires either one or three parameter(s)') - # See if file exists at specified path and if not try input file directory - if not os.path.isfile(excitationfile): - excitationfile = os.path.abspath(os.path.join(G.inputdirectory, excitationfile)) + # See if file exists at specified path and if not try input file directory + excitationfile = Path(excitationfile) + if not excitationfile.exists(): + excitationfile = Path(config.sim_config.input_file_path.parent, excitationfile) - log.info(f'\nExcitation file: {excitationfile}') + log.info(f'Excitation file: {excitationfile}') - # Get waveform names - with open(excitationfile, 'r') as f: - waveformIDs = f.readline().split() + # Get waveform names + with open(excitationfile, 'r') as f: + waveformIDs = f.readline().split() - # Read all waveform values into an array - waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=floattype) + # Read all waveform values into an array + waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=config.sim_config.dtypes['float_or_double']) - # Time array (if specified) for interpolation, otherwise use simulation time - if waveformIDs[0].lower() == 'time': - waveformIDs = waveformIDs[1:] - waveformtime = waveformvalues[:, 0] - waveformvalues = waveformvalues[:, 1:] - timestr = 'user-defined time array' - else: - waveformtime = np.arange(0, G.timewindow + G.dt, G.dt) - timestr = 'simulation time array' + # Time array (if specified) for interpolation, otherwise use simulation time + if waveformIDs[0].lower() == 'time': + waveformIDs = waveformIDs[1:] + waveformtime = waveformvalues[:, 0] + waveformvalues = waveformvalues[:, 1:] + timestr = 'user-defined time array' + else: + waveformtime = np.arange(0, G.timewindow + G.dt, G.dt) + timestr = 'simulation time array' - for waveform in range(len(waveformIDs)): - if any(x.ID == waveformIDs[waveform] for x in G.waveforms): - raise CmdInputError(f'Waveform with ID {waveformIDs[waveform]} already exists') - w = Waveform() - w.ID = waveformIDs[waveform] - w.type = 'user' + for waveform in range(len(waveformIDs)): + if any(x.ID == waveformIDs[waveform] for x in G.waveforms): + raise CmdInputError(f'Waveform with ID {waveformIDs[waveform]} already exists') + w = Waveform() + w.ID = waveformIDs[waveform] + w.type = 'user' - # Select correct column of waveform values depending on array shape - singlewaveformvalues = waveformvalues[:] if len(waveformvalues.shape) == 1 else waveformvalues[:, waveform] + # Select correct column of waveform values depending on array shape + singlewaveformvalues = waveformvalues[:] if len(waveformvalues.shape) == 1 else waveformvalues[:, waveform] - # Truncate waveform array if it is longer than time array - if len(singlewaveformvalues) > len(waveformtime): - singlewaveformvalues = singlewaveformvalues[:len(waveformtime)] - # Zero-pad end of waveform array if it is shorter than time array - elif len(singlewaveformvalues) < len(waveformtime): - singlewaveformvalues = np.lib.pad(singlewaveformvalues, - (0, len(singlewaveformvalues) - - len(waveformvalues)), - 'constant', constant_values=0) + # Truncate waveform array if it is longer than time array + if len(singlewaveformvalues) > len(waveformtime): + singlewaveformvalues = singlewaveformvalues[:len(waveformtime)] + # Zero-pad end of waveform array if it is shorter than time array + elif len(singlewaveformvalues) < len(waveformtime): + singlewaveformvalues = np.lib.pad(singlewaveformvalues, + (0, len(singlewaveformvalues) - + len(waveformvalues)), + 'constant', constant_values=0) - # Interpolate waveform values - w.userfunc = interpolate.interp1d(waveformtime, singlewaveformvalues, **kwargs) + # Interpolate waveform values + w.userfunc = interpolate.interp1d(waveformtime, singlewaveformvalues, **kwargs) - log.info(f"User waveform {w.ID} created using {timestr} and, if required, interpolation parameters (kind: {kwargs['kind']}, fill value: {kwargs['fill_value']}).") + log.info(f"User waveform {w.ID} created using {timestr} and, if required, interpolation parameters (kind: {kwargs['kind']}, fill value: {kwargs['fill_value']}).") - G.waveforms.append(w) + G.waveforms.append(w) class OutputDir(UserObjectSingle): @@ -501,7 +506,7 @@ class OutputDir(UserObjectSingle): """ def __init__(self, **kwargs): super().__init__(**kwargs) - self.order = 11 + self.order = 12 def create(self, grid, uip): config.model_configs[grid.model_num].set_output_file_path(self.kwargs['dir']) @@ -516,7 +521,7 @@ class NumberOfModelRuns(UserObjectSingle): """ def __init__(self, **kwargs): super().__init__(**kwargs) - self.order = 12 + self.order = 13 def create(self, grid, uip): try: diff --git a/gprMax/config.py b/gprMax/config.py index a0606e93..dc7fa5f1 100644 --- a/gprMax/config.py +++ b/gprMax/config.py @@ -210,7 +210,7 @@ class SimulationConfig: # Suppress nvcc warnings on Microsoft Windows if sys.platform == 'win32': self.cuda['nvcc_opts'] = '-w' self.get_gpus() - self.set_gpus() + self.set_single_gpu() # Subgrid parameter may not exist if user enters via CLI try: @@ -242,7 +242,7 @@ class SimulationConfig: self.cuda['gpus'], self.cuda['gpus_str'] = detect_check_gpus(self.cuda['gpus']) - def set_gpus(self): + def set_single_gpu(self): """Adjust list of GPU object(s) to specify single GPU.""" self.cuda['gpus'] = self.cuda['gpus'][0] self.cuda['gpus_str'] = self.cuda['gpus_str'][0] @@ -304,8 +304,10 @@ class SimulationConfig: def set_input_file_path(self): """Set input file path for CLI or API.""" + # API if self.args.inputfile is None: self.input_file_path = Path(self.args.outputfile) + # CLI else: self.input_file_path = Path(self.args.inputfile) diff --git a/gprMax/fields_outputs.py b/gprMax/fields_outputs.py index 5aa5e823..295aba5f 100644 --- a/gprMax/fields_outputs.py +++ b/gprMax/fields_outputs.py @@ -124,7 +124,6 @@ def write_hdf5_sub_grid_outputfile(outputfile, G): parent = outputfile.parent for sg in G.subgrids: - # Create an outputfile for each subgrid fp = stem + '_' + sg.name + suffix fp = parent / Path(fp) @@ -146,6 +145,9 @@ def write_data(outputfile, G): Args: outputfile (str): Name of the output file. G (FDTDGrid): Parameters describing a grid in a model. + + Returns: + f (file object): File object. """ f = h5py.File(outputfile, 'w') diff --git a/gprMax/geometry_outputs.py b/gprMax/geometry_outputs.py index 1d4aba60..b72a1aa8 100644 --- a/gprMax/geometry_outputs.py +++ b/gprMax/geometry_outputs.py @@ -405,9 +405,9 @@ class GeometryViewFineMultiGrid: """Geometry view for all grids in the simulation. Slicing is not supported by this class :( - only the full extent of the grids - are output. The subgrids are output without the non-working regions If you - require domainslicing GeometryView seperately for each grid you require and - view them at once in Paraview. + are output. The subgrids are output without the non-working regions. + If you require domain slicing, GeometryView seperately for each grid you + require and view them at once in Paraview. """ def __init__(self, xs, ys, zs, xf, yf, zf, dx, dy, dz, filename, fileext, G): @@ -418,7 +418,9 @@ class GeometryViewFineMultiGrid: filename (str): Filename to save to. fileext (str): File extension of VTK file - either '.vti' for a per cell geometry view, or '.vtp' for a per cell edge geometry view. + G (FDTDGrid): Parameters describing a grid in a model. """ + self.G = G self.nx = G.nx self.ny = G.ny @@ -460,41 +462,36 @@ class GeometryViewFineMultiGrid: PolygonalData (.vtp) for a per-cell-edge geometry view. N.B. No Python 3 support for VTK at time of writing (03/2015) - - Args: - G (FDTDGrid): Parameters describing a grid in a model. """ G = self.G with open(self.filename, 'wb') as f: - # refine parameters for subgrid - f.write('\n'.encode('utf-8')) - f.write('\n'.format(config.sim_config.vtk_byteorder).encode('utf-8')) - f.write('\n\n'.format(self.vtk_numpoints, self.vtk_numlines).encode('utf-8')) + f.write(f"""\n""".encode('utf-8')) + f.write(f"""\n\n""".encode('utf-8')) f.write('\n\n\n'.encode('utf-8')) - f.write('\n\n'.format(self.vtk_connectivity_offset).encode('utf-8')) - f.write('\n\n'.format(self.vtk_offsets_offset).encode('utf-8')) + f.write(f"""\n\n""".encode('utf-8')) + f.write(f"""\n\n""".encode('utf-8')) f.write('\n'.encode('utf-8')) - f.write('\n'.format(self.vtk_materials_offset).encode('utf-8')) + f.write(f"""\n""".encode('utf-8')) f.write('\n'.encode('utf-8')) f.write('\n\n\n_'.encode('utf-8')) # Write points - log.info('writing points main grid') + log.info('\nWriting points main grid') datasize = np.dtype(np.float32).itemsize * self.vtk_numpoints * self.vtk_numpoint_components f.write(pack('I', datasize)) for i in range(0, G.nx + 1): for j in range(0, G.ny + 1): - for k in range(0, self.G.nz + 1): + for k in range(0, G.nz + 1): f.write(pack('fff', i * G.dx, j * G.dy, k * G.dz)) for sg_v in self.sg_views: - log.info('writing points subgrid') + log.info('Writing points subgrid') sg_v.write_points(f, G) n_x_lines = self.nx * (self.ny + 1) * (self.nz + 1) @@ -509,7 +506,7 @@ class GeometryViewFineMultiGrid: z_lines = np.zeros((n_z_lines, 2), dtype=np.uint32) z_materials = np.zeros((n_z_lines), dtype=np.uint32) - log.info('calculate connectivity main grid') + log.info('Calculate connectivity main grid') label = 0 counter_x = 0 counter_y = 0 @@ -541,7 +538,7 @@ class GeometryViewFineMultiGrid: label = label + 1 - log.info('calculate connectivity subgrids') + log.info('Calculate connectivity subgrids') for sg_v in self.sg_views: sg_v.populate_connectivity_and_materials(label) # use the last subgrids label for the next view @@ -596,15 +593,14 @@ class GeometryViewFineMultiGrid: f.write('\n\n\n'.encode('utf-8')) for material in G.materials: - f.write('{}\n'.format(material.ID, material.numID).encode('utf-8')) + f.write(f"""{material.numID}\n""".encode('utf-8')) if not materialsonly: f.write('1\n'.encode('utf-8')) for index, src in enumerate(G.hertziandipoles + G.magneticdipoles + G.voltagesources + G.transmissionlines): - f.write('{}\n'.format(src.ID, index + 2).encode('utf-8')) + f.write(f"""{index + 2}\n""".encode('utf-8')) for index, rx in enumerate(G.rxs): - f.write('{}\n'.format(rx.ID, index + 1).encode('utf-8')) + f.write(f"""{index + 1}\n""".encode('utf-8')) f.write('\n'.encode('utf-8')) - return None class SubgridGeometryView: @@ -649,7 +645,7 @@ class SubgridGeometryView: def populate_connectivity_and_materials(self, label): """Label is the starting label. 0 if no other grids are present but - +1 the last label used for a multigrid view. + +1 the last label used for a multigrid view. """ sg = self.sg diff --git a/gprMax/hash_cmds_file.py b/gprMax/hash_cmds_file.py index 745bb4de..2ab6ebd5 100644 --- a/gprMax/hash_cmds_file.py +++ b/gprMax/hash_cmds_file.py @@ -24,7 +24,7 @@ import sys import gprMax.config as config from .exceptions import CmdInputError -from .hash_cmds_geometry import process_geometrycmds +# from .hash_cmds_geometry import process_geometrycmds from .hash_cmds_multiuse import process_multicmds from .hash_cmds_singleuse import process_singlecmds diff --git a/gprMax/sources.py b/gprMax/sources.py index 6f7be311..0c54a582 100644 --- a/gprMax/sources.py +++ b/gprMax/sources.py @@ -317,12 +317,12 @@ class TransmissionLine(Source): # Cell position of where line connects to antenna/main grid self.antpos = 10 - self.voltage = np.zeros(self.nl, dtype=config.dtypes['float_or_double']) - self.current = np.zeros(self.nl, dtype=config.dtypes['float_or_double']) - self.Vinc = np.zeros(G.iterations, dtype=config.dtypes['float_or_double']) - self.Iinc = np.zeros(G.iterations, dtype=config.dtypes['float_or_double']) - self.Vtotal = np.zeros(G.iterations, dtype=config.dtypes['float_or_double']) - self.Itotal = np.zeros(G.iterations, dtype=config.dtypes['float_or_double']) + self.voltage = np.zeros(self.nl, dtype=config.sim_config.dtypes['float_or_double']) + self.current = np.zeros(self.nl, dtype=config.sim_config.dtypes['float_or_double']) + self.Vinc = np.zeros(G.iterations, dtype=config.sim_config.dtypes['float_or_double']) + self.Iinc = np.zeros(G.iterations, dtype=config.sim_config.dtypes['float_or_double']) + self.Vtotal = np.zeros(G.iterations, dtype=config.sim_config.dtypes['float_or_double']) + self.Itotal = np.zeros(G.iterations, dtype=config.sim_config.dtypes['float_or_double']) def calculate_incident_V_I(self, G): """Calculates the incident voltage and current with a long length diff --git a/user_libs/antennas/MALA.py b/user_libs/antennas/MALA.py index c5f4df45..8a485fb4 100644 --- a/user_libs/antennas/MALA.py +++ b/user_libs/antennas/MALA.py @@ -147,7 +147,7 @@ def antenna_like_MALA_1200(x, y, z, resolution=0.001): c8 = gprMax.Cylinder(p1=(x + 0.147, y + 0.008, z + skidthickness), p2=(x + 0.147, y + 0.008, z + skidthickness + casesize[2] - casethickness), - r=0.007, 'free_space') + r=0.007, material_id='free_space') b6 = gprMax.Box(p1=(x + 0.054, y + casesize[1] - 0.016, z + skidthickness), p2=(x + 0.056, y + casesize[1] - 0.014, z + skidthickness + casesize[2] - casethickness), @@ -341,7 +341,7 @@ def antenna_like_MALA_1200(x, y, z, resolution=0.001): p2=(tx[0] + 0.020, tx[1] + bowtieheight + 0.006, tx[2]), material_id='txresupper') e16 = gprMax.Edge(p1=(tx[0] + 0.020 + dx, tx[1] + bowtieheight + 0.002, tx[2]), - p2=tx[0] + 0.020 + dx, tx[1] + bowtieheight + 0.006, tx[2]), + p2=(tx[0] + 0.020 + dx, tx[1] + bowtieheight + 0.006, tx[2]), material_id='txresupper') scene_objects.extend((e11, e12, e13, e14, e15, e16)) @@ -354,7 +354,7 @@ def antenna_like_MALA_1200(x, y, z, resolution=0.001): p2=(tx[0] - 0.023 + dx + 0.076, tx[1] - bowtieheight - dy, tx[2]), material_id='rxreslower') e19 = gprMax.Edge(p1=(tx[0] + 0.076, tx[1] - bowtieheight - 0.004, tx[2]), - p1=(tx[0] + 0.076, tx[1] - bowtieheight - dy, tx[2]), + p2=(tx[0] + 0.076, tx[1] - bowtieheight - dy, tx[2]), material_id='rxreslower') e20 = gprMax.Edge(p1=(tx[0] + dx + 0.076, tx[1] - bowtieheight - 0.004, tx[2]), p2=(tx[0] + dx + 0.076, tx[1] - bowtieheight - dy, tx[2]), diff --git a/user_models/antenna_like_GSSI_1500_fs.in b/user_models/antenna_like_GSSI_1500_fs.in deleted file mode 100644 index 0d282bd2..00000000 --- a/user_models/antenna_like_GSSI_1500_fs.in +++ /dev/null @@ -1,9 +0,0 @@ -#title: GSSI 1.5GHz 'like' antenna in free-space -#domain: 0.250 0.188 0.220 -#dx_dy_dz: 0.001 0.001 0.001 -#time_window: 6e-9 - -#python: -from user_libs.antennas.GSSI import antenna_like_GSSI_1500 -antenna_like_GSSI_1500(0.125, 0.094, 0.100, resolution=0.001) -#end_python: diff --git a/user_models/antenna_like_GSSI_1500_fs.py b/user_models/antenna_like_GSSI_1500_fs.py new file mode 100644 index 00000000..f976c980 --- /dev/null +++ b/user_models/antenna_like_GSSI_1500_fs.py @@ -0,0 +1,35 @@ +from pathlib import Path + +import gprMax +from user_libs.antennas.GSSI import antenna_like_GSSI_1500 + +# File path for output +fn = Path(__file__) + +# Discretisation +dl = 0.002 + +# Domain +x = 0.250 +y = 0.188 +z = 0.220 + +scene = gprMax.Scene() + +title = gprMax.Title(name=fn.with_suffix('').name) +domain = gprMax.Domain(p1=(x, y, z)) +dxdydz = gprMax.Discretisation(p1=(dl, dl, dl)) +time_window = gprMax.TimeWindow(time=6e-9) + +scene.add(title) +scene.add(domain) +scene.add(dxdydz) +scene.add(time_window) + +# Import antenna model and add to model +gssi_objects = antenna_like_GSSI_1500(0.125, 0.094, 0.100, resolution=dl) +for obj in gssi_objects: + scene.add(obj) + +# Run model +gprMax.run(scenes=[scene], geometry_only=False, outputfile=fn) diff --git a/user_models/antenna_like_GSSI_1500_patterns_E.in b/user_models/antenna_like_GSSI_1500_patterns_E.in deleted file mode 100755 index c8da92f8..00000000 --- a/user_models/antenna_like_GSSI_1500_patterns_E.in +++ /dev/null @@ -1,48 +0,0 @@ -#title: GSSI 1.5GHz antenna field patterns -#dx_dy_dz: 0.001 0.001 0.001 -#pml_cells: 14 - -#python: -import os -import numpy as np - -from gprMax.input_cmd_funcs import * -from user_libs.antennas.GSSI import antenna_like_GSSI_1500 - -filename = os.path.splitext(os.path.split(inputfile)[1])[0] - -timewindows = np.array([4.5e-9]) # For 0.3m max -radii = np.linspace(0.1, 0.3, 20) -theta = np.linspace(3, 357, 60) -materials = ['5 0 1 0 er5'] # Can add more to list and use selector integer to choose -selector = 0 - -fs = np.array([0.040, 0.040, 0.040]) -domain = np.array([2 * fs[0] + 0.170, 2 * fs[1] + 2 * radii[-1], 2 * fs[2] + 2 * radii[-1]]) -antennaposition = np.array([domain[0] / 2, fs[1] + radii[-1], fs[2] + radii[-1]]) -antenna_like_GSSI_1500(antennaposition[0], antennaposition[1], antennaposition[2]) - -print('#domain: {:.3f} {:.3f} {:.3f}'.format(domain[0], domain[1], domain[2])) -print('#time_window: {:.3e}'.format(timewindows[selector])) - -## Can introduce soil model -#print('#soil_peplinski: 0.5 0.5 2.0 2.66 0.001 0.25 mySoil') -#print('#fractal_box: 0 0 0 {} {} {} 1.5 1 1 1 50 mySoil mySoilBox 1'.format(domain[0], domain[1], fs[2] + radii[-1])) - -print('#material: {}'.format(materials[selector])) -print('#box: 0 0 0 {} {} {} {} n'.format(domain[0], domain[1], fs[2] + radii[-1], materials[selector].split()[-1])) - -## Save the position of the antenna to file for use when processing results -np.savetxt(os.path.join(os.path.dirname(inputfile), filename + '_rxsorigin.txt'), antennaposition, fmt="%f") - -## Generate receiver points for pattern -for radius in range(len(radii)): - ## E-plane circle (yz plane, x=0, phi=pi/2,3pi/2) - x = radii[radius] * np.sin(theta * np.pi /180) * np.cos(90 * np.pi / 180) - y = radii[radius] * np.sin(theta * np.pi /180) * np.sin(90 * np.pi / 180) - z = radii[radius] * np.cos(theta * np.pi /180) - for rxpt in range(len(theta)): - print('#rx: {:.3f} {:.3f} {:.3f}'.format(x[rxpt] + antennaposition[0], y[rxpt] + antennaposition[1], z[rxpt] + antennaposition[2])) - -geometry_view(0, 0, 0, domain[0], domain[1], domain[2], 0.001, 0.001, 0.001, filename, 'n') -#end_python: diff --git a/user_models/antenna_like_GSSI_1500_patterns_H.in b/user_models/antenna_like_GSSI_1500_patterns_H.in deleted file mode 100755 index 9cbd33ad..00000000 --- a/user_models/antenna_like_GSSI_1500_patterns_H.in +++ /dev/null @@ -1,48 +0,0 @@ -#title: GSSI 1.5GHz antenna field patterns -#dx_dy_dz: 0.001 0.001 0.001 -#pml_cells: 14 - -#python: -import os -import numpy as np - -from gprMax.input_cmd_funcs import * -from user_libs.antennas.GSSI import antenna_like_GSSI_1500 - -filename = os.path.splitext(os.path.split(inputfile)[1])[0] - -timewindows = np.array([4.5e-9]) # For 0.3m max -radii = np.linspace(0.1, 0.3, 20) -theta = np.linspace(3, 357, 60) -materials = ['5 0 1 0 er5'] # Can add more to list and use selector integer to choose -selector = 0 - -fs = np.array([0.040, 0.040, 0.040]) -domain = np.array([2 * fs[0] + 2 * radii[-1], 2 * fs[1] + 0.107, 2 * fs[2] + 2 * radii[-1]]) -antennaposition = np.array([fs[0] + radii[-1], domain[1] / 2, fs[2] + radii[-1]]) -antenna_like_GSSI_1500(antennaposition[0], antennaposition[1], antennaposition[2]) - -print('#domain: {:.3f} {:.3f} {:.3f}'.format(domain[0], domain[1], domain[2])) -print('#time_window: {:.3e}'.format(timewindows[selector])) - -## Can introduce soil model -#print('#soil_peplinski: 0.5 0.5 2.0 2.66 0.001 0.25 mySoil') -#print('#fractal_box: 0 0 0 {} {} {} 1.5 1 1 1 50 mySoil mySoilBox 1'.format(domain[0], domain[1], fs[2] + radii[-1])) - -print('#material: {}'.format(materials[selector])) -print('#box: 0 0 0 {} {} {} {} n'.format(domain[0], domain[1], fs[2] + radii[-1], materials[selector].split()[-1])) - -## Save the position of the antenna to file for use when processing results -np.savetxt(os.path.join(os.path.dirname(inputfile), filename + '_rxsorigin.txt'), antennaposition, fmt="%f") - -## Generate receiver points for pattern -for radius in range(len(radii)): - ## H-plane circle (xz plane, y=0, phi=0,pi) - x = radii[radius] * np.sin(theta * np.pi /180) * np.cos(180 * np.pi / 180) - y = radii[radius] * np.sin(theta * np.pi /180) * np.sin(180 * np.pi / 180) - z = radii[radius] * np.cos(theta * np.pi /180) - for rxpt in range(len(theta)): - print('#rx: {:.3f} {:.3f} {:.3f}'.format(x[rxpt] + antennaposition[0], y[rxpt] + antennaposition[1], z[rxpt] + antennaposition[2])) - -geometry_view(0, 0, 0, domain[0], domain[1], domain[2], 0.001, 0.001, 0.001, filename, 'n') -#end_python: diff --git a/user_models/antenna_like_GSSI_400_fs.in b/user_models/antenna_like_GSSI_400_fs.in deleted file mode 100644 index 1be22452..00000000 --- a/user_models/antenna_like_GSSI_400_fs.in +++ /dev/null @@ -1,9 +0,0 @@ -#title: GSSI 400MHz 'like' antenna in free-space -#domain: 0.380 0.380 0.360 -#dx_dy_dz: 0.001 0.001 0.001 -#time_window: 12e-9 - -#python: -from user_libs.antennas.GSSI import antenna_like_GSSI_400 -antenna_like_GSSI_400(0.190, 0.190, 0.140, resolution=0.001) -#end_python: diff --git a/user_models/antenna_like_GSSI_400_fs.py b/user_models/antenna_like_GSSI_400_fs.py new file mode 100644 index 00000000..5e56c46f --- /dev/null +++ b/user_models/antenna_like_GSSI_400_fs.py @@ -0,0 +1,35 @@ +from pathlib import Path + +import gprMax +from user_libs.antennas.GSSI import antenna_like_GSSI_400 + +# File path for output +fn = Path(__file__) + +# Discretisation +dl = 0.001 + +# Domain +x = 0.380 +y = 0.380 +z = 0.360 + +scene = gprMax.Scene() + +title = gprMax.Title(name=fn.with_suffix('').name) +domain = gprMax.Domain(p1=(x, y, z)) +dxdydz = gprMax.Discretisation(p1=(dl, dl, dl)) +time_window = gprMax.TimeWindow(time=12e-9) + +scene.add(title) +scene.add(domain) +scene.add(dxdydz) +scene.add(time_window) + +# Import antenna model and add to model +gssi_objects = antenna_like_GSSI_400(0.190, 0.190, 0.140, resolution=dl) +for obj in gssi_objects: + scene.add(obj) + +# Run model +gprMax.run(scenes=[scene], geometry_only=False, outputfile=fn) diff --git a/user_models/antenna_like_MALA_1200_fs.in b/user_models/antenna_like_MALA_1200_fs.in deleted file mode 100644 index 1c002c57..00000000 --- a/user_models/antenna_like_MALA_1200_fs.in +++ /dev/null @@ -1,9 +0,0 @@ -#title: MALA 1.2GHz 'like' antenna in free-space -#domain: 0.264 0.189 0.220 -#dx_dy_dz: 0.001 0.001 0.001 -#time_window: 6e-9 - -#python: -from user_libs.antennas.MALA import antenna_like_MALA_1200 -antenna_like_MALA_1200(0.132, 0.095, 0.100, 0.001) -#end_python: diff --git a/user_models/antenna_like_MALA_1200_fs.py b/user_models/antenna_like_MALA_1200_fs.py new file mode 100644 index 00000000..13ba5c04 --- /dev/null +++ b/user_models/antenna_like_MALA_1200_fs.py @@ -0,0 +1,35 @@ +from pathlib import Path + +import gprMax +from user_libs.antennas.MALA import antenna_like_MALA_1200 + +# File path for output +fn = Path(__file__) + +# Discretisation +dl = 0.002 + +# Domain +x = 0.264 +y = 0.189 +z = 0.220 + +scene = gprMax.Scene() + +title = gprMax.Title(name=fn.name) +domain = gprMax.Domain(p1=(x, y, z)) +dxdydz = gprMax.Discretisation(p1=(dl, dl, dl)) +time_window = gprMax.TimeWindow(time=6e-9) + +scene.add(title) +scene.add(domain) +scene.add(dxdydz) +scene.add(time_window) + +# Import antenna model and add to model +gssi_objects = antenna_like_MALA_1200(0.132, 0.095, 0.100, resolution=dl) +for obj in gssi_objects: + scene.add(obj) + +# Run model +gprMax.run(scenes=[scene], geometry_only=False, outputfile=fn) diff --git a/user_models/cylinder_2D_py.in b/user_models/cylinder_2D_py.in deleted file mode 100644 index f4afb52d..00000000 --- a/user_models/cylinder_2D_py.in +++ /dev/null @@ -1,53 +0,0 @@ -#python: -from gprMax.input_cmd_funcs import * -command('title', 'A or B scan from a metal cylinder buried in a dielectric half-space') -z_dim = 0.002 -resolution = 0.002 -tsim = 3e-9 -B_scan = False - -domain = domain(x=64e-2, y=30e-2, z=z_dim) -dx = dx_dy_dz(resolution, resolution, z_dim) -time_window(tsim) - -material(permittivity=6, conductivity=0, - permeability=1, magconductivity=0, name='half_space') - -identifier = waveform('ricker', amplitude=1, frequency=1.5e9, - identifier='my_ricker') - -if B_scan: - x_ant = 8e-2 -else: - x_ant = domain.x/2 - 1e-2 # in the middle of the x-axis - -tx = hertzian_dipole('z', - x_ant, domain.y - 4e-2, 0, # minus 4 cm in y-direction - identifier) -rx(tx.x + 2e-2, tx.y, tx.z) # 2 cm away in x-direction from tx - -if B_scan: - src_steps(dx=0.8e-2/4) - rx_steps(dx=0.8e-2/4) - -b0, b1 = box(0, 0, 0, - domain.x, domain.y - 4e-2, z_dim, # same as domain, minus 4 cm in y-direction - 'half_space') - -c_x, c_y = (domain.x/2, b1.y - 5e-2) # in the middle of the x-axis and 5 cm down from the half_space -cylinder(c_x, c_y, 0, - c_x, c_y, z_dim, - radius=1e-2, material='pec') - -# Outputs, geometry and snapshots -geometry_view(0, 0, 0, - domain.x, domain.y, domain.z, - dx.x, dx.y, dx.z, - 'cylinder', 'n') - -N = 32 -for i in range(1, N+1): - snapshot(0, 0, 0, - domain.x, domain.y, domain.z, - dx.x, dx.y, dx.z, i*(tsim/N), 'snapshot' + str(i)) -#end_python: diff --git a/user_models/cylinder_Bscan_GSSI_1500.in b/user_models/cylinder_Bscan_GSSI_1500.in deleted file mode 100644 index 6cf10867..00000000 --- a/user_models/cylinder_Bscan_GSSI_1500.in +++ /dev/null @@ -1,16 +0,0 @@ -#title: B-scan from a metal cylinder buried in a dielectric half-space with a GSSI 1.5GHz 'like' antenna -#domain: 0.480 0.148 0.235 -#dx_dy_dz: 0.001 0.001 0.001 -#time_window: 6e-9 - -#material: 6 0 1 0 half_space - -#box: 0 0 0 0.480 0.148 0.170 half_space -#cylinder: 0.240 0 0.080 0.240 0.148 0.080 0.010 pec - -#python: -from user_libs.antennas.GSSI import antenna_like_GSSI_1500 -antenna_like_GSSI_1500(0.105 + current_model_run * 0.005, 0.074, 0.170, 0.001) -#end_python: - -geometry_view: 0 0 0 0.480 0.148 0.235 0.001 0.001 0.001 cylinder_GSSI_1500 n diff --git a/user_models/heterogeneous_soil.py b/user_models/heterogeneous_soil.py deleted file mode 100644 index 41d71a6d..00000000 --- a/user_models/heterogeneous_soil.py +++ /dev/null @@ -1,42 +0,0 @@ -import gprMax - -# single objects -dxdydz = gprMax.Discretisation(p1=(1e-3, 1e-3, 1e-3)) -messages = gprMax.Messages(yn='y') -tw = gprMax.TimeWindow(time=6e-9) -domain = gprMax.Domain(p1=(0.15, 0.15, 0.1)) -title = gprMax.Title(name='Heterogeneous soil using a stochastic distribution of dielectric properties given by a mixing model from Peplinski') -waveform1 = gprMax.Waveform(wave_type='ricker', amp=1, freq=1.5e9, id='my_ricker') -dipole = gprMax.HertzianDipole(p1=(0.045, 0.075, 0.085), polarisation='y', waveform_id='my_ricker') - - -sp = gprMax.SoilPeplinski(sand_fraction=0.5, - clay_fraction=0.5, - bulk_density=2.0, - sand_density=2.66, - water_fraction_lower=0.001, - water_fraction_upper=0.25, - id='my_soil') - -fb = gprMax.FractalBox(p1=(0, 0, 0), p2=(0.15, 0.15, 0.070), frac_dim=1.5, weighting=[1, 1, 1], n_materials=50, mixing_model_id='my_soil', id='my_soil_box') -asf = gprMax.AddSurfaceRoughness(p1=(0, 0, 0.070), p2=(0.15, 0.15, 0.070), frac_dim=1.5, weighting=[1, 1], limits=[0.065, 0.080], fractal_box_id='my_soil_box') -gv = gprMax.GeometryView(p1=(0, 0, 0), p2=(0.15, 0.15, 0.1), dl=(0.001, 0.001, 0.001), filename='heterogeneous_soil', output_type='n') - - -rx = gprMax.Rx(p1=(0.045, 0.075 + 10e-3, 0.085)) - -scene = gprMax.Scene() -scene.add(dxdydz) -scene.add(messages) -scene.add(tw) -scene.add(domain) -scene.add(title) -scene.add(waveform1) -scene.add(dipole) -scene.add(sp) -scene.add(fb) -scene.add(asf) -scene.add(gv) -scene.add(rx) - -gprMax.run(scenes=[scene], n=1, geometry_only=False, outputfile='mysimulation')