Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
5c6e3a7
Port `FV::Div_par_mod` from Hermes-3
ZedThree Nov 6, 2025
3059d12
Port `FV::Div_par_fvv` from Hermes-3
ZedThree Nov 6, 2025
60f1946
Port `Div_par_K_Grad_par_mod` from Hermes-3
ZedThree Nov 6, 2025
f53b8f3
Add MMS tests for finite volume operators
ZedThree Nov 6, 2025
207802f
Add tests for all FV slope limiters
ZedThree Nov 7, 2025
a230642
Port `Superbee` finite volume limiter from Hermes-3
ZedThree Nov 7, 2025
30dc670
Fix clang-tidy warnings for fv_ops
ZedThree Nov 7, 2025
fcfe963
Move check up
dschwoerer Nov 12, 2025
b209a5a
Ensure FCI path is always used for FCI
dschwoerer Jan 20, 2026
e0480fc
FV_div_par_fvv seems to be reduced order due to slope limiting character
dschwoerer Feb 4, 2026
7ffc7fa
Add doc to option
dschwoerer Feb 4, 2026
aa8e5d4
Merge remote-tracking branch 'origin/hermitespline' into HEAD
dschwoerer Mar 11, 2026
f5ca1d0
Introduce Field3DParallel
dschwoerer Jun 26, 2025
12df335
No need for orderedDicts
dschwoerer Jun 26, 2025
e71eebe
Remove wrong comment, FieldPerp is present
dschwoerer Jun 26, 2025
a9366cb
Start using Field3DParallel for derivatives
dschwoerer Jul 10, 2025
b3983c1
Do not use separate derivative store for Field3DParallel
dschwoerer Jul 16, 2025
32f4c65
Do not change non-FCI fields
dschwoerer Jul 16, 2025
09f7466
Add function to header file
dschwoerer Jul 17, 2025
e1a15dd
Ensure emptyFrom works
dschwoerer Jul 17, 2025
f98d5de
Use f3dwy to preserve parallel fields
dschwoerer Jul 17, 2025
fc98ac4
Preserve parallel fields for d1_dy calculation
dschwoerer Jul 17, 2025
205d502
Add overloads for DD?(Field3DParallel)
dschwoerer Jul 17, 2025
6a7c407
add asF3dwy() stub to Field2D
dschwoerer Jul 18, 2025
268ecfc
Add some documentation
dschwoerer Jul 18, 2025
f3b36a4
Be more explicit in the naming
dschwoerer Jul 18, 2025
b47343f
do not use const for BoutReal in signature
dschwoerer Jul 21, 2025
d07bde5
Add Field3DParallel + Field2D fieldops
dschwoerer Jul 21, 2025
6374539
Move function definition after class definition
dschwoerer Jul 21, 2025
f49c94c
Prefer std::move
dschwoerer Jul 21, 2025
140bf78
Add binary operators Field2D - FieldPerp
dschwoerer Jul 21, 2025
84d99b3
Declare Field3DParallel
dschwoerer Jul 21, 2025
1219197
Add default argument like for Field3D
dschwoerer Aug 21, 2025
7bb8367
Add missing functions
dschwoerer Aug 21, 2025
acd9b93
Ensure assignment to a Field3DParallel does not fail
dschwoerer Aug 21, 2025
0e6fc75
add filledFrom for Field3DParallel
dschwoerer Aug 25, 2025
9b119c8
Allocate before usage
dschwoerer Aug 25, 2025
69dfaad
Remove commented out code
dschwoerer Sep 30, 2025
7b9525c
add asField3DParallel() const
dschwoerer Oct 21, 2025
fb6c016
Add Field3DParallel::allocate
dschwoerer Oct 23, 2025
033d872
Add implict constructors only for Field2D and Field3D
dschwoerer Oct 29, 2025
2590f7c
add yup and ydown property
dschwoerer Nov 5, 2025
957f058
simplify template
dschwoerer Nov 5, 2025
ea71ae2
Add some asserts for Field3DParallel
dschwoerer Nov 5, 2025
46d6663
Ensure parallel slices are present
dschwoerer Nov 5, 2025
b1068d1
Simplify div_par
dschwoerer Nov 5, 2025
f15f204
Do not communicate the magnetic field
dschwoerer Nov 5, 2025
d8b2240
Ensure parallel slices are set in FIELD_FUNC
dschwoerer Nov 5, 2025
9a8ebcb
ensure parallel fields are allocated
dschwoerer Jan 20, 2026
b6e1b56
Ensure `f3d.asField3DParallel() *= x` updates f3d
dschwoerer Jan 21, 2026
82d046a
ensure also parallel fields are updated in-place
dschwoerer Jan 22, 2026
00048e0
Add const version
dschwoerer Feb 2, 2026
2dd2335
Only compute parallel slices in filledFrom for FCI
dschwoerer Feb 4, 2026
4f2f60a
floor only if allocated
dschwoerer Feb 13, 2026
1adc1fc
Use allocate only to make sure data is unique
dschwoerer Feb 13, 2026
a46781a
Do not use numberParallelSlices()
dschwoerer Mar 4, 2026
80d7d34
Add regionID to f3d ctor
dschwoerer Mar 4, 2026
40e1c2e
add regionID to f2d ctor
dschwoerer Mar 4, 2026
ee6b03e
Add numberParallelSlices to all fields
dschwoerer Mar 4, 2026
9501f7a
use numberParallelSlices
dschwoerer Mar 4, 2026
ddb9132
Fix usage of coords
dschwoerer Mar 4, 2026
b5a2c3b
FCI test only works with 3D metrics
dschwoerer Mar 12, 2026
2e7dccf
Add code to load parallel metric slices
dschwoerer Oct 10, 2024
6e21bb8
Prefer [[maybe_unused]]
dschwoerer Mar 4, 2026
e5eb01a
Add code to load parallel metric slices
dschwoerer Oct 10, 2024
763ce78
Update to new interface
dschwoerer Mar 4, 2026
02aafda
Add headers from clang-tidy
dschwoerer Mar 12, 2026
f98fe9d
Remove useless std::move
dschwoerer Mar 12, 2026
bf6743f
Prefer const ref
dschwoerer Mar 12, 2026
85fb0fd
prefer const
dschwoerer Mar 12, 2026
a9c5059
fix DDY with parallel slices with FA
dschwoerer Mar 12, 2026
14462be
Merge branch 'next' of github.com:boutproject/BOUT-dev into HEAD
dschwoerer Mar 12, 2026
d5272c4
Fixes for prek
dschwoerer Mar 12, 2026
360358e
CI: install pre-release zoidberg
dschwoerer Mar 17, 2026
9943956
Add missing headers also to gen_fieldops
dschwoerer Mar 18, 2026
01582cd
Fix whitespace
dschwoerer Mar 18, 2026
f529158
Improve asserts for parallel slices
dschwoerer Mar 18, 2026
8ad5817
Do not split parallel slices by default
dschwoerer Mar 18, 2026
8d6e1a9
Simplify Div_par
dschwoerer Mar 18, 2026
de707f3
Do not compute Christoffel symbol for FCI
dschwoerer Mar 18, 2026
bd7dd2d
Do not differentiate dy for FCI
dschwoerer Mar 18, 2026
481179f
CI: install pre-release zoidberg
dschwoerer Mar 17, 2026
ca77f6b
Merge branch 'next' of https://github.com/boutproject/BOUT-dev into p…
dschwoerer Mar 18, 2026
1a5b922
CI: fix fedora CI
dschwoerer Mar 18, 2026
f89333d
CI: fix fedora CI
dschwoerer Mar 18, 2026
cbacecc
Split slices for FCI
dschwoerer Mar 18, 2026
bfbae40
Merge remote-tracking branch 'origin/par-metrics' into HEAD
dschwoerer Mar 18, 2026
d4e137c
CI: ensure pip is installed
dschwoerer Mar 18, 2026
3d184a6
CI: ensure pip is installed
dschwoerer Mar 18, 2026
2abbd6c
Load parallel B rather then J
dschwoerer Mar 18, 2026
2436326
Set parallel J
dschwoerer Mar 18, 2026
c9868d3
Fixup J computation
dschwoerer Mar 18, 2026
5bdacef
Merge branch 'par-metrics' into f3dparallel
dschwoerer Mar 18, 2026
2d922ec
Merge branch 'f3dparallel' into move-ops
dschwoerer Mar 18, 2026
a50c531
Fix region name
dschwoerer Mar 19, 2026
b57ea10
Do not attempt to communicate Bxy
dschwoerer Mar 19, 2026
be8bae5
Update to newer mesh with parallel metrics
dschwoerer Mar 19, 2026
f606ad1
Merge branch 'par-metrics' into f3dparallel
dschwoerer Mar 19, 2026
1aedd28
Merge branch 'f3dparallel' into move-ops
dschwoerer Mar 19, 2026
202e51d
Set the regionID for parallel slices
dschwoerer Mar 19, 2026
f828a9c
Allow to override isFci check
dschwoerer Mar 19, 2026
1d7b9f0
Parallel transform is not yet set, so we need to overwrite the isFci …
dschwoerer Mar 19, 2026
4b49458
Revert "Do not differentiate dy for FCI"
dschwoerer Mar 19, 2026
c865d1b
Load parallel dy
dschwoerer Mar 20, 2026
07afd43
Output that we load the parallel metrics
dschwoerer Mar 20, 2026
04d3ab3
Merge branch 'f3dparallel' into move-ops
dschwoerer Mar 20, 2026
b2a7383
prek fixes
dschwoerer Mar 20, 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: 2 additions & 0 deletions .ci_fedora.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ test . != ".$1" && mpi="$1" || mpi=openmpi
export OMP_NUM_THREADS=1
cd
cd BOUT-dev
python3 -m ensurepip
python3 -m pip install git+https://github.com/boutproject/zoidberg@better-metric
echo "starting configure"
time cmake -S . -B build -DBOUT_USE_PETSC=ON \
-DBOUT_UPDATE_GIT_SUBMODULE=OFF \
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ jobs:
run: |
python -m pip install --upgrade pip setuptools
python -m pip install -r requirements.txt
python -m pip install git+https://github.com/boutproject/zoidberg@better-metric

