Raw File
compute_dt.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file is part of NS2DDV.                                                      %
%                                                                                   %
% Copyright(C) 2011-2018    C. Calgaro  (caterina.calgaro@math.univ-lille1.fr)      %
%                           E. Creusé   (emmanuel.creuse@math.univ-lille1.fr)       %
%                           T. Goudon   (thierry.goudon@inria.fr)                   %
%                           A. Mouton   (alexandre.mouton@math.univ-lille1.fr)      %
%                                                                                   %
% NS2DDV is free software: you can redistribute it and/or modify it under the terms %
% of the GNU General Public License as published by the Free Software Foundation,   %
% either version 3 of the License, or (at your option) any later version.           %
%                                                                                   %
% NS2DDV is distributed in the hope that it will be useful, but WITHOUT ANY         %
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A   %
% PARTICULAR PURPOSE. See the GNU General Public License for more details.          %
%                                                                                   %
% You should have received a copy of the GNU General Public License along with      %
% NS2DDV. If not, see <http://www.gnu.org/licenses/>.                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function[dt] = compute_dt(t0, MESH, PARAMETERS)

	% INPUT
	% PARAMETERS	List of simulation parameters
	% MESH			Mesh metadata
	% t0			Initial time
	%
	% OUTPUT
	% dt			Adapted FE time step

	switch PARAMETERS.CV_STUDY
		case {'NONE', 'IN_REYNOLDS', 'IN_SPACETIME'}
			% Compute the time step thanks to the formula dt = Cmax*hmax^alphamax + Cmin*hmin^alphamin
			% hmax and hmin are related to the current mesh, Cmax and Cmin are fixed across the simulation set
			dtref = PARAMETERS.FE.CMAX_STEP_TIME*MESH.hmax^PARAMETERS.FE.ALPHAMAX_STEP_TIME + ...
					PARAMETERS.FE.CMIN_STEP_TIME*MESH.hmin^PARAMETERS.FE.ALPHAMIN_STEP_TIME;

		case {'IN_TIME'}
			% Compute the time step thanks to the formula dt = C*hmax^alpha
			% hmax is related to the mesh across the simulation set, C varies in the simulation set
			dtref = PARAMETERS.FE.C_STEP_TIME*MESH.hmax^PARAMETERS.FE.ALPHA_STEP_TIME;

		case {'IN_SPACE'}
			% Compute the time step thanks to the formula dt = min(Cmax*hmax^alphamax + Cmin*hmin^alphamin)
			% hmax and hmin vary across the simulation set, Cmax and Cmin are fixed
			% --> We must estimate each hmin and hmax
		
			switch PARAMETERS.MESH.GENERATION
				case {'NS2DDV'}
					switch PARAMETERS.DOMAIN.GEOMETRY
						case {'RECTANGLE'}
							if (isfield(PARAMETERS.MESH, 'NBSEG_X_LIST') && isfield(PARAMETERS.MESH, 'NBSEG_Y_LIST'))
								dttest = zeros(1,numel(PARAMETERS.MESH.NBSEG_X_LIST));
								for i=1:numel(PARAMETERS.MESH.NBSEG_X_LIST)
									hx = (PARAMETERS.DOMAIN.XMAX-PARAMETERS.DOMAIN.XMIN) ...
											/ PARAMETERS.MESH.NBSEG_X_LIST{i};
									hy = (PARAMETERS.DOMAIN.YMAX-PARAMETERS.DOMAIN.YMIN) ...
											/ PARAMETERS.MESH.NBSEG_Y_LIST{i};
									hmax = max(hx,hy);
									hmin = min(hx,hy);
									dttest(i) = PARAMETERS.FE.CMAX_STEP_TIME * ...
													hmax^PARAMETERS.FE.ALPHAMAX_STEP_TIME + ...
												PARAMETERS.FE.CMIN_STEP_TIME * ...
													hmin^PARAMETERS.FE.ALPHAMIN_STEP_TIME;
								end
								dtref = min(dttest);
								
							else
								error('PARAMETERS.MESH.NBSEG_X_LIST and PARAMETERS.MESH.NBSEG_Y_LIST are required');
							end

						case {'CIRCLE'}
							if isfield(PARAMETERS.MESH, 'NBSEG_C_LIST')
								dttest = zeros(1,numel(PARAMETERS.MESH.NBSEG_C_LIST));
								for i=1:numel(PARAMETERS.MESH.NBSEG_C_LIST)
									hmax = PARAMETERS.DOMAIN.RADIUS/PARAMETERS.MESH.NBSEG_C_LIST{i};
									dttest(i) = PARAMETERS.FE.CMAX_STEP_TIME * ...
													hmax^PARAMETERS.FE.ALPHAMAX_STEP_TIME + ...
												PARAMETERS.FE.CMIN_STEP_TIME * ...
													hmax^PARAMETERS.FE.ALPHAMIN_STEP_TIME;
								end
								dtref = min(dttest);
							else
								error('PARAMETERS.MESH.NBSEG_C_LIST is required');
							end

						otherwise
							error('Only RECTANGLE and CIRCLE geometries can be used for convergence and/or stability studies');
					end

				case {'PDET'}
					if isfield(PARAMETERS.MESH, 'H0_LIST')
						dttest = zeros(1,numel(PARAMETERS.MESH.H0_LIST));
						for i=1:numel(PARAMETERS.MESH.H0_LIST)
							hmax = PARAMETERS.MESH.H0_LIST{i};
							dttest(i) = PARAMETERS.FE.CMAX_STEP_TIME * ...
											hmax^PARAMETERS.FE.ALPHAMAX_STEP_TIME + ...
										PARAMETERS.FE.CMIN_STEP_TIME * ...
											hmax^PARAMETERS.FE.ALPHAMIN_STEP_TIME;
						end
						dtref = min(dttest);
					else
						error('PARAMETERS.MESH.H0_LIST is required');
					end

				case {'FROM_FILE'}
					error('Cannot identify the hmax of a mesh file set with PARAMETERS.MESH.GENERATION = ''FROM_FILE''');
			end

		otherwise
			error('Unknown value of PARAMETERS.CV_STUDY');
	end

	if ~strcmp(PARAMETERS.FE.FIT_STEP_TIME, 'NONE')
		if strcmp(PARAMETERS.MODEL, 'NSDV')
			if max(strcmp(PARAMETERS.TESTCASE, {'EXAC'}))
				switch PARAMETERS.TIME_SPLITTING
					case {1}
						N = 1+floor(PARAMETERS.FINAL_TIME/dtref);
						dt = (PARAMETERS.FINAL_TIME-t0)/N;
					case {2}
						N = 1+floor((PARAMETERS.FINAL_TIME-t0)/(2.*dtref));
						N = N + mod(N,2);
						dt = (PARAMETERS.FINAL_TIME-t0)/(N+1);
					otherwise
						error('Unknown time splitting');
				end
			else
				switch PARAMETERS.TIME_SPLITTING
					case {1}
						N = 1+floor((PARAMETERS.FINAL_TIME-t0)/dtref-dtref);
						dt = (-N+sqrt(N*N+4.*(PARAMETERS.FINAL_TIME-t0)))*0.5;
					case {2}
						N = 1+floor((PARAMETERS.FINAL_TIME-t0)/(2.*dtref)-dtref);
						dt = (-2.*N+sqrt(4.*N*N+8.*(PARAMETERS.FINAL_TIME-t0)))*0.25;
					otherwise
						error('Unknown time splitting');
				end
			end
		elseif strcmp(PARAMETERS.MODEL, 'NS')
			if max(strcmp(PARAMETERS.TESTCASE, {'EXAC','NONA','EXACNEU'}))
				N = 1+floor((PARAMETERS.FINAL_TIME-t0)/dtref);
				dt = (PARAMETERS.FINAL_TIME-t0)/N;
			else
				N = 1+floor((PARAMETERS.FINAL_TIME-t0)/dtref-dtref);
				dt = (-N+sqrt(N*N+4.*(PARAMETERS.FINAL_TIME-t0)))*0.5;
			end
		else
			error('Unknown model');
		end
	elseif strcmp(PARAMETERS.FE.FIT_STEP_TIME, 'NO')
		dt = dtref;
	else
		error('Unknown value for PARAMETERS.FE.FIT_STEP_TIME');
	end

end
back to top