MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
solver_utils.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "solver_utils.hpp"
13
14#ifdef MFEM_USE_MUMPS
15#include "linalg/mumps.hpp"
16#endif
17
18#ifdef MFEM_USE_MKL_CPARDISO
19#include "linalg/cpardiso.hpp"
20#endif
21
22#ifdef MFEM_USE_SUPERLU
23#include "linalg/superlu.hpp"
24#endif
25
26#ifdef MFEM_USE_STRUMPACK
27#include "linalg/strumpack.hpp"
28#endif
29
30
31namespace mfem
32{
33
34static ParallelDirectSolver::Type ParseType(const std::string &name_in)
35{
36 std::string name = name_in;
37 for (char &c : name) { c = std::tolower(c); }
38
39 if (name == "mumps") { return ParallelDirectSolver::Type::MUMPS; }
40 if (name == "superlu") { return ParallelDirectSolver::Type::SUPERLU; }
41 if (name == "strumpack") { return ParallelDirectSolver::Type::STRUMPACK; }
42 if (name == "cpardiso") { return ParallelDirectSolver::Type::CPARDISO; }
43 if (name == "auto") { return ParallelDirectSolver::Type::AUTO; }
44
45 MFEM_ABORT("Unknown ParallelDirectSolver type string: " + name_in);
46 return ParallelDirectSolver::Type::AUTO; // unreachable
47}
48
50 : type(type_), comm(comm_)
51{
52 if (type == Type::AUTO)
53 {
54#ifdef MFEM_USE_MUMPS
55 type = Type::MUMPS;
56#elif defined(MFEM_USE_SUPERLU)
57 type = Type::SUPERLU;
58#elif defined(MFEM_USE_STRUMPACK)
59 type = Type::STRUMPACK;
60#elif defined(MFEM_USE_MKL_CPARDISO)
61 type = Type::CPARDISO;
62#else
63 MFEM_ABORT("No parallel direct solver was enabled in MFEM.");
64#endif
65 }
66
67 InitSolver();
68}
69
71 const std::string &name)
72 : ParallelDirectSolver(comm, ParseType(name)) { }
73
74void ParallelDirectSolver::InitSolver()
75{
76 switch (type)
77 {
78 case Type::MUMPS:
79#ifdef MFEM_USE_MUMPS
80 {
81 auto *mumps = new MUMPSSolver(comm);
82 solver.reset(mumps);
83 }
84 break;
85#else
86 MFEM_ABORT("MUMPS requested but MFEM_USE_MUMPS is not defined.");
87#endif
88
89 case Type::SUPERLU:
90#ifdef MFEM_USE_SUPERLU
91 {
92 auto *slu = new SuperLUSolver(comm);
93 solver.reset(slu);
94 }
95 break;
96#else
97 MFEM_ABORT("SuperLU requested but MFEM_USE_SUPERLU is not defined.");
98#endif
99
100 case Type::STRUMPACK:
101#ifdef MFEM_USE_STRUMPACK
102 {
103 auto *strumpack = new STRUMPACKSolver(comm);
104 strumpack->SetKrylovSolver(strumpack::KrylovSolver::DIRECT);
105 strumpack->SetReorderingStrategy(strumpack::ReorderingStrategy::METIS);
106 strumpack->SetMatching(strumpack::MatchingJob::NONE);
107 strumpack->SetCompression(strumpack::CompressionType::NONE);
108 solver.reset(strumpack);
109 }
110 break;
111#else
112 MFEM_ABORT("STRUMPACK requested but MFEM_USE_STRUMPACK is not defined.");
113#endif
114
115 case Type::CPARDISO:
116#ifdef MFEM_USE_MKL_CPARDISO
117 {
118 auto *cpardiso = new CPardisoSolver(comm);
119 solver.reset(cpardiso);
120 }
121 break;
122#else
123 MFEM_ABORT("CPARDISO requested but MFEM_USE_MKL_CPARDISO is not defined.");
124#endif
125
126 default:
127 MFEM_ABORT("Invalid solver type.");
128 }
129}
130
132{
133 MFEM_VERIFY(solver, "Solver not initialized.");
134
135 switch (type)
136 {
137 case Type::MUMPS:
138 case Type::CPARDISO:
139 // These accept HypreParMatrix directly (or Operator that dynamic_casts to it)
140 solver->SetOperator(op);
141 break;
142
143 case Type::SUPERLU:
144#ifdef MFEM_USE_SUPERLU
145 // SuperLUSolver requires a SuperLURowLocMatrix.
146 superlu_mat.reset(new SuperLURowLocMatrix(op));
147 solver->SetOperator(*superlu_mat);
148 break;
149#else
150 MFEM_ABORT("SUPERLU not enabled.");
151#endif
152
153 case Type::STRUMPACK:
154#ifdef MFEM_USE_STRUMPACK
155 // STRUMPACKSolver requires a STRUMPACKRowLocMatrix.
156 strumpack_mat.reset(new STRUMPACKRowLocMatrix(op));
157 solver->SetOperator(*strumpack_mat);
158 break;
159#else
160 MFEM_ABORT("STRUMPACK not enabled.");
161#endif
162
163 default:
164 MFEM_ABORT("SetOperator: unknown type.");
165 }
166}
167
169{
170 MFEM_VERIFY(solver, "Solver not initialized.");
171 solver->Mult(x, y);
172}
173
175{
176 if (!solver) { return; }
177
178#ifdef MFEM_USE_MUMPS
179 if (auto *mumps = dynamic_cast<MUMPSSolver*>(solver.get()))
180 {
181 mumps->SetPrintLevel(print_lvl);
182 return;
183 }
184#endif
185#ifdef MFEM_USE_SUPERLU
186 if (auto *slu = dynamic_cast<SuperLUSolver*>(solver.get()))
187 {
188 slu->SetPrintStatistics(print_lvl != 0);
189 return;
190 }
191#endif
192#ifdef MFEM_USE_STRUMPACK
193 if (auto *sp = dynamic_cast<STRUMPACKSolver*>(solver.get()))
194 {
195 sp->SetPrintFactorStatistics(print_lvl != 0);
196 sp->SetPrintSolveStatistics(print_lvl != 0);
197 return;
198 }
199#endif
200#ifdef MFEM_USE_MKL_CPARDISO
201 if (auto *pardiso = dynamic_cast<CPardisoSolver*>(solver.get()))
202 {
203 pardiso->SetPrintLevel(print_lvl);
204 return;
205 }
206#endif
207}
208
209}
MKL Parallel Direct Sparse Solver for Clusters.
Definition cpardiso.hpp:31
MUMPS: A Parallel Sparse Direct Solver.
Definition mumps.hpp:39
Abstract operator.
Definition operator.hpp:25
Wrapper around parallel sparse direct solvers (MUMPS, SuperLU_DIST, STRUMPACK, CPARDISO).
Type
Type of parallel direct solver to use.
ParallelDirectSolver(MPI_Comm comm_, Type type_=Type::AUTO)
Construct a ParallelDirectSolver from an MPI communicator and a Type.
virtual void SetPrintLevel(int print_lvl)
virtual void Mult(const Vector &x, Vector &y) const override
Apply the inverse of the operator: y = A^{-1} x.
virtual void SetOperator(const Operator &op) override
Set the operator to be factored/solved by the direct solver.
Vector data type.
Definition vector.hpp:82