Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ddb2cbb
WIP: logfile
Antoniahuber Nov 10, 2025
37355f1
Merge branch 'main' of github.com:Antoniahuber/wakis
Antoniahuber Nov 10, 2025
28d4c74
Created Logfile and amended the test
Antoniahuber Nov 10, 2025
d04601b
Delete build/lib/wakis/__init__.py
Antoniahuber Nov 11, 2025
35f5090
Delete build/lib/wakis/_version.py
Antoniahuber Nov 11, 2025
70e5f61
Delete build/lib/wakis/conductors.py
Antoniahuber Nov 11, 2025
8ba80b5
Delete build/lib/wakis/conductors3d.py
Antoniahuber Nov 11, 2025
57d9695
Delete build/lib/wakis/field.py
Antoniahuber Nov 11, 2025
869fdb9
Delete build/lib/wakis/pmlBlock2D.py
Antoniahuber Nov 11, 2025
5d6afec
Delete build/lib/wakis/pmlBlock3D.py
Antoniahuber Nov 11, 2025
44df15c
Delete build/lib/wakis/routines.py
Antoniahuber Nov 11, 2025
2b2dbef
Delete build/lib/wakis/plotting.py
Antoniahuber Nov 11, 2025
8d1de64
Delete build/lib/wakis/geometry.py
Antoniahuber Nov 11, 2025
5f6b384
Delete build/lib/wakis/grid2D.py
Antoniahuber Nov 11, 2025
c8776ea
Delete build/lib/wakis/grid3D.py
Antoniahuber Nov 11, 2025
9865cd5
Delete build/lib/wakis/gridFIT3D.py
Antoniahuber Nov 11, 2025
8ea836f
Delete build/lib/wakis/materials.py
Antoniahuber Nov 11, 2025
7dfbf30
Delete build/lib/wakis/solver2D.py
Antoniahuber Nov 11, 2025
9807faf
Delete build/lib/wakis/solver3D.py
Antoniahuber Nov 11, 2025
17df67e
Delete build/lib/wakis/solverFIT3D.py
Antoniahuber Nov 11, 2025
a2dd44e
Delete build/lib/wakis/sources.py
Antoniahuber Nov 11, 2025
c4ee763
Delete build/lib/wakis/wakeSolver.py
Antoniahuber Nov 11, 2025
597c7e7
Merge pull request #2 from Antoniahuber/Antoniahuber-delete-unnecessa…
Antoniahuber Nov 11, 2025
57f2903
Refactor log variable names in test file
Antoniahuber Nov 11, 2025
baebebe
Refactor logger to use 'grid' instead of 'grid_logs'
Antoniahuber Nov 11, 2025
9a1e2da
Refactor Logger class to stick to camelCase
Antoniahuber Nov 11, 2025
e301c3d
Fix logger attribute assignment for wakeSolver
Antoniahuber Nov 11, 2025
c853b4b
Refactor logger attribute assignments in solverFIT3D
Antoniahuber Nov 11, 2025
b27588b
Change logger dictionary from wakeSolver_logs to wakeSolver
Antoniahuber Nov 11, 2025
796080a
Fix logger reference for wakeSolver
Antoniahuber Nov 11, 2025
c5a0ed5
Fix logger grid assignment in solverFIT3D.py
Antoniahuber Nov 11, 2025
c54d7f2
Rename bg_log to bgLog in solverFIT3D.py
Antoniahuber Nov 11, 2025
6bf3abf
Update logger attribute access in test case
Antoniahuber Nov 11, 2025
5583963
Fix logfile path in MPI lossy cavity test
Antoniahuber Nov 11, 2025
f016124
Merge branch 'ImpedanCEI:main' into main
Antoniahuber Nov 12, 2025
e198fb9
Exchanged function assign_logger by update_logger
Antoniahuber Nov 13, 2025
f22c209
Fixed bugs
Antoniahuber Nov 13, 2025
d7e3840
Fixed bug
Antoniahuber Nov 13, 2025
a19ab61
Exchange list by dictionary in comparison
Antoniahuber Nov 13, 2025
c1f59e0
Fix indentation in gridLogs dictionary
Antoniahuber Nov 13, 2025
9a68490
Fix indentation in solverLogs dictionary
Antoniahuber Nov 13, 2025
534792c
Separate changes from another pull request
Antoniahuber Nov 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/test_001_pec_cubic_cavity.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_simulation(self):
skip_cells = 12 # no. cells to skip in WP integration
wake = WakeSolver(q=q, sigmaz=sigmaz, beta=beta,
xsource=xs, ysource=ys, xtest=xt, ytest=yt,
save=False, logfile=False, Ez_file='tests/001_Ez.h5',
save=False, Ez_file='tests/001_Ez.h5',
skip_cells=skip_cells,
)

