Updates to get antenna models working with revised antenna library.

这个提交包含在:
Craig Warren
2019-10-31 14:27:22 +00:00
父节点 818d0e7866
当前提交 a0e7ff1fa1
共有 22 个文件被更改,包括 214 次插入323 次删除

5
.gitignore vendored
查看文件

@@ -21,3 +21,8 @@ dist/
# Jupyter notebook checkpoints # Jupyter notebook checkpoints
.ipynb_checkpoints/ .ipynb_checkpoints/
# Craig's files
user_models/GPU-paper-landmines/
user_models/IWAGPR2017-challenge/
user_models/to-update/

查看文件

@@ -49,6 +49,7 @@ from .cmds_geometry.fractal_box import FractalBox
from .cmds_geometry.add_surface_roughness import AddSurfaceRoughness from .cmds_geometry.add_surface_roughness import AddSurfaceRoughness
from .cmds_geometry.add_surface_water import AddSurfaceWater from .cmds_geometry.add_surface_water import AddSurfaceWater
from .cmds_geometry.add_grass import AddGrass 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 from .hash_cmds_file import user_libs_fn_to_scene_obj

查看文件

@@ -17,11 +17,17 @@
# along with gprMax. If not, see <http://www.gnu.org/licenses/>. # along with gprMax. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import os from pathlib import Path
import h5py
import gprMax.config as config import gprMax.config as config
from .cmds_geometry import UserObjectGeometry from .cmds_geometry import UserObjectGeometry
from ..cython.geometry_primitives import build_voxels_from_array
from ..exceptions import CmdInputError 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__) log = logging.getLogger(__name__)
@@ -31,6 +37,7 @@ class GeometryObjectsRead(UserObjectGeometry):
log.debug('More work required here.') log.debug('More work required here.')
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 1 self.order = 1
self.hash = '#geometry_objects_read' self.hash = '#geometry_objects_read'
@@ -49,10 +56,12 @@ class GeometryObjectsRead(UserObjectGeometry):
xs, ys, zs = uip.discretise_point(p1) xs, ys, zs = uip.discretise_point(p1)
# See if material file exists at specified path and if not try input file directory # See if material file exists at specified path and if not try input file directory
if not os.path.isfile(matfile): matfile = Path(matfile)
matfile = os.path.abspath(os.path.join(G.inputdirectory, 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) numexistmaterials = len(G.materials)
# Read materials from file # Read materials from file
@@ -64,7 +73,7 @@ class GeometryObjectsRead(UserObjectGeometry):
singlecmdsimport, multicmdsimport, geometryimport = check_cmd_names(materials, checkessential=False) singlecmdsimport, multicmdsimport, geometryimport = check_cmd_names(materials, checkessential=False)
# Process parameters for commands that can occur multiple times in the model # Process parameters for commands that can occur multiple times in the model
process_multicmds(multicmdsimport, G) process_multicmds(multicmdsimport)
# Update material type # Update material type
for material in G.materials: for material in G.materials:
@@ -75,8 +84,9 @@ class GeometryObjectsRead(UserObjectGeometry):
material.type = 'imported' material.type = 'imported'
# See if geometry object file exists at specified path and if not try input file directory # See if geometry object file exists at specified path and if not try input file directory
if not os.path.isfile(geofile): geofile = Path(geofile)
geofile = os.path.abspath(os.path.join(G.inputdirectory, 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 # Open geometry object file and read/check spatial resolution attribute
f = h5py.File(geofile, 'r') f = h5py.File(geofile, 'r')

查看文件

@@ -17,7 +17,6 @@
# along with gprMax. If not, see <http://www.gnu.org/licenses/>. # along with gprMax. If not, see <http://www.gnu.org/licenses/>.
import logging import logging
import sys
import numpy as np import numpy as np
@@ -415,7 +414,7 @@ class TransmissionLine(UserObjectMulti):
raise CmdInputError(f"'{self.params_str()}' requires at least six parameters") raise CmdInputError(f"'{self.params_str()}' requires at least six parameters")
# Warn about using a transmission line on GPU # 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.") 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 # Check polarity & position parameters
@@ -430,12 +429,12 @@ class TransmissionLine(UserObjectMulti):
xcoord, ycoord, zcoord = uip.check_src_rx_point(p1, self.params_str()) 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") 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 # Check if there is a waveformID in the waveforms list
if not any(x.ID == waveform_id for x in grid.waveforms): 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 = TransmissionLineUser(grid)
t.polarisation = polarisation t.polarisation = polarisation

查看文件

@@ -18,7 +18,7 @@
import inspect import inspect
import logging import logging
import os from pathlib import Path
from colorama import init from colorama import init
from colorama import Fore from colorama import Fore
@@ -427,6 +427,10 @@ class ExcitationFile(UserObjectSingle):
:type fill_value: float, optional :type fill_value: float, optional
""" """
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 11
def create(self, G, uip): def create(self, G, uip):
try: try:
kwargs = dict() kwargs = dict()
@@ -442,55 +446,56 @@ class ExcitationFile(UserObjectSingle):
except KeyError: except KeyError:
raise CmdInputError('#excitation_file: requires either one or three parameter(s)') 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 # See if file exists at specified path and if not try input file directory
if not os.path.isfile(excitationfile): excitationfile = Path(excitationfile)
excitationfile = os.path.abspath(os.path.join(G.inputdirectory, 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 # Get waveform names
with open(excitationfile, 'r') as f: with open(excitationfile, 'r') as f:
waveformIDs = f.readline().split() waveformIDs = f.readline().split()
# Read all waveform values into an array # Read all waveform values into an array
waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=floattype) waveformvalues = np.loadtxt(excitationfile, skiprows=1, dtype=config.sim_config.dtypes['float_or_double'])
# Time array (if specified) for interpolation, otherwise use simulation time # Time array (if specified) for interpolation, otherwise use simulation time
if waveformIDs[0].lower() == 'time': if waveformIDs[0].lower() == 'time':
waveformIDs = waveformIDs[1:] waveformIDs = waveformIDs[1:]
waveformtime = waveformvalues[:, 0] waveformtime = waveformvalues[:, 0]
waveformvalues = waveformvalues[:, 1:] waveformvalues = waveformvalues[:, 1:]
timestr = 'user-defined time array' timestr = 'user-defined time array'
else: else:
waveformtime = np.arange(0, G.timewindow + G.dt, G.dt) waveformtime = np.arange(0, G.timewindow + G.dt, G.dt)
timestr = 'simulation time array' timestr = 'simulation time array'
for waveform in range(len(waveformIDs)): for waveform in range(len(waveformIDs)):
if any(x.ID == waveformIDs[waveform] for x in G.waveforms): if any(x.ID == waveformIDs[waveform] for x in G.waveforms):
raise CmdInputError(f'Waveform with ID {waveformIDs[waveform]} already exists') raise CmdInputError(f'Waveform with ID {waveformIDs[waveform]} already exists')
w = Waveform() w = Waveform()
w.ID = waveformIDs[waveform] w.ID = waveformIDs[waveform]
w.type = 'user' w.type = 'user'
# Select correct column of waveform values depending on array shape # Select correct column of waveform values depending on array shape
singlewaveformvalues = waveformvalues[:] if len(waveformvalues.shape) == 1 else waveformvalues[:, waveform] singlewaveformvalues = waveformvalues[:] if len(waveformvalues.shape) == 1 else waveformvalues[:, waveform]
# Truncate waveform array if it is longer than time array # Truncate waveform array if it is longer than time array
if len(singlewaveformvalues) > len(waveformtime): if len(singlewaveformvalues) > len(waveformtime):
singlewaveformvalues = singlewaveformvalues[:len(waveformtime)] singlewaveformvalues = singlewaveformvalues[:len(waveformtime)]
# Zero-pad end of waveform array if it is shorter than time array # Zero-pad end of waveform array if it is shorter than time array
elif len(singlewaveformvalues) < len(waveformtime): elif len(singlewaveformvalues) < len(waveformtime):
singlewaveformvalues = np.lib.pad(singlewaveformvalues, singlewaveformvalues = np.lib.pad(singlewaveformvalues,
(0, len(singlewaveformvalues) - (0, len(singlewaveformvalues) -
len(waveformvalues)), len(waveformvalues)),
'constant', constant_values=0) 'constant', constant_values=0)
# Interpolate waveform values # Interpolate waveform values
w.userfunc = interpolate.interp1d(waveformtime, singlewaveformvalues, **kwargs) 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): class OutputDir(UserObjectSingle):
@@ -501,7 +506,7 @@ class OutputDir(UserObjectSingle):
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 11 self.order = 12
def create(self, grid, uip): def create(self, grid, uip):
config.model_configs[grid.model_num].set_output_file_path(self.kwargs['dir']) config.model_configs[grid.model_num].set_output_file_path(self.kwargs['dir'])
@@ -516,7 +521,7 @@ class NumberOfModelRuns(UserObjectSingle):
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 12 self.order = 13
def create(self, grid, uip): def create(self, grid, uip):
try: try:

查看文件

@@ -210,7 +210,7 @@ class SimulationConfig:
# Suppress nvcc warnings on Microsoft Windows # Suppress nvcc warnings on Microsoft Windows
if sys.platform == 'win32': self.cuda['nvcc_opts'] = '-w' if sys.platform == 'win32': self.cuda['nvcc_opts'] = '-w'
self.get_gpus() self.get_gpus()
self.set_gpus() self.set_single_gpu()
# Subgrid parameter may not exist if user enters via CLI # Subgrid parameter may not exist if user enters via CLI
try: try:
@@ -242,7 +242,7 @@ class SimulationConfig:
self.cuda['gpus'], self.cuda['gpus_str'] = detect_check_gpus(self.cuda['gpus']) 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.""" """Adjust list of GPU object(s) to specify single GPU."""
self.cuda['gpus'] = self.cuda['gpus'][0] self.cuda['gpus'] = self.cuda['gpus'][0]
self.cuda['gpus_str'] = self.cuda['gpus_str'][0] self.cuda['gpus_str'] = self.cuda['gpus_str'][0]
@@ -304,8 +304,10 @@ class SimulationConfig:
def set_input_file_path(self): def set_input_file_path(self):
"""Set input file path for CLI or API.""" """Set input file path for CLI or API."""
# API
if self.args.inputfile is None: if self.args.inputfile is None:
self.input_file_path = Path(self.args.outputfile) self.input_file_path = Path(self.args.outputfile)
# CLI
else: else:
self.input_file_path = Path(self.args.inputfile) self.input_file_path = Path(self.args.inputfile)

查看文件

@@ -124,7 +124,6 @@ def write_hdf5_sub_grid_outputfile(outputfile, G):
parent = outputfile.parent parent = outputfile.parent
for sg in G.subgrids: for sg in G.subgrids:
# Create an outputfile for each subgrid # Create an outputfile for each subgrid
fp = stem + '_' + sg.name + suffix fp = stem + '_' + sg.name + suffix
fp = parent / Path(fp) fp = parent / Path(fp)
@@ -146,6 +145,9 @@ def write_data(outputfile, G):
Args: Args:
outputfile (str): Name of the output file. outputfile (str): Name of the output file.
G (FDTDGrid): Parameters describing a grid in a model. G (FDTDGrid): Parameters describing a grid in a model.
Returns:
f (file object): File object.
""" """
f = h5py.File(outputfile, 'w') f = h5py.File(outputfile, 'w')

查看文件

@@ -405,9 +405,9 @@ class GeometryViewFineMultiGrid:
"""Geometry view for all grids in the simulation. """Geometry view for all grids in the simulation.
Slicing is not supported by this class :( - only the full extent of the grids 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 are output. The subgrids are output without the non-working regions.
require domainslicing GeometryView seperately for each grid you require and If you require domain slicing, GeometryView seperately for each grid you
view them at once in Paraview. require and view them at once in Paraview.
""" """
def __init__(self, xs, ys, zs, xf, yf, zf, dx, dy, dz, filename, fileext, G): 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. filename (str): Filename to save to.
fileext (str): File extension of VTK file - either '.vti' for a per cell fileext (str): File extension of VTK file - either '.vti' for a per cell
geometry view, or '.vtp' for a per cell edge geometry view. geometry view, or '.vtp' for a per cell edge geometry view.
G (FDTDGrid): Parameters describing a grid in a model.
""" """
self.G = G self.G = G
self.nx = G.nx self.nx = G.nx
self.ny = G.ny self.ny = G.ny
@@ -460,41 +462,36 @@ class GeometryViewFineMultiGrid:
PolygonalData (.vtp) for a per-cell-edge geometry view. PolygonalData (.vtp) for a per-cell-edge geometry view.
N.B. No Python 3 support for VTK at time of writing (03/2015) 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 G = self.G
with open(self.filename, 'wb') as f: with open(self.filename, 'wb') as f:
# refine parameters for subgrid # refine parameters for subgrid
f.write('<?xml version="1.0"?>\n'.encode('utf-8')) f.write('<?xml version="1.0"?>\n'.encode('utf-8'))
f.write('<VTKFile type="PolyData" version="1.0" byte_order="{}">\n'.format(config.sim_config.vtk_byteorder).encode('utf-8')) f.write(f"""<VTKFile type="PolyData" version="1.0" byte_order="{config.sim_config.vtk_byteorder}">\n""".encode('utf-8'))
f.write('<PolyData>\n<Piece NumberOfPoints="{}" NumberOfVerts="0" NumberOfLines="{}" NumberOfStrips="0" NumberOfPolys="0">\n'.format(self.vtk_numpoints, self.vtk_numlines).encode('utf-8')) f.write(f"""<PolyData>\n<Piece NumberOfPoints="{self.vtk_numpoints}" NumberOfVerts="0" NumberOfLines="{self.vtk_numlines}" NumberOfStrips="0" NumberOfPolys="0">\n""".encode('utf-8'))
f.write('<Points>\n<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="0" />\n</Points>\n'.encode('utf-8')) f.write('<Points>\n<DataArray type="Float32" NumberOfComponents="3" format="appended" offset="0" />\n</Points>\n'.encode('utf-8'))
f.write('<Lines>\n<DataArray type="UInt32" Name="connectivity" format="appended" offset="{}" />\n'.format(self.vtk_connectivity_offset).encode('utf-8')) f.write(f"""<Lines>\n<DataArray type="UInt32" Name="connectivity" format="appended" offset="{self.vtk_connectivity_offset}" />\n""".encode('utf-8'))
f.write('<DataArray type="UInt32" Name="offsets" format="appended" offset="{}" />\n</Lines>\n'.format(self.vtk_offsets_offset).encode('utf-8')) f.write(f"""<DataArray type="UInt32" Name="offsets" format="appended" offset="{self.vtk_offsets_offset}" />\n</Lines>\n""".encode('utf-8'))
f.write('<CellData Scalars="Material">\n'.encode('utf-8')) f.write('<CellData Scalars="Material">\n'.encode('utf-8'))
f.write('<DataArray type="UInt32" Name="Material" format="appended" offset="{}" />\n'.format(self.vtk_materials_offset).encode('utf-8')) f.write(f"""<DataArray type="UInt32" Name="Material" format="appended" offset="{self.vtk_materials_offset}" />\n""".encode('utf-8'))
f.write('</CellData>\n'.encode('utf-8')) f.write('</CellData>\n'.encode('utf-8'))
f.write('</Piece>\n</PolyData>\n<AppendedData encoding="raw">\n_'.encode('utf-8')) f.write('</Piece>\n</PolyData>\n<AppendedData encoding="raw">\n_'.encode('utf-8'))
# Write points # 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 datasize = np.dtype(np.float32).itemsize * self.vtk_numpoints * self.vtk_numpoint_components
f.write(pack('I', datasize)) f.write(pack('I', datasize))
for i in range(0, G.nx + 1): for i in range(0, G.nx + 1):
for j in range(0, G.ny + 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)) f.write(pack('fff', i * G.dx, j * G.dy, k * G.dz))
for sg_v in self.sg_views: for sg_v in self.sg_views:
log.info('writing points subgrid') log.info('Writing points subgrid')
sg_v.write_points(f, G) sg_v.write_points(f, G)
n_x_lines = self.nx * (self.ny + 1) * (self.nz + 1) 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_lines = np.zeros((n_z_lines, 2), dtype=np.uint32)
z_materials = np.zeros((n_z_lines), 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 label = 0
counter_x = 0 counter_x = 0
counter_y = 0 counter_y = 0
@@ -541,7 +538,7 @@ class GeometryViewFineMultiGrid:
label = label + 1 label = label + 1
log.info('calculate connectivity subgrids') log.info('Calculate connectivity subgrids')
for sg_v in self.sg_views: for sg_v in self.sg_views:
sg_v.populate_connectivity_and_materials(label) sg_v.populate_connectivity_and_materials(label)
# use the last subgrids label for the next view # use the last subgrids label for the next view
@@ -596,15 +593,14 @@ class GeometryViewFineMultiGrid:
f.write('\n\n<gprMax>\n'.encode('utf-8')) f.write('\n\n<gprMax>\n'.encode('utf-8'))
for material in G.materials: for material in G.materials:
f.write('<Material name="{}">{}</Material>\n'.format(material.ID, material.numID).encode('utf-8')) f.write(f"""<Material name="{material.ID}">{material.numID}</Material>\n""".encode('utf-8'))
if not materialsonly: if not materialsonly:
f.write('<PML name="PML boundary region">1</PML>\n'.encode('utf-8')) f.write('<PML name="PML boundary region">1</PML>\n'.encode('utf-8'))
for index, src in enumerate(G.hertziandipoles + G.magneticdipoles + G.voltagesources + G.transmissionlines): for index, src in enumerate(G.hertziandipoles + G.magneticdipoles + G.voltagesources + G.transmissionlines):
f.write('<Sources name="{}">{}</Sources>\n'.format(src.ID, index + 2).encode('utf-8')) f.write(f"""<Sources name="{src.ID}">{index + 2}</Sources>\n""".encode('utf-8'))
for index, rx in enumerate(G.rxs): for index, rx in enumerate(G.rxs):
f.write('<Receivers name="{}">{}</Receivers>\n'.format(rx.ID, index + 1).encode('utf-8')) f.write(f"""<Receivers name="{rx.ID}">{index + 1}</Receivers>\n""".encode('utf-8'))
f.write('</gprMax>\n'.encode('utf-8')) f.write('</gprMax>\n'.encode('utf-8'))
return None
class SubgridGeometryView: class SubgridGeometryView:
@@ -649,7 +645,7 @@ class SubgridGeometryView:
def populate_connectivity_and_materials(self, label): def populate_connectivity_and_materials(self, label):
"""Label is the starting label. 0 if no other grids are present but """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 sg = self.sg

查看文件

@@ -24,7 +24,7 @@ import sys
import gprMax.config as config import gprMax.config as config
from .exceptions import CmdInputError 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_multiuse import process_multicmds
from .hash_cmds_singleuse import process_singlecmds from .hash_cmds_singleuse import process_singlecmds

查看文件

@@ -317,12 +317,12 @@ class TransmissionLine(Source):
# Cell position of where line connects to antenna/main grid # Cell position of where line connects to antenna/main grid
self.antpos = 10 self.antpos = 10
self.voltage = np.zeros(self.nl, 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.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.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.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.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.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): def calculate_incident_V_I(self, G):
"""Calculates the incident voltage and current with a long length """Calculates the incident voltage and current with a long length

查看文件

@@ -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), c8 = gprMax.Cylinder(p1=(x + 0.147, y + 0.008, z + skidthickness),
p2=(x + 0.147, y + 0.008, p2=(x + 0.147, y + 0.008,
z + skidthickness + casesize[2] - casethickness), 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), b6 = gprMax.Box(p1=(x + 0.054, y + casesize[1] - 0.016, z + skidthickness),
p2=(x + 0.056, y + casesize[1] - 0.014, p2=(x + 0.056, y + casesize[1] - 0.014,
z + skidthickness + casesize[2] - casethickness), 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]), p2=(tx[0] + 0.020, tx[1] + bowtieheight + 0.006, tx[2]),
material_id='txresupper') material_id='txresupper')
e16 = gprMax.Edge(p1=(tx[0] + 0.020 + dx, tx[1] + bowtieheight + 0.002, tx[2]), 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') material_id='txresupper')
scene_objects.extend((e11, e12, e13, e14, e15, e16)) 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]), p2=(tx[0] - 0.023 + dx + 0.076, tx[1] - bowtieheight - dy, tx[2]),
material_id='rxreslower') material_id='rxreslower')
e19 = gprMax.Edge(p1=(tx[0] + 0.076, tx[1] - bowtieheight - 0.004, tx[2]), 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') material_id='rxreslower')
e20 = gprMax.Edge(p1=(tx[0] + dx + 0.076, tx[1] - bowtieheight - 0.004, tx[2]), 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]), p2=(tx[0] + dx + 0.076, tx[1] - bowtieheight - dy, tx[2]),

查看文件

@@ -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:

查看文件

@@ -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)

查看文件

@@ -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:

查看文件

@@ -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:

查看文件

@@ -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:

查看文件

@@ -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)

查看文件

@@ -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:

查看文件

@@ -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)

查看文件

@@ -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:

查看文件

@@ -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

查看文件

@@ -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')