Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
5b1bb41
Started to create new class Simulations.
spossann Feb 6, 2026
9892bd5
go back tobase.py from devel
spossann Feb 9, 2026
6f95936
back to devel setup.py
spossann Feb 9, 2026
be045e1
use Simulations in main.run()
spossann Feb 9, 2026
06c025b
everything until setup_equation_params has been moved to Simulation c…
spossann Feb 9, 2026
818dfcb
sim.allocate and sim.compute_plasma_params work
spossann Feb 10, 2026
d740d89
uncomment sim.run
spossann Feb 10, 2026
d0a899f
Simulation.run works for Maxwell
spossann Feb 11, 2026
ea3ec26
have methods called within sim.run()
spossann Feb 11, 2026
e58af43
new base class Simulation; then inherit StruphySimulation(Simulation)
spossann Feb 11, 2026
93f9d84
clean up StruphyModel base class
spossann Feb 11, 2026
408fd44
remove unused dependencies in StruphyModel
spossann Feb 11, 2026
a6fec84
move initial Poisson solve into allocate_helpers; adapt some models
spossann Feb 11, 2026
1b80e8a
use Propagator in models to retrieve derham, mass_ops, etc.
spossann Feb 11, 2026
fcbb2c3
new method StruphyImulation.pproc(); move the pproc logic to the sim …
spossann Feb 11, 2026
7e11b9d
model tests pass with pproc
spossann Feb 12, 2026
59f77ef
move pproc and load_plotting_data into module file and allow for pass…
spossann Feb 12, 2026
ad28994
add pproc and load_plotting_data to api
spossann Feb 12, 2026
ae7c929
add verbose= to all methods in StruphySimulation
spossann Feb 12, 2026
b0645f3
remove path_pproc attibute from StruphySimulation
spossann Feb 12, 2026
4298cb6
rename codes.yp -> sim.py
spossann Feb 12, 2026
957c6c4
in the middle of reworking pproc
spossann Feb 12, 2026
5935970
debug post_processing_tools
spossann Feb 13, 2026
94fd8ba
formatting
spossann Feb 13, 2026
75e42a2
return post_processor and plotting data objects in Simulation
spossann Feb 13, 2026
b023cdc
add setters to Simulation parameters attributes; use __repr__ to disp…
spossann Feb 13, 2026
37d1c56
remove setters in SImulation
spossann Feb 13, 2026
41f8c89
make verification tests run
spossann Feb 13, 2026
7caacea
formatting
spossann Feb 13, 2026
f2ccfeb
Merge branch 'devel' into simulation-class
spossann Feb 13, 2026
acc0f90
improved the look of the generated default parameter fiel: added a de…
spossann Feb 16, 2026
98b6b9a
formatting
spossann Feb 16, 2026
e26aed4
rename set_phys_params() to set_species_properties()
spossann Feb 16, 2026
90fe4e0
set background for all kinetic species
spossann Feb 16, 2026
ce67cc1
add -x flag to pytest commands
spossann Feb 16, 2026
9c2cd4d
initialize PostProcessor and PlottingData only on rank 0
spossann Feb 16, 2026
2bc2bf0
run ruff check
spossann Feb 16, 2026
ba86e7e
formatting
spossann Feb 16, 2026
5ac6a39
new commit in struphy-tutorials
spossann Feb 16, 2026
e0544eb
disable the ruff format check
spossann Feb 16, 2026
408ace4
improve screen output of simulation
spossann Feb 16, 2026
729613f
bug fix and formatting
spossann Feb 17, 2026
30f0548
pass params_path=__file__ to StruphySimulation
spossann Feb 17, 2026
1449b5e
introduce class properties in Particles classes; move deletion of dat…
spossann Feb 17, 2026
3d0ded5
fix quickstart
spossann Feb 17, 2026
d9802b9
new method spawn_sister() in StruphySimulation
spossann Feb 17, 2026
e6f7dfe
make Maxwell the default model in a simulation
spossann Feb 17, 2026
94a3b6b
remove print statement in model __init__
spossann Feb 17, 2026
fc51176
fixed tutorial 02; nices screen output; new classes for plotting data
spossann Feb 18, 2026
d555866
set defaults for species properties; new method Simulation.normalize_…
spossann Feb 19, 2026
936fb4f
fix test_init_perturbations.py
spossann Feb 19, 2026
3e6d417
fix verification tests
spossann Feb 19, 2026
09c21ca
formatting
spossann Feb 19, 2026
0fe18e0
rename StruphySimulation -> Simulation
spossann Feb 19, 2026
a08545a
add .data when laoding spline_values
spossann Feb 19, 2026
7e02b7f
actually remove main.py
spossann Feb 19, 2026
8502a39
add docstrings to Simulation class
spossann Feb 19, 2026
de65955
remove import main
spossann Feb 20, 2026
72d3ad8
added some docstrings to StruphyModel, Species and Variable
spossann Feb 20, 2026
1cdd3c0
formatting
spossann Feb 20, 2026
e482fdb
add docstrings to classes that are exposed in the API
spossann Feb 20, 2026
916ac63
Merge branch 'devel' into simulation-class
spossann Feb 20, 2026
4f1ecf2
add tests for submodule struphy-parameter-files
spossann Feb 20, 2026
30995ba
adapted submodeule struphy-parameter-files
spossann Feb 20, 2026
470190c
formatting
spossann Feb 20, 2026
0ad81d8
new submod commit
spossann Feb 20, 2026
75edcef
Merge branch 'devel' into simulation-class
spossann Feb 23, 2026
d53a125
new commit in submodule struphy-tutorials
spossann Feb 23, 2026
d8e3a09
add noslip boundary conditions for sph
spossann Feb 23, 2026
425fe55
Test for boundary condition. work in progress
aminrai2000 Feb 23, 2026
39ea742
unit test for no slip boundary conditions finished
aminrai2000 Feb 24, 2026
3f9e77d
Merge branch 'devel' into noslip-sph-bc
aminrai2000 Feb 24, 2026
54d7295
add the possibility to flip the entry at mean_velocity_index of ghost…
spossann Feb 27, 2026
68b2f76
test for y and z direction of noslip bc
aminrai2000 Mar 4, 2026
f70ece3
rework self.u_init for sph perturbations; start with gaussian blob te…
spossann Mar 16, 2026
cf9c811
Unit test for no-slip boundary conditions finished for all directions
aminrai2000 Mar 16, 2026
f3206ea
kernels fixed for test
aminrai2000 Mar 16, 2026
c1701c5
restore some formatting to previous commit
spossann Mar 17, 2026
24f207d
formatting
spossann Mar 17, 2026
b3e7c63
Merge branch 'devel' into noslip-sph-bc
spossann Mar 17, 2026
6799b9e
add def mean_velocity_index
spossann Mar 17, 2026
ff14b99
Merge branch 'devel' into noslip-sph-bc
spossann Mar 20, 2026
a5ac379
in eval_kernels_gc, skip for not valid markers (instead of holes)
spossann Mar 24, 2026
29e766b
formatting
spossann Mar 24, 2026
2d8e2bf
Merge branch 'devel' into noslip-sph-bc
spossann Mar 24, 2026
38bbb65
Merge branch 'noslip-sph-bc' into gaussian-blob-sph
spossann Mar 24, 2026
05e7237
set f_visc[:]=0 at the start of the viscous kernel sph evaluation
spossann Mar 24, 2026
d92e937
Merge branch 'devel' into gaussian-blob-sph
spossann Mar 25, 2026
bd9f738
formatting
spossann Mar 25, 2026
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
32 changes: 32 additions & 0 deletions src/struphy/initial/perturbations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,38 @@ def __call__(self, e1, e2, e3):
return val


