Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
FixedDirichletSolver.h
Go to the documentation of this file.
1#ifndef model_FixedDirichletSolver_H_
2#define model_FixedDirichletSolver_H_
3
4#include<Eigen/SparseCore>
5#include<Eigen/SparseLU>
6#include<Eigen/IterativeLinearSolvers>
7
8#include<TrialBase.h>
9
10namespace model
11{
12 template<typename DirectSolverType,typename IterativeSolverType>
14 {// solves Ax=b given x=T*x1+g. Only b, and g can change
15
16 static_assert(std::is_same<typename DirectSolverType::MatrixType,typename IterativeSolverType::MatrixType>::value, "Direct and Iterative MatrixType must be the same");
17 typedef typename DirectSolverType::MatrixType SparseMatrixType;
18
19// public:
20// typedef Eigen::SparseMatrix<double,Eigen::RowMajor> SparseMatrixType;
21
22 // private:
23
24 SparseMatrixType A1;
25
26// Eigen::SparseLU<SparseMatrixType> directSolver;
27// Eigen::BiCGSTAB<SparseMatrixType> iterativeSolver;
28
29 DirectSolverType directSolver;
30 IterativeSolverType iterativeSolver;
31
32 std::shared_ptr<const void> fieldOwner;
33 const std::map<size_t,double>* dirichletConditions;
34 const Eigen::Matrix<double,Eigen::Dynamic,1>* dofVector;
35 size_t gSize;
36 size_t cSize;
37 size_t tSize;
38
39 SparseMatrixType A;
40 SparseMatrixType T;
41
42 public:
43
44 const bool use_directSolver;
45
46 const SparseMatrixType& getA() const
47 {
48 return A;
49 }
50
51 const SparseMatrixType& getT() const
52 {
53 return T;
54 }
55
56 FixedDirichletSolver(const bool& use_directSolver_in, const double& tol):
57 /* init */ dirichletConditions(nullptr)
58 /* init */,dofVector(nullptr)
59 /* init */,gSize(0)
60 /* init */,cSize(0)
61 /* init */,tSize(0)
62 /* init */,use_directSolver(use_directSolver_in)
63 {
64 iterativeSolver.setTolerance(tol);
65 }
66
67 Eigen::VectorXd solve(const Eigen::VectorXd& b) const
68 {
71
72 Eigen::VectorXd g(Eigen::VectorXd::Zero(gSize));
73 Eigen::VectorXd guess(Eigen::VectorXd::Zero(tSize));
74
75 size_t startRow=0;
76 size_t col=0;
77
78 for (const auto& cIter : *dirichletConditions)
79 {
80 const size_t& endRow = cIter.first;
81 g(endRow)= cIter.second;
82 for (size_t row=startRow;row!=endRow;++row)
83 {
84 guess(col)=(*dofVector)(row);
85 col++;
86 }
87 startRow=endRow+1;
88 }
89 for (size_t row=startRow;row!=gSize;++row)
90 {
91 guess(col)=(*dofVector)(row);
92 col++;
93 }
94
95 Eigen::VectorXd b1(T.transpose()*(b-A*g));
96 Eigen::VectorXd x(Eigen::VectorXd::Zero(b1.rows()));
98 {
99 x=directSolver.solve(b1);
100 if(directSolver.info()!=Eigen::Success)
101 {
102 throw std::runtime_error("Direct FixedDirichletSolver failed.");
103 }
104 }
105 else
106 {
107 x=iterativeSolver.solveWithGuess(b1,guess);
108 if(iterativeSolver.info()!=Eigen::Success)
109 {
110 throw std::runtime_error("Iterative FixedDirichletSolver failed.");
111 }
112 }
113 return T*x+g;
114 }
115
116 template<typename BilinearWeakFormType>
117 void compute(const std::shared_ptr<BilinearWeakFormType>& bWF)
118 {
119 fieldOwner=bWF->field().ownership();
120 dirichletConditions=&bWF->field().dirichletConditions();
121 dofVector=&bWF->field().dofVector();
122 gSize=bWF->field().gSize();
123 cSize=dirichletConditions->size();
124 tSize = gSize-cSize;
125
126 A.resize(gSize,gSize);
127 const auto aTriplets(bWF->globalTriplets());
128 A.setFromTriplets(aTriplets.begin(),aTriplets.end());
129
130 std::vector<Eigen::Triplet<double> > tTriplets;
131 tTriplets.reserve(tSize);
132 size_t startRow=0;
133 size_t col=0;
134 for (const auto& cIter : *dirichletConditions)
135 {
136 const size_t& endRow = cIter.first;
137 for (size_t row=startRow;row!=endRow;++row)
138 {
139 tTriplets.emplace_back(row,col,1.0);
140 col++;
141 }
142 startRow=endRow+1;
143 }
144 for (size_t row=startRow;row!=gSize;++row)
145 {
146 tTriplets.emplace_back(row,col,1.0);
147 col++;
148 }
149 T.resize(gSize,tSize);
150 T.setFromTriplets(tTriplets.begin(),tTriplets.end());
151
152 A1=T.transpose()*A*T; // store new A1
153
155 {
156 directSolver.compute(A1);
157 if(directSolver.info()!=Eigen::Success)
158 {
159 throw std::runtime_error("FixedDirichletSolver failed.");
160 }
161 }
162 else
163 {
164 iterativeSolver.compute(A1);
165 if(iterativeSolver.info()!=Eigen::Success)
166 {
167 throw std::runtime_error("FixedDirichletSolver failed.");
168 }
169 }
170 }
171 };
172
173}
174#endif
void compute(const std::shared_ptr< BilinearWeakFormType > &bWF)
FixedDirichletSolver(const bool &use_directSolver_in, const double &tol)
const SparseMatrixType & getA() const
const SparseMatrixType & getT() const
Eigen::VectorXd solve(const Eigen::VectorXd &b) const
b
Definition int_R.m:16
x
Definition int_R.m:12