Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
214 commits
Select commit Hold shift + click to select a range
59169b5
add (the idea) of a new Variables class
spossann Jul 14, 2025
1995b6c
add new folder topology/ with file grids.py
spossann Jul 14, 2025
b2e8de1
also search for .py files when scanning for parameters files
spossann Jul 14, 2025
aaab3bb
new files struphy/io/inp/parameters.py and strupyh/io/inp/options.py …
spossann Jul 14, 2025
b4872e7
use new class StruphyParameters to set up a Maxwell simulation
spossann Jul 14, 2025
c76a6e5
formatting
spossann Jul 14, 2025
a397d48
some cleanup
spossann Jul 15, 2025
eeecd24
new options class FieldsBackground
spossann Jul 15, 2025
677c238
new classes `Variables` and `Variable` for handling model variables
spossann Jul 15, 2025
0988014
new classes: `Species`, `MultiSpecies` and `SubSpeceis`; these will r…
spossann Jul 16, 2025
eb0fa98
belongs to previous commit
spossann Jul 16, 2025
24b76bf
formatting and cleaning of new params file
spossann Jul 16, 2025
f248d02
a lot of tryout
spossann Jul 16, 2025
3a0e587
add method `derive_units` to Units class; remove dataclass decorator
spossann Jul 17, 2025
ce3862a
add function `check_option` to options.py
spossann Jul 17, 2025
9c97d94
finished light-weight init of models base class
spossann Jul 17, 2025
3bcb924
add `set_phys_params` and `set_equation_params` to SubSpecies
spossann Jul 17, 2025
a0fec5a
remove @staticmethod from Model.bulk_species and Model.velocity_scale
spossann Jul 17, 2025
dad4961
add inner class Options to Propagator base
spossann Jul 17, 2025
70f5349
new folder `physics`; holds the natural constants for the moment
spossann Jul 17, 2025
ece3f90
new files `propagators/hub.py` and `propagators/hub.pyi`; the Propaga…
spossann Jul 17, 2025
0261be4
adapt Maxwell propagator
spossann Jul 17, 2025
bf78073
Object-oriented brainstorming
max-models Jul 17, 2025
ccdeaba
redo Species structure: FieldSpecies, FluidSpecies, KineticSpecies
spossann Jul 18, 2025
629cc15
added new file models/variables.py
spossann Jul 18, 2025
0fddf10
remove propagators/hub
spossann Jul 18, 2025
2b7812b
working on struphy main.py
spossann Jul 18, 2025
b27e879
Added DiagnosticSpecies, added attribute variables to Species, added …
spossann Jul 29, 2025
6d6a56a
added metohd allocate to FEECVariable
spossann Jul 29, 2025
5d320ec
- new base class `Perturbation` in initial/base.py
spossann Jul 29, 2025
bf45fe7
perform initialize_coeffs in __init__ of SplineFunction when backgrou…
spossann Jul 29, 2025
60e0d39
use given_in_basis in TransformedPformComponent; experiment with TYPE…
spossann Jul 29, 2025
88d500d
put Literal options on top of options.py module
spossann Jul 29, 2025
469a56b
do not allow dict input in setup parameters anymore (only file paths,…
spossann Jul 29, 2025
ae34596
make ButcherTableau a dataclass
spossann Jul 29, 2025
7dfecfb
Propagator base class: add options attribute and setter; add Options …
spossann Jul 29, 2025
1da7b0f
New design of Maxwell propagator:
spossann Jul 29, 2025
cd81285
StruphyModel base class: new methods allocate_feec, set_propagators a…
spossann Jul 29, 2025
72528d1
added type annotation to FEECVariable declaration for better inferenc…
spossann Jul 29, 2025
6aa641b
use new methods of model in main.py
spossann Jul 29, 2025
a3b9601
have a working light-weight .py parameter file for Maxwell
spossann Jul 29, 2025
e13bcaf
work on allocate of Maxwell propagator
spossann Jul 29, 2025
d2b2f56
added allocate_propagators and prop_list to StruphyModel
spossann Jul 29, 2025
ff2c5f1
improved Propagator.set_variables() method; make Maxwell toy model work
spossann Jul 30, 2025
bd7c452
Make coaxial test for Maxwell run
spossann Jul 30, 2025
6a5e453
add function import_parameters_py; make pproc work with new params
spossann Jul 30, 2025
6721f76
added params file Maxwell_coaxial.py for verification; made pproc wor…
spossann Jul 30, 2025
11408b3
started fixing some unit tests
spossann Jul 31, 2025
0445f62
- remove StruphyModel.setup()
spossann Jul 31, 2025
6fdae08
LinearMHD model is running
spossann Jul 31, 2025
7526d9a
new abstract method StruphyModel.allocate_helpers()
spossann Aug 1, 2025
0c74a66
new generate_default_parameter_file for .py parameters
spossann Aug 1, 2025
c3bab8b
include call to struphy main in parameter file; new class MetaOptions
spossann Aug 4, 2025
95b6e17
renam main.py -> struphy.py and main() -> run()
spossann Aug 4, 2025
b76d94e
rename MetaOptions -> EnvironmentOptions
spossann Aug 4, 2025
ad4f3fe
New framework for model tests:
spossann Aug 4, 2025
78a3578
delete StruphyParameters
spossann Aug 4, 2025
c138e26
allow pickling parameter objects when no params_path is given
spossann Aug 5, 2025
419be1d
pickle of compiled domain doesnt work
spossann Aug 5, 2025
2198811
implement work-around for pickling domain
spossann Aug 5, 2025
02541ef
new function `load_data` in main.py; added fitting to power_spectrum_…
spossann Aug 6, 2025
f96f77b
clean up screen output and maxwell test
spossann Aug 6, 2025
92616fc
nicer screen output, inidicate code sections
spossann Aug 6, 2025
186545c
make test_maxwell a pytest
spossann Aug 6, 2025
5d78795
add coaxial test to test_maxwell
spossann Aug 6, 2025
66d78b1
make __init__ an abstract method of StruphyModel; require 3 ranks for…
spossann Aug 6, 2025
8e79ab8
new test test_LinearMHD.py is working
spossann Aug 6, 2025
bfca873
refactor `struphy params`, use getcwd()/params_MODEL.py as default path
spossann Aug 6, 2025
7b1d548
new file models/tests/test_models.py for generic testing
spossann Aug 7, 2025
2bd1a87
minor changes
spossann Aug 7, 2025
bb41fa9
generate specific default parameter file for LinearMHD
spossann Aug 7, 2025
d07d716
adapt marler propagators PushEta and PushVxB
spossann Aug 7, 2025
02346a3
adapt toy model VLasov
spossann Aug 7, 2025
6f4316f
work on the allocate() method for PICVariable
spossann Aug 7, 2025
86ad116
work on storing pic data
spossann Aug 7, 2025
4f9ec66
Re-factor Maxwllian3D and base class:
spossann Aug 11, 2025
c534984
set background in Particles according to new framework - no dicts, bu…
spossann Aug 12, 2025
b23593e
remove some unneccessary imports
spossann Aug 12, 2025
e24278e
re-factor marker paramter passing
spossann Aug 13, 2025
8b3cae3
Vlasov is running
spossann Aug 14, 2025
1b27f67
default parameters for kinetic species
spossann Aug 14, 2025
4e3b264
new class BoundaryParameters for particles; start working on Tutorial 01
spossann Aug 15, 2025
e0b292c
started new particels tutorial
spossann Aug 16, 2025
397282c
new way of saving during pproc
spossann Aug 25, 2025
7930d7d
new tutorial 01: parameter files
spossann Aug 25, 2025
24bd43c
improve tutorial 01
spossann Aug 25, 2025
9b151a9
improve tutorial 01 more
spossann Aug 25, 2025
b1b93c3
finish tutorial 01
spossann Aug 26, 2025
7ea7aee
- get rid of @dataclass for Species
spossann Aug 27, 2025
aca8c91
improve tutorial 02
spossann Sep 2, 2025
9e05ede
remove "as Model" in params file
spossann Sep 4, 2025
fc8b841
improve tutorials 1 and 2
spossann Sep 4, 2025
746370e
minor
spossann Sep 5, 2025
474e87b
* Refactor Domain base class:
spossann Sep 5, 2025
d0a3460
adapted GVECunit
spossann Sep 5, 2025
7e9e980
use locals() to get parameter dict; adapt some more mappings
spossann Sep 5, 2025
d306f50
adapt rest of mappings
spossann Sep 6, 2025
e81a899
replace Domain.params_map -> Domain.params
spossann Sep 6, 2025
5eca46c
fix unit tests
spossann Sep 8, 2025
390f62c
use same params.setter structure in equils as in domains (remove meth…
spossann Sep 8, 2025
994413e
formatting
spossann Sep 8, 2025
5728e79
Merge branch '458-store-domain-input-paramaters-unchanged' into 318-p…
spossann Sep 8, 2025
250ed36
tutorial 2 works up to GuidingCenter
spossann Sep 8, 2025
702fc95
Introduce SimData.orbits and SimData.spline_values
spossann Sep 9, 2025
9e99367
repair Maxwell and LinearMHD tests
spossann Sep 9, 2025
bdcaa7f
Two new abstract methods for Propagator:
spossann Sep 9, 2025
56e3c9c
New way of setting Propagator options through three abstract
spossann Sep 10, 2025
dc05b3a
adapt LinearMHD to new options setting
spossann Sep 10, 2025
00a9c5c
adapt Vlasov to new options
spossann Sep 10, 2025
ab21da6
make toy model GuidingCenter run in new framework
spossann Sep 10, 2025
6694072
tutorial 2 on test particles is now complete and running. Adaption of…
spossann Sep 10, 2025
ff45240
started to transfer model VlasovAmpereOneSpecies
spossann Sep 10, 2025
aaa58fd
VlasovAmpereOneSecies is running
spossann Sep 11, 2025
32baaf2
new class BinningPlot
spossann Sep 12, 2025
f270e5a
added Simdata.f dict for distribution function
spossann Sep 12, 2025
bc1cdc3
new method Maxwellian.add_perturbation enables to extract the backgro…
spossann Sep 12, 2025
72c59ce
fix bug in initial Poisson solve of VlasovAmpereOneSpecies; add flaf …
spossann Sep 12, 2025
ab85525
add line_profiler to some functions
spossann Sep 12, 2025
ef3ba9d
fix base_units loading; allow comm=None in Particles
spossann Sep 12, 2025
f2a403f
added tutorial 5
spossann Sep 12, 2025
508445f
Format all source files and and temporary linting check to CI
max-models Sep 12, 2025
745b2d2
Merge branch 'format-all-files' into '318-parameter-file-as-py'
spossann Sep 12, 2025
8302d5d
Move tutorials to base folder
max-models Sep 13, 2025
e014b9c
Merge branch 'move-tutorials-to-base-folder' into '318-parameter-file…
spossann Sep 13, 2025
3faca93
Fix unit testing
spossann Sep 18, 2025
0691aae
Merge branch 'fix-unit-testing' into '318-parameter-file-as-py'
spossann Sep 18, 2025
af3668b
Resolve "Port toy model PressurelessSPH to 318"
spossann Sep 25, 2025
f557c92
Merge branch '460-port-toy-model-pressurelesssph-to-318' into '318-pa…
spossann Sep 25, 2025
0f8f5e2
Port sph tutorial to 318
spossann Sep 29, 2025
33b8e76
Merge branch 'port-sph-tutorial-to-318' into '318-parameter-file-as-py'
spossann Sep 29, 2025
d3d46ca
Recent updates from devel into 318
spossann Oct 1, 2025
44dfc2e
Merge branch 'merge-devel-1-10-25' into '318-parameter-file-as-py'
spossann Oct 1, 2025
649eb92
Updated __init__.py files in 318
max-models Oct 1, 2025
60dbc08
Merge branch 'update-init-files' into '318-parameter-file-as-py'
spossann Oct 1, 2025
1952c26
Add SPH and VlasovAmpere verification tests
spossann Oct 6, 2025
d00e7ea
Merge branch 'verif-tests-porting' into '318-parameter-file-as-py'
spossann Oct 6, 2025
797f3d8
Resolve "Port some toy models to 318"
spossann Oct 7, 2025
3974ada
Merge branch '461-port-some-toy-models-to-318' into '318-parameter-fi…
spossann Oct 7, 2025
ab43c4a
Merge branch 'devel' into merge-devel-8-10-25
spossann Oct 8, 2025
b5754f0
remove double --check-file
spossann Oct 8, 2025
9f5701d
Update shearalfven to new format
max-models Oct 8, 2025
5ee5a56
Merge branch 'update-shearalfven-to-new-format' into '318-parameter-f…
spossann Oct 8, 2025
fd2a463
test hook
spossann Oct 8, 2025
4c77173
update pre-commit yaml
spossann Oct 8, 2025
16ae146
test pre-commit hooks
spossann Oct 8, 2025
b1343de
try hook option --assume-in-merge
spossann Oct 8, 2025
fc42259
test hook
spossann Oct 8, 2025
efc0fc1
remove merge conflicts
spossann Oct 8, 2025
b75d347
Resolve "Port remaining toy models"
spossann Oct 8, 2025
d3a073f
Merge branch '465-port-remaining-toy-models' into '318-parameter-file…
spossann Oct 8, 2025
bd9e618
Merge branch '318-parameter-file-as-py' into merge-devel-8-10-25
spossann Oct 8, 2025
c56a8d4
Merge branch 'merge-devel-8-10-25' into '318-parameter-file-as-py'
spossann Oct 8, 2025
1bc3a8d
Ported three fluid models
spossann Oct 9, 2025
7e516ee
Merge branch 'port-three-fluid-models' into '318-parameter-file-as-py'
spossann Oct 9, 2025
433d54b
Porting the model LinearMHDDriftkineticCC
bkna0327 Oct 14, 2025
da064e6
Merge branch '318-parameter-file-as-py-mhd-driftkinetic' into '318-pa…
spossann Oct 14, 2025
3c6a268
Added `--oversubscribe` to the test mpirun commands
max-models Oct 14, 2025
4f6d91e
Merge branch 'run-318-tests-with-oversubscribe' into '318-parameter-f…
spossann Oct 14, 2025
408932f
enable TAE sims
Oct 15, 2025
239822b
fix bug
Oct 16, 2025
4f6eccc
fix bug
bkna0327 Oct 18, 2025
f41eb71
Resolve "Porting the rest of fluid models"
spossann Oct 21, 2025
223bdf4
Merge branch '469-porting-the-rest-of-fluid-models' into '318-paramet…
spossann Oct 21, 2025
2b8dbf8
Merge branch 'devel' into merge-devel-21-10-2025
spossann Oct 21, 2025
6e9ce14
re-add model_tests_mpi
spossann Oct 21, 2025
353d692
remove test_tutorials.py again
spossann Oct 21, 2025
ac598e3
add new mpi and xp to species.py
spossann Oct 21, 2025
7be337d
add mpi and xp to some new files which do not exist in devel
spossann Oct 21, 2025
9d92d1f
add new mpi to new models files
spossann Oct 21, 2025
0e764a7
add missing Pyccelkernel
spossann Oct 21, 2025
0a85779
check for MockMPI in StruphyModel
spossann Oct 21, 2025
9d08cd5
remove deprecated --verification flag from tests
spossann Oct 21, 2025
74c5e06
formatting
spossann Oct 21, 2025
77fd7e4
test an already ported model for the single test
spossann Oct 21, 2025
111775d
use Barrier() in main.py
spossann Oct 21, 2025
533223c
fix verification test
spossann Oct 21, 2025
06e86f4
fix gyrokinetic_poisson
spossann Oct 21, 2025
613cd58
formatting
spossann Oct 21, 2025
21815d6
Merge branch 'merge-devel-21-10-2025' into '318-parameter-file-as-py'
spossann Oct 21, 2025
26fc52e
Resolve "Rename struphy array imports to xp"
max-models Oct 22, 2025
c76e68e
Merge branch '470-rename-struphy-array-imports-to-xp-3' into '318-par…
spossann Oct 22, 2025
5eac499
Resolve "Porting the rest of kinetic models"
spossann Oct 22, 2025
3241341
Merge branch '471-porting-the-rest-of-kinetic-models' into '318-param…
spossann Oct 22, 2025
6b6163c
Use cunumpy
max-models Oct 22, 2025
93263f8
Merge branch 'use-cunumpy' into '318-parameter-file-as-py'
spossann Oct 22, 2025
ac71d97
minor fixes
Oct 22, 2025
db8623c
Update tutorials
spossann Oct 22, 2025
50a689b
Merge branch 'update-tutorials' into '318-parameter-file-as-py'
spossann Oct 22, 2025
6452078
Added struphy[mpi] to [dev] dependencies
max-models Oct 23, 2025
b2afd19
Port two hybrid
spossann Oct 23, 2025
cf91a74
Merge branch 'port-two-hybrid' into '318-parameter-file-as-py'
spossann Oct 23, 2025
5a3d7c5
Merge branch 'install-mpi4pi-with-dev' into '318-parameter-file-as-py'
spossann Oct 23, 2025
670539f
merging with the main branch
Oct 23, 2025
0bd4bb6
bug fix
Oct 24, 2025
f52925e
bug fix
Oct 24, 2025
0485d8e
bug fix
Nov 28, 2025
1c99ebc
enable restart
Nov 29, 2025
3cdbc6b
remove barrier at main.py
Dec 1, 2025
f9934db
merging with devel
Dec 2, 2025
0925408
merging with devel
Dec 2, 2025
a144c08
merging with devel
Dec 2, 2025
0378cc5
merging with devel final
Dec 2, 2025
2899091
set default boxes_per_dim None
Dec 2, 2025
fa2327a
format
Dec 2, 2025
524a109
fix piplines
Dec 12, 2025
95feee4
fix piplines
Dec 12, 2025
51fd949
Merge branch 'devel' into enable_tae
Dec 12, 2025
8c2fef1
fix pipline
Dec 12, 2025
f2dd7f4
resolving comments
Jan 19, 2026
bbabb86
formatting
Jan 19, 2026
334f514
Merge branch 'devel' into enable_tae
Jan 19, 2026
92e7734
rename psic_to_eta as psic_to_rc
Jan 22, 2026
36fc8fe
pass the argument n_col_... to the base class
Jan 22, 2026
6db7bb6
consistent input arguments for CanonicalMaxwellian
Feb 17, 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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,4 @@ markers = [
"kinetic",
"hybrid",
"single",
]
]
278 changes: 278 additions & 0 deletions src/struphy/kinetic_background/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,281 @@ def add_perturbation(self) -> bool:
def add_perturbation(self, new):
assert isinstance(new, bool)
self._add_perturbation = new


class CanonicalMaxwellian(KineticBackground):
r"""canonical Maxwellian distribution function.
It is defined by three constants of motion in the axissymmetric toroidal system:

- Shifted canonical toroidal momentum
.. math::

\psi_c = \psi + \frac{m_s F}{q_s B}v_\parallel - \text{sign}(v_\parallel)\sqrt{2(\epsilon - \mu B)}\frac{m_sF}{q_sB} \mathcal{H}(\epsilon - \mu B),

- Energy
.. math::

\epsilon = \frac{1}{2}m_sv_\parallel² + \mu B,

- Magnetic moment
.. math::

\mu = \frac{m_s v_\perp²}{2B},

where :math:`\psi` is the poloidal magnetic flux function, :math:`F=F(\psi)` is the poloidal current function and :math:`\mathcal{H}` is the Heaviside function.
With the three constants of motion, a canonical Maxwellian distribution function is defined as

.. math::

F(\psi_c, \epsilon, \mu) = \frac{n(\psi_c)}{(2\pi)^{3/2}v_\text{th}³(\psi_c)} \text{exp}\left[ - \frac{\epsilon}{v_\text{th}²(\psi_c)}\right].

"""

@abstractmethod
def vth(self, *etas):
"""Thermal velocities (0-forms).

Parameters
----------
etas : numpy.arrays
Evaluation points. All arrays must be of same shape (can be 1d for flat evaluation).

Returns
-------
A list[float] (background values) or a list[numpy.array] of the evaluated thermal velocities.
"""
pass

@abstractmethod
def eval_energy(self, *etas):
"""Energy evaluated at given particle positions and velocities."""
pass

@abstractmethod
def eval_psic(self, *etas):
"""Shifted canonical toroidal momentum evaluated at given particle positions and velocities."""
pass

@abstractmethod
def eval_rc(self, *etas):
"""Callable function return evaluation points ( :math:`r_c` ) from particle positions ( :math:`\eta_1, \eta_2, \eta_3` ).

Parameters
----------
etas : numpy.arrays
Evaluation points. All arrays must be of same shape (can be 1d for flat evaluation).

Returns
-------
A list[float] (background values) or a list[numpy.array] of the evaluation points (etas).
"""
pass

@property
@abstractmethod
def maxw_params(self) -> dict:
"""Parameters dictionary defining moments of the Maxwellian."""

def check_maxw_params(self):
for k, v in self.maxw_params.items():
assert isinstance(k, str)
assert isinstance(v, tuple), f"Maxwallian parameter {k} must be tuple, but is {v}"
assert len(v) == 2

assert isinstance(v[0], (float, int, Callable))
assert isinstance(v[1], Perturbation) or v[1] is None

@classmethod
def gaussian(self, e, vth=1.0):
"""3-dim. normal distribution, to which array-valued thermal velocities can be passed.

Parameters
----------
v : float | array-like
Velocity coordinate(s).

vth : float | array-like
Thermal velocity evaluated at position array.

Returns
-------
An array of size(e).
"""

if isinstance(vth, xp.ndarray):
assert e.shape == vth.shape, f"{e.shape = } but {vth.shape = }"

out = 2.0 * xp.sqrt(e / xp.pi) / vth**3 * xp.exp(-e / vth**2)

return out

def __call__(self, *args):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here it is not clear whether one evaluates at eta or at psic. I would opt for eta for consistency.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Currently, args includes the canonical toroidal momentum psic and the energy $\varepsilon$.

"""Evaluates the canonical Maxwellian distribution function.

There are two use-cases for this function in the code:

1. Evaluating for particles ("flat evaluation", inputs are all 1D of length N_p)
2. Evaluating the function on a meshgrid (constants of motion).

Hence all arguments must always have

1. the same shape
2. either ndim = 1 or ndim = 3 (energy, mu, canonical toroidal momentum).

Parameters
----------
*args : array_like
Constants of motion arguments in the order eta1, eta2, eta3, v1, ..., vn.

Returns
-------
f : xp.ndarray
The evaluated Maxwellian.
"""

# Check that all args have the same shape
shape0 = xp.shape(args[0])
for i, arg in enumerate(args):
assert xp.shape(arg) == shape0, f"Argument {i} has {xp.shape(arg) = }, but must be {shape0 = }."
assert xp.ndim(arg) == 1 or xp.ndim(arg) == 3, (
f"{xp.ndim(arg) = } not allowed for canonical Maxwellian evaluation."
) # flat or meshgrid evaluation

# Get result evaluated at eta's
res = self.n(*args)
vths = self.vth(*args)

# take care of correct broadcasting, assuming args come from constants of motion meshgrid
if xp.ndim(args[0]) == 3:
# move eta axes to the back
arg_t = xp.moveaxis(args[0], 0, -1)
arg_t = xp.moveaxis(arg_t, 0, -1)
arg_t = xp.moveaxis(arg_t, 0, -1)

# broadcast
res_broad = res + 0.0 * arg_t

# move eta axes to the front
res = xp.moveaxis(res_broad, -1, 0)
res = xp.moveaxis(res, -1, 0)
res = xp.moveaxis(res, -1, 0)

# Multiply result with gaussian in energy
# correct broadcasting
if xp.ndim(args[0]) == 3:
vth_broad = vths + 0.0 * arg_t
vth = xp.moveaxis(vth_broad, -1, 0)
vth = xp.moveaxis(vth, -1, 0)
vth = xp.moveaxis(vth, -1, 0)
else:
vth = vths

e = self.eval_energy(*args)
res *= self.gaussian(e, vth=vth)

return res

def _evaluate_moment(self, eta1, eta2, eta3, vparallel, mu, *, name: str = "n", add_perturbation: bool = None):
"""Scalar moment evaluation as background + perturbation.

Parameters
----------
eta1, eta2, eta3 : numpy.arrays
Evaluation points. All arrays must be of same shape (can be 1d for flat evaluation).

vparallel : numpy.array
Parallel velocity.

mu : numpy.array
Magnetic moment.

name : str
Which moment to evaluate (see varaible "dct" below).

add_perturbation : bool | None
Whether to add the perturbation defined in maxw_params. If None, is taken from self.add_perturbation.

Returns
-------
A float (background value) or a numpy.array of the evaluated scalar moment.
"""

# collect arguments
assert isinstance(eta1, xp.ndarray)
assert isinstance(eta2, xp.ndarray)
assert isinstance(eta3, xp.ndarray)
assert isinstance(vparallel, xp.ndarray)
assert isinstance(mu, xp.ndarray)

params = self.maxw_params[name]
assert isinstance(params, tuple)
assert len(params) == 2

# flat evaluation for markers
if eta1.ndim == 1:
etas = [
xp.concatenate(
(eta1[:, None], eta2[:, None], eta3[:, None]),
axis=1,
),
]
# assuming that input comes from meshgrid.
elif eta1.ndim == 4:
etas = (
eta1[:, :, :, 0],
eta2[:, :, :, 0],
eta3[:, :, :, 0],
)
elif eta1.ndim == 5:
etas = (
eta1[:, :, :, 0, 0],
eta2[:, :, :, 0, 0],
eta3[:, :, :, 0, 0],
)
elif eta1.ndim == 6:
etas = (
eta1[:, :, :, 0, 0, 0],
eta2[:, :, :, 0, 0, 0],
eta3[:, :, :, 0, 0, 0],
)
else:
etas = (eta1, eta2, eta3)

# initialize output
if eta1.ndim == 1:
out = 0.0 * eta1
else:
out = 0.0 * etas[0]

# evaluate background
background = params[0]
if isinstance(background, (float, int)):
out += background
else:
assert callable(background)
# if eta1.ndim == 1:
# out += background(eta1, eta2, eta3)
# else:
out += background(self.eval_rc(eta1, eta2, eta3, vparallel, mu))

# add perturbation
if add_perturbation is None:
add_perturbation = self.add_perturbation

perturbation = params[1]
if perturbation is not None and add_perturbation:
assert isinstance(perturbation, Perturbation)
out += perturbation(self.eval_rc(eta1, eta2, eta3, vparallel, mu))

return out

@property
def add_perturbation(self) -> bool:
if not hasattr(self, "_add_perturbation"):
self._add_perturbation = True
return self._add_perturbation

@add_perturbation.setter
def add_perturbation(self, new):
assert isinstance(new, bool)
self._add_perturbation = new
Loading