-
Notifications
You must be signed in to change notification settings - Fork 107
New Y-Boundaries for unified sheath code #3308
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
ae1f285
b9b42ff
9bdfef5
c51a85f
06d581b
7f1d26f
84f8c83
ea05bae
17f8efa
0db3052
d2f2cc8
1f48a59
4af5a4d
e5fbcaf
ef7b03d
6dba751
f105c3f
f7c1aca
55bdbcf
6f40b4e
36c1f94
c7cbf11
f9cad29
e6f004b
3a0f214
4e21aac
3a850b1
e0f80cf
101f33d
4ea1657
c78dd6e
6fadc06
2129820
7fc08a3
e135545
73e4183
4c105b8
41f9b28
e1364b3
2edebb3
3821205
38293b9
6ae2351
576c609
1b99b34
ff190e8
6aac834
d5fb4c4
4b503c5
e9a0944
c59626a
2c4179d
7178646
7975518
4ee3d9d
44fd331
e94bb27
f26bbfb
52cb85a
a367a21
6d72a7e
138f20b
5968f13
ade82b7
8872cd2
32078e2
cdf9b13
5690fd2
abb322f
5f127e1
4cfbb16
30298ca
db5d3aa
c67ae87
9558cca
8d7fbd1
6729983
38e3edb
6051461
d170774
20d61c4
399d219
eaac193
372fbe7
2dfa950
1ff62a4
afe1909
6d18997
ad0f14e
f0e6f28
92569dd
42836ef
ceb557a
72cd8a4
b38fdf3
898d191
56d9a60
8eb1270
2aebc13
08fd6a7
4423d20
9a366a9
30da9d6
90032b6
7086969
e8c699d
38e5f20
da4ea6a
84c7f7e
4880e01
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 | ||
|---|---|---|---|---|
| @@ -0,0 +1,231 @@ | ||||
| #pragma once | ||||
|
|
||||
| #include "bout/assert.hxx" | ||||
| #include "bout/bout_types.hxx" | ||||
| #include "bout/build_defines.hxx" | ||||
| #include "bout/field2d.hxx" | ||||
| #include "bout/field3d.hxx" | ||||
| #include "bout/mesh.hxx" | ||||
| #include "bout/parallel_boundary_region.hxx" | ||||
| #include "bout/region.hxx" | ||||
| #include "bout/sys/parallel_stencils.hxx" | ||||
| #include "bout/sys/range.hxx" | ||||
| #include <algorithm> | ||||
| #include <functional> | ||||
|
|
||||
|
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: included header utility is not used directly [misc-include-cleaner]
Suggested change
|
||||
| class BoundaryRegionIter { | ||||
|
dschwoerer marked this conversation as resolved.
dschwoerer marked this conversation as resolved.
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: class 'BoundaryRegionIter' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] class BoundaryRegionIter {
^
Member
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.
Member
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. I guess ideally this would be templated on the direction (X or Y)
Contributor
Author
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. Does it need to be templated? It could also just be generic without templating? |
||||
| public: | ||||
| virtual ~BoundaryRegionIter() = default; | ||||
| BoundaryRegionIter(int x, int y, int bx, int by, const Mesh& mesh) | ||||
| : _dir(bx + by), _x(x), _y(y), _bx(bx), _by(by), localmesh(&mesh) { | ||||
| ASSERT3(_bx * _by == 0); | ||||
| } | ||||
| bool operator!=(const BoundaryRegionIter& rhs) const { return ind() != rhs.ind(); } | ||||
|
|
||||
| Ind3D ind() const { return xyz2ind(_x, _y, _z); } | ||||
| BoundaryRegionIter& operator++() { | ||||
| ASSERT3(_z < nz()); | ||||
| _z++; | ||||
| if (_z == nz()) { | ||||
| _z = 0; | ||||
| _next(); | ||||
| } | ||||
| return *this; | ||||
| } | ||||
|
|
||||
| protected: | ||||
| virtual void _next() = 0; | ||||
|
ZedThree marked this conversation as resolved.
|
||||
|
|
||||
| public: | ||||
| BoundaryRegionIter& operator*() { return *this; } | ||||
|
|
||||
| void dirichlet_o2(Field3D& f, BoutReal value) const { | ||||
|
dschwoerer marked this conversation as resolved.
dschwoerer marked this conversation as resolved.
Member
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. Do these need to be implemented as methods, or can they be free functions? Having them as methods makes it more difficult to extend and add new functions. They also all need docstrings, some of these are very non-obvious! |
||||
| ynext(f) = bout::parallel_stencil::dirichlet_o2(1, f[ind()], 0.5, value); | ||||
| } | ||||
|
|
||||
| BoutReal extrapolate_grad_o2(const Field3D& f) const { return f[ind()] - yprev(f); } | ||||
|
|
||||
| BoutReal extrapolate_sheath_o2(const Field3D& f) const { | ||||
| return (f[ind()] * 3 - yprev(f)) * 0.5; | ||||
| } | ||||
|
|
||||
| BoutReal extrapolate_next_o2(const Field3D& f) const { | ||||
| return (2 * f[ind()]) - yprev(f); | ||||
| } | ||||
|
|
||||
| BoutReal | ||||
| extrapolate_next_o2(const std::function<BoutReal(int yoffset, Ind3D ind)>& f) const { | ||||
|
dschwoerer marked this conversation as resolved.
|
||||
| return (2 * f(0, ind())) - f(0, ind().yp(-_by).xp(-_bx)); | ||||
| } | ||||
|
|
||||
| BoutReal interpolate_sheath_o2(const Field3D& f) const { | ||||
| return (f[ind()] + ynext(f)) * 0.5; | ||||
| } | ||||
|
|
||||
| BoutReal | ||||
| interpolate_sheath_o2(const std::function<BoutReal(int yoffset, Ind3D ind)>& f) const { | ||||
| return (f(0, ind()) + f(0, ind().yp(-_by).xp(-_bx))) * 0.5; | ||||
| } | ||||
|
|
||||
| BoutReal | ||||
| extrapolate_sheath_o2(const std::function<BoutReal(int yoffset, Ind3D ind)>& f) const { | ||||
| return 0.5 * (3 * f(0, ind()) - f(0, ind().yp(-_by).xp(-_bx))); | ||||
| } | ||||
|
|
||||
| BoutReal extrapolate_sheath_free(const Field3D& f, SheathLimitMode mode) const { | ||||
| const BoutReal fac = | ||||
| bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f), mode); | ||||
| const BoutReal val = ythis(f); | ||||
| const BoutReal next = mode == SheathLimitMode::linear_free ? val + fac : val * fac; | ||||
| return 0.5 * (val + next); | ||||
| } | ||||
|
|
||||
| void set_free(Field3D& f, SheathLimitMode mode) const { | ||||
| const BoutReal fac = | ||||
| bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f), mode); | ||||
| BoutReal val = ythis(f); | ||||
| if (mode == SheathLimitMode::linear_free) { | ||||
| for (int i = 1; i <= localmesh->ystart; ++i) { | ||||
| val += fac; | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } else { | ||||
| for (int i = 1; i <= localmesh->ystart; ++i) { | ||||
| val *= fac; | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } | ||||
| } | ||||
|
|
||||
| void limitFree(Field3D& f) const { | ||||
| const BoutReal fac = | ||||
| bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f)); | ||||
| BoutReal val = ythis(f); | ||||
| for (int i = 1; i <= localmesh->ystart; ++i) { | ||||
| val *= fac; | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } | ||||
|
|
||||
| bool is_lower() const { | ||||
| ASSERT2(_bx == 0); | ||||
| return _by == -1; | ||||
| } | ||||
|
|
||||
| void neumann_o1(Field3D& f, BoutReal grad) const { | ||||
| BoutReal val = ythis(f); | ||||
| for (int i = 1; i <= localmesh->ystart; ++i) { | ||||
| val += grad; | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } | ||||
|
|
||||
| void neumann_o2(Field3D& f, BoutReal grad) const { | ||||
| BoutReal val = yprev(f) + grad; | ||||
| for (int i = 1; i <= localmesh->ystart; ++i) { | ||||
| val += grad; | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } | ||||
|
|
||||
| void limit_at_least(Field3D& f, BoutReal value) const { | ||||
| ynext(f) = std::max(ynext(f), value); | ||||
|
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::max" is directly included [misc-include-cleaner] include/bout/boundary_iterator.hxx:12: - #include <functional>
+ #include <algorithm>
+ #include <functional> |
||||
| } | ||||
|
|
||||
| BoutReal& ynext(Field3D& f) const { return f[ind().yp(_by).xp(_bx)]; } | ||||
| const BoutReal& ynext(const Field3D& f) const { return f[ind().yp(_by).xp(_bx)]; } | ||||
| BoutReal& yprev(Field3D& f) const { return f[ind().yp(-_by).xp(-_bx)]; } | ||||
| const BoutReal& yprev(const Field3D& f) const { return f[ind().yp(-_by).xp(-_bx)]; } | ||||
| BoutReal& ythis(Field3D& f) const { return f[ind()]; } | ||||
| const BoutReal& ythis(const Field3D& f) const { return f[ind()]; } | ||||
|
|
||||
| void setYPrevIfValid(Field3D& f, BoutReal val) const { yprev(f) = val; } | ||||
| void setAll(Field3D& f, const BoutReal val) const { | ||||
| for (int i = -localmesh->ystart; i <= localmesh->ystart; ++i) { | ||||
| f[ind().yp(_by * i).xp(_bx * i)] = val; | ||||
| } | ||||
| } | ||||
|
|
||||
| static int abs_offset() { return 1; } | ||||
|
|
||||
| BoutReal& ynext(Field2D& f) const { return f[ind().yp(_by).xp(_bx)]; } | ||||
| const BoutReal& ynext(const Field2D& f) const { return f[ind().yp(_by).xp(_bx)]; } | ||||
| BoutReal& yprev(Field2D& f) const { return f[ind().yp(-_by).xp(-_bx)]; } | ||||
| const BoutReal& yprev(const Field2D& f) const { return f[ind().yp(-_by).xp(-_bx)]; } | ||||
|
|
||||
| int dir() const { return _dir; } | ||||
|
|
||||
| protected: | ||||
| int x() const { return _x; } | ||||
| int y() const { return _y; } | ||||
| int z() const { return _z; } | ||||
|
|
||||
| protected: | ||||
| void setx(int x) { _x = x; } | ||||
| void sety(int y) { _y = y; } | ||||
|
|
||||
| private: | ||||
| int _dir; | ||||
|
|
||||
| int _z{0}; | ||||
| int _x; | ||||
| int _y; | ||||
| int _bx; | ||||
| int _by; | ||||
|
|
||||
| const Mesh* localmesh; | ||||
| int nx() const { return localmesh->LocalNx; } | ||||
| int ny() const { return localmesh->LocalNy; } | ||||
| int nz() const { return localmesh->LocalNz; } | ||||
|
|
||||
| Ind3D xyz2ind(int x, int y, int z) const { | ||||
| return Ind3D{((x * ny() + y) * nz()) + z, ny(), nz()}; | ||||
| } | ||||
| }; | ||||
|
|
||||
| class BoundaryRegionIterY : public BoundaryRegionIter { | ||||
|
dschwoerer marked this conversation as resolved.
dschwoerer marked this conversation as resolved.
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: class 'BoundaryRegionIterY' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] class BoundaryRegionIterY : public BoundaryRegionIter {
^ |
||||
| public: | ||||
| ~BoundaryRegionIterY() override = default; | ||||
| BoundaryRegionIterY(const RangeIterator& r, int y, int dir, bool is_end, | ||||
| const Mesh& mesh) | ||||
| : BoundaryRegionIter(r.ind, y, 0, dir, mesh), r(r), is_end(is_end) {} | ||||
|
|
||||
| bool operator!=(const BoundaryRegionIterY& rhs) { | ||||
| ASSERT2(y() == rhs.y()); | ||||
| if (is_end) { | ||||
| if (rhs.is_end) { | ||||
| return false; | ||||
| } | ||||
| return !rhs.r.isDone(); | ||||
| } | ||||
| if (rhs.is_end) { | ||||
| return !r.isDone(); | ||||
| } | ||||
| return x() != rhs.x(); | ||||
| } | ||||
|
|
||||
| void _next() override { | ||||
| ++r; | ||||
| setx(r.ind); | ||||
| } | ||||
|
|
||||
| private: | ||||
| RangeIterator r; | ||||
| bool is_end; | ||||
| }; | ||||
|
|
||||
| class NewBoundaryRegionY { | ||||
| public: | ||||
| NewBoundaryRegionY(const Mesh& mesh, bool lower, const RangeIterator& r) | ||||
| : mesh(&mesh), lower(lower), r(r) {} | ||||
| BoundaryRegionIterY begin(bool begin = true) { | ||||
| return BoundaryRegionIterY(r, lower ? mesh->ystart : mesh->yend, lower ? -1 : +1, | ||||
| !begin, *mesh); | ||||
| } | ||||
| BoundaryRegionIterY end() { return begin(false); } | ||||
|
|
||||
| private: | ||||
| const Mesh* mesh; | ||||
| bool lower; | ||||
| RangeIterator r; | ||||
| }; | ||||
Uh oh!
There was an error while loading. Please reload this page.