Skip to content

Some theoretical background for the L2 projector#1272

Closed
termi-official wants to merge 3 commits intomasterfrom
do/more-l2-docs
Closed

Some theoretical background for the L2 projector#1272
termi-official wants to merge 3 commits intomasterfrom
do/more-l2-docs

Conversation

@termi-official
Copy link
Copy Markdown
Member

No description provided.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.36%. Comparing base (726b223) to head (b6c660a).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1272      +/-   ##
==========================================
- Coverage   94.20%   91.36%   -2.84%     
==========================================
  Files          40       40              
  Lines        6676     6963     +287     
==========================================
+ Hits         6289     6362      +73     
- Misses        387      601     +214     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/L2_projection.jl Outdated
Comment on lines +69 to +76
The operation done by the L2-projector can be interpreted as the Galerkin-projection of ``f`` onto ``u``:
```math
\\int v (u - f) \\ \\mathrm{d}\\Omega = 0 \\quad \\forall v \\in U_h(\\Omega),
```
An alternative interpretation here is that we minimize the difference between ``f`` and ``u`` with the functional (induced by the ``L_2`` norm):
```math
\\min_u \\int \\frac{1}{2} (u - f)^2 \\ \\mathrm{d}\\Omega \\, .
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we reverse the order and stating that the 1st equation is a result of setting the directional derivative of the 2nd equal to zero?

Would it also make sense to introduce the FE-approximation explicitly above then to show the discrete equation system?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Should we reverse the order and stating that the 1st equation is a result of setting the directional derivative of the 2nd equal to zero?

Not necessarily. The first equation is the orthogonality and it just happens here that it is also the variation of the latter and thereby connected.

Would it also make sense to introduce the FE-approximation explicitly above then to show the discrete equation system?

What do you mean?

Copy link
Copy Markdown
Member

@KnutAM KnutAM Jan 27, 2026

Choose a reason for hiding this comment

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

What do you mean?

$$\underbrace{\int N_i N_j \ \mathrm{d}\Omega}_{M_{ij}}\ a_j = \underbrace{\int N_i f \ \mathrm{d}\Omega}_{f_i} \quad \forall v \in U_h(\Omega)$$

And then say that M is Cholesky factorizated upon close?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Can do.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Something like this maybe?

@fredrikekre
Copy link
Copy Markdown
Member

This is great, but perhaps it should go into the "Topic guides" section rather than the docstring? (If we consider docstrings to be reference (https://diataxis.fr/start-here/#reference)).

@termi-official
Copy link
Copy Markdown
Member Author

This is great, but perhaps it should go into the "Topic guides" section rather than the docstring? (If we consider docstrings to be reference (https://diataxis.fr/start-here/#reference)).

Going over this again I still think it should be in the docstring. Quoting the material here, putting what I think is relevant into bold :[...] accurate, complete, reliable information, free of distraction and interpretation. They contain propositional or theoretical knowledge, not guides to action.` Or am I missing something? If you prefer that this should go into a new Topic guide I can do it anyway. :) I do not have any opinion here about where it should go. I just found it brief enough that it might go directly into the docstring as it does not seem to causing much noise and contains some relevant information.

@fredrikekre
Copy link
Copy Markdown
Member

I still think theoretical background is Explanation (or what we call topic guides). I interpret reference as "what you need while coding", i.e. how to use the thing ("reference documentation serves the user who is at work").

@KnutAM
Copy link
Copy Markdown
Member

KnutAM commented Jan 29, 2026

Is there a neat way to link to the online documentation directly from the docstring?
Should (can?) we add some utility functions and do something like

"""
    foo()
    
Nothing here, but see the [Topic guide]($(docref_topics("postprocessing")))
"""
foo() = nothing

@termi-official
Copy link
Copy Markdown
Member Author

Done and deploys.

@termi-official termi-official added the awaiting review PR is finished from the authors POV, waiting for feedback label Feb 6, 2026
Copy link
Copy Markdown
Member

@KnutAM KnutAM left a comment

Choose a reason for hiding this comment

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

To me it would look better to mirror the API-section and have postprocessing at the end. Also to add this in the Topic guide overview.

@@ -0,0 +1,30 @@
# [Projections and Transfer](@id man-projection-transfer)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# [Projections and Transfer](@id man-projection-transfer)
# [Projection](@id man-projection-transfer)

Since we only have projection for now?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We also have the PointEvalHandler as a transfer function. I just didn't wanted to include too many changes in one PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

OK, I read transfer as transferring between grids. But if following the API-section, this should still be two separate sub-headings then?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I read transfer as transferring between grids

Yes. This is one examplaric use-case of the PointEvalHandler. Does that make sense?

should still be two separate sub-headings then?

This is the heading for the full section. We also have this for example in the Grid and AbstractGrid section.

I am still open for improvements on the name. Postprocessing is misleading tho.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Postprocessing is misleading tho.

True, but that also a problem in the API section then, and keeping these in sync I think is better? And if we decide on a good way to split we do it for both?

Yes. This is one examplaric use-case of the PointEvalHandler. Does that make sense?

True, but another is plotting along a line as put in the postprocessing how-to, and I think finding that functionality as a transfer could be hard for users?

This is the heading for the full section.

Yes, wasn't against a general heading (just that moving it to include export, if we do that). I'm also not sure what the best name here would be.

I just didn't wanted to include too many changes in one PR.

Sure, that makes sense (but hard to see here, so IMO better add a general header then :) )

@@ -0,0 +1,30 @@
# [Projections and Transfer](@id man-projection-transfer)

