-
Notifications
You must be signed in to change notification settings - Fork 104
PETSc XZHermiteSpline #2917
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
Open
ZedThree
wants to merge
14
commits into
next
Choose a base branch
from
petsc-xzhermitespline
base: next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
PETSc XZHermiteSpline #2917
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
6ee9f74
Simplify XZInterpolation class
bendudson 936cd55
Moving registration to header
bendudson 2dc3967
Merge branch 'next' into petsc-interpolation
ZedThree 0cdb962
Make interpolation registration variables `const inline`
ZedThree 86ee8be
Fix issue with overload hiding base virtual functions
ZedThree cb8b550
Make `lagrange_4pt` interpolation function a static free function
ZedThree b9cbb52
Add `PetscXZHermiteSpline` that can be split in x direction
ZedThree 183c7a2
WIP: Switch `PetscXZHermiteSpline` to use `PetscMatrix` for weights
ZedThree 39bef1c
Fix headers when building without PETSc
ZedThree 654f605
Apply clang-format changes
ZedThree c453dee
Add a simplified `GlobalIndexer` needed for `PetscXZHermiteSpline`
ZedThree 05e4d8c
Use `PetscMatrix` interface for `PetscXZHermiteSpline`
ZedThree bf90b1d
Fix a bunch of clang-tidy warnings
ZedThree b7f5b94
Remove recursive check
ZedThree File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,7 @@ | ||
| /************************************************************************** | ||
| * Copyright 2010-2020 B.D.Dudson, S.Farley, P. Hill, J.T. Omotani, J.T. Parker, | ||
| * M.V.Umansky, X.Q.Xu | ||
| * Copyright 2010-2024 BOUT++ contributors | ||
| * | ||
| * Contact: Ben Dudson, [email protected] | ||
| * Contact: Ben Dudson, [email protected] | ||
| * | ||
| * This file is part of BOUT++. | ||
| * | ||
|
|
@@ -24,7 +23,12 @@ | |
| #ifndef BOUT_INTERP_XZ_H | ||
| #define BOUT_INTERP_XZ_H | ||
|
|
||
| #include "bout/build_defines.hxx" | ||
| #include "bout/field3d.hxx" | ||
| #include "bout/globalindexer.hxx" | ||
| #include "bout/mask.hxx" | ||
| #include "bout/petsc_interface.hxx" | ||
| #include "bout/petsclib.hxx" | ||
|
|
||
| class Options; | ||
|
|
||
|
|
@@ -95,20 +99,30 @@ public: | |
| ASSERT1(has_region); | ||
| return getRegion(); | ||
| } | ||
| /// Calculate weights using given offsets in X and Z | ||
| virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") = 0; | ||
| virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") = 0; | ||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") { | ||
| setMask(mask); | ||
| calcWeights(delta_x, delta_z, region); | ||
| } | ||
|
|
||
| /// Use pre-calculated weights | ||
| virtual Field3D interpolate(const Field3D& f, | ||
| const std::string& region = "RGN_NOBNDRY") const = 0; | ||
| virtual Field3D interpolate(const Field3D& f, const Field3D& delta_x, | ||
| const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") = 0; | ||
| virtual Field3D interpolate(const Field3D& f, const Field3D& delta_x, | ||
| const Field3D& delta_z, const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") = 0; | ||
|
|
||
| /// Calculate weights then interpolate | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") { | ||
| calcWeights(delta_x, delta_z, region); | ||
| return interpolate(f, region); | ||
| } | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const BoutMask& mask, const std::string& region = "RGN_NOBNDRY") { | ||
| calcWeights(delta_x, delta_z, mask, region); | ||
| return interpolate(f, region); | ||
| } | ||
|
|
||
| // Interpolate using the field at (x,y+y_offset,z), rather than (x,y,z) | ||
| void setYOffset(int offset) { y_offset = offset; } | ||
|
|
@@ -162,18 +176,10 @@ public: | |
|
|
||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
|
|
||
| // Use precalculated weights | ||
| Field3D interpolate(const Field3D& f, | ||
| const std::string& region = "RGN_NOBNDRY") const override; | ||
| // Calculate weights and interpolate | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
|
|
||
| std::vector<ParallelTransform::PositionsAndWeights> | ||
| getWeightsForYApproximation(int i, int j, int k, int yoffset) override; | ||
| }; | ||
|
|
@@ -218,21 +224,12 @@ public: | |
|
|
||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
|
|
||
| using XZInterpolation::interpolate; | ||
|
|
||
| // Use precalculated weights | ||
| Field3D interpolate(const Field3D& f, | ||
| const std::string& region = "RGN_NOBNDRY") const override; | ||
| // Calculate weights and interpolate | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| BoutReal lagrange_4pt(BoutReal v2m, BoutReal vm, BoutReal vp, BoutReal v2p, | ||
| BoutReal offset) const; | ||
| BoutReal lagrange_4pt(const BoutReal v[], BoutReal offset) const; | ||
| }; | ||
|
|
||
| class XZBilinear : public XZInterpolation { | ||
|
|
@@ -251,19 +248,68 @@ public: | |
|
|
||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, | ||
|
|
||
| using XZInterpolation::interpolate; | ||
|
|
||
| // Use precalculated weights | ||
| Field3D interpolate(const Field3D& f, | ||
| const std::string& region = "RGN_NOBNDRY") const override; | ||
| }; | ||
|
|
||
| #if BOUT_HAS_PETSC | ||
| class PetscXZHermiteSpline : public XZInterpolation { | ||
| PetscLib petsclib; | ||
| IndexerPtr<Field3D> indexer; | ||
| PetscMatrix<Field3D> weights; | ||
|
|
||
| Tensor<Field3D::ind_type> i_corner; // x-index of bottom-left grid point | ||
| Tensor<int> k_corner; // z-index of bottom-left grid point | ||
|
|
||
| // Basis functions for cubic Hermite spline interpolation | ||
| // see http://en.wikipedia.org/wiki/Cubic_Hermite_spline | ||
| // The h00 and h01 basis functions are applied to the function itself | ||
| // and the h10 and h11 basis functions are applied to its derivative | ||
| // along the interpolation direction. | ||
| Field3D h00_x; | ||
| Field3D h01_x; | ||
| Field3D h10_x; | ||
| Field3D h11_x; | ||
| Field3D h00_z; | ||
| Field3D h01_z; | ||
| Field3D h10_z; | ||
| Field3D h11_z; | ||
|
Comment on lines
+268
to
+280
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. They should only be used in the constructor, so no need to keep them around |
||
|
|
||
| public: | ||
| PetscXZHermiteSpline(int y_offset = 0, Mesh* mesh = nullptr); | ||
| PetscXZHermiteSpline(Mesh* mesh = nullptr) : PetscXZHermiteSpline(0, mesh) {} | ||
| PetscXZHermiteSpline(const BoutMask& mask, int y_offset = 0, Mesh* mesh = nullptr) | ||
| : PetscXZHermiteSpline(y_offset, mesh) { | ||
| region = regionFromMask(mask, localmesh); | ||
| } | ||
| PetscXZHermiteSpline(const PetscXZHermiteSpline& other) = delete; | ||
| PetscXZHermiteSpline(PetscXZHermiteSpline&& other) = default; | ||
| PetscXZHermiteSpline& operator=(const PetscXZHermiteSpline& other) = delete; | ||
| PetscXZHermiteSpline& operator=(PetscXZHermiteSpline&& other) = delete; | ||
| ~PetscXZHermiteSpline() override = default; | ||
|
|
||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY"); | ||
|
|
||
| // Use precalculated weights | ||
| Field3D interpolate(const Field3D& f, | ||
| const std::string& region = "RGN_NOBNDRY") const override; | ||
| // Calculate weights and interpolate | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| const std::string& region = "RGN_NOBNDRY"); | ||
| Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, | ||
| const BoutMask& mask, | ||
| const std::string& region = "RGN_NOBNDRY") override; | ||
| const BoutMask& mask, const std::string& region = "RGN_NOBNDRY"); | ||
|
|
||
| std::vector<ParallelTransform::PositionsAndWeights> | ||
| getWeightsForYApproximation(int i, int j, int k, int yoffset) override; | ||
| }; | ||
| #endif // BOUT_HAS_PETSC | ||
|
|
||
| class XZInterpolationFactory | ||
| : public Factory<XZInterpolation, XZInterpolationFactory, Mesh*> { | ||
|
|
@@ -279,11 +325,30 @@ public: | |
| ReturnType create(const std::string& type, [[maybe_unused]] Options* options) const { | ||
| return Factory::create(type, nullptr); | ||
| } | ||
|
|
||
| static void ensureRegistered(); | ||
| }; | ||
|
|
||
| template <class DerivedType> | ||
| using RegisterXZInterpolation = XZInterpolationFactory::RegisterInFactory<DerivedType>; | ||
|
|
||
| using RegisterUnavailableXZInterpolation = | ||
| XZInterpolationFactory::RegisterUnavailableInFactory; | ||
|
|
||
| namespace { | ||
| const inline RegisterXZInterpolation<XZHermiteSpline> registerinterphermitespline{ | ||
| "hermitespline"}; | ||
| const inline RegisterXZInterpolation<XZMonotonicHermiteSpline> | ||
| registerinterpmonotonichermitespline{"monotonichermitespline"}; | ||
| const inline RegisterXZInterpolation<XZLagrange4pt> registerinterplagrange4pt{ | ||
| "lagrange4pt"}; | ||
| const inline RegisterXZInterpolation<XZBilinear> registerinterpbilinear{"bilinear"}; | ||
|
|
||
| #if BOUT_HAS_PETSC | ||
| const inline RegisterXZInterpolation<PetscXZHermiteSpline> registerpetschermitespline{ | ||
| "petschermitespline"}; | ||
| #else | ||
| const inline RegisterUnavailableXZInterpolation register_unavailable_petsc_hermite_spline{ | ||
| "petschermitespline", "BOUT++ was not configured with PETSc"}; | ||
| #endif | ||
| } // namespace | ||
|
|
||
|
Comment on lines
+333
to
+353
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. Should they really be in the header? |
||
| #endif // BOUT_INTERP_XZ_H | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I am not to sure either.
I have to say I am worried, if no-one understands how this works ...
Why do we not need
.xp(2).zp(2)and similar? Does that include the corners, or just the boundaries?