313 lines
8.8 KiB
C
313 lines
8.8 KiB
C
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
// PPPPP H H EEEEE N N GGGGG L EEEEE III +
|
|||
|
// P P H H E NN N G L E I +
|
|||
|
// PPPPP HHHHH EEEEE N N N G GG L EEEEE I +
|
|||
|
// P H H E N N N G G L E I +
|
|||
|
// P H H EEEEE N N GGGGG LLLLL EEEEE III +
|
|||
|
//------------------------------------------------------------------------+
|
|||
|
// Platform for Hybrid Engineering Simulation of Flows +
|
|||
|
// China Aerodynamics Research and Development Center +
|
|||
|
// (C) Copyright, Since 2010 +
|
|||
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|||
|
//! @file PHSuperMatrix.h
|
|||
|
//! @brief Explain this file briefly.
|
|||
|
//! @author xxx.
|
|||
|
|
|||
|
#pragma once
|
|||
|
#include <vector>
|
|||
|
#include "PHHeader.h"
|
|||
|
#include "TK_Exit.h"
|
|||
|
#include "Math_BasisFunction.h"
|
|||
|
|
|||
|
using namespace std;
|
|||
|
|
|||
|
namespace PHSPACE
|
|||
|
{
|
|||
|
|
|||
|
template < typename T >
|
|||
|
class PHMatrix
|
|||
|
{
|
|||
|
protected:
|
|||
|
int _nrow, _ncolumn, _nsize;
|
|||
|
PHVector1D< T > _data;
|
|||
|
public:
|
|||
|
PHMatrix(int nrow, int ncolumn = 1)
|
|||
|
{
|
|||
|
_nrow = nrow;
|
|||
|
_ncolumn = ncolumn;
|
|||
|
_nsize = _nrow * _ncolumn;
|
|||
|
_data = PHVector1D< T >(_nsize);
|
|||
|
}
|
|||
|
|
|||
|
~PHMatrix()
|
|||
|
{
|
|||
|
}
|
|||
|
int rows () const { return _nrow; }
|
|||
|
int columns() const { return _ncolumn; }
|
|||
|
int sizes () const { return _nsize; };
|
|||
|
PHVector1D< T > datas() { return _data; }
|
|||
|
|
|||
|
const T & operator() (int row, int column = 1) const
|
|||
|
{
|
|||
|
if ((row < 0 || row > _nrow) || (column < 0 || column > _ncolumn))
|
|||
|
{
|
|||
|
cout << endl << "Error : overflow in type PHMatrix ! ";
|
|||
|
TK_Exit::ExceptionExit("");
|
|||
|
}
|
|||
|
return _data[(row - 1) * _ncolumn + (column - 1)] ;
|
|||
|
}
|
|||
|
|
|||
|
T & operator()(int row, int column = 1)
|
|||
|
{
|
|||
|
if ((row < 0 || row > _nrow) || (column < 0 || column > _ncolumn))
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : overflow in type PHMatrix ! ");
|
|||
|
}
|
|||
|
return _data[(row - 1) * _ncolumn + (column - 1)] ;
|
|||
|
}
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix< T > operator * (const PHMatrix<T> & matrixA, const PHMatrix<T> & matrixB)
|
|||
|
{
|
|||
|
int nrow = matrixA.rows();
|
|||
|
int ncol = matrixB.columns();
|
|||
|
|
|||
|
if (matrixA.columns() != matrixB.rows())
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : Index not matched in PHMatrix<T> operator * ! ");
|
|||
|
}
|
|||
|
|
|||
|
PHMatrix< T > result(nrow, ncol);
|
|||
|
|
|||
|
for (int col = 1; col <= ncol; ++ col)
|
|||
|
{
|
|||
|
for (int row = 1; row <= nrow; ++ row)
|
|||
|
{
|
|||
|
T sum = static_cast< T >(0);
|
|||
|
for (int i = 1; i <= matrixA.columns(); ++ i)
|
|||
|
{
|
|||
|
sum += matrixA(row, i) * matrixB(i, col);
|
|||
|
}
|
|||
|
result(row, col) = sum;
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix< T > MATMUL(PHMatrix<T> & matrixA, PHMatrix<T> & matrixB)
|
|||
|
{
|
|||
|
int nrow = matrixA.rows();
|
|||
|
int ncol = matrixB.columns();
|
|||
|
|
|||
|
if (matrixA.columns() != matrixB.rows())
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : Index not matched in function MATMUL ! ");
|
|||
|
}
|
|||
|
|
|||
|
PHMatrix<T> result(nrow, ncol);
|
|||
|
|
|||
|
for (int row = 1; row <= nrow; ++ row)
|
|||
|
{
|
|||
|
for (int col = 1; col <= ncol; ++ col)
|
|||
|
{
|
|||
|
T sum = static_cast< T >(0);
|
|||
|
for (int i = 1; i <= matrixA.columns(); ++ i)
|
|||
|
{
|
|||
|
sum += matrixA(row, i) * matrixB(i, col);
|
|||
|
}
|
|||
|
result(row, col) = sum;
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix<T> TransposeMatrix(PHMatrix<T> & matrixA)
|
|||
|
{
|
|||
|
int nrow = matrixA.rows();
|
|||
|
int ncol = matrixA.columns();
|
|||
|
|
|||
|
if (nrow != ncol)
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : Index not matched in function TransposeMatrix ! ");
|
|||
|
}
|
|||
|
|
|||
|
PHMatrix<T> matrixB(nrow, ncol);
|
|||
|
|
|||
|
for (int row = 1; row <= nrow; ++ row)
|
|||
|
{
|
|||
|
for (int col = 1; col <= ncol; ++ col)
|
|||
|
{
|
|||
|
matrixB(row, col) = matrixA(col, row);
|
|||
|
}
|
|||
|
}
|
|||
|
return matrixB;
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix<T> Matrix3X3Inverse(PHMatrix<T> & matrix)
|
|||
|
{
|
|||
|
PHMatrix<T> inverse(3, 3);
|
|||
|
|
|||
|
if (matrix.rows() != 3 || matrix.columns() != 3)
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : Index must be 3 in function Matrix3X3Inverse ! ");
|
|||
|
}
|
|||
|
|
|||
|
T detA = matrix(1, 1) * matrix(2, 2) * matrix(3, 3)
|
|||
|
+ matrix(1, 2) * matrix(2, 3) * matrix(3, 1)
|
|||
|
+ matrix(2, 1) * matrix(3, 2) * matrix(1, 3)
|
|||
|
- matrix(1, 1) * matrix(2, 3) * matrix(3, 2)
|
|||
|
- matrix(2, 2) * matrix(1, 3) * matrix(3, 1)
|
|||
|
- matrix(3, 3) * matrix(2, 1) * matrix(1, 2);
|
|||
|
|
|||
|
if (detA == 0.0)
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : The Determinant of the Matrix is Zero<72><6F>Singular Matrix ! ");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
inverse(1, 1) = matrix(2, 2) * matrix(3, 3) - matrix(2, 3) * matrix(3, 2);
|
|||
|
inverse(1, 2) = matrix(1, 3) * matrix(3, 2) - matrix(1, 2) * matrix(3, 3);
|
|||
|
inverse(1, 3) = matrix(1, 2) * matrix(2, 3) - matrix(2, 2) * matrix(1, 3);
|
|||
|
|
|||
|
inverse(2, 1) = matrix(2, 3) * matrix(3, 1) - matrix(2, 1) * matrix(3, 3);
|
|||
|
inverse(2, 2) = matrix(1, 1) * matrix(3, 3) - matrix(1, 3) * matrix(3, 1);
|
|||
|
inverse(2, 3) = matrix(2, 1) * matrix(1, 3) - matrix(1, 1) * matrix(2, 3);
|
|||
|
|
|||
|
inverse(3, 1) = matrix(2, 1) * matrix(3, 2) - matrix(3, 1) * matrix(2, 2);
|
|||
|
inverse(3, 2) = matrix(1, 2) * matrix(3, 1) - matrix(1, 1) * matrix(3, 2);
|
|||
|
inverse(3, 3) = matrix(1, 1) * matrix(2, 2) - matrix(1, 2) * matrix(2, 1);
|
|||
|
|
|||
|
for (int i = 1; i <= 3; ++ i)
|
|||
|
{
|
|||
|
for (int j = 1; j <= 3; ++ j)
|
|||
|
{
|
|||
|
inverse(i, j) /= detA;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return inverse;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix<T> BaseMatrixOfRotate(const T & angle, string const & axisLabel)
|
|||
|
{
|
|||
|
PHMatrix<T> matrix(3, 3);
|
|||
|
|
|||
|
T cosine = cos(angle);
|
|||
|
T sine = sin(angle);
|
|||
|
T oneTmp = static_cast< T >(1);
|
|||
|
T zeroTmp = static_cast< T >(0);
|
|||
|
|
|||
|
if (axisLabel == "x" || axisLabel == "X")
|
|||
|
{
|
|||
|
matrix(1, 1) = oneTmp;
|
|||
|
matrix(1, 2) = zeroTmp;
|
|||
|
matrix(1, 3) = zeroTmp;
|
|||
|
|
|||
|
matrix(2, 1) = zeroTmp;
|
|||
|
matrix(2, 2) = cosine;
|
|||
|
matrix(2, 3) = sine;
|
|||
|
|
|||
|
matrix(3, 1) = zeroTmp;
|
|||
|
matrix(3, 2) =-sine;
|
|||
|
matrix(3, 3) = cosine;
|
|||
|
}
|
|||
|
else if (axisLabel == "y" || axisLabel == "Y")
|
|||
|
{
|
|||
|
matrix(1, 1) = cosine;
|
|||
|
matrix(1, 2) = zeroTmp;
|
|||
|
matrix(1, 3) =-sine;
|
|||
|
|
|||
|
matrix(2, 1) = zeroTmp;
|
|||
|
matrix(2, 2) = oneTmp;
|
|||
|
matrix(2, 3) = zeroTmp;
|
|||
|
|
|||
|
matrix(3, 1) = sine;
|
|||
|
matrix(3, 2) = zeroTmp;
|
|||
|
matrix(3, 3) = cosine;
|
|||
|
}
|
|||
|
else if (axisLabel == "z" || axisLabel == "Z")
|
|||
|
{
|
|||
|
matrix(1, 1) = cosine;
|
|||
|
matrix(1, 2) = sine;
|
|||
|
matrix(1, 3) = zeroTmp;
|
|||
|
|
|||
|
matrix(2, 1) =-sine;
|
|||
|
matrix(2, 2) = cosine;
|
|||
|
matrix(2, 3) = zeroTmp;
|
|||
|
|
|||
|
matrix(3, 1) = zeroTmp;
|
|||
|
matrix(3, 2) = zeroTmp;
|
|||
|
matrix(3, 3) = oneTmp;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : error axis label in BaseMatrixOfRotate ! ");
|
|||
|
}
|
|||
|
|
|||
|
return matrix;
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix<T> AngleRateTransformMatrixBodyToGlobal(PHMatrix<T> & eulerangle, string const & rotateorder)
|
|||
|
{
|
|||
|
PHMatrix<T> matrix(3, 3);
|
|||
|
|
|||
|
T pitchangle = eulerangle(1);
|
|||
|
T rollangle = eulerangle(3);
|
|||
|
|
|||
|
T oneTmp = static_cast< T >(1);
|
|||
|
T zeroTmp = static_cast< T >(0);
|
|||
|
|
|||
|
if (rotateorder == "y-z-x" || rotateorder == "Y-Z-X" || rotateorder == "2-3-1")
|
|||
|
{
|
|||
|
T cosineofpitchangle = cos(pitchangle);
|
|||
|
if (PHSPACE::ABS(cosineofpitchangle) < SMALL)
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : pitching angle is 90 DEG<45><47>singular ! ");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
T sineofpitchangle = sin(pitchangle);
|
|||
|
T cosineofrollangle = cos(rollangle);
|
|||
|
T sineofrollangle = sin(rollangle);
|
|||
|
|
|||
|
matrix(1, 1) = zeroTmp;
|
|||
|
matrix(1, 2) = sineofrollangle;
|
|||
|
matrix(1, 3) = cosineofrollangle;
|
|||
|
|
|||
|
matrix(2, 1) = zeroTmp;
|
|||
|
matrix(2, 2) = cosineofrollangle / cosineofpitchangle;
|
|||
|
matrix(2, 3) =-sineofrollangle / cosineofpitchangle;
|
|||
|
|
|||
|
matrix(3, 1) = oneTmp;
|
|||
|
matrix(3, 2) =-cosineofrollangle * sineofpitchangle / cosineofpitchangle;
|
|||
|
matrix(3, 3) = sineofrollangle * sineofpitchangle / cosineofpitchangle;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
TK_Exit::ExceptionExit("Error : Undefined Euler Angle transformation order ! ");
|
|||
|
}
|
|||
|
|
|||
|
return matrix;
|
|||
|
}
|
|||
|
|
|||
|
template < typename T >
|
|||
|
PHMatrix<T> CrossProductVector(PHMatrix<T> a, PHMatrix<T> b)
|
|||
|
{
|
|||
|
PHMatrix<T> cp(a.rows());
|
|||
|
cp(1) = a(2) * b(3) - a(3) * b(2);
|
|||
|
cp(2) = a(3) * b(1) - a(1) * b(3);
|
|||
|
cp(3) = a(1) * b(2) - a(2) * b(1);
|
|||
|
return cp;
|
|||
|
}
|
|||
|
|
|||
|
}
|