diff --git a/lib/solvers/smoothers/MultilevelSmoother.m b/lib/solvers/smoothers/MultilevelSmoother.m index 0616a0300625badd384be2df0da7087d56af112e..ca7271db059c51bb0e23f923b20bd0e54110dc7c 100644 --- a/lib/solvers/smoothers/MultilevelSmoother.m +++ b/lib/solvers/smoothers/MultilevelSmoother.m @@ -26,6 +26,11 @@ classdef MultilevelSmoother < handle properties (Access=protected) fes blf + changedPatches + end + + properties (Access=private) + listenerHandle end %% methods @@ -42,6 +47,9 @@ classdef MultilevelSmoother < handle obj.nLevels = 0; obj.fes = fes; obj.blf = blf; + + mesh = fes.mesh; + obj.listenerHandle = mesh.listener('IsAboutToRefine', @obj.getChangedPatches); end function nonInvertedSmootherMatrix = setup(obj, ~) @@ -51,6 +59,21 @@ classdef MultilevelSmoother < handle nonInvertedSmootherMatrix = []; end end + + methods (Access=protected) + % callback function to be executed before mesh refinement: + % -> patches change for all vertices adjacent to refined edges and + % all new vertices + function getChangedPatches(obj, mesh, bisecData) + nCOld = mesh.nCoordinates; + nCNew = mesh.nCoordinates + nnz(bisecData.bisectedEdges) + ... + bisecData.nRefinedElements' * bisecData.nInnerNodes; + bisectedEdgeNodes = unique(mesh.edges(:,bisecData.bisectedEdges)); + obj.changedPatches{obj.nLevels+1} = false(nCNew, 1); + idx = [unique(bisectedEdgeNodes); ((nCOld+1):nCNew)']; + obj.changedPatches{obj.nLevels+1}(idx) = true; + end + end %% abstract methods methods (Abstract, Access=public) diff --git a/lib/solvers/smoothers/P1JacobiSmoother.m b/lib/solvers/smoothers/P1JacobiSmoother.m index 91a82f955b4f64675e7967b963f90cbba2a2189c..655775703440f743f4f8955cf87d771461e328e5 100644 --- a/lib/solvers/smoothers/P1JacobiSmoother.m +++ b/lib/solvers/smoothers/P1JacobiSmoother.m @@ -12,7 +12,6 @@ classdef P1JacobiSmoother < MultilevelSmoother intergridMatrix freeVertices freeVerticesOld - changedPatches end %% event data @@ -28,14 +27,12 @@ classdef P1JacobiSmoother < MultilevelSmoother blf P Prolongation end - obj = obj@MultilevelSmoother(fes, blf); - + assert(fes.finiteElement.order == 1, ... 'P1JacobiSmoother only works for lowest order finite elements.') + obj = obj@MultilevelSmoother(fes, blf); obj.P = P; - mesh = fes.mesh; - obj.listenerHandle = mesh.listener('IsAboutToRefine', @obj.getChangedPatches); end function nonInvertedSmootherMatrix = setup(obj, A) @@ -51,7 +48,7 @@ classdef P1JacobiSmoother < MultilevelSmoother if L >= 2 obj.intergridMatrix{L} = obj.P.matrix(obj.freeVertices, obj.freeVerticesOld); obj.changedPatches{L} = find(obj.changedPatches{L}(obj.freeVertices)); - obj.inverseDiagonal{L} = obj.inverseDiagonal{L}(obj.changedPatches{L},:); + obj.inverseDiagonal{L} = obj.inverseDiagonal{L}(obj.changedPatches{L}); end end @@ -69,19 +66,4 @@ classdef P1JacobiSmoother < MultilevelSmoother Px = obj.intergridMatrix{k}' * x; end end - - methods (Access=protected) - % callback function to be executed before mesh refinement: - % -> patches change for all vertices adjacent to refined edges and - % all new vertices - function getChangedPatches(obj, mesh, bisecData) - nCOld = mesh.nCoordinates; - nCNew = mesh.nCoordinates + nnz(bisecData.bisectedEdges) + ... - bisecData.nRefinedElements'*bisecData.nInnerNodes; - bisectedEdgeNodes = unique(mesh.edges(:,bisecData.bisectedEdges)); - obj.changedPatches{obj.nLevels+1} = false(nCNew, 1); - idx = [unique(bisectedEdgeNodes); ((nCOld+1):nCNew)']; - obj.changedPatches{obj.nLevels+1}(idx) = true; - end - end end \ No newline at end of file