41 using namespace Fastor;
42 using namespace FastorStandardTensors;
43 using namespace FastorIndices;
47 using MarmotMaterialFiniteStrain::MarmotMaterialFiniteStrain;
53 const double fy, fyInf, eta,
H;
89 inline const static auto layout = makeLayout( {
90 { .name =
"Fp", .length = 9 },
91 { .name =
"alphaP", .length = 1 },
94 Fastor::TensorMap< double, 3, 3 >
Fp;
100 std::unique_ptr< FiniteStrainJ2PlasticityStateVarManager >
stateVars;
102 void assignStateVars(
double* stateVars,
int nStateVars );
104 StateView getStateView(
const std::string& result );
106 void initializeYourself();
113 std::tie( mandelStress, dMandel_dFe ) = computeMandelStress( Fe );
121 std::tie( f, df_dMandel, d2f_dMandel_dMandel, df_dBetaP ) = yieldFunctionFromStress( mandelStress, betaP );
123 df_dFe = einsum< IJ, IJKL >( df_dMandel, dMandel_dFe );
125 return { f, df_dFe, df_dBetaP };
127 template <
typename T >
131 T rho = sqrt( Fastor::inner( dev, dev ) );
132 if (
double( rho ) == 0.0 )
142 const double rho = std::max( sqrt( Fastor::inner( dev, dev ) ), 1e-15 );
147 Tensor3333d d2Rho_dMandel_dMandel = -1.0 / std::pow( rho, 3 ) * outer( dev, dev ) +
155 Tensor3333d d2f_dMandel_dMandel = 1. / fy * d2Rho_dMandel_dMandel;
156 Tensor33d df_dMandel = 1. / fy * dRho_dMandel;
160 template <
typename T >
165 T rho = sqrt( Fastor::inner( dev, dev ) );
181 std::tie( f, df_dFe, df_dBetaP ) = yieldFunction( Fe, betaP );
205 dMandel_dCe = einsum< Ii, iJKL, to_IJKL >( Ce, 2. * d2Psi_dCedCe ) +
207 Tensor3333d dMandel_dFe = einsum< IJKL, KLMN >( dMandel_dCe, dCe_dFe );
208 return { mandel, dMandel_dFe };
211 template <
typename T >
226 template <
typename T >
229 const T beta = fyInf + ( fy - fyInf ) *
exp( -alphaP * eta ) + alphaP * H;
234 const double beta = fyInf + ( fy - fyInf ) *
exp( -alphaP * eta ) + alphaP * H;
235 const double dBetaP_dAlphaP = -eta * ( fy - fyInf ) *
exp( -alphaP * eta ) + H;
236 return { beta, dBetaP_dAlphaP };
239 std::tuple< double, double >
g(
const Tensor33d& Fe_trial,
const Tensor33d& df_dS,
double dLambda,
double betaP )
242 std::tie( dFp, ddFp_ddLambda ) = computePlasticIncrement( df_dS, dLambda );
247 Tensor33d dFpInv = Fastor::inverse( dFp );
248 Tensor3333d dFe_ddFp = einsum< iI, iJKL >( Fe_trial, einsum< LI, JK, to_IJKL >( -dFpInv, dFpInv ) );
250 std::tie( f, df_dFe, df_dBetaP ) = yieldFunction(
Tensor33d( Fe_trial % dFpInv ), betaP );
252 double df_ddLambda = einsum< IJ, IJKL, KL >( df_dFe, dFe_ddFp, ddFp_ddLambda ).toscalar();
254 return { f, df_ddLambda };
257 template <
typename T >
263 std::tie( mandelStressTrial, dMandel_dFe ) = computeMandelStress( Fe );
266 std::tie( f, df_dS, df_dBetaP ) = yieldFunctionFromStress( mandelStressTrial, betaP );
271 template <
typename T >
281 return { dFp, einsum< IJKL, KL >( ddFp_ddGp, df_dS ) };
284 template <
typename T >
290 using namespace Eigen;
291 using mV9t = Eigen::Map< Eigen::Matrix< T, 9, 1 > >;
296 R( 9 ) = -alphaPTrial;
300 const T dLambda = X( 10 );
301 const T alphaP = X( 9 );
303 const T betaP = computeBetaPOnly( alphaP );
310 std::tie( f, df_dMandel, df_dBetaP ) = yieldFunctionFromStressFirstOrderDerived( mandelStress, betaP );
316 mV9t( fastorTensorFromDoubleTensor< T >( FeTrial ).data() );
326 R( idxA ) = ( alphaP + dLambda * df_dBetaP ) - alphaPTrial;
333 const double alphaPTrial )
338 using namespace Eigen;
339 using mV9d = Eigen::Map< Eigen::Matrix< double, 9, 1 > >;
340 using mM9d = Eigen::Map< Eigen::Matrix< double, 9, 9 > >;
342 MatrixXd dR_dX( 11, 11 );
345 R.segment< 9 >( 0 ) = -mV9d( FeTrial.data() );
346 R( 9 ) = -alphaPTrial;
348 Tensor33d Fe( X.segment( 0, 9 ).data() );
350 const double dLambda = X( 10 );
351 const double alphaP = X( 9 );
354 double betaP, dBetaP_dAlphaP;
355 std::tie( betaP, dBetaP_dAlphaP ) = computeBetaP( alphaP );
360 std::tie( mandelStress, dMandel_dFe ) = computeMandelStress( Fe );
364 std::tie( f, df_dMandel, d2f_dMandel_dMandel, df_dBetaP ) = yieldFunctionFromStress( mandelStress, betaP );
372 Tensor3333d ddGp_dFe = dLambda * einsum< ijmn, mnkL >( d2f_dMandel_dMandel, dMandel_dFe );
373 Tensor33d ddFp_ddLambda = einsum< IJKL, KL >( ddFp_ddGp, df_dMandel );
375 Tensor3333d ddFp_dFe = einsum< iImn, mnkL >( ddFp_ddGp, ddGp_dFe );
380 Tensor3333d dFeTrial_dFe = einsum< iI, IJKL >( Fe, ddFp_dFe ) +
386 Tensor33d dFe_ddLambda = einsum< Ii, iJ >( Fe, ddFp_ddLambda );
392 Tensor33d df_dFe = einsum< IJ, IJKL >( df_dMandel, dMandel_dFe );
393 std::tie( f, df_dFe, df_dBetaP ) = yieldFunction( Fe, betaP );
394 df_dFe = einsum< IJ, IJKL >( df_dMandel, dMandel_dFe );
398 R.segment< 9 >( 0 ) += mV9d(
Tensor33d( einsum< iJ, JK >( Fe, dFp ) ).data() );
399 R( idxA ) += ( alphaP + dLambda * df_dBetaP );
402 dR_dX.block< 9, 9 >( 0, 0 ) = mM9d( dFeTrial_dFe.data() ).transpose();
404 dR_dX.block< 1, 9 >( idxF, 0 ) = mV9d( df_dFe.data() );
405 dR_dX.block< 9, 1 >( 0, idxF ) = mV9d( dFe_ddLambda.data() );
406 dR_dX( idxF, idxA ) = df_dBetaP * dBetaP_dAlphaP;
407 dR_dX( idxA, idxF ) = df_dBetaP;
408 dR_dX( idxA, idxA ) = 1.0;