Fixed regression of timestep calculation.

这个提交包含在:
Craig Warren
2019-12-09 17:08:51 +00:00
父节点 25c64fec85
当前提交 2c5afad69b
共有 2 个文件被更改,包括 63 次插入107 次删除

查看文件

@@ -55,13 +55,56 @@ class UserObjectSingle:
for k, v in kwargs.items(): for k, v in kwargs.items():
setattr(self.props, k, v) setattr(self.props, k, v)
def __str__(self):
pass
def create(self, grid, uip): def create(self, grid, uip):
pass pass
class Messages(UserObjectSingle):
"""Allows you to control the amount of information displayed on screen
when gprMax is run
:param yn: Whether information should be displayed.
:type yn: bool, optional
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 0
def create(self, G, uip):
try:
yn = self.kwargs['yn']
except KeyError:
raise CmdInputError(self.__str__() + ' requires exactly one parameter')
if yn.lower() == 'y':
config.sim_config.general['messages'] = True
elif yn.lower() == 'n':
config.sim_config.general['messages'] = False
else:
raise CmdInputError(self.__str__() + ' requires input values of either y or n')
class Title(UserObjectSingle):
"""Allows you to include a title for your model.
:param name: Simulation title.
:type name: str, optional
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 1
def create(self, G, uip):
try:
title = self.kwargs['name']
G.title = title
log.info(f'Model title: {G.title}')
except KeyError:
pass
class Domain(UserObjectSingle): class Domain(UserObjectSingle):
"""Allows you to specify the size of the model. """Allows you to specify the size of the model.
@@ -71,15 +114,7 @@ class Domain(UserObjectSingle):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 2 self.order = 3
def __str__(self):
try:
s = f"#domain: {self.kwargs['p1'][0]} {self.kwargs['p1'][1]} {self.kwargs['p1'][2]}"
except KeyError:
log.exception('error message')
return s
def create(self, G, uip): def create(self, G, uip):
try: try:
@@ -94,23 +129,20 @@ class Domain(UserObjectSingle):
# Calculate time step at CFL limit; switch off appropriate PMLs for 2D # Calculate time step at CFL limit; switch off appropriate PMLs for 2D
if G.nx == 1: if G.nx == 1:
G.calculate_dt()
G.mode = '2D TMx' G.mode = '2D TMx'
G.pmlthickness['x0'] = 0 G.pmlthickness['x0'] = 0
G.pmlthickness['xmax'] = 0 G.pmlthickness['xmax'] = 0
elif G.ny == 1: elif G.ny == 1:
G.calculate_dt()
G.mode = '2D TMy' G.mode = '2D TMy'
G.pmlthickness['y0'] = 0 G.pmlthickness['y0'] = 0
G.pmlthickness['ymax'] = 0 G.pmlthickness['ymax'] = 0
elif G.nz == 1: elif G.nz == 1:
G.calculate_dt()
G.mode = '2D TMz' G.mode = '2D TMz'
G.pmlthickness['z0'] = 0 G.pmlthickness['z0'] = 0
G.pmlthickness['zmax'] = 0 G.pmlthickness['zmax'] = 0
else: else:
G.calculate_dt()
G.mode = '3D' G.mode = '3D'
G.calculate_dt()
log.info(f'Mode: {G.mode}') log.info(f'Mode: {G.mode}')
log.info(f'Time step (at CFL limit): {G.dt:g} secs') log.info(f'Time step (at CFL limit): {G.dt:g} secs')
@@ -126,15 +158,7 @@ class Discretisation(UserObjectSingle):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 1 self.order = 2
def __str__(self):
try:
s = f"#dx_dy_dz: {self.kwargs['p1'][0]} {self.kwargs['p1'][1]} {self.kwargs['p1'][2]}"
except KeyError:
log.exception('error message')
return s
def create(self, G, uip): def create(self, G, uip):
try: try:
@@ -166,17 +190,6 @@ class TimeWindow(UserObjectSingle):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 4 self.order = 4
def __str__(self):
try:
s = f"#time_window: {self.kwargs['time']}"
except KeyError:
try:
s = f"#time_window: {self.kwargs['iterations']}"
except KeyError:
log.exception('time window error')
return s
def create(self, G, uip): def create(self, G, uip):
# If number of iterations given # If number of iterations given
# The +/- 1 used in calculating the number of iterations is to account for # The +/- 1 used in calculating the number of iterations is to account for
@@ -204,60 +217,6 @@ class TimeWindow(UserObjectSingle):
log.info(f'Time window: {G.timewindow:g} secs ({G.iterations} iterations)') log.info(f'Time window: {G.timewindow:g} secs ({G.iterations} iterations)')
class Messages(UserObjectSingle):
"""Allows you to control the amount of information displayed on screen
when gprMax is run
:param yn: Whether information should be displayed.
:type yn: bool, optional
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 0
def __str__(self):
try:
s = '#messages: {}'.format(self.kwargs['yn'])
except KeyError:
log.exception('messages problem')
def create(self, G, uip):
try:
yn = self.kwargs['yn']
except KeyError:
raise CmdInputError(self.__str__() + ' requires exactly one parameter')
if yn.lower() == 'y':
config.general['messages'] = True
elif yn.lower() == 'n':
config.general['messages'] = False
else:
raise CmdInputError(self.__str__() + ' requires input values of either y or n')
class Title(UserObjectSingle):
"""Allows you to include a title for your model.
:param name: Simulation title.
:type name: str, optional
"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.order = 5
def create(self, G, uip):
# Title
try:
title = self.kwargs['name']
G.title = title
except KeyError:
pass
log.info(f'Model title: {G.title}')
class NumThreads(UserObjectSingle): class NumThreads(UserObjectSingle):
"""Allows you to control how many OpenMP threads (usually the number of """Allows you to control how many OpenMP threads (usually the number of
physical CPU cores available) are used when running the model. physical CPU cores available) are used when running the model.
@@ -270,12 +229,6 @@ class NumThreads(UserObjectSingle):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 6 self.order = 6
def __str__(self):
try:
return f"#num_threads: {self.kwargs['n']}"
except KeyError:
return '#num_threads:'
def create(self, G, uip): def create(self, G, uip):
try: try:
n = self.kwargs['n'] n = self.kwargs['n']
@@ -298,12 +251,6 @@ class TimeStepStabilityFactor(UserObjectSingle):
super().__init__(**kwargs) super().__init__(**kwargs)
self.order = 7 self.order = 7
def __str__(self):
try:
return f"#time_step_stability_factor: {self.kwargs['f']}"
except KeyError:
return '#time_step_stability_factor:'
def create(self, G, uip): def create(self, G, uip):
try: try:
f = self.kwargs['f'] f = self.kwargs['f']
@@ -313,6 +260,7 @@ class TimeStepStabilityFactor(UserObjectSingle):
if f <= 0 or f > 1: if f <= 0 or f > 1:
raise CmdInputError(self.__str__() + ' requires the value of the time step stability factor to be between zero and one') raise CmdInputError(self.__str__() + ' requires the value of the time step stability factor to be between zero and one')
G.dt = G.dt * f G.dt = G.dt * f
log.info(f'Time step (modified): {G.dt:g} secs') log.info(f'Time step (modified): {G.dt:g} secs')
@@ -344,7 +292,6 @@ class PMLCells(UserObjectSingle):
def create(self, G, uip): def create(self, G, uip):
try: try:
thickness = self.kwargs['thickness'] thickness = self.kwargs['thickness']
for key in G.pmlthickness.keys(): for key in G.pmlthickness.keys():
G.pmlthickness[key] = int(thickness) G.pmlthickness[key] = int(thickness)