This section is concerned with projection and transfer techniques implemented in Ferrite.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
This section is concerned with projection and transfer techniques implemented in Ferrite.
Ferrite can [`project`](@ref) values stored in the quadrature points onto a finite element interpolation, making it suitable for e.g. plotting. Currently, [L2 projection](@ref man-l2projection) is implemented.

Comment on lines +8 to +9
This technique is concerned with finding the best field for some function, or after numerical quadrature for some given data points.
To be mathematically more precise, the operation done by the L2-projector can be interpreted as the Galerkin-projection of ``f`` onto ``u``:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
This technique is concerned with finding the best field for some function, or after numerical quadrature for some given data points.
To be mathematically more precise, the operation done by the L2-projector can be interpreted as the Galerkin-projection of ``f`` onto ``u``:
This method finds the closest (in the L2 norm) projection of some function onto a finite element interpolation. In practice, the function is often described by its values in the quadrature points and numerical integration is used directly.
The L2-projection is the Galerkin-projection of the function ``f`` onto the function space ``U(\Omega)``, i.e. find `u \in U(\Omega)` such that

\underbrace{\int N_i N_j \ \mathrm{d}\Omega}_{M_{ij}}\ u^h_j = \underbrace{\int N_i f \ \mathrm{d}\Omega}_{b_i}
```
where ``u^h_j`` denotes the unknown dofs of the finite-dimensional discrete space to project onto (e.g. Lagrange polynomials) with ansatz and test functions ``N``.
``b_i`` denotes the right hand side of the finite-dimensional discrete linear system. For vectorized problems we simply apply the projection component-wise.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
``b_i`` denotes the right hand side of the finite-dimensional discrete linear system. For vectorized problems we simply apply the projection component-wise.
``b_i`` denotes the right hand side of the finite-dimensional discrete linear system. The L2 projection of vector- or tensor-valued quantities onto scalar-valued finite element spaces is computed by projecting component-wise.

To prep for adding details from #1161 here.

Comment thread src/L2_projection.jl
Comment on lines 32 to 42
a function space. To define the function space, add interpolations for
different cell sets with `add!` before `close!`ing the projector,
see the example below.

The `L2Projector` acts as the integrated left hand side of the projection equation:
Find projection ``u \\in U_h(\\Omega) \\subset L_2(\\Omega)`` such that
Find projection ``u \\in U(\\Omega) \\subset L_2(\\Omega)`` such that
```math
\\int v u \\ \\mathrm{d}\\Omega = \\int v f \\ \\mathrm{d}\\Omega \\quad \\forall v \\in U_h(\\Omega),
\\int v u \\ \\mathrm{d}\\Omega = \\int v f \\ \\mathrm{d}\\Omega \\quad \\forall v \\in U(\\Omega),
```
where ``f \\in L_2(\\Omega)`` is the data to project. The function space ``U_h(\\Omega)``
where ``f \\in L_2(\\Omega)`` is the data to project. The function space ``U(\\Omega)``
is the finite element approximation given by the interpolations `add!`ed to the `L2Projector`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps make it cleaner to not have it at all here then?

And if not removing, regarding the change from U_h to U, shouldn't it be U_h here because we say that it is the finite element approximation, whereas in the the initial part of the topic guide it is described as a general function space which later is restricted (discretized) with finite elements?

Suggested change
is the finite element approximation given by the interpolations `add!`ed to the `L2Projector`.
a function space. See the corresponding [topic guide](@ref man-l2projection)
for the mathematical details.
To define the function space, add interpolations for
different cell sets with `add!` before `close!`ing the projector,
see the example below.

@termi-official termi-official removed the awaiting review PR is finished from the authors POV, waiting for feedback label Feb 10, 2026
@termi-official
Copy link
Copy Markdown
Member Author

termi-official commented Feb 10, 2026

To me it would look better to mirror the API-section and have postprocessing at the end.

Really not sure here. I do not like having the API section called postprocessing in first place -- but I think having a how to on postprocessing is a good idea. The sectioning needs a bit of restructuring anyways. For example, we have a "How to postprocessing", a "postprocessing API" and an "Export topic guide" section. Then we also list AffineConstraints in the API reference as boundary conditions, while the topic guide has its the affine constraints in its own section. It is really far from ideal and we need to put more thought into how to group stuff. For this reason I have used "Projection and Transfer" here as a separate section for now, as it is more discoverable. Although we should technically also put the projected Dirichlet here.

Also, L2 projections are indeed sometimes used in postprocessing (which can be quite harmful if one is not careful), it is also also used for example in solvers and error estimators.

Also to add this in the Topic guide overview.

I also saw that I forgot this. Thanks for pointing this out!

@KnutAM
Copy link
Copy Markdown
Member

KnutAM commented Feb 10, 2026

Although we should technically also put the projected Dirichlet here.

I don't think so, that is still about enforcing a constraint/bc, even if the constraint is not point-wise and based on the projection equation.

Really not sure here. I do not like having the API section called postprocessing in first place

I agree that we have a discrepancy and that it is not ideal, I just believe we should keep these more in sync and avoid making them even more different. Perhaps it makes sense to add this PR to add the content following the API structure, and add another issue/PR to make what is different the same and create more logical headers / overall structure? (Probably an issue as it might need some discussion first?) Would be a shame to stall the details added in this while discussing the more overall structure.

@termi-official
Copy link
Copy Markdown
Member Author

I think this is a bigger change than I initially anticipated. I just wanted to upstream here some stuff from the Ferrite paper. Probably easiest if this is picked up after we have fixed the docs.

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.

3 participants