KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
tangent_operator_calculator_utility.h
Go to the documentation of this file.
1 // KRATOS ___ _ _ _ _ _ __ _
2 // / __\___ _ __ ___| |_(_) |_ _ _| |_(_)_ _____ / / __ ___ _____ /_\ _ __ _ __
3 // / / / _ \| '_ \/ __| __| | __| | | | __| \ \ / / _ \/ / / _` \ \ /\ / / __| //_\\| '_ \| '_ |
4 // / /__| (_) | | | \__ \ |_| | |_| |_| | |_| |\ V / __/ /__| (_| |\ V V /\__ \/ _ \ |_) | |_) |
5 // \____/\___/|_| |_|___/\__|_|\__|\__,_|\__|_| \_/ \___\____/\__,_| \_/\_/ |___/\_/ \_/ .__/| .__/
6 // |_| |_|
7 //
8 // License: BSD License
9 // license: structural_mechanics_application/license.txt
10 //
11 // Main authors: Alejandro Cornejo & Lucia Barbu
12 // Collaborator: Vicente Mataix Ferrandiz
13 //
14 
15 #pragma once
16 
17 // System includes
18 
19 // External includes
20 
21 // Project includes
25 
26 namespace Kratos
27 {
28 
31 
35 
39 
43 
47 
57 {
58 public:
61 
64 
66  typedef std::size_t SizeType;
67 
69  typedef std::size_t IndexType;
70 
72  static constexpr double tolerance = std::numeric_limits<double>::epsilon();
73 
74  // Definition of the perturbation coefficients
75  static constexpr double PerturbationCoefficient1 = 1.0e-5;
76  static constexpr double PerturbationCoefficient2 = 1.0e-10;
77 
78  // Definition of the perturbation threshold
79  static constexpr double PerturbationThreshold = 1.0e-8;
80 
84 
87  {
88  }
89 
92 
96 
100 
109  ConstitutiveLaw* pConstitutiveLaw,
111  const bool ConsiderPertubationThreshold = true,
112  const IndexType ApproximationOrder = 2
113  )
114  {
115  // Ensure the proper flag
116  Flags& cl_options = rValues.GetOptions();
117  const bool use_element_provided_strain = cl_options.Is(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN);
118 
119  if (use_element_provided_strain) {
120  CalculateTangentTensorSmallDeformationProvidedStrain(rValues, pConstitutiveLaw, rStressMeasure, ConsiderPertubationThreshold, ApproximationOrder);
121  } else {
122  CalculateTangentTensorSmallDeformationNotProvidedStrain(rValues, pConstitutiveLaw, rStressMeasure, ConsiderPertubationThreshold, ApproximationOrder);
123  }
124  }
125 
134  ConstitutiveLaw *pConstitutiveLaw,
136  const bool ConsiderPertubationThreshold = true,
137  const IndexType ApproximationOrder = 2
138  )
139  {
140  // Converged values to be storaged
141  const Vector unperturbed_strain_vector_gp = Vector(rValues.GetStrainVector());
142  const Vector unperturbed_stress_vector_gp = Vector(rValues.GetStressVector());
143  const auto &r_properties = rValues.GetMaterialProperties();
144  const bool symmetrize_operator = (r_properties.Has(SYMMETRIZE_TANGENT_OPERATOR)) ? r_properties[SYMMETRIZE_TANGENT_OPERATOR] : false;
145 
146  // The number of components
147  const SizeType num_components = unperturbed_stress_vector_gp.size();
148 
149  // The tangent tensor
150  Matrix& r_tangent_tensor = rValues.GetConstitutiveMatrix();
151  r_tangent_tensor.clear();
152  Matrix auxiliary_tensor = ZeroMatrix(num_components,num_components);
153 
154  // Calculate the perturbation
155  double pertubation = PerturbationThreshold;
156  if (r_properties.Has(PERTURBATION_SIZE)) {
157  pertubation = r_properties[PERTURBATION_SIZE];
158  if (pertubation == -1.0)
159  pertubation = std::sqrt(tolerance);
160  } else {
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);
165  }
166  // We check that the perturbation has a threshold value of PerturbationThreshold
167  if (ConsiderPertubationThreshold && pertubation < PerturbationThreshold) pertubation = PerturbationThreshold;
168  }
169 
170  // Loop over components of the strain
171  Vector& r_perturbed_strain = rValues.GetStrainVector();
172  Vector& r_perturbed_integrated_stress = rValues.GetStressVector();
173  if (ApproximationOrder == 1) {
174  for (IndexType i_component = 0; i_component < num_components; ++i_component) {
175 
176  // Apply the perturbation
177  PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
178 
179  // We continue with the calculations
180  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
181 
182  // Compute tangent moduli
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);
185 
186  // Reset the values to the initial ones
187  noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
188  noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
189  }
190  } else if (ApproximationOrder == 2) {
191  for (IndexType i_component = 0; i_component < num_components; ++i_component) {
192  // Apply the perturbation (positive)
193  PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
194 
195  // We continue with the calculations
196  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
197 
198  // Compute stress (plus)
199  const Vector strain_plus = r_perturbed_strain;
200  const Vector stress_plus = r_perturbed_integrated_stress;
201 
202  // Reset the values to the initial ones
203  noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
204  noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
205 
206  // Apply the perturbation (negative)
207  PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, - pertubation, i_component);
208 
209  // We continue with the calculations
210  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
211 
212  // Compute stress (minus)
213  const Vector strain_minus = r_perturbed_strain;
214  const Vector stress_minus = r_perturbed_integrated_stress;
215 
216  // Finally we compute the components
217  CalculateComponentsToTangentTensorSecondOrder(auxiliary_tensor, strain_plus, strain_minus, stress_plus, stress_minus, i_component);
218 
219  // Reset the values to the initial ones
220  noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
221  noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
222  }
223  } else if (ApproximationOrder == 4) { // Second order but with another approach. It is computed as first order but taking into account the second derivatives
224  for (IndexType i_component = 0; i_component < num_components; ++i_component) {
225  // Apply the perturbation (positive)
226  PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, pertubation, i_component);
227 
228  // We continue with the calculations
229  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
230 
231  // Compute stress (plus)
232  const Vector strain_plus = r_perturbed_strain;
233  const Vector stress_plus = r_perturbed_integrated_stress;
234 
235  // Reset the values to the initial ones
236  noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
237  noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
238 
239  // Apply the perturbation twice
240  PerturbateStrainVector(r_perturbed_strain, unperturbed_strain_vector_gp, 2.0*pertubation, i_component);
241 
242  // We continue with the calculations
243  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
244 
245  // Compute stress (minus)
246  const Vector strain_2_plus = r_perturbed_strain;
247  const Vector stress_2_plus = r_perturbed_integrated_stress;
248 
249  // Finally we compute the components
250  const SizeType voigt_size = stress_plus.size();
251  for (IndexType row = 0; row < voigt_size; ++row) {
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);
253  }
254 
255  // Reset the values to the initial ones
256  noalias(r_perturbed_strain) = unperturbed_strain_vector_gp;
257  noalias(r_perturbed_integrated_stress) = unperturbed_stress_vector_gp;
258  }
259  }
260  if (symmetrize_operator)
261  noalias(r_tangent_tensor) = 0.5*(auxiliary_tensor + trans(auxiliary_tensor));
262  else
263  noalias(r_tangent_tensor) = auxiliary_tensor;
264  }
265 
274  ConstitutiveLaw *pConstitutiveLaw,
276  const bool ConsiderPertubationThreshold = true,
277  const IndexType ApproximationOrder = 2
278  )
279  {
280  // Converged values to be storaged
281  const Vector unperturbed_strain_vector_gp = Vector(rValues.GetStrainVector());
282  const Vector unperturbed_stress_vector_gp = Vector(rValues.GetStressVector());
283 
284  const auto &r_properties = rValues.GetMaterialProperties();
285  const bool symmetrize_operator = (r_properties.Has(SYMMETRIZE_TANGENT_OPERATOR)) ? r_properties[SYMMETRIZE_TANGENT_OPERATOR] : false;
286 
287  // The number of components
288  const SizeType num_components = unperturbed_stress_vector_gp.size();
289 
290  // Converged values to be storaged (only used in case of elements that not provide the strain)
291  const Matrix unperturbed_deformation_gradient_gp = Matrix(rValues.GetDeformationGradientF());
292  const double det_unperturbed_deformation_gradient_gp = double(rValues.GetDeterminantF());
293 
294  // The tangent tensor
295  Matrix& r_tangent_tensor = rValues.GetConstitutiveMatrix();
296  r_tangent_tensor.clear();
297  Matrix auxiliary_tensor = ZeroMatrix(num_components,num_components);
298 
299  const std::size_t size1 = unperturbed_deformation_gradient_gp.size1();
300  const std::size_t size2 = unperturbed_deformation_gradient_gp.size2();
301 
302  KRATOS_ERROR_IF_NOT(ApproximationOrder == 1 || ApproximationOrder == 2) << "The approximation order for the perturbation is " << ApproximationOrder << ". Options are 1 and 2" << std::endl;
303 
304  // Calculate the perturbation
305  double pertubation = PerturbationThreshold;
306  if (r_properties.Has(PERTURBATION_SIZE)) {
307  pertubation = r_properties[PERTURBATION_SIZE];
308  } else {
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);
313  }
314  // We check that the perturbation has a threshold value of PerturbationThreshold
315  if (ConsiderPertubationThreshold && pertubation < PerturbationThreshold) pertubation = PerturbationThreshold;
316  }
317 
318  // Loop over components of the strain
319  Vector& r_perturbed_strain = rValues.GetStrainVector();
320  Vector& r_perturbed_integrated_stress = rValues.GetStressVector();
321  Matrix& r_perturbed_deformation_gradient = const_cast<Matrix&>(rValues.GetDeformationGradientF());
322  double& r_perturbed_det_deformation_gradient = const_cast<double&>(rValues.GetDeterminantF());
323 
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) {
327  // Apply the perturbation
328  PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, pertubation, i_component, j_component);
329 
330  // We continue with the calculations
331  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
332 
333  // Compute delta stress
334  const Vector delta_stress = r_perturbed_integrated_stress - unperturbed_stress_vector_gp;
335 
336  // Finally we compute the components
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);
339 
340  // Reset the values to the initial ones
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;
344  }
345  }
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) {
349  // Apply the perturbation (positive)
350  PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, pertubation, i_component, j_component);
351 
352  // We continue with the calculations
353  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
354 
355  // Compute stress (plus)
356  const Vector strain_plus = r_perturbed_strain;
357  const Vector stress_plus = r_perturbed_integrated_stress;
358 
359  // Reset the values to the initial ones
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;
363 
364  // Apply the perturbation (negative)
365  PerturbateDeformationGradient(r_perturbed_deformation_gradient, unperturbed_deformation_gradient_gp, - pertubation, i_component, j_component);
366 
367  // We continue with the calculations
368  IntegratePerturbedStrain(rValues, pConstitutiveLaw, rStressMeasure);
369 
370  // Compute stress (minus)
371  const Vector strain_minus = r_perturbed_strain;
372  const Vector stress_minus = r_perturbed_integrated_stress;
373 
374  // Finally we compute the components
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);
377 
378  // Reset the values to the initial ones
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;
382  }
383  }
384  }
385  if (symmetrize_operator)
386  noalias(r_tangent_tensor) = 0.5*(auxiliary_tensor + trans(auxiliary_tensor));
387  else
388  noalias(r_tangent_tensor) = auxiliary_tensor;
389  }
390 
399  ConstitutiveLaw* pConstitutiveLaw,
401  const bool ConsiderPertubationThreshold = true,
402  const IndexType ApproximationOrder = 2
403  )
404  {
405  CalculateTangentTensorSmallDeformationNotProvidedStrain(rValues, pConstitutiveLaw, rStressMeasure, ConsiderPertubationThreshold, ApproximationOrder);
406  }
407 
408 protected:
411 
415 
419 
423 
427 
431 
435 
437 private:
440 
444 
448 
452 
459  static void CalculatePerturbation(
460  const Vector& rStrainVector,
461  const IndexType Component,
462  double& rPerturbation
463  )
464  {
465  double perturbation_1, perturbation_2;
466  if (std::abs(rStrainVector[Component]) > tolerance) {
467  perturbation_1 = PerturbationCoefficient1 * rStrainVector[Component];
468  } else {
469  double min_strain_component;
470  GetMinAbsValue(rStrainVector, min_strain_component);
471  perturbation_1 = PerturbationCoefficient1 * min_strain_component;
472  }
473  double max_strain_component;
474  GetMaxAbsValue(rStrainVector, max_strain_component);
475  perturbation_2 = PerturbationCoefficient2 * max_strain_component;
476  rPerturbation = std::max(perturbation_1, perturbation_2);
477  }
478 
486  static void CalculatePerturbationFiniteDeformation(
487  const Matrix& rDeformationGradient,
488  const IndexType ComponentI,
489  const IndexType ComponentJ,
490  double& rPerturbation
491  )
492  {
493  double perturbation_1, perturbation_2;
494  if (std::abs(rDeformationGradient(ComponentI, ComponentJ)) > tolerance) {
495  perturbation_1 = PerturbationCoefficient1 * rDeformationGradient(ComponentI, ComponentJ);
496  } else {
497  double min_strain_component;
498  GetMinAbsValue(rDeformationGradient, min_strain_component);
499  perturbation_1 = PerturbationCoefficient1 * min_strain_component;
500  }
501  double max_strain_component;
502  GetMaxAbsValue(rDeformationGradient, max_strain_component);
503  perturbation_2 = PerturbationCoefficient2 * max_strain_component;
504  rPerturbation = std::max(perturbation_1, perturbation_2);
505  }
506 
514  static void PerturbateStrainVector(
515  Vector& rPerturbedStrainVector,
516  const Vector& rStrainVectorGP,
517  const double Perturbation,
518  const IndexType Component
519  )
520  {
521  noalias(rPerturbedStrainVector) = rStrainVectorGP;
522  rPerturbedStrainVector[Component] += Perturbation;
523  }
524 
533  static void PerturbateDeformationGradient(
534  Matrix& rPerturbedDeformationGradient,
535  const Matrix& rDeformationGradientGP,
536  const double Perturbation,
537  const IndexType ComponentI,
538  const IndexType ComponentJ
539  )
540  {
541  Matrix aux_perturbation_matrix = IdentityMatrix(rDeformationGradientGP.size1());
542  if (ComponentI == ComponentJ) {
543  aux_perturbation_matrix(ComponentI, ComponentJ) += Perturbation;
544  } else {
545  aux_perturbation_matrix(ComponentI, ComponentJ) += 0.5 * Perturbation;
546  aux_perturbation_matrix(ComponentJ, ComponentI) += 0.5 * Perturbation;
547  }
548  noalias(rPerturbedDeformationGradient) = prod(aux_perturbation_matrix, rDeformationGradientGP);
549  }
550 
557  static void IntegratePerturbedStrain(
558  ConstitutiveLaw::Parameters& rValues,
559  ConstitutiveLaw* pConstitutiveLaw,
561  )
562  {
563  Flags& cl_options = rValues.GetOptions();
564 
565  // In order to avoid recursivity...
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);
568 
569  cl_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR, false);
570  cl_options.Set(ConstitutiveLaw::COMPUTE_STRESS, true);
571 
572  pConstitutiveLaw->CalculateMaterialResponse(rValues, rStressMeasure);
573 
574  cl_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR, flag_back_up_1);
575  cl_options.Set(ConstitutiveLaw::COMPUTE_STRESS, flag_back_up_2);
576  }
577 
583  static void GetMaxAbsValue(
584  const Vector& rArrayValues,
585  double& rMaxValue
586  )
587  {
588  const SizeType dimension = rArrayValues.size();
589 
590  double aux = 0.0;
591  for (IndexType i = 0; i < dimension; ++i) {
592  if (std::abs(rArrayValues[i]) > aux) {
593  aux = std::abs(rArrayValues[i]);
594  }
595  }
596 
597  rMaxValue = aux;
598  }
599 
605  static void GetMaxAbsValue(
606  const Matrix& rMatrixValues,
607  double& rMaxValue
608  )
609  {
610  // Sizes of the matrix
611  const SizeType size1 = rMatrixValues.size1();
612  const SizeType size2 = rMatrixValues.size2();
613 
614  // The deformation gradient is an identity matrix for zero deformation
615  const Matrix working_matrix = rMatrixValues - IdentityMatrix(size1);
616 
617  double aux = 0.0;
618  for (IndexType i = 0; i < size1; ++i) {
619  for (IndexType j = 0; j < size2; ++j) {
620  if (std::abs(working_matrix(i, j)) > aux) {
621  aux = std::abs(working_matrix(i, j));
622  }
623  }
624  }
625 
626  rMaxValue = aux;
627  }
628 
634  static void GetMinAbsValue(
635  const Vector& rArrayValues,
636  double& rMinValue
637  )
638  {
639  const SizeType dimension = rArrayValues.size();
640 
641  double aux = std::numeric_limits<double>::max();
642  for (IndexType i = 0; i < dimension; ++i) {
643  if (std::abs(rArrayValues[i]) < aux) {
644  aux = std::abs(rArrayValues[i]);
645  }
646  }
647 
648  rMinValue = aux;
649  }
650 
656  static void GetMinAbsValue(
657  const Matrix& rMatrixValues,
658  double& rMinValue
659  )
660  {
661  // Sizes of the matrix
662  const SizeType size1 = rMatrixValues.size1();
663  const SizeType size2 = rMatrixValues.size2();
664 
665  // The deformation gradient is an identity matrix for zero deformation
666  const Matrix working_matrix = rMatrixValues - IdentityMatrix(size1);
667 
668  double aux = std::numeric_limits<double>::max();
669  for (IndexType i = 0; i < size1; ++i) {
670  for (IndexType j = 0; j < size2; ++j) {
671  if (std::abs(working_matrix(i, j)) < aux) {
672  aux = std::abs(working_matrix(i, j));
673  }
674  }
675  }
676 
677  rMinValue = aux;
678  }
679 
687  static void CalculateComponentsToTangentTensorFirstOrder(
688  Matrix& rTangentTensor,
689  const Vector& rVectorStrain,
690  const Vector& rDeltaStress,
691  const IndexType Component
692  )
693  {
694  const double perturbation = rVectorStrain[Component];
695  const SizeType voigt_size = rDeltaStress.size();
696  for (IndexType row = 0; row < voigt_size; ++row) {
697  rTangentTensor(row, Component) = rDeltaStress[row] / perturbation;
698  }
699  }
700 
710  static void CalculateComponentsToTangentTensorSecondOrder(
711  Matrix& rTangentTensor,
712  const Vector& rVectorStrainPlus,
713  const Vector& rVectorStrainMinus,
714  const Vector& rStressPlus,
715  const Vector& rStressMinus,
716  const IndexType Component
717  )
718  {
719  const double perturbation = (rVectorStrainPlus[Component] - rVectorStrainMinus[Component]);
720  const SizeType voigt_size = rStressPlus.size();
721  for (IndexType row = 0; row < voigt_size; ++row) {
722  rTangentTensor(row, Component) = (rStressPlus[row] - rStressMinus[row]) / perturbation;
723  }
724  }
725 
732  static IndexType CalculateVoigtIndex(
733  const SizeType VoigtSize,
734  const IndexType ComponentI,
735  const IndexType ComponentJ
736  )
737  {
738  if (VoigtSize == 6) {
739  switch(ComponentI) {
740  case 0:
741  switch(ComponentJ) {
742  case 0:
743  return 0;
744  case 1:
745  return 3;
746  case 2:
747  return 5;
748  default:
749  return 0;
750  }
751  case 1:
752  switch(ComponentJ) {
753  case 0:
754  return 3;
755  case 1:
756  return 1;
757  case 2:
758  return 4;
759  default:
760  return 0;
761  }
762  case 2:
763  switch(ComponentJ) {
764  case 0:
765  return 5;
766  case 1:
767  return 4;
768  case 2:
769  return 2;
770  default:
771  return 0;
772  }
773  default:
774  return 0;
775  }
776  } else {
777  switch(ComponentI) {
778  case 0:
779  switch(ComponentJ) {
780  case 0:
781  return 0;
782  case 1:
783  return 2;
784  default:
785  return 0;
786  }
787  case 1:
788  switch(ComponentJ) {
789  case 0:
790  return 2;
791  case 1:
792  return 1;
793  default:
794  return 0;
795  }
796  default:
797  return 0;
798  }
799  }
800  }
801 
802 protected:
805 
809 
813 
817 
821 
825 
829 
831 private:
834 
838 
842 
846 
850 
854 
858 
861 };
862 } // namespace Kratos.
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
Definition: flags.h:58
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