Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
19da18a
The updated adhesion with the development branch
Mar 6, 2025
949045a
Merge branch 'development' into adhesion
Mar 7, 2025
fcab9a6
Merging development into adhesion
Mar 27, 2025
0bbc22b
Merging development into adhesion modifying the style error
Mar 27, 2025
4021170
Merging development into adhesion modifying all errors
Mar 27, 2025
d6718e7
Modifying clang and documentation and adding regression tests
Apr 1, 2025
237c76d
Modifying in clang format and documentation and adding regression tes…
Apr 1, 2025
e545217
Modifying in clang format and documentation and adding regression tes…
Apr 1, 2025
ad2abc8
Merge branch 'development' into adhesion
Apr 1, 2025
b09fa44
Documentation and adding regression tests and clang format
Apr 3, 2025
2af1525
Merge branch 'adhesion' of github.com:solidsgroup/alamo into adhesion
Apr 3, 2025
be5570f
Documentation of the adhesion and adding the regression tests and cla…
Apr 3, 2025
58ace0e
Documentation of Adhesion model and adding regression tests and clang…
Apr 3, 2025
9c944f4
Documentation of Adhesion model and adding regression tests in clang …
Apr 3, 2025
7975a92
Merge branch 'development' into adhesion
Apr 14, 2025
bd171a6
Adhesion model with the added test
Apr 14, 2025
841ef64
Adhesion model with added test
Apr 14, 2025
053f43f
Final tweaks
bsrunnels Apr 14, 2025
ef83cbf
removing extra code and bringing into compliance
bsrunnels Apr 14, 2025
0a436fe
integrating with nh
bsrunnels Apr 14, 2025
5c7b42a
fixed tests (issue was failing to apply symmetry in for loops for mat…
bsrunnels Apr 14, 2025
f1f4920
working test case
bsrunnels Apr 14, 2025
3e00642
working example
bsrunnels Apr 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions input
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
alamo.program = mechanics
alamo.program.mechanics.model = finite.adhesion

plot_file = output

# this is not a time integration, so do
# exactly one timestep and then quit
timestep = 0.01
stop_time = 2.0

# amr parameters
amr.plot_int = 1
amr.max_level = 6
amr.n_cell = 32 32 32
amr.blocking_factor = 8
amr.regrid_int = 1
amr.grid_eff = 1.0
amr.cell.all = 1
amr.thermo.plot_int = 1

# geometry
geometry.prob_lo = -8 -8 -8
geometry.prob_hi = 8 8 8
geometry.is_periodic = 0 0 0

#ic.type = ellipse
#ic.ellipse.a = 1.0 0.75 0.5 # ellipse radii
#ic.ellipse.x0 = 0 0 0 # location of ellipse center
#ic.ellipse.eps = 0.1 # diffuse boundary

ic.type = expression
ic.expression.constant.eps = 0.3
ic.expression.constant.R = 4.0
ic.expression.region0 = " (max( erf((x^2 + y^2 - R)/eps),0.0))^2"
ic.expression.region1 = " (max(-erf((x^2 + y^2 - R)/eps),0.0))^2"
ic.expression.region2 = "1.0 - (max( erf((x^2 + y^2 - R)/eps),0.0))^2 - (max(-erf((x^2 + y^2 - R)/eps),0.0))^2"
#ic.expression.region2 = "0.0"

# elastic moduli
nmodels = 2
model1.mu = 2.0
model1.kappa = 3.0
model2.mu = 10.0
model2.kappa = 30.0
model3.mu = 2.0
model3.kappa = 3.0
model1.d = 0.0
model2.d = 0.0
model3.d = 0.0
model1.zeta = 0.0
model2.zeta = 0.0
model3.zeta = 1.0
model1.L = 0.0
model2.L = 0.0
model3.L = 0.2
#model3.mu = 210
#model3.kappa = 0.3

solver.verbose = 3
solver.nriters = 10
#solver.max_iter = 20
solver.fixed_iter = 100
#elasticop.small = 0.1

print_model = 1

bc.type = tensiontest
bc.tensiontest.type = uniaxial_stress
bc.tensiontest.disp=(0,1,2:0,8,0)
242 changes: 242 additions & 0 deletions src/Model/Solid/Finite/Adhesion.H

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.

The formatting in this file is noncompliant with the style outlined in .clang-format.

Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
// This models a finite-strain, solid with adhesion behavior governed by
// a combination of elastic energy and an adhesion decay term.
//
// The energy and derivatives are:
//
// .. math::
// :nowrap:
//
// \begin{gather}
// W = d \left[ \frac{\mu}{2J^{2/3}}(F^T F : I - 3) + \frac{\kappa}{2}(J - 1)^2 \right] + \frac{\zeta}{J^n} \\
// DW = \text{(first Piola-Kirchhoff stress)} \\
// DDW = \text{(tangent stiffness tensor)}
// \end{gather}
//
// where:
// - :math:`d` The coefficient of degradable part,
// - :math:`\mu` is the shear modulus,
// - :math:`\kappa` is the bulk modulus,
// - :math:`\zeta` is the adhesion decay coefficient or the coefficient of non-degradable part,
// - :math:`n` is the decay exponent,
// - :math:`F` is the deformation gradient,
// - :math:`J = \det(F)` is the volume ratio,
// - :math:`F^T F : I = \text{trace}(F^T F)` is used to capture isochoric deformation.
//
// Notes:
//
// Adhesion energy model W(F):
// Consists of two parts:
// 1. Degradable (elastic shear + volumetric terms)
// 2. Non-degradable (adhesion term decaying with volume expansion)
// This model is rate-independent, reversible, and purely elastic.

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.

Please add documentation at the top of this file to outline the method. See Model::Solid::Affine::J2 for an example of suitable documentation.

#ifndef MODEL_SOLID_FINITE_ADHESION_H_
#define MODEL_SOLID_FINITE_ADHESION_H_

#include "IO/ParmParse.H"
#include "Model/Solid/Finite/NeoHookean.H"
#include "Model/Solid/Solid.H"
#include "Set/Set.H"
#include <array> // For std::array to represent fourth-order tensors
#include <cmath> // For std::pow and std::abs
#include <eigen3/Eigen/Dense> // For Eigen::Matrix3d

namespace Model
{
namespace Solid
{
namespace Finite
{

class Adhesion : public NeoHookean
{
public:
static constexpr KinematicVariable kinvar = KinematicVariable::F;

Adhesion() {}
Adhesion(Solid<Set::Sym::Major> base) : NeoHookean(base) {}
virtual ~Adhesion() {}

// Material parameters (declared in order)
Set::Scalar d = NAN; ///< Adhesion strength (degradable part coefficient)
Set::Scalar zeta = NAN; ///< Adhesion decay parameter (non-degradable part)
Set::Scalar n = NAN; ///< Decay exponent
Set::Scalar L = NAN; ///< Mobility

// Return a zero-parameter adhesion model.
static Adhesion
Zero()
{
Adhesion adhesion;
adhesion.d = 0.0; ///< Adhesion strength (degradable part coefficient)
adhesion.zeta = 0.0; ///< Adhesion decay parameter (non-degradable part)
adhesion.n = 0.0; ///< Decay exponent
adhesion.L = 0.0;
adhesion.mu = 0.0;
adhesion.kappa = 0.0;
return adhesion;
}

// Return a random-parameter adhesion model.
static Adhesion
Random()
{
Adhesion adhesion;
adhesion.d = Util::Random() ; // Util::Random(); ///< Adhesion strength (degradable part coefficient)
adhesion.zeta = Util::Random(); ///< Adhesion decay parameter (non-degradable part)
adhesion.n = Util::Random(); ///< Decay exponent
adhesion.mu = Util::Random();
adhesion.kappa = Util::Random();// Util::Random();
adhesion.L = Util::Random();
return adhesion;
}

// Parse function: Reads material parameters from the input file.
// Here, we assume the input file provides: mu, kappa, d, zeta, and n.
static void
Parse(Adhesion &value, IO::ParmParse &pp)
{
pp.queryclass<NeoHookean>(value);
// Initial value for damage
pp_query_default("d", value.d, 0.0);
// Adhesion decay parameter (non-degradable part)
pp_query_default("zeta", value.zeta, 0.0);
// Decay exponent
pp_query_default("n", value.n, 1.0);
// Mobility
pp_query_default("L", value.L, 0.0);
}

// Strain energy function:
// W = d * [ 0.5*mu*(trace(F^T F)-3)/J^(2/3) + 0.5*kappa*(J-1)^2 ] + zeta/J^n
Set::Scalar
W(const Set::Matrix &F) const override
{
Set::Scalar w_nh = (1.0 - d) * NeoHookean::W(F);
Set::Scalar J = F.determinant();
Set::Scalar w_compress = zeta * std::pow(J, -n);
return w_nh + w_compress;
}

// First Piola-Kirchhoff stress (derivative of W)
Set::Matrix
DW(const Set::Matrix &F) const override
{
Set::Matrix dw_nh = (1.0 - d) * NeoHookean::DW(F);
Set::Scalar J = F.determinant();
Set::Matrix FinvT = F.inverse().transpose();
Set::Matrix dw_compress = zeta * (-n * std::pow(J, -n) * FinvT);
return dw_nh + dw_compress;
}

// Tangent stiffness tensor (second derivative of W)
Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Major>
DDW(const Set::Matrix &F) const override
{
Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Major> ddw_nh =
(1.0 - d) * NeoHookean::DDW(F);

Set::Scalar J = F.determinant();
Set::Matrix FinvT = F.inverse().transpose();

Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Major> ddw_compress;

for (int i = 0; i < AMREX_SPACEDIM; i++)
{
for (int j = 0; j < AMREX_SPACEDIM; j++)
{
for (int k = 0; k < AMREX_SPACEDIM; k++)
{
for (int l = 0; l < AMREX_SPACEDIM; l++)
{
// Adhesion-related term (zeta)

// dFinvT(i,j) / dF(k,l)
// = dFinv(j,i) / dF(k,l)
// = -dFinvT(k,j) * dFinvT(iL)

Set::Scalar t3 = n * n * std::pow(J, -n) * FinvT(i, j) * FinvT(k, l)
+ n * std::pow(J, -n) * FinvT(k, j) * FinvT(i, l);
ddw_compress(i, j, k, l) = zeta * t3;
}
}
}
}
return ddw_nh + ddw_compress;
}

// Print material parameters
virtual void
Print(std::ostream &out) const override
{
out << "d = " << d << ", mu = " << mu << ", kappa = " << kappa
<< ", zeta = " << zeta << ", n = " << n;
}

virtual void Advance(Set::Scalar dt, Set::Matrix strain,
Set::Matrix P, Set::Scalar /*time*/) override
{
// Util::Message(INFO,dt);
// Util::Message(INFO,L);
// Util::Message(INFO,(P.transpose()*P).trace());
Set::Scalar dd = std::max(0.0,(P.transpose()*P).trace() * (0.8 - d));
// Util::Message(INFO,dd);
d += dd * L * dt;
}



#define OP_CLASS Adhesion
#define OP_VARS X(d) X(mu) X(kappa) X(zeta) X(n) X(L)
#include "Model/Solid/InClassOperators.H"
};

#include "Model/Solid/ExtClassOperators.H"

} // namespace Finite
} // namespace Solid
} // namespace Model

template<>
ALAMO_SINGLE_DEFINITION
int Set::Field<Model::Solid::Finite::Adhesion>::NComp() const
{
return 4;
}
template<>
ALAMO_SINGLE_DEFINITION
std::string Set::Field<Model::Solid::Finite::Adhesion>::Name(int i) const
{
if (i == 0) return name + "_mu";
if (i == 1) return name + "_kapp";
if (i == 2) return name + "_d";
if (i == 3) return name + "_L";
return name;
}
template<>
ALAMO_SINGLE_DEFINITION
void Set::Field<Model::Solid::Finite::Adhesion>::Copy(int a_lev, amrex::MultiFab& a_dst, int a_dstcomp, int a_nghost) const
{
for (amrex::MFIter mfi(a_dst, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
{
const amrex::Box& bx = mfi.growntilebox(amrex::IntVect(a_nghost));
if (bx.ok())
{
amrex::Array4<const Model::Solid::Finite::Adhesion> const& src = ((*this)[a_lev])->array(mfi);
amrex::Array4<Set::Scalar> const& dst = a_dst.array(mfi);
for (int n = 0; n < AMREX_SPACEDIM * AMREX_SPACEDIM; n++)
{
amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) {
dst(i, j, k, a_dstcomp + 0) = src(i, j, k).mu;
dst(i, j, k, a_dstcomp + 1) = src(i, j, k).kappa;
dst(i, j, k, a_dstcomp + 2) = src(i, j, k).d;
dst(i, j, k, a_dstcomp + 3) = src(i, j, k).L;
});
}
}
}
}



#endif // MODEL_SOLID_FINITE_ADHESION_H_
3 changes: 3 additions & 0 deletions src/mechanics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Model/Solid/Affine/Isotropic.H"
#include "Model/Solid/Linear/Cubic.H"
#include "Model/Solid/Affine/Cubic.H"
#include "Model/Solid/Finite/Adhesion.H"
#include "Model/Solid/Finite/NeoHookean.H"
#include "Model/Solid/Finite/NeoHookeanPredeformed.H"
#include "Model/Solid/Finite/PseudoLinear/Cubic.H"
Expand Down Expand Up @@ -56,6 +57,8 @@ int main (int argc, char* argv[])
pp.select_only<Integrator::Mechanics<Model::Solid::Finite::NeoHookean>>(integrator);
else if (model == "finite.neohookeanpre")
pp.select_only<Integrator::Mechanics<Model::Solid::Finite::NeoHookeanPredeformed>>(integrator);
else if (model == "finite.adhesion")
pp.select_only<Integrator::Mechanics<Model::Solid::Finite::Adhesion>>(integrator);
else if (model == "finite.pseudolinear.cubic")
pp.select_only<Integrator::Mechanics<Model::Solid::Finite::PseudoLinear::Cubic>>(integrator);
else if (model == "finite.pseudoaffine.cubic")
Expand Down
4 changes: 3 additions & 1 deletion src/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Model/Solid/Linear/Laplacian.H"
#include "Model/Solid/Affine/Isotropic.H"
#include "Model/Solid/Affine/Cubic.H"
#include "Model/Solid/Finite/Adhesion.H"
#include "Model/Solid/Finite/NeoHookean.H"
#include "Model/Solid/Finite/NeoHookeanPredeformed.H"
#include "Model/Solid/Finite/PseudoLinear/Cubic.H"
Expand Down Expand Up @@ -57,7 +58,8 @@ int main (int argc, char* argv[])
MODELTEST(Model::Solid::Finite::PseudoLinear::Cubic);
MODELTEST(Model::Solid::Finite::NeoHookeanPredeformed);
MODELTEST(Model::Solid::Finite::PseudoAffine::Cubic);

MODELTEST(Model::Solid::Finite::Adhesion);


Util::Test::Message("Set::Matrix4");
{
Expand Down
19 changes: 19 additions & 0 deletions tests/Solid/input
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@
#@ ignore = model1.E model1.nu
#@ coverage=true
#@
#@ [adhesion]
#@ exe=mechanics
#@ dim=3
#@ check = true
#@ check-file = reference/adhesion.dat
#@ args = timestep=0.01
#@ args = alamo.program.mechanics.model=finite.adhesion
#@ args = model1.mu=3.0
#@ args = model1.kappa=6.5
#@ args = model1.d=1.0
#@ args = model1.zeta=0.5
#@ args = model1.n=2.0
#@ args = bc.tensiontest.disp=(0,1:0,1)
#@ args = solver.nriters=10
#@ ignore = model1.E model1.nu
#@ benchmark-beaker = 10.73
#@ benchmark-statler = 8.17
#@ benchmark-github = 11.35
#@

alamo.program = mechanics

Expand Down
Loading