Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ca7f727
Remove unused `Context` constructor
ZedThree Dec 1, 2025
f9c616b
Add cell indices to `generator::Context`
ZedThree Dec 2, 2025
4034481
Add ability to use variables from grid files in input expressions
ZedThree Dec 2, 2025
aa963d6
tests: Only remove temp files if test passes
ZedThree Dec 2, 2025
4985b3c
Enable reading `Field2D`s as well as `Field3D`s for expressions
ZedThree Dec 2, 2025
47b852f
Refactor reading grid variables for input expressions
ZedThree Dec 2, 2025
dc80694
Apply clang-format changes
ZedThree Dec 2, 2025
259eff9
FieldFactory: Use fieldmesh not localmesh
bendudson Mar 26, 2026
afae6cd
GridVariable: Load grid variables lazily
bendudson Mar 26, 2026
ae7b02c
BoutException: Use forwarding
bendudson Mar 27, 2026
4ab3578
FieldData: Don't getCoordinates in constructor
bendudson Mar 27, 2026
cd31e42
GridVariable: Check mesh->get return
bendudson Mar 27, 2026
daced86
Merge branch 'next' into field-variable-expression-next
bendudson Mar 27, 2026
854c379
FieldGenerators: Fixes and tidying
bendudson Mar 27, 2026
7df04a7
GridVariable unit tests: Fix unit test
bendudson Mar 28, 2026
8ebc0a0
Field2D/3D: Defer sizing until allocation
bendudson Mar 28, 2026
d3b0ebe
Miscellaneous tidying
bendudson Mar 28, 2026
1bfd9ad
Field2D/3D: Partly revert 8ebc0a0
bendudson Mar 28, 2026
3f15ddb
FieldFactory: Don't test values in Y boundary
bendudson Mar 28, 2026
69ca85d
Clang formatting
bendudson Mar 28, 2026
91854fd
Merge pull request #3343 from boutproject/field-variable-expression-next
bendudson Mar 28, 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
16 changes: 9 additions & 7 deletions examples/elm-pb/elm_pb.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,8 @@ class ELMpb : public PhysicsModel {
// Only update if simulation time has advanced
// Uses an exponential decay of the weighting of the value in the boundary
// so that the solution is well behaved for arbitrary steps
BoutReal const weight = exp(-(t - phi_boundary_last_update) / phi_boundary_timescale);
const BoutReal weight =
exp(-(t - phi_boundary_last_update) / phi_boundary_timescale);
phi_boundary_last_update = t;

if (mesh->firstX()) {
Expand Down Expand Up @@ -1385,11 +1386,11 @@ class ELMpb : public PhysicsModel {
}

// Old value of phi at boundary. Note: this is constant in Z
BoutReal const oldvalue =
const BoutReal oldvalue =
0.5 * (phi(mesh->xstart - 1, j, 0) + phi(mesh->xstart, j, 0));

// New value of phi at boundary, relaxing towards phivalue
BoutReal const newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = (weight * oldvalue) + (1. - weight) * phivalue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = weight * oldvalue + ((1. - weight) * phivalue);


// Set phi at the boundary to this value
for (int k = mesh->zstart; k <= mesh->zend; k++) {
Expand All @@ -1412,7 +1413,7 @@ class ELMpb : public PhysicsModel {
0.5 * (phi(mesh->xend + 1, j, 0) + phi(mesh->xend, j, 0));

// New value of phi at boundary, relaxing towards phivalue
BoutReal const newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = (weight * oldvalue) + (1. - weight) * phivalue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
const BoutReal newvalue = weight * oldvalue + (1. - weight) * phivalue;
const BoutReal newvalue = weight * oldvalue + ((1. - weight) * phivalue);


// Set phi at the boundary to this value
for (int k = mesh->zstart; k <= mesh->zend; k++) {
Expand Down Expand Up @@ -1625,7 +1626,7 @@ class ELMpb : public PhysicsModel {
for (int jz = 0; jz < mesh->LocalNz; jz++) {

// Zero-gradient potential
BoutReal const phisheath = phi_fa(r.ind, mesh->ystart, jz);
const BoutReal phisheath = phi_fa(r.ind, mesh->ystart, jz);

BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath;

Expand All @@ -1646,7 +1647,7 @@ class ELMpb : public PhysicsModel {
for (int jz = 0; jz < mesh->LocalNz; jz++) {

// Zero-gradient potential
BoutReal const phisheath = phi_fa(r.ind, mesh->yend, jz);
const BoutReal phisheath = phi_fa(r.ind, mesh->yend, jz);

BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath;

Expand Down Expand Up @@ -2068,7 +2069,8 @@ class ELMpb : public PhysicsModel {
ddt(P).applyBoundary("neumann");

Field3D U1 = ddt(U);
U1 += (gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(ddt(P));
U1 +=
(gamma * B0 * B0) * Grad_par(Jrhs, CELL_CENTRE) + (gamma * b0xcv) * Grad(ddt(P));

// Second matrix, solving Alfven wave dynamics
static std::unique_ptr<InvertPar> invU{nullptr};
Expand Down
13 changes: 8 additions & 5 deletions include/bout/field2d.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* \brief Definition of 2D scalar field class
*
**************************************************************************
* Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu
* Copyright 2010 - 2026 BOUT++ developers
*
* Contact: Ben Dudson, bd512@york.ac.uk
* Contact: Ben Dudson, dudson2@llnl.gov
*
* This file is part of BOUT++.
*
Expand All @@ -33,13 +33,16 @@ class Field2D;
#define BOUT_FIELD2D_H

#include "bout/array.hxx"
#include "bout/build_config.hxx"
#include "bout/bout_types.hxx"
#include "bout/build_defines.hxx"
#include "bout/field.hxx"
#include "bout/field_data.hxx"
#include "bout/fieldperp.hxx"
#include "bout/region.hxx"

#include <cstddef>
#include <iostream>
#include <string>

#if BOUT_HAS_RAJA
#include "RAJA/RAJA.hpp" // using RAJA lib
Expand Down Expand Up @@ -206,7 +209,7 @@ public:
}
#endif

return data[jx * ny + jy];
return data[(jx * ny) + jy];
}
inline const BoutReal& operator()(int jx, int jy) const {
#if CHECK > 2 && !BOUT_HAS_CUDA
Expand All @@ -220,7 +223,7 @@ public:
}
#endif

return data[jx * ny + jy];
return data[(jx * ny) + jy];
}

/*!
Expand Down
5 changes: 3 additions & 2 deletions include/bout/field3d.hxx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**************************************************************************
* Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu
* Copyright 2010 - 2026 BOUT++ contributors
*
* Contact: Ben Dudson, bd512@york.ac.uk
* Contact: Ben Dudson, dudson2@llnl.gov
*
* This file is part of BOUT++.
*
Expand Down Expand Up @@ -33,6 +33,7 @@ class Field3D;
#include "bout/bout_types.hxx"
#include "bout/field.hxx"
#include "bout/field2d.hxx"
#include "bout/field_data.hxx"
#include "bout/fieldperp.hxx"
#include "bout/region.hxx"
#include "bout/traits.hxx"
Expand Down
4 changes: 2 additions & 2 deletions include/bout/invertable_operator.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ public:
: operatorFunction(func), preconditionerFunction(func),
opt(optIn == nullptr ? Options::getRoot()->getSection("invertableOperator")
: optIn),
localmesh(localmeshIn == nullptr ? bout::globals::mesh : localmeshIn), lib(opt){
localmesh(localmeshIn == nullptr ? bout::globals::mesh : localmeshIn), lib(opt) {

};
};

/// Destructor just has to cleanup the PETSc owned objects.
~InvertableOperator() {
Expand Down
2 changes: 1 addition & 1 deletion include/bout/mesh.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ public:
virtual int getLocalZIndexNoBoundaries(int zglobal) const = 0;

/// Size of the mesh on this processor including guard/boundary cells
int LocalNx, LocalNy, LocalNz;
int LocalNx{0}, LocalNy{0}, LocalNz{0};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: member variable 'LocalNx' has public visibility [cppcoreguidelines-non-private-member-variables-in-classes]

  int LocalNx{0}, LocalNy{0}, LocalNz{0};
      ^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: member variable 'LocalNy' has public visibility [cppcoreguidelines-non-private-member-variables-in-classes]

  int LocalNx{0}, LocalNy{0}, LocalNz{0};
                  ^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

warning: member variable 'LocalNz' has public visibility [cppcoreguidelines-non-private-member-variables-in-classes]

  int LocalNx{0}, LocalNy{0}, LocalNz{0};
                              ^


/// Local ranges of data (inclusive), excluding guard cells
int xstart, xend, ystart, yend, zstart, zend;
Expand Down
24 changes: 12 additions & 12 deletions include/bout/options.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -74,27 +74,27 @@ class Options;
* which can be used as a map.
*
* Options options;
*
*
* // Set values
* options["key"] = 1.0;
*
* // Get values. Throws BoutException if not found
* int val = options["key"]; // Sets val to 1
* int val = options["key"]; // Sets val to 1
*
* // Return as specified type. Throws BoutException if not found
* BoutReal var = options["key"].as<BoutReal>();
*
* // A default value can be used if key is not found
* BoutReal value = options["pi"].withDefault(3.14);
*
*
* // Assign value with source label. Throws if already has a value from same source
* options["newkey"].assign(1.0, "some source");
*
* // Force assign a new value
* options["newkey"].force(2.0, "some source");
*
* A legacy interface is also supported:
*
*
* options.set("key", 1.0, "code"); // Sets a key from source "code"
*
* int val;
Expand All @@ -119,9 +119,9 @@ class Options;
*
* Each Options object can also contain any number of sections, which are
* themselves Options objects.
*
*
* Options &section = options["section"];
*
*
* which can be nested:
*
* options["section"]["subsection"]["value"] = 3;
Expand All @@ -134,13 +134,13 @@ class Options;
*
* e.g.
* options->getSection("section")->getSection("subsection")->set("value", 3);
*
*
* Options also know about their parents:
*
* Options &parent = section.parent();
*
*
* or
*
*
* Options *parent = section->getParent();
*
* Root options object
Expand All @@ -150,8 +150,8 @@ class Options;
* there is a global singleton Options object which can be accessed with a static function
*
* Options &root = Options::root();
*
* or
*
* or
*
* Options *root = Options::getRoot();
*
Expand Down Expand Up @@ -193,7 +193,7 @@ public:
/// @param[in] parent Parent object
/// @param[in] sectionName Name of the section, including path from the root
Options(Options* parent_instance, std::string full_name)
: parent_instance(parent_instance), full_name(std::move(full_name)){};
: parent_instance(parent_instance), full_name(std::move(full_name)) {};

/// Initialise with a value
/// These enable Options to be constructed using initializer lists
Expand Down
8 changes: 4 additions & 4 deletions include/bout/output.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ class ConditionalOutput : public Output {
public:
/// @param[in] base The Output object which will be written to if enabled
/// @param[in] enabled Should this be enabled by default?
ConditionalOutput(Output* base, bool enabled = true) : base(base), enabled(enabled){};
ConditionalOutput(Output* base, bool enabled = true) : base(base), enabled(enabled) {};

/// Constuctor taking ConditionalOutput. This allows several layers of conditions
///
/// @param[in] base A ConditionalOutput which will be written to if enabled
///
ConditionalOutput(ConditionalOutput* base) : base(base), enabled(base->enabled){};
ConditionalOutput(ConditionalOutput* base) : base(base), enabled(base->enabled) {};

/// If enabled, writes a string using fmt formatting
/// by calling base->write
Expand Down Expand Up @@ -237,7 +237,7 @@ private:
/// output_debug << "debug message";
/// compile but have no effect if BOUT_USE_OUTPUT_DEBUG is false
template <typename T>
DummyOutput& operator<<(DummyOutput& out, T const& UNUSED(t)) {
DummyOutput& operator<<(DummyOutput& out, const T& UNUSED(t)) {
return out;
}

Expand All @@ -261,7 +261,7 @@ inline ConditionalOutput& operator<<(ConditionalOutput& out, stream_manipulator
}

template <typename T>
ConditionalOutput& operator<<(ConditionalOutput& out, T const& t) {
ConditionalOutput& operator<<(ConditionalOutput& out, const T& t) {
if (out.isEnabled()) {
*out.getBase() << t;
}
Expand Down
Loading
Loading