FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
superlu.cpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
7
8#if defined(FEAT_HAVE_SUPERLU_DIST) && defined(FEAT_HAVE_MPI)
9
10FEAT_DISABLE_WARNINGS
11#define VTUNE 0
12#include <superlu_ddefs.h>
13FEAT_RESTORE_WARNINGS
14
15#include <vector>
16
17namespace FEAT
18{
19 namespace Solver
20 {
21 namespace SuperLU_Aux
22 {
24 class Core
25 {
26 public:
28 MPI_Comm _comm;
30 gridinfo_t slu_grid;
32 superlu_dist_options_t slu_opts;
34 SuperLUStat_t slu_stats;
36 SuperMatrix slu_matrix;
38 NRformat_loc slu_matrix_store;
40 dScalePermstruct_t slu_scale_perm;
42 dLUstruct_t slu_lu_struct;
44 dSOLVEstruct_t slu_solve_struct;
46 int slu_info;
47
50 std::vector<int_t> slu_row_ptr, slu_col_idx, slu_col_idx2;
52 std::vector<double> a_val;
54 std::vector<double> v_berr;
55
58 bool was_factorized;
59
60 public:
61 template<typename IT_>
62 explicit Core(const void* comm, Index num_global_dofs, Index my_dof_offset, Index num_owned_dofs,
63 const IT_* row_ptr, const IT_* col_idx) :
64 _comm(*reinterpret_cast<const MPI_Comm*>(comm)),
65 slu_info(0),
66 was_factorized(false)
67 {
68 // first of all, memclear all SuperLU structures just to be safe
69 memset(&slu_grid, 0, sizeof(gridinfo_t));
70 memset(&slu_opts, 0, sizeof(superlu_dist_options_t));
71 memset(&slu_stats, 0, sizeof(SuperLUStat_t));
72 memset(&slu_matrix, 0, sizeof(SuperMatrix));
73 memset(&slu_matrix_store, 0, sizeof(NRformat_loc));
74 memset(&slu_scale_perm, 0, sizeof(dScalePermstruct_t));
75 memset(&slu_lu_struct, 0, sizeof(dLUstruct_t));
76 memset(&slu_solve_struct, 0, sizeof(dSOLVEstruct_t));
77
78 // set up grid
79 int ranks(0);
80 MPI_Comm_size(_comm, &ranks);
81 superlu_gridinit(_comm, ranks, 1, &slu_grid);
82
83 // allocate vector for 'berr'
84 v_berr.resize(num_owned_dofs);
85
86 // copy pattern
87 const Index num_nze(row_ptr[num_owned_dofs]);
88 slu_row_ptr.resize(num_owned_dofs+1u);
89 for(Index i(0); i <= num_owned_dofs; ++i)
90 slu_row_ptr[i] = int_t(row_ptr[i]);
91 slu_col_idx.resize(num_nze);
92 for(Index i(0); i < num_nze; ++i)
93 slu_col_idx[i] = int_t(col_idx[i]);
94 slu_col_idx2 = slu_col_idx;
95
96 // allocate matrix value array
97 a_val.resize(num_nze);
98
99 // setup SuperLU matrix
100 slu_matrix.Stype = SLU_NR_loc; // CSR, local
101 slu_matrix.Dtype = SLU_D; // double
102 slu_matrix.Mtype = SLU_GE; // generic matrix
103 slu_matrix.nrow = int_t(num_global_dofs);
104 slu_matrix.ncol = int_t(num_global_dofs); // always square
105 slu_matrix.Store = &slu_matrix_store;
106
107 // setup SuperLU matrix storage
108 slu_matrix_store.nnz_loc = int_t(num_nze);
109 slu_matrix_store.m_loc = int_t(num_owned_dofs);
110 slu_matrix_store.fst_row = int_t(my_dof_offset);
111 slu_matrix_store.nzval = a_val.data();
112 slu_matrix_store.rowptr = slu_row_ptr.data();
113 slu_matrix_store.colind = slu_col_idx.data();
114
115 // set up default options
116 set_default_options_dist(&slu_opts);
117
118 // don't print statistics to cout
119 slu_opts.PrintStat = NO;
120
121 // replace tiny pivots
122 slu_opts.ReplaceTinyPivot = YES;
123
124 // initialize scale perm structure
125 dScalePermstructInit(int_t(num_global_dofs), int_t(num_global_dofs), &slu_scale_perm);
126
127 // initialize LU structure
128 dLUstructInit(int_t(num_global_dofs), &slu_lu_struct);
129
130 // initialize the statistics
131 PStatInit(&slu_stats);
132 }
133
134 ~Core()
135 {
136 PStatFree(&slu_stats);
137 dDestroy_LU(slu_matrix.nrow, &slu_grid, &slu_lu_struct);
138 dLUstructFree(&slu_lu_struct);
139 dScalePermstructFree(&slu_scale_perm);
140 dSolveFinalize(&slu_opts, &slu_solve_struct);
141 superlu_gridexit(&slu_grid);
142 }
143
144 int init_numeric(const double* vals)
145 {
146 // copy matrix values
147 for(std::size_t i(0); i < a_val.size(); ++i)
148 a_val[i] = vals[i];
149
150 // reset column-index array because it might have been
151 // overwritten by the previous factorization call
152 slu_col_idx = slu_col_idx2;
153
154 // have we already factorized before?
155 slu_opts.Fact = (was_factorized ? SamePattern : DOFACT);
156
157 // call the solver routine to factorize the matrix
158 pdgssvx(
159 &slu_opts,
160 &slu_matrix,
161 &slu_scale_perm,
162 nullptr,
163 int(slu_matrix_store.m_loc),
164 0,
165 &slu_grid,
166 &slu_lu_struct,
167 &slu_solve_struct,
168 v_berr.data(),
169 &slu_stats,
170 &slu_info);
171
172 // factorization successful?
173
174 if(slu_info == 0)
175 {
176 // okay, remember that we have factorized
177 was_factorized = true;
178 }
179
180 // okay
181 return slu_info;
182 }
183
184 int solve(double* x)
185 {
186 // matrix was already factorized in set_matrix_values() call
187 slu_opts.Fact = FACTORED;
188
189 // call the solver routine
190 pdgssvx(
191 &slu_opts,
192 &slu_matrix,
193 &slu_scale_perm,
194 x,
195 int(slu_matrix_store.m_loc),
196 1,
197 &slu_grid,
198 &slu_lu_struct,
199 &slu_solve_struct,
200 v_berr.data(),
201 &slu_stats,
202 &slu_info);
203
204 // return the result
205 return slu_info;
206 }
207 }; // class Core
208
209 void* create_core(const void* comm, Index num_global_dofs, Index dof_offset,
210 Index num_owned_dofs, const unsigned int* row_ptr, const unsigned int* col_idx)
211 {
212 return new Core(comm, num_global_dofs, dof_offset, num_owned_dofs, row_ptr, col_idx);
213 }
214
215 void* create_core(const void* comm, Index num_global_dofs, Index dof_offset,
216 Index num_owned_dofs, const unsigned long* row_ptr, const unsigned long* col_idx)
217 {
218 return new Core(comm, num_global_dofs, dof_offset, num_owned_dofs, row_ptr, col_idx);
219 }
220
221 void* create_core(const void* comm, Index num_global_dofs, Index dof_offset,
222 Index num_owned_dofs, const unsigned long long* row_ptr, const unsigned long long* col_idx)
223 {
224 return new Core(comm, num_global_dofs, dof_offset, num_owned_dofs, row_ptr, col_idx);
225 }
226
227 void destroy_core(void* core)
228 {
229 delete reinterpret_cast<Core*>(core);
230 }
231
232 int init_numeric(void* core, const double* vals)
233 {
234 return reinterpret_cast<Core*>(core)->init_numeric(vals);
235 }
236
237 int solve(void* core, double* x)
238 {
239 return reinterpret_cast<Core*>(core)->solve(x);
240 }
241 } // namespace SuperLU_Aux
242 } // namespace Solver
243} // namespace FEAT
244
245#else
246// insert dummy function to suppress linker warnings
247void dummy_superlu_function() {}
248#endif // defined(FEAT_HAVE_SUPERLU_DIST) && defined(FEAT_HAVE_MPI)
FEAT Kernel base header.
Status solve(SolverBase< Vector_ > &solver, Vector_ &vec_sol, const Vector_ &vec_rhs, const Matrix_ &matrix, const Filter_ &filter)
Solve linear system with initial solution guess.
Definition: base.hpp:347
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.