-
Notifications
You must be signed in to change notification settings - Fork 90
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
Allow user to override library option defaults #1773
Conversation
Looks useful but I'm not terribly comfortable adding functionality to |
I wonder if there's an alternative design for this kind of feature, where the user could put some code to 'register' a default for an option, a bit like |
Ah, yes! Can probably be done if // Inside anonymous namespace because we don't want it to be a real global value
namespace {
const auto mydefault = Options::root()["mesh"]["staggergrids"].overrideDefault(true);
} Putting that outside of main should be sufficient as it would initialise #define BOUT_USER_OVERRIDE_DEFAULT_OPTION(option, value) \
namespace { const auto user_default ## __FILE__ ## __LINE__ = \
Options::root() option .overrideDefault(value) }
BOUT_USER_OVERRIDE_DEFAULT_OPTION(["mesh"]["staggergrids"], true) (note: completely untested and also horrible) The gross thing there is the option has to be passed in as indexing, which would be super easy to break. Could be done if we could make |
Making Options handle I've added a macro as @ZedThree suggested to override defaults, and reverted the changes to I've also added the |
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.
Looks good! Please could you also add a unit test for overrideDefault?
tests/unit/sys/test_options.cxx
Outdated
ASSERT_TRUE(options.isSection("")); | ||
ASSERT_FALSE(options.isSection("subsection")); | ||
|
||
options["subsection:testkey"] = 1.; |
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.
Please could you change "testkey" and 1.
here? I get nervous when test values could potentially clash!
include/options.hxx
Outdated
@@ -473,6 +473,23 @@ public: | |||
return val; | |||
} | |||
|
|||
/// Allow the user to override defaults set later, intended to be called in | |||
/// methods overriding PhysicsModel::setDefaults. |
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.
Comment is out of date
Allows user to set a custom default for an option, as long as the method is called before the option is fetched using withDefault(). Will support a macro to allow users to override any library defaults.
The value of the option will be output where it is used, so output from overrideDefault is just duplication.
The overrideDefault method should not be used to get the value of an option - it does not make sense to do so because there is already the withDefault method. So there is no need to return a value from the method - removing the return reduces the number of lines in the method and avoids potential confusion about where it should be used. Also do not set value_used=true in overrideDefault, since it is possible that the value might never be used (unlike in withDefault).
Allow sections to be given in the string, separated with ":", e.g. Options::root()["section:subsection:myopt"]
Allows global variable to be created so that overrideDefault() can be called before main(), allowing the user to change library default options before they are used.
BOUT_OVERRIDE_DEFAULT_OPTION(name, value) can be called in global namespace to override the default for the option "name".
Prevents errors from calls like options["somekey"].overrideDefault("string_value");
10be47c
to
bb1c95b
Compare
Previously communicateXZ() actually communicated in the y-direction as well, the only difference with communicate() was that it did not apply the twist-shift. Since sendX() method was added, can now actually change the implementation to communicate only in X.
In STORM we've started doing something like this to change the defaults for options (e.g. boundary conditions) that should always be set a certain way for a certain physics model, so that we don't have to have so many things in the input file
This PR is intended to allow this to be done for more options, by adding a static method
PhysicsModel::setDefaults()
that user physics model can override. This method is called inBOUTMAIN
just after the options are read, and beforeMesh
, etc. are created. Also adds a convenience method for overriding defaults. So with this PR we can do something liketo make
mesh:staggergrids
default to true rather than false.Comments on the design very welcome!
Note: it is important to use a reference
auto& options
rather than a copy so the options that are changed are changed in the global options. I thought about removing the copy constructor fromOptions
soauto options = Options::root()
would be an error and prevent this mistake - it seems to me like it would be nice but unfortunatelystd::map
usesstd::pair
andstd::pair
requires a copy constructor, although this might change in C++17 https://stackoverflow.com/questions/23723744/stdpair-too-restrictive-constructor