Revert "multi cmds to functions"

This reverts commit 92bf59bc36.
这个提交包含在:
craig-warren
2016-06-12 14:06:56 +08:00
父节点 92bf59bc36
当前提交 c9c627720a
共有 5 个文件被更改,包括 822 次插入926 次删除

查看文件

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

查看文件

@@ -16,149 +16,84 @@
# 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]
@@ -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,12 +250,77 @@ 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)
@@ -355,7 +328,7 @@ def create_rx(cmdname, cmdinstance, G):
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'
@@ -611,7 +588,7 @@ def create_add_dispersion_drude(cmdname, cmdinstance, G):
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