Added error check for when model could use more RAM than available.

这个提交包含在:
Craig Warren
2016-08-04 15:59:34 +01:00
父节点 3c03ebbd36
当前提交 f00cf43d14

查看文件

@@ -19,11 +19,12 @@
import os import os
import psutil import psutil
import decimal as d import decimal as d
import sys
import numpy as np import numpy as np
from gprMax.constants import c, floattype from gprMax.constants import c, floattype
from gprMax.exceptions import CmdInputError from gprMax.exceptions import CmdInputError, GeneralError
from gprMax.utilities import round_value, human_size from gprMax.utilities import round_value, human_size
from gprMax.waveforms import Waveform from gprMax.waveforms import Waveform
@@ -112,33 +113,38 @@ def process_singlecmds(singlecmds, G):
raise CmdInputError(cmd + ' requires at least one cell in every dimension') raise CmdInputError(cmd + ' requires at least one cell in every dimension')
if G.messages: 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))) 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)))
# Guesstimate at memory usage
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 # Estimate memory (RAM) usage
print('Memory (RAM) usage: ~{} required, {} available'.format(human_size(mem), human_size(psutil.virtual_memory().total))) if G.messages:
# Currently this is a pretty loose estimate but seems to match reasonably with memory usage reported when model completes.
memestimate = (((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
print('Memory (RAM) usage: ~{} required, {} available'.format(human_size(memestimate), human_size(psutil.virtual_memory().total)))
if memestimate > psutil.virtual_memory().total:
raise GeneralError('Estimated memory (RAM) required ~{} exceeds {} available!\n'.format(human_size(memestimate), human_size(psutil.virtual_memory().total)))
# Time step CFL limit (use either 2D or 3D) and default PML thickness # Time step CFL limit (use either 2D or 3D) and default PML thickness
if G.nx == 1: if G.nx == 1:
G.dt = 1 / (c * np.sqrt((1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz))) G.dt = 1 / (c * np.sqrt((1 / G.dy) * (1 / G.dy) + (1 / G.dz) * (1 / G.dz)))
G.dtlimit = '2D' gridtype = '2D'
G.pmlthickness = (0, G.pmlthickness, G.pmlthickness, 0, G.pmlthickness, G.pmlthickness) G.pmlthickness = (0, G.pmlthickness, G.pmlthickness, 0, G.pmlthickness, G.pmlthickness)
elif G.ny == 1: elif G.ny == 1:
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dz) * (1 / G.dz))) G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dz) * (1 / G.dz)))
G.dtlimit = '2D' gridtype = '2D'
G.pmlthickness = (G.pmlthickness, 0, G.pmlthickness, G.pmlthickness, 0, G.pmlthickness) G.pmlthickness = (G.pmlthickness, 0, G.pmlthickness, G.pmlthickness, 0, G.pmlthickness)
elif G.nz == 1: elif G.nz == 1:
G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy))) G.dt = 1 / (c * np.sqrt((1 / G.dx) * (1 / G.dx) + (1 / G.dy) * (1 / G.dy)))
G.dtlimit = '2D' gridtype = '2D'
G.pmlthickness = (G.pmlthickness, G.pmlthickness, 0, G.pmlthickness, G.pmlthickness, 0) G.pmlthickness = (G.pmlthickness, G.pmlthickness, 0, G.pmlthickness, G.pmlthickness, 0)
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)))
G.dtlimit = '3D' gridtype = '3D'
G.pmlthickness = (G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness) G.pmlthickness = (G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness, G.pmlthickness)
# 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. # 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) G.dt = round_value(G.dt, decimalplaces=d.getcontext().prec - 1)
if G.messages: if G.messages:
print('Time step (at {} CFL limit): {:g} secs'.format(G.dtlimit, G.dt)) print('Time step (at {} CFL limit): {:g} secs'.format(gridtype, G.dt))
# Time step stability factor # Time step stability factor
cmd = '#time_step_stability_factor' cmd = '#time_step_stability_factor'