Assemble and solve the equation system.
133{
136
139
140 std::vector<GlobalVector*> x_new{x};
141 x_new[process_id] =
144
145 bool error_norms_met = false;
146
148
149 int iteration = 1;
151 {
153 double time_dirichlet = 0.0;
154
156 time_iteration.
start();
157
158 INFO(
"Iteration #{:d} started.", iteration);
159 timer_dirichlet.
start();
160 auto& x_new_process = *x_new[process_id];
162 sys.computeKnownSolutions(x_new_process, process_id);
163 sys.applyKnownSolutions(x_new_process);
164 time_dirichlet += timer_dirichlet.
elapsed();
165
166 sys.preIteration(iteration, x_new_process);
167
169 time_assembly.
start();
170 sys.assemble(x_new, x_prev, process_id);
171 sys.getA(A);
172 sys.getRhs(*x_prev[process_id], rhs);
173
174
175 if (sys.requiresNormalization() &&
177 {
178 sys.getAandRhsNormalized(A, rhs);
180 "The equation system is rectangular, but the current linear "
181 "solver only supports square systems. "
182 "The system will be normalized, which lead to a squared "
183 "condition number and potential numerical issues. "
184 "It is recommended to use a solver that supports rectangular "
185 "equation systems for better numerical stability.");
186 }
187
188 INFO(
"[time] Assembly took {:g} s.", time_assembly.
elapsed());
189
190
192 {
194 }
195
196 timer_dirichlet.
start();
197 sys.applyKnownSolutionsPicard(A, rhs, x_new_process);
198 time_dirichlet += timer_dirichlet.
elapsed();
199 INFO(
"[time] Applying Dirichlet BCs took {:g} s.", time_dirichlet);
200
202 {
207 }
208
209 bool iteration_succeeded =
211 sys.linearSolverNeedsToCompute());
212
213 if (iteration_succeeded)
214 {
215 if (postIterationCallback)
216 {
217 postIterationCallback(iteration, error_norms_met, x_new);
218 }
219
220 switch (sys.postIteration(x_new_process))
221 {
223
224
225 break;
227 ERR(
"Picard: The postIteration() hook reported a "
228 "non-recoverable error.");
229 iteration_succeeded = false;
230
231
232
234 break;
237 "Picard: The postIteration() hook decided that this "
238 "iteration has to be repeated.");
240 *x[process_id],
241 x_new_process);
242 continue;
243 }
244 }
245
246 if (!iteration_succeeded)
247 {
248
249 error_norms_met = false;
250 break;
251 }
252
253 if (sys.isLinear())
254 {
255 error_norms_met = true;
256 }
257 else
258 {
260 {
263 x_new_process);
265 x_new_process);
266 }
267
269 }
270
271
273
274 INFO(
"[time] Iteration #{:d} took {:g} s.", iteration,
276
277 if (error_norms_met)
278 {
279 break;
280 }
281
282
283
285 {
286 break;
287 }
288 }
289
291 {
292 ERR(
"Picard: Could not solve the given nonlinear system within {:d} "
293 "iterations",
295 }
296
300
301 return {error_norms_met, iteration};
302}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
double elapsed() const
Get the elapsed time in seconds.
void start()
Start the timer.
bool canSolveRectangular() const
Get, if the solver can handle rectangular equation systems.
Global vector based on Eigen vector.
virtual void preFirstIteration()
virtual void checkResidual(GlobalVector const &residual)=0
Check if the residual satisfies the convergence criterion.
virtual bool hasResidualCheck() const =0
virtual bool isSatisfied() const
Tell if the convergence criterion is satisfied.
virtual void checkDeltaX(GlobalVector const &minus_delta_x, GlobalVector const &x)=0
virtual bool hasDeltaXCheck() const =0
void copy(PETScVector const &x, PETScVector &y)
void setLocalAccessibleVector(PETScVector const &x)
bool solvePicard(GlobalLinearSolver &linear_solver, GlobalMatrix &A, GlobalVector &rhs, GlobalVector &x, MathLib::LinearSolverBehaviour const linear_solver_behaviour)