Mercurial > repos > public > sbplib
changeset 1152:010bb2677230 feature/rv
Clean up in +rv/+time. Make the time stepping more efficient by not storing unnessecary properties in the RK-RV time steppers
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Tue, 05 Mar 2019 10:53:34 +0100 |
parents | 03ecf18d035f |
children | 635386c073b9 0c906f7ab8bf |
files | +rv/+time/BdfDerivative.m +rv/+time/RungekuttaExteriorRv.m +rv/+time/RungekuttaExteriorRvBdf.m +rv/+time/RungekuttaInteriorRv.m +rv/+time/rungekuttaRV.m +rv/ResidualViscosity.m |
diffstat | 6 files changed, 43 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/+rv/+time/BdfDerivative.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/+time/BdfDerivative.m Tue Mar 05 10:53:34 2019 +0100 @@ -2,16 +2,10 @@ 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. + methods 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;
--- a/+rv/+time/RungekuttaExteriorRv.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/+time/RungekuttaExteriorRv.m Tue Mar 05 10:53:34 2019 +0100 @@ -6,22 +6,8 @@ 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 @@ -38,8 +24,6 @@ obj.RV = RV; obj.DvDt = DvDt; - obj.dvdt = obj.DvDt(obj.v); - [obj.viscosity, obj.Df, obj.firstOrderViscosity, obj.residualViscosity] = RV.evaluate(obj.v,obj.dvdt); end function [v, t] = getV(obj) @@ -48,15 +32,16 @@ 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); + dvdt = obj.DvDt(obj.v); + [viscosity, Df, firstOrderViscosity, residualViscosity] = obj.RV.evaluate(obj.v, dvdt); + state = struct('v', obj.v, 'dvdt', dvdt, 'Df', Df, 'viscosity', viscosity, 'residualViscosity', residualViscosity, 'firstOrderViscosity', firstOrderViscosity, 't', obj.t); end + % Advances the solution vector one time step using the Runge-Kutta method given by + % obj.coeffs, using a fixed residual viscosity for the Runge-Kutta substeps function obj = step(obj) - obj.dvdt = obj.DvDt(obj.v); - [obj.viscosity, obj.Df, obj.firstOrderViscosity, obj.residualViscosity] = obj.RV.evaluate(obj.v,obj.dvdt); - % Fix the viscosity of the RHS function F - F_visc = @(v,t) obj.F(v,t,obj.viscosity); + F_visc = @(v,t) obj.F(v,t,obj.RV.evaluateViscosity(obj.v, obj.DvDt(obj.v))); 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;
--- a/+rv/+time/RungekuttaExteriorRvBdf.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/+time/RungekuttaExteriorRvBdf.m Tue Mar 05 10:53:34 2019 +0100 @@ -15,13 +15,6 @@ % 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) @@ -36,22 +29,11 @@ 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) @@ -60,31 +42,42 @@ 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); + if (size(obj.v_prev,2) >= obj.lowerBdfOrder) + dvdt = obj.DvDt.evaluate(obj.v, obj.v_prev, obj.k); + [viscosity, Df, firstOrderViscosity, residualViscosity] = obj.RV.evaluate(obj.v, dvdt); + else + viscosity = zeros(size(obj.v)); + dvdt = zeros(size(obj.v)); + Df = zeros(size(obj.v)); + firstOrderViscosity = zeros(size(obj.v)); + residualViscosity = zeros(size(obj.v)); + end + state = struct('v', obj.v, 'dvdt', dvdt, 'Df', Df, 'viscosity', viscosity, 'residualViscosity', residualViscosity, 'firstOrderViscosity', 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) + nStoredStages = size(obj.v_prev,2); + + %Calculate viscosity for the new time level + if (nStoredStages >= obj.lowerBdfOrder) + viscosity = obj.RV.evaluateViscosity(obj.v, obj.DvDt.evaluate(obj.v, obj.v_prev, obj.k)); + else + viscosity = zeros(size(obj.v)); + end + + % Store current time level and update v_prev + if (nStoredStages < 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); + F_visc = @(v,t) obj.F(v, t, 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 \ No newline at end of file
--- a/+rv/+time/RungekuttaInteriorRv.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/+time/RungekuttaInteriorRv.m Tue Mar 05 10:53:34 2019 +0100 @@ -8,13 +8,6 @@ coeffs % The coefficents used for the RK time integration RV % Residual Viscosity DvDt % Function for computing the time deriative used for the RV evaluation - - % 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 @@ -30,8 +23,6 @@ obj.coeffs = struct('s',s,'a',a,'b',b,'c',c); obj.RV = RV; obj.DvDt = DvDt; - obj.dvdt = obj.DvDt(obj.v); - [obj.viscosity, obj.Df, obj.firstOrderViscosity, obj.residualViscosity] = obj.RV.evaluate(obj.v,obj.dvdt); end function [v, t] = getV(obj) @@ -40,15 +31,17 @@ 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); + dvdt = obj.DvDt(obj.v); + [viscosity, Df, firstOrderViscosity, residualViscosity] = obj.RV.evaluate(obj.v, dvdt); + state = struct('v', obj.v, 'dvdt', dvdt, 'Df', Df, 'viscosity', viscosity, 'residualViscosity', residualViscosity, 'firstOrderViscosity', firstOrderViscosity, 't', obj.t); end + % Advances the solution vector one time step using the Runge-Kutta method given by + % obj.coeffs, updating the Residual Viscosity in each Runge-Kutta stage function obj = step(obj) obj.v = rv.time.rungekuttaRV(obj.v, obj.t, obj.k, obj.F, obj.RV, obj.DvDt, obj.coeffs); obj.t = obj.t + obj.k; obj.n = obj.n + 1; - obj.dvdt = obj.DvDt(obj.v); - [obj.viscosity, obj.Df, obj.firstOrderViscosity, obj.residualViscosity] = obj.RV.evaluate(obj.v,obj.dvdt); end end end \ No newline at end of file
--- a/+rv/+time/rungekuttaRV.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/+time/rungekuttaRV.m Tue Mar 05 10:53:34 2019 +0100 @@ -7,7 +7,7 @@ % Move one stage outside to avoid branching for updating the % residual inside the loop. k = zeros(length(v), coeffs.s); - k(:,1) = F(v,t,RV.evaluate(v,DvDt(v))); + k(:,1) = F(v,t,RV.evaluateViscosity(v,DvDt(v))); % Compute the intermediate stages k for i = 2:coeffs.s @@ -15,8 +15,7 @@ for j = 1:i-1 u = u + dt*coeffs.a(i,j)*k(:,j); end - %RV.update(0.5*(u+v),(u-v)/(coeffs.c(i)*dt)); % Crank-Nicholson for time discretization - k(:,i) = F(u,t+coeffs.c(i)*dt, RV.evaluate(u,DvDt(u))); + k(:,i) = F(u,t+coeffs.c(i)*dt, RV.evaluateViscosity(u,DvDt(u))); end % Compute the updated solution as a linear combination @@ -25,6 +24,5 @@ for i = 1:coeffs.s u = u + dt*coeffs.b(i)*k(:,i); end - %RV.update(0.5*(u+v),(u-v)/dt); % Crank-Nicholson for time discretization v = u; end
--- a/+rv/ResidualViscosity.m Mon Feb 18 09:00:00 2019 +0100 +++ b/+rv/ResidualViscosity.m Tue Mar 05 10:53:34 2019 +0100 @@ -24,6 +24,12 @@ obj.boundaryIndices = obj.getBoundaryIndices(g); end + function viscosity = evaluateViscosity(obj, v, dvdt) + viscosity = min(obj.Cmax*obj.h*abs(obj.waveSpeed(v)), obj.Cres*obj.h^2*abs(dvdt + obj.Df(v))./obj.normalization(v)); + % TODO: If the boundary conditions are implemented correctly, this might not be needed. + viscosity(obj.boundaryIndices) = 0; + end + function [viscosity, Df, firstOrderViscosity, residualViscosity] = evaluate(obj, v, dvdt) Df = obj.Df(v); firstOrderViscosity = obj.Cmax*obj.h*abs(obj.waveSpeed(v)); @@ -47,15 +53,6 @@ end end - % function f = minmaxDiffNeighborhood(g) - % switch g.D() - % case 1 - % f = @(u)minmaxDiffNeighborhood1d(u); - % case 2 - % f = @(u)minmaxDiffNeighborhood2d(g,u); - % end - % end - function minmaxDiff = minmaxDiffNeighborhood1d(u) umax = movmax(u,3); umin = movmin(u,3);