-
Notifications
You must be signed in to change notification settings - Fork 104
Add ability to use variables from grid file in input file expressions #3222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Changes from all commits
e5f91f1
80b0169
77420d1
ca7f727
f9c616b
4034481
aa963d6
4985b3c
47b852f
dc80694
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,20 +19,28 @@ | |
| * along with BOUT++. If not, see <http://www.gnu.org/licenses/>. | ||
| * | ||
| **************************************************************************/ | ||
| #include <bout/globals.hxx> | ||
|
|
||
| #include <bout/field_factory.hxx> | ||
|
|
||
| #include <cmath> | ||
|
|
||
| #include <bout/bout_enum_class.hxx> | ||
| #include <bout/bout_types.hxx> | ||
| #include <bout/boutexception.hxx> | ||
| #include <bout/constants.hxx> | ||
| #include <bout/field2d.hxx> | ||
| #include <bout/field3d.hxx> | ||
| #include <bout/fieldperp.hxx> | ||
| #include <bout/globals.hxx> | ||
| #include <bout/output.hxx> | ||
| #include <bout/sys/expressionparser.hxx> | ||
| #include <bout/traits.hxx> | ||
| #include <bout/utils.hxx> | ||
|
|
||
| #include "bout/constants.hxx" | ||
|
|
||
| #include "fieldgenerators.hxx" | ||
|
|
||
| #include <cmath> | ||
| #include <memory> | ||
| #include <string> | ||
|
|
||
| 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<FieldValuePtr>(ptr); | ||
| } | ||
|
|
||
| BOUT_ENUM_CLASS(GridVariableFunction, field3d, field2d, boutreal); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'GridVariableFunctionFromString' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage] BOUT_ENUM_CLASS(GridVariableFunction, field3d, field2d, boutreal);
^expanded from here
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: parameter 'UNUSED_similar_to' is unused [misc-unused-parameters] BOUT_ENUM_CLASS(GridVariableFunction, field3d, field2d, boutreal);
^Additional contextinclude/bout/bout_enum_class.hxx:98: expanded from macro 'BOUT_ENUM_CLASS' inline enumname Options::as<enumname>(const enumname&) const { \
^ |
||
|
|
||
| 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 <class T> | ||
| auto add_grid_variable(FieldFactory& factory, Mesh& mesh, const std::string& name) { | ||
| T var; | ||
| mesh.get(var, name); | ||
| factory.addGenerator(name, std::make_shared<GridVariable<T>>(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<std::string>(); | ||
| throw BoutException( | ||
| "Grid file '{}' missing `{}` specified in `input:grid_variables`", filename, | ||
| name); | ||
| } | ||
|
|
||
| const auto func = value.as<GridVariableFunction>(); | ||
| switch (func) { | ||
| case GridVariableFunction::field3d: | ||
| add_grid_variable<Field3D>(factory, mesh, name); | ||
| break; | ||
| case GridVariableFunction::field2d: | ||
| add_grid_variable<Field2D>(factory, mesh, name); | ||
| break; | ||
| case GridVariableFunction::boutreal: | ||
| BoutReal var{}; | ||
| mesh.get(var, name); | ||
| factory.addGenerator(name, std::make_shared<FieldValue>(var)); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| } // namespace | ||
|
|
||
| ////////////////////////////////////////////////////////// | ||
|
|
@@ -176,6 +228,9 @@ FieldFactory::FieldFactory(Mesh* localmesh, Options* opt) | |
|
|
||
| // Where switch function | ||
| addGenerator("where", std::make_shared<FieldWhere>(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, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,9 +9,13 @@ | |||||
|
|
||||||
| #include <bout/boutexception.hxx> | ||||||
| #include <bout/field_factory.hxx> | ||||||
| #include <bout/sys/expressionparser.hxx> | ||||||
| #include <bout/traits.hxx> | ||||||
| #include <bout/unused.hxx> | ||||||
|
|
||||||
| #include <cmath> | ||||||
| #include <memory> | ||||||
| #include <string> | ||||||
|
|
||||||
| ////////////////////////////////////////////////////////// | ||||||
| // Generators from values | ||||||
|
|
@@ -352,4 +356,29 @@ private: | |||||
| FieldGeneratorPtr test, gt0, lt0; | ||||||
| }; | ||||||
|
|
||||||
| /// A `Field3D` that can be used in expressions | ||||||
| template <class T, typename = bout::utils::EnableIfField<T>> | ||||||
| class GridVariable : public FieldGenerator { | ||||||
| public: | ||||||
| GridVariable(T var, std::string name) | ||||||
| : variable(std::move(var)), name(std::move(name)) {} | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "std::move" is directly included [misc-include-cleaner] src/field/fieldgenerators.hxx:18: + #include <utility> |
||||||
|
|
||||||
| double generate(const bout::generator::Context& ctx) override { | ||||||
| return variable(ctx.ix(), ctx.jy(), ctx.kz()); | ||||||
| } | ||||||
|
|
||||||
| FieldGeneratorPtr clone(const std::list<FieldGeneratorPtr> args) override { | ||||||
| if (args.size() != 0) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
Suggested change
Additional context/usr/include/c++/13/bits/stl_list.h:1142: method 'list'::empty() defined here empty() const _GLIBCXX_NOEXCEPT
^ |
||||||
| throw ParseException("Variable '{}' takes no arguments but got {:d}", args.size()); | ||||||
| } | ||||||
| return std::make_shared<GridVariable<T>>(variable, name); | ||||||
| } | ||||||
|
|
||||||
| std::string str() const override { return name; } | ||||||
|
|
||||||
| private: | ||||||
| T variable; | ||||||
| std::string name; | ||||||
| }; | ||||||
|
|
||||||
| #endif // BOUT_FIELDGENERATORS_H | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: enum 'GridVariableFunction' uses a larger base type ('int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size]
BOUT_ENUM_CLASS(GridVariableFunction, field3d, field2d, boutreal); ^