Skip to content
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

Rename Positon -> Context, simplify class, fix things #1750

Merged
merged 23 commits into from
Nov 22, 2019
Merged

Conversation

bendudson
Copy link
Contributor

@bendudson bendudson commented Jun 16, 2019

Now more general than position, can contain other keys.

Renamed position.[ch]xx to generator_context.[ch]xx

Simplifying the Context (Position) class, so logic of cell location is handled in constructors only. Now passed around as const references to generators.

Removing some unneeded FieldGenerator code.

Now more general than position, can contain other keys.

Renamed `position.[ch]xx` to `generator-context.[ch]xx`

Simplifying the `Context` (`Position`) class, so logic of cell
location is handled in constructors only.
@bendudson bendudson added the work in progress Not ready for merging label Jun 16, 2019
Copy link
Contributor

@dschwoerer dschwoerer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure Context is a good description, imho it is to generic, context can be anything.

As it always holds the position, and potentially some additional information, thus I would prefere Position.

src/mesh/generator-context.cxx Outdated Show resolved Hide resolved
pos.setY(y);
pos.setZ(z);
return pos;
Context LegacyPosition(BoutReal x, BoutReal y, BoutReal z, BoutReal t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be LegacyContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes probably, thanks! Once the name is settled this can be modified. I'm not sure about testing legacy uses of the code though, and would prefer to test ways that the code is intended to be used.

@@ -49,7 +45,7 @@ class BinaryGenerator : public FieldGenerator {
return std::make_shared<BinaryGenerator>(args.front(), args.back());
}

BoutReal generate(Position pos) {
BoutReal generate(const Context& pos) override {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we rename Position to Context - should pos be renamed to con or context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes probably, but that was harder to search and replace.

@bendudson
Copy link
Contributor Author

Thanks @dschwoerer . For the name I'd be happy with something else. I agree that Position is quite descriptive, but is also a bit generic. Can revert easily if its agreed that Position is better. Other suggestions welcome.

Replace `FieldSin` and similar with use of `FieldGenOneArg`

Add a `std::string name` attribute to `FieldGenOneArg` and `FieldGenTwoArgs`
so that a useful description can be printed.
@bendudson bendudson changed the title WIP: Rename Positon -> Context, simplify class Rename Positon -> Context, simplify class, fix things Jun 17, 2019
Mosly introduced when changing generators to `Context`/`Position`:
Neumann boundary conditions need a factor of the grid spacing to be
included when generating a value.

A couple of copy-paste bugs in applying Neumann boundaries to
`Field2D` objects: `dx` used rather than `dy`. More tests needed on
boundary conditions.
Namespacing so that the meaning and purpose of the class is clearer.

Also moved `generator_context.cxx` from `mesh` into `sys` to follow
structure of header file location.
Add `using bout::generator::Context` to unit tests.

Rename `LegacyPosition` to `LegacyContext`
Enables more clear swiching than the H(x) Heaviside function

Like the C++ functions in BOUT++, one of two expressions is evaluated,
depending on the sign of the first expression.
Allows the definition of new scopes with local variables,
by setting values in the `Context` object.

One use is to simplify expressions using local variables, for
efficiency and readability e.g. ensuring that a value is positive:
```
positive_value = H(expression) * expression
```
where the expression would be evaluated twice. This can be replaced by:
```
positive_value = [value = expression]( H({value}) * {value} )
```
This mechanism can also be used to implement simple functions
```
mycosh = 0.5 * (exp({arg}) + exp(-{arg}))
```
which can be called by defining a new Context:
```
result = [arg = x*2](mycosh)
```
(sort-of a dynamic scope system)

so we could write:
```
floor = H({arg}) * {arg}
positive_value = [arg = expression](floor)
```
Some code not recompiled previously, now updated.
Another test defining two variables in a `Context` object.
Long expressions can become hard to read in the options file.
This adopts the Python approach, where if there are unbalanced
brackets ('()' or '[]') then the expression continues on the next
line.

In the BOUT.inp file we can therefore write

```
value = (something
         + more
         - things)
```

or define complex expression using a Context scope:
```
result = [a = expression,
          b = something](
            {a} + {b})
```
Enables a simple kind of loop, but one which is guaranteed to finish.
Iterates a given symbol from 0 to count-1, evaluating and summing
a given expression.
Using parseExpression captures the rest of the string,
rather than just the next expression. Instead call
parseParenExpr to stop when parentheses close.

Added tests to reproduce this.
By default recursive expressions are not allowed in the input options.
What is committed here adds an input option to allow recursion:
```
[input]
max_recursion_depth = 10  # 0 = none, -1 = unlimited
```
By putting a limit on the depth we avoid the halting problem at least,
and expressions should (eventually) terminate, preferably before they
overflow the stack.

As is traditional, I present to you the Fibonacci sequence:
```
fib = where({n} - 2.5,
            [n={n}-1](fib) + [n={n}-2](fib),
            1)
```
so if `n` = 1 or 2 then `fib` = 1, but if `n` = 3 or above then the
recursion fun begins.

And another ill-considered language is born.
`FieldFactory` reads `input:max_recursion_depth` as an int. `Options`
then creates a `FieldFactory` to parse the string to an int.

This change uses `std::stoi` to do the string conversion. This means
no fancy expressions in this parameter, but that should not be needed.
Documenting new features for expressions, and some examples of how to
use them. Some of the existing documentation was out of date from
earlier changes.
Slight efficiency improvement when repeatedly iterating over
@bendudson bendudson removed the work in progress Not ready for merging label Jul 22, 2019
@d7919 d7919 changed the title Rename Positon -> Context, simplify class, fix things 6ename Positon -> Context, simplify class, fix things Aug 6, 2019
@d7919 d7919 changed the title 6ename Positon -> Context, simplify class, fix things Rename Positon -> Context, simplify class, fix things Oct 24, 2019
Codacy would like several constructors to be explicit. Two
of these (FieldIndirect and FieldGenOneArg) take strings,
so it is useful to enable these to take `const char*` arguments.
@bendudson bendudson merged commit 7e78a51 into ynorm2 Nov 22, 2019
@bendudson bendudson deleted the ynorm2-simplify branch November 22, 2019 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants