diff --git a/include/bout/sys/generator_context.hxx b/include/bout/sys/generator_context.hxx
index bbe60fab65..e39eea1835 100644
--- a/include/bout/sys/generator_context.hxx
+++ b/include/bout/sys/generator_context.hxx
@@ -24,12 +24,8 @@ public:
: Context(i.x(), i.y(), 0, (loc == CELL_ZLOW) ? CELL_CENTRE : loc, msh, t) {}
/// Specify a cell index, together with the cell location, mesh and time
- ///
Context(int ix, int iy, int iz, CELL_LOC loc, Mesh* msh, BoutReal t);
- /// Specify the values directly
- Context(BoutReal x, BoutReal y, BoutReal z, Mesh* msh, BoutReal t);
-
/// If constructed without parameters, contains no values (null).
/// Requesting x,y,z or t throws an exception
Context() = default;
@@ -44,6 +40,11 @@ public:
BoutReal z() const { return get("z"); }
BoutReal t() const { return get("t"); }
+ /// Cell indices
+ int ix() const { return ix_; }
+ int jy() const { return jy_; }
+ int kz() const { return kz_; }
+
/// Set the value of a parameter with given name
Context& set(const std::string& name, BoutReal value) {
parameters[name] = value;
@@ -76,6 +77,10 @@ public:
}
private:
+ int ix_{0};
+ int jy_{0};
+ int kz_{0};
+
Mesh* localmesh{nullptr}; ///< The mesh on which the position is defined
/// Contains user-set values which can be set and retrieved
diff --git a/manual/sphinx/user_docs/input_grids.rst b/manual/sphinx/user_docs/input_grids.rst
index 3d6be2cf77..983346f14e 100644
--- a/manual/sphinx/user_docs/input_grids.rst
+++ b/manual/sphinx/user_docs/input_grids.rst
@@ -155,6 +155,21 @@ The only quantities which are required are the sizes of the grid. If
these are the only quantities specified, then the coordinates revert to
Cartesian.
+You can read additional quantities from the grid and make them available in
+expressions in the input file by listing them in the ``input:grid_variables``
+section, with the key being the name in the grid file (``mesh:file``) and the
+value being the type (one of ``field3d``, ``field2d``, ``boutreal``):
+
+.. code-block:: cfg
+
+ [input:grid_variables]
+ rho = field2d
+ theta = field2d
+ scale = boutreal
+
+ [mesh]
+ B = (scale / rho) * cos(theta)
+
This section describes how to generate inputs for tokamak equilibria. If
you’re not interested in tokamaks then you can skip to the next section.
diff --git a/src/field/field_factory.cxx b/src/field/field_factory.cxx
index f65f2e7f55..44fe8c1783 100644
--- a/src/field/field_factory.cxx
+++ b/src/field/field_factory.cxx
@@ -19,20 +19,28 @@
* along with BOUT++. If not, see .
*
**************************************************************************/
-#include
#include
-#include
-
+#include
+#include
+#include
#include
+#include
+#include
+#include
+#include
#include
+#include
+#include
#include
-#include "bout/constants.hxx"
-
#include "fieldgenerators.hxx"
+#include
+#include
+#include
+
using bout::generator::Context;
/// Helper function to create a FieldValue generator from a BoutReal
@@ -45,6 +53,8 @@ FieldGeneratorPtr generator(BoutReal* ptr) {
return std::make_shared(ptr);
}
+BOUT_ENUM_CLASS(GridVariableFunction, field3d, field2d, boutreal);
+
namespace {
/// Provides a placeholder whose target can be changed after creation.
/// This enables recursive FieldGenerator expressions to be generated
@@ -80,6 +90,48 @@ class FieldIndirect : public FieldGenerator {
FieldGeneratorPtr target;
};
+
+// Read variables from the grid file and make them available in expressions
+template
+auto add_grid_variable(FieldFactory& factory, Mesh& mesh, const std::string& name) {
+ T var;
+ mesh.get(var, name);
+ factory.addGenerator(name, std::make_shared>(var, name));
+}
+
+auto read_grid_variables(FieldFactory& factory, Mesh& mesh, Options& options) {
+ auto& field_variables = options["input"]["grid_variables"].doc(
+ "Variables to read from the grid file and make available in expressions");
+
+ for (const auto& [name, value] : field_variables) {
+ if (not mesh.isDataSourceGridFile()) {
+ throw BoutException(
+ "A grid file ('mesh:file') is required for `input:grid_variables`");
+ }
+
+ if (not mesh.sourceHasVar(name)) {
+ const auto filename = Options::root()["mesh"]["file"].as();
+ throw BoutException(
+ "Grid file '{}' missing `{}` specified in `input:grid_variables`", filename,
+ name);
+ }
+
+ const auto func = value.as();
+ switch (func) {
+ case GridVariableFunction::field3d:
+ add_grid_variable(factory, mesh, name);
+ break;
+ case GridVariableFunction::field2d:
+ add_grid_variable(factory, mesh, name);
+ break;
+ case GridVariableFunction::boutreal:
+ BoutReal var{};
+ mesh.get(var, name);
+ factory.addGenerator(name, std::make_shared(var));
+ break;
+ }
+ }
+}
} // namespace
//////////////////////////////////////////////////////////
@@ -176,6 +228,9 @@ FieldFactory::FieldFactory(Mesh* localmesh, Options* opt)
// Where switch function
addGenerator("where", std::make_shared(nullptr, nullptr, nullptr));
+
+ // Variables from the grid file
+ read_grid_variables(*this, *localmesh, nonconst_options);
}
Field2D FieldFactory::create2D(const std::string& value, const Options* opt,
diff --git a/src/field/fieldgenerators.hxx b/src/field/fieldgenerators.hxx
index 2485b4b82d..f640f33c06 100644
--- a/src/field/fieldgenerators.hxx
+++ b/src/field/fieldgenerators.hxx
@@ -9,9 +9,13 @@
#include
#include
+#include
+#include
#include
#include
+#include
+#include
//////////////////////////////////////////////////////////
// Generators from values
@@ -352,4 +356,29 @@ private:
FieldGeneratorPtr test, gt0, lt0;
};
+/// A `Field3D` that can be used in expressions
+template >
+class GridVariable : public FieldGenerator {
+public:
+ GridVariable(T var, std::string name)
+ : variable(std::move(var)), name(std::move(name)) {}
+
+ double generate(const bout::generator::Context& ctx) override {
+ return variable(ctx.ix(), ctx.jy(), ctx.kz());
+ }
+
+ FieldGeneratorPtr clone(const std::list args) override {
+ if (args.size() != 0) {
+ throw ParseException("Variable '{}' takes no arguments but got {:d}", args.size());
+ }
+ return std::make_shared>(variable, name);
+ }
+
+ std::string str() const override { return name; }
+
+private:
+ T variable;
+ std::string name;
+};
+
#endif // BOUT_FIELDGENERATORS_H
diff --git a/src/sys/generator_context.cxx b/src/sys/generator_context.cxx
index 25274e8107..c34f266b76 100644
--- a/src/sys/generator_context.cxx
+++ b/src/sys/generator_context.cxx
@@ -7,7 +7,7 @@ namespace bout {
namespace generator {
Context::Context(int ix, int iy, int iz, CELL_LOC loc, Mesh* msh, BoutReal t)
- : localmesh(msh) {
+ : ix_(ix), jy_(iy), kz_(iz), localmesh(msh) {
parameters["x"] = (loc == CELL_XLOW) ? 0.5 * (msh->GlobalX(ix) + msh->GlobalX(ix - 1))
: msh->GlobalX(ix);
@@ -23,20 +23,17 @@ Context::Context(int ix, int iy, int iz, CELL_LOC loc, Mesh* msh, BoutReal t)
}
Context::Context(const BoundaryRegion* bndry, int iz, CELL_LOC loc, BoutReal t, Mesh* msh)
- : localmesh(msh) {
-
- // Add one to X index if boundary is in -x direction, so that XLOW is on the boundary
- int ix = (bndry->bx < 0) ? bndry->x + 1 : bndry->x;
+ : // Add one to X index if boundary is in -x direction, so that XLOW is on the boundary
+ ix_((bndry->bx < 0) ? bndry->x + 1 : bndry->x),
+ jy_((bndry->by < 0) ? bndry->y + 1 : bndry->y), kz_(iz), localmesh(msh) {
parameters["x"] = ((loc == CELL_XLOW) || (bndry->bx != 0))
- ? 0.5 * (msh->GlobalX(ix) + msh->GlobalX(ix - 1))
- : msh->GlobalX(ix);
-
- int iy = (bndry->by < 0) ? bndry->y + 1 : bndry->y;
+ ? 0.5 * (msh->GlobalX(ix_) + msh->GlobalX(ix_ - 1))
+ : msh->GlobalX(ix_);
- parameters["y"] = ((loc == CELL_YLOW) || bndry->by)
- ? PI * (msh->GlobalY(iy) + msh->GlobalY(iy - 1))
- : TWOPI * msh->GlobalY(iy);
+ parameters["y"] = ((loc == CELL_YLOW) || (bndry->by != 0))
+ ? PI * (msh->GlobalY(jy_) + msh->GlobalY(jy_ - 1))
+ : TWOPI * msh->GlobalY(jy_);
parameters["z"] = (loc == CELL_ZLOW)
? TWOPI * (iz - 0.5) / static_cast(msh->LocalNz)
@@ -45,8 +42,5 @@ Context::Context(const BoundaryRegion* bndry, int iz, CELL_LOC loc, BoutReal t,
parameters["t"] = t;
}
-Context::Context(BoutReal x, BoutReal y, BoutReal z, Mesh* msh, BoutReal t)
- : localmesh(msh), parameters{{"x", x}, {"y", y}, {"z", z}, {"t", t}} {}
-
} // namespace generator
} // namespace bout
diff --git a/tests/unit/fake_mesh.hxx b/tests/unit/fake_mesh.hxx
index 5d0d12de07..fdee861fc3 100644
--- a/tests/unit/fake_mesh.hxx
+++ b/tests/unit/fake_mesh.hxx
@@ -133,7 +133,7 @@ public:
MPI_Comm getYcomm(int UNUSED(jx)) const override { return BoutComm::get(); }
bool periodicY(int UNUSED(jx)) const override { return true; }
bool periodicY(int UNUSED(jx), BoutReal& UNUSED(ts)) const override { return true; }
- int numberOfYBoundaries() const override { return 1; }
+ int numberOfYBoundaries() const override { return 0; }
std::pair hasBranchCutLower(int UNUSED(jx)) const override {
return std::make_pair(false, 0.);
}
diff --git a/tests/unit/field/test_field_factory.cxx b/tests/unit/field/test_field_factory.cxx
index 964788b25a..dd5d730545 100644
--- a/tests/unit/field/test_field_factory.cxx
+++ b/tests/unit/field/test_field_factory.cxx
@@ -1,17 +1,21 @@
#include "gtest/gtest.h"
+#include "fake_mesh.hxx"
#include "test_extras.hxx"
#include "bout/boutexception.hxx"
#include "bout/constants.hxx"
#include "bout/field2d.hxx"
#include "bout/field3d.hxx"
#include "bout/field_factory.hxx"
+#include "bout/globals.hxx"
#include "bout/mesh.hxx"
+#include "bout/options_io.hxx"
#include "bout/output.hxx"
#include "bout/paralleltransform.hxx"
#include "bout/traits.hxx"
#include "fake_mesh_fixture.hxx"
+#include "test_tmpfiles.hxx"
// The unit tests use the global mesh
using namespace bout::globals;
@@ -969,3 +973,122 @@ TEST_F(FieldFactoryCreateAndTransformTest, Create3DCantTransform) {
EXPECT_TRUE(IsFieldEqual(output, expected));
}
+
+struct FieldFactoryFieldVariableTest : public FakeMeshFixture {
+ WithQuietOutput quiet{output_info};
+};
+
+TEST_F(FieldFactoryFieldVariableTest, CreateField3D) {
+ bout::testing::TempFile filename;
+
+ {
+ // Write some fields to a grid file
+ FieldFactory factory{mesh};
+ const auto rho = factory.create3D("sqrt(x^2 + y^2)");
+ const auto theta = factory.create3D("atan(y, x)");
+ Options grid{{"rho", rho},
+ {"theta", theta},
+ {"nx", mesh->LocalNx},
+ {"ny", mesh->LocalNy},
+ {"nz", mesh->LocalNz}};
+ bout::OptionsIO::create(filename)->write(grid);
+ }
+
+ {
+ Options options{
+ {"mesh", {{"file", filename.string()}}},
+ {"input", {{"grid_variables", {{"rho", "field3d"}, {"theta", "field3d"}}}}}};
+
+ dynamic_cast(mesh)->setGridDataSource(new GridFile{filename});
+ auto factory = FieldFactory{mesh, &options};
+
+ const auto output = factory.create3D("rho * cos(theta)");
+ const auto x = factory.create3D("x");
+ EXPECT_TRUE(IsFieldEqual(output, x));
+ }
+}
+
+TEST_F(FieldFactoryFieldVariableTest, CreateField2D) {
+ bout::testing::TempFile filename;
+
+ {
+ // Write some fields to a grid file
+ FieldFactory factory{mesh};
+ const auto rho = factory.create2D("sqrt(x^2 + y^2)");
+ const auto theta = factory.create2D("atan(y, x)");
+ Options grid{{"rho", rho},
+ {"theta", theta},
+ {"nx", mesh->LocalNx},
+ {"ny", mesh->LocalNy},
+ {"nz", mesh->LocalNz}};
+ bout::OptionsIO::create(filename)->write(grid);
+ }
+
+ {
+ Options options{
+ {"mesh", {{"file", filename.string()}}},
+ {"input", {{"grid_variables", {{"rho", "field2d"}, {"theta", "field2d"}}}}}};
+
+ dynamic_cast(mesh)->setGridDataSource(new GridFile{filename});
+ auto factory = FieldFactory{mesh, &options};
+
+ const auto output = factory.create2D("rho * cos(theta)");
+ const auto x = factory.create2D("x");
+ EXPECT_TRUE(IsFieldEqual(output, x));
+ }
+}
+
+TEST_F(FieldFactoryFieldVariableTest, ReadBoutReal) {
+ bout::testing::TempFile filename;
+
+ {
+ Options grid{{"rho", 4},
+ {"theta", 5},
+ {"nx", mesh->LocalNx},
+ {"ny", mesh->LocalNy},
+ {"nz", mesh->LocalNz}};
+ bout::OptionsIO::create(filename)->write(grid);
+ }
+
+ {
+ Options options{
+ {"mesh", {{"file", filename.string()}}},
+ {"input", {{"grid_variables", {{"rho", "boutreal"}, {"theta", "boutreal"}}}}}};
+
+ dynamic_cast(mesh)->setGridDataSource(new GridFile{filename});
+ auto factory = FieldFactory{mesh, &options};
+
+ const auto output = factory.create3D("rho * theta");
+ EXPECT_TRUE(IsFieldEqual(output, 4 * 5));
+ }
+}
+
+TEST_F(FieldFactoryFieldVariableTest, NoMeshFile) {
+ Options options{{"input", {{"grid_variables", {{"rho", "field3d"}}}}}};
+
+ EXPECT_THROW((FieldFactory(mesh, &options)), BoutException);
+}
+
+TEST_F(FieldFactoryFieldVariableTest, MissingVariable) {
+ bout::testing::TempFile filename;
+
+ {
+ // Write some fields to a grid file
+ FieldFactory factory{mesh};
+ const auto rho = factory.create3D("sqrt(x^2 + y^2)");
+ Options grid{{"rho", rho},
+ {"nx", mesh->LocalNx},
+ {"ny", mesh->LocalNy},
+ {"nz", mesh->LocalNz}};
+ bout::OptionsIO::create(filename)->write(grid);
+ }
+
+ {
+ Options options{
+ {"mesh", {{"file", filename.string()}}},
+ {"input", {{"grid_variables", {{"rho", "field3d"}, {"theta", "field3d"}}}}}};
+
+ dynamic_cast(mesh)->setGridDataSource(new GridFile{filename});
+ EXPECT_THROW((FieldFactory{mesh, &options}), BoutException);
+ }
+}
diff --git a/tests/unit/mesh/test_boutmesh.cxx b/tests/unit/mesh/test_boutmesh.cxx
index fd2ba50d28..8a446a742b 100644
--- a/tests/unit/mesh/test_boutmesh.cxx
+++ b/tests/unit/mesh/test_boutmesh.cxx
@@ -242,21 +242,20 @@ BoutMeshParameters createDisconnectedDoubleNull(const BoutMeshGridInfo& grid) {
////////////////////////////////////////////////////////////
// Start of tests
-TEST(BoutMeshTest, NullOptionsCheck) {
+struct BoutMeshTest : public ::testing::Test {
+ WithQuietOutput debug{output_debug};
WithQuietOutput info{output_info};
WithQuietOutput warn{output_warn};
+ WithQuietOutput progress{output_progress};
+};
+TEST_F(BoutMeshTest, NullOptionsCheck) {
EXPECT_NO_THROW(BoutMesh mesh(new FakeGridDataSource, nullptr));
}
// Not a great test as it's not specific to the thing we want to test,
// and can also take a whopping ~300ms!
-TEST(BoutMeshTest, SingleCoreDecomposition) {
- WithQuietOutput debug{output_debug};
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
- WithQuietOutput progress{output_progress};
-
+TEST_F(BoutMeshTest, SingleCoreDecomposition) {
Options options{};
options["ny"] = 1;
options["nx"] = 4;
@@ -327,8 +326,7 @@ TEST_P(BoutMeshSetYDecompositionTest, BasicTest) {
EXPECT_EQ(mesh.numberOfXPoints, params.number_of_X_points);
}
-TEST(BoutMeshTest, SetYDecompositionIndicesJyseps22LowInconsistent) {
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, SetYDecompositionIndicesJyseps22LowInconsistent) {
BoutMeshExposer mesh(1, 24, 1, 1, 1);
EXPECT_THROW(mesh.setYDecompositionIndices({3, 7, 32, 8, 12}), BoutException);
@@ -466,8 +464,7 @@ TEST_P(BadBoutMeshDecompositionTest, BadSingleCoreYDecomposition) {
EXPECT_THAT(result.reason, HasSubstr(params.expected_message));
}
-TEST(BoutMeshTest, ChooseProcessorSplitBadNXPE) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, ChooseProcessorSplitBadNXPE) {
Options options{{"NXPE", 3}};
BoutMeshExposer mesh(1, 24, 1, 1, 1, 8);
@@ -475,8 +472,7 @@ TEST(BoutMeshTest, ChooseProcessorSplitBadNXPE) {
EXPECT_THROW(mesh.chooseProcessorSplit(options), BoutException);
}
-TEST(BoutMeshTest, ChooseProcessorSplitBadNYPE) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, ChooseProcessorSplitBadNYPE) {
Options options{{"NYPE", 7}};
BoutMeshExposer mesh(1, 24, 1, 1, 1, 8);
@@ -484,8 +480,7 @@ TEST(BoutMeshTest, ChooseProcessorSplitBadNYPE) {
EXPECT_THROW(mesh.chooseProcessorSplit(options), BoutException);
}
-TEST(BoutMeshTest, ChooseProcessorSplitNXPE) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, ChooseProcessorSplitNXPE) {
Options options{{"NXPE", 4}};
BoutMeshExposer mesh(1, 24, 1, 1, 1, 8);
@@ -496,8 +491,7 @@ TEST(BoutMeshTest, ChooseProcessorSplitNXPE) {
EXPECT_EQ(mesh.getNYPE(), 2);
}
-TEST(BoutMeshTest, ChooseProcessorSplitBadNXPENotEnoughGuards) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, ChooseProcessorSplitBadNXPENotEnoughGuards) {
Options options{{"NXPE", 4}};
BoutMeshExposer mesh(1, 24, 1, 1, 13, 8);
@@ -505,8 +499,7 @@ TEST(BoutMeshTest, ChooseProcessorSplitBadNXPENotEnoughGuards) {
EXPECT_THROW(mesh.chooseProcessorSplit(options), BoutException);
}
-TEST(BoutMeshTest, ChooseProcessorSplitNYPE) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, ChooseProcessorSplitNYPE) {
Options options{{"NYPE", 4}};
BoutMeshExposer mesh(1, 24, 1, 1, 1, 8);
@@ -698,9 +691,7 @@ TEST_P(BoutMeshProcNumTest, ProcNum) {
EXPECT_EQ(result, params.expected_result);
}
-TEST(BoutMeshTest, YProc) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, YProc) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
BoutMeshExposer mesh(5, 3, 1, 2, 2, 0, 0);
@@ -716,9 +707,7 @@ TEST(BoutMeshTest, YProc) {
EXPECT_EQ(mesh.YPROC(7), -1);
}
-TEST(BoutMeshTest, XProc) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, XProc) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
BoutMeshExposer mesh(5, 3, 1, 2, 2, 0, 0);
@@ -735,9 +724,7 @@ TEST(BoutMeshTest, XProc) {
// one example, so probably fine
}
-TEST(BoutMeshTest, GetGlobalXIndex) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalXIndex) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the global index
@@ -781,9 +768,7 @@ TEST(BoutMeshTest, GetGlobalXIndex) {
EXPECT_EQ(mesh11.getGlobalXIndex(4), 7);
}
-TEST(BoutMeshTest, GetGlobalXIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalXIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Global indices start counting from the first non-boundary point
@@ -827,10 +812,7 @@ TEST(BoutMeshTest, GetGlobalXIndexNoBoundaries) {
EXPECT_EQ(mesh11.getGlobalXIndexNoBoundaries(4), 6);
}
-TEST(BoutMeshTest, GlobalXIntSymmetricX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalXIntSymmetricX) {
BoutMeshExposer mesh01(4, 3, 1, 2, 2, 0, 1);
EXPECT_EQ(mesh01.GlobalX(0), -0.125);
EXPECT_EQ(mesh01.GlobalX(1), 0.125);
@@ -839,10 +821,7 @@ TEST(BoutMeshTest, GlobalXIntSymmetricX) {
EXPECT_EQ(mesh01.GlobalX(4), 0.875);
}
-TEST(BoutMeshTest, GlobalXIntAsymmetricX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalXIntAsymmetricX) {
BoutMeshExposer mesh01(4, 3, 1, 2, 2, 0, 1, false, false);
EXPECT_EQ(mesh01.GlobalX(0), 0.);
EXPECT_EQ(mesh01.GlobalX(1), 0.25);
@@ -851,10 +830,7 @@ TEST(BoutMeshTest, GlobalXIntAsymmetricX) {
EXPECT_EQ(mesh01.GlobalX(4), 1.0);
}
-TEST(BoutMeshTest, GlobalXRealSymmetricX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalXRealSymmetricX) {
BoutMeshExposer mesh01(4, 3, 1, 2, 2, 0, 1);
EXPECT_EQ(mesh01.GlobalX(0.5), 0.);
EXPECT_EQ(mesh01.GlobalX(1.5), 0.25);
@@ -863,10 +839,7 @@ TEST(BoutMeshTest, GlobalXRealSymmetricX) {
EXPECT_EQ(mesh01.GlobalX(4.5), 1.0);
}
-TEST(BoutMeshTest, GlobalXRealAsymmetricX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalXRealAsymmetricX) {
BoutMeshExposer mesh01(4, 3, 1, 2, 2, 0, 1, false, false);
EXPECT_EQ(mesh01.GlobalX(0.5), 0.125);
EXPECT_EQ(mesh01.GlobalX(1.5), 0.375);
@@ -875,9 +848,7 @@ TEST(BoutMeshTest, GlobalXRealAsymmetricX) {
EXPECT_EQ(mesh01.GlobalX(4.5), 1.125);
}
-TEST(BoutMeshTest, GetLocalXIndex) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalXIndex) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the local index
@@ -921,9 +892,7 @@ TEST(BoutMeshTest, GetLocalXIndex) {
EXPECT_EQ(mesh11.getLocalXIndex(7), 4);
}
-TEST(BoutMeshTest, GetLocalXIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalXIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Local indices start counting from the first non-boundary point
@@ -967,9 +936,7 @@ TEST(BoutMeshTest, GetLocalXIndexNoBoundaries) {
EXPECT_EQ(mesh11.getLocalXIndexNoBoundaries(6), 4);
}
-TEST(BoutMeshTest, GetGlobalYIndexSingleNull) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalYIndexSingleNull) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the global index
@@ -1013,9 +980,7 @@ TEST(BoutMeshTest, GetGlobalYIndexSingleNull) {
EXPECT_EQ(mesh11.getGlobalYIndex(4), 7);
}
-TEST(BoutMeshTest, GetGlobalYIndexDoubleNull) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalYIndexDoubleNull) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the global index
@@ -1064,9 +1029,7 @@ TEST(BoutMeshTest, GetGlobalYIndexDoubleNull) {
EXPECT_EQ(mesh11.getGlobalYIndex(4), 9);
}
-TEST(BoutMeshTest, GetGlobalYIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalYIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Global indices start counting from the first non-boundary point
@@ -1110,9 +1073,7 @@ TEST(BoutMeshTest, GetGlobalYIndexNoBoundaries) {
EXPECT_EQ(mesh11.getGlobalYIndexNoBoundaries(4), 6);
}
-TEST(BoutMeshTest, GetLocalYIndexSingleNull) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalYIndexSingleNull) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the local index
@@ -1156,9 +1117,7 @@ TEST(BoutMeshTest, GetLocalYIndexSingleNull) {
EXPECT_EQ(mesh11.getLocalYIndex(7), 4);
}
-TEST(BoutMeshTest, GetLocalYIndexDoubleNull) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalYIndexDoubleNull) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the global index
@@ -1207,9 +1166,7 @@ TEST(BoutMeshTest, GetLocalYIndexDoubleNull) {
EXPECT_EQ(mesh11.getLocalYIndex(9), 4);
}
-TEST(BoutMeshTest, GetLocalYIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalYIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Local indices start counting from the first non-boundary point
@@ -1253,10 +1210,7 @@ TEST(BoutMeshTest, GetLocalYIndexNoBoundaries) {
EXPECT_EQ(mesh11.getLocalYIndexNoBoundaries(6), 4);
}
-TEST(BoutMeshTest, GlobalYIntSymmetricY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalYIntSymmetricY) {
BoutMeshExposer mesh_inner_pf(createDisconnectedDoubleNull({12, 4, 1, 1, 1, 6, 0, 0}));
EXPECT_EQ(mesh_inner_pf.GlobalY(0), -0.5625);
EXPECT_EQ(mesh_inner_pf.GlobalY(1), -0.4375);
@@ -1284,10 +1238,7 @@ TEST(BoutMeshTest, GlobalYIntSymmetricY) {
EXPECT_EQ(mesh_outer_pf.GlobalY(3), 1.3125);
}
-TEST(BoutMeshTest, GlobalYIntAsymmetricY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalYIntAsymmetricY) {
auto grid_inner_pf = createDisconnectedDoubleNull({12, 4, 1, 1, 1, 6, 0, 0});
grid_inner_pf.grid.symmetric_Y = false;
BoutMeshExposer mesh_inner_pf(grid_inner_pf);
@@ -1321,10 +1272,7 @@ TEST(BoutMeshTest, GlobalYIntAsymmetricY) {
EXPECT_EQ(mesh_outer_pf.GlobalY(3), 1);
}
-TEST(BoutMeshTest, GlobalYRealSymmetricY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalYRealSymmetricY) {
BoutMeshExposer mesh_inner_pf(createDisconnectedDoubleNull({12, 4, 1, 1, 1, 6, 0, 0}));
EXPECT_EQ(mesh_inner_pf.GlobalY(0.5), -0.5);
EXPECT_EQ(mesh_inner_pf.GlobalY(1.5), -0.375);
@@ -1352,10 +1300,7 @@ TEST(BoutMeshTest, GlobalYRealSymmetricY) {
EXPECT_EQ(mesh_outer_pf.GlobalY(3.5), 1.375);
}
-TEST(BoutMeshTest, GlobalYRealAsymmetricY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GlobalYRealAsymmetricY) {
auto grid_inner_pf = createDisconnectedDoubleNull({12, 4, 1, 1, 1, 6, 0, 0});
grid_inner_pf.grid.symmetric_Y = false;
BoutMeshExposer mesh_inner_pf(grid_inner_pf);
@@ -1389,9 +1334,7 @@ TEST(BoutMeshTest, GlobalYRealAsymmetricY) {
EXPECT_EQ(mesh_outer_pf.GlobalY(3.5), 1);
}
-TEST(BoutMeshTest, GetGlobalZIndex) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalZIndex) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the global index
@@ -1427,9 +1370,7 @@ TEST(BoutMeshTest, GetGlobalZIndex) {
EXPECT_EQ(mesh11.getGlobalZIndex(4), 4);
}
-TEST(BoutMeshTest, GetGlobalZIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetGlobalZIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
BoutMeshExposer mesh00(5, 3, 4, 2, 2, 0, 0);
@@ -1461,9 +1402,7 @@ TEST(BoutMeshTest, GetGlobalZIndexNoBoundaries) {
EXPECT_EQ(mesh11.getGlobalZIndexNoBoundaries(4), 4);
}
-TEST(BoutMeshTest, GetLocalZIndex) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalZIndex) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Boundaries are included in the local index
@@ -1507,9 +1446,7 @@ TEST(BoutMeshTest, GetLocalZIndex) {
EXPECT_EQ(mesh11.getLocalZIndex(4), 4);
}
-TEST(BoutMeshTest, GetLocalZIndexNoBoundaries) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
+TEST_F(BoutMeshTest, GetLocalZIndexNoBoundaries) {
// 2x2 processors, 3x3x1 (not including guards) on each processor
// Local indices start counting from the first non-boundary point
@@ -1553,10 +1490,7 @@ TEST(BoutMeshTest, GetLocalZIndexNoBoundaries) {
EXPECT_EQ(mesh11.getLocalZIndexNoBoundaries(4), 4);
}
-TEST(BoutMeshTest, FirstX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, FirstX) {
BoutMeshExposer mesh00(5, 3, 4, 3, 3, 0, 0);
EXPECT_TRUE(mesh00.firstX());
BoutMeshExposer mesh10(5, 3, 4, 3, 3, 1, 0);
@@ -1577,10 +1511,7 @@ TEST(BoutMeshTest, FirstX) {
EXPECT_FALSE(mesh22.firstX());
}
-TEST(BoutMeshTest, LastX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, LastX) {
BoutMeshExposer mesh00(5, 3, 4, 3, 3, 0, 0);
EXPECT_FALSE(mesh00.lastX());
BoutMeshExposer mesh10(5, 3, 4, 3, 3, 1, 0);
@@ -1601,10 +1532,7 @@ TEST(BoutMeshTest, LastX) {
EXPECT_TRUE(mesh22.lastX());
}
-TEST(BoutMeshTest, FirstY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, FirstY) {
BoutMeshExposer mesh00(5, 3, 4, 3, 3, 0, 0);
EXPECT_TRUE(mesh00.firstY());
BoutMeshExposer mesh10(5, 3, 4, 3, 3, 1, 0);
@@ -1625,10 +1553,7 @@ TEST(BoutMeshTest, FirstY) {
EXPECT_FALSE(mesh22.firstY());
}
-TEST(BoutMeshTest, LastY) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, LastY) {
BoutMeshExposer mesh00(5, 3, 4, 3, 3, 0, 0);
EXPECT_FALSE(mesh00.lastY());
BoutMeshExposer mesh10(5, 3, 4, 3, 3, 1, 0);
@@ -1666,8 +1591,7 @@ void checkRegionSizes(const BoutMeshExposer& mesh, std::array rgn_lower_
// These next few tests check both default_connections and the Region
// creation, as these are quite tightly linked.
-TEST(BoutMeshTest, DefaultConnectionsCore1x1) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, DefaultConnectionsCore1x1) {
// 5x3x1 grid on 1 processor, 1 boundary point. Boundaries should be
// simple 1D rectangles, with 4 boundaries on this processor
BoutMeshExposer mesh00(5, 3, 1, 1, 1, 0, 0, false);
@@ -1685,9 +1609,7 @@ TEST(BoutMeshTest, DefaultConnectionsCore1x1) {
checkRegionSizes(mesh00, {5, 0, 5}, {0, 5, 5}, {3, 3});
}
-TEST(BoutMeshTest, TopologySOL2x2) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, TopologySOL2x2) {
{
SCOPED_TRACE("TopologySOL2x2, mesh00");
BoutMeshExposer mesh00(createSOL({3, 3, 1, 1, 2, 2, 0, 0}));
@@ -1725,9 +1647,7 @@ TEST(BoutMeshTest, TopologySOL2x2) {
}
}
-TEST(BoutMeshTest, TopologySOLPeriodicX2x2) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, TopologySOLPeriodicX2x2) {
{
SCOPED_TRACE("TopologySOLPeriodicX2x2, mesh00");
@@ -1766,9 +1686,7 @@ TEST(BoutMeshTest, TopologySOLPeriodicX2x2) {
}
}
-TEST(BoutMeshTest, TopologySingleNull2x3) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, TopologySingleNull2x3) {
{
SCOPED_TRACE("TopologySingleNull2x3, mesh00");
BoutMeshExposer mesh00(createSingleNull({3, 3, 1, 1, 2, 3, 0, 0}));
@@ -1824,9 +1742,7 @@ TEST(BoutMeshTest, TopologySingleNull2x3) {
}
}
-TEST(BoutMeshTest, TopologyDisconnectedDoubleNull1x6) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, TopologyDisconnectedDoubleNull1x6) {
{
SCOPED_TRACE("TopologyDisconnectedDoubleNull1x6, mesh00"); // Inner lower leg
BoutMeshExposer mesh00(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 0}));
@@ -1882,8 +1798,7 @@ TEST(BoutMeshTest, TopologyDisconnectedDoubleNull1x6) {
}
}
-TEST(BoutMeshTest, SetDerivedGridSizes) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, SetDerivedGridSizes) {
BoutMeshGridInfo grid{12, 3, 1, 2, 3, 6, 2, 2};
BoutMeshExposer mesh(createDisconnectedDoubleNull(grid));
@@ -1911,8 +1826,7 @@ TEST(BoutMeshTest, SetDerivedGridSizes) {
EXPECT_EQ(mesh.zend, 0);
}
-TEST(BoutMeshTest, CreateXBoundariesPeriodicX) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesPeriodicX) {
// Periodic in X, so no boundaries
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 3, 6, 1, 0}));
mesh.periodicX = true;
@@ -1922,8 +1836,7 @@ TEST(BoutMeshTest, CreateXBoundariesPeriodicX) {
EXPECT_TRUE(boundaries.empty());
}
-TEST(BoutMeshTest, CreateXBoundariesNoGuards) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesNoGuards) {
// No guards in X, so no boundaries
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 0, 1, 3, 6, 1, 0}));
mesh.createXBoundaries();
@@ -1932,8 +1845,7 @@ TEST(BoutMeshTest, CreateXBoundariesNoGuards) {
EXPECT_TRUE(boundaries.empty());
}
-TEST(BoutMeshTest, CreateXBoundariesDoubleNullInsidePF) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesDoubleNullInsidePF) {
// Three cores in X, inside core, one boundary
BoutMeshExposer mesh_inside(createDisconnectedDoubleNull({12, 3, 1, 1, 3, 6, 0, 0}));
mesh_inside.createXBoundaries();
@@ -1943,8 +1855,7 @@ TEST(BoutMeshTest, CreateXBoundariesDoubleNullInsidePF) {
EXPECT_EQ(boundaries_inside[0]->label, "pf");
}
-TEST(BoutMeshTest, CreateXBoundariesDoubleNullMiddlePF) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesDoubleNullMiddlePF) {
// Three cores in X, middle core, so no boundaries
BoutMeshExposer mesh_middle(createDisconnectedDoubleNull({12, 3, 1, 1, 3, 6, 1, 0}));
mesh_middle.createXBoundaries();
@@ -1953,8 +1864,7 @@ TEST(BoutMeshTest, CreateXBoundariesDoubleNullMiddlePF) {
EXPECT_TRUE(boundaries_middle.empty());
}
-TEST(BoutMeshTest, CreateXBoundariesDoubleNullOutsidePF) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesDoubleNullOutsidePF) {
// Three cores in X, outside core, one boundary
BoutMeshExposer mesh_inside(createDisconnectedDoubleNull({12, 3, 1, 1, 3, 6, 0, 0}));
mesh_inside.createXBoundaries();
@@ -1964,8 +1874,7 @@ TEST(BoutMeshTest, CreateXBoundariesDoubleNullOutsidePF) {
EXPECT_EQ(boundaries_inside[0]->label, "pf");
}
-TEST(BoutMeshTest, CreateXBoundariesDoubleNullInsideOutsideCore) {
- WithQuietOutput info{output_info};
+TEST_F(BoutMeshTest, CreateXBoundariesDoubleNullInsideOutsideCore) {
// One core in X, so we expect two boundaries
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 1}));
mesh.createXBoundaries();
@@ -1976,9 +1885,7 @@ TEST(BoutMeshTest, CreateXBoundariesDoubleNullInsideOutsideCore) {
EXPECT_EQ(boundaries[1]->label, "sol");
}
-TEST(BoutMeshTest, CreateYBoundariesNoGuards) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, CreateYBoundariesNoGuards) {
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 0, 1, 6, 0, 0}));
mesh.createYBoundaries();
@@ -1986,10 +1893,7 @@ TEST(BoutMeshTest, CreateYBoundariesNoGuards) {
EXPECT_TRUE(boundaries.empty());
}
-TEST(BoutMeshTest, CreateYBoundariesClosedFieldLines) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, CreateYBoundariesClosedFieldLines) {
BoutMeshExposer mesh(createCore({4, 4, 2, 2, 4, 4}));
mesh.createYBoundaries();
@@ -1997,9 +1901,7 @@ TEST(BoutMeshTest, CreateYBoundariesClosedFieldLines) {
EXPECT_TRUE(boundaries.empty());
}
-TEST(BoutMeshTest, CreateYBoundariesInnerLower) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, CreateYBoundariesInnerLower) {
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 0}));
mesh.createYBoundaries();
@@ -2008,9 +1910,7 @@ TEST(BoutMeshTest, CreateYBoundariesInnerLower) {
EXPECT_EQ(boundaries[0]->label, "lower_target");
}
-TEST(BoutMeshTest, CreateYBoundariesInnerUpper) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, CreateYBoundariesInnerUpper) {
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 2}));
mesh.createYBoundaries();
@@ -2019,9 +1919,7 @@ TEST(BoutMeshTest, CreateYBoundariesInnerUpper) {
EXPECT_EQ(boundaries[0]->label, "upper_target");
}
-TEST(BoutMeshTest, CreateYBoundariesOuterUpper) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, CreateYBoundariesOuterUpper) {
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 5}));
mesh.createYBoundaries();
@@ -2030,9 +1928,7 @@ TEST(BoutMeshTest, CreateYBoundariesOuterUpper) {
EXPECT_EQ(boundaries[0]->label, "upper_target");
}
-TEST(BoutMeshTest, CreateYBoundariesOuterLower) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, CreateYBoundariesOuterLower) {
BoutMeshExposer mesh(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 3}));
mesh.createYBoundaries();
@@ -2041,9 +1937,7 @@ TEST(BoutMeshTest, CreateYBoundariesOuterLower) {
EXPECT_EQ(boundaries[0]->label, "lower_target");
}
-TEST(BoutMestTest, PeriodicY) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, PeriodicY) {
BoutMeshExposer mesh00(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 0}));
EXPECT_FALSE(mesh00.periodicY(2));
EXPECT_FALSE(mesh00.periodicY(10));
@@ -2053,9 +1947,7 @@ TEST(BoutMestTest, PeriodicY) {
EXPECT_FALSE(mesh01.periodicY(10));
}
-TEST(BoutMestTest, PeriodicYWithShiftAngle) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, PeriodicYWithShiftAngle) {
const std::vector shift_angle = {-1., 11., 10., 9., 8., 7., 6.,
5., 4., 3., 2., 1., 0., -1.};
@@ -2076,9 +1968,7 @@ TEST(BoutMestTest, PeriodicYWithShiftAngle) {
EXPECT_EQ(twist_shift01, 0.);
}
-TEST(BoutMeshTest, NumberOfYBoundaries) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, NumberOfYBoundaries) {
BoutMeshExposer mesh_SOL(createSOL({3, 3, 1, 1, 2, 2, 1, 1}));
EXPECT_EQ(mesh_SOL.numberOfYBoundaries(), 1);
@@ -2086,9 +1976,7 @@ TEST(BoutMeshTest, NumberOfYBoundaries) {
EXPECT_EQ(mesh_DND.numberOfYBoundaries(), 2);
}
-TEST(BoutMeshTest, HasBranchCutLower) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, HasBranchCutLower) {
BoutMeshExposer mesh_SOL(createSOL({3, 3, 1, 1, 2, 2, 1, 1}));
EXPECT_EQ(mesh_SOL.hasBranchCutLower(2), std::make_pair(false, 0.));
@@ -2103,9 +1991,7 @@ TEST(BoutMeshTest, HasBranchCutLower) {
EXPECT_EQ(mesh_DND04.hasBranchCutLower(2), std::make_pair(false, 0.));
}
-TEST(BoutMeshTest, HasBranchCutUpper) {
- WithQuietOutput info{output_info};
-
+TEST_F(BoutMeshTest, HasBranchCutUpper) {
BoutMeshExposer mesh_SOL(createSOL({3, 3, 1, 1, 2, 2, 1, 1}));
EXPECT_EQ(mesh_SOL.hasBranchCutUpper(2), std::make_pair(false, 0.));
@@ -2120,10 +2006,7 @@ TEST(BoutMeshTest, HasBranchCutUpper) {
EXPECT_EQ(mesh_DND04.hasBranchCutUpper(2), std::make_pair(true, 10.));
}
-TEST(BoutMeshTest, GetPossibleBoundariesCore) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GetPossibleBoundariesCore) {
BoutMeshExposer mesh_core_1x1(createCore({12, 3, 1, 1, 1, 1, 0, 0}));
BoutMeshExposer mesh_core_32x64(createCore({12, 3, 1, 1, 32, 64, 7, 4}));
@@ -2133,10 +2016,7 @@ TEST(BoutMeshTest, GetPossibleBoundariesCore) {
EXPECT_EQ(mesh_core_32x64.getPossibleBoundaries(), boundaries);
}
-TEST(BoutMeshTest, GetPossibleBoundariesCorePeriodicX) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GetPossibleBoundariesCorePeriodicX) {
BoutMeshExposer mesh_core_1x1(createCore({12, 3, 1, 1, 1, 1, 0, 0}), true);
BoutMeshExposer mesh_core_32x64(createCore({12, 3, 1, 1, 32, 64, 7, 4}), true);
@@ -2144,10 +2024,7 @@ TEST(BoutMeshTest, GetPossibleBoundariesCorePeriodicX) {
EXPECT_TRUE(mesh_core_32x64.getPossibleBoundaries().empty());
}
-TEST(BoutMeshTest, GetPossibleBoundariesDND) {
- WithQuietOutput info{output_info};
- WithQuietOutput warn{output_warn};
-
+TEST_F(BoutMeshTest, GetPossibleBoundariesDND) {
BoutMeshExposer mesh_DND_1x6(createDisconnectedDoubleNull({12, 3, 1, 1, 1, 6, 0, 1}));
BoutMeshExposer mesh_DND_32x64(
createDisconnectedDoubleNull({12, 3, 1, 1, 32, 64, 0, 4}));
diff --git a/tests/unit/mesh/test_coordinates.cxx b/tests/unit/mesh/test_coordinates.cxx
index c5091b6599..fb400e593e 100644
--- a/tests/unit/mesh/test_coordinates.cxx
+++ b/tests/unit/mesh/test_coordinates.cxx
@@ -14,7 +14,9 @@ using bout::globals::mesh;
class CoordinatesTest : public FakeMeshFixture {
public:
using FieldMetric = Coordinates::FieldMetric;
- CoordinatesTest() : FakeMeshFixture() {}
+ WithQuietOutput info{output_info};
+ WithQuietOutput warn{output_warn};
+ WithQuietOutput progress{output_progress};
};
constexpr BoutReal default_dz{TWOPI / CoordinatesTest::nz};
@@ -133,9 +135,7 @@ TEST_F(CoordinatesTest, CalcContravariant) {
FieldMetric{0.0}}; // IntShiftTorsion
// No call to Coordinates::geometry() needed here
- output_info.disable();
coords.calcCovariant();
- output_info.enable();
EXPECT_TRUE(IsFieldEqual(coords.g_11, 1.0));
EXPECT_TRUE(IsFieldEqual(coords.g_22, 1.0));
@@ -168,9 +168,7 @@ TEST_F(CoordinatesTest, CalcCovariant) {
FieldMetric{0.0}}; // IntShiftTorsion
// No call to Coordinates::geometry() needed here
- output_info.disable();
coords.calcContravariant();
- output_info.enable();
EXPECT_TRUE(IsFieldEqual(coords.g11, 1.0));
EXPECT_TRUE(IsFieldEqual(coords.g22, 1.0));
@@ -182,11 +180,7 @@ TEST_F(CoordinatesTest, CalcCovariant) {
// #endif
TEST_F(CoordinatesTest, DefaultConstructor) {
- output_info.disable();
- output_warn.disable();
Coordinates coords(mesh);
- output_warn.enable();
- output_info.enable();
EXPECT_TRUE(IsFieldEqual(coords.dx, 1.0));
EXPECT_TRUE(IsFieldEqual(coords.dy, 1.0));
@@ -208,11 +202,7 @@ TEST_F(CoordinatesTest, ConstructWithMeshSpacing) {
static_cast(bout::globals::mesh)
->setGridDataSource(new FakeGridDataSource({{"dx", 2.0}, {"dy", 3.2}, {"dz", 42}}));
- output_info.disable();
- output_warn.disable();
Coordinates coords(mesh);
- output_warn.enable();
- output_info.enable();
EXPECT_TRUE(IsFieldEqual(coords.dx, 2.0));
EXPECT_TRUE(IsFieldEqual(coords.dy, 3.2));
@@ -233,12 +223,8 @@ TEST_F(CoordinatesTest, SmallMeshSpacing) {
static_cast(bout::globals::mesh)
->setGridDataSource(new FakeGridDataSource({{"dx", 1e-9}}));
- output_info.disable();
- output_warn.disable();
Coordinates coords(mesh);
EXPECT_THROW(coords.geometry(), BoutException);
- output_warn.enable();
- output_info.enable();
}
TEST_F(CoordinatesTest, ConstructWithDiagonalContravariantMetric) {
@@ -247,11 +233,7 @@ TEST_F(CoordinatesTest, ConstructWithDiagonalContravariantMetric) {
->setGridDataSource(
new FakeGridDataSource({{"g11", 2.0}, {"g22", 3.2}, {"g33", 42}}));
- output_info.disable();
- output_warn.disable();
Coordinates coords(mesh);
- output_warn.enable();
- output_info.enable();
// Didn't specify grid spacing, so default to 1
EXPECT_TRUE(IsFieldEqual(coords.dx, 1.0));
@@ -280,20 +262,12 @@ TEST_F(CoordinatesTest, NegativeJacobian) {
static_cast(bout::globals::mesh)
->setGridDataSource(new FakeGridDataSource({{"J", -1.0}}));
- output_info.disable();
- output_warn.disable();
EXPECT_THROW(Coordinates coords(mesh), BoutException);
- output_warn.enable();
- output_info.enable();
}
TEST_F(CoordinatesTest, NegativeB) {
static_cast(bout::globals::mesh)
->setGridDataSource(new FakeGridDataSource({{"Bxy", -1.0}}));
- output_info.disable();
- output_warn.disable();
EXPECT_THROW(Coordinates coords(mesh), BoutException);
- output_warn.enable();
- output_info.enable();
}
diff --git a/tests/unit/sys/test_timer.cxx b/tests/unit/sys/test_timer.cxx
index 7641c5f8cf..ed749c14f3 100644
--- a/tests/unit/sys/test_timer.cxx
+++ b/tests/unit/sys/test_timer.cxx
@@ -227,7 +227,6 @@ TEST(TimerTest, Cleanup) {
// Don't currently know why this test fails, and also causes segfault when unwinding the
// tests
-#if 1
TEST(TimerTest, ListAllInfo) {
Timer::cleanup();
@@ -245,33 +244,17 @@ TEST(TimerTest, ListAllInfo) {
Timer time_long{"18 characters long"};
}
- printf("Timer::resetTime\n");
Timer::resetTime("two");
-#if 0
std::streambuf* old_cout_rdbuf(std::cout.rdbuf());
std::stringstream cout_capture;
- cout_capture.str("");
- cout_capture.clear();
std::cout.rdbuf(cout_capture.rdbuf());
- printf("Timer printTimeReport\n");
Timer::printTimeReport();
- printf("Timer printTimeReport done\n");
std::cout.rdbuf(old_cout_rdbuf);
-#else
-
- std::stringstream cout_capture;
- std::streambuf* oldbuf = std::cout.rdbuf(cout_capture.rdbuf());
- Timer::printTimeReport();
- std::cout.rdbuf(oldbuf);
-
-#endif
- std::cerr << cout_capture.str();
using namespace ::testing;
EXPECT_THAT(cout_capture.str(), HasSubstr("Timer name |"));
EXPECT_THAT(cout_capture.str(), ContainsRegex("one *| 0\\.[0-9]+ | 1 | 0\\.[0-9]+"));
EXPECT_THAT(cout_capture.str(), ContainsRegex("two *| 0 * | 2 | 0\\.[0-9]+"));
}
-#endif
diff --git a/tests/unit/test_tmpfiles.hxx b/tests/unit/test_tmpfiles.hxx
index 6c37e7c792..db7387bb45 100644
--- a/tests/unit/test_tmpfiles.hxx
+++ b/tests/unit/test_tmpfiles.hxx
@@ -1,5 +1,6 @@
#pragma once
+#include
#include
#include
#include
@@ -30,7 +31,11 @@ public:
TempFile& operator=(const TempFile&) = delete;
TempFile& operator=(TempFile&&) = delete;
- ~TempFile() { std::filesystem::remove_all(filename); }
+ ~TempFile() {
+ if (std::uncaught_exceptions() <= 0) {
+ std::filesystem::remove_all(filename);
+ }
+ }
// Enable conversions to std::string / const char*
operator std::string() const { return filename.string(); }