Expand Down
24 changes: 23 additions & 1 deletion tests/test_007_mpi_lossy_cavity.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ class TestMPILossyCavity:
-6.04105997e+01 ,-3.06532160e+01 ,-1.17749936e+01 ,-3.12574866e+00,
-7.35339521e-01 ,-1.13085658e-01 , 7.18247535e-01 , 8.73829036e-02])

gridLogs = {'Nx': 60, 'Ny': 60, 'Nz': 140, 'dx': 0.008666666348775227, 'dy': 0.008666666348775227,
'dz': 0.005714285799435207, 'stl_solids': ['tests/stl/007_vacuum_cavity.stl', 'tests/stl/007_lossymetal_shell.stl'],
'stl_materials': ['vacuum', [30, 1.0, 30]], 'gridInitializationTime': 0}

solverLogs = {'use_gpu': False, 'use_mpi': False, 'bc_low': ['pec', 'pec', 'pec'],
'bc_high': ['pec', 'pec', 'pec'], 'n_pml': 10, 'bg': 'pec',
'dt': 6.970326728398968e-12, 'solverInitializationTime': 0}

wakeSolverLogs = {'ti': 2.8516132094735135e-09, 'q': 1e-09, 'sigmaz': 0.1, 'beta': 1.0,
'xsource': 0.0, 'ysource': 0.0, 'xtest': 0.0, 'ytest': 0.0, 'chargedist': None,
'skip_cells': 10, 'results_folder': 'tests/007_results/', 'wakelength': 10.0, 'simulationTime': 0}

img_folder = 'tests/007_img/'

def test_mpi_import(self):
Expand Down Expand Up @@ -314,4 +326,14 @@ def test_long_impedance(self):
assert np.allclose(np.real(wake.Z)[::20], np.real(self.Z), rtol=0.1), "Real Impedance samples failed"
assert np.allclose(np.imag(wake.Z)[::20], np.imag(self.Z), rtol=0.1), "Imag Impedance samples failed"
assert np.cumsum(np.abs(wake.Z))[-1] == pytest.approx(250910.51090497518, 0.1), "Abs Impedance cumsum failed"


def test_log_file(self):
global solver
solver.logger.grid["gridInitializationTime"] = 0 #times can vary
solver.logger.solver["solverInitializationTime"] = 0
solver.logger.wakeSolver["simulationTime"] = 0
logfile = os.path.join(solver.logger.wakeSolver["results_folder"], "Simulation_Parameters.log")
assert os.path.exists(logfile), "Log file not created"
assert solver.logger.grid == self.gridLogs, "Grid logs do not match expected values"
assert solver.logger.solver == self.solverLogs, "Solver logs do not match expected values"
assert solver.logger.wakeSolver == self.wakeSolverLogs, "WakeSolver logs do not match expected values"
2 changes: 2 additions & 0 deletions wakis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
from . import materials
from . import wakeSolver
from . import geometry
from . import logger
from . import field_monitors

from .field_monitors import FieldMonitor
from .field import Field
from .gridFIT3D import GridFIT3D
from .solverFIT3D import SolverFIT3D
from .wakeSolver import WakeSolver
from .logger import Logger

from ._version import __version__
23 changes: 22 additions & 1 deletion wakis/gridFIT3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import pyvista as pv
from functools import partial
from scipy.optimize import least_squares
import time

from .field import Field
from .logger import Logger

try:
from mpi4py import MPI
Expand Down Expand Up @@ -63,6 +65,7 @@ def __init__(self, xmin, xmax, ymin, ymax, zmin, zmax,
stl_rotate=[0., 0., 0.], stl_translate=[0., 0., 0.], stl_scale=1.0,
stl_colors=None, verbose=1, stl_tol=1e-3):

t0 = time.time()
if verbose: print('Generating grid...')
self.verbose = verbose
self.use_mpi = use_mpi
Expand Down Expand Up @@ -143,6 +146,24 @@ def __init__(self, xmin, xmax, ymin, ymax, zmin, zmax,
if stl_colors is None:
self.assign_colors()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as in SolverFIT3D

# Forward Parameters to logger
self.logger = Logger()
self.logger.grid["Nx"] = self.Nx
self.logger.grid["Ny"] = self.Ny
self.logger.grid["Nz"] = self.Nz
self.logger.grid["dx"] = self.dx
self.logger.grid["dy"] = self.dy
self.logger.grid["dz"] = self.dz
self.logger.grid["stl_solids"] = list(self.stl_solids.values()) if self.stl_solids is not None else []
self.logger.grid["stl_materials"] = list(self.stl_materials.values()) if self.stl_materials is not None else []
if stl_rotate != [0., 0., 0.]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice, I really like this :) helps keep the logger short

