Rheolef  7.2
an efficient C++ finite element environment
 
Loading...
Searching...
No Matches
solver_option.cc
Go to the documentation of this file.
1
21// direct solver interface
22//
23#include "rheolef/solver_option.h"
24#include <unordered_set>
25namespace rheolef {
26
27// -----------------------------------------------------------------------------
28// default preferred direct solver library manager
29// -----------------------------------------------------------------------------
30// rule:
31// 1) when distributed: only mumps
32// 2) otherwise:
33// 2a) when symmetry: eigen, mumps, cholmod(sdp)
34// 2b) when no-symmetry: umfpack, mumps, eigen
35// TODO: check stokes with eigen for indefinite sym pbs !
36// --------------------------------------------------------------------------
37// mumps note: for best performance in both distributed and sequential modes
38// mumps requires to be compiled with a good numbering library (scotch or metis)
39// such as within the libdmumps_scotch debian package
40std::string
41solver_option::_default_preferred_library (size_t dis_ext_nnz, bool is_sym, bool is_dp)
42{
43 // for a given matrix a:
44 // dis_ext_nnz = number of non-block diagonal coefs on distributed matrix
45 // = 0 in sequential mode or block-diagonal matrix
46 // sequential libraries are not able to manage dis_ext_nnz != 0
47 if (dis_ext_nnz != 0) {
48 return "mumps"; // yet, the only supported distributed direct solver
49 }
50 // here, we can use some sequential libs, depending on the configuration:
51#if defined(_RHEOLEF_HAVE_MUMPS)
52#if defined(_RHEOLEF_HAVE_MUMPS_WITH_METIS) || \
53 defined(_RHEOLEF_HAVE_MUMPS_WITH_PARMETIS) || \
54 defined(_RHEOLEF_HAVE_MUMPS_WITH_SCOTCH) || \
55 defined(_RHEOLEF_HAVE_MUMPS_WITH_PTSCOTCH)
56 constexpr bool have_mumps_scotch = true,
57 have_mumps_no_scotch = false;
58#else
59 constexpr bool have_mumps_scotch = false,
60 have_mumps_no_scotch = true;
61#endif
62#else
63 constexpr bool have_mumps_scotch = false,
64 have_mumps_no_scotch = false;
65#endif
66 constexpr bool have_mumps = have_mumps_scotch || have_mumps_no_scotch;
67#ifdef _RHEOLEF_HAVE_CHOLMOD
68 constexpr bool have_cholmod = true;
69#else
70 constexpr bool have_cholmod = false;
71#endif
72#ifdef _RHEOLEF_HAVE_UMFPACK
73 constexpr bool have_umfpack = true;
74#else
75 constexpr bool have_umfpack = false;
76#endif
77
78 // the best choice depends upon the symmetry of the matrix
79 std::string default_preferred_library;
80 if (is_sym) {
81 // if sdp, eigen is faster
82 // if not sdp, mumps is better when compiled with scotch
83 if (is_dp) default_preferred_library += " eigen";
84 if (have_mumps) default_preferred_library += " mumps";
85 if (!is_dp) default_preferred_library += " eigen";
86 if (have_cholmod && is_dp) default_preferred_library += " suitesparse";
87 if (!is_dp) default_preferred_library += " suitesparse";
88 } else {
89 // umfpack is best than mumps and eigen
90 if (have_umfpack) default_preferred_library += " suitesparse";
91 if (have_mumps) default_preferred_library += " mumps";
92 default_preferred_library += " eigen";
93 }
95}
96static
97std::string
98strip_white (std::string x)
99{
100 using namespace std;
101 size_t first = 0;
102 while (first < x.length() && (x[first] == ' ' || x[first] == ',')) ++first;
103 return x.substr(first);
104}
105static
106void
107split_options (std::string o, std::vector<std::string>& o_table)
108{
109 using namespace std;
110 size_t first = 0;
111 while (first < o.length()) {
112 while (first < o.length() && (o[first] == ' ' || o[first] == ',')) ++first;
113 size_t last = first;
114 while ( last < o.length() && !(o[last] == ' ' || o[last] == ',')) ++last;
115 if (last - first != 0) {
116 string x = strip_white (string(o, first, last-first));
117 o_table.push_back (x);
118 }
119 first = last;
120 }
121}
122static
123void
124split_options (std::string o, std::unordered_set<std::string>& o_table)
125{
126 using namespace std;
127 size_t first = 0;
128 while (first < o.length()) {
129 while (first < o.length() && (o[first] == ' ' || o[first] == ',')) ++first;
130 size_t last = first;
131 while ( last < o.length() && !(o[last] == ' ' || o[last] == ',')) ++last;
132 if (last - first != 0) {
133 string x = o.substr (first, last-first);
134 o_table.insert (x);
135 }
136 first = last;
137 }
138}
139static
140std::string
141try_choice (
142 const std::vector<std::string>& preferred,
143 const std::unordered_set<std::string>& available)
144{
145 using namespace std;
146 string choice;
147 for (size_t i = 0; i < preferred.size(); ++i) {
148 string x = strip_white(preferred[i]);
149 if (available.find (x) != available.end()) {
150 choice = x;
151 break;
152 }
153 }
154 return choice;
155}
156std::string
157solver_option::_used_library (std::string init_preferred_library, size_t dis_ext_nnz, bool is_sym, bool is_dp)
158{
159 using namespace std;
160 string available_library = _default_preferred_library (dis_ext_nnz, is_sym, is_dp);
161 string preferred_library = (init_preferred_library != "") ? init_preferred_library : available_library;
162 vector<string> preferred;
163 unordered_set<string> available;
164 split_options (available_library, available);
165 split_options (preferred_library, preferred);
166 string choice = try_choice (preferred, available);
167 if (choice == "") {
168 if (dis_ext_nnz == 0) { // when dis_ext_nnz != 0: distributed and only mumps is available
169 dis_warning_macro ("preferred_library=\""<<init_preferred_library<<"\" not available, use default=\""<<available_library<<"\"");
170 }
171 vector<string> available_as_vector;
172 split_options (available_library, available_as_vector);
173 choice = try_choice (available_as_vector, available); // now, will get the fist available
174 }
175 return choice;
176}
177
178} // namespace rheolef
static std::string default_preferred_library(const csr< T, M > &a)
std::string preferred_library
static std::string _default_preferred_library(size_t dis_ext_nnz, bool is_sym, bool is_dp)
static std::string _used_library(std::string init_preferred_library, size_t dis_ext_nnz, bool is_sym, bool is_dp)
#define dis_warning_macro(message)
Definition dis_macros.h:66
This file is part of Rheolef.
STL namespace.