class GaussianBlobEta1(Perturbation):
r"""Gaussian blob in eta1.

.. math::

u(\eta_1, \eta_2, \eta_3) = A \exp \left(- \frac{(\eta_1 - 0.5)^2}{2 \sigma^2} \right) \,.
"""

def __init__(
self,
center: float = 0.5,
amp: float = 1e-1,
sigma: float = 0.1,
given_in_basis: LiteralOptions.GivenInBasis = None,
comp: int = 0,
):
if given_in_basis is not None:
assert "physical" not in given_in_basis, f"Perturbation {self.__name__} can only be used in logical space."

self._center = center
self._amp = amp
self._sigma = sigma

# use the setters
self.given_in_basis = given_in_basis
self.comp = comp

def __call__(self, e1, e2, e3):
val = self._amp * xp.exp(-((e1 - self._center) ** 2) / (2.0 * self._sigma**2))
return val


class Erf_z(Perturbation):
r"""Shear layer in eta3 (-1 in lower regions, 1 in upper regions).

Expand Down
137 changes: 136 additions & 1 deletion src/struphy/models/tests/verification/test_verif_ViscousEulerSPH.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import shutil

import cunumpy as xp
import h5py
import pytest
from feectools.ddm.mpi import mpi as MPI
from matplotlib import pyplot as plt
Expand Down Expand Up @@ -161,5 +162,139 @@ def test_soundwave_1d(nx: int, plot_pts: int, do_plot: bool = False):
shutil.rmtree(test_folder)


@pytest.mark.parametrize("nx", [12, 24])
@pytest.mark.parametrize("plot_pts", [11, 32])
def test_viscosity_1d(nx: int, plot_pts: int, do_plot: bool = False):
"""Verification test for SPH discretization of viscosity in Euler equations.
A Gaussian blob in vx diffuses in periodic boundary conditions.
"""

# environment options
test_folder = os.path.join(os.getcwd(), "struphy_verification_tests")
out_folders = os.path.join(test_folder, "ViscousEulerSPH")
env = EnvironmentOptions(out_folders=out_folders, sim_folder="viscosity_1d")

# units
base_units = BaseUnits(kBT=1.0)

# time stepping
time_opts = Time(dt=0.01, Tend=1.0, split_algo="LieTrotter")

# geometry
r1 = 1.0
domain = domains.Cuboid(r1=r1)

# grid
grid = None

# derham options
derham_opts = None

# light-weight model instance
model = ViscousEulerSPH(with_B0=False, with_p=False, with_viscosity=True)

# species parameters
model.euler_fluid.set_species_properties()

loading_params = LoadingParameters(ppb=100, loading="tesselation")
weights_params = WeightsParameters()
boundary_params = BoundaryParameters(bc_sph=("periodic", "periodic", "periodic"))
model.euler_fluid.set_markers(
loading_params=loading_params,
weights_params=weights_params,
boundary_params=boundary_params,
)
model.euler_fluid.set_sorting_boxes(
boxes_per_dim=(nx, 1, 1),
dims_maks=(True, False, False),
)

bin_plot = BinningPlot(slice="e1", n_bins=(32,), ranges=(0.0, 1.0), output_quantity="current_1")
kd_plot = KernelDensityPlot(pts_e1=plot_pts, pts_e2=1)
model.euler_fluid.set_save_data(
binning_plots=(bin_plot,),
kernel_density_plots=(kd_plot,),
)

# propagator options
from struphy.ode.utils import ButcherTableau

butcher = ButcherTableau(algo="forward_euler")
# model.propagators.push_eta.options = model.propagators.push_eta.Options(butcher=butcher)
if model.with_viscosity:
model.propagators.push_viscous.options = model.propagators.push_viscous.Options(
kernel_type="gaussian_1d", mu=0.1
)

# background, perturbations and initial conditions
background = equils.ConstantVelocity()
model.euler_fluid.var.add_background(background)
# perturbation = perturbations.GaussianBlobEta1(center=0.5, amp=1.0, sigma=0.1)
perturbation = perturbations.ModesSin(ls=(1,), amps=(1.0,))
model.euler_fluid.var.add_perturbation(del_u1=perturbation)

# instance of simulation
sim = Simulation(
model=model,
env=env,
base_units=base_units,
time_opts=time_opts,
domain=domain,
grid=grid,
derham_opts=derham_opts,
verbose=True,
)

# run
sim.run(verbose=True)

# get scalar data
if MPI.COMM_WORLD.Get_rank() == 0:
pa_data = os.path.join(env.path_out, "data")
with h5py.File(os.path.join(pa_data, "data_proc0.hdf5"), "r") as f:
time = f["time"]["value"][()]
en_kin = f["scalar"]["en_kin"][()]

# plot
if do_plot:
plt.figure(figsize=(18, 12))
plt.plot(time, en_kin, label="numerical")
plt.legend()
plt.show()

# post processing
if MPI.COMM_WORLD.Get_rank() == 0:
sim.pproc(verbose=True)

# diagnostics
sim.load_plotting_data(env.path_out)

shp = sim.t_grid.size
grid_e1 = sim.f.euler_fluid.e1_current_1.grid_e1
f_binned = sim.f.euler_fluid.e1_current_1.f_binned
print(f_binned.shape)

if do_plot:
plt.figure(figsize=(20, 8))
plt.subplot(1, 4, 1)
plt.plot(grid_e1, f_binned[0, :], label=f"time {sim.t_grid[0]}")
plt.title(f"time {sim.t_grid[0]}")
plt.ylim([-1, 1])
plt.subplot(1, 4, 2)
plt.plot(grid_e1, f_binned[shp // 3, :], label=f"time {sim.t_grid[shp // 3]}")
plt.title(f"time {sim.t_grid[shp // 3]}")
plt.ylim([-1, 1])
plt.subplot(1, 4, 3)
plt.plot(grid_e1, f_binned[2 * shp // 3, :], label=f"time {sim.t_grid[2 * shp // 3]}")
plt.title(f"time {sim.t_grid[2 * shp // 3]}")
plt.ylim([-1, 1])
plt.subplot(1, 4, 4)
plt.plot(grid_e1, f_binned[-1, :], label=f"time {sim.t_grid[-1]}")
plt.title(f"time {sim.t_grid[-1]}")
plt.ylim([-1, 1])
plt.show()


if __name__ == "__main__":
test_soundwave_1d(nx=12, plot_pts=11, do_plot=True)
# test_soundwave_1d(nx=12, plot_pts=11, do_plot=True)
test_viscosity_1d(nx=12, plot_pts=11, do_plot=True)
4 changes: 2 additions & 2 deletions src/struphy/models/viscous_euler_sph.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __init__(self):

class Propagators:
def __init__(self, with_B0: bool = True, with_p: bool = True, with_viscosity: bool = True):
self.push_eta = propagators_markers.PushEta()
# self.push_eta = propagators_markers.PushEta()
if with_B0:
self.push_vxb = propagators_markers.PushVxB()
if with_p:
Expand All @@ -98,7 +98,7 @@ def __init__(self, with_B0: bool = True, with_p: bool = True, with_viscosity: bo
self.propagators = self.Propagators(with_B0=with_B0, with_p=with_p, with_viscosity=with_viscosity)

# 3. assign variables to propagators
self.propagators.push_eta.variables.var = self.euler_fluid.var
# self.propagators.push_eta.variables.var = self.euler_fluid.var
if with_B0:
self.propagators.push_vxb.variables.ions = self.euler_fluid.var
if with_p:
Expand Down
58 changes: 47 additions & 11 deletions src/struphy/pic/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1291,8 +1291,10 @@ def _set_initial_condition(self):
else:
assert isinstance(self.f0, FluidEquilibrium)

# get vector-field representation of the fluid velocity
self._u_init = self.f0.uv
_del_n = None
_del_u1 = None
_del_u2 = None
_del_u3 = None

if self.perturbations is not None:
for (
Expand All @@ -1308,7 +1310,7 @@ def _set_initial_condition(self):
if pert.given_in_basis is None:
pert.given_in_basis = "0"

_fun = TransformedPformComponent(
_del_n = TransformedPformComponent(
pert,
pert.given_in_basis,
"0",
Expand All @@ -1318,24 +1320,24 @@ def _set_initial_condition(self):
elif moment == "u1":
if pert.given_in_basis is None:
pert.given_in_basis = "v"
_fun = TransformedPformComponent(
_del_u1 = TransformedPformComponent(
pert,
pert.given_in_basis,
"v",
comp=pert.comp,
domain=self.domain,
)
self._u_init = lambda e1, e2, e3: self.f0.uv(e1, e2, e3) + _fun(e1, e2, e3)
# TODO: add other velocity components
# self._u_init = lambda e1, e2, e3: self.f0.uv(e1, e2, e3) + _del_u1(e1, e2, e3)
# # TODO: add other velocity components
else:
_fun = None
_del_n = None

def _f_init(*etas, flat_eval=False):
if len(etas) == 1:
if _fun is None:
if _del_n is None:
out = self.f0.n0(etas[0])
else:
out = self.f0.n0(etas[0]) + _fun(*etas[0].T)
out = self.f0.n0(etas[0]) + _del_n(*etas[0].T)
else:
assert len(etas) == 3
E1, E2, E3, is_sparse_meshgrid = Domain.prepare_eval_pts(
Expand All @@ -1347,10 +1349,42 @@ def _f_init(*etas, flat_eval=False):

out0 = self.f0.n0(E1, E2, E3)

if _fun is None:
if _del_n is None:
out = out0
else:
out1 = _fun(E1, E2, E3)
out1 = _del_n(E1, E2, E3)
assert out0.shape == out1.shape
out = out0 + out1

if flat_eval:
out = xp.squeeze(out)

return out

def _u_init(*etas, flat_eval=False):
if len(etas) == 1:
out = self.f0.uv(etas[0])
if _del_u1 is not None:
out[0] += _del_u1(*etas[0].T)
if _del_u2 is not None:
out[1] += _del_u2(*etas[0].T)
if _del_u3 is not None:
out[2] += _del_u3(*etas[0].T)
else:
assert len(etas) == 3
E1, E2, E3, is_sparse_meshgrid = Domain.prepare_eval_pts(
etas[0],
etas[1],
etas[2],
flat_eval=flat_eval,
)

out0 = self.f0.uv(E1, E2, E3)

if _del_u1 is None:
out = out0
else:
out1 = _del_u1(E1, E2, E3)
assert out0.shape == out1.shape
out = out0 + out1

Expand All @@ -1360,6 +1394,7 @@ def _f_init(*etas, flat_eval=False):
return out

self._f_init = _f_init
self._u_init = _u_init

def _load_external(
self,
Expand Down Expand Up @@ -1568,6 +1603,7 @@ def draw_markers(
self._load_tesselation()
if self.type == "sph":
self._set_initial_condition()
print()
self.velocities = xp.array(self.u_init(self.positions)).T
# set markers ID in last column
self.marker_ids = _first_marker_id + xp.arange(n_mks_load_loc, dtype=float)
Expand Down
1 change: 1 addition & 0 deletions src/struphy/pic/pushing/pusher_kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -3127,6 +3127,7 @@ def push_v_viscosity(
# n_at_eta = markers[ip, first_free_idx]
loc_box = int(markers[ip, n_cols - 2])

f_visc[:] = 0.0
for j in range(3): # row of viscosity tensor
for k in range(3): # column = derivative direction
coeff_idx = first_free_idx + 3 * (j + 1) + k
Expand Down
13 changes: 6 additions & 7 deletions src/struphy/pic/tests/test_sph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1959,11 +1959,10 @@ def u_xyz(x, y, z):


if __name__ == "__main__":
# test_sph_no_slip_boundary_1d(
# tesselation=False,
# direction="x",
# show_plot=True,
# )
test_sph_velocity_evaluation_2d(
(12, 12, 1), "gaussian_2d", 1, "periodic", "periodic", 11, tesselation=False, show_plot=True
test_sph_no_slip_boundary_1d(
(1, 1, 12),
"gaussian_3d",
tesselation=False,
direction="z",
show_plot=True,
)
Loading