Skip to content

Add ADR integration#284

Open
JBludau wants to merge 45 commits into
ORNL:mainfrom
JBludau:ADL_integration
Open

Add ADR integration#284
JBludau wants to merge 45 commits into
ORNL:mainfrom
JBludau:ADL_integration

Conversation

@JBludau

@JBludau JBludau commented Jan 28, 2026

Copy link
Copy Markdown
Collaborator

This is based upon the formulation in https://www.sciencedirect.com/science/article/pii/S0020768317304833 but without the rotational stiffness.

One important difference is: in (75) we use (L_u(t-1)/Delta_ii-L_u(t)/Delta_ii). This corresponds to a -1*(75). Otherwise we get negative damping coefficients due to the approximated stiffness term being negative (the force difference points opposite to the velocity).

The implementation tries to be independent of CabanaPD's particle interface. This allows for easier testing (testcase is just a single mass) and potential reuse.

  • Add adapters for particle interface
  • Add testcase with particles
  • Add interface in Solver class Not sure if that is a good idea ... we need to discuss this probably. In general the interface is still a bit ugly. The points are marked with TODO in comments
  • Add convenience functions for creation of an ADRIntegrator
  • Convert Dogbone case to use this method
  • MPI support/testing (this probably revolves around bounding the iteration to exclude the frozen particles and end at the offset)
  • Think about how to guess c for non PMB materials

Related to issue #207

@JBludau JBludau self-assigned this Jan 28, 2026
Comment thread src/CabanaPD_Integrate.hpp Outdated
Comment thread src/CabanaPD_Integrate.hpp Outdated
Comment on lines +293 to +296
stiffness[i] = ( -forces( index, i ) +
_forces_last_step( index, i ) ) /
mass[i] / _delta_t /
_velocities_last_step( index, i );

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is where it differs from the paper

@JBludau JBludau force-pushed the ADL_integration branch 2 times, most recently from d5e5fef to 48a5aae Compare January 28, 2026 21:54
#include <fstream>
#include <iostream>

#include "mpi.h"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

hmm currently this does not support mpi ... maybe I should remove it

ParticleType const& particles )
{
auto forces = particles.sliceForce();
_integrator.initialSubStep( exec_space, forces );

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hmm...right now the integrator cycles over all particles ... that is probably false and should be corrected somehow ... I guess the best would be to create proxy objects for the slices

Comment thread src/CabanaPD_Integrate.hpp Outdated
Comment on lines +486 to +492
integrator.middleSubStep( exec_space, particles, args... );

// Add non-force boundary condition.
if ( !boundary_condition.forceUpdate() )
boundary_condition.apply( exec_space, particles, time );

integrator.finalSubStep( exec_space, particles, args... );

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is the reason why we need a middle step. We calculate the velocity in the middle step but need to overwrite it with the bc if the bc sets a velocity. After that is applied we can go and integrate the displacement

@JBludau JBludau marked this pull request as ready for review February 2, 2026 15:33
@yaowwwwwww

Copy link
Copy Markdown

"Think about how to guess c for non PMB materials". This is a big question for the application. People cannot calibrate the c for each material, since the material behavior is different.

I am trying to define a bond-based JC strain rate-dependent model, and i define the equivalent plastic strain as the weighted root-mean-square norm of norm of bond plastic stretches in PMB model. The theoretical consistency needs further study.

Maybe use a reasonable mapping method of bond deformation to the material point strain, it will provide a easy way for defining different classical material in the future.

@JBludau

JBludau commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

"Think about how to guess c for non PMB materials". This is a big question for the application. People cannot calibrate the c for each material, since the material behavior is different.

I am trying to define a bond-based JC strain rate-dependent model, and i define the equivalent plastic strain as the weighted root-mean-square norm of norm of bond plastic stretches in PMB model. The theoretical consistency needs further study.

Maybe use a reasonable mapping method of bond deformation to the material point strain, it will provide a easy way for defining different classical material in the future.

I guess we would be fine with guessing a minimal value for c. Due to the ADR using c in the numerator for the fictitious masses, having a higher c than what the force uses increases the fictitious masses and makes the ADR converge slower (The implementation has a safety-factor of 5 anyways). I mainly expect numerical problems if c is far too low. In this case the ADR uses particles that are too light and thus they are underdamped, allowing them to oscillate. If that gets severe, it might lead to large errors in the time integration and thus to wrong solutions which might be hard to detect.

Maybe guessing c for the ADR as we do for PMB via 6E/(pihorizon^4(1-2nu)) is a good approximation for many cases. Basically as long as we guess the maximal stiffness we might be ok (and we still have the safety factor). Nevertheless, if we want to tune for performance that still might be tricky. But other factors might get us there faster (e.g. using something similar to a multi-scale simulation or even just using reduced precision for the ADR)

@JBludau JBludau left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The recent addition uses the specific c for every material instead of a user given c for multimaterial cases.

#include <CabanaPD_Integrate.hpp>
#include <CabanaPD_Particles.hpp>
#include <CabanaPD_config.hpp>
#include <CabanaPD.hpp>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not something I like, but the multimaterial and particle together need almost everything

Comment on lines +25 to +37
std::enable_if_t<current == ParameterPackType::size - 1, int> = 0>
KOKKOS_INLINE_FUNCTION auto recursion_functor_for_index_in_pack_with_args(
FunctorType const& functor, std::size_t index,
ParameterPackType& parameterPack, ARGS... args )
{
if ( index == current )
{
return functor( Cabana::get<current>( parameterPack ), args... );
}
else
{
return recursion_functor_for_index_in_pack_with_args<current + 1>(
functor, index, parameterPack, args... );
Kokkos::abort( "Requested index not contained in ParameterPack" );
return functor( Cabana::get<current>( parameterPack ), args... );

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is basically just a reversal of order of the two functions in the file. The old order was spoofing the compiler to not see the second SFINAE version.

Comment on lines +398 to +402
for ( unsigned i = 0; i < IndexingType::NumBaseModels; ++i )
{
_c[i] = CabanaPD::Impl::run_functor_for_index_in_pack_with_args(
GetCFunctor{}, i, _models.models );
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is the critical part where the multimaterial differs from single material. We need to get the correct stiffness for a specific material and store it. But we only get the basic set of materials, not the averaged ones. The reason for that is in the comment line 406

Comment on lines +406 to +414
double KOKKOS_FUNCTION operator()( IndexType index, int ) const
{
auto materialIndex =
_indexing( _particleType( index ), _particleType( index ) );
return _safety_factor *
( _delta_t * _delta_t * Kokkos::numbers::pi * _horizon *
_horizon * _horizon * _c[materialIndex] ) /
( 3.0 * _delta_x );
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

During the integration, we iterate over the particles and only have one particle index. That means we can only have one c that we use for the fictitious mass even though the particle we are integrating might only use this c in some of its bonds.
But currently I don't see a way for us to get a better estimate for c with reasonable effort ... we could average c over the neighborhood and store it for every particle, but that would be a lot of new algorithmic lift and data. And it would need to be recomputed every step as bonds can break.

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.

2 participants