LCOV - code coverage report
Current view: top level - src/utils - RankTwoTensorImplementation.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 42 82 51.2 %
Date: 2025-07-17 01:28:37 Functions: 4 11 36.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "RankTwoTensorImplementation.h"
      11             : 
      12             : template <>
      13             : void
      14           0 : RankTwoTensor::printReal(std::ostream & stm) const
      15             : {
      16           0 :   this->print(stm);
      17           0 : }
      18             : 
      19             : template <>
      20             : void
      21           0 : ADRankTwoTensor::printReal(std::ostream & stm) const
      22             : {
      23           0 :   const ADRankTwoTensor & a = *this;
      24           0 :   for (const auto i : make_range(N))
      25             :   {
      26           0 :     for (const auto j : make_range(N))
      27           0 :       stm << std::setw(15) << a(i, j).value() << ' ';
      28           0 :     stm << std::endl;
      29             :   }
      30           0 : }
      31             : 
      32             : template <>
      33             : void
      34           0 : ADRankTwoTensor::printADReal(unsigned int nDual, std::ostream & stm) const
      35             : {
      36           0 :   const ADRankTwoTensor & a = *this;
      37           0 :   for (const auto i : make_range(N))
      38             :   {
      39           0 :     for (const auto j : make_range(N))
      40             :     {
      41           0 :       stm << std::setw(15) << a(i, j).value() << " {";
      42           0 :       for (const auto k : make_range(nDual))
      43           0 :         stm << std::setw(5) << a(i, j).derivatives()[k] << ' ';
      44           0 :       stm << " }";
      45             :     }
      46           0 :     stm << std::endl;
      47             :   }
      48           0 : }
      49             : 
      50             : template <>
      51             : void
      52         630 : RankTwoTensor::syev(const char * calculation_type,
      53             :                     std::vector<Real> & eigvals,
      54             :                     std::vector<Real> & a) const
      55             : {
      56         630 :   eigvals.resize(N);
      57         630 :   a.resize(N * N);
      58             : 
      59             :   // prepare data for the LAPACKsyev_ routine (which comes from petscblaslapack.h)
      60         630 :   PetscBLASInt nd = N;
      61         630 :   PetscBLASInt lwork = 66 * nd;
      62             :   PetscBLASInt info;
      63         630 :   std::vector<PetscScalar> work(lwork);
      64             : 
      65        2520 :   for (const auto i : make_range(N))
      66        7560 :     for (const auto j : make_range(N))
      67             :       // a is destroyed by dsyev, and if calculation_type == "V" then eigenvectors are placed
      68             :       // there Note the explicit symmeterisation
      69        5670 :       a[i * N + j] = 0.5 * (this->operator()(i, j) + this->operator()(j, i));
      70             : 
      71             :   // compute the eigenvalues only (if calculation_type == "N"),
      72             :   // or both the eigenvalues and eigenvectors (if calculation_type == "V")
      73             :   // assume upper triangle of a is stored (second "U")
      74         630 :   LAPACKsyev_(calculation_type, "U", &nd, &a[0], &nd, &eigvals[0], &work[0], &lwork, &info);
      75             : 
      76         630 :   if (info != 0)
      77           0 :     mooseException(
      78             :         "In computing the eigenvalues and eigenvectors for the symmetric rank-2 tensor (",
      79             :         Moose::stringify(a),
      80             :         "), the PETSC LAPACK syev routine returned error code ",
      81             :         info);
      82         630 : }
      83             : 
      84             : template <>
      85             : void
      86          96 : RankTwoTensor::symmetricEigenvalues(std::vector<Real> & eigvals) const
      87             : {
      88          96 :   std::vector<Real> a;
      89          96 :   syev("N", eigvals, a);
      90          96 : }
      91             : 
      92             : template <>
      93             : void
      94          36 : RankTwoTensor::symmetricEigenvaluesEigenvectors(std::vector<Real> & eigvals,
      95             :                                                 RankTwoTensor & eigvecs) const
      96             : {
      97          36 :   std::vector<Real> a;
      98          36 :   syev("V", eigvals, a);
      99             : 
     100         144 :   for (const auto i : make_range(N))
     101         432 :     for (const auto j : make_range(N))
     102         324 :       eigvecs(j, i) = a[i * N + j];
     103          36 : }
     104             : 
     105             : template <>
     106             : void
     107          25 : ADRankTwoTensor::symmetricEigenvaluesEigenvectors(std::vector<ADReal> & eigvals,
     108             :                                                   ADRankTwoTensor & eigvecs) const
     109             : {
     110             :   typedef Eigen::Matrix<ADReal, N, N> RankTwoMatrix;
     111          25 :   RankTwoMatrix self;
     112         100 :   for (const auto i : make_range(N))
     113         225 :     for (unsigned int j = i; j < N; ++j)
     114             :     {
     115         150 :       auto & v = self(j, i);
     116         150 :       v = (*this)(i, j);
     117         150 :       if (i != j && MooseUtils::absoluteFuzzyEqual(v, 0.0))
     118          20 :         v.value() = 0.0;
     119             :     }
     120             : 
     121          25 :   Eigen::SelfAdjointEigenSolver<RankTwoMatrix> es;
     122          25 :   es.compute(self);
     123             : 
     124          25 :   const auto & lambda = es.eigenvalues();
     125          25 :   eigvals.resize(N);
     126         100 :   for (const auto i : make_range(N))
     127          75 :     eigvals[i] = lambda(i);
     128             : 
     129          25 :   const auto & v = es.eigenvectors();
     130         100 :   for (const auto i : make_range(N))
     131         300 :     for (const auto j : make_range(N))
     132         225 :       eigvecs(i, j) = v(i, j);
     133          25 : }
     134             : 
     135             : template <>
     136             : void
     137           0 : RankTwoTensor::getRUDecompositionRotation(RankTwoTensor & rot) const
     138             : {
     139           0 :   const RankTwoTensor & a = *this;
     140           0 :   RankTwoTensor c, diag, evec;
     141             :   PetscScalar cmat[N][N], work[10];
     142             :   PetscReal w[N];
     143             : 
     144             :   // prepare data for the LAPACKsyev_ routine (which comes from petscblaslapack.h)
     145           0 :   PetscBLASInt nd = N, lwork = 10, info;
     146             : 
     147           0 :   c = a.transpose() * a;
     148             : 
     149           0 :   for (const auto i : make_range(N))
     150           0 :     for (const auto j : make_range(N))
     151           0 :       cmat[i][j] = c(i, j);
     152             : 
     153           0 :   LAPACKsyev_("V", "U", &nd, &cmat[0][0], &nd, w, work, &lwork, &info);
     154             : 
     155           0 :   if (info != 0)
     156           0 :     mooseException(
     157             :         "In computing the eigenvalues and eigenvectors of a symmetric rank-2 tensor, the "
     158             :         "PETSC LAPACK syev routine returned error code ",
     159             :         info);
     160             : 
     161           0 :   diag.zero();
     162             : 
     163           0 :   for (const auto i : make_range(N))
     164           0 :     diag(i, i) = std::sqrt(w[i]);
     165             : 
     166           0 :   for (const auto i : make_range(N))
     167           0 :     for (const auto j : make_range(N))
     168           0 :       evec(i, j) = cmat[i][j];
     169             : 
     170           0 :   rot = a * (evec.transpose() * diag * evec).inverse();
     171           0 : }

Generated by: LCOV version 1.14