From 4b7a0cf01c66c5a386b1d6a4d0cba6c3e28e0cab Mon Sep 17 00:00:00 2001 From: Michael Innerberger <michael.innerberger@asc.tuwien.ac.at> Date: Wed, 19 Jul 2023 09:53:27 -0400 Subject: [PATCH] Make chooseIterativeSolver a static factory method of IterativeSolver --- examples/algebraicSolver.m | 2 +- examples/goafemIterativeSolver.m | 2 +- .../{ => @IterativeSolver}/IterativeSolver.m | 9 ++++++++ .../choose.m} | 21 +++++++++++++------ runAdditiveSchwarzPreconditioner.m | 8 +++---- runIterativeSolver.m | 8 +++---- tests/TestIterativeSolver.m | 6 +++--- 7 files changed, 37 insertions(+), 19 deletions(-) rename lib/solvers/{ => @IterativeSolver}/IterativeSolver.m (92%) rename lib/solvers/{chooseIterativeSolver.m => @IterativeSolver/choose.m} (77%) diff --git a/examples/algebraicSolver.m b/examples/algebraicSolver.m index 15084f3..3ef04b1 100644 --- a/examples/algebraicSolver.m +++ b/examples/algebraicSolver.m @@ -33,7 +33,7 @@ for p = 1:pmax % choose the iterative solver of choice: multigrid (with the variants % lowOrderVcycle and highOrderVcycle), pcg (with jacobi and additive % Schwarz preconditioner), and the cg solver - [solver, P] = chooseIterativeSolver(fes, blf, 'multigrid', 'lowOrderVcycle'); + [solver, P] = IterativeSolver.choose(fes, blf, 'multigrid', 'lowOrderVcycle'); solver.tol = 1e-6; solver.maxIter = 100; diff --git a/examples/goafemIterativeSolver.m b/examples/goafemIterativeSolver.m index 801bbfb..50a7df3 100644 --- a/examples/goafemIterativeSolver.m +++ b/examples/goafemIterativeSolver.m @@ -37,7 +37,7 @@ for p = 1:pmax lfG.qrf = QuadratureRule.ofOrder(2*p); %% set up solver and lifting operator for nested iteration - [solver, P] = chooseIterativeSolver(fes, blf, 'multigrid', 'lowOrderVcycle'); + [solver, P] = IterativeSolver.choose(fes, blf, 'multigrid', 'lowOrderVcycle'); solver.tol = 1e-6; solver.maxIter = 1000; diff --git a/lib/solvers/IterativeSolver.m b/lib/solvers/@IterativeSolver/IterativeSolver.m similarity index 92% rename from lib/solvers/IterativeSolver.m rename to lib/solvers/@IterativeSolver/IterativeSolver.m index 191676e..35495b1 100644 --- a/lib/solvers/IterativeSolver.m +++ b/lib/solvers/@IterativeSolver/IterativeSolver.m @@ -25,6 +25,10 @@ % % tf = solver.isConverged(solver) returns state of convergence of the solver % for each column of the right-hand side. +% +% [solver, P] = IterativeSolver.choose(fes, blf, class, variant) convenience +% factory method. Returns instances of IterativeSolver and Prolongation +% accoding to the given parameters. classdef IterativeSolver < handle @@ -102,6 +106,11 @@ classdef IterativeSolver < handle obj.activeComponents = obj.activeComponents & ~tf; end end + + %% convenience factory function + methods (Static, Access=public) + solver = choose(fes, blf, class, variant) + end %% validation functions to use within this class methods (Static, Access=protected) diff --git a/lib/solvers/chooseIterativeSolver.m b/lib/solvers/@IterativeSolver/choose.m similarity index 77% rename from lib/solvers/chooseIterativeSolver.m rename to lib/solvers/@IterativeSolver/choose.m index 54bf5fb..ef5d4fa 100644 --- a/lib/solvers/chooseIterativeSolver.m +++ b/lib/solvers/@IterativeSolver/choose.m @@ -1,7 +1,18 @@ -% chooseIterativeSolver Return suitable solver (instance of subclass of -% IterativeSolver) and suitable Prolongation P. +% choose Return suitable solver (instance of subclass of IterativeSolver) and +% suitable Prolongation P. +% +% solver = choose(fes, blf, class) returns a solver of class 'class' for given +% finite element space fes and bilinear form blf. For each class, sensible +% default variants are chosen. +% +% solver = choose(fes, blf, class, variant) returns a solver of class 'class' +% of specific variant 'variant'. +% +% [solver, P] = choose(__) additionally to the solver, returns a suitable +% Prolongation P, that can be used to prolongate the solution of the +% solver to the next finer mesh. -function [solver, P] = chooseIterativeSolver(fes, blf, class, variant) +function [solver, P] = choose(fes, blf, class, variant) arguments fes FeSpace blf BilinearForm @@ -48,7 +59,7 @@ switch class end solver = PcgSolver(preconditioner); - % geometric multigrid family + % geometric , Pmultigrid family case "multigrid" switch variant case {"", "lowOrderVcycle"} @@ -78,5 +89,3 @@ switch class end end - - diff --git a/runAdditiveSchwarzPreconditioner.m b/runAdditiveSchwarzPreconditioner.m index 3e6d606..971ffd8 100644 --- a/runAdditiveSchwarzPreconditioner.m +++ b/runAdditiveSchwarzPreconditioner.m @@ -32,10 +32,10 @@ function leveldata = runAdditiveSchwarzPreconditioner(pMax) lf.f = Constant(mesh, 1); % Choose iterative solver - solver = chooseIterativeSolver(fes, blf, "pcg", "additiveSchwarzLowOrder"); - % solver = chooseIterativeSolver(fes, blf, "pcg", "additiveSchwarzHighOrder"); - % solver = chooseIterativeSolver(fes, blf, "pcg", "iChol"); - % solver = chooseIterativeSolver(fes, blf, "multigrid", "lowOrderVcycle"); + solver = IterativeSolver.choose(fes, blf, "pcg", "additiveSchwarzLowOrder"); + % solver = IterativeSolver.choose(fes, blf, "pcg", "additiveSchwarzHighOrder"); + % solver = IterativeSolver.choose(fes, blf, "pcg", "iChol"); + % solver = IterativeSolver.choose(fes, blf, "multigrid", "lowOrderVcycle"); for k = 1:nLevels-1 % Assemble matrices on intermediate meshes diff --git a/runIterativeSolver.m b/runIterativeSolver.m index 350c6b1..ce2bcf8 100644 --- a/runIterativeSolver.m +++ b/runIterativeSolver.m @@ -28,10 +28,10 @@ function leveldata = runIterativeSolver(maxNiter) lf.f = Constant(mesh, 1); % Choose iterative solver - solver = chooseIterativeSolver(fes, blf, "pcg", "additiveSchwarzLowOrder"); - % solver = chooseIterativeSolver(fes, blf, "pcg", "additiveSchwarzHighOrder"); - % solver = chooseIterativeSolver(fes, blf, "pcg", "iChol"); - % solver = chooseIterativeSolver(fes, blf, "multigrid", "lowOrderVcycle"); + solver = IterativeSolver.choose(fes, blf, "pcg", "additiveSchwarzLowOrder"); + % solver = IterativeSolver.choose(fes, blf, "pcg", "additiveSchwarzHighOrder"); + % solver = IterativeSolver.choose(fes, blf, "pcg", "iChol"); + % solver = IterativeSolver.choose(fes, blf, "multigrid", "lowOrderVcycle"); % Initialize LevelData leveldata = LevelData('results'); diff --git a/tests/TestIterativeSolver.m b/tests/TestIterativeSolver.m index cbde884..6a32e6a 100644 --- a/tests/TestIterativeSolver.m +++ b/tests/TestIterativeSolver.m @@ -16,7 +16,7 @@ methods (Test) function firstStepDecreasesNorm(testCase, p, variant) [~, fes, blf, lf] = setupProblem(testCase, p); s = variant(1); v = variant(2); - solver = chooseIterativeSolver(fes, blf, s, v); + solver = IterativeSolver.choose(fes, blf, s, v); [xstar, A, F] = assembleData(testCase, blf, lf, fes); solver.setupSystemMatrix(A); @@ -32,7 +32,7 @@ methods (Test) function laterStepDecreasesNorm(testCase, p, variant) [mesh, fes, blf, lf] = setupProblem(testCase, p); s = variant(1); v = variant(2); - solver = chooseIterativeSolver(fes, blf, s, v); + solver = IterativeSolver.choose(fes, blf, s, v); for k = 1:3 [xstar, A, F] = assembleData(testCase, blf, lf, fes); @@ -51,7 +51,7 @@ methods (Test) function solverIsLinear(testCase, p, variant) [mesh, fes, blf, lf] = setupProblem(testCase, p); s = variant(1); v = variant(2); - solver = chooseIterativeSolver(fes, blf, s, v); + solver = IterativeSolver.choose(fes, blf, s, v); for k = 1:3 [xstar, A, F] = assembleData(testCase, blf, lf, fes); -- GitLab