changeset 1016:4b42999874c0 feature/advectionRV

Add lower level for boot-strapping to RungeKuttaExteriorRV - Add a lower level to RungeKuttaExteriorRV for which bootstrapping starts, e.g start bootstrapping from time level 3 using a 3rd order BDF - Clean up ResidualViscosity
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Fri, 07 Dec 2018 13:11:53 +0100
parents 9b7fcd5e4480
children 2d7c1333bd6c
files +rv/+time/BDFDerivative.m +rv/+time/BdfDerivative.m +rv/+time/RungekuttaExteriorRV.m +rv/ResidualViscosity.m
diffstat 4 files changed, 59 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
diff -r 9b7fcd5e4480 -r 4b42999874c0 +rv/+time/BDFDerivative.m
--- a/+rv/+time/BDFDerivative.m	Thu Dec 06 17:03:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-classdef BDFDerivative < handle
-    properties
-        coefficients
-    end
-    methods %TBD: Decide if the BDF order should be passed in construction
-            %     and only a row of coefficients stored based on the order.
-            %     There would still be an implicit dependancy on the number
-            %     of vectors in v_prev and elements in coefficients.
-            %     In addition, dt could be stored, but this would be
-            %     inflexible if different step sizes are employed.
-        function obj = BDFDerivative()
-            obj.coefficients = obj.getBDFCoefficients();
-        end
-        % Add asserts here?
-        function DvDt = evaluate(obj, v, v_prev, dt)
-            order = size(v_prev,2);
-            DvDt = (obj.coefficients(order,1)*v - sum(obj.coefficients(order,2:order+1).*v_prev,2))/dt;
-        end
-    end
-    methods(Static)
-        function c = getBDFCoefficients()
-            c = zeros(6,7);
-            c(1,1) = 1; c(1,2) = 1;
-            c(2,1) = 3/2; c(2,2) = 4/2; c(2,3) = -1/2;
-            c(3,1) = 11/6; c(3,2) = 18/6; c(3,3) = -9/6; c(3,4) = 2/6;
-            c(4,1) = 25/12; c(4,2) = 48/12; c(4,3) = -36/12; c(4,4) = 16/12; c(4,5) = -3/12;
-            c(5,1) = 137/60; c(5,2) = 300/60; c(5,3) = -300/60; c(5,4) = 200/60; c(5,5) = -75/60; c(5,6) = 12/60;
-            c(6,1) = 147/60; c(6,2) = 360/60; c(6,3) = -450/60; c(6,4) = 400/60; c(6,5) = -225/60; c(6,6) = 72/60; c(6,7) = -10/60;
-        end
-    end
-end
diff -r 9b7fcd5e4480 -r 4b42999874c0 +rv/+time/BdfDerivative.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+rv/+time/BdfDerivative.m	Fri Dec 07 13:11:53 2018 +0100
@@ -0,0 +1,31 @@
+classdef BdfDerivative < handle
+    properties
+        coefficients
+    end
+    methods %TBD: Decide if the BDF order should be passed in construction
+            %     and only a row of coefficients stored based on the order.
+            %     There would still be an implicit dependancy on the number
+            %     of vectors in v_prev and elements in coefficients.
+            %     In addition, dt could be stored, but this would be
+            %     inflexible if different step sizes are employed.
+        function obj = BdfDerivative()
+            obj.coefficients = obj.getBdfCoefficients();
+        end
+        % Add asserts here?
+        function DvDt = evaluate(obj, v, v_prev, dt)
+            order = size(v_prev,2);
+            DvDt = (obj.coefficients(order,1)*v - sum(obj.coefficients(order,2:order+1).*v_prev,2))/dt;
+        end
+    end
+    methods(Static)
+        function c = getBdfCoefficients()
+            c = zeros(6,7);
+            c(1,1) = 1; c(1,2) = 1;
+            c(2,1) = 3/2; c(2,2) = 4/2; c(2,3) = -1/2;
+            c(3,1) = 11/6; c(3,2) = 18/6; c(3,3) = -9/6; c(3,4) = 2/6;
+            c(4,1) = 25/12; c(4,2) = 48/12; c(4,3) = -36/12; c(4,4) = 16/12; c(4,5) = -3/12;
+            c(5,1) = 137/60; c(5,2) = 300/60; c(5,3) = -300/60; c(5,4) = 200/60; c(5,5) = -75/60; c(5,6) = 12/60;
+            c(6,1) = 147/60; c(6,2) = 360/60; c(6,3) = -450/60; c(6,4) = 400/60; c(6,5) = -225/60; c(6,6) = 72/60; c(6,7) = -10/60;
+        end
+    end
+end
diff -r 9b7fcd5e4480 -r 4b42999874c0 +rv/+time/RungekuttaExteriorRV.m
--- a/+rv/+time/RungekuttaExteriorRV.m	Thu Dec 06 17:03:22 2018 +0100
+++ b/+rv/+time/RungekuttaExteriorRV.m	Fri Dec 07 13:11:53 2018 +0100
@@ -7,16 +7,16 @@
         n       % Time level
         coeffs  % The coefficents used for the RK time integration
         RV      % Residual Viscosity
