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(); }