Skip to content

Legacy boundary conditions - #3420

Open
malamast wants to merge 5 commits into
nextfrom
legacy-boundary-conditions
Open

Legacy boundary conditions#3420
malamast wants to merge 5 commits into
nextfrom
legacy-boundary-conditions

Conversation

@malamast

@malamast malamast commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Added a legacy implementation of 1st order Dirichlet and Neumann BCs.

  • This is what we used to do in Bout++ version 3.
  • The default BC remain unchanged.
  • Higher order extrapolation can be unstable sometimes when using C4 so I added back the 1st order BC.
  • You can use them in the input file by setting e.g. bndry_all = dirichlet_o1.
  • Implementation for staggered grids is not done.

malamast added 3 commits July 7, 2026 16:39
…et and Neumann BCs.

- This is what we used to do in Bout++ version 3.

- Higher order extrapolation can be unstable sometimes so I added back the 1st order BC. You can use thm in the input file by setting e.g. dirichlet_o1.

- Implementation for staggered grids is not done.
… the rest of the BC code.

-This was a later change to the BCs
@malamast
malamast requested a review from ZedThree July 8, 2026 00:30
@malamast malamast added feature backport candidiate Does not break backward compatibility, so can be back-ported to v4.4 labels Jul 8, 2026

@github-actions github-actions Bot left a comment

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.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 54. Check the log or trigger a new build to see more.