-        bdfOrder
         v_prev  % Solution vector at previous time levels, used for the RV update
         DvDt    % Function for computing the time deriative used for the RV update
-
-
-        dudt
+        lowerBdfOrder % Orders of the approximation of the time deriative, used for the RV update.
+                      % dictates which accuracy the boot-strapping should start from.
+        upperBdfOrder % Orders of the approximation of the time deriative, used for the RV update.
+                      % Dictates the order of accuracy used once the boot-strapping is complete.
     end
     methods
 
-        function obj = RungekuttaExteriorRV(F, k, t0, v0, RV, rkOrder, bdfOrder, dudt)
+        function obj = RungekuttaExteriorRV(F, k, t0, v0, RV, rkOrder, bdfOrders)
             obj.F = F;
             obj.k = k;
             obj.t = t0;
@@ -28,16 +28,17 @@
             obj.coeffs = struct('s',s,'a',a,'b',b,'c',c);
         
             obj.RV = RV;
-            %  TBD: For cases where h~k we could probably use rkOrder-2 here.
             %  TBD: Decide on if the initialization of the previous stages used by
             %       the BDF should be done here, or if it should be checked for each
             %       step taken.
-            assert((bdfOrder >= 1) && (bdfOrder <= 6));
-            obj.bdfOrder = bdfOrder;
+            %       If it is moved here, then multiple branching stages can be removed in step()
+            %       but this will effectively result in a plotted simulation starting from n = upperBdfOrder.
+            %       In addition, the properties lowerBdfOrder and upperBdfOrder can be removed.
+            obj.lowerBdfOrder = bdfOrders.lowerBdfOrder;
+            obj.upperBdfOrder = bdfOrders.upperBdfOrder;
+            assert((obj.lowerBdfOrder >= 1) && (obj.upperBdfOrder <= 6));
             obj.v_prev = [];
-            obj.DvDt = rv.time.BDFDerivative();
-
-            obj.dudt = dudt;
+            obj.DvDt = rv.time.BdfDerivative();
         end
 
         function [v, t] = getV(obj)
@@ -52,8 +53,10 @@
 
         function obj = step(obj)
             % Store current time level
-            if (size(obj.v_prev,2) < obj.bdfOrder)
+            numStoredStages = size(obj.v_prev,2);
+            if (numStoredStages < obj.upperBdfOrder)
                 obj.v_prev = [obj.v, obj.v_prev];
+                numStoredStages = numStoredStages+1;
             else
                 obj.v_prev(:,2:end) = obj.v_prev(:,1:end-1);
                 obj.v_prev(:,1) = obj.v;
@@ -64,11 +67,10 @@
             obj.t = obj.t + obj.k;
             obj.n = obj.n + 1;
             % Calculate dvdt and update RV for the new time level
-            dvdt = obj.DvDt.evaluate(obj.v, obj.v_prev, obj.k);
-            if ((size(obj.v_prev,2) >= 4) && (size(obj.v_prev,2) <= obj.bdfOrder))
+            if ((numStoredStages >=  obj.lowerBdfOrder) && (numStoredStages <= obj.upperBdfOrder))
+                dvdt = obj.DvDt.evaluate(obj.v, obj.v_prev, obj.k);
                 obj.RV.update(obj.v,dvdt);
             end
