Changed method of setting range of number of models to run.

Changed method of appending model number to geometry and output files when running more than a single model.
这个提交包含在:
Craig Warren
2017-03-16 12:35:31 +00:00
父节点 328375323d
当前提交 a4c67f1ee3

查看文件

@@ -44,12 +44,13 @@ from gprMax.utilities import get_terminal_width, human_size, open_path_file
from gprMax.yee_cell_build import build_electric_components, build_magnetic_components from gprMax.yee_cell_build import build_electric_components, build_magnetic_components
def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace): def run_model(args, currentmodelrun, modelend, numbermodelruns, inputfile, usernamespace):
"""Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop. """Runs a model - processes the input file; builds the Yee cells; calculates update coefficients; runs main FDTD loop.
Args: Args:
args (dict): Namespace with command line arguments args (dict): Namespace with command line arguments
currentmodelrun (int): Current model run number. currentmodelrun (int): Current model run number.
modelend (int): Number of last model to run.
numbermodelruns (int): Total number of model runs. numbermodelruns (int): Total number of model runs.
inputfile (object): File object for the input file. 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. usernamespace (dict): Namespace that can be accessed by user in any Python code blocks in input file.
@@ -72,7 +73,7 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
G.inputfilename = os.path.split(inputfile.name)[1] G.inputfilename = os.path.split(inputfile.name)[1]
G.inputdirectory = os.path.dirname(os.path.abspath(inputfile.name)) G.inputdirectory = os.path.dirname(os.path.abspath(inputfile.name))
inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, numbermodelruns, inputfile.name) inputfilestr = '\n--- Model {}/{}, input file: {}'.format(currentmodelrun, modelend, inputfile.name)
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL) print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
# Add the current model run to namespace that can be accessed by user in any Python code blocks in input file # Add the current model run to namespace that can be accessed by user in any Python code blocks in input file
@@ -183,7 +184,7 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
# If geometry information to be reused between model runs # If geometry information to be reused between model runs
else: else:
inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, numbermodelruns, inputfile.name) inputfilestr = '\n--- Model {}/{}, input file (not re-processed, i.e. geometry fixed): {}'.format(currentmodelrun, modelend, inputfile.name)
print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL) print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_width() - 1 - len(inputfilestr))) + Style.RESET_ALL)
# Clear arrays for field components # Clear arrays for field components
@@ -197,7 +198,7 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0: if G.srcsteps[0] != 0 or G.srcsteps[1] != 0 or G.srcsteps[2] != 0:
for source in itertools.chain(G.hertziandipoles, G.magneticdipoles): for source in itertools.chain(G.hertziandipoles, G.magneticdipoles):
if currentmodelrun == 1: if currentmodelrun == 1:
if source.xcoord + G.srcsteps[0] * (numbermodelruns - 1) < 0 or source.xcoord + G.srcsteps[0] * (numbermodelruns - 1) > G.nx or source.ycoord + G.srcsteps[1] * (numbermodelruns - 1) < 0 or source.ycoord + G.srcsteps[1] * (numbermodelruns - 1) > G.ny or source.zcoord + G.srcsteps[2] * (numbermodelruns - 1) < 0 or source.zcoord + G.srcsteps[2] * (numbermodelruns - 1) > G.nz: 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.') raise GeneralError('Source(s) will be stepped to a position outside the domain.')
source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0] source.xcoord = source.xcoordorigin + (currentmodelrun - 1) * G.srcsteps[0]
source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1] source.ycoord = source.ycoordorigin + (currentmodelrun - 1) * G.srcsteps[1]
@@ -205,21 +206,24 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0: if G.rxsteps[0] != 0 or G.rxsteps[1] != 0 or G.rxsteps[2] != 0:
for receiver in G.rxs: for receiver in G.rxs:
if currentmodelrun == 1: if currentmodelrun == 1:
if receiver.xcoord + G.rxsteps[0] * (numbermodelruns - 1) < 0 or receiver.xcoord + G.rxsteps[0] * (numbermodelruns - 1) > G.nx or receiver.ycoord + G.rxsteps[1] * (numbermodelruns - 1) < 0 or receiver.ycoord + G.rxsteps[1] * (numbermodelruns - 1) > G.ny or receiver.zcoord + G.rxsteps[2] * (numbermodelruns - 1) < 0 or receiver.zcoord + G.rxsteps[2] * (numbermodelruns - 1) > G.nz: 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.') raise GeneralError('Receiver(s) will be stepped to a position outside the domain.')
receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0] receiver.xcoord = receiver.xcoordorigin + (currentmodelrun - 1) * G.rxsteps[0]
receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1] receiver.ycoord = receiver.ycoordorigin + (currentmodelrun - 1) * G.rxsteps[1]
receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2] receiver.zcoord = receiver.zcoordorigin + (currentmodelrun - 1) * G.rxsteps[2]
# Used for naming geometry and output files
appendmodelnumber = '' if numbermodelruns == 1 and not args.task and not args.restart else str(currentmodelrun)
# Write files for any geometry views and geometry object outputs # Write files for any geometry views and geometry object outputs
if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only: if not (G.geometryviews or G.geometryobjectswrite) and args.geometry_only:
print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL) print(Fore.RED + '\nWARNING: No geometry views or geometry objects to output found.' + Style.RESET_ALL)
if G.geometryviews: if G.geometryviews:
print() print()
for i, geometryview in enumerate(G.geometryviews): for i, geometryview in enumerate(G.geometryviews):
geometryview.set_filename(currentmodelrun, numbermodelruns, G) geometryview.set_filename(appendmodelnumber, G)
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=G.tqdmdisable) 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=G.tqdmdisable)
geometryview.write_vtk(currentmodelrun, numbermodelruns, G, pbar) geometryview.write_vtk(G, pbar)
pbar.close() pbar.close()
if G.geometryobjectswrite: if G.geometryobjectswrite:
for i, geometryobject in enumerate(G.geometryobjectswrite): for i, geometryobject in enumerate(G.geometryobjectswrite):
@@ -235,18 +239,15 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
else: else:
# Prepare any snapshot files # Prepare any snapshot files
for snapshot in G.snapshots: for snapshot in G.snapshots:
snapshot.prepare_vtk_imagedata(currentmodelrun, numbermodelruns, G) snapshot.prepare_vtk_imagedata(appendmodelnumber, G)
# Output filename # Output filename
inputfileparts = os.path.splitext(os.path.join(G.inputdirectory, G.inputfilename)) inputfileparts = os.path.splitext(os.path.join(G.inputdirectory, G.inputfilename))
if numbermodelruns == 1: outputfile = inputfileparts[0] + appendmodelnumber + '.out'
outputfile = inputfileparts[0] + '.out'
else:
outputfile = inputfileparts[0] + str(currentmodelrun) + '.out'
print('\nOutput file: {}\n'.format(outputfile)) print('\nOutput file: {}\n'.format(outputfile))
# Main FDTD solving functions for either CPU or GPU # Main FDTD solving functions for either CPU or GPU
tsolve = solve_cpu(currentmodelrun, numbermodelruns, G) tsolve = solve_cpu(currentmodelrun, modelend, G)
# Write an output file in HDF5 format # Write an output file in HDF5 format
write_hdf5_outputfile(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G) write_hdf5_outputfile(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
@@ -262,12 +263,12 @@ def run_model(args, currentmodelrun, numbermodelruns, inputfile, usernamespace):
return tsolve return tsolve
def solve_cpu(currentmodelrun, numbermodelruns, G): def solve_cpu(currentmodelrun, modelend, G):
"""Solving using FDTD method on CPU. Parallelised using Cython (OpenMP) for electric and magnetic field updates, and PML updates. """Solving using FDTD method on CPU. Parallelised using Cython (OpenMP) for electric and magnetic field updates, and PML updates.
Args: Args:
currentmodelrun (int): Current model run number. currentmodelrun (int): Current model run number.
numbermodelruns (int): Total number of model runs. modelend (int): Number of last model to run.
G (class): Grid class instance - holds essential parameters describing the model. G (class): Grid class instance - holds essential parameters describing the model.
Returns: Returns:
@@ -276,7 +277,7 @@ def solve_cpu(currentmodelrun, numbermodelruns, G):
tsolvestart = perf_counter() tsolvestart = perf_counter()
for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(numbermodelruns), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable): for iteration in tqdm(range(G.iterations), desc='Running simulation, model ' + str(currentmodelrun) + '/' + str(modelend), ncols=get_terminal_width() - 1, file=sys.stdout, disable=G.tqdmdisable):
# Store field component values for every receiver and transmission line # Store field component values for every receiver and transmission line
store_outputs(iteration, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G) store_outputs(iteration, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)