你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
Added checks for correct source polarisation in 2D modes, & explicit setting of PEC boundaries for invariant direction in 2D modes.
这个提交包含在:
@@ -116,7 +116,7 @@ class FDTDGrid(Grid):
|
||||
self.dy = 0
|
||||
self.dz = 0
|
||||
self.dt = 0
|
||||
self.dimension = None
|
||||
self.mode = None
|
||||
self.iterations = 0
|
||||
self.timewindow = 0
|
||||
|
||||
@@ -296,9 +296,9 @@ def dispersion_analysis(G):
|
||||
minwavelength = minvelocity / results['maxfreq']
|
||||
|
||||
# Maximum spatial step
|
||||
if G.dimension == '3D':
|
||||
if '3D' in G.mode:
|
||||
delta = max(G.dx, G.dy, G.dz)
|
||||
elif G.dimension == '2D':
|
||||
elif '2D' in G.mode:
|
||||
if G.nx == 1:
|
||||
delta = max(G.dy, G.dz)
|
||||
elif G.ny == 1:
|
||||
|
@@ -97,6 +97,12 @@ def process_multicmds(multicmds, G):
|
||||
polarisation = tmp[0].lower()
|
||||
if polarisation not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
if '2D TMx' in G.mode and (polarisation == 'y' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x in 2D TMx mode')
|
||||
elif '2D TMy' in G.mode and (polarisation == 'x' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be y in 2D TMy mode')
|
||||
elif '2D TMz' in G.mode and (polarisation == 'x' or polarisation == 'y'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be z in 2D TMz mode')
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
@@ -162,6 +168,12 @@ def process_multicmds(multicmds, G):
|
||||
polarisation = tmp[0].lower()
|
||||
if polarisation not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
if '2D TMx' in G.mode and (polarisation == 'y' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x in 2D TMx mode')
|
||||
elif '2D TMy' in G.mode and (polarisation == 'x' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be y in 2D TMy mode')
|
||||
elif '2D TMz' in G.mode and (polarisation == 'x' or polarisation == 'y'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be z in 2D TMz mode')
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
@@ -218,7 +230,7 @@ def process_multicmds(multicmds, G):
|
||||
h.calculate_waveform_values(G)
|
||||
|
||||
if G.messages:
|
||||
if G.dimension == '2D':
|
||||
if G.mode == '2D':
|
||||
print('Hertzian dipole is a line source in 2D with polarity {} at {:g}m, {:g}m, {:g}m,'.format(h.polarisation, h.xcoord * G.dx, h.ycoord * G.dy, h.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(h.waveformID))
|
||||
else:
|
||||
print('Hertzian dipole with polarity {} at {:g}m, {:g}m, {:g}m,'.format(h.polarisation, h.xcoord * G.dx, h.ycoord * G.dy, h.zcoord * G.dz) + startstop + 'using waveform {} created.'.format(h.waveformID))
|
||||
@@ -237,6 +249,12 @@ def process_multicmds(multicmds, G):
|
||||
polarisation = tmp[0].lower()
|
||||
if polarisation not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
if '2D TMx' in G.mode and (polarisation == 'y' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x in 2D TMx mode')
|
||||
elif '2D TMy' in G.mode and (polarisation == 'x' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be y in 2D TMy mode')
|
||||
elif '2D TMz' in G.mode and (polarisation == 'x' or polarisation == 'y'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be z in 2D TMz mode')
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
@@ -304,6 +322,12 @@ def process_multicmds(multicmds, G):
|
||||
polarisation = tmp[0].lower()
|
||||
if polarisation not in ('x', 'y', 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x, y, or z')
|
||||
if '2D TMx' in G.mode and (polarisation == 'y' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be x in 2D TMx mode')
|
||||
elif '2D TMy' in G.mode and (polarisation == 'x' or polarisation == 'z'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be y in 2D TMy mode')
|
||||
elif '2D TMz' in G.mode and (polarisation == 'x' or polarisation == 'y'):
|
||||
raise CmdInputError("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' polarisation must be z in 2D TMz mode')
|
||||
|
||||
xcoord = G.calculate_coord('x', tmp[1])
|
||||
ycoord = G.calculate_coord('y', tmp[2])
|
||||
|
@@ -139,44 +139,32 @@ def process_singlecmds(singlecmds, G):
|
||||
if G.messages:
|
||||
print('Domain size: {:g} x {:g} x {:g}m ({:d} x {:d} x {:d} = {:g} cells)'.format(tmp[0], tmp[1], tmp[2], G.nx, G.ny, G.nz, (G.nx * G.ny * G.nz)))
|
||||
|
||||
# Estimate memory (RAM) usage
|
||||
memestimate = memory_usage(G)
|
||||
# Check if model can be built and/or run on host
|
||||
if memestimate > G.hostinfo['ram']:
|
||||
raise GeneralError('Estimated memory (RAM) required ~{} exceeds {} detected!\n'.format(human_size(memestimate), human_size(hostinfo['ram'], a_kilobyte_is_1024_bytes=True)))
|
||||
|
||||
# Check if model can be run on specified GPU if required
|
||||
if G.gpu is not None:
|
||||
if memestimate > G.gpu.totalmem:
|
||||
raise GeneralError('Estimated memory (RAM) required ~{} exceeds {} detected on specified {} - {} GPU!\n'.format(human_size(memestimate), human_size(G.gpu.totalmem, a_kilobyte_is_1024_bytes=True), G.gpu.deviceID, G.gpu.name))
|
||||
if G.messages:
|
||||
print('Estimated memory (RAM) required: ~{}'.format(human_size(memestimate)))
|
||||
|
||||
# Time step CFL limit (either 2D or 3D); switch off appropriate PMLs for 2D
|
||||
if G.nx == 1:
|
||||
G.dt = 1 / (c * np.sqrt((1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
||||
G.dimension = '2D'
|
||||
G.mode = '2D TMx'
|
||||
G.pmlthickness['x0'] = 0
|
||||
G.pmlthickness['xmax'] = 0
|
||||
elif G.ny == 1:
|
||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dz) * (1 / G.dz)))
|
||||
G.dimension = '2D'
|
||||
G.mode = '2D TMy'
|
||||
G.pmlthickness['y0'] = 0
|
||||
G.pmlthickness['ymax'] = 0
|
||||
elif G.nz == 1:
|
||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy)))
|
||||
G.dimension = '2D'
|
||||
G.mode = '2D TMz'
|
||||
G.pmlthickness['z0'] = 0
|
||||
G.pmlthickness['zmax'] = 0
|
||||
else:
|
||||
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
|
||||
G.dimension = '3D'
|
||||
G.mode = '3D'
|
||||
|
||||
# Round down time step to nearest float with precision one less than hardware maximum. Avoids inadvertently exceeding the CFL due to binary representation of floating point number.
|
||||
G.dt = round_value(G.dt, decimalplaces=d.getcontext().prec - 1)
|
||||
|
||||
if G.messages:
|
||||
print('Time step (at {} CFL limit): {:g} secs'.format(G.dimension, G.dt))
|
||||
print('Mode: {}'.format(G.mode))
|
||||
print('Time step (at CFL limit): {:g} secs'.format(G.dt))
|
||||
|
||||
# Time step stability factor
|
||||
cmd = '#time_step_stability_factor'
|
||||
@@ -213,6 +201,19 @@ def process_singlecmds(singlecmds, G):
|
||||
if G.messages:
|
||||
print('Time window: {:g} secs ({} iterations)'.format(G.timewindow, G.iterations))
|
||||
|
||||
# Estimate memory (RAM) usage
|
||||
memestimate = memory_usage(G)
|
||||
# Check if model can be built and/or run on host
|
||||
if memestimate > G.hostinfo['ram']:
|
||||
raise GeneralError('Estimated memory (RAM) required ~{} exceeds {} detected!\n'.format(human_size(memestimate), human_size(hostinfo['ram'], a_kilobyte_is_1024_bytes=True)))
|
||||
|
||||
# Check if model can be run on specified GPU if required
|
||||
if G.gpu is not None:
|
||||
if memestimate > G.gpu.totalmem:
|
||||
raise GeneralError('Estimated memory (RAM) required ~{} exceeds {} detected on specified {} - {} GPU!\n'.format(human_size(memestimate), human_size(G.gpu.totalmem, a_kilobyte_is_1024_bytes=True), G.gpu.deviceID, G.gpu.name))
|
||||
if G.messages:
|
||||
print('Estimated memory (RAM) required: ~{}'.format(human_size(memestimate)))
|
||||
|
||||
# PML
|
||||
cmd = '#pml_cells'
|
||||
if singlecmds[cmd] is not None:
|
||||
|
@@ -194,6 +194,27 @@ def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usern
|
||||
pbar.update()
|
||||
pbar.close()
|
||||
|
||||
# Add PEC boundaries to invariant direction in 2D modes
|
||||
# N.B. 2D modes are a single cell slice of 3D grid
|
||||
if '2D TMx' in G.mode:
|
||||
# Ey & Ez components
|
||||
G.ID[1,0,:,:] = 0
|
||||
G.ID[1,1,:,:] = 0
|
||||
G.ID[2,0,:,:] = 0
|
||||
G.ID[2,1,:,:] = 0
|
||||
elif '2D TMy' in G.mode:
|
||||
# Ex & Ez components
|
||||
G.ID[0,:,0,:] = 0
|
||||
G.ID[0,:,1,:] = 0
|
||||
G.ID[2,:,0,:] = 0
|
||||
G.ID[2,:,1,:] = 0
|
||||
elif '2D TMz' in G.mode:
|
||||
# Ex & Ey components
|
||||
G.ID[0,:,:,0] = 0
|
||||
G.ID[0,:,:,1] = 0
|
||||
G.ID[1,:,:,0] = 0
|
||||
G.ID[1,:,:,1] = 0
|
||||
|
||||
# Process any voltage sources (that have resistance) to create a new
|
||||
# material at the source location
|
||||
for voltagesource in G.voltagesources:
|
||||
|
在新工单中引用
屏蔽一个用户