你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 07:24:19 +08:00
refactor methods
这个提交包含在:
@@ -86,13 +86,65 @@ class ModelBuildRun:
|
|||||||
self.model_config = model_config
|
self.model_config = model_config
|
||||||
self.G = solver.get_G()
|
self.G = solver.get_G()
|
||||||
|
|
||||||
def tm_grid_update(self):
|
def build(self):
|
||||||
if '2D TMx' in self.model_config.mode:
|
"""Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.
|
||||||
self.G.tmx()
|
|
||||||
elif '2D TMy' in self.model_config.mode:
|
Args:
|
||||||
self.G.tmy()
|
args (dict): Namespace with command line arguments
|
||||||
elif '2D TMz' in self.model_config.mode:
|
currentmodelrun (int): Current model run number.
|
||||||
self.G.tmz()
|
modelend (int): Number of last model to run.
|
||||||
|
numbermodelruns (int): Total number of model runs.
|
||||||
|
inputfile (object): File object for the input file.
|
||||||
|
usernamespace (dict): Namespace that can be accessed by user
|
||||||
|
in any Python code blocks in input file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tsolve (int): Length of time (seconds) of main FDTD calculations
|
||||||
|
"""
|
||||||
|
# Monitor memory usage
|
||||||
|
p = psutil.Process()
|
||||||
|
|
||||||
|
# Normal model reading/building process; bypassed if geometry information to be reused
|
||||||
|
if not self.sim_config.geometry_fixed:
|
||||||
|
self.build_geometry()
|
||||||
|
else:
|
||||||
|
self.reuse_geometry()
|
||||||
|
|
||||||
|
# Adjust position of simple sources and receivers if required
|
||||||
|
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
|
||||||
|
for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
|
||||||
|
if currentmodelrun == 1:
|
||||||
|
if source.xcoord + G.srcsteps[0] * modelend < 0 or source.xcoord + G.srcsteps[0] * modelend > G.nx or source.ycoord + G.srcsteps[1] * modelend < 0 or source.ycoord + G.srcsteps[1] * modelend > G.ny or source.zcoord + G.srcsteps[2] * modelend < 0 or source.zcoord + G.srcsteps[2] * modelend > G.nz:
|
||||||
|
raise GeneralError('Source(s) will be stepped to a position outside the domain.')
|
||||||
|
source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0]
|
||||||
|
source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1]
|
||||||
|
source.zcoord = source.zcoordorigin + (currentmodelrun - 1) * G.srcsteps[2]
|
||||||
|
if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
|
||||||
|
for receiver in G.rxs:
|
||||||
|
if currentmodelrun == 1:
|
||||||
|
if receiver.xcoord + G.rxsteps[0] * modelend < 0 or receiver.xcoord + G.rxsteps[0] * modelend > G.nx or receiver.ycoord + G.rxsteps[1] * modelend < 0 or receiver.ycoord + G.rxsteps[1] * modelend > G.ny or receiver.zcoord + G.rxsteps[2] * modelend < 0 or receiver.zcoord + G.rxsteps[2] * modelend > G.nz:
|
||||||
|
raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
|
||||||
|
receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0]
|
||||||
|
receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1]
|
||||||
|
receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]
|
||||||
|
|
||||||
|
# Write files for any geometry views and geometry object outputs
|
||||||
|
if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only and config.general['messages']:
|
||||||
|
print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
|
||||||
|
if config.general['messages']: print()
|
||||||
|
for i, geometryview in enumerate(G.geometryviews):
|
||||||
|
geometryview.set_filename(appendmodelnumber)
|
||||||
|
pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
|
geometryview.write_vtk(G, pbar)
|
||||||
|
pbar.close()
|
||||||
|
for i, geometryobject in enumerate(G.geometryobjectswrite):
|
||||||
|
pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
|
geometryobject.write_hdf5(G, pbar)
|
||||||
|
pbar.close()
|
||||||
|
|
||||||
|
# If only writing geometry information
|
||||||
|
if args.geometry_only:
|
||||||
|
tsolve = 0
|
||||||
|
|
||||||
def build_geometry(self):
|
def build_geometry(self):
|
||||||
model_config = self.model_config
|
model_config = self.model_config
|
||||||
@@ -102,46 +154,18 @@ class ModelBuildRun:
|
|||||||
printer = Printer(sim_config)
|
printer = Printer(sim_config)
|
||||||
printer.print(model_config.next_model)
|
printer.print(model_config.next_model)
|
||||||
|
|
||||||
# api for multiple scenes / model runs
|
scene = self.build_scene()
|
||||||
try:
|
|
||||||
scene = model_config.get_scene()
|
|
||||||
# process using hashcommands
|
|
||||||
except AttributeError:
|
|
||||||
scene = Scene()
|
|
||||||
# parse the input file into user objects and add them to the scene
|
|
||||||
scene = parse_hash_commands(args, usernamespace, appendmodelnumber, G, scene)
|
|
||||||
|
|
||||||
# Creates the internal simulation objects.
|
|
||||||
scene.create_internal_objects(G)
|
|
||||||
|
|
||||||
# print PML information
|
# print PML information
|
||||||
printer.print(pml_information(G))
|
printer.print(pml_information(G))
|
||||||
|
|
||||||
# build the PMLS
|
self.build_pmls()
|
||||||
pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
self.build_components()
|
||||||
|
|
||||||
for pml_id, thickness in G.pmlthickness.items():
|
|
||||||
build_pml(G, pml_id, thickness)
|
|
||||||
pbar.update()
|
|
||||||
pbar.close()
|
|
||||||
|
|
||||||
# Build the model, i.e. set the material properties (ID) for every edge
|
|
||||||
# of every Yee cell
|
|
||||||
printer.print('')
|
|
||||||
pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
|
||||||
build_electric_components(G.solid, G.rigidE, G.ID, G)
|
|
||||||
pbar.update()
|
|
||||||
build_magnetic_components(G.solid, G.rigidH, G.ID, G)
|
|
||||||
pbar.update()
|
|
||||||
pbar.close()
|
|
||||||
|
|
||||||
# update grid for tm modes
|
# update grid for tm modes
|
||||||
tm_grid_update(model_config)
|
self.tm_grid_update()
|
||||||
|
|
||||||
# Process any voltage sources (that have resistance) to create a new
|
self.update_voltage_source_materials()
|
||||||
# material at the source location
|
|
||||||
for voltagesource in G.voltagesources:
|
|
||||||
voltagesource.create_material(G)
|
|
||||||
|
|
||||||
# Initialise arrays of update coefficients to pass to update functions
|
# Initialise arrays of update coefficients to pass to update functions
|
||||||
G.initialise_std_update_coeff_arrays()
|
G.initialise_std_update_coeff_arrays()
|
||||||
@@ -206,66 +230,53 @@ class ModelBuildRun:
|
|||||||
printer.print(Fore.GREEN + '{} {}\n'.format(model_config.inputfilestr, '-' * (get_terminal_width() - 1 - len(model_config.inputfilestr))) + Style.RESET_ALL)
|
printer.print(Fore.GREEN + '{} {}\n'.format(model_config.inputfilestr, '-' * (get_terminal_width() - 1 - len(model_config.inputfilestr))) + Style.RESET_ALL)
|
||||||
self.G.reset_fields()
|
self.G.reset_fields()
|
||||||
|
|
||||||
|
def tm_grid_update(self):
|
||||||
|
if '2D TMx' in self.model_config.mode:
|
||||||
|
self.G.tmx()
|
||||||
|
elif '2D TMy' in self.model_config.mode:
|
||||||
|
self.G.tmy()
|
||||||
|
elif '2D TMz' in self.model_config.mode:
|
||||||
|
self.G.tmz()
|
||||||
|
|
||||||
def build(self):
|
def build_scene(self):
|
||||||
"""Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.
|
# api for multiple scenes / model runs
|
||||||
|
try:
|
||||||
|
scene = self.model_config.get_scene()
|
||||||
|
# process using hashcommands
|
||||||
|
except AttributeError:
|
||||||
|
scene = Scene()
|
||||||
|
# parse the input file into user objects and add them to the scene
|
||||||
|
scene = parse_hash_commands(args, usernamespace, appendmodelnumber, G, scene)
|
||||||
|
|
||||||
Args:
|
# Creates the internal simulation objects.
|
||||||
args (dict): Namespace with command line arguments
|
scene.create_internal_objects(G)
|
||||||
currentmodelrun (int): Current model run number.
|
return scene
|
||||||
modelend (int): Number of last model to run.
|
|
||||||
numbermodelruns (int): Total number of model runs.
|
|
||||||
inputfile (object): File object for the input file.
|
|
||||||
usernamespace (dict): Namespace that can be accessed by user
|
|
||||||
in any Python code blocks in input file.
|
|
||||||
|
|
||||||
Returns:
|
def build_pmls(self):
|
||||||
tsolve (int): Length of time (seconds) of main FDTD calculations
|
# build the PMLS
|
||||||
"""
|
pbar = tqdm(total=sum(1 for value in G.pmlthickness.values() if value > 0), desc='Building PML boundaries', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
# Monitor memory usage
|
|
||||||
p = psutil.Process()
|
|
||||||
|
|
||||||
# Normal model reading/building process; bypassed if geometry information to be reused
|
for pml_id, thickness in G.pmlthickness.items():
|
||||||
if not self.sim_config.geometry_fixed:
|
build_pml(G, pml_id, thickness)
|
||||||
self.build_geometry()
|
pbar.update()
|
||||||
else:
|
|
||||||
self.reuse_geometry()
|
|
||||||
|
|
||||||
# Adjust position of simple sources and receivers if required
|
|
||||||
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
|
|
||||||
for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
|
|
||||||
if currentmodelrun == 1:
|
|
||||||
if source.xcoord + G.srcsteps[0] * modelend < 0 or source.xcoord + G.srcsteps[0] * modelend > G.nx or source.ycoord + G.srcsteps[1] * modelend < 0 or source.ycoord + G.srcsteps[1] * modelend > G.ny or source.zcoord + G.srcsteps[2] * modelend < 0 or source.zcoord + G.srcsteps[2] * modelend > G.nz:
|
|
||||||
raise GeneralError('Source(s) will be stepped to a position outside the domain.')
|
|
||||||
source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0]
|
|
||||||
source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1]
|
|
||||||
source.zcoord = source.zcoordorigin + (currentmodelrun - 1) * G.srcsteps[2]
|
|
||||||
if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
|
|
||||||
for receiver in G.rxs:
|
|
||||||
if currentmodelrun == 1:
|
|
||||||
if receiver.xcoord + G.rxsteps[0] * modelend < 0 or receiver.xcoord + G.rxsteps[0] * modelend > G.nx or receiver.ycoord + G.rxsteps[1] * modelend < 0 or receiver.ycoord + G.rxsteps[1] * modelend > G.ny or receiver.zcoord + G.rxsteps[2] * modelend < 0 or receiver.zcoord + G.rxsteps[2] * modelend > G.nz:
|
|
||||||
raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
|
|
||||||
receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0]
|
|
||||||
receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1]
|
|
||||||
receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]
|
|
||||||
|
|
||||||
# Write files for any geometry views and geometry object outputs
|
|
||||||
if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only and config.general['messages']:
|
|
||||||
print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
|
|
||||||
if config.general['messages']: print()
|
|
||||||
for i, geometryview in enumerate(G.geometryviews):
|
|
||||||
geometryview.set_filename(appendmodelnumber)
|
|
||||||
pbar = tqdm(total=geometryview.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry view file {}/{}, {}'.format(i + 1, len(G.geometryviews), os.path.split(geometryview.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
|
||||||
geometryview.write_vtk(G, pbar)
|
|
||||||
pbar.close()
|
|
||||||
for i, geometryobject in enumerate(G.geometryobjectswrite):
|
|
||||||
pbar = tqdm(total=geometryobject.datawritesize, unit='byte', unit_scale=True, desc='Writing geometry object file {}/{}, {}'.format(i + 1, len(G.geometryobjectswrite), os.path.split(geometryobject.filename)[1]), ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
|
||||||
geometryobject.write_hdf5(G, pbar)
|
|
||||||
pbar.close()
|
pbar.close()
|
||||||
|
|
||||||
# If only writing geometry information
|
def build_components(self):
|
||||||
if args.geometry_only:
|
# Build the model, i.e. set the material properties (ID) for every edge
|
||||||
tsolve = 0
|
# of every Yee cell
|
||||||
|
printer.print('')
|
||||||
|
pbar = tqdm(total=2, desc='Building main grid', ncols=get_terminal_width() - 1, file=sys.stdout, disable=not config.general['progressbars'])
|
||||||
|
build_electric_components(G.solid, G.rigidE, G.ID, G)
|
||||||
|
pbar.update()
|
||||||
|
build_magnetic_components(G.solid, G.rigidH, G.ID, G)
|
||||||
|
pbar.update()
|
||||||
|
pbar.close()
|
||||||
|
|
||||||
|
def update_voltage_source_materials(self):
|
||||||
|
# Process any voltage sources (that have resistance) to create a new
|
||||||
|
# material at the source location
|
||||||
|
for voltagesource in G.voltagesources:
|
||||||
|
voltagesource.create_material(G)
|
||||||
|
|
||||||
|
|
||||||
def run_model(self):
|
def run_model(self):
|
||||||
|
在新工单中引用
屏蔽一个用户