Skip to content

Commit 06872f1

Browse files
committed
Add GSPH Model class and Python bindings
- Add Model.hpp/cpp with high-level GSPH interface - Add pyGSPHModel.cpp with pybind11 bindings for Python - Use shared ShamrockDump mechanism for checkpoints (same as SPH) - Remove duplicate checkpoint methods from Solver (reuse SPH pattern) - Add example scripts for Sod shock tube and Sedov blast - Add analytical Riemann solver utilities for validation
1 parent 6514860 commit 06872f1

14 files changed

Lines changed: 2853 additions & 46 deletions

File tree

exemples/common/__init__.py

Whitespace-only changes.

exemples/common/analytical/__init__.py

Whitespace-only changes.

exemples/common/analytical/riemann.py

Lines changed: 476 additions & 0 deletions
Large diffs are not rendered by default.

exemples/gsph/run_gsph_sod_tube.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"""
2+
GSPH Sod Shock Tube Simulation with VTK Output
3+
===============================================
4+
5+
Runs the Sod shock tube test using Godunov SPH (GSPH) with HLLC Riemann solver
6+
and outputs VTK files for visualization.
7+
8+
Uses the same initial conditions as the SPH Sod test for direct comparison.
9+
10+
Output: VTK files in output/ directory with simulation time metadata
11+
"""
12+
13+
import json
14+
import os
15+
16+
import shamrock
17+
18+
# Physical parameters (same as SPH test)
19+
gamma = 1.4
20+
21+
rho_L = 1.0 # Left density
22+
rho_R = 0.125 # Right density
23+
24+
P_L = 1.0 # Left pressure
25+
P_R = 0.1 # Right pressure
26+
27+
# Derived quantities
28+
fact = (rho_L / rho_R) ** (1.0 / 3.0)
29+
u_L = P_L / ((gamma - 1) * rho_L) # Left internal energy
30+
u_R = P_R / ((gamma - 1) * rho_R) # Right internal energy
31+
32+
# Resolution (same as SPH test)
33+
resol = 128
34+
35+
# Initialize context and model
36+
ctx = shamrock.Context()
37+
ctx.pdata_layout_new()
38+
39+
# Use GSPH model with M6 kernel (same as SPH test)
40+
model = shamrock.get_Model_GSPH(context=ctx, vector_type="f64_3", sph_kernel="M6")
41+
42+
# Configure solver
43+
cfg = model.gen_default_config()
44+
45+
# Set HLLC Riemann solver
46+
cfg.set_riemann_hllc()
47+
48+
# Set piecewise constant reconstruction (first-order, most stable)
49+
cfg.set_reconstruct_piecewise_constant()
50+
51+
# Set periodic boundaries (with wall particles for shock tube)
52+
cfg.set_boundary_periodic()
53+
54+
# Set adiabatic EOS
55+
cfg.set_eos_adiabatic(gamma)
56+
57+
# Print configuration
58+
cfg.print_status()
59+
model.set_solver_config(cfg)
60+
61+
model.init_scheduler(int(1e8), 1)
62+
63+
# Setup domain (same as SPH test)
64+
(xs, ys, zs) = model.get_box_dim_fcc_3d(1, resol, 24, 24)
65+
dr = 1 / xs
66+
(xs, ys, zs) = model.get_box_dim_fcc_3d(dr, resol, 24, 24)
67+
68+
model.resize_simulation_box((-xs, -ys / 2, -zs / 2), (xs, ys / 2, zs / 2))
69+
70+
# Setup initial conditions using HCP lattice (same as SPH test)
71+
# Left side: high density (smaller spacing)
72+
model.add_cube_hcp_3d(dr, (-xs, -ys / 2, -zs / 2), (0, ys / 2, zs / 2))
73+
# Right side: low density (larger spacing)
74+
model.add_cube_hcp_3d(dr * fact, (0, -ys / 2, -zs / 2), (xs, ys / 2, zs / 2))
75+
76+
# Set internal energy
77+
model.set_value_in_a_box("uint", "f64", u_L, (-xs, -ys / 2, -zs / 2), (0, ys / 2, zs / 2))
78+
model.set_value_in_a_box("uint", "f64", u_R, (0, -ys / 2, -zs / 2), (xs, ys / 2, zs / 2))
79+
80+
# Set particle mass (same as SPH test)
81+
vol_b = xs * ys * zs
82+
totmass = (rho_R * vol_b) + (rho_L * vol_b)
83+
pmass = model.total_mass_to_part_mass(totmass)
84+
model.set_particle_mass(pmass)
85+
86+
print(f"Total mass: {totmass}")
87+
print(f"Particle mass: {pmass}")
88+
89+
# Set CFL conditions (same as SPH test)
90+
model.set_cfl_cour(0.1)
91+
model.set_cfl_force(0.1)
92+
93+
# Simulation parameters (same as SPH test)
94+
t_final = 0.245
95+
n_outputs = 50
96+
dt_output = t_final / n_outputs
97+
98+
# Track output times
99+
times = []
100+
output_count = 0
101+
102+
# Create output directory
103+
os.makedirs("output", exist_ok=True)
104+
105+
# Initial output
106+
filename = f"output/gsph_sod_{output_count:04d}.vtk"
107+
model.do_vtk_dump(filename, True)
108+
times.append({"index": output_count, "time": 0.0, "file": filename})
109+
print(f"Saved: {filename} (t = 0.0)")
110+
output_count += 1
111+
112+
# Time evolution with outputs
113+
t_current = 0.0
114+
t_next_output = dt_output
115+
116+
while t_current < t_final:
117+
# Evolve to next output time or final time
118+
t_target = min(t_next_output, t_final)
119+
model.evolve_until(t_target)
120+
t_current = t_target
121+
122+
# Output VTK
123+
filename = f"output/gsph_sod_{output_count:04d}.vtk"
124+
model.do_vtk_dump(filename, True)
125+
times.append({"index": output_count, "time": t_current, "file": filename})
126+
print(f"Saved: {filename} (t = {t_current:.6f})")
127+
output_count += 1
128+
129+
t_next_output += dt_output
130+
131+
# Save times metadata
132+
with open("output/times_gsph_sod.json", "w") as f:
133+
json.dump(
134+
{
135+
"method": "GSPH",
136+
"riemann_solver": "HLLC",
137+
"kernel": "M6",
138+
"gamma": gamma,
139+
"rho_L": rho_L,
140+
"rho_R": rho_R,
141+
"P_L": P_L,
142+
"P_R": P_R,
143+
"t_final": t_final,
144+
"outputs": times,
145+
},
146+
f,
147+
indent=2,
148+
)
149+
150+
print(f"\nSimulation complete! {output_count} VTK files saved to output/")
151+
print("\nNote: L2 error analysis not available for GSPH model.")
152+
print("Use post-processing scripts for comparison with analytical solution.")

0 commit comments

Comments
 (0)