https://mooseframework.inl.gov
Loading...
Searching...
No Matches
RankTwoScalarTools.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12// MOOSE includes
13#include "MooseEnum.h"
14#include "MooseTypes.h"
15#include "libmesh/point.h"
16#include "RankTwoTensor.h"
17#include "MooseError.h"
18#include "MooseUtils.h"
19
21{
22/*
23 * Return the scalar_type MooseEnum
24 */
26
30
48
55
57{
60};
61
62/*
63 * Extracts the value of the tensor component at the specified indices
64 */
65template <typename T>
66T
67component(const RankTwoTensorTempl<T> & r2tensor, unsigned int i, unsigned int j)
68{
69 return r2tensor(i, j);
70}
71
72/*
73 * Extracts the value of the tensor component at the specified indices and
74 * updates the unit direction vector.
75 */
76template <typename T>
77T
78component(const RankTwoTensorTempl<T> & r2tensor, unsigned int i, unsigned int j, Point & direction)
79{
80 direction.zero();
81 if (i == j)
82 direction(i) = 1.0;
83 else
84 {
85 direction(i) = std::sqrt(0.5);
86 direction(j) = std::sqrt(0.5);
87 }
88
89 return r2tensor(i, j);
90}
91
92/*
93 * The von Mises Stress is calculated in the deviatoric stress space:
94 * \sigma_{vm} = \sqrt{\frac{3}{2}S_{ij}S_{ij}}
95 * This scalar quanitity is often used to determine the onset of plasticity by
96 * comparing the von Mises stress to the yield stress in J2 plasticity models.
97 */
98template <typename T>
99T
101{
102 RankTwoTensorTempl<T> dev_stress = stress.deviatoric();
103
104 return std::sqrt(1.5 * dev_stress.doubleContraction(dev_stress));
105}
106
107/*
108 * The effective strain increment (or equivalent von Mises strain) is calculated as
109 * \epsilon_{eff} = \sqrt{\frac{2}{3}\epsilon_{ij} \epsilon_{ij}}
110 */
111template <typename T>
112T
114{
115 return std::sqrt(2.0 / 3.0 * strain.doubleContraction(strain));
116}
117
118/*
119 * The hydrostatic scalar of a tensor is computed as the sum of the diagonal
120 * terms divided by 3.
121 */
122template <typename T>
123T
125{
126 return r2tensor.trace() / 3.0;
127}
128
129/*
130 * Computes the L2 normal of a rank two tensor
131 */
132template <typename T>
133T
135{
136 return r2tensor.L2norm();
137}
138
139/*
140 * The volumentric strain is the change in volume over the original volume. In
141 * this method the squared and cubic terms are included so that the calculation
142 * is valid for both small and finite strains.
143 * Since the strains are logarithmic strains, which are by definition log(L/L0),
144 * exp(log_strain) = L/L0
145 * The ratio of the volume change of a strained cube to the original volume
146 * (delta V / V) is thus:
147 * exp(log_strain_11) * exp(log_strain_22) * exp(log_strain_33) - 1
148 *
149 * Since eng_strain = exp(log_strain) - 1, the equivalent calculation using
150 * engineering strains would be:
151 * (1 + eng_strain_11) * (1 + eng_strain_22) + (1 + eng_strain_33) - 1
152 * If strains are small, the resulting terms that involve squared and cubed
153 * strains are negligible, resulting in the following approximate form:
154 * strain_11 + strain_22 + strain_33
155 * There is not currently an option to compute this small-strain form of the
156 * volumetric strain, but at small strains, it is approximately equal to the
157 * finite strain form that is computed.
158 *
159 * @param strain Total logarithmic strain
160 * @return volumetric strain (delta V / V)
161 */
162template <typename T>
163T
165{
166 return std::exp(strain(0, 0)) * std::exp(strain(1, 1)) * std::exp(strain(2, 2)) - 1.0;
167}
168
169/*
170 * The first invariant of a tensor is the sum of the diagonal component; defined
171 * in L. Malvern, Introduction to the Mechanics of a Continuous Mediam (1969) pg 89.
172 */
173template <typename T>
174T
176{
177 return r2tensor.trace();
178}
179
180/*
181 * The second invariant is calculated using the formula from K. Hjelmstad,
182 * Fundamentals of Structural Mechanics (1997) pg. 24.
183 * Note that the Hjelmstad version of the second invariant is the negative of
184 * the second invariant given in L. Malvern, Introduction to the Mechanics of a
185 * Continuous Medium (1969) pg 89.
186 */
187template <typename T>
188T
190{
191 T val = 0.0;
192 for (unsigned int i = 0; i < 2; ++i)
193 for (unsigned int j = i + 1; j < 3; ++j)
194 {
195 val += r2tensor(i, i) * r2tensor(j, j);
196 val -= (r2tensor(i, j) * r2tensor(i, j) + r2tensor(j, i) * r2tensor(j, i)) * 0.5;
197 }
198
199 return val;
200}
201
202/*
203 * The third invariant of a rank 2 tensor is the determinate of the tensor; defined
204 * in L. Malvern, Introduction to the Mechanics of a Continuous Mediam (1969) pg 89.
205 */
206template <typename T>
207T
209{
210 T val = 0.0;
211 val = r2tensor(0, 0) * r2tensor(1, 1) * r2tensor(2, 2) -
212 r2tensor(0, 0) * r2tensor(1, 2) * r2tensor(2, 1) +
213 r2tensor(0, 1) * r2tensor(1, 2) * r2tensor(2, 0) -
214 r2tensor(0, 1) * r2tensor(1, 0) * r2tensor(2, 2) +
215 r2tensor(0, 2) * r2tensor(1, 0) * r2tensor(2, 1) -
216 r2tensor(0, 2) * r2tensor(1, 1) * r2tensor(2, 0);
217
218 return val;
219}
220
221/*
222 * This method is called by the *Principal methods to calculate the eigenvalues
223 * and eigenvectors of a symmetric tensor and return the desired value based on
224 * vector position.
225 * param r2tensor The RankTwoTensor from which to extract eigenvalues/vectors
226 * param index The index of the principal value
227 * param direction The eigenvector corresponding to the computed eigenvalue
228 */
229template <typename T>
230T
232 unsigned int index,
233 Point & eigenvec)
234{
235 std::vector<T> eigenval(LIBMESH_DIM);
236 RankTwoTensorTempl<T> eigvecs;
237 r2tensor.symmetricEigenvaluesEigenvectors(eigenval, eigvecs);
238
239 T val = eigenval[index];
240 eigenvec = eigvecs.column(index);
241
242 return val;
243}
244
245/*
246 * The max Principal method returns the largest principal value for a symmetric
247 * tensor, using the calcEigenValues method.
248 * param r2tensor RankTwoTensor from which to extract the principal value
249 * param direction Direction corresponding to the principal value
250 */
251template <typename T>
252T
253maxPrincipal(const RankTwoTensorTempl<T> & r2tensor, Point & direction)
254{
255 return calcEigenValuesEigenVectors(r2tensor, (LIBMESH_DIM - 1), direction);
256}
257
258/*
259 * The mid Principal method calculates the second largest principal value for a
260 * tensor.
261 * param r2tensor RankTwoTensor from which to extract the principal value
262 * param direction Direction corresponding to the principal value
263 */
264template <typename T>
265T
266midPrincipal(const RankTwoTensorTempl<T> & r2tensor, Point & direction)
267{
268 return calcEigenValuesEigenVectors(r2tensor, 1, direction);
269}
270
271/*
272 * The min Principal stress returns the smallest principal value from a symmetric
273 * tensor.
274 * param r2tensor RankTwoTensor from which to extract the principal value
275 * param direction Direction corresponding to the principal value
276 */
277template <typename T>
278T
279minPrincipal(const RankTwoTensorTempl<T> & r2tensor, Point & direction)
280{
281 return calcEigenValuesEigenVectors(r2tensor, 0, direction);
282}
283
284/*
285 * The axial stress is the scalar component of the stress tensor in an user-defined
286 * direction; the axis direction is specified by inputing two points.
287 * axial-stress = axis^T_i * \sigma_{ij} * axis_j
288 * @param point1 The starting point of the rotation axis for a cylinderical system
289 * @param point2 The end point of the rotation axis
290 * @param direction The direction vector in which the scalar stress value is calculated.
291 */
292template <typename T>
293T
295 const Point & point1,
296 const Point & point2,
297 Point & direction)
298{
299 Point axis = point2 - point1;
300 axis /= axis.norm();
301
302 // Calculate the stress in the direction of the axis specifed by the user
303 T axial_stress = axis * (stress * axis);
304
305 direction = axis;
306
307 return axial_stress;
308}
309
310/*
311 * This method is a helper method for the hoopStress and radialStress methods to
312 * calculate the unit position vector which is normal to the user supplied axis
313 * of rotation; the rotation axis direction is specified by inputing two points.
314 * @param point1 The starting point of the rotation axis for a cylinderical system
315 * @param point2 The end point of the rotation axis
316 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
317 * @param normalPosition The vector from the current point that is normal to the rotation axis
318 */
319void normalPositionVector(const Point & point1,
320 const Point & point2,
321 const Point & curr_point,
322 Point & normalPosition);
323
324/*
325 * The hoop stress is calculated as
326 * hoop-stress = z^T_i * \sigma_{ij} * z_j
327 * where z is defined as the cross of the user-defined (via input points) axis
328 * of rotation and the normal from the current position to the axis of rotation.
329 * @param point1 The starting point of the rotation axis for a cylinderical system
330 * @param point2 The end point of the rotation axis
331 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
332 * @param direction The direction vector in which the scalar stress value is calculated.
333 */
334template <typename T>
335T
337 const Point & point1,
338 const Point & point2,
339 const Point & curr_point,
340 Point & direction)
341{
342 // Calculate the cross of the normal to the axis of rotation from the current
343 // location and the axis of rotation
344 Point xp;
345 normalPositionVector(point1, point2, curr_point, xp);
346 Point axis_rotation = point2 - point1;
347 Point yp = axis_rotation / axis_rotation.norm();
348 Point zp = xp.cross(yp);
349
350 // Calculate the scalar value of the hoop stress
351 T hoop_stress = zp * (stress * zp);
352
353 direction = zp;
354
355 return hoop_stress;
356}
357
358/* The radial stress is calculated as
359 * radial_stress = normal^T_i * \sigma_{ij} * normal_j
360 * where normal is the position vector of the current point that is normal to
361 * the user-defined axis of rotation; the axis direction is specified with two points.
362 * @param point1 The starting point of the rotation axis for a cylinderical system
363 * @param point2 The end point of the rotation axis
364 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
365 * @param direction The direction vector in which the scalar stress value is calculated.
366 */
367template <typename T>
368T
370 const Point & point1,
371 const Point & point2,
372 const Point & curr_point,
373 Point & direction)
374{
375 Point radial_norm;
376 normalPositionVector(point1, point2, curr_point, radial_norm);
377
378 // Compute the scalar stress component in the direction of the normal vector from the
379 // user-defined axis of rotation.
380 T radial_stress = radial_norm * (stress * radial_norm);
381
382 direction = radial_norm;
383
384 return radial_stress;
385}
386
387/* The radial stress is calculated as
388 * radial_stress = radial^T_i * \sigma_{ij} * radial_j
389 * where normal is the position vector of the current point that is normal to
390 * the user-defined axis of rotation;
391 * @param center The center point of the spherical system
392 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
393 * @param direction The direction vector in which the scalar stress value is calculated.
394 */
395template <typename T>
396T
398 const Point & center,
399 const Point & curr_point,
400 Point & direction)
401{
402 Point radial = curr_point - center;
403 radial /= radial.norm();
404
405 // Compute the scalar stress component in the radial direction
406 T radial_stress = radial * (stress * radial);
407
408 direction = radial;
409
410 return radial_stress;
411}
412
413/* The hoop stress is calculated as
414 * hoop_stress = tangential^T_i * \sigma_{ij} * tangential_j
415 * where tangential is tangential direction at the current point in the spherical system;
416 * @param center The center point of the spherical system
417 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
418 * @param direction The direction vector in which the scalar stress value is calculated.
419 */
420template <typename T>
421T
423 const Point & center,
424 const Point & curr_point,
425 Point & direction)
426{
427 Point radial = curr_point - center;
428 Real r = radial.norm();
429 radial /= r;
430
431 // Given normal vector N=(n1,n2,n3) and current point C(c1,c2,c3), the tangential plane is then
432 // defined as n1(x-c1) + n2(y-c2) + n3(z-c3)=0. Let us assume n1!=0, the arbitrary point P on this
433 // plane can be taken as P(x,c2+r,c3+r) where r is the radius. The x can be solved as x =
434 // -r(n2+n3)/n1 + c1. The tangential vector PC is given as P-C.
435
436 Point tangential;
437
438 if (!MooseUtils::absoluteFuzzyEqual(radial(0), 0.0))
439 {
440 Real x = curr_point(0) - (radial(1) + radial(2)) * r / radial(0);
441 tangential = Point(x, curr_point(1) + r, curr_point(2) + r) - curr_point;
442 }
443 else if (!MooseUtils::absoluteFuzzyEqual(radial(1), 0.0))
444 {
445 Real y = curr_point(1) - (radial(0) + radial(2)) * r / radial(1);
446 tangential = Point(curr_point(0) + r, y, curr_point(2) + r) - curr_point;
447 }
448 else if (!MooseUtils::absoluteFuzzyEqual(radial(1), 0.0))
449 {
450 Real z = curr_point(2) - (radial(0) + radial(1)) * r / radial(2);
451 tangential = Point(curr_point(0) + r, curr_point(1) + r, z) - curr_point;
452 }
453 else
454 mooseError("In Hoop stress calculation for spherical geometry, the current (quadracture) point "
455 "is likely to be at the center. ");
456
457 tangential /= tangential.norm();
458
459 // Compute the scalar stress component in the hoop direction
460 T hoop_stress = 0.0;
461 for (unsigned int i = 0; i < 3; ++i)
462 for (unsigned int j = 0; j < 3; ++j)
463 hoop_stress += tangential(j) * stress(j, i) * tangential(i);
464
465 direction = tangential;
466
467 return hoop_stress;
468}
469
470/*
471 * This method calculates the scalar value of the supplied rank-2 tensor in the
472 * direction specified by the user.
473 */
474template <typename T>
475T
476directionValueTensor(const RankTwoTensorTempl<T> & r2tensor, const Point & direction)
477{
478 T tensor_value_in_direction = direction * (r2tensor * direction);
479
480 return tensor_value_in_direction;
481}
482
483/*
484 * Triaxiality is the ratio of the hydrostatic stress to the von Mises stress.
485 */
486template <typename T>
487T
489{
490 return hydrostatic(stress) / vonMisesStress(stress);
491}
492
493/*
494 * maxShear is the maximum shear stress defined as the maximum principal
495 * stress minus the minimum principal stress.
496 */
497template <typename T>
498T
500{
501 Point dummy;
502 return (maxPrincipal(stress, dummy) - minPrincipal(stress, dummy)) / 2.;
503}
504/*
505 * stressIntensity is defined as two times the maximum shear stress.
506 */
507template <typename T>
508T
510{
511 return 2. * maxShear(stress);
512}
513
514/*
515 * Return scalar quantity of a rank two tensor based on the user specified scalar_type
516 * @param point1 The starting point of the rotation axis for a cylinderical system
517 * @param point2 The end point of the rotation axis
518 * @param curr_point The point corresponding to the stress (pass in & _q_point[_qp])
519 * @param direction The direction vector in which the scalar stress value is calculated
520 * point1 and point2 are required only for the cases of axialStress, hoopStress and radialStress
521 * curr_point is required only for the cases of hoopStress and radialStress
522 * direction is required only for directionValueTensor
523 * for all other cases, these parameters will take the default values
524 */
525template <typename T>
526T
528 const MooseEnum & scalar_type,
529 const Point & point1,
530 const Point & point2,
531 const Point & curr_point,
532 Point & direction)
533{
534 switch (scalar_type)
535 {
536 case 0:
537 return vonMisesStress(tensor);
538 case 1:
539 mooseError("To compute an effective inelastic strain use "
540 "RankTwoScalarTools::effectiveStrain()");
541 case 2:
542 return hydrostatic(tensor);
543 case 3:
544 return L2norm(tensor);
545 case 4:
546 return maxPrincipal(tensor, direction);
547 case 5:
548 return midPrincipal(tensor, direction);
549 case 6:
550 return minPrincipal(tensor, direction);
551 case 7:
552 return volumetricStrain(tensor);
553 case 8:
554 return firstInvariant(tensor);
555 case 9:
556 return secondInvariant(tensor);
557 case 10:
558 return thirdInvariant(tensor);
559 case 11:
560 return axialStress(tensor, point1, point2, direction);
561 case 12:
562 return hoopStress(tensor, point1, point2, curr_point, direction);
563 case 13:
564 return radialStress(tensor, point1, point2, curr_point, direction);
565 case 14:
566 return triaxialityStress(tensor);
567 case 15:
568 return directionValueTensor(tensor, direction);
569 case 16:
570 return maxShear(tensor);
571 case 17:
572 return stressIntensity(tensor);
573 default:
574 mooseError("RankTwoScalarTools Error: invalid scalar type");
575 }
576}
577
578template <typename T>
579T
581 const CylindricalComponent & scalar_type,
582 const Point & point1,
583 const Point & point2,
584 const Point & curr_point,
585 Point & direction)
586{
587 switch (scalar_type)
588 {
590 return axialStress(tensor, point1, point2, direction);
592 return hoopStress(tensor, point1, point2, curr_point, direction);
594 return radialStress(tensor, point1, point2, curr_point, direction);
595 default:
596 mooseError("RankTwoCylindricalComponent Error: scalar type invalid");
597 }
598}
599
600template <typename T>
601T
603 const SphericalComponent & scalar_type,
604 const Point & center,
605 const Point & curr_point,
606 Point & direction)
607{
608 switch (scalar_type)
609 {
611 return hoopStress(tensor, center, curr_point, direction);
613 return radialStress(tensor, center, curr_point, direction);
614 default:
615 mooseError("RankTwoSphericalComponent Error: scalar type invalid");
616 }
617}
618
619template <typename T>
620T
622 const InvariantType & scalar_type,
623 Point & direction)
624{
625 switch (scalar_type)
626 {
628 return maxPrincipal(tensor, direction);
630 return midPrincipal(tensor, direction);
632 return minPrincipal(tensor, direction);
633 default:
634 mooseError("RankTwoInvariant Error: valid invariant");
635 }
636}
637
638template <typename T>
639T
640getDirectionalComponent(const RankTwoTensorTempl<T> & tensor, const Point & direction)
641{
642 return directionValueTensor(tensor, direction);
643}
644
645template <typename T>
646T
647getInvariant(const RankTwoTensorTempl<T> & tensor, const InvariantType & scalar_type)
648{
649 switch (scalar_type)
650 {
652 return vonMisesStress(tensor);
654 mooseError("To compute an effective inelastic strain use "
655 "RankTwoScalarTools::effectiveStrain()");
657 return hydrostatic(tensor);
659 return L2norm(tensor);
661 return volumetricStrain(tensor);
663 return firstInvariant(tensor);
665 return secondInvariant(tensor);
667 return thirdInvariant(tensor);
669 return triaxialityStress(tensor);
671 return maxShear(tensor);
673 return stressIntensity(tensor);
674 default:
675 mooseError("RankTwoCartesianComponent Error: Pass valid invariant - " +
676 invariantOptions().getRawNames());
677 }
678}
679
680void setRotationMatrix(const RealVectorValue & outwardnormal,
681 const RealVectorValue & axialVector,
682 RankTwoTensor & rotationMatrix,
683 const bool transpose);
684
685template <bool is_ad>
686void
688 GenericDenseVector<is_ad> & voigt_vector)
689{
690 voigt_vector(0) = tensor(0, 0);
691 voigt_vector(1) = tensor(1, 1);
692 voigt_vector(2) = tensor(2, 2);
693 voigt_vector(3) = tensor(0, 1);
694 voigt_vector(4) = tensor(1, 2);
695 voigt_vector(5) = tensor(0, 2);
696}
697
698template <bool is_ad>
699void
702{
703 tensor(0, 0) = voigt_vector(0);
704 tensor(1, 1) = voigt_vector(1);
705 tensor(2, 2) = voigt_vector(2);
706 tensor(0, 1) = tensor(1, 0) = voigt_vector(3);
707 tensor(1, 2) = tensor(2, 1) = voigt_vector(4);
708 tensor(0, 2) = tensor(2, 0) = voigt_vector(5);
709}
710}
const std::vector< double > y
const std::vector< double > x
const double T
void mooseError(Args &&... args)
Moose::GenericType< DenseVector< Real >, is_ad > GenericDenseVector
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor
Point center
T doubleContraction(const RankTwoTensorTempl< T > &a) const
libMesh::VectorValue< T > column(const unsigned int i) const
RankTwoTensorTempl< T > deviatoric() const
void symmetricEigenvaluesEigenvectors(std::vector< T > &eigvals, RankTwoTensorTempl< T > &eigvecs) const
MooseEnum scalarOptions()
This enum is left for legacy calls.
T getSphericalComponent(const RankTwoTensorTempl< T > &tensor, const SphericalComponent &scalar_type, const Point &center, const Point &curr_point, Point &direction)
T axialStress(const RankTwoTensorTempl< T > &stress, const Point &point1, const Point &point2, Point &direction)
T secondInvariant(const RankTwoTensorTempl< T > &r2tensor)
MooseEnum cylindricalOptions()
T effectiveStrain(const RankTwoTensorTempl< T > &strain)
T getInvariant(const RankTwoTensorTempl< T > &tensor, const InvariantType &scalar_type)
T getCylindricalComponent(const RankTwoTensorTempl< T > &tensor, const CylindricalComponent &scalar_type, const Point &point1, const Point &point2, const Point &curr_point, Point &direction)
T triaxialityStress(const RankTwoTensorTempl< T > &stress)
T maxPrincipal(const RankTwoTensorTempl< T > &r2tensor, Point &direction)
T maxShear(const RankTwoTensorTempl< T > &stress)
T radialStress(const RankTwoTensorTempl< T > &stress, const Point &point1, const Point &point2, const Point &curr_point, Point &direction)
T stressIntensity(const RankTwoTensorTempl< T > &stress)
T component(const RankTwoTensorTempl< T > &r2tensor, unsigned int i, unsigned int j)
void RankTwoTensorToVoigtVector(const GenericRankTwoTensor< is_ad > &tensor, GenericDenseVector< is_ad > &voigt_vector)
T getQuantity(const RankTwoTensorTempl< T > &tensor, const MooseEnum &scalar_type, const Point &point1, const Point &point2, const Point &curr_point, Point &direction)
T vonMisesStress(const RankTwoTensorTempl< T > &stress)
T calcEigenValuesEigenVectors(const RankTwoTensorTempl< T > &r2tensor, unsigned int index, Point &eigenvec)
T getPrincipalComponent(const RankTwoTensorTempl< T > &tensor, const InvariantType &scalar_type, Point &direction)
T hoopStress(const RankTwoTensorTempl< T > &stress, const Point &point1, const Point &point2, const Point &curr_point, Point &direction)
T getDirectionalComponent(const RankTwoTensorTempl< T > &tensor, const Point &direction)
T thirdInvariant(const RankTwoTensorTempl< T > &r2tensor)
T midPrincipal(const RankTwoTensorTempl< T > &r2tensor, Point &direction)
T firstInvariant(const RankTwoTensorTempl< T > &r2tensor)
void setRotationMatrix(const RealVectorValue &outwardnormal, const RealVectorValue &axialVector, RankTwoTensor &rotationMatrix, const bool transpose)
T directionValueTensor(const RankTwoTensorTempl< T > &r2tensor, const Point &direction)
void VoigtVectorToRankTwoTensor(const GenericDenseVector< is_ad > &voigt_vector, GenericRankTwoTensor< is_ad > &tensor)
void normalPositionVector(const Point &point1, const Point &point2, const Point &curr_point, Point &normalPosition)
T hydrostatic(const RankTwoTensorTempl< T > &r2tensor)
T volumetricStrain(const RankTwoTensorTempl< T > &strain)
T minPrincipal(const RankTwoTensorTempl< T > &r2tensor, Point &direction)