Loading...
Searching...
No Matches
system_solvers_large.hpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_SYSTEM_SOLVERS_LARGE_HPP__
26#define __BITPIT_SYSTEM_SOLVERS_LARGE_HPP__
27
28#include <unordered_map>
29#include <unordered_set>
30#include <vector>
31
32#include <petscksp.h>
33
34#include "bitpit_IO.hpp"
35
36#include "system_matrix.hpp"
37
38namespace bitpit {
39
40struct KSPOptions {
41 PetscInt overlap;
42 PetscInt levels;
43
44 PetscBool initial_non_zero;
45 PetscInt restart;
46 PetscInt maxits;
47 PetscScalar rtol;
48 PetscScalar atol;
49
51 : overlap(PETSC_DEFAULT), levels(PETSC_DEFAULT),
52 initial_non_zero(PETSC_TRUE), restart(PETSC_DEFAULT),
53 maxits(PETSC_DEFAULT), rtol(PETSC_DEFAULT), atol(PETSC_DEFAULT)
54 {
55 }
56};
57
58struct KSPStatus {
59 PetscErrorCode error;
60 PetscInt its;
61 KSPConvergedReason convergence;
62
63 KSPStatus()
64 : error(0), its(-1), convergence(KSP_DIVERGED_BREAKDOWN)
65 {
66 }
67};
68
69class SystemMatrixOrdering
70{
71
72public:
73 virtual ~SystemMatrixOrdering() = default;
74
85 virtual long getRowPermutationRank(long row) const = 0;
86
97 virtual long getColPermutationRank(long col) const = 0;
98
99protected:
100 SystemMatrixOrdering() = default;
101
102};
103
104class NaturalSystemMatrixOrdering : public SystemMatrixOrdering
105{
106
107public:
108 NaturalSystemMatrixOrdering() = default;
109
110 long getRowPermutationRank(long row) const override;
111 long getColPermutationRank(long col) const override;
112
113};
114
115template<typename RowRankStorage, typename ColRankStorage>
116class ProxySystemMatrixOrdering : public SystemMatrixOrdering
117{
118
119public:
120 ProxySystemMatrixOrdering(const RowRankStorage *rowRankStorage, const ColRankStorage *colRankStorage);
121
122 long getRowPermutationRank(long row) const override;
123 long getColPermutationRank(long col) const override;
124
125private:
126 const RowRankStorage *m_rowRankStorage;
127 const ColRankStorage *m_colRankStorage;
128
129};
130
131class SystemMatrixAssembler {
132
133public:
135 bool full;
136 bool sorted;
137 };
138
139 virtual ~SystemMatrixAssembler() = default;
140
141#if BITPIT_ENABLE_MPI==1
142 virtual bool isPartitioned() const = 0;
143 virtual const MPI_Comm & getCommunicator() const = 0;
144#endif
145
146 virtual AssemblyOptions getOptions() const = 0;
147
148 virtual int getBlockSize() const = 0;
149
150 virtual long getRowCount() const = 0;
151 virtual long getColCount() const = 0;
152
153 virtual long getRowElementCount() const = 0;
154 virtual long getColElementCount() const = 0;
155
156#if BITPIT_ENABLE_MPI==1
157 virtual long getRowGlobalCount() const = 0;
158 virtual long getColGlobalCount() const = 0;
159
160 virtual long getRowGlobalElementCount() const = 0;
161 virtual long getColGlobalElementCount() const = 0;
162
163 virtual long getRowGlobalOffset() const = 0;
164 virtual long getColGlobalOffset() const = 0;
165
166 virtual long getRowGlobalElementOffset() const = 0;
167 virtual long getColGlobalElementOffset() const = 0;
168#endif
169
170 virtual long getRowNZCount(long rowIndex) const = 0;
171 virtual long getMaxRowNZCount() const = 0;
172
173 virtual void getRowPattern(long rowIndex, ConstProxyVector<long> *pattern) const = 0;
174 virtual void getRowValues(long rowIndex, ConstProxyVector<double> *values) const = 0;
175 virtual void getRowData(long rowIndex, ConstProxyVector<long> *pattern, ConstProxyVector<double> *values) const = 0;
176
177protected:
178 SystemMatrixAssembler() = default;
179
180};
181
182class SystemSparseMatrixAssembler : virtual public SystemMatrixAssembler {
183
184public:
186
187#if BITPIT_ENABLE_MPI==1
188 bool isPartitioned() const override;
189 const MPI_Comm & getCommunicator() const override;
190#endif
191
192 AssemblyOptions getOptions() const override;
193
194 int getBlockSize() const override;
195
196 long getRowCount() const override;
197 long getColCount() const override;
198
199 long getRowElementCount() const override;
200 long getColElementCount() const override;
201
202#if BITPIT_ENABLE_MPI==1
203 long getRowGlobalCount() const override;
204 long getColGlobalCount() const override;
205
206 long getRowGlobalElementCount() const override;
207 long getColGlobalElementCount() const override;
208
209 long getRowGlobalOffset() const override;
210 long getColGlobalOffset() const override;
211
212 long getRowGlobalElementOffset() const override;
213 long getColGlobalElementOffset() const override;
214#endif
215
216 long getRowNZCount(long rowIndex) const override;
217 long getMaxRowNZCount() const override;
218
219 void getRowPattern(long rowIndex, ConstProxyVector<long> *pattern) const override;
220 void getRowValues(long rowIndex, ConstProxyVector<double> *values) const override;
221 void getRowData(long rowIndex, ConstProxyVector<long> *pattern, ConstProxyVector<double> *values) const override;
222
223protected:
224 const SparseMatrix *m_matrix;
225
226};
227
229
230public:
231 PetscManager();
232
233 virtual ~PetscManager();
234
235 bool areOptionsEditable() const;
236
237 bool initialize(bool debug);
238 bool finalize();
239
240 void addInitOption(const std::string &option);
241 void addInitOptions(int argc, char **args);
242 void addInitOptions(const std::vector<std::string> &options);
243 void clearInitOptions();
244
245private:
246 static PetscErrorCode displayLogView();
247
248 bool m_externalMPIInitialization;
249 bool m_externalPETScInitialization;
250
251 std::vector<std::string> m_options;
252
253 bool m_logViewEnabled;
254
255 void enableLogView();
256
257};
258
260
261public:
262 typedef SystemMatrixAssembler Assembler;
263
264 enum FileFormat {
265 FILE_BINARY,
266 FILE_ASCII
267 };
268
269 SystemSolver(bool debug = false);
270 SystemSolver(bool transpose, bool debug);
271 SystemSolver(bool flatten, bool transpose, bool debug);
272 SystemSolver(const std::string &prefix, bool debug = false);
273 SystemSolver(const std::string &prefix, bool transpose, bool debug);
274 SystemSolver(const std::string &prefix, bool flatten, bool transpose, bool debug);
275
276 virtual ~SystemSolver();
277
278 virtual void clear();
279 virtual void clearWorkspace();
280
281 bool isAssembled() const;
282
283 void assembly(const SparseMatrix &matrix);
284 void assembly(const SparseMatrix &matrix, const SystemMatrixOrdering &reordering);
285 void assembly(const Assembler &assembler);
286 void assembly(const Assembler &assembler, const SystemMatrixOrdering &reordering);
287
288 void update(const SparseMatrix &elements);
289 void update(long nRows, const long *rows, const SparseMatrix &elements);
290 void update(const Assembler &assembler);
291 void update(long nRows, const long *rows, const Assembler &assembler);
292
293 bool getTranspose() const;
294 void setTranspose(bool transpose);
295
296 virtual int getBlockSize() const;
297
298 long getRowCount() const;
299 long getColCount() const;
300 long getRowElementCount() const;
301 long getColElementCount() const;
302#if BITPIT_ENABLE_MPI==1
303 long getRowGlobalCount() const;
304 long getColGlobalCount() const;
305 long getRowGlobalElementCount() const;
306 long getColGlobalElementCount() const;
307
308 bool isPartitioned() const;
309#endif
310
311 void solve();
312 void solve(const std::vector<double> &rhs, std::vector<double> *solution);
313
314 void dumpSystem(const std::string &header, const std::string &directory, const std::string &prefix = "") const;
315#if BITPIT_ENABLE_MPI==1
316 void restoreSystem(MPI_Comm communicator, bool redistribute, const std::string &directory,
317 const std::string &prefix = "");
318#else
319 void restoreSystem(const std::string &directory, const std::string &prefix = "");
320#endif
321
322 virtual void setNullSpace();
323 void unsetNullSpace();
324
326 const KSPOptions & getKSPOptions() const;
327
328 const KSPStatus & getKSPStatus() const;
329
330 virtual void exportMatrix(const std::string &filePath, FileFormat exportFormat = FILE_BINARY) const;
331 virtual void importMatrix(const std::string &filePath);
332
333 double * getRHSRawPtr();
334 const double * getRHSRawPtr() const;
335 const double * getRHSRawReadPtr() const;
336 void restoreRHSRawPtr(double *raw_rhs);
337 void restoreRHSRawReadPtr(const double *raw_rhs) const;
338 virtual void exportRHS(const std::string &filePath, FileFormat exportFormat = FILE_BINARY) const;
339 virtual void importRHS(const std::string &filePath);
340
341 double * getSolutionRawPtr();
342 const double * getSolutionRawPtr() const;
343 const double * getSolutionRawReadPtr() const;
344 void restoreSolutionRawPtr(double *raw_solution);
345 void restoreSolutionRawReadPtr(const double *raw_solution) const;
346 virtual void exportSolution(const std::string &filePath, FileFormat exportFormat = FILE_BINARY) const;
347 virtual void importSolution(const std::string &filePath);
348
349 bool isForceConsistencyEnabled() const;
350 void enableForceConsistency(bool enable);
351
352protected:
353 enum VectorSide {
354 VECTOR_SIDE_RIGHT, // Vector that the matrix can be multiplied against
355 VECTOR_SIDE_LEFT, // Vector that the matrix vector product can be stored in
356 };
357
358 bool m_flatten;
359 bool m_transpose;
360
361 Mat m_A;
362 Vec m_rhs;
363 Vec m_solution;
364
365 IS m_rowReordering;
366 IS m_colReordering;
367
368 bool m_convergenceMonitorEnabled;
369
370 KSP m_KSP;
371 bool m_KSPDirty;
372 KSPOptions m_KSPOptions;
373 KSPStatus m_KSPStatus;
374
375 virtual int getDumpVersion() const;
376
377 void matrixAssembly(const Assembler &assembler);
378 void matrixUpdate(long nRows, const long *rows, const Assembler &assembler);
379 virtual void matrixFill(const std::string &filePath);
380 virtual void matrixDump(std::ostream &systemStream, const std::string &directory, const std::string &prefix) const;
381#if BITPIT_ENABLE_MPI==1
382 virtual void matrixRestore(std::istream &systemStream, const std::string &directory, const std::string &prefix, bool redistribute);
383#else
384 virtual void matrixRestore(std::istream &systemStream, const std::string &directory, const std::string &prefix);
385#endif
386 virtual void matrixDestroy();
387
388 virtual void vectorsCreate();
389 virtual void vectorsFill(const std::vector<double> &rhs, const std::vector<double> &solution);
390 virtual void vectorsFill(const std::string &rhsFilePath, const std::string &solutionFilePath);
391 virtual void vectorsReorder(bool invert);
392 virtual void vectorsDump(std::ostream &systemStream, const std::string &directory, const std::string &prefix) const;
393 virtual void vectorsRestore(std::istream &systemStream, const std::string &directory, const std::string &prefix);
394 virtual void vectorsDestroy();
395
396 void clearReordering();
397 void setReordering(long nRows, long nCols, const SystemMatrixOrdering &reordering);
398
399 template<typename DerivedSystemSolver>
400 void assembly(const typename DerivedSystemSolver::Assembler &assembler, const SystemMatrixOrdering &reordering);
401
402 template<typename DerivedSystemSolver>
403 void update(long nRows, const long *rows, const typename DerivedSystemSolver::Assembler &assembler);
404
405 virtual void prepareKSP();
406 virtual void finalizeKSP();
407 virtual void createKSP();
408 virtual void destroyKSP();
409
410 virtual void setupPreconditioner();
411 virtual void setupPreconditioner(PC pc, const KSPOptions &options) const;
412 virtual void prePreconditionerSetupActions();
413 virtual void postPreconditionerSetupActions();
414
415 virtual void setupKrylov();
416 virtual void setupKrylov(KSP ksp, const KSPOptions &options) const;
417 virtual void preKrylovSetupActions();
418 virtual void postKrylovSetupActions();
419
420 virtual void solveKSP();
421 virtual void preKSPSolveActions();
422 virtual void postKSPSolveActions();
423
424 virtual void initializeKSPOptions();
425 virtual void resetKSPOptions(KSPOptions *options) const;
426 virtual void destroyKSPOptions();
427
428 virtual void initializeKSPStatus();
429 virtual void resetKSPStatus();
430 virtual void resetKSPStatus(KSPStatus *status) const;
431 virtual void fillKSPStatus();
432 virtual void fillKSPStatus(KSP ksp, KSPStatus *status) const;
433 virtual void destroyKSPStatus();
434
435 virtual void dumpInfo(std::ostream &stream) const;
436 virtual void restoreInfo(std::istream &stream);
437
438 void createMatrix(int rowBlockSize, int colBlockSize, Mat *matrix) const;
439 void createMatrix(int rowBlockSize, int colBlockSize, int nNestRows, int nNestCols, Mat *subMatrices, Mat *matrix) const;
440 void fillMatrix(Mat matrix, const std::string &filePath) const;
441 void dumpMatrix(Mat matrix, const std::string &directory, const std::string &name) const;
442#if BITPIT_ENABLE_MPI==1
443 void restoreMatrix(const std::string &directory, const std::string &name, bool redistribute, Mat *matrix) const;
444#else
445 void restoreMatrix(const std::string &directory, const std::string &name, Mat *matrix) const;
446#endif
447 void exportMatrix(Mat matrix, const std::string &filePath, FileFormat fileFormat) const;
448 void destroyMatrix(Mat *matrix) const;
449
450 void createVector(int blockSize, Vec *vector) const;
451 void createVector(int blockSize, int nestSize, Vec *subVectors, Vec *vector) const;
452 void fillVector(Vec vector, const std::string &filePath) const;
453 void fillVector(Vec vector, const std::vector<double> &data) const;
454 void reorderVector(Vec vector, IS permutations, bool invert) const;
455 void dumpVector(Vec vector, const std::string &directory, const std::string &name) const;
456 void dumpVector(Vec vector, VectorSide side, const std::string &directory, const std::string &name) const;
457 void restoreVector(const std::string &directory, const std::string &name, Mat matrix, VectorSide side, Vec *vector) const;
458#if BITPIT_ENABLE_MPI==1
459 void restoreVector(const std::string &directory, const std::string &name, bool redistribute, Vec *vector) const;
460#else
461 void restoreVector(const std::string &directory, const std::string &name, Vec *vector) const;
462#endif
463 void restoreVector(const std::string &directory, const std::string &name, std::size_t localSize, std::size_t globalSize, Vec *vector) const;
464 void exportVector(Vec vector, const std::string &filePath, FileFormat fileFormat) const;
465 void exportVector(Vec vector, std::vector<double> *data) const;
466 void destroyVector(Vec *vector) const;
467
468 std::string getInfoFilePath(const std::string &directory, const std::string &name) const;
469 std::string getDataFilePath(const std::string &directory, const std::string &name) const;
470 std::string getFilePath(const std::string &directory, const std::string &name) const;
471
472#if BITPIT_ENABLE_MPI==1
473 const MPI_Comm & getCommunicator() const;
474#endif
475
476private:
477 static PetscManager m_petscManager;
478
479 static int m_nInstances;
480
481 std::string m_prefix;
482
483 bool m_assembled;
484
485#if BITPIT_ENABLE_MPI==1
486 MPI_Comm m_communicator;
487
488 bool m_partitioned;
489#endif
490
491 bool m_forceConsistency;
492
493#if BITPIT_ENABLE_MPI==1
494 void setCommunicator(MPI_Comm communicator);
495 void freeCommunicator();
496#endif
497
498 void resetPermutations();
499
500 void removeNullSpaceFromRHS();
501
502 void openBinaryArchive(const std::string &directory, const std::string &prefix,
503 int block, IBinaryArchive *archive) const;
504 void openBinaryArchive(const std::string &header, const std::string &directory,
505 const std::string &prefix, int block, OBinaryArchive *archive) const;
506
507 void closeBinaryArchive(BinaryArchive *archive) const;
508
509 int getBinaryArchiveBlock() const;
510};
511
512}
513
514// Include template implementations
515#include "system_solvers_large.tpp"
516
517#endif
Base class for binary archives.
Input binary archive.
long getColPermutationRank(long col) const override
long getRowPermutationRank(long row) const override
Output binary archive.
The PetscManager class handles the interaction with PETSc library.
void addInitOptions(int argc, char **args)
void addInitOption(const std::string &option)
long getRowPermutationRank(long row) const override
long getColPermutationRank(long col) const override
ProxySystemMatrixOrdering(const RowRankStorage *rowRankStorage, const ColRankStorage *colRankStorage)
The SystemMatrixAssembler class provides an interface for defining system matrix assemblers.
The SystemMatrixOrdering class provides an interface for defining classes that allows to reorder the ...
virtual long getColPermutationRank(long col) const =0
virtual long getRowPermutationRank(long row) const =0
void dumpMatrix(Mat matrix, const std::string &directory, const std::string &name) const
void matrixUpdate(long nRows, const long *rows, const Assembler &assembler)
virtual int getDumpVersion() const
virtual void exportMatrix(const std::string &filePath, FileFormat exportFormat=FILE_BINARY) const
virtual void matrixFill(const std::string &filePath)
virtual void prePreconditionerSetupActions()
void restoreSolutionRawPtr(double *raw_solution)
virtual void matrixRestore(std::istream &systemStream, const std::string &directory, const std::string &prefix, bool redistribute)
void fillMatrix(Mat matrix, const std::string &filePath) const
void restoreRHSRawReadPtr(const double *raw_rhs) const
void dumpVector(Vec vector, const std::string &directory, const std::string &name) const
virtual void postPreconditionerSetupActions()
virtual void importMatrix(const std::string &filePath)
void reorderVector(Vec vector, IS permutations, bool invert) const
std::string getInfoFilePath(const std::string &directory, const std::string &name) const
virtual void vectorsDump(std::ostream &systemStream, const std::string &directory, const std::string &prefix) const
virtual void resetKSPOptions(KSPOptions *options) const
void exportVector(Vec vector, const std::string &filePath, FileFormat fileFormat) const
void dumpSystem(const std::string &header, const std::string &directory, const std::string &prefix="") const
void setReordering(long nRows, long nCols, const SystemMatrixOrdering &reordering)
virtual void restoreInfo(std::istream &stream)
void restoreSystem(MPI_Comm communicator, bool redistribute, const std::string &directory, const std::string &prefix="")
const double * getSolutionRawReadPtr() const
virtual void exportRHS(const std::string &filePath, FileFormat exportFormat=FILE_BINARY) const
virtual int getBlockSize() const
void restoreRHSRawPtr(double *raw_rhs)
void setTranspose(bool transpose)
const KSPStatus & getKSPStatus() const
void restoreMatrix(const std::string &directory, const std::string &name, bool redistribute, Mat *matrix) const
void matrixAssembly(const Assembler &assembler)
void createVector(int blockSize, Vec *vector) const
void destroyMatrix(Mat *matrix) const
std::string getFilePath(const std::string &directory, const std::string &name) const
virtual void matrixDump(std::ostream &systemStream, const std::string &directory, const std::string &prefix) const
virtual void dumpInfo(std::ostream &stream) const
void assembly(const SparseMatrix &matrix)
const MPI_Comm & getCommunicator() const
std::string getDataFilePath(const std::string &directory, const std::string &name) const
const double * getRHSRawReadPtr() const
virtual void importSolution(const std::string &filePath)
virtual void importRHS(const std::string &filePath)
void destroyVector(Vec *vector) const
void createMatrix(int rowBlockSize, int colBlockSize, Mat *matrix) const
void fillVector(Vec vector, const std::string &filePath) const
virtual void vectorsFill(const std::vector< double > &rhs, const std::vector< double > &solution)
void enableForceConsistency(bool enable)
void restoreSolutionRawReadPtr(const double *raw_solution) const
virtual void vectorsReorder(bool invert)
virtual void vectorsRestore(std::istream &systemStream, const std::string &directory, const std::string &prefix)
void restoreVector(const std::string &directory, const std::string &name, Mat matrix, VectorSide side, Vec *vector) const
virtual void exportSolution(const std::string &filePath, FileFormat exportFormat=FILE_BINARY) const
void getRowValues(long rowIndex, ConstProxyVector< double > *values) const override
const MPI_Comm & getCommunicator() const override
void getRowData(long rowIndex, ConstProxyVector< long > *pattern, ConstProxyVector< double > *values) const override
long getRowNZCount(long rowIndex) const override
AssemblyOptions getOptions() const override
void getRowPattern(long rowIndex, ConstProxyVector< long > *pattern) const override
SystemSparseMatrixAssembler(const SparseMatrix *matrix)
PetscInt levels
Overlap between a pair of subdomains for the partitioned preconditioner.
PetscInt restart
Tells the iterative solver that the initial guess is nonzero.
PetscInt maxits
Number of iterations at which the GMRES method restarts.
PetscScalar atol
Relative convergence tolerance, relative decrease in the preconditioned residual norm.
PetscScalar rtol
Maximum number of iterations.
PetscBool initial_non_zero
Number of levels of fill used by the preconditioner.
KSPOptions()
Absolute convergence tolerance, absolute size of the preconditioned residual norm.
bool full
Controls if the assembler is providing all the non-zero values of a row.