Formatting and comments update.

这个提交包含在:
Craig Warren
2016-08-04 12:08:12 +01:00
父节点 35d0efeb40
当前提交 a39dcd3d98

查看文件

@@ -33,7 +33,7 @@ from ._version import __version__
from .constants import c, e0, m0, z0 from .constants import c, e0, m0, z0
from .exceptions import GeneralError from .exceptions import GeneralError
from .fields_update import update_electric, update_magnetic, update_electric_dispersive_multipole_A, update_electric_dispersive_multipole_B, update_electric_dispersive_1pole_A, update_electric_dispersive_1pole_B from .fields_update import update_electric, update_magnetic, update_electric_dispersive_multipole_A, update_electric_dispersive_multipole_B, update_electric_dispersive_1pole_A, update_electric_dispersive_1pole_B
from .grid import FDTDGrid, dispersion_check, Ix, Iy, Iz from .grid import FDTDGrid, dispersion_check
from .input_cmds_geometry import process_geometrycmds from .input_cmds_geometry import process_geometrycmds
from .input_cmds_file import process_python_include_code, write_processed_file, check_cmd_names from .input_cmds_file import process_python_include_code, write_processed_file, check_cmd_names
from .input_cmds_multiuse import process_multicmds from .input_cmds_multiuse import process_multicmds
@@ -69,7 +69,7 @@ def main():
def api(inputfile, n=1, mpi=False, benchmark=False, geometry_only=False, geometry_fixed=False, write_processed=False, opt_taguchi=False): def api(inputfile, n=1, mpi=False, benchmark=False, geometry_only=False, geometry_fixed=False, write_processed=False, opt_taguchi=False):
"""If installed as a module this is the entry point.""" """If installed as a module this is the entry point."""
class ImportArguments: class ImportArguments:
pass pass
@@ -89,11 +89,11 @@ def api(inputfile, n=1, mpi=False, benchmark=False, geometry_only=False, geometr
def run_main(args): def run_main(args):
"""Top-level function that controls what mode of simulation (standard/optimsation/benchmark etc...) is run. """Top-level function that controls what mode of simulation (standard/optimsation/benchmark etc...) is run.
Args: Args:
args (dict): Namespace with input arguments from command line or api. args (dict): Namespace with input arguments from command line or api.
""" """
numbermodelruns = args.n numbermodelruns = args.n
inputdirectory = os.path.dirname(os.path.abspath(args.inputfile)) inputdirectory = os.path.dirname(os.path.abspath(args.inputfile))
inputfile = os.path.abspath(os.path.join(inputdirectory, os.path.basename(args.inputfile))) inputfile = os.path.abspath(os.path.join(inputdirectory, os.path.basename(args.inputfile)))
@@ -125,7 +125,7 @@ def run_main(args):
else: else:
run_std_sim(args, numbermodelruns, inputfile, usernamespace) run_std_sim(args, numbermodelruns, inputfile, usernamespace)
print('\nSimulation completed.\n{}\n'.format(68*'*')) print('\nSimulation completed.\n{}\n'.format(68 * '*'))
def run_std_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None): def run_std_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None):
@@ -141,7 +141,7 @@ def run_std_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None)
tsimstart = perf_counter() tsimstart = perf_counter()
for modelrun in range(1, numbermodelruns + 1): for modelrun in range(1, numbermodelruns + 1):
if optparams: # If Taguchi optimistaion, add specific value for each parameter to optimise for each experiment to user accessible namespace if optparams: # If Taguchi optimistaion, add specific value for each parameter to optimise for each experiment to user accessible namespace
tmp = {} tmp = {}
tmp.update((key, value[modelrun - 1]) for key, value in optparams.items()) tmp.update((key, value[modelrun - 1]) for key, value in optparams.items())
modelusernamespace = usernamespace.copy() modelusernamespace = usernamespace.copy()
@@ -165,13 +165,14 @@ def run_benchmark_sim(args, inputfile, usernamespace):
# Number of threads to test - start from max physical CPU cores and divide in half until 1 # Number of threads to test - start from max physical CPU cores and divide in half until 1
thread = psutil.cpu_count(logical=False) thread = psutil.cpu_count(logical=False)
threads = [thread] threads = [thread]
while not thread%2: while not thread % 2:
thread /= 2 thread /= 2
threads.append(int(thread)) threads.append(int(thread))
benchtimes = np.zeros(len(threads)) benchtimes = np.zeros(len(threads))
numbermodelruns = len(threads) numbermodelruns = len(threads)
usernamespace['number_model_runs'] = numbermodelruns
tsimstart = perf_counter() tsimstart = perf_counter()
for modelrun in range(1, numbermodelruns + 1): for modelrun in range(1, numbermodelruns + 1):
os.environ['OMP_NUM_THREADS'] = str(threads[modelrun - 1]) os.environ['OMP_NUM_THREADS'] = str(threads[modelrun - 1])
@@ -181,7 +182,7 @@ def run_benchmark_sim(args, inputfile, usernamespace):
# Save number of threads and benchmarking times to NumPy archive # Save number of threads and benchmarking times to NumPy archive
threads = np.array(threads) threads = np.array(threads)
np.savez(os.path.splitext(inputfile)[0], threads=threads, benchtimes=benchtimes) np.savez(os.path.splitext(inputfile)[0], threads=threads, benchtimes=benchtimes, version=__version__)
print('\nTotal simulation time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart)))) print('\nTotal simulation time [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart))))
@@ -209,17 +210,17 @@ def run_mpi_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None)
status = MPI.Status() # get MPI status object status = MPI.Status() # get MPI status object
name = MPI.Get_processor_name() # get name of processor/host name = MPI.Get_processor_name() # get name of processor/host
if rank == 0: # Master process if rank == 0: # Master process
modelrun = 1 modelrun = 1
numworkers = size - 1 numworkers = size - 1
closedworkers = 0 closedworkers = 0
print('Master: PID {} on {} using {} workers.'.format(os.getpid(), name, numworkers)) print('Master: PID {} on {} using {} workers.'.format(os.getpid(), name, numworkers))
while closedworkers < numworkers: while closedworkers < numworkers:
data = comm.recv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG, status=status) # data = comm.recv(source=MPI.ANY_SOURCE, tag=MPI.ANY_TAG, status=status) # Check if this line is really needed
source = status.Get_source() source = status.Get_source()
tag = status.Get_tag() tag = status.Get_tag()
if tag == tags.READY.value: # Worker is ready, so send it a task if tag == tags.READY.value: # Worker is ready, so send it a task
if modelrun < numbermodelruns + 1: if modelrun < numbermodelruns + 1:
comm.send(modelrun, dest=source, tag=tags.START.value) comm.send(modelrun, dest=source, tag=tags.START.value)
print('Master: sending model {} to worker {}.'.format(modelrun, source)) print('Master: sending model {} to worker {}.'.format(modelrun, source))
@@ -234,16 +235,16 @@ def run_mpi_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None)
print('Worker {}: exited.'.format(source)) print('Worker {}: exited.'.format(source))
closedworkers += 1 closedworkers += 1
else: # Worker process else: # Worker process
print('Worker {}: PID {} on {} requesting {} OpenMP threads.'.format(rank, os.getpid(), name, os.environ.get('OMP_NUM_THREADS'))) print('Worker {}: PID {} on {} requesting {} OpenMP threads.'.format(rank, os.getpid(), name, os.environ.get('OMP_NUM_THREADS')))
while True: while True:
comm.send(None, dest=0, tag=tags.READY.value) comm.send(None, dest=0, tag=tags.READY.value)
modelrun = comm.recv(source=0, tag=MPI.ANY_TAG, status=status) # Receive a model number to run from the master modelrun = comm.recv(source=0, tag=MPI.ANY_TAG, status=status) #  Receive a model number to run from the master
tag = status.Get_tag() tag = status.Get_tag()
# Run a model # Run a model
if tag == tags.START.value: if tag == tags.START.value:
if optparams: # If Taguchi optimistaion, add specific value for each parameter to optimise for each experiment to user accessible namespace if optparams: # If Taguchi optimistaion, add specific value for each parameter to optimise for each experiment to user accessible namespace
tmp = {} tmp = {}
tmp.update((key, value[modelrun - 1]) for key, value in optparams.items()) tmp.update((key, value[modelrun - 1]) for key, value in optparams.items())
modelusernamespace = usernamespace.copy() modelusernamespace = usernamespace.copy()
@@ -281,8 +282,8 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
global G global G
# Normal model reading/building process; bypassed if geometry information to be reused # Normal model reading/building process; bypassed if geometry information to be reused
if not 'G' in globals(): if 'G' not in globals():
print('\n{}\n\nModel input file: {}\n'.format(68*'*', inputfile)) print('\n{}\n\nModel input file: {}\n'.format(68 * '*', inputfile))
# 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
usernamespace['current_model_run'] = modelrun usernamespace['current_model_run'] = modelrun
@@ -355,7 +356,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
if G.messages: if G.messages:
print('\nMaterials:\n') print('\nMaterials:\n')
print('ID\tName\t\tProperties') print('ID\tName\t\tProperties')
print('{}'.format('-'*50)) print('{}'.format('-' * 50))
for material in G.materials: for material in G.materials:
# Calculate update coefficients for material # Calculate update coefficients for material
@@ -370,7 +371,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
if Material.maxpoles != 0: if Material.maxpoles != 0:
z = 0 z = 0
for pole in range(Material.maxpoles): for pole in range(Material.maxpoles):
G.updatecoeffsdispersive[material.numID, z:z+3] = e0 * material.eqt2[pole], material.eqt[pole], material.zt[pole] G.updatecoeffsdispersive[material.numID, z:z + 3] = e0 * material.eqt2[pole], material.eqt[pole], material.zt[pole]
z += 3 z += 3
if G.messages: if G.messages:
@@ -423,7 +424,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
tgeostart = perf_counter() tgeostart = perf_counter()
for geometryview in G.geometryviews: for geometryview in G.geometryviews:
geometryview.write_vtk(modelrun, numbermodelruns, G) geometryview.write_vtk(modelrun, numbermodelruns, G)
#geometryview.write_xdmf(modelrun, numbermodelruns, G) # geometryview.write_xdmf(modelrun, numbermodelruns, G)
tgeoend = perf_counter() tgeoend = perf_counter()
print('\nGeometry file(s) written in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tgeoend - tgeostart)))) print('\nGeometry file(s) written in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tgeoend - tgeostart))))
@@ -449,7 +450,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
tsolvestart = perf_counter() tsolvestart = perf_counter()
# Absolute time # Absolute time
abstime = 0 abstime = 0
for timestep in range(G.iterations): for timestep in range(G.iterations):
if timestep == 0: if timestep == 0:
tstepstart = perf_counter() tstepstart = perf_counter()
@@ -463,9 +464,9 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
snapshot.write_vtk_imagedata(G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G) snapshot.write_vtk_imagedata(G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
# Update electric field components # Update electric field components
if Material.maxpoles == 0: # All materials are non-dispersive so do standard update if Material.maxpoles == 0: # All materials are non-dispersive so do standard update
update_electric(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz) update_electric(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
elif Material.maxpoles == 1: # If there are any dispersive materials do 1st part of dispersive update (it is split into two parts as it requires present and updated electric field values). elif Material.maxpoles == 1: # If there are any dispersive materials do 1st part of dispersive update (it is split into two parts as it requires present and updated electric field values).
update_electric_dispersive_1pole_A(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz) update_electric_dispersive_1pole_A(G.nx, G.ny, G.nz, G.nthreads, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
elif Material.maxpoles > 1: elif Material.maxpoles > 1:
update_electric_dispersive_multipole_A(G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz) update_electric_dispersive_multipole_A(G.nx, G.ny, G.nz, G.nthreads, Material.maxpoles, G.updatecoeffsE, G.updatecoeffsdispersive, G.ID, G.Tx, G.Ty, G.Tz, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz)
@@ -478,7 +479,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
voltagesource.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G) voltagesource.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G)
for transmissionline in G.transmissionlines: for transmissionline in G.transmissionlines:
transmissionline.update_electric(abstime, G.Ex, G.Ey, G.Ez, G) transmissionline.update_electric(abstime, G.Ex, G.Ey, G.Ez, G)
for hertziandipole in G.hertziandipoles: # Update any Hertzian dipole sources last for hertziandipole in G.hertziandipoles: # Update any Hertzian dipole sources last
hertziandipole.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G) hertziandipole.update_electric(abstime, G.updatecoeffsE, G.ID, G.Ex, G.Ey, G.Ez, G)
# If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates. # If there are any dispersive materials do 2nd part of dispersive update (it is split into two parts as it requires present and updated electric field values). Therefore it can only be completely updated after the electric field has been updated by the PML and source updates.
@@ -519,8 +520,8 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
write_hdf5(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G) write_hdf5(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
tsolveend = perf_counter() tsolveend = perf_counter()
print('\n\nSolving took [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsolveend - tsolvestart)))) print('\n\nSolving took [HH:MM:SS]: {} @ {:g} cells/s'.format(datetime.timedelta(seconds=int(tsolveend - tsolvestart)), (G.nx * G.ny * G.nz) / (tsolveend - tsolvestart)))
print('Peak memory (approx) used: {}'.format(human_size(p.memory_info().rss))) print('Memory (RAM) usage: ~{}'.format(human_size(p.memory_info().rss)))
################################## ##################################
# End - Main FDTD calculations # # End - Main FDTD calculations #
@@ -531,7 +532,3 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
del G del G
return int(tsolveend - tsolvestart) return int(tsolveend - tsolvestart)