5 #ifndef UG4_SOLVER_UTIL_H
6 #define UG4_SOLVER_UTIL_H
11 #include <nlohmann/json.hpp>
17 #include <unordered_map>
34 void CondAbort(
bool condition, std::string message){
35 UG_ASSERT(!condition,
"ERROR in util.solver: " << message);
37 template<
typename TAlgebra>
43 if(descriptor.contains(
"verbose")){
44 verbose = descriptor[
"verbose"];
46 std::string name =
"standard";
47 if(descriptor.contains(
"type")){
48 name = descriptor[
"type"];
51 if(descriptor.contains(
"iterations")){
52 iterations = descriptor[
"iterations"];
55 if(descriptor.contains(
"reduction")){
56 reduction = descriptor[
"reduction"];
59 if(descriptor.contains(
"absolute")){
60 absolute = descriptor[
"absolute"];
62 bool suppress_unsuccessful =
false;
63 if(descriptor.contains(
"suppress_unsuccessful")){
64 suppress_unsuccessful = descriptor[
"suppress_unsuccessful"];
69 new StdConvCheck<vector_type>(iterations,
73 suppress_unsuccessful));
78 template<
typename TDomain,
typename TAlgebra>
79 using SolverComponent = std::variant<
95 template<
typename TDomain,
typename TAlgebra>
104 void setComponent(
const std::string& key, SolverComponent<TDomain, TAlgebra> component){
105 components[key] = component;
108 SolverComponent<TDomain, TAlgebra> getComponent(
const std::string& key)
const {
109 auto it = components.find(key);
110 if (it != components.end()){
113 UG_THROW(
"SolverUtil.getComponent(" << key <<
"): no component named " << key <<
" found");
116 bool hasComponent(
const std::string& key)
const{
118 auto it = components.find(key);
119 if (it != components.end()){
127 SmartPtr<T> getComponentAs(
const std::string& key)
const {
128 return std::get<SmartPtr<T>>(getComponent(key));
132 std::unordered_map<std::string, SolverComponent<TDomain, TAlgebra>> components;
138 template<
typename TDomain,
typename TAlgebra>
140 SolverUtil<TDomain, TAlgebra> solverutil){
143 std::string
type =
"linear";
144 if(solverDesc.contains(
"type")){
145 type = solverDesc[
"type"];
147 if(
type ==
"newton"){
148 auto newton_solver=
make_sp(
new NewtonSolver<TAlgebra>());
152 if(solverDesc.contains(
"linSolver")){
157 if(solverDesc.contains(
"lineSearch")){
160 newton_solver->set_convergence_check(CreateConvCheck<TAlgebra>(solverDesc[
"convCheck"]), solverutil);
169 template<
typename TDomain,
typename TAlgebra>
171 SolverUtil<TDomain, TAlgebra> solverutil){
173 typedef LinearSolver<TVector> TLinSolv;
177 bool create_precond =
false;
178 bool create_conv_check =
false;
181 if(!desc.contains(
"LinearSolver")){
185 new StdConvCheck<TVector>(100, 1e-9, 1e-12));
187 default_linear_solver->set_convergence_check(convCheck);
188 default_linear_solver->set_preconditioner(ilu);
189 return default_linear_solver;
197 template<
typename TDomain,
typename TAlgebra>
201 typedef IPreconditioner<TAlgebra> TPrecond;
206 nlohmann::json json_default_preconds = json_predefined_defaults::solvers.at(
"preconditioner");
212 if(solverutil.hasComponent(
"approxSpace")){
216 std::string
type = desc[
"type"];
219 typedef ILU<TAlgebra> TILU;
223 number beta = json_default_preconds[
"ilu"][
"beta"];
224 if(desc.contains(
"beta")){
229 number damping = json_default_preconds[
"ilu"][
"damping"];
230 if(desc.contains(
"damping")){
231 damping = desc[
"damping"];
233 ILU->set_damp(damping);
235 bool sort = json_default_preconds[
"ilu"][
"sort"];
236 if(desc.contains(
"sort")){
241 number sortEps = json_default_preconds[
"ilu"][
"sortEps"];
242 if(desc.contains(
"sortEps")){
243 sortEps = desc[
"sortEps"];
245 ILU->set_sort_eps(sortEps);
247 number inversionEps = json_default_preconds[
"ilu"][
"inversionEps"];
248 if(desc.contains(
"inversionEps")){
249 inversionEps = desc[
"inversionEps"];
251 ILU->set_inversion_eps(inversionEps);
253 bool consistentInterfaces = json_default_preconds[
"ilu"][
"consistentInterfaces"];
254 if(desc.contains(
"consistentInterfaces")){
255 consistentInterfaces = desc[
"consistentInterfaces"];
257 ILU->enable_consistent_interfaces(consistentInterfaces);
259 bool overlap = json_default_preconds[
"ilu"][
"overlap"];
260 if(desc.contains(
"overlap")){
261 overlap = desc[
"overlap"];
263 ILU->enable_overlap(overlap);
269 preconditioner = ILU.template cast_static<TPrecond>();
272 else if(
type ==
"ilut"){
274 typedef ILUTPreconditioner<TAlgebra> TILUT;
276 number threshold = json_default_preconds[
"ilut"][
"threshold"];
277 if(desc[
"ilut"].
contains(
"threshold")){
278 threshold = desc[
"ilut"][
"threshold"];
287 else if(
type ==
"jac"){
290 else if(
type ==
"gs"){
292 UG_LOG(
"creating gauss seidel\n")
293 typedef GaussSeidel<TAlgebra> TGS;
295 UG_LOG("consistentInterfaces default\n")
296 bool consistentInterfaces = json_default_preconds["gs"]["consistentInterfaces"];
297 UG_LOG("consistentInterfaces desc\n")
298 if(desc["gs"].contains("consistentInterfaces")){
299 consistentInterfaces = desc[
"gs"][
"consistentInterfaces"];
301 UG_LOG(
"enable consistentInterfaces\n")
302 GS->enable_consistent_interfaces(consistentInterfaces);
305 bool overlap = json_default_preconds["gs"]["overlap"];
306 if(desc["gs"].contains("overlap")){
307 overlap = desc[
"gs"][
"overlap"];
309 UG_LOG(
"enable overlap\n")
310 GS->enable_overlap(overlap);
311 preconditioner = GS.template cast_static<TPrecond>();
313 else if(
type == "sgs"){
316 else if(
type ==
"egs"){
319 else if(
type ==
"cgs"){
322 else if(
type ==
"ssc"){
325 else if(
type ==
"gmg"){
328 else if(
type ==
"schur"){
333 return preconditioner;
336 template<
typename TAlgebra>
339 typedef StandardLineSearch<typename TAlgebra::vector_type> line_search_type;
343 nlohmann::json json_default_lineSearch = json_predefined_defaults::solvers[
"lineSearch"];
347 std::string
type =
"standard";
349 if(desc.contains(
"type")){
353 if(
type ==
"standard"){
355 int maxSteps = json_default_lineSearch[
type][
"maxSteps"];
356 if(desc.contains(
"maxSteps")){
357 maxSteps = desc[
"maxSteps"];
359 number lambdaStart = json_default_lineSearch[
type][
"lambdaStart"];
360 if(desc.contains(
"lambdaStart")){
361 lambdaStart = desc[
"lambdaStart"];
363 number lambdaReduce = json_default_lineSearch[
type][
"lambdaReduce"];
364 if(desc.contains(
"lambdaReduce")){
365 lambdaReduce = desc[
"lambdaReduce"];
367 bool acceptBest = json_default_lineSearch[
type][
"acceptBest"];
368 if(desc.contains(
"acceptBest")){
369 acceptBest = desc[
"acceptBest"];
371 bool checkAll = json_default_lineSearch[
type][
"checkAll"];
372 if(desc.contains(
"checkAll")){
373 checkAll = desc[
"checkAll"];
376 ls =
make_sp(
new line_search_type(maxSteps,
382 if(desc.contains(
"verbose")){
383 bool verbose = desc[
"verbose"];
384 ls->set_verbose(verbose);
386 if(desc.contains(
"suffDesc")){
387 number suffDesc = desc[
"suffDesc"];
388 ls->set_suff_descent_factor(suffDesc);
390 if(desc.contains(
"maxDefect")){
391 number maxDefect = desc[
"maxDefect"];
392 ls->set_maximum_defect(maxDefect);
397 CondAbort(ls.
invalid(),
"Invalid line-search specified: " +
type);
402 template<
typename TDomain,
typename TAlgebra>
403 void PrepateSolverUtil(nlohmann::json& desc, nlohmann::json& solverutil){
405 typedef SolverUtil<TDomain, TAlgebra> TSolverUtil;
409 if(solverutil.contains(
"ApproxSpace")){
410 solv_util->setComponent(
"ApproxSpace",solverutil[
"ApproxSpace"]);
423 template<
typename TDomain,
typename TAlgebra>
424 class SolverUtilFunctionProvider{
430 SolverUtilFunctionProvider(){};
433 return CreatePreconditioner<TDomain, TAlgebra>(desc, solverutil);
437 return CreateLineSearch<TAlgebra>(desc);
function util test CreateConvCheck(convCheckDesc, solverutil)
function util test CreatePreconditioner(desc, solverutil)
function util test CreateLineSearch(desc)
function util test CreateSolver(descriptor, solverutil)
ParallelMatrix< SparseMatrix< double > > matrix_type
ParallelVector< Vector< double > > vector_type
#define UG_ASSERT(expr, msg)
bool contains(std::string str, std::string search)
SmartPtr< T, FreePolicy > make_sp(T *inst)
function ProblemDisc new(problemDesc, dom)