你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-07 15:10:13 +08:00
@@ -150,7 +150,7 @@ def check_cmd_names(processedlines, checkessential=True):
|
||||
singlecmds = dict.fromkeys(['#domain', '#dx_dy_dz', '#time_window', '#title', '#messages', '#num_threads', '#time_step_stability_factor', '#pml_cells', '#excitation_file', '#src_steps', '#rx_steps', '#taguchi', '#end_taguchi'], 'None')
|
||||
|
||||
# Commands that there can be multiple instances of in a model - these will be lists within the dictionary
|
||||
multiplecmds = {key: [] for key in ['#geometry_view', '#material', '#soil_peplinski', '#add_dispersion_debye', '#add_dispersion_lorentz', '#add_dispersion_drude', '#waveform', '#voltage_source', '#hertzian_dipole', '#magnetic_dipole', '#transmission_line', '#tem_transmission_line', '#rx', '#rx_box', '#snapshot', '#pml_cfs']}
|
||||
multiplecmds = {key: [] for key in ['#geometry_view', '#material', '#soil_peplinski', '#add_dispersion_debye', '#add_dispersion_lorentz', '#add_dispersion_drude', '#waveform', '#voltage_source', '#hertzian_dipole', '#magnetic_dipole', '#transmission_line', '#rx', '#rx_box', '#snapshot', '#pml_cfs']}
|
||||
|
||||
# Geometry object building commands that there can be multiple instances of in a model - these will be lists within the dictionary
|
||||
geometrycmds = ['#geometry_objects_file', '#edge', '#plate', '#triangle', '#box', '#sphere', '#cylinder', '#cylindrical_sector', '#fractal_box', '#add_surface_roughness', '#add_surface_water', '#add_grass']
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2015-2016: The University of Edinburgh
|
||||
# Copyright (C) 2015-2016: The University of Edinburgh
|
||||
# Authors: Craig Warren and Antonis Giannopoulos
|
||||
#
|
||||
# This file is part of gprMax.
|
||||
@@ -16,152 +16,87 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gprMax. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .constants import z0
|
||||
from .exceptions import CmdInputError
|
||||
from .geometry_views import GeometryView
|
||||
from .materials import Material, PeplinskiSoil
|
||||
from .pml import CFSParameter, CFS
|
||||
from .receivers import Rx
|
||||
from .snapshots import Snapshot
|
||||
from .sources import (
|
||||
VoltageSource, HertzianDipole, MagneticDipole, TransmissionLine, TEMTransmissionLine)
|
||||
from .utilities import round_value
|
||||
from .waveforms import Waveform
|
||||
|
||||
from collections import OrderedDict
|
||||
from gprMax.constants import z0
|
||||
from gprMax.exceptions import CmdInputError
|
||||
from gprMax.geometry_views import GeometryView
|
||||
from gprMax.materials import Material, PeplinskiSoil
|
||||
from gprMax.pml import CFSParameter, CFS
|
||||
from gprMax.receivers import Rx
|
||||
from gprMax.snapshots import Snapshot
|
||||
from gprMax.sources import VoltageSource, HertzianDipole, MagneticDipole, TransmissionLine
|
||||
from gprMax.utilities import round_value
|
||||
from gprMax.waveforms import Waveform
|
||||
|
||||
|
||||
def check_coordinates(x, y, z, G, cmdname, tmp, name=''):
|
||||
def process_multicmds(multicmds, G):
|
||||
"""Checks the validity of command parameters and creates instances of classes of parameters.
|
||||
|
||||
Args:
|
||||
multicmds (dict): Commands that can have multiple instances in the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
# Check if coordinates are within the bounds of the grid
|
||||
def check_coordinates(x, y, z, name=''):
|
||||
try:
|
||||
G.within_bounds(x=x, y=y, z=z)
|
||||
except ValueError as err:
|
||||
|
||||
s = "'{}: {} ' {} {}-coordinate is not within the model domain".format(
|
||||
cmdname, ' '.join(tmp), name, err.args[0])
|
||||
s = "'{}: {} ' {} {}-coordinate is not within the model domain".format(cmdname, ' '.join(tmp), name, err.args[0])
|
||||
raise CmdInputError(s)
|
||||
|
||||
|
||||
def create_cmd_msg(cmdname, cmdinstance):
|
||||
"""Function to create a formatted str relating to a command
|
||||
and its parameters
|
||||
"""
|
||||
return "'{}:{}'".format(cmdname, cmdinstance)
|
||||
|
||||
|
||||
def create_transmission_line(cmdname, cmdinstance, G):
|
||||
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
# Waveform definitions
|
||||
cmdname = '#waveform'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
if len(tmp) != 4:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly four parameters')
|
||||
if tmp[0].lower() not in Waveform.types:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' must have one of the following types {}'.format(','.join(Waveform.types)))
|
||||
if float(tmp[2]) <= 0:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires an excitation frequency value of greater than zero')
|
||||
if any(x.ID == tmp[3] for x in G.waveforms):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' with ID {} already exists'.format(tmp[3]))
|
||||
|
||||
# Check correct number of args
|
||||
if len(tmp) < 6:
|
||||
raise CmdInputError(
|
||||
"{} requires at least six parameters".format(cmd_msg))
|
||||
|
||||
# Check polarity & position parameters
|
||||
if tmp[0].lower() not in ('x', 'y', 'z', 'zx', 'xz'):
|
||||
raise CmdInputError(
|
||||
"{} polarisation must be x, y, z or zx".format(cmd_msg))
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
zcoord = G.calculate_coord('z', tmp[3])
|
||||
resistance = float(tmp[4])
|
||||
|
||||
check_coordinates(xcoord, ycoord, zcoord, G, cmdname, tmp)
|
||||
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be \
|
||||
positioned within the PML.".format(cmd_msg))
|
||||
if resistance <= 0 or resistance > z0:
|
||||
raise CmdInputError(
|
||||
"{} requires a resistance greater than zero and less than the impedance \
|
||||
of free space, i.e. 376.73 Ohms".format(cmd_msg))
|
||||
|
||||
# Check if there is a waveformID in the waveforms list
|
||||
if not any(x.ID == tmp[5] for x in G.waveforms):
|
||||
raise CmdInputError("{} there is no waveform with the identifier \
|
||||
{}".format(cmd_msg, tmp[4]))
|
||||
|
||||
# Can create several types of transmission line
|
||||
if cmdname == '#transmission_line':
|
||||
t = TransmissionLine(G)
|
||||
elif cmdname == '#tem_transmission_line':
|
||||
t = TEMTransmissionLine(G)
|
||||
else:
|
||||
raise CmdInputError("{} is not a valid transmission line type")
|
||||
|
||||
t.polarisation = tmp[0]
|
||||
t.xcoord = xcoord
|
||||
t.ycoord = ycoord
|
||||
t.zcoord = zcoord
|
||||
t.setID()
|
||||
t.resistance = resistance
|
||||
t.waveformID = tmp[5]
|
||||
t.calculate_incident_V_I(G)
|
||||
|
||||
if len(tmp) > 6:
|
||||
# Check source start & source remove time parameters
|
||||
start = float(tmp[6])
|
||||
stop = float(tmp[7])
|
||||
if start < 0:
|
||||
raise CmdInputError("{} delay of the initiation of the source should \
|
||||
not be less than zero".format(cmd_msg))
|
||||
if stop < 0:
|
||||
raise CmdInputError("{} time to remove the source should not be less \
|
||||
than zero".format(cmd_msg))
|
||||
if stop - start <= 0:
|
||||
raise CmdInputError("{} duration of the source should not be zero or \
|
||||
less".format(cmd_msg))
|
||||
t.start = start
|
||||
if stop > G.timewindow:
|
||||
t.stop = G.timewindow
|
||||
else:
|
||||
t.stop = stop
|
||||
startstop = ' start time {:g} secs, finish time {:g} secs '.format(
|
||||
t.start, t.stop)
|
||||
else:
|
||||
t.start = 0
|
||||
t.stop = G.timewindow
|
||||
startstop = ' '
|
||||
w = Waveform()
|
||||
w.ID = tmp[3]
|
||||
w.type = tmp[0].lower()
|
||||
w.amp = float(tmp[1])
|
||||
w.freq = float(tmp[2])
|
||||
|
||||
if G.messages:
|
||||
print('Transmission line with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(t.polarisation, t.xcoord * G.dx, t.ycoord * G.dy, t.zcoord * G.dz, t.resistance) + startstop + 'using waveform {} created.'.format(t.waveformID))
|
||||
print('Waveform {} of type {} with amplitude {:g}, frequency {:g}Hz created.'.format(w.ID, w.type, w.amp, w.freq))
|
||||
|
||||
G.transmissionlines.append(t)
|
||||
G.waveforms.append(w)
|
||||
|
||||
|
||||
def create_voltage_source(cmdname, cmdinstance, G):
|
||||
# Voltage source
|
||||
cmdname = '#voltage_source'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) < 6:
|
||||
raise CmdInputError("{} requires at least six parameters".format(
|
||||
cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least six parameters')
|
||||
|
||||
# Check polarity & position parameters
|
||||
if tmp[0].lower() not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("{} polarisation must be x, y, or z".format(
|
||||
cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
zcoord = G.calculate_coord('z', tmp[3])
|
||||
resistance = float(tmp[4])
|
||||
check_coordinates(xcoord, ycoord, zcoord, G, cmdname, tmp)
|
||||
check_coordinates(xcoord, ycoord, zcoord)
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be \
|
||||
positioned within the PML.".format(cmd_msg))
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
if resistance < 0:
|
||||
raise CmdInputError("{} requires a source resistance of zero or \
|
||||
greater".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a source resistance of zero or greater')
|
||||
|
||||
# Check if there is a waveformID in the waveforms list
|
||||
if not any(x.ID == tmp[5] for x in G.waveforms):
|
||||
raise CmdInputError("{} there is no waveform with the \
|
||||
identifier {}".format(cmd_msg, tmp[5]))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' there is no waveform with the identifier {}'.format(tmp[5]))
|
||||
|
||||
v = VoltageSource()
|
||||
v.polarisation = tmp[0]
|
||||
v.polarisation= tmp[0]
|
||||
v.xcoord = xcoord
|
||||
v.ycoord = ycoord
|
||||
v.zcoord = zcoord
|
||||
@@ -174,14 +109,11 @@ def create_voltage_source(cmdname, cmdinstance, G):
|
||||
start = float(tmp[6])
|
||||
stop = float(tmp[7])
|
||||
if start < 0:
|
||||
raise CmdInputError("{} delay of the initiation of the source should \
|
||||
not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' delay of the initiation of the source should not be less than zero')
|
||||
if stop < 0:
|
||||
raise CmdInputError("{} time to remove the source should not be less \
|
||||
than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time to remove the source should not be less than zero')
|
||||
if stop - start <= 0:
|
||||
raise CmdInputError("{} duration of the source should not be zero or \
|
||||
less".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' duration of the source should not be zero or less')
|
||||
v.start = start
|
||||
if stop > G.timewindow:
|
||||
v.stop = G.timewindow
|
||||
@@ -199,53 +131,27 @@ def create_voltage_source(cmdname, cmdinstance, G):
|
||||
G.voltagesources.append(v)
|
||||
|
||||
|
||||
def create_waveforms(cmdname, cmdinstance, G):
|
||||
# Hertzian dipole
|
||||
cmdname = '#hertzian_dipole'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 4:
|
||||
raise CmdInputError("{} requires exactly four parameters".format(
|
||||
cmd_msg))
|
||||
if tmp[0].lower() not in Waveform.types:
|
||||
raise CmdInputError("{} must have one of the following types \
|
||||
{}".format(cmd_msg, ','.join(Waveform.types)))
|
||||
if float(tmp[2]) <= 0:
|
||||
raise CmdInputError("{} requires an excitation frequency value of greater \
|
||||
than zero".format(cmd_msg))
|
||||
if any(x.ID == tmp[3] for x in G.waveforms):
|
||||
raise CmdInputError("{} with ID {} already exists".format(
|
||||
cmd_msg, tmp[3]))
|
||||
|
||||
w = Waveform()
|
||||
w.ID = tmp[3]
|
||||
w.type = tmp[0].lower()
|
||||
w.amp = float(tmp[1])
|
||||
w.freq = float(tmp[2])
|
||||
|
||||
if G.messages:
|
||||
print('Waveform {} of type {} with amplitude {:g}, frequency {:g}Hz created.'.format(w.ID, w.type, w.amp, w.freq))
|
||||
|
||||
G.waveforms.append(w)
|
||||
|
||||
|
||||
def create_hertzian_dipole(cmdname, cmdinstance, G):
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) < 5:
|
||||
raise CmdInputError("{} requires at least five parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least five parameters')
|
||||
|
||||
# Check polarity & position parameters
|
||||
if tmp[0].lower() not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("{} polarisation must be x, y, or z".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
zcoord = G.calculate_coord('z', tmp[3])
|
||||
check_coordinates(xcoord, ycoord, zcoord, G, cmdname, tmp)
|
||||
check_coordinates(xcoord, ycoord, zcoord)
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be positioned within the PML.".format(cmd_msg))
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
|
||||
# Check if there is a waveformID in the waveforms list
|
||||
if not any(x.ID == tmp[4] for x in G.waveforms):
|
||||
raise CmdInputError("{} there is no waveform with the identifier {}".format(cmd_msg, tmp[4]))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' there is no waveform with the identifier {}'.format(tmp[4]))
|
||||
|
||||
h = HertzianDipole()
|
||||
h.polarisation = tmp[0]
|
||||
@@ -263,11 +169,11 @@ def create_hertzian_dipole(cmdname, cmdinstance, G):
|
||||
start = float(tmp[5])
|
||||
stop = float(tmp[6])
|
||||
if start < 0:
|
||||
raise CmdInputError("{} delay of the initiation of the source should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' delay of the initiation of the source should not be less than zero')
|
||||
if stop < 0:
|
||||
raise CmdInputError("{} time to remove the source should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time to remove the source should not be less than zero')
|
||||
if stop - start <= 0:
|
||||
raise CmdInputError("{} duration of the source should not be zero or less".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' duration of the source should not be zero or less')
|
||||
h.start = start
|
||||
if stop > G.timewindow:
|
||||
h.stop = G.timewindow
|
||||
@@ -285,25 +191,27 @@ def create_hertzian_dipole(cmdname, cmdinstance, G):
|
||||
G.hertziandipoles.append(h)
|
||||
|
||||
|
||||
def create_magnetic_dipole(cmdname, cmdinstance, G):
|
||||
# Magnetic dipole
|
||||
cmdname = '#magnetic_dipole'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) < 5:
|
||||
raise CmdInputError("{} requires at least five parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least five parameters')
|
||||
|
||||
# Check polarity & position parameters
|
||||
if tmp[0].lower() not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("{} polarisation must be x, y, or z".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
zcoord = G.calculate_coord('z', tmp[3])
|
||||
check_coordinates(xcoord, ycoord, zcoord, G, cmdname, tmp)
|
||||
check_coordinates(xcoord, ycoord, zcoord)
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be positioned within the PML.".format(cmd_msg))
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
|
||||
# Check if there is a waveformID in the waveforms list
|
||||
if not any(x.ID == tmp[4] for x in G.waveforms):
|
||||
raise CmdInputError("{} there is no waveform with the identifier {}".format(cmd_msg, tmp[4]))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' there is no waveform with the identifier {}'.format(tmp[4]))
|
||||
|
||||
m = MagneticDipole()
|
||||
m.polarisation = tmp[0]
|
||||
@@ -321,11 +229,11 @@ def create_magnetic_dipole(cmdname, cmdinstance, G):
|
||||
start = float(tmp[5])
|
||||
stop = float(tmp[6])
|
||||
if start < 0:
|
||||
raise CmdInputError("{} delay of the initiation of the source should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' delay of the initiation of the source should not be less than zero')
|
||||
if stop < 0:
|
||||
raise CmdInputError("{} time to remove the source should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time to remove the source should not be less than zero')
|
||||
if stop - start <= 0:
|
||||
raise CmdInputError("{} duration of the source should not be zero or less".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' duration of the source should not be zero or less')
|
||||
m.start = start
|
||||
if stop > G.timewindow:
|
||||
m.stop = G.timewindow
|
||||
@@ -342,20 +250,85 @@ def create_magnetic_dipole(cmdname, cmdinstance, G):
|
||||
|
||||
G.magneticdipoles.append(m)
|
||||
|
||||
|
||||
def create_rx(cmdname, cmdinstance, G):
|
||||
# Transmission line
|
||||
cmdname = '#transmission_line'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
if len(tmp) < 6:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least six parameters')
|
||||
|
||||
# Check polarity & position parameters
|
||||
if tmp[0].lower() not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
zcoord = G.calculate_coord('z', tmp[3])
|
||||
resistance = float(tmp[4])
|
||||
|
||||
check_coordinates(xcoord, ycoord, zcoord)
|
||||
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
if resistance <= 0 or resistance > z0:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' 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 == tmp[5] for x in G.waveforms):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' there is no waveform with the identifier {}'.format(tmp[4]))
|
||||
|
||||
t = TransmissionLine(G)
|
||||
t.polarisation = tmp[0]
|
||||
t.xcoord = xcoord
|
||||
t.ycoord = ycoord
|
||||
t.zcoord = zcoord
|
||||
t.ID = 'TransmissionLine(' + str(t.xcoord) + ',' + str(t.ycoord) + ',' + str(t.zcoord) + ')'
|
||||
t.resistance = resistance
|
||||
t.waveformID = tmp[5]
|
||||
t.calculate_incident_V_I(G)
|
||||
|
||||
if len(tmp) > 6:
|
||||
# Check source start & source remove time parameters
|
||||
start = float(tmp[6])
|
||||
stop = float(tmp[7])
|
||||
if start < 0:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' delay of the initiation of the source should not be less than zero')
|
||||
if stop < 0:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time to remove the source should not be less than zero')
|
||||
if stop - start <= 0:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' duration of the source should not be zero or less')
|
||||
t.start = start
|
||||
if stop > G.timewindow:
|
||||
t.stop = G.timewindow
|
||||
else:
|
||||
t.stop = stop
|
||||
startstop = ' start time {:g} secs, finish time {:g} secs '.format(t.start, t.stop)
|
||||
else:
|
||||
t.start = 0
|
||||
t.stop = G.timewindow
|
||||
startstop = ' '
|
||||
|
||||
if G.messages:
|
||||
print('Transmission line with polarity {} at {:g}m, {:g}m, {:g}m, resistance {:.1f} Ohms,'.format(t.polarisation, t.xcoord * G.dx, t.ycoord * G.dy, t.zcoord * G.dz, t.resistance) + startstop + 'using waveform {} created.'.format(t.waveformID))
|
||||
|
||||
G.transmissionlines.append(t)
|
||||
|
||||
# Receiver
|
||||
cmdname = '#rx'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 3 and len(tmp) < 5:
|
||||
raise CmdInputError("{} has an incorrect number of parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' has an incorrect number of parameters')
|
||||
|
||||
# Check position parameters
|
||||
xcoord = round_value(float(tmp[0]) / G.dx)
|
||||
ycoord = round_value(float(tmp[1]) / G.dy)
|
||||
zcoord = round_value(float(tmp[2]) / G.dz)
|
||||
xcoord = round_value(float(tmp[0])/G.dx)
|
||||
ycoord = round_value(float(tmp[1])/G.dy)
|
||||
zcoord = round_value(float(tmp[2])/G.dz)
|
||||
check_coordinates(xcoord, ycoord, zcoord)
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be positioned within the PML.\n".format(cmd_msg))
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
|
||||
r = Rx()
|
||||
r.xcoord = xcoord
|
||||
@@ -376,7 +349,7 @@ def create_rx(cmdname, cmdinstance, G):
|
||||
if field in Rx.availableoutputs:
|
||||
r.outputs.append(field)
|
||||
else:
|
||||
raise CmdInputError("{} contains an output type that is not available".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' contains an output type that is not available')
|
||||
|
||||
if G.messages:
|
||||
print('Receiver at {:g}m, {:g}m, {:g}m with output(s) {} created.'.format(r.xcoord * G.dx, r.ycoord * G.dy, r.zcoord * G.dz, ', '.join(r.outputs)))
|
||||
@@ -384,11 +357,13 @@ def create_rx(cmdname, cmdinstance, G):
|
||||
G.rxs.append(r)
|
||||
|
||||
|
||||
def create_rx_box(cmdname, cmdinstance, G):
|
||||
# Receiver box
|
||||
cmdname = '#rx_box'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 9:
|
||||
raise CmdInputError("{} requires exactly nine parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly nine parameters')
|
||||
|
||||
xs = G.calculate_coord('x', tmp[0])
|
||||
ys = G.calculate_coord('y', tmp[1])
|
||||
@@ -402,17 +377,17 @@ def create_rx_box(cmdname, cmdinstance, G):
|
||||
dy = G.calculate_coord('y', tmp[7])
|
||||
dz = G.calculate_coord('z', tmp[8])
|
||||
|
||||
check_coordinates(xs, ys, zs, G, cmdname, tmp, name='lower')
|
||||
check_coordinates(xf, yf, zf, G, cmdname, tmp, name='upper')
|
||||
check_coordinates(xs, ys, zs, name='lower')
|
||||
check_coordinates(xf, yf, zf, name='upper')
|
||||
|
||||
if xcoord < G.pmlthickness[0] or xcoord > G.nx - G.pmlthickness[3] or ycoord < G.pmlthickness[1] or ycoord > G.ny - G.pmlthickness[4] or zcoord < G.pmlthickness[2] or zcoord > G.nz - G.pmlthickness[5]:
|
||||
print("WARNING: {} sources and receivers should not normally be positioned within the PML.".format(cmd_msg))
|
||||
print("WARNING: '" + cmdname + ': ' + ' '.join(tmp) + "'" + ' sources and receivers should not normally be positioned within the PML.\n')
|
||||
if xs >= xf or ys >= yf or zs >= zf:
|
||||
raise CmdInputError("{} the lower coordinates should be less than the upper coordinates".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the lower coordinates should be less than the upper coordinates')
|
||||
if dx < 0 or dy < 0 or dz < 0:
|
||||
raise CmdInputError("{} the step size should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than zero')
|
||||
if dx < G.dx or dy < G.dy or dz < G.dz:
|
||||
raise CmdInputError("{} the step size should not be less than the spatial discretisation".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than the spatial discretisation')
|
||||
|
||||
for x in range(xs, xf, dx):
|
||||
for y in range(ys, yf, dy):
|
||||
@@ -431,11 +406,13 @@ def create_rx_box(cmdname, cmdinstance, G):
|
||||
print('Receiver box {:g}m, {:g}m, {:g}m, to {:g}m, {:g}m, {:g}m with steps {:g}m, {:g}m, {:g} created.'.format(xs * G.dx, ys * G.dy, zs * G.dz, xf * G.dx, yf * G.dy, zf * G.dz, dx * G.dx, dy * G.dy, dz * G.dz))
|
||||
|
||||
|
||||
def create_snapshot(cmdname, cmdinstance, G):
|
||||
# Snapshot
|
||||
cmdname = '#snapshot'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 11:
|
||||
raise CmdInputError("{} requires exactly eleven parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly eleven parameters')
|
||||
|
||||
xs = G.calculate_coord('x', tmp[0])
|
||||
ys = G.calculate_coord('y', tmp[1])
|
||||
@@ -458,19 +435,19 @@ def create_snapshot(cmdname, cmdinstance, G):
|
||||
if time > 0:
|
||||
time = round_value((time / G.dt)) + 1
|
||||
else:
|
||||
raise CmdInputError("{} time value must be greater than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time value must be greater than zero')
|
||||
|
||||
check_coordinates(xs, ys, zs, G, cmdname, tmp, name='lower')
|
||||
check_coordinates(xf, yf, zf, G, cmdname, tmp, name='upper')
|
||||
check_coordinates(xs, ys, zs, name='lower')
|
||||
check_coordinates(xf, yf, zf, name='upper')
|
||||
|
||||
if xs >= xf or ys >= yf or zs >= zf:
|
||||
raise CmdInputError("{} the lower coordinates should be less than the upper coordinates".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the lower coordinates should be less than the upper coordinates')
|
||||
if dx < 0 or dy < 0 or dz < 0:
|
||||
raise CmdInputError("{} the step size should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than zero')
|
||||
if dx < G.dx or dy < G.dy or dz < G.dz:
|
||||
raise CmdInputError("{} the step size should not be less than the spatial discretisation".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than the spatial discretisation')
|
||||
if time <= 0 or time > G.iterations:
|
||||
raise CmdInputError("{} time value is not valid".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' time value is not valid')
|
||||
|
||||
s = Snapshot(xs, ys, zs, xf, yf, zf, dx, dy, dz, time, tmp[10])
|
||||
|
||||
@@ -479,22 +456,23 @@ def create_snapshot(cmdname, cmdinstance, G):
|
||||
|
||||
G.snapshots.append(s)
|
||||
|
||||
|
||||
def create_material(cmdname, cmdinstance, G):
|
||||
# Materials
|
||||
cmdname = '#material'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 5:
|
||||
raise CmdInputError("{} requires exactly five parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly five parameters')
|
||||
if float(tmp[0]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for static (DC) permittivity".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for static (DC) permittivity')
|
||||
if float(tmp[1]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for conductivity".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for conductivity')
|
||||
if float(tmp[2]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for permeability".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for permeability')
|
||||
if float(tmp[3]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for magnetic conductivity".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for magnetic conductivity')
|
||||
if any(x.ID == tmp[4] for x in G.materials):
|
||||
raise CmdInputError("{} with ID {} already exists'.format(tmp[4]".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' with ID {} already exists'.format(tmp[4]))
|
||||
|
||||
# Create a new instance of the Material class material (start index after pec & free_space)
|
||||
m = Material(len(G.materials), tmp[4], G)
|
||||
@@ -510,14 +488,15 @@ def create_material(cmdname, cmdinstance, G):
|
||||
G.materials.append(m)
|
||||
|
||||
|
||||
def create_add_dispersion_debye(cmdname, cmdinstance, G):
|
||||
cmdname = '#add_dispersion_debye'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
|
||||
if len(tmp) < 4:
|
||||
raise CmdInputError("{} requires at least four parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least four parameters')
|
||||
if int(tmp[0]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for number of poles".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for number of poles')
|
||||
poles = int(tmp[0])
|
||||
materialsrequested = tmp[(2 * poles) + 1:len(tmp)]
|
||||
|
||||
@@ -526,7 +505,7 @@ def create_add_dispersion_debye(cmdname, cmdinstance, G):
|
||||
|
||||
if len(materials) != len(materialsrequested):
|
||||
notfound = [x for x in materialsrequested if x not in materials]
|
||||
raise CmdInputError("{} material(s) {} do not exist".format(cmd_msg, notfound))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' material(s) {} do not exist'.format(notfound))
|
||||
|
||||
for material in materials:
|
||||
material.type = 'debye'
|
||||
@@ -537,24 +516,22 @@ def create_add_dispersion_debye(cmdname, cmdinstance, G):
|
||||
material.deltaer.append(float(tmp[pole]))
|
||||
material.tau.append(float(tmp[pole + 1]))
|
||||
else:
|
||||
raise CmdInputError("{} requires positive values for the permittivity \
|
||||
difference and relaxation times, and relaxation times that are greater \
|
||||
than the time step for the model.".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference and relaxation times, and relaxation times that are greater than the time step for the model.')
|
||||
if material.poles > Material.maxpoles:
|
||||
Material.maxpoles = material.poles
|
||||
|
||||
if G.messages:
|
||||
print('Debye disperion added to {} with delta_epsr={}, and tau={} secs created.'.format(material.ID, ', '.join('%4.2f' % deltaer for deltaer in material.deltaer), ', '.join('%4.3e' % tau for tau in material.tau)))
|
||||
|
||||
|
||||
def create_add_dispersion_lorentz(cmdname, cmdinstance, G):
|
||||
cmdname = '#add_dispersion_lorentz'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
|
||||
if len(tmp) < 5:
|
||||
raise CmdInputError("{} requires at least five parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least five parameters')
|
||||
if int(tmp[0]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for number of poles".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for number of poles')
|
||||
poles = int(tmp[0])
|
||||
materialsrequested = tmp[(3 * poles) + 1:len(tmp)]
|
||||
|
||||
@@ -563,7 +540,7 @@ def create_add_dispersion_lorentz(cmdname, cmdinstance, G):
|
||||
|
||||
if len(materials) != len(materialsrequested):
|
||||
notfound = [x for x in materialsrequested if x not in materials]
|
||||
raise CmdInputError("{} material(s) {} do not exist".format(notfound, cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' material(s) {} do not exist'.format(notfound))
|
||||
|
||||
for material in materials:
|
||||
material.type = 'lorentz'
|
||||
@@ -575,7 +552,7 @@ def create_add_dispersion_lorentz(cmdname, cmdinstance, G):
|
||||
material.tau.append(float(tmp[pole + 1]))
|
||||
material.alpha.append(float(tmp[pole + 2]))
|
||||
else:
|
||||
raise CmdInputError("{} requires positive values for the permittivity difference and frequencies, and associated times that are greater than the time step for the model.".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the permittivity difference and frequencies, and associated times that are greater than the time step for the model.')
|
||||
if material.poles > Material.maxpoles:
|
||||
Material.maxpoles = material.poles
|
||||
|
||||
@@ -583,15 +560,15 @@ def create_add_dispersion_lorentz(cmdname, cmdinstance, G):
|
||||
print('Lorentz disperion added to {} with delta_epsr={}, omega={} secs, and gamma={} created.'.format(material.ID, ', '.join('%4.2f' % deltaer for deltaer in material.deltaer), ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
||||
|
||||
|
||||
def create_add_dispersion_drude(cmdname, cmdinstance, G):
|
||||
|
||||
cmdname = '#add_dispersion_drude'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
|
||||
if len(tmp) < 5:
|
||||
raise CmdInputError("{} requires at least five parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at least five parameters')
|
||||
if int(tmp[0]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for number of poles".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for number of poles')
|
||||
poles = int(tmp[0])
|
||||
materialsrequested = tmp[(3 * poles) + 1:len(tmp)]
|
||||
|
||||
@@ -600,7 +577,7 @@ def create_add_dispersion_drude(cmdname, cmdinstance, G):
|
||||
|
||||
if len(materials) != len(materialsrequested):
|
||||
notfound = [x for x in materialsrequested if x not in materials]
|
||||
raise CmdInputError("{} material(s) {} do not exist".format(cmd_msg, notfound))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' material(s) {} do not exist'.format(notfound))
|
||||
|
||||
for material in materials:
|
||||
material.type = 'drude'
|
||||
@@ -608,10 +585,10 @@ def create_add_dispersion_drude(cmdname, cmdinstance, G):
|
||||
material.average = False
|
||||
for pole in range(1, 2 * poles, 2):
|
||||
if float(tmp[pole]) > 0 and float(tmp[pole + 1]) > G.dt:
|
||||
material.tau.append(float(tmp[pole]))
|
||||
material.tau.append(float(tmp[pole ]))
|
||||
material.alpha.append(float(tmp[pole + 1]))
|
||||
else:
|
||||
raise CmdInputError("{} requires positive values for the frequencies, and associated times that are greater than the time step for the model.".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires positive values for the frequencies, and associated times that are greater than the time step for the model.')
|
||||
if material.poles > Material.maxpoles:
|
||||
Material.maxpoles = material.poles
|
||||
|
||||
@@ -619,25 +596,26 @@ def create_add_dispersion_drude(cmdname, cmdinstance, G):
|
||||
print('Drude disperion added to {} with omega={} secs, and gamma={} secs created.'.format(material.ID, ', '.join('%4.3e' % tau for tau in material.tau), ', '.join('%4.3e' % alpha for alpha in material.alpha)))
|
||||
|
||||
|
||||
def create_soil_peplinski(cmdname, cmdinstance, G):
|
||||
cmdname = '#soil_peplinski'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 7:
|
||||
raise CmdInputError("{} requires at exactly seven parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires at exactly seven parameters')
|
||||
if float(tmp[0]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the sand fraction".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the sand fraction')
|
||||
if float(tmp[1]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the clay fraction".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the clay fraction')
|
||||
if float(tmp[2]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the bulk density".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the bulk density')
|
||||
if float(tmp[3]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the sand particle density".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the sand particle density')
|
||||
if float(tmp[4]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the lower limit of the water volumetric fraction".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the lower limit of the water volumetric fraction')
|
||||
if float(tmp[5]) < 0:
|
||||
raise CmdInputError("{} requires a positive value for the upper limit of the water volumetric fraction".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires a positive value for the upper limit of the water volumetric fraction')
|
||||
if any(x.ID == tmp[6] for x in G.mixingmodels):
|
||||
raise CmdInputError("{} with ID {} already exists".format(cmd_msg, tmp[6]))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' with ID {} already exists'.format(tmp[6]))
|
||||
|
||||
# Create a new instance of the Material class material (start index after pec & free_space)
|
||||
s = PeplinskiSoil(tmp[6], float(tmp[0]), float(tmp[1]), float(tmp[2]), float(tmp[3]), (float(tmp[4]), float(tmp[5])))
|
||||
@@ -649,11 +627,13 @@ def create_soil_peplinski(cmdname, cmdinstance, G):
|
||||
G.mixingmodels.append(s)
|
||||
|
||||
|
||||
def create_geometry_view(cmdname, cmdinstance, G):
|
||||
# Geometry views (creates VTK-based geometry files)
|
||||
cmdname = '#geometry_view'
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
if len(tmp) != 11:
|
||||
raise CmdInputError("{} requires exactly eleven parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly eleven parameters')
|
||||
|
||||
xs = G.calculate_coord('x', tmp[0])
|
||||
ys = G.calculate_coord('y', tmp[1])
|
||||
@@ -667,21 +647,21 @@ def create_geometry_view(cmdname, cmdinstance, G):
|
||||
dy = G.calculate_coord('y', tmp[7])
|
||||
dz = G.calculate_coord('z', tmp[8])
|
||||
|
||||
check_coordinates(xs, ys, zs, G, cmdname, tmp, name='lower')
|
||||
check_coordinates(xf, yf, zf, G, cmdname, tmp, name='upper')
|
||||
check_coordinates(xs, ys, zs, name='lower')
|
||||
check_coordinates(xf, yf, zf, name='upper')
|
||||
|
||||
if xs >= xf or ys >= yf or zs >= zf:
|
||||
raise CmdInputError("{} the lower coordinates should be less than the upper coordinates".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the lower coordinates should be less than the upper coordinates')
|
||||
if dx < 0 or dy < 0 or dz < 0:
|
||||
raise CmdInputError("{} the step size should not be less than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than zero')
|
||||
if dx > G.nx or dy > G.ny or dz > G.nz:
|
||||
raise CmdInputError("{} the step size should be less than the domain size".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should be less than the domain size')
|
||||
if dx < G.dx or dy < G.dy or dz < G.dz:
|
||||
raise CmdInputError("{} the step size should not be less than the spatial discretisation".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' the step size should not be less than the spatial discretisation')
|
||||
if tmp[10].lower() != 'n' and tmp[10].lower() != 'f':
|
||||
raise CmdInputError("{} requires type to be either n (normal) or f (fine)".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires type to be either n (normal) or f (fine)')
|
||||
if tmp[10].lower() == 'f' and (dx * G.dx != G.dx or dy * G.dy != G.dy or dz * G.dz != G.dz):
|
||||
raise CmdInputError("{} requires the spatial discretisation for the geometry view to be the same as the model for geometry view of type f (fine)".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires the spatial discretisation for the geometry view to be the same as the model for geometry view of type f (fine)')
|
||||
|
||||
g = GeometryView(xs, ys, zs, xf, yf, zf, dx, dy, dz, tmp[9], tmp[10].lower())
|
||||
|
||||
@@ -692,24 +672,23 @@ def create_geometry_view(cmdname, cmdinstance, G):
|
||||
G.geometryviews.append(g)
|
||||
|
||||
|
||||
def create_pml_cfs(cmdname, cmdinstance, G):
|
||||
|
||||
# Complex frequency shifted (CFS) PML parameter
|
||||
cmdname = '#pml_cfs'
|
||||
if multicmds[cmdname] != 'None':
|
||||
if len(multicmds[cmdname]) > 2:
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' can only be used up to two times, for up to a 2nd order PML')
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
tmp = cmdinstance.split()
|
||||
cmd_msg = create_cmd_msg(cmdname, cmdinstance)
|
||||
|
||||
if len(G.cfs) == 2:
|
||||
raise CmdInputError("{} can only be used up to two times, for up to a 2nd order PML".format(cmd_msg))
|
||||
|
||||
if len(tmp) != 12:
|
||||
raise CmdInputError("{} requires exactly twelve parameters".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires exactly twelve parameters')
|
||||
if tmp[0] not in CFSParameter.scalingprofiles.keys() or tmp[4] not in CFSParameter.scalingprofiles.keys() or tmp[8] not in CFSParameter.scalingprofiles.keys():
|
||||
raise CmdInputError("{} must have scaling type {}'.format(','.join(CFSParameter.scalingprofiles.keys())".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' must have scaling type {}'.format(','.join(CFSParameter.scalingprofiles.keys())))
|
||||
if tmp[1] not in CFSParameter.scalingdirections or tmp[5] not in CFSParameter.scalingdirections or tmp[9] not in CFSParameter.scalingdirections:
|
||||
raise CmdInputError("{} must have scaling type {}'.format(','.join(CFSParameter.scalingprofiles.keys())".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' must have scaling type {}'.format(','.join(CFSParameter.scalingprofiles.keys())))
|
||||
if float(tmp[2]) < 0 or float(tmp[3]) < 0 or float(tmp[6]) < 0 or float(tmp[7]) < 0 or float(tmp[10]) < 0:
|
||||
raise CmdInputError("{} minimum and maximum scaling values must be greater than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' minimum and maximum scaling values must be greater than zero')
|
||||
if float(tmp[6]) < 1:
|
||||
raise CmdInputError("{} minimum scaling value for kappa must be greater than zero".format(cmd_msg))
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' minimum scaling value for kappa must be greater than zero')
|
||||
|
||||
cfsalpha = CFSParameter()
|
||||
cfsalpha.ID = 'alpha'
|
||||
@@ -742,39 +721,3 @@ def create_pml_cfs(cmdname, cmdinstance, G):
|
||||
|
||||
G.cfs.append(cfs)
|
||||
|
||||
|
||||
def process_multicmds(multicmds, G):
|
||||
"""Checks the validity of command parameters and creates instances of
|
||||
classes of parameters.
|
||||
|
||||
Args:
|
||||
multicmds (dict): Commands that can have multiple instances in the
|
||||
model.
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
"""
|
||||
|
||||
# Order of commands is important as some cmds have dependencies.
|
||||
cmds = OrderedDict()
|
||||
|
||||
cmds['#waveform'] = create_waveforms
|
||||
cmds['#voltage_source'] = create_voltage_source
|
||||
cmds['#hertzian_dipole'] = create_hertzian_dipole
|
||||
cmds['#magnetic_dipole'] = create_magnetic_dipole
|
||||
cmds['#transmission_line'] = create_transmission_line
|
||||
cmds['#tem_transmission_line'] = create_transmission_line
|
||||
cmds['#rx'] = create_rx
|
||||
cmds['#rx_box'] = create_rx_box
|
||||
cmds['#snapshot'] = create_snapshot
|
||||
cmds['#material'] = create_material
|
||||
cmds['#add_dispersion_debye'] = create_add_dispersion_debye
|
||||
cmds['#add_dispersion_lorentz'] = create_add_dispersion_lorentz
|
||||
cmds['#add_dispersion_drude'] = create_add_dispersion_drude
|
||||
cmds['#soil_peplinski'] = create_soil_peplinski
|
||||
cmds['#geometry_view'] = create_geometry_view
|
||||
cmds['#pml_cfs'] = create_pml_cfs
|
||||
|
||||
for cmdname, func in cmds.items():
|
||||
if multicmds[cmdname] != 'None':
|
||||
for cmdinstance in multicmds[cmdname]:
|
||||
func(cmdname, cmdinstance, G)
|
||||
|
@@ -20,12 +20,6 @@ import numpy as np
|
||||
|
||||
from gprMax.constants import e0, m0, floattype, complextype
|
||||
|
||||
# Look up for material ids
|
||||
material_ids = {
|
||||
'pec': 0,
|
||||
'freespace': 1
|
||||
}
|
||||
|
||||
|
||||
class Material(object):
|
||||
"""Materials, their properties and update coefficients."""
|
||||
|
@@ -20,11 +20,9 @@ from copy import deepcopy
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .constants import c, floattype
|
||||
from .grid import Ix, Iy, Iz
|
||||
from .utilities import round_value
|
||||
from .materials import material_ids
|
||||
from .exceptions import GeneralError
|
||||
from gprMax.constants import c, floattype
|
||||
from gprMax.grid import Ix, Iy, Iz
|
||||
from gprMax.utilities import round_value
|
||||
|
||||
|
||||
class Source(object):
|
||||
@@ -45,13 +43,10 @@ class Source(object):
|
||||
|
||||
|
||||
class VoltageSource(Source):
|
||||
"""The voltage source can be a hard source if it's resistance is zero,
|
||||
i.e. the time variation of the specified electric field component is
|
||||
prescribed. If it's resistance is non-zero it behaves as a resistive
|
||||
voltage source."""
|
||||
"""The voltage source can be a hard source if it's resistance is zero, i.e. the time variation of the specified electric field component is prescribed. If it's resistance is non-zero it behaves as a resistive voltage source."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
super(Source, self).__init__()
|
||||
self.resistance = None
|
||||
|
||||
def update_electric(self, abstime, updatecoeffsE, ID, Ex, Ey, Ez, G):
|
||||
@@ -130,7 +125,7 @@ class HertzianDipole(Source):
|
||||
"""The Hertzian dipole is an additive source (electric current density)."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
super(Source, self).__init__()
|
||||
|
||||
def update_electric(self, abstime, updatecoeffsE, ID, Ex, Ey, Ez, G):
|
||||
"""Updates electric field values for a Hertzian dipole.
|
||||
@@ -168,7 +163,7 @@ class MagneticDipole(Source):
|
||||
"""The magnetic dipole is an additive source (magnetic current density)."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
super(Source, self).__init__()
|
||||
|
||||
def update_magnetic(self, abstime, updatecoeffsH, ID, Hx, Hy, Hz, G):
|
||||
"""Updates magnetic field values for a magnetic dipole.
|
||||
@@ -200,35 +195,28 @@ class MagneticDipole(Source):
|
||||
|
||||
|
||||
class TransmissionLine(Source):
|
||||
"""The transmission line source is a one-dimensional transmission
|
||||
line which is attached virtually to a grid cell.
|
||||
"""
|
||||
"""The transmission line source is a one-dimensional transmission line which is attached virtually to a grid cell."""
|
||||
|
||||
def __init__(self, G):
|
||||
"""
|
||||
Args:
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
super(Source, self).__init__()
|
||||
self.resistance = None
|
||||
|
||||
# Coefficients for ABC termination of end of the transmission line
|
||||
self.abcv0 = 0
|
||||
self.abcv1 = 0
|
||||
|
||||
# Spatial step of transmission line (based on magic time step for
|
||||
# dispersionless behaviour)
|
||||
# Spatial step of transmission line (based on magic time step for dispersionless behaviour)
|
||||
self.dl = c * G.dt
|
||||
|
||||
# Number of nodes in the transmission line (initially a long line
|
||||
# to calculate incident voltage and current);
|
||||
# consider putting ABCs/PML at end
|
||||
# Number of nodes in the transmission line (initially a long line to calculate incident voltage and current); consider putting ABCs/PML at end
|
||||
self.nl = round_value(0.667 * G.iterations)
|
||||
|
||||
# Nodal position of the one-way injector excitation in the
|
||||
# transmission line
|
||||
# Nodal position of the one-way injector excitation in the transmission line
|
||||
self.srcpos = 5
|
||||
|
||||
# Nodal position of where line connects to antenna/main grid
|
||||
@@ -239,19 +227,11 @@ class TransmissionLine(Source):
|
||||
self.Vinc = np.zeros(G.iterations, dtype=floattype)
|
||||
self.Iinc = np.zeros(G.iterations, dtype=floattype)
|
||||
|
||||
self.type_str = 'TransmissionLine'
|
||||
|
||||
def setID(self):
|
||||
self.ID = self.type_str + '(' + str(self.xcoord) + ',' + str(self.ycoord) + ',' + str(self.zcoord) + ')'
|
||||
|
||||
def calculate_incident_V_I(self, G):
|
||||
"""Calculates the incident voltage and current with a long length
|
||||
transmission line not connected to the main grid from:
|
||||
http://dx.doi.org/10.1002/mop.10415
|
||||
"""Calculates the incident voltage and current with a long length transmission line not connected to the main grid from: http://dx.doi.org/10.1002/mop.10415
|
||||
|
||||
Args:
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
abstime = 0
|
||||
@@ -263,16 +243,14 @@ class TransmissionLine(Source):
|
||||
self.update_current(abstime, G)
|
||||
abstime += 0.5 * G.dt
|
||||
|
||||
# Shorten number of nodes in the transmission line before use
|
||||
# with main grid
|
||||
# Shorten number of nodes in the transmission line before use with main grid
|
||||
self.nl = self.antpos + 1
|
||||
|
||||
def update_abc(self, G):
|
||||
"""Updates absorbing boundary condition at end of the transmission line.
|
||||
|
||||
Args:
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
h = (c * G.dt - self.dl) / (c * G.dt + self.dl)
|
||||
@@ -286,8 +264,7 @@ class TransmissionLine(Source):
|
||||
|
||||
Args:
|
||||
time (float): Absolute time.
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
# Update all the voltage values along the line
|
||||
@@ -305,8 +282,7 @@ class TransmissionLine(Source):
|
||||
|
||||
Args:
|
||||
time (float): Absolute time.
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
# Update all the current values along the line
|
||||
@@ -317,18 +293,16 @@ class TransmissionLine(Source):
|
||||
self.current[self.srcpos - 1] += (c * G.dt / self.dl) * waveform.amp * waveform.calculate_value(time - 0.5 * G.dt, G.dt) * (1 / self.resistance)
|
||||
|
||||
def update_electric(self, abstime, Ex, Ey, Ez, G):
|
||||
"""Updates electric field value in the main grid from voltage value
|
||||
in the transmission line.
|
||||
"""Updates electric field value in the main grid from voltage value in the transmission line.
|
||||
|
||||
Args:
|
||||
abstime (float): Absolute time.
|
||||
Ex, Ey, Ez (memory view): numpy array of electric field values.
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
if abstime >= self.start and abstime <= self.stop:
|
||||
# Set the time of the waveform evaluation to account
|
||||
# for any delay in the start
|
||||
# Set the time of the waveform evaluation to account for any delay in the start
|
||||
time = abstime - self.start
|
||||
i = self.xcoord
|
||||
j = self.ycoord
|
||||
@@ -346,19 +320,16 @@ class TransmissionLine(Source):
|
||||
Ez[i, j, k] = - self.voltage[self.antpos] / G.dz
|
||||
|
||||
def update_magnetic(self, abstime, Hx, Hy, Hz, G):
|
||||
"""Updates current value in transmission line from magnetic field
|
||||
values in the main grid.
|
||||
"""Updates current value in transmission line from magnetic field values in the main grid.
|
||||
|
||||
Args:
|
||||
abstime (float): Absolute time.
|
||||
Hx, Hy, Hz (memory view): numpy array of magnetic field values.
|
||||
G (class): Grid class instance - holds essential parameters
|
||||
describing the model.
|
||||
G (class): Grid class instance - holds essential parameters describing the model.
|
||||
"""
|
||||
|
||||
if abstime >= self.start and abstime <= self.stop:
|
||||
# Set the time of the waveform evaluation to account
|
||||
# for any delay in the start
|
||||
# Set the time of the waveform evaluation to account for any delay in the start
|
||||
time = abstime - self.start
|
||||
i = self.xcoord
|
||||
j = self.ycoord
|
||||
@@ -375,15 +346,3 @@ class TransmissionLine(Source):
|
||||
|
||||
self.update_current(time, G)
|
||||
|
||||
|
||||
class TEMTransmissionLine(TransmissionLine):
|
||||
|
||||
def __init__(self, G):
|
||||
super().__init__(G)
|
||||
self.type_str = 'TEMTransmissionLine'
|
||||
|
||||
def update_magnetic(self, abstime, Hx, Hy, Hz, G):
|
||||
pass
|
||||
|
||||
def update_electric(self, abstime, Ex, Ey, Ez, G):
|
||||
pass
|
||||
|
在新工单中引用
屏蔽一个用户