Changed name of rvalue function to roundvalues. Added modification to 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.

这个提交包含在:
Craig Warren
2016-01-11 13:37:59 +00:00
父节点 d1b73caac8
当前提交 82ebb67541

查看文件

@@ -23,7 +23,7 @@ from psutil import virtual_memory
from gprMax.constants import c, floattype from gprMax.constants import c, floattype
from gprMax.exceptions import CmdInputError from gprMax.exceptions import CmdInputError
from gprMax.pml import PML, CFS from gprMax.pml import PML, CFS
from gprMax.utilities import rvalue, human_size from gprMax.utilities import roundvalue, rounddownmax, human_size
from gprMax.waveforms import Waveform from gprMax.waveforms import Waveform
@@ -114,9 +114,9 @@ def process_singlecmds(singlecmds, multicmds, G):
tmp = [float(x) for x in singlecmds[cmd].split()] tmp = [float(x) for x in singlecmds[cmd].split()]
if len(tmp) != 3: if len(tmp) != 3:
raise CmdInputError(cmd + ' requires exactly three parameters') raise CmdInputError(cmd + ' requires exactly three parameters')
G.nx = rvalue(tmp[0]/G.dx) G.nx = roundvalue(tmp[0]/G.dx)
G.ny = rvalue(tmp[1]/G.dy) G.ny = roundvalue(tmp[1]/G.dy)
G.nz = rvalue(tmp[2]/G.dz) G.nz = roundvalue(tmp[2]/G.dz)
if G.messages: if G.messages:
print('Model domain: {:.3f} x {:.3f} x {:.3f} m ({:d} x {:d} x {:d} = {:.1f} Mcells)'.format(tmp[0], tmp[1], tmp[2], G.nx, G.ny, G.nz, (G.nx * G.ny * G.nz)/1e6)) print('Model domain: {:.3f} x {:.3f} x {:.3f} m ({:d} x {:d} x {:d} = {:.1f} Mcells)'.format(tmp[0], tmp[1], tmp[2], G.nx, G.ny, G.nz, (G.nx * G.ny * G.nz)/1e6))
mem = (((G.nx + 1) * (G.ny + 1) * (G.nz + 1) * 13 * np.dtype(floattype).itemsize + (G.nx + 1) * (G.ny + 1) * (G.nz + 1) * 18) * 1.1) + 30e6 mem = (((G.nx + 1) * (G.ny + 1) * (G.nz + 1) * 13 * np.dtype(floattype).itemsize + (G.nx + 1) * (G.ny + 1) * (G.nz + 1) * 18) * 1.1) + 30e6
@@ -144,6 +144,10 @@ def process_singlecmds(singlecmds, multicmds, G):
raise CmdInputError(cmd + ' requires input values of either 2D or 3D') raise CmdInputError(cmd + ' requires input values of either 2D or 3D')
else: 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.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
# 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 = rounddownmax(G.dt)
if G.messages: if G.messages:
print('Time step: {:.3e} secs'.format(G.dt)) print('Time step: {:.3e} secs'.format(G.dt))
@@ -171,7 +175,7 @@ def process_singlecmds(singlecmds, multicmds, G):
if '.' in tmp or 'e' in tmp: if '.' in tmp or 'e' in tmp:
if float(tmp) > 0: if float(tmp) > 0:
G.timewindow = float(tmp) G.timewindow = float(tmp)
G.iterations = rvalue((float(tmp) / G.dt)) + 1 G.iterations = roundvalue((float(tmp) / G.dt)) + 1
else: else:
raise CmdInputError(cmd + ' must have a value greater than zero') raise CmdInputError(cmd + ' must have a value greater than zero')
# If number of iterations given # If number of iterations given
@@ -202,9 +206,9 @@ def process_singlecmds(singlecmds, multicmds, G):
tmp = singlecmds[cmd].split() tmp = singlecmds[cmd].split()
if len(tmp) != 3: if len(tmp) != 3:
raise CmdInputError(cmd + ' requires exactly three parameters') raise CmdInputError(cmd + ' requires exactly three parameters')
G.srcstepx = rvalue(float(tmp[0])/G.dx) G.srcstepx = roundvalue(float(tmp[0])/G.dx)
G.srcstepy = rvalue(float(tmp[1])/G.dy) G.srcstepy = roundvalue(float(tmp[1])/G.dy)
G.srcstepz = rvalue(float(tmp[2])/G.dz) G.srcstepz = roundvalue(float(tmp[2])/G.dz)
if G.messages: if G.messages:
print('All sources will step {:.3f}m, {:.3f}m, {:.3f}m for each model run.'.format(G.srcstepx * G.dx, G.srcstepy * G.dy, G.srcstepz * G.dz)) print('All sources will step {:.3f}m, {:.3f}m, {:.3f}m for each model run.'.format(G.srcstepx * G.dx, G.srcstepy * G.dy, G.srcstepz * G.dz))
@@ -215,9 +219,9 @@ def process_singlecmds(singlecmds, multicmds, G):
tmp = singlecmds[cmd].split() tmp = singlecmds[cmd].split()
if len(tmp) != 3: if len(tmp) != 3:
raise CmdInputError(cmd + ' requires exactly three parameters') raise CmdInputError(cmd + ' requires exactly three parameters')
G.rxstepx = rvalue(float(tmp[0])/G.dx) G.rxstepx = roundvalue(float(tmp[0])/G.dx)
G.rxstepy = rvalue(float(tmp[1])/G.dy) G.rxstepy = roundvalue(float(tmp[1])/G.dy)
G.rxstepz = rvalue(float(tmp[2])/G.dz) G.rxstepz = roundvalue(float(tmp[2])/G.dz)
if G.messages: if G.messages:
print('All receivers will step {:.3f}m, {:.3f}m, {:.3f}m for each model run.'.format(G.rxstepx * G.dx, G.rxstepy * G.dy, G.rxstepz * G.dz)) print('All receivers will step {:.3f}m, {:.3f}m, {:.3f}m for each model run.'.format(G.rxstepx * G.dx, G.rxstepy * G.dy, G.rxstepz * G.dz))