Skip to content

StaticCondensation can also be a DofMap #4140

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
wants to merge 38 commits into
base: devel
Choose a base branch
from

Conversation

lindsayad
Copy link
Member

My goal is to be able to do field splits on the statically condensed system. This should sit in draft since it has meaningful impacts like converting DofMap methods into virtuals until I have some useful demonstration of capability

@moosebuild
Copy link

moosebuild commented Apr 12, 2025

Job Coverage, step Generate coverage on 33b607a wanted to post the following:

Coverage

091bdd #4140 33b607
Total Total +/- New
Rate 63.58% 63.60% +0.02% 84.67%
Hits 75670 75794 +124 381
Misses 43349 43379 +30 69

Diff coverage report

Full coverage report

Warnings

  • New new line coverage rate 84.67% is less than the suggested 90.0%

This comment will be updated on new commits.

@lindsayad lindsayad changed the title StaticCondensation can also be a DofMap [WIP] StaticCondensation can also be a DofMap Apr 15, 2025
@lindsayad lindsayad changed the title [WIP] StaticCondensation can also be a DofMap StaticCondensation can also be a DofMap May 12, 2025
@lindsayad lindsayad marked this pull request as ready for review May 13, 2025 23:06
@lindsayad lindsayad requested a review from roystgnr May 13, 2025 23:07
Copy link
Member

@roystgnr roystgnr left a comment

Choose a reason for hiding this comment

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

I think my only pointed concern here is the backwards-compatibility (and forwards-compatibility, I suppose; feel free to libmesh_experimental() anything that you think is likely still in flux), but my biggest vague request is that we need to get much more documentation on this sometime. E.g. I can't follow vector_fe_ex9 - we're querying system.has_static_condensation(), but I don't see anywhere we might be enabling static condensation in that example.

@@ -73,6 +75,7 @@ System::System (EquationSystems & es,
time (0.),
qoi (0),
qoi_error_estimates (0),
_sc_dof_map (nullptr),
Copy link
Member

Choose a reason for hiding this comment

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

My first design instinct here wouldn't have been "DofMap, and also SCDofMap that might be null", it would have been "DofMapBase, which might be a plain DofMap or might be a SCCapableDofMap". I'm not saying your way isn't better or asking you to change it, but I'm curious as to what you think the pros+cons are.

Copy link
Member Author

@lindsayad lindsayad May 22, 2025

Choose a reason for hiding this comment

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

The StaticCondensation matrix, if being used, will be the system matrix that users add into. The dof indices that users use for adding into this are the global dofs, hence its conceptual reliance on the full DofMap. However, internally the StaticCondensation class will need to map global system matrix data to statically condensed matrix data for which it must rely on the statically condensed dof map (StaticCondensationDofMap).

Having the full system hold both full and condensed dof maps makes StaticCondensation class construction easy. Additionally, construction of sparsity patterns for the condensed matrices currently routes through the full dof map because it implements methods that the SparsityPattern::Build class calls like find_connected_dofs that the StaticCondensationDofMap doesn't currently have implementations for. But the SparsityPattern::Build does also query the StaticCondensationDofMap for things like dont_condense_vars. So this is another instance where we require both the DofMap and the StaticCondensationDofMap at the same time. I think sometime in the future StaticCondensationDofMap could be more full featured such that it can handle sparsity pattern construction for the statically condensed system all by itself, but I'm not there yet

Copy link
Member Author

@lindsayad lindsayad May 22, 2025

Choose a reason for hiding this comment

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

That isn't a pro-con list. It's perhaps a "current necessity due to a degree of laziness" list? I have not yet made a serious attempt to see if I can make SparsityPattern::Build use only the statically condensed dof map. I think that one of the logical outcomes of such an attempt would be to change the current constructor in this PR

Build::Build (const DofMap & dof_map_in,
              const CouplingMatrix * dof_coupling_in,
              const std::set<GhostingFunctor *> & coupling_functors_in,
              const bool implicit_neighbor_dofs_in,
              const bool need_full_sparsity_pattern_in,
              const bool calculate_constrained_in,
              const StaticCondensationDofMap * const sc_in)

to

Build::Build (const DofMapBase & dof_map_in,
              const CouplingMatrix * dof_coupling_in,
              const std::set<GhostingFunctor *> & coupling_functors_in,
              const bool implicit_neighbor_dofs_in,
              const bool need_full_sparsity_pattern_in,
              const bool calculate_constrained_in)

which would in turn mean enhancing DofMapBase/StaticCondensationDofMap.

I can attempt a serious run at this if you would like me to

Copy link
Member

Choose a reason for hiding this comment

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

Oh, definitely don't attempt a serious run at this yet. I'm still just spitballing here. Trying to understand the design, not to criticize it.

Even in my idea, we'd still have two DofMapBase subclasses, it's just that one of them would own the other, to make the APIs cleaner. An Elem is-a DofObject, which at times has-a second DofObject accessible via old_dof_object(), which is non-nullptr in cases where we need to track both an old and a current numbering at once. The analogous thing to do here would be a DofMap which has-a StaticCondensationDofMap, non-null when we're doing static condensation; but perhaps the better solution in this case would be to have a StaticCondensationDofMap for the advanced cases, which then always has-a plain DofMap that doesn't itself know about static condensation.

Even that might not be an improvement. If you're 99% sure it wouldn't be an improvement, I'm fine with us not trying. If you're 90% sure it wouldn't be an improvement, I'd like to get something in the new code paths marked libmesh_experimental() but I'm still fine with us not trying yet.

Copy link
Member Author

Choose a reason for hiding this comment

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

So you're thinking that the DofMap, not the System, should own StaticCondensationDofMap?

@@ -171,7 +171,7 @@ main(int argc, char ** argv)
libmesh_error_msg_if(!libMesh::relative_fuzzy_equals(*sys.solution, *sc_sys.solution, 1e-4),
"mismatching solution");
libMesh::out << "Static condensation reduced problem size to "
<< sc_sys.get_static_condensation().get_condensed_mat().m() << std::endl;
Copy link
Member

Choose a reason for hiding this comment

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

This old idiom should still work, right? Could we leave it around, either in one example or in a unit test, to cover that?

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you mean? get_static_condensation() now returns a DofMapBase instead of the SparseMatrix derived class. So the options are either (what is currently used in that example)

sc_sys.get_static_condensation_system_matrix().get_condensed_mat().m()

or

sc_sys.get_static_condensation().n_dofs()

Copy link
Member

Choose a reason for hiding this comment

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

Ugh. I misunderstood part of the API change here.

Is there anything we can do to preserve backwards compatibility here? Maybe make get_static_condensation() do what get_static_condensation_system_matrix() now does, and make get_static_condensation_map() the new API that returns the DofMapBase subclass? If we've got what's effectively a new API then we can give it a new name, and then we've still got the old name left over to try to preserve compatibility.

The old API made it into the 1.8.0 branch, and wasn't marked libmesh_experimental(), and I just don't like yanking users around. I like to be one of the people who ameliorates others' API consistency problems, despite the ugliness of #if VERSION > foo #elif VERSION > bar #etc code; I don't like to be the one of the ones creating the problems.

@lindsayad
Copy link
Member Author

lindsayad commented May 22, 2025

E.g. I can't follow vector_fe_ex9 - we're querying system.has_static_condensation(), but I don't see anywhere we might be enabling static condensation in that example.

Static condensation is setup from the command line in run.sh. I'll add a comment in the source

@lindsayad
Copy link
Member Author

I've restored the matrix_build_type

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
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy