730 lines
27 KiB
C++
730 lines
27 KiB
C++
#pragma once
|
|
|
|
#include "geom.h"
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
// #####################################################################
|
|
/**
|
|
* Abstract matrix class.
|
|
*/
|
|
class Matrix
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor for abstract matrix class.
|
|
*
|
|
* No memory is allocated.
|
|
*
|
|
* @param[in] nrows number of matrix rows.
|
|
* @param[in] ncols number of matrix columns.
|
|
*/
|
|
Matrix(int nrows, int ncols);
|
|
|
|
//Matrix(Matrix &) = default;
|
|
Matrix(Matrix const& org) = default; // Copy constructor
|
|
Matrix(Matrix && org) = default; // Move constructor
|
|
Matrix& operator=(Matrix const& rhs) = default; // Copy assignment
|
|
Matrix& operator=(Matrix && rhs) = default; // Move assignment
|
|
virtual ~Matrix();
|
|
|
|
/**
|
|
* Checks whether the matrix is a square matrix.
|
|
*
|
|
* @return True iff square matrix.
|
|
*/
|
|
bool isSquare() const
|
|
{ return _nrows==_ncols;}
|
|
|
|
/**
|
|
* Number of rows in matrix.
|
|
* @return number of rows.
|
|
*/
|
|
int Nrows() const
|
|
{return _nrows;}
|
|
|
|
/**
|
|
* Number of columns in matrix.
|
|
* @return number of columns.
|
|
*/
|
|
int Ncols() const
|
|
{return _ncols;}
|
|
|
|
/**
|
|
* Show the matrix entries.
|
|
*/
|
|
virtual void Debug() const = 0;
|
|
|
|
/**
|
|
* Extracts the diagonal elements of an inherited matrix.
|
|
*
|
|
* @param[in,out] d (prellocated) vector of diagonal elements
|
|
*/
|
|
virtual void GetDiag(std::vector<double> &d) const = 0;
|
|
|
|
/**
|
|
* Extracts the diagonal elements of the matrix.
|
|
*
|
|
* @return d vector of diagonal elements
|
|
*/
|
|
std::vector<double> const & GetDiag() const;
|
|
|
|
/**
|
|
* Performs the matrix-vector product w := K*u.
|
|
*
|
|
* @param[in,out] w resulting vector (preallocated)
|
|
* @param[in] u vector
|
|
*/
|
|
virtual void Mult(std::vector<double> &w, std::vector<double> const &u) const = 0;
|
|
|
|
/**
|
|
* Calculates the defect/residuum w := f - K*u.
|
|
*
|
|
* @param[in,out] w resulting vector (preallocated)
|
|
* @param[in] f load vector
|
|
* @param[in] u vector
|
|
*/
|
|
virtual void Defect(
|
|
std::vector<double> &w,
|
|
std::vector<double> const &f, std::vector<double> const &u) const = 0;
|
|
|
|
//virtual void JacobiSmoother(std::vector<double> const &f, std::vector<double> &u,
|
|
//std::vector<double> &r, int nsmooth, double const omega, bool zero) const
|
|
virtual void JacobiSmoother(std::vector<double> const &, std::vector<double> &,
|
|
std::vector<double> &, int, double const, bool) const
|
|
{
|
|
std::cout << "ERROR in Matrix::JacobiSmoother" << std::endl;
|
|
assert(false);
|
|
}
|
|
|
|
/**
|
|
* Finds in a CRS matrix the access index for an entry at row @p row and column @p col.
|
|
*
|
|
* @param[in] row row index
|
|
* @param[in] col column index
|
|
* @return index for element (@p row, @p col). If no appropriate entry exists then -1 will be returned.
|
|
*
|
|
* @warning assert() stops the function in case that matrix element (@p row, @p col) doesn't exist.
|
|
*/
|
|
virtual int fetch(int row, int col) const =0;
|
|
|
|
protected:
|
|
int _nrows; //!< number of rows in matrix
|
|
int _ncols; //!< number of columns in matrix
|
|
mutable std::vector<double> _dd; //!< diagonal matrix elements
|
|
};
|
|
|
|
// #####################################################################
|
|
class BisectInterpolation; // class forward declaration
|
|
/**
|
|
* Matrix in CRS format (compressed row storage; also named CSR),
|
|
* see an <a href="https://en.wikipedia.org/wiki/Sparse_matrix">introduction</a>.
|
|
*/
|
|
class CRS_Matrix: public Matrix
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
*
|
|
*/
|
|
CRS_Matrix();
|
|
|
|
//! \brief The sparse matrix in CRS format is initialized from a binary file.
|
|
//!
|
|
//! The binary file has to store 4 Byte integers and 8 Byte doubles and contains the following data:
|
|
//! - Number of rows
|
|
//! - Number of non-zero elements/blocks
|
|
//! - Number of non-zero matrix elements (= previous number * dofs per block)
|
|
//! - [#elements per row] (counter)
|
|
//! - [column indices]
|
|
//! - [matrix elements]
|
|
//!
|
|
//! \param[in] file name of binary file
|
|
//!
|
|
explicit CRS_Matrix(const std::string& file);
|
|
|
|
CRS_Matrix(CRS_Matrix const& org) = default; // Copy constructor
|
|
CRS_Matrix(CRS_Matrix && org) = default; // Move constructor
|
|
CRS_Matrix& operator=(CRS_Matrix const& rhs) = default; // Copy assignment
|
|
CRS_Matrix& operator=(CRS_Matrix && rhs) = default; // Move assignment
|
|
~CRS_Matrix() override;
|
|
|
|
/**
|
|
* Extracts the diagonal elements of the sparse matrix.
|
|
*
|
|
* @param[in,out] d (prellocated) vector of diagonal elements
|
|
*/
|
|
void GetDiag(std::vector<double> &d) const override;
|
|
|
|
// Solves non-M matrix problems for Jacobi iteration but not for MG
|
|
void GetDiag_M(std::vector<double> &d) const;
|
|
|
|
/**
|
|
* Performs the matrix-vector product w := K*u.
|
|
*
|
|
* @param[in,out] w resulting vector (preallocated)
|
|
* @param[in] u vector
|
|
*/
|
|
void Mult(std::vector<double> &w, std::vector<double> const &u) const override;
|
|
|
|
/**
|
|
* Calculates the defect/residuum w := f - K*u.
|
|
*
|
|
* @param[in,out] w resulting vector (preallocated)
|
|
* @param[in] f load vector
|
|
* @param[in] u vector
|
|
*/
|
|
void Defect(std::vector<double> &w,
|
|
std::vector<double> const &f, std::vector<double> const &u) const override;
|
|
|
|
void JacobiSmoother(std::vector<double> const &f, std::vector<double> &u,
|
|
std::vector<double> &r, int nsmooth, double omega, bool zero) const override;
|
|
|
|
/**
|
|
* Show the matrix entries.
|
|
*/
|
|
void Debug() const override;
|
|
|
|
/**
|
|
* Finds in a CRS matrix the access index for an entry at row @p row and column @p col.
|
|
*
|
|
* @param[in] row row index
|
|
* @param[in] col column index
|
|
* @return index for element (@p row, @p col). If no appropriate entry exists then -1 will be returned.
|
|
*
|
|
* @warning assert() stops the function in case that matrix element (@p row, @p col) doesn't exist.
|
|
*/
|
|
int fetch(int row, int col) const override;
|
|
|
|
/**
|
|
* Compare @p this CRS matrix with an external CRS matrix stored in C-Style.
|
|
*
|
|
* The method prints statements on differences found.
|
|
*
|
|
* @param[in] nnode row number of external matrix
|
|
* @param[in] id start indices of matrix rows of external matrix
|
|
* @param[in] ik column indices of external matrix
|
|
* @param[in] sk non-zero values of external matrix
|
|
*
|
|
* @return true iff all data are identical.
|
|
*/
|
|
bool Compare2Old(int nnode, int const id[], int const ik[], double const sk[]) const;
|
|
|
|
/**
|
|
* Calculates the defect and projects it to the next coarser level @f$ f_C := P^T \cdot (f_F - SK\cdot u_F) @f$.
|
|
*
|
|
* @param[in] SK matrix on fine mesh
|
|
* @param[in] P prolongation operator
|
|
* @param[in,out] fc resulting coarse mesh vector (preallocated)
|
|
* @param[in] ff r.h.s. on fine mesh
|
|
* @param[in] uf status vector on fine mesh
|
|
*
|
|
*/
|
|
friend void DefectRestrict(CRS_Matrix const & SK, BisectInterpolation const& P,
|
|
std::vector<double> &fc, std::vector<double> &ff, std::vector<double> &uf);
|
|
|
|
//! \brief A sparse matrix in CRS format (counter, column index, value) is written to a binary file.
|
|
//!
|
|
//! The binary file has to store 4 Byte integers and 8 Byte doubles and contains the following data:
|
|
//! - Number of rows
|
|
//! - Number of non-zero elements
|
|
//! - Number of non-zero elements
|
|
//! - [#elements per row]
|
|
//! - [column indices]
|
|
//! - [elements]
|
|
//!
|
|
//! \param[in] file name of binary file
|
|
//!
|
|
void writeBinary(const std::string& file);
|
|
|
|
private:
|
|
//! \brief A sparse matrix in CRS format (counter, column index, value) is read from a binary file.
|
|
//!
|
|
//! The binary file has to store 4 Byte integers and 8 Byte doubles and contains the following data:
|
|
//! - Number of rows
|
|
//! - Number of non-zero elements/blocks
|
|
//! - Number of non-zero matrix elements (= previous number * dofs per block)
|
|
//! - [#elements per row]
|
|
//! - [column indices]
|
|
//! - [matrix elements]
|
|
//!
|
|
//! \param[in] file name of binary file
|
|
//!
|
|
void readBinary(const std::string& file);
|
|
|
|
public:
|
|
//private:
|
|
/**
|
|
* Checks matrix symmetry.
|
|
* @return true iff matrix is symmetric.
|
|
*/
|
|
bool CheckSymmetry() const;
|
|
|
|
/**
|
|
* Checks whether the sum of all entries in each separate row is zero.
|
|
* @return true/false
|
|
*/
|
|
bool CheckRowSum() const;
|
|
|
|
/**
|
|
* Checks M-matrix properties.
|
|
* @return true/false
|
|
*/
|
|
bool CheckMproperty() const;
|
|
|
|
/**
|
|
* Checks for several matrix properties, as row sum and M-matrix
|
|
* @return true/false
|
|
*/
|
|
bool CheckMatrix() const;
|
|
|
|
/**
|
|
* Changes the given matrix into an M-matrix.
|
|
* The posive off diagonal enries of a row are lumped (added)
|
|
* to the main diagonal entry of that row.
|
|
*
|
|
* @return true iff changes have been neccessary.
|
|
*/
|
|
bool ForceMproperty();
|
|
|
|
protected:
|
|
int _nnz; //!< number of non-zero entries
|
|
std::vector<int> _id; //!< start indices of matrix rows
|
|
std::vector<int> _ik; //!< column indices
|
|
std::vector<double> _sk; //!< non-zero values
|
|
};
|
|
|
|
|
|
/**
|
|
* FEM Matrix in CRS format (compressed row storage; also named CSR),
|
|
* see an <a href="https://en.wikipedia.org/wiki/Sparse_matrix">introduction</a>.
|
|
*/
|
|
class FEM_Matrix: public CRS_Matrix
|
|
{
|
|
public:
|
|
/**
|
|
* Initializes the CRS matrix structure from the given discretization in @p mesh.
|
|
*
|
|
* The sparse matrix pattern is generated but the values are 0.
|
|
*
|
|
* @param[in] mesh given discretization
|
|
*
|
|
* @warning A reference to the discretization @p mesh is stored inside this class.
|
|
* Therefore, changing @p mesh outside requires also
|
|
* to call method @p Derive_Matrix_Pattern explicitly.
|
|
*
|
|
* @see Derive_Matrix_Pattern
|
|
*/
|
|
explicit FEM_Matrix(Mesh const & mesh);
|
|
|
|
FEM_Matrix(FEM_Matrix const &) = default;
|
|
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
~FEM_Matrix() override;
|
|
|
|
/**
|
|
* Generates the sparse matrix pattern and overwrites the existing pattern.
|
|
*
|
|
* The sparse matrix pattern is generated but the values are 0.
|
|
*/
|
|
void Derive_Matrix_Pattern()
|
|
{
|
|
//Derive_Matrix_Pattern_slow();
|
|
Derive_Matrix_Pattern_fast();
|
|
CheckRowSum();
|
|
}
|
|
void Derive_Matrix_Pattern_fast();
|
|
void Derive_Matrix_Pattern_slow();
|
|
|
|
|
|
/**
|
|
* Calculates the entries of f.e. stiffness matrix for the Laplace operator
|
|
* for multiple domains with different conductivities
|
|
* and load/rhs vector @p f.
|
|
* No memory is allocated.
|
|
*
|
|
* @param[in,out] f (preallocated) rhs/load vector
|
|
*/
|
|
void CalculateLaplaceMult(std::vector<double> &f);
|
|
|
|
// Returns thermal conductivity coefficient of subdomain [ kg * m / (s^3 * K) ]
|
|
double ThermalConductivity(const int subdomain);
|
|
|
|
// Returns volumetric heap capacity (specific heat capacity * density) coefficient of subdomain
|
|
// c * rho [ J / (m^3 * K) ]
|
|
double VolumetricHeatCapacity(const int subdomain);
|
|
|
|
/**
|
|
* Calculates the entries of f.e. stiffness matrix for the Laplace operator
|
|
* and load/rhs vector @p f.
|
|
* No memory is allocated.
|
|
*
|
|
* @param[in,out] f (preallocated) rhs/load vector
|
|
*/
|
|
void CalculateLaplace(std::vector<double> &f);
|
|
|
|
///**
|
|
//* Calculates the entries of f.e. stiffness matrix for the Laplace operator
|
|
//* and load/rhs vector @p f according to function @p f_func,
|
|
//*
|
|
//* @param[in,out] f (preallocated) rhs/load vector
|
|
//* @param[in] f_func function f(x,y,z)
|
|
//*/
|
|
//void CalculateLaplace(std::vector<double> &f, const std::function<double(double, double, double)> &f_func);
|
|
|
|
/**
|
|
* Calculates the entries of load/rhs vector @p f.
|
|
* No memory is allocated.
|
|
*
|
|
* @param[in,out] f (preallocated) rhs/load vector
|
|
* @param[in] func continuous function f(x,y)
|
|
*/
|
|
void CalculateRHS(std::vector<double> &f, const std::function<double(double,double)> &func);
|
|
|
|
/**
|
|
* Applies Dirichlet boundary conditions to stiffness matrix and to load vector @p f.
|
|
* The <a href="https://www.jstor.org/stable/2005611?seq=1#metadata_info_tab_contents">penalty method</a>
|
|
* is used for incorporating the given values @p u.
|
|
*
|
|
* @param[in] u (global) vector with Dirichlet data
|
|
* @param[in,out] f load vector
|
|
*/
|
|
void ApplyDirichletBC(std::vector<double> const &u, std::vector<double> &f);
|
|
|
|
/**
|
|
* Applies Robin boundary conditions to stiffness matrix and to load vector @p f
|
|
* for multiple subdomains
|
|
* The <a href="https://www.jstor.org/stable/2005611?seq=1#metadata_info_tab_contents">penalty method</a>
|
|
* is used for incorporating the given values @p u.
|
|
*
|
|
* @param[in] u (global) vector with Dirichlet data
|
|
* @param[in] u_out outside temperature
|
|
* @param[in,out] f load vector
|
|
*/
|
|
void ApplyRobinBC_mult(std::vector<double> const &u, std::vector<double> &f, const double u_out);
|
|
|
|
double Heat_transfer_coefficient(const int subdomain);
|
|
|
|
/**
|
|
* Extracts the diagonal elements of the sparse matrix.
|
|
*
|
|
* @param[in,out] d (prellocated) vector of diagonal elements
|
|
*/
|
|
//void GetDiag(std::vector<double> &d) const; // override in MPI parallel
|
|
void GetDiag(std::vector<double> &d) const override { GetDiag_M(d); }
|
|
|
|
// Solves non-M matrix problems for Jacobi iteration but not for MG
|
|
//void GetDiag_M(std::vector<double> &d) const;
|
|
|
|
|
|
/**
|
|
* Adds the element stiffness matrix @p ske and the element load vector @p fe
|
|
* of one triangular element with linear shape functions to the appropriate positions in
|
|
* the stiffness matrix, stored as CSR matrix K(@p sk,@p id, @p ik).
|
|
*
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] ske element stiffness matrix
|
|
* @param[in] fe element load vector
|
|
* @param[in,out] f distributed local vector storing the right hand side
|
|
*
|
|
* @warning Algorithm assumes linear triangular elements (ndof_e==3).
|
|
*/
|
|
void AddElem_3(int const ial[3], double const ske[3][3], double const fe[3], std::vector<double> &f);
|
|
|
|
/**
|
|
* Adds the the element load vector @p fe
|
|
* of one triangular element with linear shape functions to the appropriate positions in
|
|
* the right hand side @p f.
|
|
*
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] fe element load vector
|
|
* @param[in,out] f distributed local vector storing the right hand side
|
|
*
|
|
* @warning Algorithm assumes linear triangular elements (ndof_e==3).
|
|
*/
|
|
void AddElemRHS_3(int const ial[3], double const fe[3], std::vector<double> &f);
|
|
|
|
|
|
private:
|
|
Mesh const & _mesh; //!< reference to discretization
|
|
|
|
};
|
|
|
|
|
|
///**
|
|
//* Prolongation matrix in CRS format (compressed row storage; also named CSR),
|
|
//* see an <a href="https://en.wikipedia.org/wiki/Sparse_matrix">introduction</a>.
|
|
//*
|
|
//* The prolongation is applied for each node from the coarse mesh to the fine mesh and
|
|
//* is derived only geometrically (no operator weighted prolongation).
|
|
//*/
|
|
//class Prolongation: public CRS_Matrix
|
|
//{
|
|
//public:
|
|
///**
|
|
//* Intializes the CRS matrix structure from the given discetization in @p mesh.
|
|
//*
|
|
//* The sparse matrix pattern is generated but the values are 0.
|
|
//*
|
|
//* @param[in] cmesh coarse mesh
|
|
//* @param[in] fmesh fine mesh
|
|
//*
|
|
//* @warning A reference to the discretizations @p fmesh @p cmesh are stored inside this class.
|
|
//* Therefore, changing these meshes outside requires also
|
|
//* to call method @p Derive_Matrix_Pattern explicitely.
|
|
//*
|
|
//* @see Derive_Matrix_Pattern
|
|
//*/
|
|
//Prolongation(Mesh const & cmesh, Mesh const & fmesh);
|
|
|
|
///**
|
|
//* Destructor.
|
|
//*/
|
|
//~Prolongation() override
|
|
//{}
|
|
|
|
///**
|
|
//* Generates the sparse matrix pattern and overwrites the existing pattern.
|
|
//*
|
|
//* The sparse matrix pattern is generated but the values are 0.
|
|
//*/
|
|
//void Derive_Matrix_Pattern() override;
|
|
|
|
//private:
|
|
//Mesh const & _cmesh; //!< reference to coarse discretization
|
|
//Mesh const & _fmesh; //!< reference to fine discretization
|
|
//};
|
|
|
|
// *********************************************************************
|
|
|
|
|
|
/**
|
|
* Interpolation matrix for prolongation coarse mesh (C) to a fine mesh (F)
|
|
* generated by bisecting edges.
|
|
*
|
|
* All interpolation weights are 0.5 (injection points contribute twice).
|
|
*/
|
|
class BisectInterpolation: public Matrix
|
|
{
|
|
public:
|
|
/**
|
|
* Generates the interpolation matrix for prolongation coarse mesh to a fine mesh
|
|
* generated by bisecting edges.
|
|
* The interpolation weights are all 0.5.
|
|
*
|
|
* @param[in] fathers vector[nnodes][2] containing
|
|
* the two coarse grid fathers of a fine grid vertex
|
|
*
|
|
*/
|
|
explicit BisectInterpolation(std::vector<int> const & fathers);
|
|
BisectInterpolation();
|
|
|
|
BisectInterpolation(BisectInterpolation const& org) = default; // Copy constructor
|
|
BisectInterpolation(BisectInterpolation && org) = default; // Move constructor
|
|
BisectInterpolation& operator=(BisectInterpolation const& rhs) = default; // Copy assignment
|
|
BisectInterpolation& operator=(BisectInterpolation && rhs) = default; // Move assignment
|
|
~BisectInterpolation() override;
|
|
|
|
/**
|
|
* Extracts the diagonal elements of the matrix.
|
|
*
|
|
* @param[in,out] d (prellocated) vector of diagonal elements
|
|
*/
|
|
void GetDiag(std::vector<double> &d) const override;
|
|
///**
|
|
//* Extracts the diagonal elements of the sparse matrix.
|
|
//*
|
|
//* @return d vector of diagonal elements
|
|
//*/
|
|
//std::vector<double> const & GetDiag() const override;
|
|
|
|
/**
|
|
* Performs the prolongation @f$ w_F := P*u_C @f$.
|
|
*
|
|
* @param[in,out] wf resulting fine vector (preallocated)
|
|
* @param[in] uc coarse vector
|
|
*/
|
|
void Mult(std::vector<double> &wf, std::vector<double> const &uc) const override;
|
|
|
|
/**
|
|
* Performs the restriction @f$ u_C := P^T*w_F @f$.
|
|
*
|
|
* @param[in] wf fine vector
|
|
* @param[in,out] uc resulting coarse vector (preallocated)
|
|
*/
|
|
virtual void MultT(std::vector<double> const &wf, std::vector<double> &uc) const;
|
|
|
|
/**
|
|
* Performs the full restriction @f$ u_C := F^{-1}*P^T*w_F @f$.
|
|
*
|
|
* @f$ F @f$ denotes the row sum of the restriction matrix
|
|
* and results in restricting exactly a bilinear function from the fine grid onto
|
|
* the same bilinear function on the coarse grid.
|
|
*
|
|
* @param[in] wf fine vector
|
|
* @param[in,out] uc resulting coarse vector (preallocated)
|
|
*/
|
|
void MultT_Full(std::vector<double> const &wf, std::vector<double> &uc) const;
|
|
|
|
|
|
/**
|
|
* Calculates the defect/residuum w := f - P*u.
|
|
*
|
|
* @param[in,out] w resulting vector (preallocated)
|
|
* @param[in] f load vector
|
|
* @param[in] u coarse vector
|
|
*/
|
|
void Defect(std::vector<double> &w,
|
|
std::vector<double> const &f, std::vector<double> const &u) const override;
|
|
|
|
/**
|
|
* Show the matrix entries.
|
|
*/
|
|
void Debug() const override;
|
|
|
|
/**
|
|
* Finds in this matrix the access index for an entry at row @p row and column @p col.
|
|
*
|
|
* @param[in] row row index
|
|
* @param[in] col column index
|
|
* @return index for element (@p row, @p col). If no appropriate entry exists then -1 will be returned.
|
|
*
|
|
* @warning assert() stops the function in case that matrix element (@p row, @p col) doesn't exist.
|
|
*/
|
|
int fetch(int row, int col) const override;
|
|
|
|
/**
|
|
* Calculates the defect and projects it to the next coarser level @f$ f_C := P^T \cdot (f_F - SK\cdot u_F) @f$.
|
|
*
|
|
* @param[in] SK matrix on fine mesh
|
|
* @param[in] P prolongation operator
|
|
* @param[in,out] fc resulting coarse mesh vector (preallocated)
|
|
* @param[in] ff r.h.s. on fine mesh
|
|
* @param[in] uf status vector on fine mesh
|
|
*
|
|
*/
|
|
friend void DefectRestrict(CRS_Matrix const & SK, BisectInterpolation const& P,
|
|
std::vector<double> &fc, std::vector<double> &ff, std::vector<double> &uf);
|
|
|
|
protected:
|
|
std::vector<int> _iv; //!< fathers[nnode][2] of fine grid nodes, double entries denote injection points
|
|
std::vector<double> _vv; //!< weights[nnode][2] of fathers for grid nodes
|
|
};
|
|
|
|
/**
|
|
* Interpolation matrix for prolongation from coarse mesh (C)) to a fine mesh (F)
|
|
* generated by bisecting edges.
|
|
*
|
|
* We take into account that values at Dirichlet nodes have to be preserved, i.e.,
|
|
* @f$ w_F = P \cdot I_D \cdot w_C @f$ and @f$ d_C = I_D \cdot P^T \cdot d_F@f$
|
|
* with @f$ I_D @f$ as @f$ n_C \times n_C @f$ diagonal matrix and entries
|
|
* @f$ I_{D(j,j)} := \left\{{\begin{array}{l@{\qquad}l} 0 & x_{j}\;\; \textrm{is Dirichlet node} \\ 1 & \textrm{else} \end{array}}\right. @f$
|
|
*
|
|
* Interpolation weights are eighter 0.5 or 0.0 in case of coarse Dirichlet nodes
|
|
* (injection points contribute twice),
|
|
* Sets weight to zero iff (at least) one father nodes is a Dirichlet node.
|
|
*/
|
|
class BisectIntDirichlet: public BisectInterpolation
|
|
{
|
|
public:
|
|
/**
|
|
* Default constructor.
|
|
*/
|
|
BisectIntDirichlet()
|
|
: BisectInterpolation(), _idxDir()
|
|
{}
|
|
|
|
/**
|
|
* Constructs interpolation from father-@p row and column @p col.
|
|
*
|
|
* @param[in] fathers two father nodes from each fine node [nnode_f*2].
|
|
* @param[in] idxc_dir vector containing the indices of coarse mesh Dirichlet nodes.
|
|
*
|
|
*/
|
|
BisectIntDirichlet(std::vector<int> const & fathers, std::vector<int> idxc_dir);
|
|
|
|
BisectIntDirichlet(BisectIntDirichlet const& org) = default; // Copy constructor
|
|
BisectIntDirichlet(BisectIntDirichlet && org) = default; // Move constructor
|
|
BisectIntDirichlet& operator=(BisectIntDirichlet const& rhs) = delete; // Copy assignment
|
|
BisectIntDirichlet& operator=(BisectIntDirichlet && rhs) = delete; // Move assignment
|
|
~BisectIntDirichlet() override;
|
|
|
|
/**
|
|
* Performs the restriction @f$ u_C := P^T*w_F @f$.
|
|
*
|
|
* @param[in] wf fine vector
|
|
* @param[in,out] uc resulting coarse vector (preallocated)
|
|
*/
|
|
void MultT(std::vector<double> const &wf, std::vector<double> &uc) const override;
|
|
|
|
private:
|
|
std::vector<int> const _idxDir;
|
|
};
|
|
|
|
|
|
|
|
// *********************************************************************
|
|
|
|
/**
|
|
* Calculates the element stiffness matrix @p ske and the element load vector @p fe
|
|
* of one triangular element with linear shape functions.
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] xc vector of node coordinates with x(2*k,2*k+1) as coordinates of node k
|
|
* @param[out] ske element stiffness matrix
|
|
* @param[out] fe element load vector
|
|
*/
|
|
void CalcElem(int const ial[3], double const xc[], double ske[3][3], double fe[3]);
|
|
|
|
/**
|
|
* Calculates the element stiffness matrix @p ske
|
|
* of one triangular element with linear shape functions
|
|
* for specific thermal conductivity in subdomain
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] xc vector of node coordinates with x(2*k,2*k+1) as coordinates of node k
|
|
* @param[in] lambda thermal conductivity of element
|
|
* @param[out] ske element stiffness matrix
|
|
*/
|
|
void CalcElemSpecific(int const ial[3], double const xc[], double const lambda, double ske[3][3]);
|
|
|
|
/**
|
|
* Calculates the element mass matrix @p ske.
|
|
* of one triangular element with linear shape functions.
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] xc vector of node coordinates with x(2*k,2*k+1) as coordinates of node k
|
|
* @param[out] ske element stiffness matrix
|
|
*/
|
|
void CalcElem_Masse(int const ial[3], double const xc[], double ske[3][3]);
|
|
|
|
/**
|
|
* Calculates element load vector @p fe of one triangular element with linear shape functions.
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] xc vector of node coordinates with x(2*k,2*k+1) as coordinates of node k
|
|
* @param[out] fe element load vector
|
|
* @param[in] func continuous function f(x,y)
|
|
*/
|
|
void CalcElem_RHS(int const ial[3], double const xc[], double fe[3],
|
|
const std::function<double(double,double)> &func);
|
|
|
|
/**
|
|
* Adds the element stiffness matrix @p ske and the element load vector @p fe
|
|
* of one triangular element with linear shape functions to the appropriate positions in
|
|
* the symmetric stiffness matrix, stored as CSR matrix K(@p sk,@p id, @p ik)
|
|
*
|
|
* @param[in] ial node indices of the three element vertices
|
|
* @param[in] ske element stiffness matrix
|
|
* @param[in] fe element load vector
|
|
* @param[out] sk vector non-zero entries of CSR matrix
|
|
* @param[in] id index vector containing the first entry in a CSR row
|
|
* @param[in] ik column index vector of CSR matrix
|
|
* @param[out] f distributed local vector storing the right hand side
|
|
*
|
|
* @warning Algorithm requires indices in connectivity @p ial in ascending order.
|
|
* Currently deprecated.
|
|
*/
|
|
void AddElem(int const ial[3], double const ske[3][3], double const fe[3],
|
|
int const id[], int const ik[], double sk[], double f[]);
|
|
|
|
|