你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-08 15:27:57 +08:00
Tidy up logging (mainly for log files/debug level)
这个提交包含在:
@@ -89,7 +89,7 @@ class ModelConfig:
|
||||
f"input file: {sim_config.input_file_path}"
|
||||
)
|
||||
self.inputfilestr = (
|
||||
Fore.GREEN + f"{s} {'-' * (get_terminal_width() - 1 - len(s))}\n" + Style.RESET_ALL
|
||||
Fore.GREEN + f"{s} {'-' * (get_terminal_width() - 1 - len(s))}\n\n" + Style.RESET_ALL
|
||||
)
|
||||
|
||||
# Output file path and name for specific model
|
||||
|
@@ -152,7 +152,7 @@ class Context:
|
||||
def print_sim_time_taken(self) -> None:
|
||||
"""Prints the total simulation time based on context."""
|
||||
s = (
|
||||
f"\n=== Simulation completed in "
|
||||
f"=== Simulation completed in "
|
||||
f"{humanize.precisedelta(datetime.timedelta(seconds=self.sim_end_time - self.sim_start_time), format='%0.4f')}"
|
||||
)
|
||||
logger.basic(f"{s} {'=' * (get_terminal_width() - 1 - len(s))}\n")
|
||||
|
@@ -81,7 +81,8 @@ def write_hdf5_outputfile(outputfile: Path, title: str, model):
|
||||
grp = f.create_group(f"/subgrids/{sg.name}")
|
||||
write_hd5_data(grp, sg, is_subgrid=True)
|
||||
|
||||
logger.basic(f"Written output file: {outputfile.name}")
|
||||
logger.basic("")
|
||||
logger.basic(f"Written output file: {outputfile.name}\n")
|
||||
|
||||
|
||||
def write_hd5_data(basegrp, grid, is_subgrid=False):
|
||||
|
@@ -329,8 +329,9 @@ class FDTDGrid:
|
||||
materialstable.outer_border = False
|
||||
materialstable.justify_columns[0] = "right"
|
||||
|
||||
logger.info(f"\nMaterials [{self.name}]:")
|
||||
logger.info(materialstable.table)
|
||||
logger.info("")
|
||||
logger.info(f"Materials [{self.name}]:")
|
||||
logger.info(f"{materialstable.table}\n")
|
||||
|
||||
def _update_positions(
|
||||
self, items: Iterable[Union[Source, Rx]], step_size: List[int], step_number: int
|
||||
@@ -694,7 +695,7 @@ class FDTDGrid:
|
||||
results = self._dispersion_analysis(iterations)
|
||||
if results["error"]:
|
||||
logger.warning(
|
||||
f"\nNumerical dispersion analysis [{self.name}] "
|
||||
f"Numerical dispersion analysis [{self.name}] "
|
||||
f"not carried out as {results['error']}"
|
||||
)
|
||||
elif results["N"] < config.get_model_config().numdispersion["mingridsampling"]:
|
||||
@@ -713,22 +714,22 @@ class FDTDGrid:
|
||||
> config.get_model_config().numdispersion["maxnumericaldisp"]
|
||||
):
|
||||
logger.warning(
|
||||
f"\n[{self.name}] has potentially significant "
|
||||
f"[{self.name}] has potentially significant "
|
||||
f"numerical dispersion. Estimated largest physical "
|
||||
f"phase-velocity error is {results['deltavp']:.2f}% "
|
||||
f"in material '{results['material'].ID}' whose "
|
||||
f"wavelength sampled by {results['N']} cells. "
|
||||
f"Maximum significant frequency estimated as "
|
||||
f"{results['maxfreq']:g}Hz"
|
||||
f"{results['maxfreq']:g}Hz\n"
|
||||
)
|
||||
elif results["deltavp"]:
|
||||
logger.info(
|
||||
f"\nNumerical dispersion analysis [{self.name}]: "
|
||||
f"Numerical dispersion analysis [{self.name}]: "
|
||||
f"estimated largest physical phase-velocity error is "
|
||||
f"{results['deltavp']:.2f}% in material '{results['material'].ID}' "
|
||||
f"whose wavelength sampled by {results['N']} cells. "
|
||||
f"Maximum significant frequency estimated as "
|
||||
f"{results['maxfreq']:g}Hz"
|
||||
f"{results['maxfreq']:g}Hz\n"
|
||||
)
|
||||
|
||||
def _dispersion_analysis(self, iterations: int):
|
||||
|
@@ -355,7 +355,6 @@ class MPIGrid(FDTDGrid):
|
||||
return self.neighbours[dim][dir] != -1
|
||||
|
||||
def set_halo_map(self):
|
||||
print(f"[Rank {self.rank}] Size = {self.size}")
|
||||
size = (self.size + 1).tolist()
|
||||
|
||||
for dim in Dim:
|
||||
@@ -365,14 +364,8 @@ class MPIGrid(FDTDGrid):
|
||||
|
||||
if self.has_neighbour(dim, Dir.NEG):
|
||||
start[dim] = 1
|
||||
print(
|
||||
f"[Rank {self.rank}, Dim {dim}, Dir {Dir.NEG}] Grid of size {size}, creating halo map of size {halo_size} at start {start}"
|
||||
)
|
||||
self.send_halo_map[dim][Dir.NEG] = MPI.FLOAT.Create_subarray(size, halo_size, start)
|
||||
start[dim] = 0
|
||||
print(
|
||||
f"[Rank {self.rank}, Dim {dim}, Dir {Dir.NEG}] Grid of size {size}, creating halo map of size {halo_size} at start {start}"
|
||||
)
|
||||
self.recv_halo_map[dim][Dir.NEG] = MPI.FLOAT.Create_subarray(size, halo_size, start)
|
||||
|
||||
self.send_halo_map[dim][Dir.NEG].Commit()
|
||||
@@ -380,14 +373,8 @@ class MPIGrid(FDTDGrid):
|
||||
|
||||
if self.has_neighbour(dim, Dir.POS):
|
||||
start[dim] = size[dim] - 2
|
||||
print(
|
||||
f"[Rank {self.rank}, Dim {dim}, Dir {Dir.POS}] Grid of size {size}, creating halo map of size {halo_size} at start {start}"
|
||||
)
|
||||
self.send_halo_map[dim][Dir.POS] = MPI.FLOAT.Create_subarray(size, halo_size, start)
|
||||
start[dim] = size[dim] - 1
|
||||
print(
|
||||
f"[Rank {self.rank}, Dim {dim}, Dir {Dir.POS}] Grid of size {size}, creating halo map of size {halo_size} at start {start}"
|
||||
)
|
||||
self.recv_halo_map[dim][Dir.POS] = MPI.FLOAT.Create_subarray(size, halo_size, start)
|
||||
|
||||
self.send_halo_map[dim][Dir.POS].Commit()
|
||||
@@ -413,5 +400,5 @@ class MPIGrid(FDTDGrid):
|
||||
self.upper_extent = self.lower_extent + self.size
|
||||
|
||||
logger.debug(
|
||||
f"[Rank {self.rank}] Grid size: {self.size}, Lower extent: {self.lower_extent}, Upper extent: {self.upper_extent}"
|
||||
f"Grid size: {self.size}, Lower extent: {self.lower_extent}, Upper extent: {self.upper_extent}"
|
||||
)
|
||||
|
@@ -167,7 +167,7 @@ class Model:
|
||||
self.reuse_geometry() if config.get_model_config().reuse_geometry() else self.build_geometry()
|
||||
|
||||
logger.info(
|
||||
f"\nOutput directory: {config.get_model_config().output_file_path.parent.resolve()}"
|
||||
f"Output directory: {config.get_model_config().output_file_path.parent.resolve()}\n"
|
||||
)
|
||||
|
||||
# Adjust position of simple sources and receivers if required
|
||||
@@ -246,15 +246,15 @@ class Model:
|
||||
|
||||
if total_mem_build > total_mem_run:
|
||||
logger.info(
|
||||
f'\nMemory required (estimated): {" + ".join(mem_strs_build)} + '
|
||||
f'Memory required (estimated): {" + ".join(mem_strs_build)} + '
|
||||
f"~{humanize.naturalsize(config.get_model_config().mem_overhead)} "
|
||||
f"overhead = {humanize.naturalsize(total_mem_build)}"
|
||||
f"overhead = {humanize.naturalsize(total_mem_build)}\n"
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
f'\nMemory required (estimated): {" + ".join(mem_strs_run)} + '
|
||||
f'Memory required (estimated): {" + ".join(mem_strs_run)} + '
|
||||
f"~{humanize.naturalsize(config.get_model_config().mem_overhead)} "
|
||||
f"overhead = {humanize.naturalsize(total_mem_run)}"
|
||||
f"overhead = {humanize.naturalsize(total_mem_run)}\n"
|
||||
)
|
||||
|
||||
def reuse_geometry(self):
|
||||
@@ -264,7 +264,7 @@ class Model:
|
||||
f"{config.sim_config.input_file_path}"
|
||||
)
|
||||
config.get_model_config().inputfilestr = (
|
||||
Fore.GREEN + f"{s} {'-' * (get_terminal_width() - 1 - len(s))}\n" + Style.RESET_ALL
|
||||
Fore.GREEN + f"{s} {'-' * (get_terminal_width() - 1 - len(s))}\n\n" + Style.RESET_ALL
|
||||
)
|
||||
logger.basic(config.get_model_config().inputfilestr)
|
||||
self.iteration = 0 # Reset current iteration number
|
||||
@@ -297,7 +297,7 @@ class Model:
|
||||
# Print information about and check OpenMP threads
|
||||
if config.sim_config.general["solver"] == "cpu":
|
||||
logger.basic(
|
||||
f"\nModel {config.sim_config.current_model + 1}/{config.sim_config.model_end} "
|
||||
f"Model {config.sim_config.current_model + 1}/{config.sim_config.model_end} "
|
||||
f"on {config.sim_config.hostinfo['hostname']} "
|
||||
f"with OpenMP backend using {config.get_model_config().ompthreads} thread(s)"
|
||||
)
|
||||
@@ -359,10 +359,10 @@ class Model:
|
||||
mem_str = f" host + unknown for device"
|
||||
|
||||
logger.info(
|
||||
f"\nMemory used (estimated): "
|
||||
f"Memory used (estimated): "
|
||||
+ f"~{humanize.naturalsize(self.p.memory_full_info().uss)}{mem_str}"
|
||||
)
|
||||
logger.info(
|
||||
f"Time taken: "
|
||||
+ f"{humanize.precisedelta(datetime.timedelta(seconds=solver.solvetime), format='%0.4f')}"
|
||||
+ f"{humanize.precisedelta(datetime.timedelta(seconds=solver.solvetime), format='%0.4f')}\n"
|
||||
)
|
||||
|
@@ -80,8 +80,7 @@ class MPIModel(Model):
|
||||
super().write_output_data()
|
||||
|
||||
def _output_geometry(self):
|
||||
if self.is_coordinator():
|
||||
logger.info("Geometry views and geometry objects are not currently supported with MPI.")
|
||||
logger.warn("Geometry views and geometry objects are not currently supported with MPI\n")
|
||||
|
||||
def _create_grid(self) -> MPIGrid:
|
||||
cart_comm = MPI.COMM_WORLD.Create_cart(config.sim_config.mpi)
|
||||
|
@@ -727,7 +727,7 @@ def print_pml_info(G):
|
||||
"""
|
||||
# No PML
|
||||
if all(value == 0 for value in G.pmls["thickness"].values()):
|
||||
return f"\nPML boundaries [{G.name}]: switched off"
|
||||
return f"PML boundaries [{G.name}]: switched off\n"
|
||||
|
||||
if all(value == G.pmls["thickness"]["x0"] for value in G.pmls["thickness"].values()):
|
||||
pmlinfo = str(G.pmls["thickness"]["x0"])
|
||||
@@ -738,6 +738,6 @@ def print_pml_info(G):
|
||||
pmlinfo = pmlinfo[:-2]
|
||||
|
||||
return (
|
||||
f"\nPML boundaries [{G.name}]: {{formulation: {G.pmls['formulation']}, "
|
||||
f"order: {len(G.pmls['cfs'])}, thickness (cells): {pmlinfo}}}"
|
||||
f"PML boundaries [{G.name}]: {{formulation: {G.pmls['formulation']}, "
|
||||
f"order: {len(G.pmls['cfs'])}, thickness (cells): {pmlinfo}}}\n"
|
||||
)
|
||||
|
@@ -48,7 +48,9 @@ def get_host_info():
|
||||
# Manufacturer/model
|
||||
try:
|
||||
manufacturer = (
|
||||
subprocess.check_output(["wmic", "csproduct", "get", "vendor"], shell=False, stderr=subprocess.STDOUT)
|
||||
subprocess.check_output(
|
||||
["wmic", "csproduct", "get", "vendor"], shell=False, stderr=subprocess.STDOUT
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
@@ -59,7 +61,9 @@ def get_host_info():
|
||||
manufacturer = manufacturer[0]
|
||||
model = (
|
||||
subprocess.check_output(
|
||||
["wmic", "computersystem", "get", "model"], shell=False, stderr=subprocess.STDOUT
|
||||
["wmic", "computersystem", "get", "model"],
|
||||
shell=False,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
@@ -76,7 +80,9 @@ def get_host_info():
|
||||
# CPU information
|
||||
try:
|
||||
allcpuinfo = (
|
||||
subprocess.check_output(["wmic", "cpu", "get", "Name"], shell=False, stderr=subprocess.STDOUT)
|
||||
subprocess.check_output(
|
||||
["wmic", "cpu", "get", "Name"], shell=False, stderr=subprocess.STDOUT
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
@@ -109,7 +115,9 @@ def get_host_info():
|
||||
manufacturer = "Apple"
|
||||
try:
|
||||
model = (
|
||||
subprocess.check_output(["sysctl", "-n", "hw.model"], shell=False, stderr=subprocess.STDOUT)
|
||||
subprocess.check_output(
|
||||
["sysctl", "-n", "hw.model"], shell=False, stderr=subprocess.STDOUT
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
@@ -120,14 +128,18 @@ def get_host_info():
|
||||
# CPU information
|
||||
try:
|
||||
sockets = (
|
||||
subprocess.check_output(["sysctl", "-n", "hw.packages"], shell=False, stderr=subprocess.STDOUT)
|
||||
subprocess.check_output(
|
||||
["sysctl", "-n", "hw.packages"], shell=False, stderr=subprocess.STDOUT
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
sockets = int(sockets)
|
||||
cpuID = (
|
||||
subprocess.check_output(
|
||||
["sysctl", "-n", "machdep.cpu.brand_string"], shell=False, stderr=subprocess.STDOUT
|
||||
["sysctl", "-n", "machdep.cpu.brand_string"],
|
||||
shell=False,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
@@ -150,7 +162,9 @@ def get_host_info():
|
||||
# Manufacturer/model
|
||||
try:
|
||||
manufacturer = (
|
||||
subprocess.check_output(["cat", "/sys/class/dmi/id/sys_vendor"], shell=False, stderr=subprocess.STDOUT)
|
||||
subprocess.check_output(
|
||||
["cat", "/sys/class/dmi/id/sys_vendor"], shell=False, stderr=subprocess.STDOUT
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
@@ -170,7 +184,9 @@ def get_host_info():
|
||||
# Locale to ensure English
|
||||
myenv = {**os.environ, "LANG": "en_US.utf8"}
|
||||
cpuIDinfo = (
|
||||
subprocess.check_output(["cat", "/proc/cpuinfo"], shell=False, stderr=subprocess.STDOUT, env=myenv)
|
||||
subprocess.check_output(
|
||||
["cat", "/proc/cpuinfo"], shell=False, stderr=subprocess.STDOUT, env=myenv
|
||||
)
|
||||
.decode("utf-8")
|
||||
.strip()
|
||||
)
|
||||
@@ -237,7 +253,7 @@ def print_host_info(hostinfo):
|
||||
else ""
|
||||
)
|
||||
logger.basic(
|
||||
f"\n{config.sim_config.hostinfo['hostname']} | "
|
||||
f"{config.sim_config.hostinfo['hostname']} | "
|
||||
f"{config.sim_config.hostinfo['machineID']} | "
|
||||
f"{hostinfo['sockets']} x {hostinfo['cpuID']} "
|
||||
f"({hostinfo['physicalcores']} cores{hyperthreadingstr}) | "
|
||||
|
@@ -71,7 +71,10 @@ def logo(version):
|
||||
str: string containing logo, version, and licencing/copyright info.
|
||||
"""
|
||||
|
||||
description = "\n=== Electromagnetic modelling software based on the " "Finite-Difference Time-Domain (FDTD) method"
|
||||
description = (
|
||||
"\n=== Electromagnetic modelling software based on the "
|
||||
"Finite-Difference Time-Domain (FDTD) method"
|
||||
)
|
||||
current_year = datetime.datetime.now().year
|
||||
copyright = f"Copyright (C) 2015-{current_year}: The University of " "Edinburgh, United Kingdom"
|
||||
authors = "Authors: Craig Warren, Antonis Giannopoulos, and John Hartley"
|
||||
@@ -109,15 +112,30 @@ def logo(version):
|
||||
|
||||
str = f"{description} {'=' * (get_terminal_width() - len(description) - 1)}\n\n"
|
||||
str += f"{Fore.CYAN}{logo}"
|
||||
str += Style.RESET_ALL + textwrap.fill(copyright, width=get_terminal_width() - 1, initial_indent=" ") + "\n"
|
||||
str += (
|
||||
Style.RESET_ALL
|
||||
+ textwrap.fill(copyright, width=get_terminal_width() - 1, initial_indent=" ")
|
||||
+ "\n"
|
||||
)
|
||||
str += textwrap.fill(authors, width=get_terminal_width() - 1, initial_indent=" ") + "\n\n"
|
||||
str += (
|
||||
textwrap.fill(licenseinfo1, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" ") + "\n"
|
||||
textwrap.fill(
|
||||
licenseinfo1, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" "
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
str += (
|
||||
textwrap.fill(licenseinfo2, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" ") + "\n"
|
||||
textwrap.fill(
|
||||
licenseinfo2, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" "
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
str += (
|
||||
textwrap.fill(
|
||||
licenseinfo3, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" "
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
str += textwrap.fill(licenseinfo3, width=get_terminal_width() - 1, initial_indent=" ", subsequent_indent=" ")
|
||||
|
||||
return str
|
||||
|
||||
|
在新工单中引用
屏蔽一个用户