OOFEM 3.0
Loading...
Searching...
No Matches
mklpardisosolver.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "mklpardisosolver.h"
36
37#include "compcol.h"
38#include "symcompcol.h"
39#include "engngm.h"
40#include "floatarray.h"
41#include "verbose.h"
42#include "timer.h"
43#include "error.h"
44#include "classfactory.h"
45#include "convergedreason.h"
46
47#include <mkl.h>
48
49namespace oofem {
51
52MKLPardisoSolver :: MKLPardisoSolver(Domain *d, EngngModel *m) : SparseLinearSystemNM(d, m) { }
53
54MKLPardisoSolver :: ~MKLPardisoSolver() { }
55
56ConvergedReason MKLPardisoSolver :: solve(SparseMtrx &A, FloatArray &b, FloatArray &x)
57{
58 int neqs = b.giveSize();
59 x.resize(neqs);
60
61 int mtype = -2; // Real symmetric positive definite matrix
62 CompCol *mat = dynamic_cast< SymCompCol * >(&A);
63 if ( !mat ) {
64 mtype = 11; // Real unsymmetric matrix
65 mat = dynamic_cast< CompCol * >(&A);
66 if ( !mat ) {
67 OOFEM_ERROR("CompCol matrix needed for Pardiso solver");
68 }
69 }
70
71 // Pardiso's CGS-implementation can't handle b = 0.
72 if ( b.computeSquaredNorm() == 0 ) {
73 return CR_CONVERGED;
74 }
75
76 const int *ia = mat->giveColPtr().givePointer();
77 const int *ja = mat->giveRowIndex().givePointer();
78 const double *a = mat->giveValues().givePointer();
79
80 Timer timer;
81 timer.startTimer();
82
83 // RHS and solution vectors.
84 int nrhs = 1; // Number of right hand sides.
85
86 // Internal solver memory pointer pt,
87 // 32-bit: int pt[64]; 64-bit: long int pt[64]
88 // or void *pt[64] should be OK on both architectures
89 void *pt[64];
90
91 // Pardiso control parameters.
92 IntArray iparm(64);
93 int maxfct, mnum, phase, error, msglvl;
94
95 double ddum = 0.; // Double dummy
96 int idum = 0; // Integer dummy.
97
98 // Setup Pardiso control parameters
99 /* -------------------------------------------------------------------- */
100 error = 0;
101 pardisoinit(pt, &mtype, iparm.givePointer()); // INITIALIZATION!
102 // Settings are here:
103 // https://software.intel.com/en-us/articles/pardiso-parameter-table#table2
104
105 iparm[0] = 1;
107 //iparm[4-1] = 32; // 10*L + K. K = 1 implies CGS (instead of LU), K = 2 implies CG. L specifies exponent tolerance.
108 iparm[8-1] = 2; /* Max numbers of iterative refinement steps. */
109 iparm[12-1] = 2; // Transpose (we have a CSC matrix representation here instead of the expected CSR)
110 iparm[35-1] = 1; // 1 implies 0-indexing
111 //iparm[27-1] = 1; // Checks the matrix (only in MKL)
113
114 maxfct = 1; // Maximum number of numerical factorizations.
115 mnum = 1; // Which factorization to use.
116 msglvl = 0; // Print statistical information
117 error = 0; // Initialize error flag
118
119 /* -------------------------------------------------------------------- */
120 /* .. Reordering and Symbolic Factorization. This step also allocates */
121 /* all memory that is necessary for the factorization. */
122 /* -------------------------------------------------------------------- */
123 phase = 11;
124
125 pardiso(pt, &maxfct, &mnum, &mtype, &phase, &neqs,
126 (void*)a, (int*)ia, (int*)ja,
127 &idum, &nrhs, iparm.givePointer(), &msglvl, &ddum, &ddum, &error); // FACTORIZATION!
128
129 if ( error != 0 ) {
130 OOFEM_WARNING("Error during symbolic factorization: %d", error);
131 return CR_FAILED;
132 }
133 OOFEM_LOG_DEBUG("Reordering completed: %d nonzero factors, %d factorization MFLOPS\n", iparm[17-1], iparm[18-1]);
134
135 /* -------------------------------------------------------------------- */
136 /* .. Numerical factorization. */
137 /* -------------------------------------------------------------------- */
138 phase = 22;
139
140 pardiso(pt, &maxfct, &mnum, &mtype, &phase, &neqs,
141 (void*)a, (int*)ia, (int*)ja,
142 &idum, &nrhs, iparm.givePointer(), &msglvl, &ddum, &ddum, &error);
143
144 if ( error != 0 ) {
145 OOFEM_WARNING("ERROR during numerical factorization: %d", error);
146 return CR_FAILED;
147 }
148 OOFEM_LOG_DEBUG("Factorization completed ...\n");
149
150 /* -------------------------------------------------------------------- */
151 /* .. Back substitution and iterative refinement. */
152 /* -------------------------------------------------------------------- */
153 phase = 33;
154
155 pardiso(pt, &maxfct, &mnum, &mtype, &phase, &neqs,
156 (void*)a, (int*)ia, (int*)ja,
157 &idum, &nrhs, iparm.givePointer(), &msglvl, (void*)b.givePointer(), (void*)x.givePointer(), &error);
158
159 printf("iparm(20) = %d\n", iparm[20]);
160 if ( error != 0 ) {
161 OOFEM_WARNING("ERROR during solution: %d, iparm(20) = %d", error, iparm[20-1]);
162 return CR_FAILED;
163 }
164
165 OOFEM_LOG_DEBUG("Solve completed ... \n");
166
167 /* -------------------------------------------------------------------- */
168 /* .. Termination and release of memory. */
169 /* -------------------------------------------------------------------- */
170 phase = -1; /* Release internal memory. */
171
172 pardiso(pt, &maxfct, &mnum, &mtype, &phase,
173 &neqs, &ddum, &idum, &idum, &idum, &nrhs,
174 iparm.givePointer(), &msglvl, &ddum, &ddum, &error);
175
176 timer.stopTimer();
177 OOFEM_LOG_INFO( "MKLPardisoSolver: User time consumed by solution: %.2fs\n", timer.getUtime() );
178
179 return CR_CONVERGED;
180}
181
182#if 0
184ConvergedReason MKLPardisoSolver :: solve(SparseMtrx &A, FloatMatrix &B, FloatMatrix &X)
185{
187}
188#endif
189} // end namespace oofem
#define REGISTER_SparseLinSolver(class, type)
FloatArray & giveValues()
Definition compcol.h:126
IntArray & giveColPtr()
Definition compcol.h:128
IntArray & giveRowIndex()
Definition compcol.h:127
void resize(Index s)
Definition floatarray.C:94
double computeSquaredNorm() const
Definition floatarray.C:867
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
const double * givePointer() const
Definition floatarray.h:506
const int * givePointer() const
Definition intarray.h:345
SparseLinearSystemNM(Domain *d, EngngModel *m)
Constructor.
double getUtime()
Returns total user time elapsed in seconds.
Definition timer.C:105
void startTimer()
Definition timer.C:69
void stopTimer()
Definition timer.C:77
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
void pardisoinit(void *, int *, int *, int *, double *, int *)
void pardiso(void *, int *, int *, int *, int *, int *, double *, int *, int *, int *, int *, int *, int *, double *, double *, int *, double *)

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011