GCC Code Coverage Report


Directory: ./
File: PETScInterface/petscMatrix_inline.hpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 104 196 53.1%
Branches: 38 260 14.6%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: Julien Castelneau, Dominique Chapelle, Miguel Fernandez
13 //
14
15 #ifndef PETSCMATRIX_HPP
16 #error Include petscMatrix.hpp instead of petscMatrix_inline.hpp
17 #endif
18
19 // System includes
20
21 // External includes
22
23 // Project includes
24 #include "Core/felisce.hpp"
25 #include "Core/felisce_error.hpp"
26 #include "PETScInterface/petscVector.hpp"
27 #include "Core/felisceParam.hpp"
28 #include "Core/filesystemUtil.hpp"
29
30 namespace felisce {
31
32 //=======================
33 // CONSTRUCTOR/DESTRUCTOR
34 //=======================
35
36 2269 inline PetscMatrix::PetscMatrix()
37 {
38 2269 m_self = nullptr;
39 2269 }
40
41 /***********************************************************************************/
42 /***********************************************************************************/
43
44 60 inline PetscMatrix::PetscMatrix(const PetscMatrix& b)
45 {
46
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
60 if ( b.isNotNull() ) {
47 duplicateFrom(b);
48 copyFrom(b);
49 }
50 60 }
51
52 /***********************************************************************************/
53 /***********************************************************************************/
54
55 inline PetscMatrix& PetscMatrix::operator=(const PetscMatrix& b)
56 {
57 this->destroy();
58 PetscObjectReference((PetscObject)b.m_self);
59 m_self = b.m_self;
60 return *this;
61 }
62
63 /***********************************************************************************/
64 /***********************************************************************************/
65
66 2329 inline PetscMatrix::~PetscMatrix()
67 {
68 // In PETSc, Mat are handled like shared pointers.
69 2329 this->destroy();
70 2329 }
71
72 //===================
73 // CREATION FUNCTIONS
74 //===================
75
76 4 inline PetscErrorCode PetscMatrix::createDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscScalar *data)
77 {
78 4 const PetscErrorCode code = MatCreateDense(comm,m,n,M,N,data,&m_self);
79
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 CHKERRQ(code);
80 4 return code;
81 }
82
83 /***********************************************************************************/
84 /***********************************************************************************/
85
86 inline PetscErrorCode PetscMatrix::createSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data)
87 {
88 const PetscErrorCode code = MatCreateSeqDense(comm,m,n,data,&m_self);
89 CHKERRQ(code);
90 return code;
91 }
92
93 /***********************************************************************************/
94 /***********************************************************************************/
95
96 inline PetscErrorCode PetscMatrix::createMPIAdj(MPI_Comm comm,PetscInt m,PetscInt N,PetscInt *i,PetscInt *j,PetscInt *values)
97 {
98 const PetscErrorCode code = MatCreateMPIAdj(comm,m,N,i,j,values,&m_self);
99 CHKERRQ(code);
100 return code;
101 }
102
103 /***********************************************************************************/
104 /***********************************************************************************/
105
106 39 inline PetscErrorCode PetscMatrix::createSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[])
107 {
108 39 const PetscErrorCode code = MatCreateSeqAIJ(comm,m,n,nz,nnz,&m_self);
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 CHKERRQ(code);
110 39 return code;
111 }
112
113 /***********************************************************************************/
114 /***********************************************************************************/
115
116 1006 inline PetscErrorCode PetscMatrix::createAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt d_nz,const PetscInt d_nnz[],PetscInt o_nz,const PetscInt o_nnz[])
117 {
118 1006 const PetscErrorCode code = MatCreateAIJ(comm,m,n,M,N,d_nz,d_nnz,o_nz,o_nnz,&m_self);
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1006 times.
1006 CHKERRQ(code);
120 1006 return code;
121 }
122
123 //======================
124 // DESTRUCTION FUNCTIONS
125 //======================
126
127 2369 inline PetscErrorCode PetscMatrix::destroy()
128 {
129 2369 const PetscErrorCode code = MatDestroy(&m_self);
130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2369 times.
2369 CHKERRQ(code);
131 2369 return code;
132 }
133
134 //===============
135 // COPY FUNCTIONS
136 //===============
137
138 1220 inline PetscErrorCode PetscMatrix::copyFrom(const PetscMatrix& mat,MatStructure str)
139 {
140 1220 const PetscErrorCode code = MatCopy(mat.m_self,m_self,str);
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1220 times.
1220 CHKERRQ(code);
142 1220 return code;
143 }
144
145 /***********************************************************************************/
146 /***********************************************************************************/
147
148 46 inline PetscErrorCode PetscMatrix::duplicateFrom(const PetscMatrix& mat,MatDuplicateOption op)
149 {
150 46 const PetscErrorCode code = MatDuplicate(mat.m_self,op,&m_self);
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
46 CHKERRQ(code);
152 46 return code;
153 }
154
155 //=======================
156 // MODIFICATION FUNCTIONS
157 //=======================
158
159 96461 inline PetscErrorCode PetscMatrix::assembly(MatAssemblyType type)
160 {
161 96461 PetscErrorCode code = MatAssemblyBegin(m_self,type);
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96461 times.
96461 CHKERRQ(code);
163 96461 code = MatAssemblyEnd(m_self,type);
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96461 times.
96461 CHKERRQ(code);
165 96461 return code;
166 }
167
168 /***********************************************************************************/
169 /***********************************************************************************/
170
171 inline PetscErrorCode PetscMatrix::diagonalSet(const PetscVector& diag,InsertMode is)
172 {
173 const PetscErrorCode code = MatDiagonalSet(m_self,diag.m_self,is);
174 CHKERRQ(code);
175 return code;
176 }
177
178 /***********************************************************************************/
179 /***********************************************************************************/
180
181 1006 inline PetscErrorCode PetscMatrix::mpiAIJSetPreallocationCSR(const PetscInt i[],const PetscInt j[],const PetscScalar v[])
182 {
183 1006 const PetscErrorCode code = MatMPIAIJSetPreallocationCSR(m_self,i,j,v);
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1006 times.
1006 CHKERRQ(code);
185 1006 return code;
186 }
187
188 /***********************************************************************************/
189 /***********************************************************************************/
190
191 inline PetscErrorCode PetscMatrix::seqAIJSetPreallocationCSR(const PetscInt i[],const PetscInt j[],const PetscScalar v[])
192 {
193 const PetscErrorCode code = MatSeqAIJSetPreallocationCSR(m_self,i,j,v);
194 CHKERRQ(code);
195 return code;
196 }
197
198 /***********************************************************************************/
199 /***********************************************************************************/
200
201 1049 inline PetscErrorCode PetscMatrix::setFromOptions()
202 {
203 1049 const PetscErrorCode code = MatSetFromOptions(m_self);
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1049 times.
1049 CHKERRQ(code);
205 1049 return code;
206 }
207
208 /***********************************************************************************/
209 /***********************************************************************************/
210
211 1165 inline PetscErrorCode PetscMatrix::setOption(MatOption op,PetscBool flg)
212 {
213 1165 const PetscErrorCode code = MatSetOption(m_self,op,flg);
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1165 times.
1165 CHKERRQ(code);
215 1165 return code;
216 }
217
218 /***********************************************************************************/
219 /***********************************************************************************/
220
221 inline PetscErrorCode PetscMatrix::setValue(PetscInt row,PetscInt col,PetscScalar value,InsertMode mode)
222 {
223 const PetscErrorCode code = MatSetValue(m_self,row,col,value,mode);
224 CHKERRQ(code);
225 return code;
226 }
227
228 /***********************************************************************************/
229 /***********************************************************************************/
230
231 36941193 inline PetscErrorCode PetscMatrix::setValues(PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
232 {
233 36941193 const PetscErrorCode code = MatSetValues(m_self,m,idxm,n,idxn,v,addv);
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36941193 times.
36941193 CHKERRQ(code);
235 36941193 return code;
236 }
237
238 /***********************************************************************************/
239 /***********************************************************************************/
240
241 48398 inline PetscErrorCode PetscMatrix::zeroEntries()
242 {
243 48398 const PetscErrorCode code = MatZeroEntries(m_self);
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48398 times.
48398 CHKERRQ(code);
245 48398 return code;
246 }
247
248 /***********************************************************************************/
249 /***********************************************************************************/
250
251 27897 inline PetscErrorCode PetscMatrix::zeroRows(PetscInt numRows,const PetscInt rows[], const PetscScalar diag)
252 {
253 27897 const PetscErrorCode code = MatZeroRows(m_self,numRows,rows,diag,nullptr,nullptr);
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27897 times.
27897 CHKERRQ(code);
255 27897 return code;
256 }
257
258 /***********************************************************************************/
259 /***********************************************************************************/
260
261 inline PetscErrorCode PetscMatrix::zeroRowsColumns(PetscInt numRows,const PetscInt rows[],const PetscScalar diag)
262 {
263 const PetscErrorCode code = MatZeroRowsColumns(m_self,numRows,rows,diag,nullptr,nullptr);
264 CHKERRQ(code);
265 return code;
266 }
267
268 //=================
269 // ACCESS FUNCTIONS
270 //=================
271
272 inline PetscErrorCode PetscMatrix::getSize(PetscInt *m,PetscInt *n) const
273 {
274 const PetscErrorCode code = MatGetSize(m_self,m,n);
275 CHKERRQ(code);
276 return code;
277 }
278
279 /***********************************************************************************/
280 /***********************************************************************************/
281
282 inline PetscErrorCode PetscMatrix::getVecs(Vec */*FELISCE_PETSC_NULLPTR*/, PetscVector& left) const
283 {
284 const PetscErrorCode code = MatCreateVecs(m_self, FELISCE_PETSC_NULLPTR, &left.m_self);
285 CHKERRQ(code);
286 return code;
287 }
288
289 /***********************************************************************************/
290 /***********************************************************************************/
291
292 inline PetscErrorCode PetscMatrix::getVecs(PetscVector& right, Vec */*FELISCE_PETSC_NULLPTR*/) const
293 {
294 const PetscErrorCode code = MatCreateVecs(m_self,&right.m_self, FELISCE_PETSC_NULLPTR);
295 CHKERRQ(code);
296 return code;
297 }
298
299 /***********************************************************************************/
300 /***********************************************************************************/
301
302 27 inline PetscErrorCode PetscMatrix::getVecs(PetscVector& right,PetscVector& left) const
303 {
304 27 const PetscErrorCode code = MatCreateVecs(m_self,&right.m_self,&left.m_self);
305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 CHKERRQ(code);
306 27 return code;
307 }
308
309 //==================
310 // BOOLEAN FUNCTIONS
311 //==================
312
313 inline bool PetscMatrix::isNull()
314 {
315 return m_self == nullptr;
316 }
317
318 /***********************************************************************************/
319 /***********************************************************************************/
320
321 inline bool PetscMatrix::isNull() const
322 {
323 return m_self == nullptr;
324 }
325
326 /***********************************************************************************/
327 /***********************************************************************************/
328
329 inline bool PetscMatrix::isNotNull()
330 {
331 return m_self != nullptr;
332 }
333
334 /***********************************************************************************/
335 /***********************************************************************************/
336
337 60 inline bool PetscMatrix::isNotNull() const
338 {
339 60 return m_self != nullptr;
340 }
341
342 //=======================
343 // MATHEMATICAL FUNCTIONS
344 //=======================
345
346 23094 inline PetscErrorCode PetscMatrix::axpy(PetscScalar a,PetscMatrix& X,MatStructure str)
347 {
348 23094 const PetscErrorCode code = MatAXPY(m_self,a,X.m_self,str);
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23094 times.
23094 CHKERRQ(code);
350 23094 return code;
351 }
352
353 /***********************************************************************************/
354 /***********************************************************************************/
355
356 inline PetscErrorCode PetscMatrix::luFactor(IS row,IS col,const MatFactorInfo *info)
357 {
358 const PetscErrorCode code = MatLUFactor(m_self,row,col,info);
359 CHKERRQ(code);
360 return code;
361 }
362
363 /***********************************************************************************/
364 /***********************************************************************************/
365
366 inline PetscErrorCode PetscMatrix::diagonalScale(const PetscVector& leftDiagonalMatrix, const PetscVector& rightDiagonalMatrix)
367 {
368 const PetscErrorCode code = MatDiagonalScale(m_self,leftDiagonalMatrix.m_self,rightDiagonalMatrix.m_self);
369 CHKERRQ(code);
370 return code;
371 }
372
373 /***********************************************************************************/
374 /***********************************************************************************/
375
376 2168 inline PetscErrorCode PetscMatrix::scale(PetscScalar scalar)
377 {
378 2168 const PetscErrorCode code = MatScale(m_self,scalar);
379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2168 times.
2168 CHKERRQ(code);
380 2168 return code;
381 }
382
383 /***********************************************************************************/
384 /***********************************************************************************/
385
386 28481 inline PetscErrorCode PetscMatrix::setUnfactored()
387 {
388 28481 const PetscErrorCode code = MatSetUnfactored(m_self);
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28481 times.
28481 CHKERRQ(code);
390 28481 return code;
391 }
392
393 /***********************************************************************************/
394 /***********************************************************************************/
395
396 inline PetscErrorCode PetscMatrix::shift(const PetscScalar a)
397 {
398 const PetscErrorCode code = MatShift(m_self,a);
399 CHKERRQ(code);
400 return code;
401 }
402
403 /***********************************************************************************/
404 /***********************************************************************************/
405
406 inline PetscErrorCode PetscMatrix::norm(NormType type, PetscReal* val) const
407 {
408 const PetscErrorCode code = MatNorm(m_self,type,val);
409 CHKERRQ(code);
410 return code;
411 }
412
413 //=================
414 // OUTPUT FUNCTIONS
415 //=================
416
417 inline PetscErrorCode PetscMatrix::view(PetscViewer viewer) const
418 {
419 const PetscErrorCode code = MatView(m_self,viewer);
420 CHKERRQ(code);
421 return code;
422 }
423
424 /***********************************************************************************/
425 /***********************************************************************************/
426
427 // std::ostream& operator<<(std::ostream& out, PetscMatrix& mm){
428 //
429 // Mat m = mm.toPetsc();
430 //
431 // PetscInt nCols, nRows;
432 //
433 // MatGetSize(m, &nRows, &nCols);
434 // const PetscScalar *row;
435 //
436 // out << "[\n";
437 // for (PetscInt i=0; i<nRows; i++){
438 // MatGetRow(m, i, NULL, NULL, &row);
439 // for (PetscInt j=0; j<nCols; j++)
440 // out << row[j] << " ";
441 // out << std::endl;
442 // }
443 // out << " ]\n";
444 //
445 // return out;
446 // }
447
448 /***********************************************************************************/
449 /***********************************************************************************/
450
451 // TODO: https://www.mcs.anl.gov/petsc/petsc-3.12/docs/manualpages/Viewer/PetscViewerFormat.html
452
453 inline PetscErrorCode PetscMatrix::saveInBinaryFormat(MPI_Comm comm, const std::string filename, const std::string folder) const
454 {
455 std::string foldername = folder + "/";
456 // TODO: Replace std::filesystem
457 std::string command = "mkdir -p " + foldername;
458 int ierr=system(command.c_str());
459 if (ierr>0)
460 FEL_ERROR(std::string("Impossible to save "+filename+"matrix.\nProblem in creating folder: "+foldername+"\n").c_str());
461 std::stringstream filenameBin;
462 filenameBin<< foldername << filename << ".mb";
463 PetscViewer binaryViewer;
464 PetscErrorCode code;
465 code = PetscViewerBinaryOpen(comm, filenameBin.str().c_str(), FILE_MODE_WRITE, &binaryViewer);
466 CHKERRQ(code);
467 code = PetscViewerPushFormat(binaryViewer,PETSC_VIEWER_NATIVE);
468 CHKERRQ(code);
469 code = this->view(binaryViewer);
470 CHKERRQ(code);
471 code = PetscViewerDestroy(&binaryViewer);
472 CHKERRQ(code);
473 if ( FelisceParam::verbose() > 1 ) {
474 std::stringstream msg;
475 msg<<"Petsc Matrix saved in "<<filename<<".mb in folder "<<foldername<<std::endl;
476 PetscPrintf(comm, "%s",msg.str().c_str());
477 }
478 return code;
479 }
480
481 /***********************************************************************************/
482 /***********************************************************************************/
483
484 inline PetscErrorCode PetscMatrix::saveInMatlabFormat(MPI_Comm comm, const std::string filename, const std::string folder) const
485 {
486 std::stringstream filenameMatlab;
487 filenameMatlab<< folder << filename << ".m";
488 PetscViewer matlabViewer;
489 PetscErrorCode code;
490 code = PetscViewerCreate(comm,&matlabViewer);
491 CHKERRQ(code);
492 code = PetscViewerASCIIOpen(comm,filenameMatlab.str().c_str(),&matlabViewer);
493 CHKERRQ(code);
494 code = PetscViewerPushFormat(matlabViewer,PETSC_VIEWER_ASCII_MATLAB);
495 CHKERRQ(code);
496 code = this->view(matlabViewer);
497 CHKERRQ(code);
498 code = PetscViewerDestroy(&matlabViewer);
499 CHKERRQ(code);
500 if ( FelisceParam::verbose() > 1 ) {
501 std::stringstream msg;
502 msg<<"Petsc Matrix saved in "<<filename<<".m in folder "<<folder<<std::endl;
503 PetscPrintf(comm,"%s",msg.str().c_str());
504 }
505 return code;
506 }
507
508 //================
509 // INPUT FUNCTIONS
510 //================
511
512 4 inline PetscErrorCode PetscMatrix::load(PetscViewer viewer)
513 {
514 4 const PetscErrorCode code = MatLoad(m_self,viewer);
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 CHKERRQ(code);
516 4 return code;
517 }
518
519 /***********************************************************************************/
520 /***********************************************************************************/
521
522 4 inline PetscErrorCode PetscMatrix::loadFromBinaryFormat(MPI_Comm comm, const std::string filename, const std::string folder) {
523
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::stringstream filenameBin;
524
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
4 filenameBin<< folder << filename << ".mb";
525
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
4 if ( ! filesystemUtil::fileExists( filenameBin.str() ) )
526 FEL_ERROR("Requested file "+ filenameBin.str()+" does not exists");
527 PetscViewer binaryViewer;
528 PetscErrorCode code;
529
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 code = PetscViewerBinaryOpen(comm, filenameBin.str().c_str(), FILE_MODE_READ, &binaryViewer);
530
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 CHKERRQ(code);
531
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 code = PetscViewerPushFormat(binaryViewer,PETSC_VIEWER_NATIVE);
532
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 CHKERRQ(code);
533
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 code = this->load(binaryViewer);
534
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 CHKERRQ(code);
535
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 code = PetscViewerDestroy(&binaryViewer);
536
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 CHKERRQ(code);
537
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
4 if ( FelisceParam::verbose() > 1 ) {
538 std::stringstream msg;
539 msg<<"Petsc Matrix loaded from "<<filename<<".mb in folder "<<folder<<std::endl;
540 PetscPrintf(comm,"%s",msg.str().c_str());
541 }
542 4 return code;
543 4 }
544
545 //===============
546 // TEST FUNCTIONS
547 //===============
548
549 inline bool PetscMatrix::isTransposeOf(PetscMatrix& A, double tol)
550 {
551 PetscBool isTranspose;
552 const PetscErrorCode code = MatIsTranspose(m_self, A.m_self, tol, &isTranspose);
553 CHKERRQ(code);
554 return isTranspose;
555 }
556
557 //=================
558 // TO BE DEPRECATED
559 //=================
560
561 4 inline const Mat& PetscMatrix::toPetsc() const
562 {
563 4 return m_self;
564 }
565
566 /***********************************************************************************/
567 /***********************************************************************************/
568
569 14140 inline Mat& PetscMatrix::toPetsc()
570 {
571 14140 return m_self;
572 }
573
574 }
575