Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
aa5ea58
Add `format_as` methods delegating to existing `toString` methods
tomchapman Sep 24, 2026
2f82759
Handle 's' format specification in fmt::formatter<SpecificInd<N>>
tomchapman Sep 24, 2026
f5ec5e0
No longer need to call `toString()` on CELL_LOC types
tomchapman Sep 24, 2026
163fda2
Move fmt::formatter<SpecificInd<N>> to same file as SpecificInd is de…
tomchapman Sep 24, 2026
670310a
Refactor `fmt::formatter<SpecificInd<N>>::format()` method
tomchapman Sep 24, 2026
9b1ce11
Prefer const
tomchapman Sep 24, 2026
4f5987c
Directly include fmt/base.h header
tomchapman Sep 24, 2026
d7b458e
Redundant 'typename' keyword
tomchapman Sep 24, 2026
5a6048b
Clang-Tidy: add parentheses to explicitly specify the order of operat…
tomchapman Sep 24, 2026
753fd1f
Clang-Tidy: Redundant parentheses around expression
tomchapman Sep 24, 2026
05cc34f
Clang-Tidy: add parentheses to explicitly specify the order of operat…
tomchapman Sep 24, 2026
40ad179
Clang-Tidy: Function 'createRegionIndices' has inline specifier but i…
tomchapman Sep 24, 2026
f15068e
Add custom formatter for DirectionTypes
tomchapman Sep 24, 2026
8055c18
Restore #include utils.hxx to field.hxx
tomchapman Sep 24, 2026
9a72d7f
Move `std::string toString(const DirectionTypes& dir)` from utils.hxx…
tomchapman Sep 24, 2026
762b618
Add `format_as()` wrapper for BoundaryParType
tomchapman Sep 25, 2026
2fab339
Remove call to `toString()` in BoutException arguments
tomchapman Sep 26, 2026
aca326b
Redundant 'typename' keyword
tomchapman Sep 26, 2026
8e2de4f
Clang-Tidy: No header providing "BoutException" is directly included
tomchapman Sep 26, 2026
0538320
Clang-Tidy: No header providing "std::set" is directly included
tomchapman Sep 26, 2026
c5bd564
Remove redundant `const` qualifier
tomchapman Sep 26, 2026
ce45224
Clang-Tidy: Pointer parameter 'localmesh' can be pointer to const
tomchapman Sep 26, 2026
b3719a6
Parameter can be made const
tomchapman Sep 26, 2026
75a6a28
Apply clang-format
tomchapman Sep 28, 2026
badede6
Remove more to `toString()` calls in BoutException arguments
tomchapman Sep 28, 2026
c9db23a
Apply clang-format
tomchapman Sep 29, 2026
0e90ad5
Add `format_as()` wrapper for ConductionMethod type
tomchapman Sep 29, 2026
48363a0
Make `format_as()` parameters const (ref)
tomchapman Sep 29, 2026
7b77b11
Apply clang-format
tomchapman Sep 29, 2026
d9b4d51
Remove unused #include "bout/utils.hxx"
tomc271 Sep 29, 2026
8046c2f
Restore comments in `fmt::formatter<SpecificInd<N>>`
tomchapman Sep 29, 2026
2e41f70
Move `toString()` and `format_as()` methods for `DirectionTypes` belo…
tomchapman Sep 29, 2026
f0239f6
Revert `s` option for presentation format
tomchapman Sep 29, 2026
d5d1027
Remove unused #include "bout/utils.hxx"
tomchapman Sep 29, 2026
8e5b27d
Move definitions and specializations of `checkFinite()` and `checkPos…
tomchapman Sep 29, 2026
ad83aa6
Directly include headers
tomchapman Sep 30, 2026
641e54b
Revert "Move fmt::formatter<SpecificInd<N>> to same file as SpecificI…
tomchapman Sep 30, 2026
ff8a337
Remove unused #include directives
tomchapman Sep 30, 2026
4952b23
Apply clang-format
tomchapman Sep 30, 2026
5c7d768
Don't include region.hxx in field.cxx
tomchapman Sep 30, 2026
dd6b000
Include output_bout_types.hxx in operatorstencil.hxx
tomchapman Sep 30, 2026
6033b79
Reset to original function order
tomchapman Sep 30, 2026
c29857c
No need to call `toString()` on a string
tomchapman Oct 6, 2026
d279cf5
Apply clang-format
tomchapman Oct 12, 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
11 changes: 11 additions & 0 deletions include/bout/bout_types.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ constexpr CELL_LOC CELL_VSHIFT = CELL_LOC::vshift;

std::string toString(CELL_LOC location);
CELL_LOC CELL_LOCFromString(const std::string& location_string);
inline std::string format_as(const CELL_LOC& loc) { return toString(loc); }

/// Differential methods. Both central and upwind
enum class DIFF_METHOD { deflt, u1, u2, c2, w2, w3, c4, u3, fft, split, s2 };
Expand All @@ -67,6 +68,7 @@ constexpr DIFF_METHOD DIFF_SPLIT = DIFF_METHOD::split;
constexpr DIFF_METHOD DIFF_S2 = DIFF_METHOD::s2;

std::string toString(DIFF_METHOD location);
inline std::string format_as(const DIFF_METHOD& method) { return toString(method); }

/// Specify grid region for looping
enum class REGION { all, nobndry, nox, noy, noz };
Expand All @@ -77,6 +79,7 @@ constexpr REGION RGN_NOY = REGION::noy;
constexpr REGION RGN_NOZ = REGION::noz;

std::string toString(REGION region);
inline std::string format_as(const REGION& region) { return toString(region); }

/// To identify particular directions (in index space):
/// - X, Y, Z are the coordinate directions
Expand All @@ -88,6 +91,7 @@ std::string toString(REGION region);
enum class DIRECTION { X, Y, Z, YAligned, YOrthogonal };

std::string toString(DIRECTION direction);
inline std::string format_as(const DIRECTION& dir) { return toString(dir); }

/// Identify kind of a field's y-direction
/// - Standard is the default for the Mesh/Coordinates/ParallelTransform
Expand All @@ -97,6 +101,7 @@ enum class YDirectionType { Standard, Aligned };

std::string toString(YDirectionType d);
YDirectionType YDirectionTypeFromString(const std::string& y_direction_string);
inline std::string format_as(const YDirectionType& d) { return toString(d); }

/// Identify kind of a field's z-direction
/// - Standard is the default
Expand All @@ -107,13 +112,17 @@ enum class ZDirectionType { Standard, Average };

std::string toString(ZDirectionType d);
ZDirectionType ZDirectionTypeFromString(const std::string& z_direction_string);
inline std::string format_as(const ZDirectionType& d) { return toString(d); }

/// Container for direction types
struct DirectionTypes {
YDirectionType y;
ZDirectionType z;
};

std::string toString(const DirectionTypes& dir);
inline std::string format_as(const DirectionTypes& dir) { return toString(dir); }

/// Check whether direction types are compatible, so two fields with attributes
/// d1 and d2 respectively can be added, subtracted, etc.
bool areDirectionsCompatible(const DirectionTypes& d1, const DirectionTypes& d2);
Expand All @@ -124,11 +133,13 @@ void swap(const DirectionTypes& first, const DirectionTypes& second);
enum class STAGGER { None, C2L, L2C };

std::string toString(STAGGER stagger);
inline std::string format_as(const STAGGER& stagger) { return toString(stagger); }

/// To identify types of derivative method combinations
enum class DERIV { Standard, StandardSecond, StandardFourth, Upwind, Flux };

std::string toString(DERIV deriv);
inline std::string format_as(const DERIV& deriv) { return toString(deriv); }

// A small struct that can be used to wrap a specific enum value, giving
// it a unique type that can be passed as a valid type to templates and
Expand Down
22 changes: 11 additions & 11 deletions include/bout/deriv_store.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -135,30 +135,30 @@ struct DerivativeStore {
if (standard.count(key) != 0) {
throw BoutException("Trying to override standard derivative : "
"direction {:s}, stagger {:s}, key {:s}",
Comment thread
ZedThree marked this conversation as resolved.
toString(direction), toString(stagger), methodName);
direction, stagger, methodName);
}
standard[key] = func;
break;
case (DERIV::StandardSecond):
if (standardSecond.count(key) != 0) {
throw BoutException("Trying to override standardSecond derivative : "
"direction {:s}, stagger {:s}, key {:s}",
toString(direction), toString(stagger), methodName);
direction, stagger, methodName);
}
standardSecond[key] = func;
break;
case (DERIV::StandardFourth):
if (standardFourth.count(key) != 0) {
throw BoutException("Trying to override standardFourth derivative : "
"direction {:s}, stagger {:s}, key {:s}",
toString(direction), toString(stagger), methodName);
direction, stagger, methodName);
}
standardFourth[key] = func;
break;
default:
throw BoutException("Invalid function signature in registerDerivative : Function "
"signature 'standard' but derivative type {:s} passed",
toString(derivType));
derivType);
};

// Register this method name in lookup of known methods
Expand All @@ -177,22 +177,22 @@ struct DerivativeStore {
if (upwind.count(key) != 0) {
throw BoutException("Trying to override upwind derivative : "
"direction {:s}, stagger {:s}, key {:s}",
toString(direction), toString(stagger), methodName);
direction, stagger, methodName);
}
upwind[key] = func;
break;
case (DERIV::Flux):
if (flux.count(key) != 0) {
throw BoutException("Trying to override flux derivative : "
"direction {:s}, stagger {:s}, key {:s}",
toString(direction), toString(stagger), methodName);
direction, stagger, methodName);
}
flux[key] = func;
break;
default:
throw BoutException("Invalid function signature in registerDerivative : Function "
"signature 'upwind/flux' but derivative type {:s} passed",
toString(derivType));
derivType);
};

// Register this method name in lookup of known methods
Expand Down Expand Up @@ -239,7 +239,7 @@ struct DerivativeStore {
} else {
throw BoutException("getStandardDerivative only works for derivType in {{Standard, "
"StandardSecond, StandardFourth}} but receieved {:s}",
toString(derivType));
derivType);
};

const auto resultOfFind = theMap->find(key);
Expand All @@ -249,7 +249,7 @@ struct DerivativeStore {

throw BoutException("Couldn't find requested method {:s} in map for standard "
"derivative of type {:s}.",
getMethodName(realName, direction, stagger), toString(derivType));
getMethodName(realName, direction, stagger), derivType);
};

standardFunc getStandard2ndDerivative(std::string name, DIRECTION direction,
Expand Down Expand Up @@ -282,7 +282,7 @@ struct DerivativeStore {
throw BoutException(
"getFlowDerivative only works for derivType in {{Upwind, Flux}} "
"but received {:s}",
toString(derivType));
derivType);
};

const auto resultOfFind = theMap->find(key);
Expand All @@ -292,7 +292,7 @@ struct DerivativeStore {

throw BoutException(
"Couldn't find requested method {:s} in map for standard flow of type {:s}.",
getMethodName(realName, direction, stagger), toString(derivType));
getMethodName(realName, direction, stagger), derivType);
}

upwindFunc getUpwindDerivative(std::string name, DIRECTION direction,
Expand Down
4 changes: 4 additions & 0 deletions include/bout/difops.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ Field3D Div_par_K_Grad_par(const Field3DParallel& kY, const Field3DParallel& f,
/// different results when coefficients or cell sizes vary strongly.
BOUT_ENUM_CLASS_NS(bout, ConductionMethod, Original, ProductJK, Harmonic);

namespace bout {
inline std::string format_as(const ConductionMethod& method) { return toString(method); }
} // namespace bout
Comment on lines +222 to +224

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.

If we add this to the BOUT_ENUM_CLASS{,_NS} macros, then we don't need to add it manually


/// Version with energy flow diagnostic
/// For FCI fields, `flow_ylow` is currently returned as zero.
Field3D
Expand Down
122 changes: 49 additions & 73 deletions include/bout/field.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -160,53 +160,53 @@ inline bool areFieldsCompatible(const Field& field1, const Field& field2) {
}

#if CHECKLEVEL >= 1
#define ASSERT1_FIELDS_COMPATIBLE(field1, field2) \
if ((field1).getLocation() != (field2).getLocation()) { \
throw BoutException("Error in {:s}:{:d}\nFields at different position:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #field1, toString((field1).getLocation()), \
#field2, toString((field2).getLocation())); \
} \
if ((field1).getCoordinates() != (field2).getCoordinates()) { \
throw BoutException("Error in {:s}:{:d}\nFields have different coordinates:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #field1, \
static_cast<void*>((field1).getCoordinates()), #field2, \
static_cast<void*>((field2).getCoordinates())); \
} \
if ((field1).getMesh() != (field2).getMesh()) { \
throw BoutException("Error in {:s}:{:d}\nFields are on different Meshes:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #field1, \
static_cast<void*>((field1).getMesh()), #field2, \
static_cast<void*>((field2).getMesh())); \
} \
if (!areDirectionsCompatible((field1).getDirections(), (field2).getDirections())) { \
throw BoutException("Error in {:s}:{:d}\nFields at different directions:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #field1, toString((field1).getDirections()), \
#field2, toString((field2).getDirections())); \
#define ASSERT1_FIELDS_COMPATIBLE(field1, field2) \
if ((field1).getLocation() != (field2).getLocation()) { \
throw BoutException("Error in {:s}:{:d}\nFields at different position:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #field1, (field1).getLocation(), #field2, \
(field2).getLocation()); \
} \
if ((field1).getCoordinates() != (field2).getCoordinates()) { \
throw BoutException("Error in {:s}:{:d}\nFields have different coordinates:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #field1, \
static_cast<void*>((field1).getCoordinates()), #field2, \
static_cast<void*>((field2).getCoordinates())); \
} \
if ((field1).getMesh() != (field2).getMesh()) { \
throw BoutException("Error in {:s}:{:d}\nFields are on different Meshes:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #field1, \
static_cast<void*>((field1).getMesh()), #field2, \
static_cast<void*>((field2).getMesh())); \
} \
if (!areDirectionsCompatible((field1).getDirections(), (field2).getDirections())) { \
throw BoutException("Error in {:s}:{:d}\nFields at different directions:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #field1, (field1).getDirections(), #field2, \
(field2).getDirections()); \
}

#define ASSERT1_EXPR_COMPATIBLE(expr1, expr2) \
if ((expr1).getLocation() != (expr2).getLocation()) { \
throw BoutException("Error in {:s}:{:d}\nFields at different position:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #expr1, toString((expr1).getLocation()), \
#expr2, toString((expr2).getLocation())); \
} \
if ((expr1).getMesh() != (expr2).getMesh()) { \
throw BoutException("Error in {:s}:{:d}\nFields are on different Meshes:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #expr1, \
static_cast<void*>((expr1).getMesh()), #expr2, \
static_cast<void*>((expr2).getMesh())); \
} \
if (!areDirectionsCompatible((expr1).getDirections(), (expr2).getDirections())) { \
throw BoutException("Error in {:s}:{:d}\nFields at different directions:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #expr1, toString((expr1).getDirections()), \
#expr2, toString((expr2).getDirections())); \
#define ASSERT1_EXPR_COMPATIBLE(expr1, expr2) \
if ((expr1).getLocation() != (expr2).getLocation()) { \
throw BoutException("Error in {:s}:{:d}\nFields at different position:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #expr1, (expr1).getLocation(), #expr2, \
(expr2).getLocation()); \
} \
if ((expr1).getMesh() != (expr2).getMesh()) { \
throw BoutException("Error in {:s}:{:d}\nFields are on different Meshes:" \
"`{:s}` at {:p}, `{:s}` at {:p}", \
__FILE__, __LINE__, #expr1, \
static_cast<void*>((expr1).getMesh()), #expr2, \
static_cast<void*>((expr2).getMesh())); \
} \
if (!areDirectionsCompatible((expr1).getDirections(), (expr2).getDirections())) { \
throw BoutException("Error in {:s}:{:d}\nFields at different directions:" \
"`{:s}` at {:s}, `{:s}` at {:s}", \
__FILE__, __LINE__, #expr1, (expr1).getDirections(), #expr2, \
(expr2).getDirections()); \
}

#else
Expand Down Expand Up @@ -291,19 +291,8 @@ namespace bout {
/// used during initialization, where we always want to check inputs, even for optimized
/// builds.
template <typename T>
inline void checkFinite(const T& f, const std::string& name = "field",
const std::string& rgn = "RGN_ALL") {

if (!f.isAllocated()) {
throw BoutException("{:s} is not allocated", name);
}

BOUT_FOR_SERIAL(i, f.getRegion(rgn)) {
if (!std::isfinite(f[i])) {
throw BoutException("{:s} is not finite at {:s}", name, toString(i));
}
}
}
void checkFinite(const T& f, const std::string& name = "field",
const std::string& rgn = "RGN_ALL");

/// Check if all values of a field \p var are positive. Loops over all points including
/// the boundaries by default (can be changed using the \p rgn argument)
Expand All @@ -314,21 +303,8 @@ inline void checkFinite(const T& f, const std::string& name = "field",
/// be used during initialization, where we always want to check inputs, even for
/// optimized builds.
template <typename T>
inline void checkPositive(const T& f, const std::string& name = "field",
const std::string& rgn = "RGN_ALL") {

if (!f.isAllocated()) {
throw BoutException("{:s} is not allocated", name);
}

BOUT_FOR_SERIAL(i, f.getRegion(rgn)) {
if (f[i] <= 0.) {
throw BoutException("{:s} ({:s} {:s}) is {:e} (not positive) at {:s}", name,
toString(f.getLocation()), toString(f.getDirections()), f[i],
toString(i));
}
}
}
void checkPositive(const T& f, const std::string& name = "field",
const std::string& rgn = "RGN_ALL");
} // namespace bout

//////////////// NON-MEMBER FUNCTIONS //////////////////
Expand Down
2 changes: 1 addition & 1 deletion include/bout/interpolation.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ interp_to(const T& var, CELL_LOC loc, const std::string& region = "RGN_ALL") {
// This should never happen
throw BoutException("Unsupported direction of interpolation\n"
" - don't know how to interpolate to {:s}",
toString(loc));
loc);
}
};

Expand Down
2 changes: 2 additions & 0 deletions include/bout/mesh.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public:
BOUT_ENUM_CLASS(BoundaryParType, all, xin, xout, fwd, bwd, xin_fwd, xout_fwd, xin_bwd,
xout_bwd, SIZE);

inline auto format_as(const BoundaryParType& type) { return toString(type); }

template <class DerivedType>
using RegisterMesh = MeshFactory::RegisterInFactory<DerivedType>;

Expand Down
Loading
Loading