From d94f21c51f38c75efb876f1416e08a16f5ff3145 Mon Sep 17 00:00:00 2001 From: Timothy Kassis Date: Thu, 13 Nov 2025 19:46:29 -0800 Subject: [PATCH] Add support for fluidsim for computational fluid dynamics --- .claude-plugin/marketplace.json | 3 +- README.md | 11 +- docs/scientific-skills.md | 3 + scientific-skills/fluidsim/SKILL.md | 343 +++++++++++++++ .../fluidsim/references/advanced_features.md | 398 ++++++++++++++++++ .../fluidsim/references/installation.md | 82 ++++ .../fluidsim/references/output_analysis.md | 283 +++++++++++++ .../fluidsim/references/parameters.md | 198 +++++++++ .../references/simulation_workflow.md | 172 ++++++++ .../fluidsim/references/solvers.md | 94 +++++ 10 files changed, 1581 insertions(+), 6 deletions(-) create mode 100644 scientific-skills/fluidsim/SKILL.md create mode 100644 scientific-skills/fluidsim/references/advanced_features.md create mode 100644 scientific-skills/fluidsim/references/installation.md create mode 100644 scientific-skills/fluidsim/references/output_analysis.md create mode 100644 scientific-skills/fluidsim/references/parameters.md create mode 100644 scientific-skills/fluidsim/references/simulation_workflow.md create mode 100644 scientific-skills/fluidsim/references/solvers.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index f1c61d5..960ae50 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -7,7 +7,7 @@ }, "metadata": { "description": "Claude scientific skills from K-Dense Inc", - "version": "2.0.0" + "version": "2.1.0" }, "plugins": [ { @@ -35,6 +35,7 @@ "./scientific-skills/esm", "./scientific-skills/etetoolkit", "./scientific-skills/flowio", + "./scientific-skills/fluidsim", "./scientific-skills/geniml", "./scientific-skills/gget", "./scientific-skills/gtars", diff --git a/README.md b/README.md index 0ad904a..836075f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Claude Scientific Skills [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md) -[![Skills](https://img.shields.io/badge/Skills-117-brightgreen.svg)](#whats-included) +[![Skills](https://img.shields.io/badge/Skills-118-brightgreen.svg)](#whats-included) -A comprehensive collection of **117+ ready-to-use scientific skills** for Claude, created by the K-Dense team. Transform Claude into your AI research assistant capable of executing complex multi-step scientific workflows across biology, chemistry, medicine, and beyond. +A comprehensive collection of **118+ ready-to-use scientific skills** for Claude, created by the K-Dense team. Transform Claude into your AI research assistant capable of executing complex multi-step scientific workflows across biology, chemistry, medicine, and beyond. These skills enable Claude to seamlessly work with specialized scientific libraries, databases, and tools across multiple scientific domains: - 🧬 Bioinformatics & Genomics - Sequence analysis, single-cell RNA-seq, gene regulatory networks, variant annotation, phylogenetic analysis @@ -32,7 +32,7 @@ These skills enable Claude to seamlessly work with specialized scientific librar ## 📦 What's Included -This repository provides **117+ scientific skills** organized into the following categories: +This repository provides **118+ scientific skills** organized into the following categories: - **25+ Scientific Databases** - Direct API access to PubMed, ChEMBL, UniProt, COSMIC, ClinicalTrials.gov, and more - **50+ Python Packages** - RDKit, Scanpy, PyTorch Lightning, scikit-learn, BioPython, and others @@ -308,7 +308,7 @@ networks, and search GEO for similar patterns. ## 📚 Available Skills -This repository contains **117+ scientific skills** organized across multiple domains. Each skill provides comprehensive documentation, code examples, and best practices for working with scientific libraries, databases, and tools. +This repository contains **118+ scientific skills** organized across multiple domains. Each skill provides comprehensive documentation, code examples, and best practices for working with scientific libraries, databases, and tools. ### Skill Categories @@ -352,7 +352,8 @@ This repository contains **117+ scientific skills** organized across multiple do - Metabolic modeling: COBRApy - Astronomy: Astropy -#### ⚙️ **Engineering & Simulation** (2 skills) +#### ⚙️ **Engineering & Simulation** (3 skills) +- Computational fluid dynamics: FluidSim - Discrete-event simulation: SimPy - Data processing: Dask, Polars, Vaex diff --git a/docs/scientific-skills.md b/docs/scientific-skills.md index 99e3b41..1cf20a8 100644 --- a/docs/scientific-skills.md +++ b/docs/scientific-skills.md @@ -117,6 +117,9 @@ - **COBRApy** - Python package for constraint-based reconstruction and analysis (COBRA) of metabolic networks. Provides tools for building, manipulating, and analyzing genome-scale metabolic models (GEMs). Key features include: flux balance analysis (FBA) for predicting optimal metabolic fluxes, flux variability analysis (FVA), gene knockout simulations, pathway analysis, model validation, and integration with other COBRA Toolbox formats (SBML, JSON). Supports various optimization objectives (biomass production, ATP production, metabolite production), constraint handling (reaction bounds, gene-protein-reaction associations), and model comparison. Includes utilities for model construction, gap filling, and model refinement. Use cases: metabolic engineering, systems biology, biotechnology applications, understanding cellular metabolism, and predicting metabolic phenotypes - **Pymatgen** - Python Materials Genomics (pymatgen) library for materials science computation and analysis. Provides comprehensive tools for crystal structure manipulation, phase diagram construction, electronic structure analysis, and materials property calculations. Key features include: structure objects with symmetry analysis, space group determination, structure matching and comparison, phase diagram generation from formation energies, band structure and density of states analysis, defect calculations, surface and interface analysis, and integration with DFT codes (VASP, Quantum ESPRESSO, ABINIT). Supports Materials Project database integration, structure file I/O (CIF, POSCAR, VASP), and high-throughput materials screening workflows. Use cases: materials discovery, crystal structure analysis, phase stability prediction, electronic structure calculations, and computational materials science research +### Engineering & Simulation +- **FluidSim** - Object-oriented Python framework for high-performance computational fluid dynamics (CFD) simulations using pseudospectral methods with FFT. Provides solvers for periodic-domain equations including 2D/3D incompressible Navier-Stokes equations (with/without stratification), shallow water equations, and Föppl-von Kármán elastic plate equations. Key features include: Pythran/Transonic compilation for performance comparable to Fortran/C++, MPI parallelization for large-scale simulations, hierarchical parameter configuration with type safety, comprehensive output management (physical fields in HDF5, spatial means, energy/enstrophy spectra, spectral energy budgets), custom forcing mechanisms (time-correlated random forcing, proportional forcing, script-defined forcing), flexible initial conditions (noise, vortex, dipole, Taylor-Green, from file, in-script), online and offline visualization, and integration with ParaView/VisIt for 3D visualization. Supports workflow features including simulation restart/continuation, parametric studies with batch execution, cluster submission integration, and adaptive CFL-based time stepping. Use cases: 2D/3D turbulence studies with energy cascade analysis, stratified oceanic and atmospheric flows with buoyancy effects, geophysical flows with rotation (Coriolis effects), vortex dynamics and fundamental fluid mechanics research, high-resolution direct numerical simulation (DNS), parametric studies exploring parameter spaces, validation studies (Taylor-Green vortex), and any periodic-domain fluid dynamics research requiring HPC-grade performance with Python flexibility + ### Data Analysis & Visualization - **Dask** - Parallel computing for larger-than-memory datasets with distributed DataFrames, Arrays, Bags, and Futures - **Data Commons** - Programmatic access to public statistical data from global sources including census bureaus, health organizations, and environmental agencies. Provides unified Python API for querying demographic data, economic indicators, health statistics, and environmental datasets through a knowledge graph interface. Features three main endpoints: Observation (statistical time-series queries for population, GDP, unemployment rates, disease prevalence), Node (knowledge graph exploration for entity relationships and hierarchies), and Resolve (entity identification from names, coordinates, or Wikidata IDs). Seamless Pandas integration for DataFrames, relation expressions for hierarchical queries, data source filtering for consistency, and support for custom Data Commons instances diff --git a/scientific-skills/fluidsim/SKILL.md b/scientific-skills/fluidsim/SKILL.md new file mode 100644 index 0000000..5e3a736 --- /dev/null +++ b/scientific-skills/fluidsim/SKILL.md @@ -0,0 +1,343 @@ +--- +name: fluidsim +description: Framework for computational fluid dynamics simulations using Python. Use when running fluid dynamics simulations including Navier-Stokes equations (2D/3D), shallow water equations, stratified flows, or when analyzing turbulence, vortex dynamics, or geophysical flows. Provides pseudospectral methods with FFT, HPC support, and comprehensive output analysis. +--- + +# FluidSim + +## Overview + +FluidSim is an object-oriented Python framework for high-performance computational fluid dynamics (CFD) simulations. It provides solvers for periodic-domain equations using pseudospectral methods with FFT, delivering performance comparable to Fortran/C++ while maintaining Python's ease of use. + +**Key strengths**: +- Multiple solvers: 2D/3D Navier-Stokes, shallow water, stratified flows +- High performance: Pythran/Transonic compilation, MPI parallelization +- Complete workflow: Parameter configuration, simulation execution, output analysis +- Interactive analysis: Python-based post-processing and visualization + +## Core Capabilities + +### 1. Installation and Setup + +Install fluidsim using uv with appropriate feature flags: + +```bash +# Basic installation +uv pip install fluidsim + +# With FFT support (required for most solvers) +uv pip install "fluidsim[fft]" + +# With MPI for parallel computing +uv pip install "fluidsim[fft,mpi]" +``` + +Set environment variables for output directories (optional): + +```bash +export FLUIDSIM_PATH=/path/to/simulation/outputs +export FLUIDDYN_PATH_SCRATCH=/path/to/working/directory +``` + +No API keys or authentication required. + +See `references/installation.md` for complete installation instructions, conda/mamba alternatives, and environment configuration. + +### 2. Running Simulations + +Standard workflow consists of five steps: + +**Step 1**: Import solver +```python +from fluidsim.solvers.ns2d.solver import Simul +``` + +**Step 2**: Create and configure parameters +```python +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 256 +params.oper.Lx = params.oper.Ly = 2 * 3.14159 +params.nu_2 = 1e-3 +params.time_stepping.t_end = 10.0 +params.init_fields.type = "noise" +``` + +**Step 3**: Instantiate simulation +```python +sim = Simul(params) +``` + +**Step 4**: Execute +```python +sim.time_stepping.start() +``` + +**Step 5**: Analyze results +```python +sim.output.phys_fields.plot("vorticity") +sim.output.spatial_means.plot() +``` + +See `references/simulation_workflow.md` for complete examples, restarting simulations, and cluster deployment. + +### 3. Available Solvers + +Choose solver based on physical problem: + +**2D Navier-Stokes** (`ns2d`): 2D turbulence, vortex dynamics +```python +from fluidsim.solvers.ns2d.solver import Simul +``` + +**3D Navier-Stokes** (`ns3d`): 3D turbulence, realistic flows +```python +from fluidsim.solvers.ns3d.solver import Simul +``` + +**Stratified flows** (`ns2d.strat`, `ns3d.strat`): Oceanic/atmospheric flows +```python +from fluidsim.solvers.ns2d.strat.solver import Simul +params.N = 1.0 # Brunt-Väisälä frequency +``` + +**Shallow water** (`sw1l`): Geophysical flows, rotating systems +```python +from fluidsim.solvers.sw1l.solver import Simul +params.f = 1.0 # Coriolis parameter +``` + +See `references/solvers.md` for complete solver list and selection guidance. + +### 4. Parameter Configuration + +Parameters are organized hierarchically and accessed via dot notation: + +**Domain and resolution**: +```python +params.oper.nx = 256 # grid points +params.oper.Lx = 2 * pi # domain size +``` + +**Physical parameters**: +```python +params.nu_2 = 1e-3 # viscosity +params.nu_4 = 0 # hyperviscosity (optional) +``` + +**Time stepping**: +```python +params.time_stepping.t_end = 10.0 +params.time_stepping.USE_CFL = True # adaptive time step +params.time_stepping.CFL = 0.5 +``` + +**Initial conditions**: +```python +params.init_fields.type = "noise" # or "dipole", "vortex", "from_file", "in_script" +``` + +**Output settings**: +```python +params.output.periods_save.phys_fields = 1.0 # save every 1.0 time units +params.output.periods_save.spectra = 0.5 +params.output.periods_save.spatial_means = 0.1 +``` + +The Parameters object raises `AttributeError` for typos, preventing silent configuration errors. + +See `references/parameters.md` for comprehensive parameter documentation. + +### 5. Output and Analysis + +FluidSim produces multiple output types automatically saved during simulation: + +**Physical fields**: Velocity, vorticity in HDF5 format +```python +sim.output.phys_fields.plot("vorticity") +sim.output.phys_fields.plot("vx") +``` + +**Spatial means**: Time series of volume-averaged quantities +```python +sim.output.spatial_means.plot() +``` + +**Spectra**: Energy and enstrophy spectra +```python +sim.output.spectra.plot1d() +sim.output.spectra.plot2d() +``` + +**Load previous simulations**: +```python +from fluidsim import load_sim_for_plot +sim = load_sim_for_plot("simulation_dir") +sim.output.phys_fields.plot() +``` + +**Advanced visualization**: Open `.h5` files in ParaView or VisIt for 3D visualization. + +See `references/output_analysis.md` for detailed analysis workflows, parametric study analysis, and data export. + +### 6. Advanced Features + +**Custom forcing**: Maintain turbulence or drive specific dynamics +```python +params.forcing.enable = True +params.forcing.type = "tcrandom" # time-correlated random forcing +params.forcing.forcing_rate = 1.0 +``` + +**Custom initial conditions**: Define fields in script +```python +params.init_fields.type = "in_script" +sim = Simul(params) +X, Y = sim.oper.get_XY_loc() +vx = sim.state.state_phys.get_var("vx") +vx[:] = sin(X) * cos(Y) +sim.time_stepping.start() +``` + +**MPI parallelization**: Run on multiple processors +```bash +mpirun -np 8 python simulation_script.py +``` + +**Parametric studies**: Run multiple simulations with different parameters +```python +for nu in [1e-3, 5e-4, 1e-4]: + params = Simul.create_default_params() + params.nu_2 = nu + params.output.sub_directory = f"nu{nu}" + sim = Simul(params) + sim.time_stepping.start() +``` + +See `references/advanced_features.md` for forcing types, custom solvers, cluster submission, and performance optimization. + +## Common Use Cases + +### 2D Turbulence Study + +```python +from fluidsim.solvers.ns2d.solver import Simul +from math import pi + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 512 +params.oper.Lx = params.oper.Ly = 2 * pi +params.nu_2 = 1e-4 +params.time_stepping.t_end = 50.0 +params.time_stepping.USE_CFL = True +params.init_fields.type = "noise" +params.output.periods_save.phys_fields = 5.0 +params.output.periods_save.spectra = 1.0 + +sim = Simul(params) +sim.time_stepping.start() + +# Analyze energy cascade +sim.output.spectra.plot1d(tmin=30.0, tmax=50.0) +``` + +### Stratified Flow Simulation + +```python +from fluidsim.solvers.ns2d.strat.solver import Simul + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 256 +params.N = 2.0 # stratification strength +params.nu_2 = 5e-4 +params.time_stepping.t_end = 20.0 + +# Initialize with dense layer +params.init_fields.type = "in_script" +sim = Simul(params) +X, Y = sim.oper.get_XY_loc() +b = sim.state.state_phys.get_var("b") +b[:] = exp(-((X - 3.14)**2 + (Y - 3.14)**2) / 0.5) +sim.state.statephys_from_statespect() + +sim.time_stepping.start() +sim.output.phys_fields.plot("b") +``` + +### High-Resolution 3D Simulation with MPI + +```python +from fluidsim.solvers.ns3d.solver import Simul + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = params.oper.nz = 512 +params.nu_2 = 1e-5 +params.time_stepping.t_end = 10.0 +params.init_fields.type = "noise" + +sim = Simul(params) +sim.time_stepping.start() +``` + +Run with: +```bash +mpirun -np 64 python script.py +``` + +### Taylor-Green Vortex Validation + +```python +from fluidsim.solvers.ns2d.solver import Simul +import numpy as np +from math import pi + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 128 +params.oper.Lx = params.oper.Ly = 2 * pi +params.nu_2 = 1e-3 +params.time_stepping.t_end = 10.0 +params.init_fields.type = "in_script" + +sim = Simul(params) +X, Y = sim.oper.get_XY_loc() +vx = sim.state.state_phys.get_var("vx") +vy = sim.state.state_phys.get_var("vy") +vx[:] = np.sin(X) * np.cos(Y) +vy[:] = -np.cos(X) * np.sin(Y) +sim.state.statephys_from_statespect() + +sim.time_stepping.start() + +# Validate energy decay +df = sim.output.spatial_means.load() +# Compare with analytical solution +``` + +## Quick Reference + +**Import solver**: `from fluidsim.solvers.ns2d.solver import Simul` + +**Create parameters**: `params = Simul.create_default_params()` + +**Set resolution**: `params.oper.nx = params.oper.ny = 256` + +**Set viscosity**: `params.nu_2 = 1e-3` + +**Set end time**: `params.time_stepping.t_end = 10.0` + +**Run simulation**: `sim = Simul(params); sim.time_stepping.start()` + +**Plot results**: `sim.output.phys_fields.plot("vorticity")` + +**Load simulation**: `sim = load_sim_for_plot("path/to/sim")` + +## Resources + +**Documentation**: https://fluidsim.readthedocs.io/ + +**Reference files**: +- `references/installation.md`: Complete installation instructions +- `references/solvers.md`: Available solvers and selection guide +- `references/simulation_workflow.md`: Detailed workflow examples +- `references/parameters.md`: Comprehensive parameter documentation +- `references/output_analysis.md`: Output types and analysis methods +- `references/advanced_features.md`: Forcing, MPI, parametric studies, custom solvers diff --git a/scientific-skills/fluidsim/references/advanced_features.md b/scientific-skills/fluidsim/references/advanced_features.md new file mode 100644 index 0000000..2f9d025 --- /dev/null +++ b/scientific-skills/fluidsim/references/advanced_features.md @@ -0,0 +1,398 @@ +# Advanced Features + +## Custom Forcing + +### Forcing Types + +FluidSim supports several forcing mechanisms to maintain turbulence or drive specific dynamics. + +#### Time-Correlated Random Forcing + +Most common for sustained turbulence: + +```python +params.forcing.enable = True +params.forcing.type = "tcrandom" +params.forcing.nkmin_forcing = 2 # minimum forced wavenumber +params.forcing.nkmax_forcing = 5 # maximum forced wavenumber +params.forcing.forcing_rate = 1.0 # energy injection rate +params.forcing.tcrandom_time_correlation = 1.0 # correlation time +``` + +#### Proportional Forcing + +Maintains a specific energy distribution: + +```python +params.forcing.type = "proportional" +params.forcing.forcing_rate = 1.0 +``` + +#### Custom Forcing in Script + +Define forcing directly in the launch script: + +```python +params.forcing.enable = True +params.forcing.type = "in_script" + +sim = Simul(params) + +# Define custom forcing function +def compute_forcing_fft(sim): + """Compute forcing in Fourier space""" + forcing_vx_fft = sim.oper.create_arrayK(value=0.) + forcing_vy_fft = sim.oper.create_arrayK(value=0.) + + # Add custom forcing logic + # Example: force specific modes + forcing_vx_fft[10, 10] = 1.0 + 0.5j + + return forcing_vx_fft, forcing_vy_fft + +# Override forcing method +sim.forcing.forcing_maker.compute_forcing_fft = lambda: compute_forcing_fft(sim) + +# Run simulation +sim.time_stepping.start() +``` + +## Custom Initial Conditions + +### In-Script Initialization + +Full control over initial fields: + +```python +from math import pi +import numpy as np + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 256 +params.oper.Lx = params.oper.Ly = 2 * pi + +params.init_fields.type = "in_script" + +sim = Simul(params) + +# Get coordinate arrays +X, Y = sim.oper.get_XY_loc() + +# Define velocity fields +vx = sim.state.state_phys.get_var("vx") +vy = sim.state.state_phys.get_var("vy") + +# Taylor-Green vortex +vx[:] = np.sin(X) * np.cos(Y) +vy[:] = -np.cos(X) * np.sin(Y) + +# Initialize state in Fourier space +sim.state.statephys_from_statespect() + +# Run simulation +sim.time_stepping.start() +``` + +### Layer Initialization (Stratified Flows) + +Set up density layers: + +```python +from fluidsim.solvers.ns2d.strat.solver import Simul + +params = Simul.create_default_params() +params.N = 1.0 # stratification +params.init_fields.type = "in_script" + +sim = Simul(params) + +# Define dense layer +X, Y = sim.oper.get_XY_loc() +b = sim.state.state_phys.get_var("b") # buoyancy field + +# Gaussian density anomaly +x0, y0 = pi, pi +sigma = 0.5 +b[:] = np.exp(-((X - x0)**2 + (Y - y0)**2) / (2 * sigma**2)) + +sim.state.statephys_from_statespect() +sim.time_stepping.start() +``` + +## Parallel Computing with MPI + +### Running MPI Simulations + +Install with MPI support: +```bash +uv pip install "fluidsim[fft,mpi]" +``` + +Run with MPI: +```bash +mpirun -np 8 python simulation_script.py +``` + +FluidSim automatically detects MPI and distributes computation. + +### MPI-Specific Parameters + +```python +# No special parameters needed +# FluidSim handles domain decomposition automatically + +# For very large 3D simulations +params.oper.nx = 512 +params.oper.ny = 512 +params.oper.nz = 512 + +# Run with: mpirun -np 64 python script.py +``` + +### Output with MPI + +Output files are written from rank 0 processor. Analysis scripts work identically for serial and MPI runs. + +## Parametric Studies + +### Running Multiple Simulations + +Script to generate and run multiple parameter combinations: + +```python +from fluidsim.solvers.ns2d.solver import Simul +import numpy as np + +# Parameter ranges +viscosities = [1e-3, 5e-4, 1e-4, 5e-5] +resolutions = [128, 256, 512] + +for nu in viscosities: + for nx in resolutions: + params = Simul.create_default_params() + + # Configure simulation + params.oper.nx = params.oper.ny = nx + params.nu_2 = nu + params.time_stepping.t_end = 10.0 + + # Unique output directory + params.output.sub_directory = f"nu{nu}_nx{nx}" + + # Run simulation + sim = Simul(params) + sim.time_stepping.start() +``` + +### Cluster Submission + +Submit multiple jobs to a cluster: + +```python +from fluiddyn.clusters.legi import Calcul8 as Cluster + +cluster = Cluster() + +for nu in viscosities: + for nx in resolutions: + script_content = f""" +from fluidsim.solvers.ns2d.solver import Simul + +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = {nx} +params.nu_2 = {nu} +params.time_stepping.t_end = 10.0 +params.output.sub_directory = "nu{nu}_nx{nx}" + +sim = Simul(params) +sim.time_stepping.start() +""" + + with open(f"job_nu{nu}_nx{nx}.py", "w") as f: + f.write(script_content) + + cluster.submit_script( + f"job_nu{nu}_nx{nx}.py", + name_run=f"sim_nu{nu}_nx{nx}", + nb_nodes=1, + nb_cores_per_node=24, + walltime="12:00:00" + ) +``` + +### Analyzing Parametric Studies + +```python +import os +import pandas as pd +from fluidsim import load_sim_for_plot +import matplotlib.pyplot as plt + +results = [] + +# Collect data from all simulations +for sim_dir in os.listdir("simulations"): + sim_path = f"simulations/{sim_dir}" + if not os.path.isdir(sim_path): + continue + + try: + sim = load_sim_for_plot(sim_path) + + # Extract parameters + nu = sim.params.nu_2 + nx = sim.params.oper.nx + + # Extract results + df = sim.output.spatial_means.load() + final_energy = df["E"].iloc[-1] + mean_energy = df["E"].mean() + + results.append({ + "nu": nu, + "nx": nx, + "final_energy": final_energy, + "mean_energy": mean_energy + }) + except Exception as e: + print(f"Error loading {sim_dir}: {e}") + +# Analyze results +results_df = pd.DataFrame(results) + +# Plot results +plt.figure(figsize=(10, 6)) +for nx in results_df["nx"].unique(): + subset = results_df[results_df["nx"] == nx] + plt.plot(subset["nu"], subset["mean_energy"], + marker="o", label=f"nx={nx}") + +plt.xlabel("Viscosity") +plt.ylabel("Mean Energy") +plt.xscale("log") +plt.legend() +plt.savefig("parametric_study_results.png") +``` + +## Custom Solvers + +### Extending Existing Solvers + +Create a new solver by inheriting from an existing one: + +```python +from fluidsim.solvers.ns2d.solver import Simul as SimulNS2D +from fluidsim.base.setofvariables import SetOfVariables + +class SimulCustom(SimulNS2D): + """Custom solver with additional physics""" + + @staticmethod + def _complete_params_with_default(params): + """Add custom parameters""" + SimulNS2D._complete_params_with_default(params) + params._set_child("custom", {"param1": 0.0}) + + def __init__(self, params): + super().__init__(params) + # Custom initialization + + def tendencies_nonlin(self, state_spect=None): + """Override to add custom tendencies""" + tendencies = super().tendencies_nonlin(state_spect) + + # Add custom terms + # tendencies.vx_fft += custom_term_vx + # tendencies.vy_fft += custom_term_vy + + return tendencies +``` + +Use the custom solver: +```python +params = SimulCustom.create_default_params() +# Configure params... +sim = SimulCustom(params) +sim.time_stepping.start() +``` + +## Online Visualization + +Display fields during simulation: + +```python +params.output.ONLINE_PLOT_OK = True +params.output.periods_plot.phys_fields = 1.0 # plot every 1.0 time units +params.output.phys_fields.field_to_plot = "vorticity" + +sim = Simul(params) +sim.time_stepping.start() +``` + +Plots appear in real-time during execution. + +## Checkpoint and Restart + +### Automatic Checkpointing + +```python +params.output.periods_save.phys_fields = 1.0 # save every 1.0 time units +``` + +Fields are saved automatically during simulation. + +### Manual Checkpointing + +```python +# During simulation +sim.output.phys_fields.save() +``` + +### Restarting from Checkpoint + +```python +params = Simul.create_default_params() +params.init_fields.type = "from_file" +params.init_fields.from_file.path = "simulation_dir/state_phys_t5.000.h5" +params.time_stepping.t_end = 20.0 # extend simulation + +sim = Simul(params) +sim.time_stepping.start() +``` + +## Memory and Performance Optimization + +### Reduce Memory Usage + +```python +# Disable unnecessary outputs +params.output.periods_save.spectra = 0 # disable spectra saving +params.output.periods_save.spect_energy_budg = 0 # disable energy budget + +# Reduce spatial field saves +params.output.periods_save.phys_fields = 10.0 # save less frequently +``` + +### Optimize FFT Performance + +```python +import os + +# Select FFT library +os.environ["FLUIDSIM_TYPE_FFT2D"] = "fft2d.with_fftw" +os.environ["FLUIDSIM_TYPE_FFT3D"] = "fft3d.with_fftw" + +# Or use MKL if available +# os.environ["FLUIDSIM_TYPE_FFT2D"] = "fft2d.with_mkl" +``` + +### Time Step Optimization + +```python +# Use adaptive time stepping +params.time_stepping.USE_CFL = True +params.time_stepping.CFL = 0.8 # slightly larger CFL for faster runs + +# Use efficient time scheme +params.time_stepping.type_time_scheme = "RK4" # 4th order Runge-Kutta +``` diff --git a/scientific-skills/fluidsim/references/installation.md b/scientific-skills/fluidsim/references/installation.md new file mode 100644 index 0000000..3b9e19a --- /dev/null +++ b/scientific-skills/fluidsim/references/installation.md @@ -0,0 +1,82 @@ +# FluidSim Installation + +## Requirements + +- Python >= 3.9 +- Virtual environment recommended + +## Installation Methods + +### Basic Installation + +Install fluidsim using uv: + +```bash +uv pip install fluidsim +``` + +### With FFT Support (Required for Pseudospectral Solvers) + +Most fluidsim solvers use Fourier-based methods and require FFT libraries: + +```bash +uv pip install "fluidsim[fft]" +``` + +This installs fluidfft and pyfftw dependencies. + +### With MPI and FFT (For Parallel Simulations) + +For high-performance parallel computing: + +```bash +uv pip install "fluidsim[fft,mpi]" +``` + +Note: This triggers local compilation of mpi4py. + +### Conda/Mamba Installation + +For sequential simulations: + +```bash +conda install fluidsim +``` + +For MPI-enabled environment: + +```bash +conda create -n env-fluidsim fluidsim "h5py[build=mpi*]" fluidfft-mpi_with_fftw fluidfft-fftwmpi +``` + +## Environment Configuration + +### Output Directories + +Set environment variables to control where simulation data is stored: + +```bash +export FLUIDSIM_PATH=/path/to/simulation/outputs +export FLUIDDYN_PATH_SCRATCH=/path/to/working/directory +``` + +### FFT Method Selection + +Specify FFT implementation (optional): + +```bash +export FLUIDSIM_TYPE_FFT2D=fft2d.with_fftw +export FLUIDSIM_TYPE_FFT3D=fft3d.with_fftw +``` + +## Verification + +Test the installation: + +```bash +pytest --pyargs fluidsim +``` + +## No Authentication Required + +FluidSim does not require API keys or authentication tokens. diff --git a/scientific-skills/fluidsim/references/output_analysis.md b/scientific-skills/fluidsim/references/output_analysis.md new file mode 100644 index 0000000..b9791b5 --- /dev/null +++ b/scientific-skills/fluidsim/references/output_analysis.md @@ -0,0 +1,283 @@ +# Output and Analysis + +## Output Types + +FluidSim automatically saves several types of output during simulations. + +### Physical Fields + +**File format**: HDF5 (`.h5`) + +**Location**: `simulation_dir/state_phys_t*.h5` + +**Contents**: Velocity, vorticity, and other physical space fields at specific times + +**Access**: +```python +sim.output.phys_fields.plot() +sim.output.phys_fields.plot("vorticity") +sim.output.phys_fields.plot("vx") +sim.output.phys_fields.plot("div") # check divergence + +# Save manually +sim.output.phys_fields.save() + +# Get data +vorticity = sim.state.state_phys.get_var("rot") +``` + +### Spatial Means + +**File format**: Text file (`.txt`) + +**Location**: `simulation_dir/spatial_means.txt` + +**Contents**: Volume-averaged quantities vs time (energy, enstrophy, etc.) + +**Access**: +```python +sim.output.spatial_means.plot() + +# Load from file +from fluidsim import load_sim_for_plot +sim = load_sim_for_plot("simulation_dir") +sim.output.spatial_means.load() +spatial_means_data = sim.output.spatial_means +``` + +### Spectra + +**File format**: HDF5 (`.h5`) + +**Location**: `simulation_dir/spectra_*.h5` + +**Contents**: Energy and enstrophy spectra vs wavenumber + +**Access**: +```python +sim.output.spectra.plot1d() # 1D spectrum +sim.output.spectra.plot2d() # 2D spectrum + +# Load spectra data +spectra = sim.output.spectra.load2d_mean() +``` + +### Spectral Energy Budget + +**File format**: HDF5 (`.h5`) + +**Location**: `simulation_dir/spect_energy_budg_*.h5` + +**Contents**: Energy transfer between scales + +**Access**: +```python +sim.output.spect_energy_budg.plot() +``` + +## Post-Processing + +### Loading Simulations for Analysis + +#### Fast Loading (Read-Only) + +```python +from fluidsim import load_sim_for_plot + +sim = load_sim_for_plot("simulation_dir") + +# Access all output types +sim.output.phys_fields.plot() +sim.output.spatial_means.plot() +sim.output.spectra.plot1d() +``` + +Use this for quick visualization and analysis. Does not initialize full simulation state. + +#### Full State Loading + +```python +from fluidsim import load_state_phys_file + +sim = load_state_phys_file("simulation_dir/state_phys_t10.000.h5") + +# Can continue simulation +sim.time_stepping.start() +``` + +### Visualization Tools + +#### Built-in Plotting + +FluidSim provides basic plotting through matplotlib: + +```python +# Physical fields +sim.output.phys_fields.plot("vorticity") +sim.output.phys_fields.animate("vorticity") + +# Time series +sim.output.spatial_means.plot() + +# Spectra +sim.output.spectra.plot1d() +``` + +#### Advanced Visualization + +For publication-quality or 3D visualization: + +**ParaView**: Open `.h5` files directly +```bash +paraview simulation_dir/state_phys_t*.h5 +``` + +**VisIt**: Similar to ParaView for large datasets + +**Custom Python**: +```python +import h5py +import matplotlib.pyplot as plt + +# Load field manually +with h5py.File("state_phys_t10.000.h5", "r") as f: + vx = f["state_phys"]["vx"][:] + vy = f["state_phys"]["vy"][:] + +# Custom plotting +plt.contourf(vx) +plt.show() +``` + +## Analysis Examples + +### Energy Evolution + +```python +from fluidsim import load_sim_for_plot +import matplotlib.pyplot as plt + +sim = load_sim_for_plot("simulation_dir") +df = sim.output.spatial_means.load() + +plt.figure() +plt.plot(df["t"], df["E"], label="Kinetic Energy") +plt.xlabel("Time") +plt.ylabel("Energy") +plt.legend() +plt.show() +``` + +### Spectral Analysis + +```python +sim = load_sim_for_plot("simulation_dir") + +# Plot energy spectrum +sim.output.spectra.plot1d(tmin=5.0, tmax=10.0) # average over time range + +# Get spectral data +k, E_k = sim.output.spectra.load1d_mean(tmin=5.0, tmax=10.0) + +# Check for power law +import numpy as np +log_k = np.log(k) +log_E = np.log(E_k) +# fit power law in inertial range +``` + +### Parametric Study Analysis + +When running multiple simulations with different parameters: + +```python +import os +import pandas as pd +from fluidsim import load_sim_for_plot + +# Collect results from multiple simulations +results = [] +for sim_dir in os.listdir("simulations"): + if not os.path.isdir(f"simulations/{sim_dir}"): + continue + + sim = load_sim_for_plot(f"simulations/{sim_dir}") + + # Extract key metrics + df = sim.output.spatial_means.load() + final_energy = df["E"].iloc[-1] + + # Get parameters + nu = sim.params.nu_2 + + results.append({ + "nu": nu, + "final_energy": final_energy, + "sim_dir": sim_dir + }) + +# Analyze results +results_df = pd.DataFrame(results) +results_df.plot(x="nu", y="final_energy", logx=True) +``` + +### Field Manipulation + +```python +sim = load_sim_for_plot("simulation_dir") + +# Load specific time +sim.output.phys_fields.set_of_phys_files.update_times() +times = sim.output.phys_fields.set_of_phys_files.times + +# Load field at specific time +field_file = sim.output.phys_fields.get_field_to_plot(time=5.0) +vorticity = field_file.get_var("rot") + +# Compute derived quantities +import numpy as np +vorticity_rms = np.sqrt(np.mean(vorticity**2)) +vorticity_max = np.max(np.abs(vorticity)) +``` + +## Output Directory Structure + +``` +simulation_dir/ +├── params_simul.xml # Simulation parameters +├── stdout.txt # Standard output log +├── state_phys_t*.h5 # Physical fields at different times +├── spatial_means.txt # Time series of spatial averages +├── spectra_*.h5 # Spectral data +├── spect_energy_budg_*.h5 # Energy budget data +└── info_solver.txt # Solver information +``` + +## Performance Monitoring + +```python +# During simulation, check progress +sim.output.print_stdout.complete_timestep() + +# After simulation, review performance +sim.output.print_stdout.plot_deltat() # plot time step evolution +sim.output.print_stdout.plot_clock_times() # plot computation time +``` + +## Data Export + +Convert fluidsim output to other formats: + +```python +import h5py +import numpy as np + +# Export to numpy array +with h5py.File("state_phys_t10.000.h5", "r") as f: + vx = f["state_phys"]["vx"][:] + np.save("vx.npy", vx) + +# Export to CSV +df = sim.output.spatial_means.load() +df.to_csv("spatial_means.csv", index=False) +``` diff --git a/scientific-skills/fluidsim/references/parameters.md b/scientific-skills/fluidsim/references/parameters.md new file mode 100644 index 0000000..bc8e9dd --- /dev/null +++ b/scientific-skills/fluidsim/references/parameters.md @@ -0,0 +1,198 @@ +# Parameter Configuration + +## Parameters Object + +The `Parameters` object is hierarchical and organized into logical groups. Access using dot notation: + +```python +params = Simul.create_default_params() +params.group.subgroup.parameter = value +``` + +## Key Parameter Groups + +### Operators (`params.oper`) + +Define domain and resolution: + +```python +params.oper.nx = 256 # number of grid points in x +params.oper.ny = 256 # number of grid points in y +params.oper.nz = 128 # number of grid points in z (3D only) + +params.oper.Lx = 2 * pi # domain length in x +params.oper.Ly = 2 * pi # domain length in y +params.oper.Lz = pi # domain length in z (3D only) + +params.oper.coef_dealiasing = 2./3. # dealiasing cutoff (default 2/3) +``` + +**Resolution guidance**: Use powers of 2 for optimal FFT performance (128, 256, 512, 1024, etc.) + +### Physical Parameters + +#### Viscosity + +```python +params.nu_2 = 1e-3 # Laplacian viscosity (negative Laplacian) +params.nu_4 = 0 # hyperviscosity (optional) +params.nu_8 = 0 # hyper-hyperviscosity (very high wavenumber damping) +``` + +Higher-order viscosity (`nu_4`, `nu_8`) damps high wavenumbers without affecting large scales. + +#### Stratification (Stratified Solvers) + +```python +params.N = 1.0 # Brunt-Väisälä frequency (buoyancy frequency) +``` + +#### Rotation (Shallow Water) + +```python +params.f = 1.0 # Coriolis parameter +params.c2 = 10.0 # squared phase velocity (gravity wave speed) +``` + +### Time Stepping (`params.time_stepping`) + +```python +params.time_stepping.t_end = 10.0 # simulation end time +params.time_stepping.it_end = 100 # or maximum iterations + +params.time_stepping.deltat0 = 0.01 # initial time step +params.time_stepping.USE_CFL = True # adaptive CFL-based time step +params.time_stepping.CFL = 0.5 # CFL number (if USE_CFL=True) + +params.time_stepping.type_time_scheme = "RK4" # or "RK2", "Euler" +``` + +**Recommended**: Use `USE_CFL=True` with `CFL=0.5` for adaptive time stepping. + +### Initial Fields (`params.init_fields`) + +```python +params.init_fields.type = "noise" # initialization method +``` + +**Available types**: +- `"noise"`: Random noise +- `"dipole"`: Vortex dipole +- `"vortex"`: Single vortex +- `"taylor_green"`: Taylor-Green vortex +- `"from_file"`: Load from file +- `"in_script"`: Define in script + +#### From File + +```python +params.init_fields.type = "from_file" +params.init_fields.from_file.path = "path/to/state_file.h5" +``` + +#### In Script + +```python +params.init_fields.type = "in_script" + +# Define initialization after creating sim +sim = Simul(params) + +# Access state fields +vx = sim.state.state_phys.get_var("vx") +vy = sim.state.state_phys.get_var("vy") + +# Set fields +X, Y = sim.oper.get_XY_loc() +vx[:] = np.sin(X) * np.cos(Y) +vy[:] = -np.cos(X) * np.sin(Y) + +# Run simulation +sim.time_stepping.start() +``` + +### Output Settings (`params.output`) + +#### Output Directory + +```python +params.output.sub_directory = "my_simulation" +``` + +Directory created within `$FLUIDSIM_PATH` or current directory. + +#### Save Periods + +```python +params.output.periods_save.phys_fields = 1.0 # save fields every 1.0 time units +params.output.periods_save.spectra = 0.5 # save spectra +params.output.periods_save.spatial_means = 0.1 # save spatial averages +params.output.periods_save.spect_energy_budg = 0.5 # spectral energy budget +``` + +Set to `0` to disable a particular output type. + +#### Print Control + +```python +params.output.periods_print.print_stdout = 0.5 # print status every 0.5 time units +``` + +#### Online Plotting + +```python +params.output.periods_plot.phys_fields = 2.0 # plot every 2.0 time units + +# Must also enable the output module +params.output.ONLINE_PLOT_OK = True +params.output.phys_fields.field_to_plot = "vorticity" # or "vx", "vy", etc. +``` + +### Forcing (`params.forcing`) + +Add forcing terms to maintain energy: + +```python +params.forcing.enable = True +params.forcing.type = "tcrandom" # time-correlated random forcing + +# Forcing parameters +params.forcing.nkmax_forcing = 5 # maximum forced wavenumber +params.forcing.nkmin_forcing = 2 # minimum forced wavenumber +params.forcing.forcing_rate = 1.0 # energy injection rate +``` + +**Common forcing types**: +- `"tcrandom"`: Time-correlated random forcing +- `"proportional"`: Proportional forcing (maintains specific spectrum) +- `"in_script"`: Custom forcing defined in script + +## Parameter Safety + +The Parameters object raises `AttributeError` when accessing non-existent parameters: + +```python +params.nu_2 = 1e-3 # OK +params.nu2 = 1e-3 # ERROR: AttributeError +``` + +This prevents typos that would be silently ignored in text-based configuration files. + +## Viewing All Parameters + +```python +# Print all parameters +params._print_as_xml() + +# Get as dictionary +param_dict = params._make_dict() +``` + +## Saving Parameter Configuration + +Parameters are automatically saved with simulation output: + +```python +params._save_as_xml("simulation_params.xml") +params._save_as_json("simulation_params.json") +``` diff --git a/scientific-skills/fluidsim/references/simulation_workflow.md b/scientific-skills/fluidsim/references/simulation_workflow.md new file mode 100644 index 0000000..29c85da --- /dev/null +++ b/scientific-skills/fluidsim/references/simulation_workflow.md @@ -0,0 +1,172 @@ +# Simulation Workflow + +## Standard Workflow + +Follow these steps to run a fluidsim simulation: + +### 1. Import Solver + +```python +from fluidsim.solvers.ns2d.solver import Simul + +# Or use dynamic import +import fluidsim +Simul = fluidsim.import_simul_class_from_key("ns2d") +``` + +### 2. Create Default Parameters + +```python +params = Simul.create_default_params() +``` + +This returns a hierarchical `Parameters` object containing all simulation settings. + +### 3. Configure Parameters + +Modify parameters as needed. The Parameters object prevents typos by raising `AttributeError` for non-existent parameters: + +```python +# Domain and resolution +params.oper.nx = 256 # grid points in x +params.oper.ny = 256 # grid points in y +params.oper.Lx = 2 * pi # domain size x +params.oper.Ly = 2 * pi # domain size y + +# Physical parameters +params.nu_2 = 1e-3 # viscosity (negative Laplacian) + +# Time stepping +params.time_stepping.t_end = 10.0 # end time +params.time_stepping.deltat0 = 0.01 # initial time step +params.time_stepping.USE_CFL = True # adaptive time step + +# Initial conditions +params.init_fields.type = "noise" # or "dipole", "vortex", etc. + +# Output settings +params.output.periods_save.phys_fields = 1.0 # save every 1.0 time units +params.output.periods_save.spectra = 0.5 +params.output.periods_save.spatial_means = 0.1 +``` + +### 4. Instantiate Simulation + +```python +sim = Simul(params) +``` + +This initializes: +- Operators (FFT, differential operators) +- State variables (velocity, vorticity, etc.) +- Output handlers +- Time stepping scheme + +### 5. Run Simulation + +```python +sim.time_stepping.start() +``` + +The simulation runs until `t_end` or specified number of iterations. + +### 6. Analyze Results During/After Simulation + +```python +# Plot physical fields +sim.output.phys_fields.plot() +sim.output.phys_fields.plot("vorticity") +sim.output.phys_fields.plot("div") + +# Plot spatial means +sim.output.spatial_means.plot() + +# Plot spectra +sim.output.spectra.plot1d() +sim.output.spectra.plot2d() +``` + +## Loading Previous Simulations + +### Quick Loading (For Plotting Only) + +```python +from fluidsim import load_sim_for_plot + +sim = load_sim_for_plot("path/to/simulation") +sim.output.phys_fields.plot() +sim.output.spatial_means.plot() +``` + +Fast loading without full state initialization. Use for post-processing. + +### Full State Loading (For Restarting) + +```python +from fluidsim import load_state_phys_file + +sim = load_state_phys_file("path/to/state_file.h5") +sim.time_stepping.start() # continue simulation +``` + +Loads complete state for continuing simulations. + +## Restarting Simulations + +To restart from a saved state: + +```python +params = Simul.create_default_params() +params.init_fields.type = "from_file" +params.init_fields.from_file.path = "path/to/state_file.h5" + +# Optionally modify parameters for the continuation +params.time_stepping.t_end = 20.0 # extend simulation + +sim = Simul(params) +sim.time_stepping.start() +``` + +## Running on Clusters + +FluidSim integrates with cluster submission systems: + +```python +from fluiddyn.clusters.legi import Calcul8 as Cluster + +# Configure cluster job +cluster = Cluster() +cluster.submit_script( + "my_simulation.py", + name_run="my_job", + nb_nodes=4, + nb_cores_per_node=24, + walltime="24:00:00" +) +``` + +Script should contain standard workflow steps (import, configure, run). + +## Complete Example + +```python +from fluidsim.solvers.ns2d.solver import Simul +from math import pi + +# Create and configure parameters +params = Simul.create_default_params() +params.oper.nx = params.oper.ny = 256 +params.oper.Lx = params.oper.Ly = 2 * pi +params.nu_2 = 1e-3 +params.time_stepping.t_end = 10.0 +params.init_fields.type = "dipole" +params.output.periods_save.phys_fields = 1.0 + +# Run simulation +sim = Simul(params) +sim.time_stepping.start() + +# Analyze results +sim.output.phys_fields.plot("vorticity") +sim.output.spatial_means.plot() +``` diff --git a/scientific-skills/fluidsim/references/solvers.md b/scientific-skills/fluidsim/references/solvers.md new file mode 100644 index 0000000..96eedf6 --- /dev/null +++ b/scientific-skills/fluidsim/references/solvers.md @@ -0,0 +1,94 @@ +# FluidSim Solvers + +FluidSim provides multiple solvers for different fluid dynamics equations. All solvers work on periodic domains using pseudospectral methods with FFT. + +## Available Solvers + +### 2D Incompressible Navier-Stokes + +**Solver key**: `ns2d` + +**Import**: +```python +from fluidsim.solvers.ns2d.solver import Simul +# or dynamically +Simul = fluidsim.import_simul_class_from_key("ns2d") +``` + +**Use for**: 2D turbulence studies, vortex dynamics, fundamental fluid flow simulations + +**Key features**: Energy and enstrophy cascades, vorticity dynamics + +### 3D Incompressible Navier-Stokes + +**Solver key**: `ns3d` + +**Import**: +```python +from fluidsim.solvers.ns3d.solver import Simul +``` + +**Use for**: 3D turbulence, realistic fluid flow simulations, high-resolution DNS + +**Key features**: Full 3D turbulence dynamics, parallel computing support + +### Stratified Flows (2D/3D) + +**Solver keys**: `ns2d.strat`, `ns3d.strat` + +**Import**: +```python +from fluidsim.solvers.ns2d.strat.solver import Simul # 2D +from fluidsim.solvers.ns3d.strat.solver import Simul # 3D +``` + +**Use for**: Oceanic and atmospheric flows, density-driven flows + +**Key features**: Boussinesq approximation, buoyancy effects, constant Brunt-Väisälä frequency + +**Parameters**: Set stratification via `params.N` (Brunt-Väisälä frequency) + +### Shallow Water Equations + +**Solver key**: `sw1l` (one-layer) + +**Import**: +```python +from fluidsim.solvers.sw1l.solver import Simul +``` + +**Use for**: Geophysical flows, tsunami modeling, rotating flows + +**Key features**: Rotating frame support, geostrophic balance + +**Parameters**: Set rotation via `params.f` (Coriolis parameter) + +### Föppl-von Kármán Equations + +**Solver key**: `fvk` (elastic plate equations) + +**Import**: +```python +from fluidsim.solvers.fvk.solver import Simul +``` + +**Use for**: Elastic plate dynamics, fluid-structure interaction studies + +## Solver Selection Guide + +Choose a solver based on the physical problem: + +1. **2D turbulence, quick testing**: Use `ns2d` +2. **3D flows, realistic simulations**: Use `ns3d` +3. **Density-stratified flows**: Use `ns2d.strat` or `ns3d.strat` +4. **Geophysical flows, rotating systems**: Use `sw1l` +5. **Elastic plates**: Use `fvk` + +## Modified Versions + +Many solvers have modified versions with additional physics: +- Forcing terms +- Different boundary conditions +- Additional scalar fields + +Check `fluidsim.solvers` module for complete list.