Merge pull request #341 from Sai-Suraj-27/class_Waveform

This PR updates a few files which makes them much cleaner with better code.
这个提交包含在:
Craig Warren
2023-04-17 09:43:47 +01:00
提交者 GitHub
当前提交 65057de491
共有 8 个文件被更改,包括 194 次插入172 次删除

查看文件

@@ -61,9 +61,9 @@ class UserObjectMulti:
"""Readable user string as per hash commands."""
s = ''
for _, v in self.kwargs.items():
if isinstance(v, tuple) or isinstance(v, list):
if isinstance(v, (tuple, list)):
v = ' '.join([str(el) for el in v])
s += str(v) + ' '
s += f'{str(v)} '
return f'{self.hash}: {s[:-1]}'
@@ -77,7 +77,7 @@ class UserObjectMulti:
def params_str(self):
"""Readable string of parameters given to object."""
return self.hash + ': ' + str(self.kwargs)
return f'{self.hash}: {str(self.kwargs)}'
def grid_name(self, grid):
"""Returns subgrid name for use with logging info. Returns an empty
@@ -114,12 +114,14 @@ class Waveform(UserObjectMulti):
try:
wavetype = self.kwargs['wave_type'].lower()
except KeyError:
logger.exception(self.params_str() + (f" must have one of the "
f"following types {','.join(WaveformUser.types)}."))
logger.exception(
f"{self.params_str()} must have one of the following types {','.join(WaveformUser.types)}."
)
raise
if wavetype not in WaveformUser.types:
logger.exception(self.params_str() + (f" must have one of the "
f"following types {','.join(WaveformUser.types)}."))
logger.exception(
f"{self.params_str()} must have one of the following types {','.join(WaveformUser.types)}."
)
raise ValueError
if wavetype != 'user':
@@ -817,16 +819,14 @@ class Rx(UserObjectMulti):
outputs = [self.kwargs['outputs']]
except KeyError:
# If no ID or outputs are specified, use default
r.ID = (r.__class__.__name__ + '(' + str(r.xcoord) + ',' +
str(r.ycoord) + ',' + str(r.zcoord) + ')')
r.ID = f'{r.__class__.__name__}({str(r.xcoord)},{str(r.ycoord)},{str(r.zcoord)})'
for key in RxUser.defaultoutputs:
r.outputs[key] = np.zeros(grid.iterations,
dtype=config.sim_config.dtypes['float_or_double'])
else:
outputs.sort()
# Get allowable outputs
if (config.sim_config.general['solver'] =='cuda' or
config.sim_config.general['solver'] =='opencl'):
if config.sim_config.general['solver'] in ['cuda', 'opencl']:
allowableoutputs = RxUser.allowableoutputs_dev
else:
allowableoutputs = RxUser.allowableoutputs
@@ -836,15 +836,14 @@ class Rx(UserObjectMulti):
r.outputs[field] = np.zeros(grid.iterations,
dtype=config.sim_config.dtypes['float_or_double'])
else:
logger.exception(self.params_str() + ' contains an '
'output type that is not allowable. '
'Allowable outputs in current context are '
f'{allowableoutputs}.')
logger.exception(
f'{self.params_str()} contains an output type that is not allowable. Allowable outputs in current context are {allowableoutputs}.'
)
raise ValueError
logger.info(self.grid_name(grid) + f"Receiver at {p2[0]:g}m, "
f"{p2[1]:g}m, {p2[2]:g}m with output component(s) "
f"{', '.join(r.outputs)} created.")
logger.info(
f"{self.grid_name(grid)}Receiver at {p2[0]:g}m, {p2[1]:g}m, {p2[2]:g}m with output component(s) {', '.join(r.outputs)} created."
)
grid.rxs.append(r)
@@ -911,10 +910,9 @@ class RxArray(UserObjectMulti):
'not be less than the spatial discretisation.')
raise ValueError
logger.info(self.grid_name(grid) + f'Receiver array {p3[0]:g}m, '
f'{p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, '
f'{p4[2]:g}m with steps {dx * grid.dx:g}m, '
f'{dy * grid.dy:g}m, {dz * grid.dz:g}m')
logger.info(
f'{self.grid_name(grid)}Receiver array {p3[0]:g}m, {p3[1]:g}m, {p3[2]:g}m, to {p4[0]:g}m, {p4[1]:g}m, {p4[2]:g}m with steps {dx * grid.dx:g}m, {dy * grid.dy:g}m, {dz * grid.dz:g}m'
)
for x in range(xs, xf + 1, dx):
for y in range(ys, yf + 1, dy):
@@ -930,8 +928,7 @@ class RxArray(UserObjectMulti):
p5 = np.array([x, y, z])
p5 = uip.descretised_to_continuous(p5)
p5 = uip.round_to_grid_static_point(p5)
r.ID = (r.__class__.__name__ + '(' + str(x) + ',' +
str(y) + ',' + str(z) + ')')
r.ID = f'{r.__class__.__name__}({str(x)},{str(y)},{str(z)})'
for key in RxUser.defaultoutputs:
r.outputs[key] = np.zeros(grid.iterations, dtype=config.sim_config.dtypes['float_or_double'])
logger.info(f" Receiver at {p5[0]:g}m, {p5[1]:g}m, "
@@ -986,7 +983,7 @@ class Snapshot(UserObjectMulti):
p4 = uip.round_to_grid_static_point(p2)
p1, p2 = uip.check_box_points(p1, p2, self.params_str())
except ValueError:
logger.exception(self.params_str() + ' point is outside the domain.')
logger.exception(f'{self.params_str()} point is outside the domain.')
raise
xs, ys, zs = p1
xf, yf, zf = p2
@@ -1027,10 +1024,9 @@ class Snapshot(UserObjectMulti):
# Check and set output names
for output in tmp:
if output not in SnapshotUser.allowableoutputs.keys():
logger.exception(self.params_str() + " contains an "
"output type that is not allowable. "
"Allowable outputs in current context are "
f"{', '.join(SnapshotUser.allowableoutputs.keys())}.")
logger.exception(
f"{self.params_str()} contains an output type that is not allowable. Allowable outputs in current context are {', '.join(SnapshotUser.allowableoutputs.keys())}."
)
raise ValueError
else:
outputs[output] = True
@@ -1047,7 +1043,7 @@ class Snapshot(UserObjectMulti):
'be less than the spatial discretisation.')
raise ValueError
if iterations <= 0 or iterations > grid.iterations:
logger.exception(self.params_str() + ' time value is not valid.')
logger.exception(f'{self.params_str()} time value is not valid.')
raise ValueError
s = SnapshotUser(xs, ys, zs, xf, yf, zf, dx, dy, dz, iterations,
@@ -1088,39 +1084,40 @@ class Material(UserObjectMulti):
sm = self.kwargs['sm']
material_id = self.kwargs['id']
except KeyError:
logger.exception(self.params_str() + ' requires exactly five '
'parameters.')
logger.exception(f'{self.params_str()} requires exactly five parameters.')
raise
if er < 1:
logger.exception(self.params_str() + ' requires a positive value '
'of one or greater for static (DC) permittivity.')
logger.exception(
f'{self.params_str()} requires a positive value of one or greater for static (DC) permittivity.'
)
raise ValueError
if se != 'inf':
se = float(se)
if se < 0:
logger.exception(self.params_str() + ' requires a positive '
'value for electric conductivity.')
logger.exception(
f'{self.params_str()} requires a positive value for electric conductivity.'
)
raise ValueError
else:
se = float('inf')
if mr < 1:
logger.exception(self.params_str() + ' requires a positive value '
'of one or greater for magnetic permeability.')
logger.exception(
f'{self.params_str()} requires a positive value of one or greater for magnetic permeability.'
)
raise ValueError
if sm < 0:
logger.exception(self.params_str() + ' requires a positive value '
'for magnetic loss.')
logger.exception(
f'{self.params_str()} requires a positive value for magnetic loss.'
)
raise ValueError
if any(x.ID == material_id for x in grid.materials):
logger.exception(self.params_str() + f' with ID {material_id} '
'already exists')
logger.exception(f'{self.params_str()} with ID {material_id} already exists')
raise ValueError
# Create a new instance of the Material class material
# (start index after pec & free_space)
m = MaterialUser(len(grid.materials), material_id)
m.er = er
m.se = se
m.mr = mr
m.sm = sm
@@ -1129,9 +1126,10 @@ class Material(UserObjectMulti):
if m.se == float('inf'):
m.averagable = False
logger.info(self.grid_name(grid) + f'Material {m.ID} with '
f'eps_r={m.er:g}, sigma={m.se:g} S/m; mu_r={m.mr:g}, '
f'sigma*={m.sm:g} Ohm/m created.')
m.er = er
logger.info(
f'{self.grid_name(grid)}Material {m.ID} with eps_r={m.er:g}, sigma={m.se:g} S/m; mu_r={m.mr:g}, sigma*={m.sm:g} Ohm/m created.'
)
grid.materials.append(m)
@@ -1176,8 +1174,7 @@ class AddDebyeDispersion(UserObjectMulti):
if len(materials) != len(material_ids):
notfound = [x for x in material_ids if x not in materials]
logger.exception(self.params_str() + f' material(s) {notfound} do '
'not exist')
logger.exception(f'{self.params_str()} material(s) {notfound} do not exist')
raise ValueError
for material in materials:
@@ -1189,7 +1186,7 @@ class AddDebyeDispersion(UserObjectMulti):
disp_material.type = 'debye'
disp_material.poles = poles
disp_material.averagable = False
for i in range(0, poles):
for i in range(poles):
if tau[i] > 0:
logger.debug('Not checking if relaxation times are '
'greater than time-step.')
@@ -1205,9 +1202,9 @@ class AddDebyeDispersion(UserObjectMulti):
# Replace original material with newly created DispersiveMaterial
grid.materials = [disp_material if mat.numID==material.numID else mat for mat in grid.materials]
logger.info(self.grid_name(grid) + f"Debye disperion added to {disp_material.ID} "
f"with delta_eps_r={', '.join('%4.2f' % deltaer for deltaer in disp_material.deltaer)}, "
f"and tau={', '.join('%4.3e' % tau for tau in disp_material.tau)} secs created.")
logger.info(
f"{self.grid_name(grid)}Debye disperion added to {disp_material.ID} with delta_eps_r={', '.join('%4.2f' % deltaer for deltaer in disp_material.deltaer)}, and tau={', '.join('%4.3e' % tau for tau in disp_material.tau)} secs created."
)
class AddLorentzDispersion(UserObjectMulti):
@@ -1252,8 +1249,7 @@ class AddLorentzDispersion(UserObjectMulti):
if len(materials) != len(material_ids):
notfound = [x for x in material_ids if x not in materials]
logger.exception(self.params_str() + f' material(s) {notfound} do '
'not exist')
logger.exception(f'{self.params_str()} material(s) {notfound} do not exist')
raise ValueError
for material in materials:
@@ -1265,7 +1261,7 @@ class AddLorentzDispersion(UserObjectMulti):
disp_material.type = 'lorentz'
disp_material.poles = poles
disp_material.averagable = False
for i in range(0, poles):
for i in range(poles):
if er_delta[i] > 0 and omega[i] > grid.dt and delta[i] > grid.dt:
disp_material.deltaer.append(er_delta[i])
disp_material.tau.append(omega[i])
@@ -1283,10 +1279,9 @@ class AddLorentzDispersion(UserObjectMulti):
# Replace original material with newly created DispersiveMaterial
grid.materials = [disp_material if mat.numID==material.numID else mat for mat in grid.materials]
logger.info(self.grid_name(grid) + f"Lorentz disperion added to {disp_material.ID} "
f"with delta_eps_r={', '.join('%4.2f' % deltaer for deltaer in disp_material.deltaer)}, "
f"omega={', '.join('%4.3e' % omega for omega in disp_material.tau)} secs, "
f"and gamma={', '.join('%4.3e' % delta for delta in disp_material.alpha)} created.")
logger.info(
f"{self.grid_name(grid)}Lorentz disperion added to {disp_material.ID} with delta_eps_r={', '.join('%4.2f' % deltaer for deltaer in disp_material.deltaer)}, omega={', '.join('%4.3e' % omega for omega in disp_material.tau)} secs, and gamma={', '.join('%4.3e' % delta for delta in disp_material.alpha)} created."
)
class AddDrudeDispersion(UserObjectMulti):
@@ -1327,8 +1322,7 @@ class AddDrudeDispersion(UserObjectMulti):
if len(materials) != len(material_ids):
notfound = [x for x in material_ids if x not in materials]
logger.exception(self.params_str() + f' material(s) {notfound} do '
'not exist.')
logger.exception(f'{self.params_str()} material(s) {notfound} do not exist.')
raise ValueError
for material in materials:
@@ -1340,7 +1334,7 @@ class AddDrudeDispersion(UserObjectMulti):
disp_material.type = 'drude'
disp_material.poles = poles
disp_material.averagable = False
for i in range(0, poles):
for i in range(poles):
if omega[i] > 0 and alpha[i] > grid.dt:
disp_material.tau.append(omega[i])
disp_material.alpha.append(alpha[i])
@@ -1356,9 +1350,9 @@ class AddDrudeDispersion(UserObjectMulti):
# Replace original material with newly created DispersiveMaterial
grid.materials = [disp_material if mat.numID==material.numID else mat for mat in grid.materials]
logger.info(self.grid_name(grid) + f"Drude disperion added to {disp_material.ID} "
f"with omega={', '.join('%4.3e' % omega for omega in disp_material.tau)} secs, "
f"and gamma={', '.join('%4.3e' % alpha for alpha in disp_material.alpha)} secs created.")
logger.info(
f"{self.grid_name(grid)}Drude disperion added to {disp_material.ID} with omega={', '.join('%4.3e' % omega for omega in disp_material.tau)} secs, and gamma={', '.join('%4.3e' % alpha for alpha in disp_material.alpha)} secs created."
)
class SoilPeplinski(UserObjectMulti):
@@ -1423,7 +1417,7 @@ class SoilPeplinski(UserObjectMulti):
'fraction.')
raise ValueError
if any(x.ID == ID for x in grid.mixingmodels):
logger.exception(self.params_str() + f' with ID {ID} already exists')
logger.exception(f'{self.params_str()} with ID {ID} already exists')
raise ValueError
# Create a new instance of the Material class material
@@ -1624,7 +1618,7 @@ class GeometryView(UserObjectMulti):
p4 = uip.round_to_grid_static_point(p2)
p1, p2 = uip.check_box_points(p1, p2, self.params_str())
except ValueError:
logger.exception(self.params_str() + ' point is outside the domain.')
logger.exception(f'{self.params_str()} point is outside the domain.')
raise
xs, ys, zs = p1
xf, yf, zf = p2
@@ -1644,7 +1638,7 @@ class GeometryView(UserObjectMulti):
logger.exception(self.params_str() + ' the step size should not '
'be less than the spatial discretisation.')
raise ValueError
if output_type != 'n' and output_type != 'f':
if output_type not in ['n', 'f']:
logger.exception(self.params_str() + ' requires type to be either '
'n (normal) or f (fine).')
raise ValueError

查看文件

@@ -93,20 +93,23 @@ class Discretisation(UserObjectSingle):
G.dl = np.array(self.kwargs['p1'])
G.dx, G.dy, G.dz = self.kwargs['p1']
except KeyError:
logger.exception(self.__str__() + ' discretisation requires a point')
logger.exception(f'{self.__str__()} discretisation requires a point')
raise
if G.dl[0] <= 0:
logger.exception(self.__str__() + ' discretisation requires the ' +
'x-direction spatial step to be greater than zero')
logger.exception(
f'{self.__str__()} discretisation requires the x-direction spatial step to be greater than zero'
)
raise ValueError
if G.dl[1] <= 0:
logger.exception(self.__str__() + ' discretisation requires the ' +
'y-direction spatial step to be greater than zero')
logger.exception(
f'{self.__str__()} discretisation requires the y-direction spatial step to be greater than zero'
)
raise ValueError
if G.dl[2] <= 0:
logger.exception(self.__str__() + ' discretisation requires the ' +
'z-direction spatial step to be greater than zero')
logger.exception(
f'{self.__str__()} discretisation requires the z-direction spatial step to be greater than zero'
)
raise ValueError
logger.info(f'Spatial discretisation: {G.dl[0]:g} x {G.dl[1]:g} x {G.dl[2]:g}m')
@@ -127,11 +130,13 @@ class Domain(UserObjectSingle):
try:
G.nx, G.ny, G.nz = uip.discretise_point(self.kwargs['p1'])
except KeyError:
logger.exception(self.__str__() + ' please specify a point')
logger.exception(f'{self.__str__()} please specify a point')
raise
if G.nx == 0 or G.ny == 0 or G.nz == 0:
logger.exception(self.__str__() + ' requires at least one cell in every dimension')
logger.exception(
f'{self.__str__()} requires at least one cell in every dimension'
)
raise ValueError
logger.info(f"Domain size: {self.kwargs['p1'][0]:g} x {self.kwargs['p1'][1]:g} x " +
@@ -181,12 +186,13 @@ class TimeStepStabilityFactor(UserObjectSingle):
try:
f = self.kwargs['f']
except KeyError:
logger.exception(self.__str__() + ' requires exactly one parameter')
logger.exception(f'{self.__str__()} requires exactly one parameter')
raise
if f <= 0 or f > 1:
logger.exception(self.__str__() + ' requires the value of the time ' +
'step stability factor to be between zero and one')
logger.exception(
f'{self.__str__()} requires the value of the time step stability factor to be between zero and one'
)
raise ValueError
G.dt = G.dt * f
@@ -250,12 +256,14 @@ class OMPThreads(UserObjectSingle):
try:
n = self.kwargs['n']
except KeyError:
logger.exception(self.__str__() + ' requires exactly one parameter ' +
'to specify the number of CPU OpenMP threads to use')
logger.exception(
f'{self.__str__()} requires exactly one parameter to specify the number of CPU OpenMP threads to use'
)
raise
if n < 1:
logger.exception(self.__str__() + ' requires the value to be an ' +
'integer not less than one')
logger.exception(
f'{self.__str__()} requires the value to be an integer not less than one'
)
raise ValueError
config.get_model_config().ompthreads = set_omp_threads(n)
@@ -302,7 +310,7 @@ class PMLProps(UserObjectSingle):
G.pmls['thickness']['ymax'] = int(self.kwargs['ymax'])
G.pmls['thickness']['zmax'] = int(self.kwargs['zmax'])
except KeyError:
logger.exception(self.__str__() + ' requires either one or six parameter(s)')
logger.exception(f'{self.__str__()} requires either one or six parameter(s)')
raise
if (2 * G.pmls['thickness']['x0'] >= G.nx or
@@ -311,8 +319,8 @@ class PMLProps(UserObjectSingle):
2 * G.pmls['thickness']['xmax'] >= G.nx or
2 * G.pmls['thickness']['ymax'] >= G.ny or
2 * G.pmls['thickness']['zmax'] >= G.nz):
logger.exception(self.__str__() + ' has too many cells for the domain size')
raise ValueError
logger.exception(f'{self.__str__()} has too many cells for the domain size')
raise ValueError
class SrcSteps(UserObjectSingle):
@@ -330,12 +338,16 @@ class SrcSteps(UserObjectSingle):
try:
G.srcsteps = uip.discretise_point(self.kwargs['p1'])
except KeyError:
logger.exception(self.__str__() + ' requires exactly three parameters')
logger.exception(f'{self.__str__()} requires exactly three parameters')
raise
logger.info(f'Simple sources will step {G.srcsteps[0] * G.dx:g}m, ' +
f'{G.srcsteps[1] * G.dy:g}m, {G.srcsteps[2] * G.dz:g}m ' +
f'for each model run.')
logger.info(
(
f'Simple sources will step {G.srcsteps[0] * G.dx:g}m, '
+ f'{G.srcsteps[1] * G.dy:g}m, {G.srcsteps[2] * G.dz:g}m '
+ 'for each model run.'
)
)
class RxSteps(UserObjectSingle):
@@ -353,12 +365,16 @@ class RxSteps(UserObjectSingle):
try:
G.rxsteps = uip.discretise_point(self.kwargs['p1'])
except KeyError:
logger.exception(self.__str__() + ' requires exactly three parameters')
logger.exception(f'{self.__str__()} requires exactly three parameters')
raise
logger.info(f'All receivers will step {G.rxsteps[0] * G.dx:g}m, ' +
f'{G.rxsteps[1] * G.dy:g}m, {G.rxsteps[2] * G.dz:g}m ' +
f'for each model run.')
logger.info(
(
f'All receivers will step {G.rxsteps[0] * G.dx:g}m, '
+ f'{G.rxsteps[1] * G.dy:g}m, {G.rxsteps[2] * G.dz:g}m '
+ 'for each model run.'
)
)
class ExcitationFile(UserObjectSingle):
@@ -378,7 +394,7 @@ class ExcitationFile(UserObjectSingle):
def create(self, G, uip):
try:
kwargs = dict()
kwargs = {}
excitationfile = self.kwargs['filepath']
kwargs['kind'] = self.kwargs['kind']
kwargs['fill_value'] = self.kwargs['fill_value']
@@ -389,7 +405,7 @@ class ExcitationFile(UserObjectSingle):
args, varargs, keywords, defaults = inspect.getargspec(interpolate.interp1d)
kwargs = dict(zip(reversed(args), reversed(defaults)))
except KeyError:
logger.exception(self.__str__() + ' requires either one or three parameter(s)')
logger.exception(f'{self.__str__()} requires either one or three parameter(s)')
raise
# See if file exists at specified path and if not try input file directory

查看文件

@@ -225,13 +225,14 @@ class SimulationConfig:
# subgrid: whether the simulation uses sub-grids.
# precision: data type for electromagnetic field output (single/double).
self.general = {'solver': 'cpu',
'subgrid': False,
'precision': 'single'}
self.general = {
'solver': 'cpu',
'subgrid': False,
'precision': 'single',
'progressbars': args.log_level <= 20,
}
# Progress bars on stdoout or not - switch off progressbars when
# logging level is greater than info (20)
self.general['progressbars'] = False if args.log_level > 20 else True
self.em_consts = {'c': c, # Speed of light in free space (m/s)
'e0': e0, # Permittivity of free space (F/m)

查看文件

@@ -277,10 +277,7 @@ class Comments():
"""
# Comments for Paraview macro
comments = {}
comments['gprMax_version'] = __version__
comments['dx_dy_dz'] = self.dx_dy_dz_comment()
comments = {'gprMax_version': __version__, 'dx_dy_dz': self.dx_dy_dz_comment()}
comments['nx_ny_nz'] = self.nx_ny_nz_comment()
# Write the name and numeric ID for each material