查看文件

@@ -44,6 +44,7 @@ class FDTDGrid:
def __init__(self): def __init__(self):
self.title = '' self.title = ''
self.name = 'main_grid' self.name = 'main_grid'
self.mem_use = 0
self.nx = 0 self.nx = 0
self.ny = 0 self.ny = 0
@@ -273,10 +274,18 @@ class FDTDGrid:
def calculate_dt(self): def calculate_dt(self):
"""Calculate time step at the CFL limit.""" """Calculate time step at the CFL limit."""
self.dt = (1 / (config.sim_config.em_consts['c'] * np.sqrt( if self.mode == '2D TMx':
(1 / self.dx) * (1 / self.dx) + self.dt = 1 / (config.sim_config.em_consts['c'] *
(1 / self.dy) * (1 / self.dy) + np.sqrt((1 / self.dy**2) + (1 / self.dz**2)))
(1 / self.dz) * (1 / self.dz)))) elif self.mode == '2D TMy':
self.dt = 1 / (config.sim_config.em_consts['c'] *
np.sqrt((1 / self.dx**2) + (1 / self.dz**2)))
elif self.mode == '2D TMz':
self.dt = 1 / (config.sim_config.em_consts['c'] *
np.sqrt((1 / self.dx**2) + (1 / self.dy**2)))
else:
self.dt = 1 / (config.sim_config.em_consts['c'] *
np.sqrt((1 / self.dx**2) + (1 / self.dy**2) + (1 / self.dz**2)))
# Round down time step to nearest float with precision one less than # Round down time step to nearest float with precision one less than
# hardware maximum. Avoids inadvertently exceeding the CFL due to # hardware maximum. Avoids inadvertently exceeding the CFL due to