Added checks for correct source polarisation in 2D modes, & explicit setting of PEC boundaries for invariant direction in 2D modes.

这个提交包含在:
Craig Warren
2018-05-02 14:31:06 +01:00
父节点 cc33a628b6
当前提交 dd110fd687
共有 4 个文件被更改,包括 68 次插入22 次删除

查看文件

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