self.logger.grid["stl_rotate"] = self.stl_rotate
if stl_translate != [0., 0., 0.]:
self.logger.grid["stl_translate"] = self.stl_translate
if stl_scale != 1.0:
self.logger.grid["stl_scale"] = self.stl_scale
self.logger.grid["gridInitializationTime"] = time.time()-t0

def compute_grid(self):
X, Y, Z = np.meshgrid(self.x, self.y, self.z, indexing='ij')
self.grid = pv.StructuredGrid(X.transpose(), Y.transpose(), Z.transpose())
Expand Down Expand Up @@ -838,4 +859,4 @@ def clip(widget):
if offscreen:
pl.export_html('grid_inspect.html')
else:
pl.show()
pl.show()
67 changes: 67 additions & 0 deletions wakis/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# copyright ################################# #
# This file is part of the wakis Package. #
# Copyright (c) CERN, 2025. #
# ########################################### #

from tqdm import tqdm

import numpy as np
import time
import h5py
import os
import json

from scipy.constants import c as c_light, epsilon_0 as eps_0, mu_0 as mu_0
from scipy.sparse import csc_matrix as sparse_mat
from scipy.sparse import diags, hstack, vstack



class Logger():

def __init__(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to stick to camelCase convention, we should avoid using underscores _. Do you think it would be still legible if we remove the _logs? like this we keep the variable format a bit more uniform. In the end, you call it using logger.wakeSolver so the log is implicit? What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think that is fine. Should I remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

self.grid = {}
self.solver = {}
self.wakeSolver = {}

def save_logs(self):
"""
Save all logs (grid, solver, wakeSolver) into log-file inside the results folder.
"""
logfile = os.path.join(self.wakeSolver["results_folder"], "Simulation_Parameters.log")

# Write sections
if not os.path.exists(self.wakeSolver["results_folder"]):
os.mkdir(self.wakeSolver["results_folder"])

with open(logfile, "w", encoding="utf-8") as fh:
fh.write("Simulation Parameters\n")
fh.write("""=====================\n\n""")

sections = [
("WakeSolver Logs", self.wakeSolver),
("Solver Logs", self.solver),
("Grid Logs", self.grid),
]

for title, data in sections:
fh.write(f"\n## {title} ##\n")
if not data:
fh.write("(empty)\n")
continue

# convert non-serializable values to strings recursively
def _convert(obj):
if isinstance(obj, dict):
return {k: _convert(v) for k, v in obj.items()}
if isinstance(obj, (list, tuple)):
return [_convert(v) for v in obj]
try:
json.dumps(obj)
return obj
except Exception:
return str(obj)

clean = _convert(data)
fh.write(json.dumps(clean, indent=2, ensure_ascii=False))
fh.write("\n")
9 changes: 8 additions & 1 deletion wakis/routines.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import numpy as np
import h5py
import time
from tqdm import tqdm
from scipy.constants import c as c_light
from wakis.sources import Beam
Expand Down Expand Up @@ -297,6 +298,7 @@ def save_to_h5(self, hf, field, x, y, z, comp, n):
if plot_from is None: plot_from = int(self.ti/self.dt)

print('Running electromagnetic time-domain simulation...')
t0 = time.time()
for n in tqdm(range(Nt)):

# Initial condition
Expand Down Expand Up @@ -340,4 +342,9 @@ def save_to_h5(self, hf, field, x, y, z, comp, n):

# Compute wakefield magnitudes is done inside WakeSolver
self.wake.solve(compute_plane=compute_plane)


# Forward parameters to logger
self.logger.wakeSolver=self.wake.logger.wakeSolver
self.logger.wakeSolver["wakelength"]=wakelength
self.logger.wakeSolver["simulationTime"]=time.time()-t0
self.logger.save_logs()
19 changes: 16 additions & 3 deletions wakis/solverFIT3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .materials import material_lib
from .plotting import PlotMixin
from .routines import RoutinesMixin
from .logger import Logger

try:
from cupyx.scipy.sparse import csc_matrix as gpu_sparse_mat
Expand Down Expand Up @@ -93,7 +94,7 @@ def __init__(self, grid, wake=None, cfln=0.5, dt=None,
'''

self.verbose = verbose
if verbose: t0 = time.time()
t0 = time.time()

# Flags
self.step_0 = True
Expand All @@ -113,7 +114,7 @@ def __init__(self, grid, wake=None, cfln=0.5, dt=None,

# Grid
self.grid = grid

bgLog = bg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I like this one :( we can simply add it to self as self.bg or maybe even better self.background--I should have called background since the beginning...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, I thought there was already a self.bg, but apparently there is none. Then I prefer the self.background myself

self.Nx = self.grid.Nx
self.Ny = self.grid.Ny
self.Nz = self.grid.Nz
Expand Down Expand Up @@ -252,6 +253,18 @@ def __init__(self, grid, wake=None, cfln=0.5, dt=None,

if verbose: print(f'Total initialization time: {time.time() - t0} s')

# assign logs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, we're almost there!!!

I was thinking, in order to keep the (already long) _init__ short and legible, should we populate/assign the logs in a separate method? I was thinking something private like _assign_logs(self) where we can allocate all this variables since they are already contained in self.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that makes the code clearer. I will do it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I do that I see a problem with self.bc_low and self.bc_high. They are both changed if use_mpi is True: if self.use_mpi and self.grid.use_mpi:
if self.rank > 0:
self.bc_low=['pec', 'pec', 'mpi'] In that case you can't comprehend, what the z boundary condition was originally, can you? And if you called the assign_log function before, you wouldn't get the initialization time of the solver

self.logger = Logger()
self.logger.grid = self.grid.logger.grid
self.logger.solver["use_gpu"] = use_gpu
self.logger.solver["use_mpi"] = use_mpi
self.logger.solver["bc_low"] = bc_low
self.logger.solver["bc_high"] = bc_high
self.logger.solver["n_pml"] = n_pml
self.logger.solver["bg"] = bgLog
self.logger.solver["dt"] = self.dt
self.logger.solver["solverInitializationTime"] = time.time() - t0

def update_tensors(self, tensor='all'):
'''Update tensor matrices after
Field ieps, imu or sigma have been modified
Expand Down Expand Up @@ -1107,4 +1120,4 @@ def reset_fields(self):
for d in ['x', 'y', 'z']:
self.E[:, :, :, d] = 0.0
self.H[:, :, :, d] = 0.0
self.J[:, :, :, d] = 0.0
self.J[:, :, :, d] = 0.0
30 changes: 17 additions & 13 deletions wakis/wakeSolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from tqdm import tqdm
from scipy.constants import c as c_light

from .logger import Logger

class WakeSolver():
''' Class for wake potential and impedance
calculation from 3D time domain E fields
Expand All @@ -22,7 +24,7 @@ def __init__(self, wakelength=None, q=1e-9, sigmaz=1e-3, beta=1.0,
chargedist=None, ti=None,
compute_plane='both', skip_cells=0, add_space=None,
Ez_file='Ez.h5', save=True, results_folder='results/',
verbose=0, logfile=False, counter_moving=False):
verbose=0, counter_moving=False):
'''
Parameters
----------
Expand Down Expand Up @@ -61,9 +63,6 @@ def __init__(self, wakelength=None, q=1e-9, sigmaz=1e-3, beta=1.0,
- Charge distribution: lambda.txt, spectrum.txt
verbose: bool, default 0
Controls the level of verbose in the terminal output
logfile: bool, default False
Creates a `wake.log` file with the summary of the input parameters
and calculations performed
counter_moving: bool, default False
If the test charge is moving in the same or opposite direction to the source

Expand Down Expand Up @@ -161,8 +160,8 @@ def __init__(self, wakelength=None, q=1e-9, sigmaz=1e-3, beta=1.0,

#user
self.verbose = verbose
self.logger = Logger()
self.save = save
self.logfile = logfile
self.folder = results_folder

if self.save:
Expand All @@ -173,6 +172,19 @@ def __init__(self, wakelength=None, q=1e-9, sigmaz=1e-3, beta=1.0,
if self.log:
self.params_to_log()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as in SolverFIT3D

Also, should we remove the self.params_to_log()?

# Forward parameters to logger
self.logger.wakeSolver["ti"]=self.ti
self.logger.wakeSolver["q"]=self.q
self.logger.wakeSolver["sigmaz"]=self.sigmaz
self.logger.wakeSolver["beta"]=self.beta
self.logger.wakeSolver["xsource"]=self.xsource
self.logger.wakeSolver["ysource"]=self.ysource
self.logger.wakeSolver["xtest"]=self.xtest
self.logger.wakeSolver["ytest"]=self.ytest
self.logger.wakeSolver["chargedist"]=self.chargedist
self.logger.wakeSolver["skip_cells"]=self.skip_cells
self.logger.wakeSolver["results_folder"]=self.folder

def solve(self, compute_plane=None, **kwargs):
'''
Perform the wake potential and impedance for
Expand Down Expand Up @@ -1114,14 +1126,6 @@ def log(self, txt):

if self.verbose:
print('\x1b[2;37m'+txt+'\x1b[0m')

if not self.logfile:
return

title = 'wake'
f = open(title + '.log', "a")
f.write(txt + '\r\n')
f.close()

def params_to_log(self):
self.log(time.asctime())
Expand Down
Loading