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