Files
lammps/src/math_eigen.cpp
Steve Plimpton d06b86916a more debugging
2024-04-03 11:11:16 -06:00

95 lines
3.2 KiB
C++

/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Andrew Jewett (Scripps Research)
------------------------------------------------------------------------- */
#include "math_eigen.h"
#include "math_eigen_impl.h"
#include <array>
#include <utility>
#include <vector>
using std::array;
using std::vector;
using namespace MathEigen;
// Special case: 3x3 matrices
typedef Jacobi<double, double *, double (*)[3], double const (*)[3]> Jacobi_v1;
typedef Jacobi<double, double *, double **, double const *const *> Jacobi_v2;
int MathEigen::jacobi3(double const mat[3][3], double *eval, double evec[3][3], int sort)
{
// make copy of const matrix
double mat_cpy[3][3] = {{mat[0][0], mat[0][1], mat[0][2]},
{mat[1][0], mat[1][1], mat[1][2]},
{mat[2][0], mat[2][1], mat[2][2]}};
double *M[3] = {&(mat_cpy[0][0]), &(mat_cpy[1][0]), &(mat_cpy[2][0])};
int midx[3];
// create instance of generic Jacobi class and get eigenvalues and -vectors
Jacobi_v1 ecalc3(3, M, midx);
int ierror = 1;
if (sort == -1)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v1::SORT_DECREASING_EVALS);
else if (sort == 0)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v1::DO_NOT_SORT);
else if (sort == 1)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v1::SORT_INCREASING_EVALS);
if (ierror) return ierror;
// transpose the evec matrix
for (int i = 0; i < 3; i++)
for (int j = i + 1; j < 3; j++) std::swap(evec[i][j], evec[j][i]);
return ierror;
}
int MathEigen::jacobi3(double const *const *mat, double *eval, double **evec, int sort)
{
// make copy of const matrix
double mat_cpy[3][3] = {{mat[0][0], mat[0][1], mat[0][2]},
{mat[1][0], mat[1][1], mat[1][2]},
{mat[2][0], mat[2][1], mat[2][2]}};
double *M[3] = {&(mat_cpy[0][0]), &(mat_cpy[1][0]), &(mat_cpy[2][0])};
int midx[3];
// create instance of generic Jacobi class and get eigenvalues and -vectors
Jacobi_v2 ecalc3(3, M, midx);
int ierror = 1;
if (sort == -1)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v2::SORT_DECREASING_EVALS);
else if (sort == 0)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v2::DO_NOT_SORT);
else if (sort == 1)
ierror = ecalc3.Diagonalize(mat, eval, evec, Jacobi_v2::SORT_INCREASING_EVALS);
if (ierror) return ierror;
// transpose the evec matrix
for (int i = 0; i < 3; i++)
for (int j = i + 1; j < 3; j++) std::swap(evec[i][j], evec[j][i]);
return ierror;
}