- name: Cache Zenodo test data
uses: actions/cache@v5
Expand All @@ -187,7 +188,7 @@ jobs:
run: BUILD_PETSC=${{ matrix.config.build_petsc }} ./.build_petsc_for_ci.sh ${{ matrix.config.build_petsc_branch }}

- name: Build ADIOS2
run: BUILD_ADIOS2=${{ matrix.config.build_adios2 }} ./.build_adios2_for_ci.sh
run: BUILD_ADIOS2=${{ matrix.config.build_adios2 }} ./.build_adios2_for_ci.sh

- name: Build BOUT++
run: UNIT_ONLY=${{ matrix.config.unit_only }} ./.ci_with_cmake.sh ${{ matrix.config.cmake_options }}
Expand Down
24 changes: 12 additions & 12 deletions include/bout/coordinates.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
*
* ChangeLog
* =========
*
*
* 2014-11-10 Ben Dudson <bd512@york.ac.uk>
* * Created by separating metric from Mesh
*
*
*
**************************************************************************
* Copyright 2014-2025 BOUT++ contributors
*
* Contact: Ben Dudson, dudson2@llnl.gov
*
*
* This file is part of BOUT++.
*
* BOUT++ is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -160,7 +160,7 @@ public:
const std::string& method = "DEFAULT",
const std::string& region = "RGN_NOBNDRY");

Field3D DDY(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D DDY(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT",
const std::string& region = "RGN_NOBNDRY") const;

Expand All @@ -172,30 +172,30 @@ public:
FieldMetric Grad_par(const Field2D& var, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

Field3D Grad_par(const Field3D& var, CELL_LOC outloc = CELL_DEFAULT,
Field3D Grad_par(const Field3DParallel& var, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

/// Advection along magnetic field V*b.Grad(f)
FieldMetric Vpar_Grad_par(const Field2D& v, const Field2D& f,
CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

Field3D Vpar_Grad_par(const Field3D& v, const Field3D& f,
Field3D Vpar_Grad_par(const Field3D& v, const Field3DParallel& f,
CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

/// Divergence along magnetic field Div(b*f) = B.Grad(f/B)
FieldMetric Div_par(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

Field3D Div_par(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D Div_par(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

// Second derivative along magnetic field
FieldMetric Grad2_par2(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");

Field3D Grad2_par2(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D Grad2_par2(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT");
// Perpendicular Laplacian operator, using only X-Z derivatives
// NOTE: This might be better bundled with the Laplacian inversion code
Expand All @@ -207,13 +207,13 @@ public:
// Full parallel Laplacian operator on scalar field
// Laplace_par(f) = Div( b (b dot Grad(f)) )
FieldMetric Laplace_par(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT);
Field3D Laplace_par(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT);
Field3D Laplace_par(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT);

// Full Laplacian operator on scalar field
FieldMetric Laplace(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& dfdy_boundary_conditions = "free_o3",
const std::string& dfdy_dy_region = "");
Field3D Laplace(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D Laplace(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& dfdy_boundary_conditions = "free_o3",
const std::string& dfdy_dy_region = "");

Expand Down Expand Up @@ -256,10 +256,10 @@ private:
class TokamakCoordinates : public Coordinates {
public:
TokamakCoordinates(Mesh *mesh) : Coordinates(mesh) {

}
private:

};
*/

Expand Down
9 changes: 9 additions & 0 deletions include/bout/deriv_store.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -522,4 +522,13 @@ private:
}
};

template <typename T>
auto& getStore() {
if constexpr (std::is_same<T, Field3DParallel>::value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "Field3DParallel" is directly included [misc-include-cleaner]

include/bout/deriv_store.hxx:37:

- #include <bout/scorepwrapper.hxx>
+ #include "bout/field3d.hxx"
+ #include <bout/scorepwrapper.hxx>

Copy link
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "std::is_same" is directly included [misc-include-cleaner]

include/bout/deriv_store.hxx:35:

- #include <unordered_map>
+ #include <type_traits>
+ #include <unordered_map>

return DerivativeStore<Field3D>::getInstance();
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: no header providing "Field3D" is directly included [misc-include-cleaner]

    return DerivativeStore<Field3D>::getInstance();
                           ^

} else {
return DerivativeStore<T>::getInstance();
}
}

#endif
6 changes: 3 additions & 3 deletions include/bout/derivs.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Coordinates::FieldMetric DDX(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT,
/// If not given, defaults to DIFF_DEFAULT
/// @param[in] region What region is expected to be calculated
/// If not given, defaults to RGN_NOBNDRY
Field3D DDY(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D DDY(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT",
const std::string& region = "RGN_NOBNDRY");

Expand Down Expand Up @@ -410,7 +410,7 @@ Coordinates::FieldMetric VDDX(const Field2D& v, const Field2D& f,
/// If not given, defaults to DIFF_DEFAULT
/// @param[in] region What region is expected to be calculated
/// If not given, defaults to RGN_NOBNDRY
Field3D VDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D VDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT",
const std::string& region = "RGN_NOBNDRY");

Expand Down Expand Up @@ -533,7 +533,7 @@ Coordinates::FieldMetric FDDX(const Field2D& v, const Field2D& f,
/// If not given, defaults to DIFF_DEFAULT
/// @param[in] region What region is expected to be calculated
/// If not given, defaults to RGN_NOBNDRY
Field3D FDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc = CELL_DEFAULT,
Field3D FDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT,
const std::string& method = "DEFAULT",
const std::string& region = "RGN_NOBNDRY");

Expand Down
32 changes: 18 additions & 14 deletions include/bout/difops.hxx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*!******************************************************************************
* \file difops.hxx
*
*
* Differential operators
*
* Changelog:
*
* 2009-01 Ben Dudson <bd512@york.ac.uk>
* 2009-01 Ben Dudson <bd512@york.ac.uk>
* * Added two optional parameters which can be put in any order
* These determine the method to use (DIFF_METHOD)
* and CELL_LOC location of the result.
Expand All @@ -15,7 +15,7 @@
* Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu
*
* Contact: Ben Dudson, bd512@york.ac.uk
*
*
* This file is part of BOUT++.
*
* BOUT++ is free software: you can redistribute it and/or modify
Expand All @@ -30,7 +30,7 @@
*
* You should have received a copy of the GNU Lesser General Public License
* along with BOUT++. If not, see <http://www.gnu.org/licenses/>.
*
*
*******************************************************************************/

#ifndef BOUT_DIFOPS_H
Expand Down Expand Up @@ -81,7 +81,7 @@ Field3D Grad_parP(const Field3D& apar, const Field3D& f);
* \f[
* v\mathbf{b}_0 \cdot \nabla f
* \f]
*
*
*
* @param[in] v The velocity in y direction
* @param[in] f The scalar field to be differentiated
Expand Down Expand Up @@ -175,7 +175,7 @@ inline Field3D Grad2_par2(const Field3D& f, CELL_LOC outloc, DIFF_METHOD method)

/*!
* Parallel divergence of diffusive flux, K*Grad_par
*
*
* \f[
* \nabla \cdot ( \mathbf{b}_0 kY (\mathbf{b}_0 \cdot \nabla) f )
* \f]
Expand All @@ -195,12 +195,16 @@ Field3D Div_par_K_Grad_par(const Field3D& kY, const Field2D& f,
Field3D Div_par_K_Grad_par(const Field3D& kY, const Field3D& f,
CELL_LOC outloc = CELL_DEFAULT);

/// Version with energy flow diagnostic
Field3D Div_par_K_Grad_par_mod(const Field3D& k, const Field3D& f, Field3D& flow_ylow,
bool bndry_flux = true);

/*!
* Perpendicular Laplacian operator
*
* This version only includes terms in X and Z, dropping
* derivatives in Y. This is the inverse operation to
* the Laplacian inversion class.
* derivatives in Y. This is the inverse operation to
* the Laplacian inversion class.
*
* For the full perpendicular Laplacian, use Laplace_perp
*/
Expand All @@ -212,7 +216,7 @@ FieldPerp Delp2(const FieldPerp& f, CELL_LOC outloc = CELL_DEFAULT, bool useFFT
/*!
* Perpendicular Laplacian, keeping y derivatives
*
*
*
*/
Coordinates::FieldMetric
Laplace_perp(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT,
Expand Down Expand Up @@ -246,18 +250,18 @@ Field2D Laplace_perpXY(const Field2D& A, const Field2D& f);

/*!
* Terms of form b0 x Grad(phi) dot Grad(A)
*
*
*/
Coordinates::FieldMetric b0xGrad_dot_Grad(const Field2D& phi, const Field2D& A,
CELL_LOC outloc = CELL_DEFAULT);

/*!
* Terms of form
* Terms of form
*
* \f[
* \mathbf{b}_0 \times \nabla \phi \cdot \nabla A
* \f]
*
*
* @param[in] phi The scalar potential
* @param[in] A The field being advected
* @param[in] outloc The cell location where the result is defined. By default the same as A.
Expand Down Expand Up @@ -291,13 +295,13 @@ constexpr BRACKET_METHOD BRACKET_CTU = BRACKET_METHOD::ctu;
* \f[
* [f, g] = (1/B) \mathbf{b}_0 \times \nabla f \cdot \nabla g
* \f]
*
*
* @param[in] f The potential
* @param[in] g The field being advected
* @param[in] method The method to use
* @param[in] outloc The cell location where the result is defined. Default is the same as g
* @param[in] solver Pointer to the time integration solver
*
*
*/
Coordinates::FieldMetric bracket(const Field2D& f, const Field2D& g,
BRACKET_METHOD method = BRACKET_STD,
Expand Down
67 changes: 53 additions & 14 deletions include/bout/field.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public:
virtual void calcParallelSlices() {}
virtual void splitParallelSlices() {}
virtual void clearParallelSlices() {}
virtual size_t numberParallelSlices() const { return 0; }

private:
/// Labels for the type of coordinate system this field is defined over
Expand Down Expand Up @@ -189,8 +190,8 @@ inline bool areFieldsCompatible(const Field& field1, const Field& field2) {
template <typename T>
inline T emptyFrom(const T& f) {
static_assert(bout::utils::is_Field_v<T>, "emptyFrom only works on Fields");
return T(f.getMesh(), f.getLocation(), {f.getDirectionY(), f.getDirectionZ()},
f.getRegionID())
return T(f.getMesh(), f.getLocation(),
DirectionTypes{f.getDirectionY(), f.getDirectionZ()}, f.getRegionID())
.allocate();
}

Expand Down Expand Up @@ -524,20 +525,27 @@ T pow(BoutReal lhs, const T& rhs, const std::string& rgn = "RGN_ALL") {
* result for non-finite numbers
*
*/
class Field3DParallel;
#ifdef FIELD_FUNC
#error This macro has already been defined
#else
#define FIELD_FUNC(name, func) \
template <typename T, typename = bout::utils::EnableIfField<T>> \
inline T name(const T& f, const std::string& rgn = "RGN_ALL") { \
\
/* Check if the input is allocated */ \
checkData(f); \
/* Define and allocate the output result */ \
T result{emptyFrom(f)}; \
BOUT_FOR(d, result.getRegion(rgn)) { result[d] = func(f[d]); } \
checkData(result); \
return result; \
#define FIELD_FUNC(_name, func) \
template <typename T, typename = bout::utils::EnableIfField<T>> \
inline T _name(const T& f, const std::string& rgn = "RGN_ALL") { \
/* Check if the input is allocated */ \
checkData(f); \
/* Define and allocate the output result */ \
T result{emptyFrom(f)}; \
BOUT_FOR(d, result.getRegion(rgn)) { result[d] = func(f[d]); } \
if constexpr (std::is_base_of_v<Field3DParallel, T>) { \
for (int i = 0; i < f.numberParallelSlices(); ++i) { \
result.yup(i) = func(f.yup(i)); \
result.ydown(i) = func(f.ydown(i)); \
} \
} \
result.name = std::string(#_name "(") + f.name + std::string(")"); \
checkData(result); \
return result; \
}
#endif

Expand Down Expand Up @@ -661,6 +669,8 @@ T copy(const T& f) {
return result;
}

class Field3DParallel;

/// Apply a floor value \p f to a field \p var. Any value lower than
/// the floor is set to the floor.
///
Expand All @@ -677,7 +687,36 @@ inline T floor(const T& var, BoutReal f, const std::string& rgn = "RGN_ALL") {
result[d] = f;
}
}

if constexpr (std::is_same_v<T, Field3DParallel>) {
if (var.hasParallelSlices()) {
for (size_t i = 0; i < result.numberParallelSlices(); ++i) {
if (result.yup(i).isAllocated()) {
BOUT_FOR(d, result.yup(i).getRegion(rgn)) {
if (result.yup(i)[d] < f) {
result.yup(i)[d] = f;
}
}
} else {
if (result.isFci()) {
throw BoutException("Expected parallel slice to be allocated");
}
}
if (result.ydown(i).isAllocated()) {
BOUT_FOR(d, result.ydown(i).getRegion(rgn)) {
if (result.ydown(i)[d] < f) {
result.ydown(i)[d] = f;
}
}
} else {
if (result.isFci()) {
throw BoutException("Expected parallel slice to be allocated");
}
}
}
}
} else {
result.clearParallelSlices();
}
return result;
}

Expand Down
Loading
Loading