查看文件

@@ -178,14 +178,15 @@ def write_processed_file(processedlines):
for item in processedlines:
f.write(f'{item}')
logger.info(f'Written input commands, after processing any Python code and ' +
f'include commands, to file: {processedfile}\n')
logger.info(
f'Written input commands, after processing any Python code and include commands, to file: {processedfile}\n'
)
def check_cmd_names(processedlines, checkessential=True):
"""Checks the validity of commands, i.e. are they gprMax commands,
and that all essential commands are present.
Args:
processedlines: list of input commands after Python processing.
checkessential: boolean to check for essential commands or not.

查看文件

@@ -620,12 +620,13 @@ def process_materials(G):
z += 3
# Construct information on material properties for printing table
materialtext = []
materialtext.append(str(material.numID))
materialtext.append(material.ID[:50] if len(material.ID) > 50 else material.ID)
materialtext.append(material.type)
materialtext.append(f'{material.er:g}')
materialtext.append(f'{material.se:g}')
materialtext = [
str(material.numID),
material.ID[:50] if len(material.ID) > 50 else material.ID,
material.type,
f'{material.er:g}',
f'{material.se:g}',
]
if config.get_model_config().materials['maxpoles'] > 0:
if 'debye' in material.type:
materialtext.append('\n'.join('{:g}'.format(deltaer) for deltaer in material.deltaer))
@@ -645,9 +646,9 @@ def process_materials(G):
else:
materialtext.extend(['', '', '', '', ''])
materialtext.append(f'{material.mr:g}')
materialtext.append(f'{material.sm:g}')
materialtext.append(material.averagable)
materialtext.extend(
(f'{material.mr:g}', f'{material.sm:g}', material.averagable)
)
materialsdata.append(materialtext)
return materialsdata

查看文件

@@ -53,19 +53,24 @@ class Waveform:
"""Calculates coefficients (used to calculate values) for specific
waveforms.
"""
if self.freq is None:
raise ValueError("Frequency is not specified")
if (self.type == 'gaussian' or self.type == 'gaussiandot' or
self.type == 'gaussiandotnorm' or self.type == 'gaussianprime' or
self.type == 'gaussiandoubleprime'):
if self.type in [
'gaussian',
'gaussiandot',
'gaussiandotnorm',
'gaussianprime',
'gaussiandoubleprime',
]:
self.chi = 1 / self.freq
self.zeta = 2 * np.pi**2 * self.freq**2
elif (self.type == 'gaussiandotdot' or
self.type == 'gaussiandotdotnorm' or self.type == 'ricker'):
elif self.type in ['gaussiandotdot', 'gaussiandotdotnorm', 'ricker']:
self.chi = np.sqrt(2) / self.freq
self.zeta = np.pi**2 * self.freq**2
def calculate_value(self, time, dt):
"""Calculates value of the waveform at a specific time.
"""Calculates the value of the waveform at a specific time.
Args:
time: float for absolute time.
@@ -82,7 +87,7 @@ class Waveform:
delay = time - self.chi
ampvalue = np.exp(-self.zeta * delay**2)
elif self.type == 'gaussiandot' or self.type == 'gaussianprime':
elif self.type in ['gaussiandot', 'gaussianprime']:
delay = time - self.chi
ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2)
@@ -91,7 +96,7 @@ class Waveform:
normalise = np.sqrt(np.exp(1) / (2 * self.zeta))
ampvalue = -2 * self.zeta * delay * np.exp(-self.zeta * delay**2) * normalise
elif self.type == 'gaussiandotdot' or self.type == 'gaussiandoubleprime':
elif self.type in ['gaussiandotdot', 'gaussiandoubleprime']:
delay = time - self.chi
ampvalue = (2 * self.zeta * (2 * self.zeta * delay**2 - 1) *
np.exp(-self.zeta * delay**2))
@@ -116,8 +121,8 @@ class Waveform:
elif self.type == 'contsine':
rampamp = 0.25
ramp = rampamp * time * self.freq
if ramp > 1:
ramp = 1
ramp = min(ramp, 1)
ampvalue = ramp * np.sin(2 * np.pi * self.freq * time)
elif self.type == 'impulse':
@@ -126,7 +131,7 @@ class Waveform:
ampvalue = 1
elif time >= dt:
ampvalue = 0
elif self.type == 'user':
ampvalue = self.userfunc(time)

查看文件

@@ -37,8 +37,9 @@ if sys.version_info[:2] < MIN_PYTHON_VERSION:
# Importing gprMax _version__.py before building can cause issues.
with open('gprMax/_version.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
version = re.search(
r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE
)[1]
def build_dispersive_material_templates():
"""Function to generate Cython .pyx file for dispersive media update.
@@ -46,7 +47,7 @@ def build_dispersive_material_templates():
functions.
"""
iswin = True if sys.platform == 'win32' else False
iswin = (sys.platform == 'win32')
env = Environment(loader = FileSystemLoader(os.path.join('gprMax', 'cython')), )
@@ -151,7 +152,7 @@ if 'cleanall' in sys.argv:
print(f'Removed: {os.path.abspath(libfile)}')
except OSError:
print(f'Could not remove: {os.path.abspath(libfile)}')
# Remove build, dist, egg and __pycache__ directories
shutil.rmtree(Path.cwd().joinpath('build'), ignore_errors=True)
shutil.rmtree(Path.cwd().joinpath('dist'), ignore_errors=True)
@@ -163,7 +164,7 @@ if 'cleanall' in sys.argv:
# Remove 'gprMax/cython/fields_updates_dispersive.jinja' if its there
if os.path.isfile(cython_disp_file):
os.remove(cython_disp_file)
# Now do a normal clean
sys.argv[1] = 'clean' # this is what distutils understands
@@ -176,10 +177,6 @@ else:
linker_args = []
libraries = []
# Compiler options - macOS - needs gcc (usually via HomeBrew) because the
# default compiler LLVM (clang) does not
# support OpenMP. With gcc -fopenmp option
# implies -pthread
elif sys.platform == 'darwin':
# Check for Intel or Apple M series CPU
cpuID = subprocess.check_output("sysctl -n machdep.cpu.brand_string",
@@ -209,7 +206,7 @@ else:
'to be installed - easily done through the Homebrew package ' +
'manager (http://brew.sh). Note: gcc with OpenMP support ' +
'is required.')
# Minimum supported macOS deployment target
MIN_MACOS_VERSION = '10.13'
try:
@@ -219,12 +216,16 @@ else:
pass
os.environ['MIN_SUPPORTED_MACOSX_DEPLOYMENT_TARGET'] = MIN_MACOS_VERSION
# Sometimes worth testing with '-fstrict-aliasing', '-fno-common'
compile_args = ['-O3', '-w', '-fopenmp', '-march=native',
'-mmacosx-version-min=' + MIN_MACOS_VERSION]
linker_args = ['-fopenmp', '-mmacosx-version-min=' + MIN_MACOS_VERSION]
compile_args = [
'-O3',
'-w',
'-fopenmp',
'-march=native',
f'-mmacosx-version-min={MIN_MACOS_VERSION}',
]
linker_args = ['-fopenmp', f'-mmacosx-version-min={MIN_MACOS_VERSION}']
libraries=['gomp']
# Compiler options - Linux
elif sys.platform == 'linux':
compile_args = ['-O3', '-w', '-fopenmp', '-march=native']
linker_args = ['-fopenmp']
@@ -256,37 +257,43 @@ else:
# Parse long_description from README.rst file.
with open('README.rst','r') as fd:
long_description = fd.read()
setup(name='gprMax',
version=version,
author='Craig Warren, Antonis Giannopoulos, and John Hartley',
url='http://www.gprmax.com',
description='Electromagnetic Modelling Software based on the ' +
'Finite-Difference Time-Domain (FDTD) method',
long_description=long_description,
long_description_content_type="text/x-rst",
license='GPLv3+',
python_requires='>' + str(MIN_PYTHON_VERSION[0]) + '.' + str(MIN_PYTHON_VERSION[1]),
install_requires=['colorama',
'cython',
'h5py',
'jinja2',
'matplotlib',
'numpy',
'psutil',
'scipy',
'terminaltables',
'tqdm'],
setup(
name='gprMax',
version=version,
author='Craig Warren, Antonis Giannopoulos, and John Hartley',
url='http://www.gprmax.com',
description='Electromagnetic Modelling Software based on the '
+ 'Finite-Difference Time-Domain (FDTD) method',
long_description=long_description,
long_description_content_type="text/x-rst",
license='GPLv3+',
python_requires=f'>{str(MIN_PYTHON_VERSION[0])}.{str(MIN_PYTHON_VERSION[1])}',
install_requires=[
'colorama',
'cython',
'h5py',
'jinja2',
'matplotlib',
'numpy',
'psutil',
'scipy',
'terminaltables',
'tqdm',
],
ext_modules=extensions,
packages=find_packages(),
include_package_data=True,
include_dirs=[np.get_include()],
zip_safe=False,
classifiers=['Environment :: Console',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX :: Linux',
'Programming Language :: Cython',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering'])
classifiers=[
'Environment :: Console',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX :: Linux',
'Programming Language :: Cython',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering',
],
)