view +rv/+time/RungekuttaExteriorRvBdf.m @ 1031:2ef20d00b386 feature/advectionRV

For easier comparison, return both the first order and residual viscosity when evaluating the residual. Add the first order and residual viscosity to the state of the RungekuttaRV time steppers
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Thu, 17 Jan 2019 10:25:06 +0100
parents dce08a74e0ad
children 010bb2677230
line wrap: on
line source

classdef RungekuttaExteriorRvBdf < time.Timestepper
    properties
        F       % RHS of the ODE
        k       % Time step
        t       % Time point
        v       % Solution vector
        n       % Time level
        coeffs  % The coefficents used for the RK time integration
        
        % Properties related to the residual viscositys
        RV              % Residual Viscosity operator
        v_prev          % Solution vector at previous time levels, used for the RV evaluation
        DvDt            % Function for computing the time deriative used for the RV evaluation
        lowerBdfOrder   % Orders of the approximation of the time deriative, used for the RV evaluation.
                        % dictates which accuracy the boot-strapping should start from.
        upperBdfOrder   % Orders of the approximation of the time deriative, used for the RV evaluation.
                        % Dictates the order of accuracy used once the boot-strapping is complete.
        
        % Convenience properties. Only for plotting
        viscosity % Total viscosity
        residualViscosity % Residual viscosity
        firstOrderViscosity % first order viscosity
        dvdt % Evaluated time derivative in residual
        Df % Evaluated flux in residual
    end
    methods
        function obj = RungekuttaExteriorRvBdf(F, k, t0, v0, RV, rkOrder, bdfOrders)
            obj.F = F;
            obj.k = k;
            obj.t = t0;
            obj.v = v0;
            obj.n = 0;
            % Extract the coefficients for the specified rkOrder
            % used for the RK updates from the Butcher tableua.
            [s,a,b,c] = time.rk.butcherTableau(rkOrder);
            obj.coeffs = struct('s',s,'a',a,'b',b,'c',c);
        
            obj.RV = RV;
            %  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.
            %       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.viscosity = zeros(size(v0));
            obj.firstOrderViscosity = zeros(size(v0));
            obj.residualViscosity = zeros(size(v0));
            obj.dvdt = zeros(size(v0));
            obj.Df = zeros(size(v0));
        end

        function [v, t] = getV(obj)
            v = obj.v;
            t = obj.t;
        end

        function state = getState(obj)
            state = struct('v', obj.v, 'dvdt', obj.dvdt, 'Df', obj.Df, 'viscosity', obj.viscosity, 'residualViscosity', obj.residualViscosity, 'firstOrderViscosity', obj.firstOrderViscosity, 't', obj.t);
        end

        function obj = step(obj)
            % Store current time level and update v_prev
            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;
            end

            % Fix the viscosity of the RHS function F
            F_visc = @(v,t) obj.F(v,t,obj.viscosity);
            obj.v = time.rk.rungekutta(obj.v, obj.t, obj.k, F_visc, obj.coeffs);
            obj.t = obj.t + obj.k;
            obj.n = obj.n + 1;

            %Calculate dvdt and evaluate RV for the new time level
            if ((numStoredStages >=  obj.lowerBdfOrder) && (numStoredStages <= obj.upperBdfOrder))
                obj.dvdt = obj.DvDt.evaluate(obj.v, obj.v_prev, obj.k);
                [obj.viscosity, obj.Df, obj.firstOrderViscosity, obj.residualViscosity] = obj.RV.evaluate(obj.v,obj.dvdt);
            end
        end
    end
end