From 06d7ff52389746f9596a617a1bcda88f8287c05a Mon Sep 17 00:00:00 2001 From: malamast Date: Tue, 7 Jul 2026 16:39:07 -0700 Subject: [PATCH 1/4] boundary_standard: Added a legacy implementation of 1st order Dirichlet 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. --- include/bout/boundary_standard.hxx | 48 ++++++ src/mesh/boundary_factory.cxx | 11 +- src/mesh/boundary_standard.cxx | 261 +++++++++++++++++++++++++++++ 3 files changed, 316 insertions(+), 4 deletions(-) diff --git a/include/bout/boundary_standard.hxx b/include/bout/boundary_standard.hxx index b1116e159f..3cb4b23803 100644 --- a/include/bout/boundary_standard.hxx +++ b/include/bout/boundary_standard.hxx @@ -33,6 +33,30 @@ private: BoutReal val; }; +/// Dirichlet (set to zero) boundary condition +class BoundaryDirichlet_O1 : public BoundaryOp { +public: + BoundaryDirichlet_O1() : gen(nullptr) {} + BoundaryDirichlet_O1(BoundaryRegion* region, std::shared_ptr g) + : BoundaryOp(region), gen(std::move(g)) {} + + using BoundaryOp::clone; + BoundaryOp* clone(BoundaryRegion* region, const std::list& args) override; + + using BoundaryOp::apply; + void apply(Field2D& f) override; + void apply(Field2D& f, BoutReal t) override; + void apply(Field3D& f) override; + void apply(Field3D& f, BoutReal t) override; + + using BoundaryOp::apply_ddt; + void apply_ddt(Field2D& f) override; + void apply_ddt(Field3D& f) override; + +private: + std::shared_ptr gen; // Generator +}; + /// Dirichlet (set to zero) boundary condition class BoundaryDirichlet : public BoundaryOp { public: @@ -163,6 +187,30 @@ public: void apply(Field3D& f) override; }; +/// Neumann (zero-gradient) boundary condition, using 1st order on boundary +class BoundaryNeumann_O1 : public BoundaryOp { +public: + BoundaryNeumann_O1() : gen(nullptr) {} + BoundaryNeumann_O1(BoundaryRegion* region, std::shared_ptr g) + : BoundaryOp(region), gen(std::move(g)) {} + + using BoundaryOp::clone; + BoundaryOp* clone(BoundaryRegion* region, const std::list& args) override; + + using BoundaryOp::apply; + void apply(Field2D& f) override; + void apply(Field2D& f, BoutReal t) override; + void apply(Field3D& f) override; + void apply(Field3D& f, BoutReal t) override; + + using BoundaryOp::apply_ddt; + void apply_ddt(Field2D& f) override; + void apply_ddt(Field3D& f) override; + +private: + std::shared_ptr gen; +}; + /// Neumann boundary condition set half way between guard cell and grid cell at 2nd order accuracy class BoundaryNeumann_2ndOrder : public BoundaryOp { public: diff --git a/src/mesh/boundary_factory.cxx b/src/mesh/boundary_factory.cxx index 988fcfce9b..db1189900c 100644 --- a/src/mesh/boundary_factory.cxx +++ b/src/mesh/boundary_factory.cxx @@ -20,15 +20,18 @@ using std::string; BoundaryFactory* BoundaryFactory::instance = nullptr; BoundaryFactory::BoundaryFactory() { - add(new BoundaryDirichlet(), "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"); add(new BoundaryDirichlet_O4(), "dirichlet_o4"); add(new BoundaryDirichlet_4thOrder(), "dirichlet_4thorder"); - add(new BoundaryNeumann(), "neumann"); - add(new BoundaryNeumann(), "neumann_O2"); // Synonym for "neumann" + + add(new BoundaryNeumann(), "neumann"); // Default + add(new BoundaryNeumann_O1(), "neumann_o1"); // Old implementation in v3 + add(new BoundaryNeumann(), "neumann_o2"); // Synonym for "neumann" add(new BoundaryNeumann_4thOrder(), "neumann_4thorder"); - add(new BoundaryNeumann_O4(), "neumann_O4"); + add(new BoundaryNeumann_O4(), "neumann_o4"); add(new BoundaryNeumannPar(), "neumannpar"); add(new BoundaryNeumann_NonOrthogonal(), "neumann_nonorthogonal"); add(new BoundaryRobin(), "robin"); diff --git a/src/mesh/boundary_standard.cxx b/src/mesh/boundary_standard.cxx index 141cab0a43..ba0eea658e 100644 --- a/src/mesh/boundary_standard.cxx +++ b/src/mesh/boundary_standard.cxx @@ -115,6 +115,135 @@ void verifyNumPoints(BoundaryRegion* region, int ptsRequired) { void verifyNumPoints(BoundaryRegion*, int) {} #endif + +/////////////////////////////////////////////////////////////// + +BoundaryOp* BoundaryDirichlet_O1::clone(BoundaryRegion* region, + const std::list& args) { + verifyNumPoints(region, 1); + + std::shared_ptr newgen; + if (!args.empty()) { + // First argument should be an expression + newgen = FieldFactory::get()->parse(args.front()); + } + return new BoundaryDirichlet_O1(region, newgen); +} + +void BoundaryDirichlet_O1::apply(Field2D& f) { BoundaryDirichlet_O1::apply(f, 0.); } + +void BoundaryDirichlet_O1::apply(Field2D& f, BoutReal t) { + // Set (at 1st order) the value at the grid cell to the guard cells. + + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + bndry->first(); + + // Decide which generator to use + std::shared_ptr fg = gen; + if (!fg) { + fg = f.getBndryGenerator(bndry->location); + } + + BoutReal val = 0.0; + + // Check for staggered grids + + CELL_LOC loc = f.getLocation(); + if (mesh->StaggerGrids) { + // Staggered + throw BoutException("dirichlet_o1 BC is not implementated for staggered grids."); + + } else { + // Non-staggered, standard case + for (; !bndry->isDone(); bndry->next1d()) { + + if (fg) { + val = fg->generate(Context(bndry, loc, t, mesh)); + } + f(bndry->x, bndry->y) = val; + + // Need to set second guard cell, as may be used for interpolation or upwinding derivatives + // This is not very efficient. Both boundary cells can be treated in one loop. + for (int i = 1; i < bndry->width; i++) { + int xi = bndry->x + i * bndry->bx; + int yi = bndry->y + i * bndry->by; + f(xi, yi) = val; + } + + } + } +} + +void BoundaryDirichlet_O1::apply(Field3D& f) { BoundaryDirichlet_O1::apply(f, 0.); } + +void BoundaryDirichlet_O1::apply(Field3D& f, BoutReal t) { + // Set (at 1st order) the value at the grid cell to the guard cells. + + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + bndry->first(); + + // Decide which generator to use + std::shared_ptr fg = gen; + if (!fg) { + fg = f.getBndryGenerator(bndry->location); + } + + BoutReal val = 0.0; + + // Check for staggered grids + + CELL_LOC loc = f.getLocation(); + if (mesh->StaggerGrids) { + // Staggered. + throw BoutException("dirichlet_o1 BC is not implementated for staggered grids."); + + } else { + // Standard (non-staggered) case + for (; !bndry->isDone(); bndry->next1d()) { + for (int zk = 0; zk < mesh->LocalNz; 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 = 0; zk < mesh->LocalNz; zk++) { + if (fg) { + val = fg->generate(Context(bndry, zk, loc, t, mesh)); + } + f(xi, yi, zk) = val; + } + } + } + } +} + +void BoundaryDirichlet_O1::apply_ddt(Field2D& f) { + Field2D* dt = f.timeDeriv(); + for (bndry->first(); !bndry->isDone(); bndry->next()) { + (*dt)(bndry->x, bndry->y) = 0.; // Set time derivative to zero + } +} + +void BoundaryDirichlet_O1::apply_ddt(Field3D& f) { + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + Field3D* dt = f.timeDeriv(); + + for (bndry->first(); !bndry->isDone(); bndry->next()) { + for (int z = 0; z < mesh->LocalNz; z++) { + (*dt)(bndry->x, bndry->y, z) = 0.; // Set time derivative to zero + } + } +} + /////////////////////////////////////////////////////////////// BoundaryOp* BoundaryDirichlet::clone(BoundaryRegion* region, @@ -1714,6 +1843,138 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { /////////////////////////////////////////////////////////////// + BoundaryOp* BoundaryNeumann_O1::clone(BoundaryRegion * region, + const std::list& args) { + verifyNumPoints(region, 1); + std::shared_ptr newgen = nullptr; + if (!args.empty()) { + // First argument should be an expression + newgen = FieldFactory::get()->parse(args.front()); + } + return new BoundaryNeumann_O1(region, newgen); + } + + void BoundaryNeumann_O1::apply(Field2D & f) { BoundaryNeumann_O1::apply(f, 0.); } + + void BoundaryNeumann_O1::apply(Field2D & f, BoutReal t) { + // Set (at 1st order) the gradient/value at the grid cell to the guard cells. + + +#if not(BOUT_USE_METRIC_3D) + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + Coordinates* metric = f.getCoordinates(); + + bndry->first(); + + // Decide which generator to use + std::shared_ptr fg = gen; + if (!fg) { + fg = f.getBndryGenerator(bndry->location); + } + + BoutReal val = 0.0; + + // Check for staggered grids + + CELL_LOC loc = f.getLocation(); + if (mesh->StaggerGrids) { + // Staggered. + throw BoutException("neumann_o1 BC is not implementated for staggered grids."); + + } else { + // Non-staggered, standard case + + for (bndry->first(); !bndry->isDone(); bndry->next1d()) { + BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) + + bndry->by * metric->dy(bndry->x, bndry->y); + + if (fg) { + val = fg->generate(Context(bndry, loc, t, mesh)); + } + + f(bndry->x, bndry->y) = + f(bndry->x - bndry->bx, bndry->y - bndry->by) + delta * val; + if (bndry->width == 2) { + f(bndry->x + bndry->bx, bndry->y + bndry->by) = f(bndry->x, bndry->y) + delta * val; + } + } + } +#else + throw BoutException("Applying boundary condition 'neumann' to Field2D " + "not compatible with 3D metrics in all cases."); +#endif + } + + void BoundaryNeumann_O1::apply(Field3D & f) { BoundaryNeumann_O1::apply(f, 0.); } + + void BoundaryNeumann_O1::apply(Field3D & f, BoutReal t) { + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + Coordinates* metric = f.getCoordinates(); + + bndry->first(); + + // Decide which generator to use + std::shared_ptr fg = gen; + if (!fg) { + fg = f.getBndryGenerator(bndry->location); + } + + BoutReal val = 0.0; + + // Check for staggered grids + + CELL_LOC loc = f.getLocation(); + if (mesh->StaggerGrids) { + // Staggered. + throw BoutException("neumann_o1 BC is not implementated for staggered grids."); + + } else { + for (; !bndry->isDone(); bndry->next1d()) { +#if BOUT_USE_METRIC_3D + for (int zk = 0; zk < mesh->LocalNz; zk++) { + BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y, zk) + + bndry->by * metric->dy(bndry->x, bndry->y, zk); +#else + BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) + + bndry->by * metric->dy(bndry->x, bndry->y); + for (int zk = 0; zk < mesh->LocalNz; zk++) { +#endif + if (fg) { + val = fg->generate(Context(bndry, zk, loc, t, mesh)); + } + f(bndry->x, bndry->y, zk) = + f(bndry->x - bndry->bx, bndry->y - bndry->by, zk) + delta * val; + if (bndry->width == 2) { + f(bndry->x + bndry->bx, bndry->y + bndry->by, zk) = + f(bndry->x, bndry->y, zk) + delta * val; + } + } + } + } + } + + void BoundaryNeumann_O1::apply_ddt(Field2D & f) { + Field2D* dt = f.timeDeriv(); + for (bndry->first(); !bndry->isDone(); bndry->next()) { + (*dt)(bndry->x, bndry->y) = 0.; // Set time derivative to zero + } + } + + void BoundaryNeumann_O1::apply_ddt(Field3D & f) { + Mesh* mesh = bndry->localmesh; + ASSERT1(mesh == f.getMesh()); + Field3D* dt = f.timeDeriv(); + for (bndry->first(); !bndry->isDone(); bndry->next()) { + for (int z = 0; z < mesh->LocalNz; z++) { + (*dt)(bndry->x, bndry->y, z) = 0.; // Set time derivative to zero + } + } + } + + /////////////////////////////////////////////////////////////// + BoundaryOp* BoundaryNeumann::clone(BoundaryRegion * region, const std::list& args) { verifyNumPoints(region, 1); From a9a5f418f8d75243c87e922c4e4923feb3c833e5 Mon Sep 17 00:00:00 2001 From: malamast Date: Tue, 7 Jul 2026 16:59:42 -0700 Subject: [PATCH 2/4] boundary_standard: changed LocalNz to zend to make it compatible with the rest of the BC code. -This was a later change to the BCs --- src/mesh/boundary_standard.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mesh/boundary_standard.cxx b/src/mesh/boundary_standard.cxx index ba0eea658e..f12d079d01 100644 --- a/src/mesh/boundary_standard.cxx +++ b/src/mesh/boundary_standard.cxx @@ -202,7 +202,7 @@ void BoundaryDirichlet_O1::apply(Field3D& f, BoutReal t) { } else { // Standard (non-staggered) case for (; !bndry->isDone(); bndry->next1d()) { - for (int zk = 0; zk < mesh->LocalNz; zk++) { + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { if (fg) { val = fg->generate(Context(bndry, zk, loc, t, mesh)); } @@ -214,7 +214,7 @@ void BoundaryDirichlet_O1::apply(Field3D& f, BoutReal t) { // 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 = 0; zk < mesh->LocalNz; zk++) { + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { if (fg) { val = fg->generate(Context(bndry, zk, loc, t, mesh)); } @@ -238,7 +238,7 @@ void BoundaryDirichlet_O1::apply_ddt(Field3D& f) { Field3D* dt = f.timeDeriv(); for (bndry->first(); !bndry->isDone(); bndry->next()) { - for (int z = 0; z < mesh->LocalNz; z++) { + for (int z = mesh->zstart; z <= mesh->zend; z++) { (*dt)(bndry->x, bndry->y, z) = 0.; // Set time derivative to zero } } @@ -1933,13 +1933,13 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { } else { for (; !bndry->isDone(); bndry->next1d()) { #if BOUT_USE_METRIC_3D - for (int zk = 0; zk < mesh->LocalNz; zk++) { + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y, zk) + bndry->by * metric->dy(bndry->x, bndry->y, zk); #else BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) + bndry->by * metric->dy(bndry->x, bndry->y); - for (int zk = 0; zk < mesh->LocalNz; zk++) { + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { #endif if (fg) { val = fg->generate(Context(bndry, zk, loc, t, mesh)); @@ -1967,7 +1967,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { ASSERT1(mesh == f.getMesh()); Field3D* dt = f.timeDeriv(); for (bndry->first(); !bndry->isDone(); bndry->next()) { - for (int z = 0; z < mesh->LocalNz; z++) { + for (int z = mesh->zstart; z <= mesh->zend; z++) { (*dt)(bndry->x, bndry->y, z) = 0.; // Set time derivative to zero } } From a96044748c6464b5fc297460476a306c7719905d Mon Sep 17 00:00:00 2001 From: malamast Date: Tue, 7 Jul 2026 17:23:00 -0700 Subject: [PATCH 3/4] Apply clang-format --- src/mesh/boundary_factory.cxx | 6 +++--- src/mesh/boundary_standard.cxx | 32 +++++++++++++++----------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/mesh/boundary_factory.cxx b/src/mesh/boundary_factory.cxx index db1189900c..58e37ed53f 100644 --- a/src/mesh/boundary_factory.cxx +++ b/src/mesh/boundary_factory.cxx @@ -20,16 +20,16 @@ using std::string; BoundaryFactory* BoundaryFactory::instance = nullptr; BoundaryFactory::BoundaryFactory() { - add(new BoundaryDirichlet(), "dirichlet"); // Default + 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"); add(new BoundaryDirichlet_O4(), "dirichlet_o4"); add(new BoundaryDirichlet_4thOrder(), "dirichlet_4thorder"); - add(new BoundaryNeumann(), "neumann"); // Default + add(new BoundaryNeumann(), "neumann"); // Default add(new BoundaryNeumann_O1(), "neumann_o1"); // Old implementation in v3 - add(new BoundaryNeumann(), "neumann_o2"); // Synonym for "neumann" + add(new BoundaryNeumann(), "neumann_o2"); // Synonym for "neumann" add(new BoundaryNeumann_4thOrder(), "neumann_4thorder"); add(new BoundaryNeumann_O4(), "neumann_o4"); add(new BoundaryNeumannPar(), "neumannpar"); diff --git a/src/mesh/boundary_standard.cxx b/src/mesh/boundary_standard.cxx index f12d079d01..8917011a93 100644 --- a/src/mesh/boundary_standard.cxx +++ b/src/mesh/boundary_standard.cxx @@ -115,11 +115,10 @@ void verifyNumPoints(BoundaryRegion* region, int ptsRequired) { void verifyNumPoints(BoundaryRegion*, int) {} #endif - /////////////////////////////////////////////////////////////// BoundaryOp* BoundaryDirichlet_O1::clone(BoundaryRegion* region, - const std::list& args) { + const std::list& args) { verifyNumPoints(region, 1); std::shared_ptr newgen; @@ -168,9 +167,8 @@ void BoundaryDirichlet_O1::apply(Field2D& f, BoutReal t) { for (int i = 1; i < bndry->width; i++) { int xi = bndry->x + i * bndry->bx; int yi = bndry->y + i * bndry->by; - f(xi, yi) = val; - } - + f(xi, yi) = val; + } } } } @@ -1844,7 +1842,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { /////////////////////////////////////////////////////////////// BoundaryOp* BoundaryNeumann_O1::clone(BoundaryRegion * region, - const std::list& args) { + const std::list& args) { verifyNumPoints(region, 1); std::shared_ptr newgen = nullptr; if (!args.empty()) { @@ -1857,8 +1855,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { void BoundaryNeumann_O1::apply(Field2D & f) { BoundaryNeumann_O1::apply(f, 0.); } void BoundaryNeumann_O1::apply(Field2D & f, BoutReal t) { - // Set (at 1st order) the gradient/value at the grid cell to the guard cells. - + // Set (at 1st order) the gradient/value at the grid cell to the guard cells. #if not(BOUT_USE_METRIC_3D) Mesh* mesh = bndry->localmesh; @@ -1879,7 +1876,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { CELL_LOC loc = f.getLocation(); if (mesh->StaggerGrids) { - // Staggered. + // Staggered. throw BoutException("neumann_o1 BC is not implementated for staggered grids."); } else { @@ -1896,13 +1893,14 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { f(bndry->x, bndry->y) = f(bndry->x - bndry->bx, bndry->y - bndry->by) + delta * val; if (bndry->width == 2) { - f(bndry->x + bndry->bx, bndry->y + bndry->by) = f(bndry->x, bndry->y) + delta * val; + f(bndry->x + bndry->bx, bndry->y + bndry->by) = + f(bndry->x, bndry->y) + delta * val; } } } #else - throw BoutException("Applying boundary condition 'neumann' to Field2D " - "not compatible with 3D metrics in all cases."); + throw BoutException("Applying boundary condition 'neumann' to Field2D " + "not compatible with 3D metrics in all cases."); #endif } @@ -1927,7 +1925,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { CELL_LOC loc = f.getLocation(); if (mesh->StaggerGrids) { - // Staggered. + // Staggered. throw BoutException("neumann_o1 BC is not implementated for staggered grids."); } else { @@ -1937,9 +1935,9 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y, zk) + bndry->by * metric->dy(bndry->x, bndry->y, zk); #else - BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) - + bndry->by * metric->dy(bndry->x, bndry->y); - for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { + BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) + + bndry->by * metric->dy(bndry->x, bndry->y); + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { #endif if (fg) { val = fg->generate(Context(bndry, zk, loc, t, mesh)); @@ -1948,7 +1946,7 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { f(bndry->x - bndry->bx, bndry->y - bndry->by, zk) + delta * val; if (bndry->width == 2) { f(bndry->x + bndry->bx, bndry->y + bndry->by, zk) = - f(bndry->x, bndry->y, zk) + delta * val; + f(bndry->x, bndry->y, zk) + delta * val; } } } From 4687df8e99028f7cc90f87360b74398f5855e83b Mon Sep 17 00:00:00 2001 From: malamast Date: Wed, 22 Jul 2026 17:22:28 -0700 Subject: [PATCH 4/4] Apply perk-formatting --- src/mesh/boundary_factory.cxx | 2 +- src/mesh/boundary_standard.cxx | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mesh/boundary_factory.cxx b/src/mesh/boundary_factory.cxx index 627297eeed..3841a95b11 100644 --- a/src/mesh/boundary_factory.cxx +++ b/src/mesh/boundary_factory.cxx @@ -23,7 +23,7 @@ BoundaryFactory* BoundaryFactory::instance = nullptr; BoundaryFactory::BoundaryFactory() { 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(), "dirichlet_o2"); // Synonym for "dirichlet" add(new BoundaryDirichlet_O3(), "dirichlet_o3"); add(new BoundaryDirichlet_O4(), "dirichlet_o4"); add(new BoundaryDirichlet_4thOrder(), "dirichlet_4thorder"); diff --git a/src/mesh/boundary_standard.cxx b/src/mesh/boundary_standard.cxx index 8917011a93..491b4a5b71 100644 --- a/src/mesh/boundary_standard.cxx +++ b/src/mesh/boundary_standard.cxx @@ -1899,8 +1899,8 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { } } #else - throw BoutException("Applying boundary condition 'neumann' to Field2D " - "not compatible with 3D metrics in all cases."); + throw BoutException("Applying boundary condition 'neumann' to Field2D " + "not compatible with 3D metrics in all cases."); #endif } @@ -1935,9 +1935,9 @@ void BoundaryNeumann_NonOrthogonal::apply(Field3D& f) { BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y, zk) + bndry->by * metric->dy(bndry->x, bndry->y, zk); #else - BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) - + bndry->by * metric->dy(bndry->x, bndry->y); - for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { + BoutReal delta = bndry->bx * metric->dx(bndry->x, bndry->y) + + bndry->by * metric->dy(bndry->x, bndry->y); + for (int zk = mesh->zstart; zk <= mesh->zend; zk++) { #endif if (fg) { val = fg->generate(Context(bndry, zk, loc, t, mesh));