72 static constexpr
double tolerance = std::numeric_limits<double>::epsilon();
111 const bool ConsiderPertubationThreshold =
true,
117 const bool use_element_provided_strain = cl_options.
Is(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN);
119 if (use_element_provided_strain) {
136 const bool ConsiderPertubationThreshold =
true,
144 const bool symmetrize_operator = (r_properties.Has(SYMMETRIZE_TANGENT_OPERATOR)) ? r_properties[SYMMETRIZE_TANGENT_OPERATOR] :
false;
147 const SizeType num_components = unperturbed_stress_vector_gp.size();
151 r_tangent_tensor.
clear();
156 if (r_properties.Has(PERTURBATION_SIZE)) {
157 pertubation = r_properties[PERTURBATION_SIZE];
158 if (pertubation == -1.0)
161 for (
IndexType i_component = 0; i_component < num_components; ++i_component) {
162 double component_perturbation;
163 CalculatePerturbation(unperturbed_strain_vector_gp, i_component, component_perturbation);
164 pertubation =
std::max(component_perturbation, pertubation);
173 if (ApproximationOrder == 1) {
174 for (
IndexType i_component = 0; i_component < num_components; ++i_component) {
177 PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
180 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
183 const Vector delta_stress = r_perturbed_integrated_stress - unperturbed_stress_vector_gp;
184 CalculateComponentsToTangentTensorFirstOrder(auxiliary_tensor, r_perturbed_strain-unperturbed_strain_vector_gp, delta_stress, i_component);
187 noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
188 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
190 }
else if (ApproximationOrder == 2) {
191 for (
IndexType i_component = 0; i_component < num_components; ++i_component) {
193 PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
196 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
199 const Vector strain_plus = r_perturbed_strain;
200 const Vector stress_plus = r_perturbed_integrated_stress;
203 noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
204 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
207 PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, - pertubation, i_component);
210 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
213 const Vector strain_minus = r_perturbed_strain;
214 const Vector stress_minus = r_perturbed_integrated_stress;
217 CalculateComponentsToTangentTensorSecondOrder(auxiliary_tensor, strain_plus, strain_minus, stress_plus, stress_minus, i_component);
220 noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
221 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
223 }
else if (ApproximationOrder == 4) {
224 for (
IndexType i_component = 0; i_component < num_components; ++i_component) {
226 PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
229 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
232 const Vector strain_plus = r_perturbed_strain;
233 const Vector stress_plus = r_perturbed_integrated_stress;
236 noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
237 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
240 PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, 2.0*pertubation, i_component);
243 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
246 const Vector strain_2_plus = r_perturbed_strain;
247 const Vector stress_2_plus = r_perturbed_integrated_stress;
250 const SizeType voigt_size = stress_plus.size();
252 auxiliary_tensor(
row, i_component) = (stress_plus[
row] - unperturbed_stress_vector_gp[
row]) / pertubation - (stress_2_plus[
row] - 2.0 * stress_plus[
row] + unperturbed_stress_vector_gp[
row]) / (2.0 * pertubation);
256 noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
257 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
260 if (symmetrize_operator)
261 noalias(r_tangent_tensor) = 0.5*(auxiliary_tensor +
trans(auxiliary_tensor));
263 noalias(r_tangent_tensor) = auxiliary_tensor;
276 const bool ConsiderPertubationThreshold =
true,
285 const bool symmetrize_operator = (r_properties.Has(SYMMETRIZE_TANGENT_OPERATOR)) ? r_properties[SYMMETRIZE_TANGENT_OPERATOR] :
false;
288 const SizeType num_components = unperturbed_stress_vector_gp.size();
296 r_tangent_tensor.
clear();
299 const std::size_t size1 = unperturbed_deformation_gradient_gp.size1();
300 const std::size_t size2 = unperturbed_deformation_gradient_gp.size2();
302 KRATOS_ERROR_IF_NOT(ApproximationOrder == 1 || ApproximationOrder == 2) <<
"The approximation order for the perturbation is " << ApproximationOrder <<
". Options are 1 and 2" << std::endl;
306 if (r_properties.Has(PERTURBATION_SIZE)) {
307 pertubation = r_properties[PERTURBATION_SIZE];
309 for (
IndexType i_component = 0; i_component < num_components; ++i_component) {
310 double component_perturbation;
311 CalculatePerturbation(unperturbed_strain_vector_gp, i_component, component_perturbation);
312 pertubation =
std::max(component_perturbation, pertubation);
322 double& r_perturbed_det_deformation_gradient =
const_cast<double&
>(rValues.
GetDeterminantF());
324 if (ApproximationOrder == 1) {
325 for (
IndexType i_component = 0; i_component < size1; ++i_component) {
326 for (
IndexType j_component = i_component; j_component < size2; ++j_component) {
328 PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, pertubation, i_component, j_component);
331 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
334 const Vector delta_stress = r_perturbed_integrated_stress - unperturbed_stress_vector_gp;
337 const IndexType voigt_index = CalculateVoigtIndex(delta_stress.size(), i_component, j_component);
338 CalculateComponentsToTangentTensorFirstOrder(auxiliary_tensor, r_perturbed_strain-unperturbed_strain_vector_gp, delta_stress, voigt_index);
341 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
342 noalias(r_perturbed_deformation_gradient) = unperturbed_deformation_gradient_gp;
343 r_perturbed_det_deformation_gradient = det_unperturbed_deformation_gradient_gp;
346 }
else if (ApproximationOrder == 2) {
347 for (
IndexType i_component = 0; i_component < size1; ++i_component) {
348 for (
IndexType j_component = i_component; j_component < size2; ++j_component) {
350 PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, pertubation, i_component, j_component);
353 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
356 const Vector strain_plus = r_perturbed_strain;
357 const Vector stress_plus = r_perturbed_integrated_stress;
360 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
361 noalias(r_perturbed_deformation_gradient) = unperturbed_deformation_gradient_gp;
362 r_perturbed_det_deformation_gradient = det_unperturbed_deformation_gradient_gp;
365 PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, - pertubation, i_component, j_component);
368 IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
371 const Vector strain_minus = r_perturbed_strain;
372 const Vector stress_minus = r_perturbed_integrated_stress;
375 const IndexType voigt_index = CalculateVoigtIndex(stress_plus.size(), i_component, j_component);
376 CalculateComponentsToTangentTensorSecondOrder(auxiliary_tensor, strain_plus, strain_minus, stress_plus, stress_minus, voigt_index);
379 noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
380 noalias(r_perturbed_deformation_gradient) = unperturbed_deformation_gradient_gp;
381 r_perturbed_det_deformation_gradient = det_unperturbed_deformation_gradient_gp;
385 if (symmetrize_operator)
386 noalias(r_tangent_tensor) = 0.5*(auxiliary_tensor +
trans(auxiliary_tensor));
388 noalias(r_tangent_tensor) = auxiliary_tensor;
401 const bool ConsiderPertubationThreshold =
true,
459 static void CalculatePerturbation(
460 const Vector& rStrainVector,
462 double& rPerturbation
465 double perturbation_1, perturbation_2;
466 if (std::abs(rStrainVector[Component]) >
tolerance) {
469 double min_strain_component;
470 GetMinAbsValue(rStrainVector, min_strain_component);
473 double max_strain_component;
474 GetMaxAbsValue(rStrainVector, max_strain_component);
476 rPerturbation =
std::max(perturbation_1, perturbation_2);
486 static void CalculatePerturbationFiniteDeformation(
487 const Matrix& rDeformationGradient,
490 double& rPerturbation
493 double perturbation_1, perturbation_2;
494 if (std::abs(rDeformationGradient(ComponentI, ComponentJ)) >
tolerance) {
497 double min_strain_component;
498 GetMinAbsValue(rDeformationGradient, min_strain_component);
501 double max_strain_component;
502 GetMaxAbsValue(rDeformationGradient, max_strain_component);
504 rPerturbation =
std::max(perturbation_1, perturbation_2);
514 static void PerturbateStrainVector(
515 Vector& rPerturbedStrainVector,
516 const Vector& rStrainVectorGP,
517 const double Perturbation,
521 noalias(rPerturbedStrainVector) = rStrainVectorGP;
522 rPerturbedStrainVector[Component] += Perturbation;
533 static void PerturbateDeformationGradient(
534 Matrix& rPerturbedDeformationGradient,
535 const Matrix& rDeformationGradientGP,
536 const double Perturbation,
542 if (ComponentI == ComponentJ) {
543 aux_perturbation_matrix(ComponentI, ComponentJ) += Perturbation;
545 aux_perturbation_matrix(ComponentI, ComponentJ) += 0.5 * Perturbation;
546 aux_perturbation_matrix(ComponentJ, ComponentI) += 0.5 * Perturbation;
548 noalias(rPerturbedDeformationGradient) =
prod(aux_perturbation_matrix, rDeformationGradientGP);
557 static void IntegratePerturbedStrain(
558 ConstitutiveLaw::Parameters& rValues,
559 ConstitutiveLaw* pConstitutiveLaw,
563 Flags& cl_options = rValues.GetOptions();
566 const bool flag_back_up_1 = cl_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR);
567 const bool flag_back_up_2 = cl_options.Is(ConstitutiveLaw::COMPUTE_STRESS);
569 cl_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR,
false);
570 cl_options.Set(ConstitutiveLaw::COMPUTE_STRESS,
true);
572 pConstitutiveLaw->CalculateMaterialResponse(rValues, rStressMeasure);
574 cl_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR, flag_back_up_1);
575 cl_options.Set(ConstitutiveLaw::COMPUTE_STRESS, flag_back_up_2);
583 static void GetMaxAbsValue(
584 const Vector& rArrayValues,
592 if (std::abs(rArrayValues[
i]) > aux) {
593 aux = std::abs(rArrayValues[
i]);
605 static void GetMaxAbsValue(
606 const Matrix& rMatrixValues,
611 const SizeType size1 = rMatrixValues.size1();
612 const SizeType size2 = rMatrixValues.size2();
620 if (std::abs(working_matrix(
i,
j)) > aux) {
621 aux = std::abs(working_matrix(
i,
j));
634 static void GetMinAbsValue(
635 const Vector& rArrayValues,
643 if (std::abs(rArrayValues[
i]) < aux) {
644 aux = std::abs(rArrayValues[
i]);
656 static void GetMinAbsValue(
657 const Matrix& rMatrixValues,
662 const SizeType size1 = rMatrixValues.size1();
663 const SizeType size2 = rMatrixValues.size2();
671 if (std::abs(working_matrix(
i,
j)) < aux) {
672 aux = std::abs(working_matrix(
i,
j));
687 static void CalculateComponentsToTangentTensorFirstOrder(
689 const Vector& rVectorStrain,
690 const Vector& rDeltaStress,
694 const double perturbation = rVectorStrain[Component];
695 const SizeType voigt_size = rDeltaStress.size();
697 rTangentTensor(
row, Component) = rDeltaStress[
row] / perturbation;
710 static void CalculateComponentsToTangentTensorSecondOrder(
712 const Vector& rVectorStrainPlus,
713 const Vector& rVectorStrainMinus,
714 const Vector& rStressPlus,
715 const Vector& rStressMinus,
719 const double perturbation = (rVectorStrainPlus[Component] - rVectorStrainMinus[Component]);
720 const SizeType voigt_size = rStressPlus.size();
722 rTangentTensor(
row, Component) = (rStressPlus[
row] - rStressMinus[
row]) / perturbation;
738 if (VoigtSize == 6) {
Definition: constitutive_law.h:47
StressMeasure
Definition: constitutive_law.h:69
@ StressMeasure_Cauchy
Definition: constitutive_law.h:73
@ StressMeasure_PK2
Definition: constitutive_law.h:71
bool Is(Flags const &rOther) const
Definition: flags.h:274
void clear()
Definition: amatrix_interface.h:284
An algorithm that derives numerically the constitutive tangent tensor at one GP.
Definition: tangent_operator_calculator_utility.h:57
static void CalculateTangentTensorFiniteDeformation(ConstitutiveLaw::Parameters &rValues, ConstitutiveLaw *pConstitutiveLaw, const ConstitutiveLaw::StressMeasure &rStressMeasure=ConstitutiveLaw::StressMeasure_PK2, const bool ConsiderPertubationThreshold=true, const IndexType ApproximationOrder=2)
Main method that computes the tangent tensor (for finite deformation problems)
Definition: tangent_operator_calculator_utility.h:397
static void CalculateTangentTensorSmallDeformationProvidedStrain(ConstitutiveLaw::Parameters &rValues, ConstitutiveLaw *pConstitutiveLaw, const ConstitutiveLaw::StressMeasure &rStressMeasure=ConstitutiveLaw::StressMeasure_Cauchy, const bool ConsiderPertubationThreshold=true, const IndexType ApproximationOrder=2)
Main method that computes the tangent tensor (provided strain)
Definition: tangent_operator_calculator_utility.h:132
static void CalculateTangentTensor(ConstitutiveLaw::Parameters &rValues, ConstitutiveLaw *pConstitutiveLaw, const ConstitutiveLaw::StressMeasure &rStressMeasure=ConstitutiveLaw::StressMeasure_Cauchy, const bool ConsiderPertubationThreshold=true, const IndexType ApproximationOrder=2)
Main method that computes the tangent tensor.
Definition: tangent_operator_calculator_utility.h:107
std::size_t IndexType
Definition of index type.
Definition: tangent_operator_calculator_utility.h:69
static constexpr double PerturbationCoefficient2
Definition: tangent_operator_calculator_utility.h:76
static void CalculateTangentTensorSmallDeformationNotProvidedStrain(ConstitutiveLaw::Parameters &rValues, ConstitutiveLaw *pConstitutiveLaw, const ConstitutiveLaw::StressMeasure &rStressMeasure=ConstitutiveLaw::StressMeasure_Cauchy, const bool ConsiderPertubationThreshold=true, const IndexType ApproximationOrder=2)
Main method that computes the tangent tensor (not provided strain)
Definition: tangent_operator_calculator_utility.h:272
static constexpr double tolerance
Definition of the zero tolerance.
Definition: tangent_operator_calculator_utility.h:72
KRATOS_CLASS_POINTER_DEFINITION(TangentOperatorCalculatorUtility)
Pointer definition of TangentOperatorCalculatorUtility.
static constexpr double PerturbationCoefficient1
Definition: tangent_operator_calculator_utility.h:75
TangentOperatorCalculatorUtility()
Constructor.
Definition: tangent_operator_calculator_utility.h:86
std::size_t SizeType
Definition of size type.
Definition: tangent_operator_calculator_utility.h:66
virtual ~TangentOperatorCalculatorUtility()
Destructor.
Definition: tangent_operator_calculator_utility.h:91
static constexpr double PerturbationThreshold
Definition: tangent_operator_calculator_utility.h:79
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
static double max(double a, double b)
Definition: GeometryFunctions.h:79
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
AMatrix::IdentityMatrix< double > IdentityMatrix
Definition: amatrix_interface.h:564
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
Internals::Matrix< double, AMatrix::dynamic, AMatrix::dynamic > Matrix
Definition: amatrix_interface.h:470
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17
Definition: constitutive_law.h:189
const double & GetDeterminantF()
Definition: constitutive_law.h:414
Flags & GetOptions()
Definition: constitutive_law.h:412
StrainVectorType & GetStrainVector()
Definition: constitutive_law.h:435
const DeformationGradientMatrixType & GetDeformationGradientF()
Definition: constitutive_law.h:429
const Properties & GetMaterialProperties()
Definition: constitutive_law.h:457
VoigtSizeMatrixType & GetConstitutiveMatrix()
Definition: constitutive_law.h:446
StressVectorType & GetStressVector()
Definition: constitutive_law.h:440