16 static_assert(std::is_same<typename DirectSolverType::MatrixType,typename IterativeSolverType::MatrixType>::value,
"Direct and Iterative MatrixType must be the same");
67 Eigen::VectorXd
solve(
const Eigen::VectorXd&
b)
const
72 Eigen::VectorXd g(Eigen::VectorXd::Zero(gSize));
73 Eigen::VectorXd guess(Eigen::VectorXd::Zero(tSize));
78 for (
const auto& cIter : *dirichletConditions)
80 const size_t& endRow = cIter.first;
81 g(endRow)= cIter.second;
82 for (
size_t row=startRow;row!=endRow;++row)
84 guess(col)=(*dofVector)(row);
89 for (
size_t row=startRow;row!=gSize;++row)
91 guess(col)=(*dofVector)(row);
95 Eigen::VectorXd b1(T.transpose()*(
b-A*g));
96 Eigen::VectorXd
x(Eigen::VectorXd::Zero(b1.rows()));
99 x=directSolver.solve(b1);
100 if(directSolver.info()!=Eigen::Success)
102 throw std::runtime_error(
"Direct FixedDirichletSolver failed.");
107 x=iterativeSolver.solveWithGuess(b1,guess);
108 if(iterativeSolver.info()!=Eigen::Success)
110 throw std::runtime_error(
"Iterative FixedDirichletSolver failed.");
117 void compute(
const std::shared_ptr<BilinearWeakFormType>& bWF)
119 fieldOwner=bWF->field().ownership();
120 dirichletConditions=&bWF->field().dirichletConditions();
121 dofVector=&bWF->field().dofVector();
122 gSize=bWF->field().gSize();
123 cSize=dirichletConditions->size();
126 A.resize(gSize,gSize);
127 const auto aTriplets(bWF->globalTriplets());
128 A.setFromTriplets(aTriplets.begin(),aTriplets.end());
130 std::vector<Eigen::Triplet<double> > tTriplets;
131 tTriplets.reserve(tSize);
134 for (
const auto& cIter : *dirichletConditions)
136 const size_t& endRow = cIter.first;
137 for (
size_t row=startRow;row!=endRow;++row)
139 tTriplets.emplace_back(row,col,1.0);
144 for (
size_t row=startRow;row!=gSize;++row)
146 tTriplets.emplace_back(row,col,1.0);
149 T.resize(gSize,tSize);
150 T.setFromTriplets(tTriplets.begin(),tTriplets.end());
152 A1=T.transpose()*A*T;
156 directSolver.compute(A1);
157 if(directSolver.info()!=Eigen::Success)
159 throw std::runtime_error(
"FixedDirichletSolver failed.");
164 iterativeSolver.compute(A1);
165 if(iterativeSolver.info()!=Eigen::Success)
167 throw std::runtime_error(
"FixedDirichletSolver failed.");