class BoundaryDirichlet_O1 : public BoundaryOp {
public:
BoundaryDirichlet_O1() : gen(nullptr) {}
BoundaryDirichlet_O1(BoundaryRegion* region, std::shared_ptr<FieldGenerator> g)

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: no header providing "FieldGenerator" is directly included [misc-include-cleaner]

include/bout/boundary_standard.hxx:7:

- #include "bout/unused.hxx"
+ #include "bout/sys/expressionparser.hxx"
+ #include "bout/unused.hxx"

class BoundaryDirichlet_O1 : public BoundaryOp {
public:
BoundaryDirichlet_O1() : gen(nullptr) {}
BoundaryDirichlet_O1(BoundaryRegion* region, std::shared_ptr<FieldGenerator> g)

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: no header providing "std::shared_ptr" is directly included [misc-include-cleaner]

include/bout/boundary_standard.hxx:10:

- #include <utility>
+ #include <memory>
+ #include <utility>


BoundaryFactory::BoundaryFactory() {
add(new BoundaryDirichlet(), "dirichlet");
add(new BoundaryDirichlet(), "dirichlet"); // Default

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: initializing non-owner argument of type 'BoundaryOp *' with a newly created 'gsl::owner<>' [cppcoreguidelines-owning-memory]

  add(new BoundaryDirichlet(), "dirichlet");       // Default
      ^

BoundaryFactory::BoundaryFactory() {
add(new BoundaryDirichlet(), "dirichlet");
add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3

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: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
          ^
Additional context

src/mesh/boundary_factory.cxx:73: Assuming the condition is true

  if (instance == nullptr) {
      ^

src/mesh/boundary_factory.cxx:73: Taking true branch

  if (instance == nullptr) {
  ^

src/mesh/boundary_factory.cxx:75: Calling default constructor for 'BoundaryFactory'

    instance = new BoundaryFactory();
                   ^

src/mesh/boundary_factory.cxx:22: Memory is allocated

  add(new BoundaryDirichlet(), "dirichlet");       // Default
      ^

src/mesh/boundary_factory.cxx:23: Potential memory leak

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
          ^

BoundaryFactory::BoundaryFactory() {
add(new BoundaryDirichlet(), "dirichlet");
add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3

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: initializing non-owner argument of type 'BoundaryOp *' with a newly created 'gsl::owner<>' [cppcoreguidelines-owning-memory]

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
      ^

return new BoundaryDirichlet_O1(region, newgen);
}

void BoundaryDirichlet_O1::apply(Field2D& f) { BoundaryDirichlet_O1::apply(f, 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: no header providing "Field2D" is directly included [misc-include-cleaner]

src/mesh/boundary_standard.cxx:0:

- #include <bout/boundary_standard.hxx>
+ #include "bout/field2d.hxx"
+ #include <bout/boundary_standard.hxx>


void BoundaryDirichlet_O1::apply(Field2D& f) { BoundaryDirichlet_O1::apply(f, 0.); }

void BoundaryDirichlet_O1::apply(Field2D& f, BoutReal t) {

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: no header providing "BoutReal" is directly included [misc-include-cleaner]

src/mesh/boundary_standard.cxx:0:

- #include <bout/boundary_standard.hxx>
+ #include "bout/bout_types.hxx"
+ #include <bout/boundary_standard.hxx>

// Set (at 1st order) the value at the grid cell to the guard cells.

Mesh* mesh = bndry->localmesh;
ASSERT1(mesh == f.getMesh());

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: no header providing "ASSERT1" is directly included [misc-include-cleaner]

src/mesh/boundary_standard.cxx:0:

- #include <bout/boundary_standard.hxx>
+ #include "bout/assert.hxx"
+ #include <bout/boundary_standard.hxx>


// Check for staggered grids

CELL_LOC loc = f.getLocation();

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: no header providing "CELL_LOC" is directly included [misc-include-cleaner]

  CELL_LOC loc = f.getLocation();
  ^


// Check for staggered grids

CELL_LOC loc = f.getLocation();

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: variable 'loc' of type 'CELL_LOC' can be declared 'const' [misc-const-correctness]

Suggested change
CELL_LOC loc = f.getLocation();
CELL_LOC const loc = f.getLocation();

@dschwoerer

dschwoerer commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
* Implementation for staggered grids is not done.

Could you add an assert?

Also, please fix the clang-tidy and clang-format issues.

@malamast

malamast commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author
* Implementation for staggered grids is not done.

Could you add an assert?

Also, please fix the clang-tidy and clang-format issues.

I have this line here:

throw BoutException("dirichlet_o1 BC is not implementated for staggered grids.");

throw BoutException("neumann_o1 BC is not implementated for staggered grids.");
That throws an Exception if this BC is used with staggered grids. Does this BoutException work as an error message or a an assert statement?

Also, I used: git clang-format origin/next for the formatting. Is there another command I sue use for clang-tidy?

@github-actions github-actions Bot left a comment

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.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 39. Check the log or trigger a new build to see more.

add(new BoundaryDirichlet(), "dirichlet");
add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"
add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3

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: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
          ^
Additional context

src/mesh/boundary_factory.cxx:74: Assuming the condition is true

  if (instance == nullptr) {
      ^

src/mesh/boundary_factory.cxx:74: Taking true branch

  if (instance == nullptr) {
  ^

src/mesh/boundary_factory.cxx:76: Calling default constructor for 'BoundaryFactory'

    instance = new BoundaryFactory();
                   ^

src/mesh/boundary_factory.cxx:23: Memory is allocated

  add(new BoundaryDirichlet(), "dirichlet");       // Default
      ^

src/mesh/boundary_factory.cxx:24: Potential memory leak

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
          ^

add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"
add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"

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: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]

  add(new BoundaryDirichlet(), "dirichlet_o2");    // Synonym for "dirichlet"
          ^
Additional context

src/mesh/boundary_factory.cxx:74: Assuming the condition is true

  if (instance == nullptr) {
      ^

src/mesh/boundary_factory.cxx:74: Taking true branch

  if (instance == nullptr) {
  ^

src/mesh/boundary_factory.cxx:76: Calling default constructor for 'BoundaryFactory'

    instance = new BoundaryFactory();
                   ^

src/mesh/boundary_factory.cxx:24: Memory is allocated

  add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
      ^

src/mesh/boundary_factory.cxx:25: Potential memory leak

  add(new BoundaryDirichlet(), "dirichlet_o2");    // Synonym for "dirichlet"
          ^

add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"
add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"

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: initializing non-owner argument of type 'BoundaryOp *' with a newly created 'gsl::owner<>' [cppcoreguidelines-owning-memory]

  add(new BoundaryDirichlet(), "dirichlet_o2");    // Synonym for "dirichlet"
      ^

add(new BoundaryDirichlet(), "dirichlet"); // Default
add(new BoundaryDirichlet_O1(), "dirichlet_o1"); // Old implementation in v3
add(new BoundaryDirichlet(), "dirichlet_o2"); // Synonym for "dirichlet"
add(new BoundaryDirichlet_O3(), "dirichlet_o3");

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: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]

  add(new BoundaryDirichlet_O3(), "dirichlet_o3");
          ^
Additional context

src/mesh/boundary_factory.cxx:74: Assuming the condition is true

  if (instance == nullptr) {
      ^

src/mesh/boundary_factory.cxx:74: Taking true branch

  if (instance == nullptr) {
  ^

src/mesh/boundary_factory.cxx:76: Calling default constructor for 'BoundaryFactory'

    instance = new BoundaryFactory();
                   ^

src/mesh/boundary_factory.cxx:25: Memory is allocated

  add(new BoundaryDirichlet(), "dirichlet_o2");    // Synonym for "dirichlet"
      ^

src/mesh/boundary_factory.cxx:26: Potential memory leak

  add(new BoundaryDirichlet_O3(), "dirichlet_o3");
          ^

add(new BoundaryNeumann(), "neumann");
add(new BoundaryNeumann(), "neumann_O2"); // Synonym for "neumann"

add(new BoundaryNeumann(), "neumann"); // Default

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: Potential memory leak [clang-analyzer-cplusplus.NewDeleteLeaks]

  add(new BoundaryNeumann(), "neumann");       // Default
          ^
Additional context

src/mesh/boundary_factory.cxx:74: Assuming the condition is true

  if (instance == nullptr) {
      ^

src/mesh/boundary_factory.cxx:74: Taking true branch

  if (instance == nullptr) {
  ^

src/mesh/boundary_factory.cxx:76: Calling default constructor for 'BoundaryFactory'

    instance = new BoundaryFactory();
                   ^

src/mesh/boundary_factory.cxx:28: Memory is allocated

  add(new BoundaryDirichlet_4thOrder(), "dirichlet_4thorder");
      ^

src/mesh/boundary_factory.cxx:30: Potential memory leak

  add(new BoundaryNeumann(), "neumann");       // Default
          ^

for (int i = 1; i < bndry->width; i++) {
// Set any other guard cells using the values on the cells
int xi = bndry->x + i * bndry->bx;
int yi = bndry->y + i * bndry->by;

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: variable 'yi' of type 'int' can be declared 'const' [misc-const-correctness]

        int yi = bndry->y + i * bndry->by;
        ^

this fix will not be applied because it overlaps with another fix

}
}
}
}

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: do not use 'else' after 'throw' [readability-else-after-return]

Suggested change
}
} // Standard (non-staggered) case
for (; !bndry->isDone(); bndry->next1d()) {
for (int zk = mesh->zstart; zk <= mesh->zend; zk++) {
if (fg) {
val = fg->generate(Context(bndry, zk, loc, t, mesh));
}
f(bndry->x, bndry->y, zk) = val;
}
// This is not very efficient. Both boundary cells can be treated in one loop.
for (int i = 1; i < bndry->width; i++) {
// Set any other guard cells using the values on the cells
int xi = bndry->x + i * bndry->bx;
int yi = bndry->y + i * bndry->by;
for (int zk = mesh->zstart; zk <= mesh->zend; zk++) {
if (fg) {
val = fg->generate(Context(bndry, zk, loc, t, mesh));
}
f(xi, yi, zk) = val;
}
}
}

}

void BoundaryDirichlet_O1::apply_ddt(Field3D& f) {
Mesh* mesh = bndry->localmesh;

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: pointee of variable 'mesh' of type 'Mesh *' can be declared 'const' [misc-const-correctness]

Suggested change
Mesh* mesh = bndry->localmesh;
Mesh const* mesh = bndry->localmesh;

// First argument should be an expression
newgen = FieldFactory::get()->parse(args.front());
}
return new BoundaryNeumann_O1(region, newgen);

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: returning a newly created resource of type 'BoundaryOp *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>' [cppcoreguidelines-owning-memory]

    return new BoundaryNeumann_O1(region, newgen);
    ^


// Check for staggered grids

CELL_LOC loc = f.getLocation();

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: variable 'loc' of type 'CELL_LOC' can be declared 'const' [misc-const-correctness]

Suggested change
CELL_LOC loc = f.getLocation();
CELL_LOC const loc = f.getLocation();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport candidiate Does not break backward compatibility, so can be back-ported to v4.4 feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants