Skip to content

Contact-Homotopy Updates (Cache results of Tribol calls, etc).#1521

Open
thartland wants to merge 14 commits intodevelopfrom
hartland1/feature/contact-homotopy-bcs
Open

Contact-Homotopy Updates (Cache results of Tribol calls, etc).#1521
thartland wants to merge 14 commits intodevelopfrom
hartland1/feature/contact-homotopy-bcs

Conversation

@thartland
Copy link
Contributor

@thartland thartland commented Jan 14, 2026

This PR adds

  • initial caching of results from Tribol contact mechanics computations. That is, repeated calls to the same function at the same point will not lead to additional contact mechanics computations.
  • update ContinuationSolvers in order to avoid compilation errors when users compile smith with ContinuationSolvers enabled and no direct solver (STRUMPACK, MUMPS, CPARDISO) in the mfem build. Thanks Chris for bringing this issue to my attention.
  • complete caching of results from Tribol mechanics computations. That is, when the gap constraints are evaluated internally Tribol also computes gap constraint Jacobians.

Regarding item (3) -- there is now a structure in the Constraint class to communicate that we are requesting a "fresh_derivative" but not at a "new point". By "new point" we mean has the Constraint class "seen" this point in it's most recent computation (perhaps as just a constraint evaluation), so that a derived Constraint class can cache the Jacobian computations from the constraint evaluation and just provide the cached Jacobian when a "fresh derivative" is requested at an "old point".

@thartland thartland added the WIP Work in progress label Jan 14, 2026
@thartland thartland changed the title (WIP) -- Contact-Homotopy Updates (Cache results of Tribol calls, Non-tied contact, etc). Contact-Homotopy Updates (Cache results of Tribol calls, etc). Feb 2, 2026
@thartland thartland added ready for review Ready for active inspection by reviewers and removed WIP Work in progress labels Feb 2, 2026
Copy link
Collaborator

@tupek2 tupek2 left a comment

Choose a reason for hiding this comment

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

This looks conceptually fine, but I didn't really work through all the low level logic to know if there might be some dangerous cases. We've had trouble with 'memory' leaks through block matrices if we dont appropriately hand over ownership. maybe double check all that is alright.

Copy link
Member

@ebchin ebchin left a comment

Choose a reason for hiding this comment

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

Looks good overall! Before I approve, can you clarify the usage of fresh_evaluation vs. fresh_derivative?

contact_opts_.enforcement = ContactEnforcement::LagrangeMultiplier;
contact_.addContactInteraction(interaction_id, bdry_attr_surf1, bdry_attr_surf2, contact_opts_);
interaction_id_ = interaction_id;
tribol::setLagrangeMultiplierOptions(interaction_id_, tribol::ImplicitEvalMode::MORTAR_GAP);
Copy link
Member

Choose a reason for hiding this comment

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

Is this line needed? I think the ContactInteraction controls this

const mfem::Vector& multipliers, int direction,
bool fresh_evaluation = true) const override
bool fresh_evaluation = true,
bool fresh_derivative = true) const override
Copy link
Member

Choose a reason for hiding this comment

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

Update doxygen comment

std::unique_ptr<mfem::HypreParMatrix> jacobian_tilde(double time, double dt, const std::vector<ConstFieldPtr>& fields,
int direction, bool fresh_evaluation = true) const override
int direction, bool fresh_evaluation = true,
[[maybe_unused]] bool fresh_derivative = true) const override
Copy link
Member

Choose a reason for hiding this comment

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

Update doxygen

* @param fields vector of smith::FiniteElementState*
* @param direction index for which field to take the gradient with respect to
* @param fresh_evaluation boolean indicating if we re-evaluate or use previously cached evaluation
* @param fresh_derivative boolean indicating with fresh_evaluation if we re-evaluate or use previously cached
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I follow the difference between fresh evaluation vs fresh derivative. If I have fresh evaluation without fresh derivative, do I just get updated constraints + forces (and no tangents)? If I have fresh_derivative and no fresh_evaluation, what happens?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If fresh_evaluation is true this is the first time any gap computations are being done at the current point and so we setDisplacements and update the ContactData based on the displacements. If fresh_evaluation is false then ContactData uses the displacement from the most recent setDisplacements call and then if fresh_derivative is called then additional derivative specific operations are done at that point, such as setting pressures, etc.

@thartland
Copy link
Contributor Author

This looks conceptually fine, but I didn't really work through all the low level logic to know if there might be some dangerous cases. We've had trouble with 'memory' leaks through block matrices if we dont appropriately hand over ownership. maybe double check all that is alright.

Good point. I've been working on this item today.

@thartland
Copy link
Contributor Author

Looks good overall! Before I approve, can you clarify the usage of fresh_evaluation vs. fresh_derivative?

Yes. The idea is that sometimes one would call a gap computation and then a gap Jacobian computation at the same displacement state. For instance when one determines the tied contact residual

r(u) + (dg/du)^T \lambda = 0
g(u) = 0

There were similar computations done in both the gap computation g(u) and gap Jacobian calls. I wanted to be able to communicate to the constraint that we've previously done a gap computation at this point (fresh_evaluation = false) but that this is the first time we are computing a derivative at this point (fresh_derivative = true). Honestly we should probably talk given your recent work on exposing individual gap computations in tribol as this interface might be more cumbersome/confusing given the alternatives we will get from tribol. I'll contact you outside of git for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Ready for active inspection by reviewers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants