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
Hermite polynomials #14657
Hermite polynomials #14657
Conversation
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.
Yes, very nice! I've left a bunch of comments, but this is close -- nicely done, many thanks!
#include <deal.II/lac/full_matrix.h> | ||
|
||
#include <algorithm> | ||
#include <exception> | ||
#include <memory> | ||
#include <vector> |
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 don't think you actually need any of these header files.
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.
One of the member functions returns an std::vector, but you're right I think the others might be from an older implementation.
* either a non-zero shape value or derivative at $y=0$ and $y=1$ | ||
* on the reference interval $y \in [0,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.
This is an interesting convention to use
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.
Will do!
* $j-(r+1)$ (or value for $j=r+1$) at $x=1$. The basis is rescaled | ||
* so that a function corresponding to a non-zero $j^{th}$ | ||
* derivative has derivative value $j! 4^{j}$ at the corresponding | ||
* node. |
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.
Is it correct that the value of the 0th and (r+1)st basis function is one at the end points of the interval then? Maybe state that as well, just to be extra clear.
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.
Yes, this is correct. I will specify this directly.
* derivative has derivative value $j! 4^{j}$ at the corresponding | ||
* node. | ||
*/ | ||
class HermitePoly : public Polynomial<double> |
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.
All of the other classes in this direction have names of the form PolynomialsX
. So maybe call this one PolynomialsHermite
?
{ | ||
public: | ||
/** | ||
* Constructor for an individual Hermite polynomial. We write f_{j} |
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.
* Constructor for an individual Hermite polynomial. We write f_{j} | |
* Constructor for an individual Hermite polynomial. We write $f_{j}$ |
source/base/polynomials_hermite.cc
Outdated
, degree(2 * regularity + 1) | ||
, regularity(regularity) | ||
, side_index(index % (regularity + 1)) | ||
, side((index > regularity) ? 1 : 0) |
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.
This may be easier to read as follows, given the modulus operation in the line above:
, side((index > regularity) ? 1 : 0) | |
, side((index >= regularity+1) ? 1 : 0) |
source/base/polynomials_hermite.cc
Outdated
, regularity(regularity) | ||
, side_index(index % (regularity + 1)) | ||
, side((index > regularity) ? 1 : 0) | ||
{} |
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.
Would you mind adding an assertion like this:
{} | |
{ | |
AssertIndexRange(index, 2*(regularity+1)); | |
} |
source/base/polynomials_hermite.cc
Outdated
const unsigned int sz = 2 * regularity + 2; | ||
|
||
for (unsigned int i = 0; i < sz; ++i) | ||
polys.push_back(HermitePoly(regularity, i)); |
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.
polys.push_back(HermitePoly(regularity, i)); | |
polys.emplace_back(HermitePoly(regularity, i)); |
fbe78e3
to
bd2904f
Compare
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.
.gitignore
Outdated
@@ -16,6 +16,7 @@ CMakeLists.txt.user | |||
/compile_commands.json | |||
/.clang_complete | |||
/contrib/utilities/programs | |||
/include/build/ |
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.
/include/build/ |
/** | ||
* This class implements Hermite interpolation polynomials (see | ||
* @cite CiarletRiavart1972interpolation) enforcing the maximum | ||
* posible level of regularity $r$ in the FEM basis given a |
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.
* posible level of regularity $r$ in the FEM basis given a | |
* possible level of regularity $r$ in the FEM basis given a |
/** | ||
* This stores whether the shape function corresponds to a non-zero | ||
* value or derivative at $x=0$ on the reference interval | ||
* ($\mathtt{side} =0$), or at $x=1$ ($\mathtt{side} =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.
* ($\mathtt{side} =0$), or at $x=1$ ($\mathtt{side} =1$). | |
* ($\mathtt{side} =0$) or at $x=1$ ($\mathtt{side} =1$). |
bd2904f
to
715f9a7
Compare
@peterrum I've just corrected the typos and changed .gitignore back. |
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.
This looks good but we could improve things by picking a clearer name.
@ivweber May I ask you to resolve the conflict in |
8c2c02a
to
876b8e8
Compare
876b8e8
to
8c2c02a
Compare
I've just reverted back to a clean version from before the rebase |
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.
Thank you for tackling this. To me, both the implementation and the naming look good, as the first step to implement a finite element based on these polynomials.
Just to be sure: I assume it would be difficult/impossible to express these polynomials as the product of the factors (x-x0)*(x-x0)*(x-x_1)*(x-x_1)
for some x_0
and x_1
? For the values it is easy to see what to do, but not for the derivatives. The reason I'm asking is that for Lagrange polynomials we observed that expressing the polynomial with conventional coefficients in front of 1, x, x^2, etc. are unstable in terms of roundoff behavior, and one needs to form with roots. I'm wondering if the Hermite polynomials have similar behavior. On the other hand, it really starts to matter for degrees beyond 6, so we might be fine. If you're wondering and have not looked into it, the evaluation stability is the reason why the Polynomial
class has these members:
dealii/include/deal.II/base/polynomial.h
Lines 304 to 314 in cb6ee41
/** | |
* Stores whether the polynomial is in Lagrange product form, i.e., | |
* constructed as a product $(x-x_0) (x-x_1) \ldots (x-x_n)/c$, or not. | |
*/ | |
bool in_lagrange_product_form; | |
/** | |
* If the polynomial is in Lagrange product form, i.e., constructed as a | |
* product $(x-x_0) (x-x_1) \ldots (x-x_n)/c$, store the shifts $x_i$. | |
*/ | |
std::vector<number> lagrange_support_points; |
dealii/include/deal.II/base/polynomial.h
Lines 819 to 839 in cb6ee41
if (in_lagrange_product_form == false) | |
{ | |
Assert(coefficients.size() > 0, ExcEmptyObject()); | |
// Horner scheme | |
const unsigned int m = coefficients.size(); | |
number value = coefficients.back(); | |
for (int k = m - 2; k >= 0; --k) | |
value = value * x + coefficients[k]; | |
return value; | |
} | |
else | |
{ | |
// direct evaluation of Lagrange polynomial | |
const unsigned int m = lagrange_support_points.size(); | |
number value = 1.; | |
for (unsigned int j = 0; j < m; ++j) | |
value *= x - lagrange_support_points[j]; | |
value *= lagrange_weight; | |
return value; | |
} |
#ifndef dealii_hermite_polynomials | ||
#define dealii_hermite_polynomials |
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.
Can you please rename:
#ifndef dealii_hermite_polynomials | |
#define dealii_hermite_polynomials | |
#ifndef dealii_polynomials_hermite_h | |
#define dealii_polynomials_hermite_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.
Done!
40cbebe
to
ed3f570
Compare
@ivweber I think we are very close to merging! However, some of the tests are not picked up. Only 4 tests are picked up in contrast to the 10, which should be the normal case (see #15165). I think the might be related to the fact that the branch is not rebased on master (not 100% sure). May I ask you to rebase the code. If it helps I can do that for you and I force push it to this branch. |
@kronbichler As far as I know, for most Hermite interpolation polynomials it's difficult to find a fully factorised form of the polynomial because part of the expression is a truncated Taylor series at x=0 for (1-x)^(-r-1), where r is the level of regularity being enforced. Some of the polynomials can be easily written like this, but it's only for the whole basis at lower polynomial degrees. |
6a15bb6
to
7b58a85
Compare
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, apart from a minor comment regarding appearance. Thank you for the explanation, this is what I suspected.
doc/doxygen/references.bib
Outdated
@@ -2159,4 +2168,4 @@ @article{zalesak1979fully | |||
pages={335--362}, | |||
year={1979}, | |||
publisher={Elsevier} | |||
} | |||
} |
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.
Can you please fix the missing line break at the end of the file, such that this diff here disappears?
@peterrum I tried git rebase dealii/master on a copy of the branch and removed the duplicate entries in references.bib that this produced, but I can still only see 4 tests. Is it possible that github-actions doesn't have access to this PR for some reason? |
7b58a85
to
8ddb800
Compare
/rebuild |
I must admit I am bit clueless what the issue is. Maybe you need to create a new PR!? This would be really annoying... |
@drwells Is there a way to get GitHub Actions to start tests on this PR? I looked at the missing tests mentioned above, and they were all ones directly linked to GitHub. Also for some reason the indent test isn't listed as a GitHub Action here, while it is on other PRs. |
I don't know - it should work. I'll spend some time digging into this problem. |
I think we ran into an interesting corner-case where the CI needs to be approved for first time contributors, but the first PR (#13239) wasn't actually merged or had CI enabled. I need someone with higher repository permissions to handle this (or possibly upgrade my access). |
@drwells Would it be useful to remove the previous pull request, or would be likely to create further issues? |
8ddb800
to
0715177
Compare
@ivweber I have pushed a rebase of your changes to your branch (on github) in order to get the tests going. |
@ivweber Finally, the test have run. There are few indentation issues. Good to go once you fixed these 👍 |
@ivweber I will rebase this pull request again to get rid of your merge commit. This means that the history on github and on your local branch will diverge. Edit: I have squashed everything into a single commit to clean up the history and making it easier to review the changes. |
73ce577
to
16c8693
Compare
Nice job, @ivweber ! It took a little while to get this merged, but welcome to the deal.II authors! |
I have grouped together the modified files into different sets. These are the files for generating Hermite polynomials.