-            %obj.RV.update(obj.v,obj.dudt(obj.t));
         end
     end
 end
\ No newline at end of file
diff -r 9b7fcd5e4480 -r 4b42999874c0 +rv/ResidualViscosity.m
--- a/+rv/ResidualViscosity.m	Thu Dec 06 17:03:22 2018 +0100
+++ b/+rv/ResidualViscosity.m	Fri Dec 07 13:11:53 2018 +0100
@@ -1,12 +1,13 @@
-% class describing the viscosity 
 classdef ResidualViscosity < handle
     properties
         D % Diff op approximating the gradient of the flux f(u)
         waveSpeed % Wave speed at each grid point, e.g f'(u). %TBD: Better naming?
-        Cmax % Constant controling magnitude of upwind dissipation
-        Cres % Constant controling magnitude residual dissipation
-        h % Length scale used for scaling the viscosity.
+        Cmax % Constant controlling relative amount of upwind dissipation
+        Cres % Constant controling relative amount of upwind dissipation
+        h % Length scale used for scaling the viscosity. Typically grid spacing.
         viscosity % Stores the computed viscosity.
+        normalization % Function used to normalize the residual such that it is amplified in the
+                      % shocks.
 
         % Convenice (for verification and plotting) TBD: Decide on if it should be kept.
         u_t % Stores the latest approximated time derivative of the solution.
@@ -15,13 +16,10 @@
     end
 
     methods
-        % TODO: - Consider passing residual normalization as a function handle.
-        %         or choosing a type of normalization on construction.
-        %         Could for example be 1, norm((v-mean(v),inf) or normInfNeighborhood(v)
-        %         but working
-        %       - Decide on how to treat waveSpeed. It would be nice to just pass a constant value without
-        %         wrapping it in a function.
-        function obj = ResidualViscosity(D, waveSpeed, Cmax, Cres, h, N)
+        %  TBD: Decide on how to treat waveSpeed. It would be nice to just pass a constant value without
+        %       wrapping it in a function.
+        function obj = ResidualViscosity(D, waveSpeed, Cmax, Cres, h, N, normalization)
+            default_arg('normalization',@(v)norm(v-mean(v),inf));
             obj.D = D;
             obj.waveSpeed = waveSpeed;
             obj.h = h;
@@ -31,22 +29,14 @@
             obj.u_t = zeros(N,1);
             obj.grad_f = zeros(N,1);
             obj.residual = zeros(N,1);
+            obj.normalization = normalization;
         end
 
         function obj = update(obj, v, dvdt)
             obj.u_t = dvdt;
             obj.grad_f = obj.D(v);
             obj.residual = obj.u_t + obj.grad_f;
-            %obj.viscosity = min(obj.Cmax*obj.h*abs(obj.waveSpeed(v)), obj.Cres*obj.h^2*abs(obj.residual)/norm(v-mean(v),inf));
-            obj.viscosity = obj.smoothen(obj.Cres*obj.h^2*abs(obj.residual)/norm(v-mean(v),inf));
-
-        end
-
-        function smoothendVector = smoothen(obj, vector)
-            smoothendVector = vector;
-            for i = 2:length(vector)-1
-                smoothendVector(i) = (1/6)*(vector(i-1) + 4*vector(i) + vector(i+1));
-            end
+            obj.viscosity = min(obj.Cmax*obj.h*abs(obj.waveSpeed(v)), obj.Cres*obj.h^2*abs(obj.residual)/obj.normalization(v));
         end
 
         function [residual, u_t, grad_f] = getResidual(obj)
@@ -59,16 +49,4 @@
             viscosity = obj.viscosity;
         end
     end
-    % Remove or fix. Should be able to handle values close to zero. Should work in 2d and 3d.
-    methods (Static)
-        function R_norm = normInfNeighborhood(v)
-            n = length(v);
-            R_norm = zeros(n,1);
-            R_norm(1,1) = norm(v(1:3), inf);
-            R_norm(n,1) = norm(v(n-3:n), inf);
-            for i = 2:n-1
-                R_norm(i,1) = norm(v(i-1:i+1), inf);
-            end
-        end        
-    end
 end
\ No newline at end of file