Anl_Transient Class
This class inherits from the base class 'Anl' to implement the solution of a transient nonlinear analysis with implicit time integration schemes.
Contents
Authors
- Danilo Cavalcanti (dborges@cimne.upc.edu)
Class definition
classdef Anl_Transient < Anl
Public properties
properties (SetAccess = public, GetAccess = public) nlscheme = []; % Nonlinear solution scheme theta = 1.0; % Implicit time integration scheme parameter ti = 0.01; % Initial time tf = 1.0; % Final time dt = 0.001; % Time step dtMax = 0.001; % Maximum time step dtMin = 0.001; % Minimum time step adaptStep = false; % Adaptive step size maxIter = 250; % Maximum number of iterations maxAttempts = 10; % Maximum attempts to converge echo = true; % Flag to print in the command window end
Constructor method
methods %------------------------------------------------------------------ function this = Anl_Transient(nlscheme) this = this@Anl('Transient'); if strcmp(nlscheme,'Picard') this.nlscheme = NonlinearScheme_Picard(); elseif strcmp(nlscheme,'Newton') this.nlscheme = NonlinearScheme_Newton(); else disp("Error creating the Analysis object."); disp("Nonlinear solution scheme was not provided."); disp("Available options:"); disp(" Picard"); disp(" Newton"); error("Error: Nonlinear solution scheme was not provided"); end end end
Public methods
methods %------------------------------------------------------------------ % Execute the transient nonlinear analysis, handle time-stepping, % convergence checks, and update the model state. function run(this,mdl) disp("*** Performing transient nonlinear analysis...") % Initialize model object mdl.preComputations(); % Initialize analysis parameters t = this.ti; t0 = this.ti; step = 1; % Initialize solution vector X = mdl.U; dx = zeros(mdl.ndof); % Start transient process attempt = 1; brokenStep = false; while (t0 < this.tf) if this.echo fprintf("\t Time: %12.5f s \n", t); end % Update transient solution XOld = X; % Start iterative process convFlg = false; attemptOld = attempt; attempt = 1; while attempt < this.maxAttempts iter = 1; while true % Compute model global matrices [A,b] = mdl.getLinearSystem(X,XOld,this.nlscheme,this.dt); % Apply Dirichlet boundary conditions [A,b] = mdl.applyDirichletBC(A,b,X,this.nlscheme); % Update variables [X,dx] = this.nlscheme.eval(A,b,X,dx,mdl.doffree,iter); % Check convergence convFlg = this.nlscheme.convergence(X,XOld,dx,b,mdl.doffree,iter,this.echo); if convFlg == true break; end % Check maximum number of iterations iter = iter + 1; if (iter > this.maxIter) break end end % Check convergence if convFlg == true break; end % Reduce time step this.dt = max(this.dt/4.0, this.dtMin); % Clean previous attempt X = XOld; % Update attempt counter attempt = attempt + 1; end if convFlg == false disp("Solution did not converge!"); break; end % Update state variables mdl.updateStateVar(); % Update time step if (this.adaptStep == true) && (attempt == 1) && (brokenStep == false) && (attemptOld == 1) this.dt = min(2 * this.dt, this.dtMax); end % Update time t0 = t; if (t + this.dt) > this.tf this.dt = this.tf - t; end t = t + this.dt; step = step + 1; end % Update state variables mdl.updateStateVar(); % Save final result mdl.U = X; for i = 1:mdl.nelem gle = mdl.element(i).type.gle; mdl.element(i).type.ue = mdl.U(gle); end disp("*** Analysis completed!"); end %------------------------------------------------------------------ % Configure the transient solver with specified parameters. function setUpTransientSolver(this,ti,dt,tf,dtMax,dtMin,adaptStep) if nargin == 4 dtMax = dt; dtMin = dt; adaptStep = false; end this.ti = ti; this.dt = dt; this.tf = tf; this.adaptStep = adaptStep; this.dtMax = dtMax; this.dtMin = dtMin; end %------------------------------------------------------------------ % Enable or disable relaxation for the Picard nonlinear solution scheme. function setPicardRelaxation(this,flag) this.nlscheme.applyRelaxation = flag; end %------------------------------------------------------------------ % Enable or disable normalization of the error for relative convergence criteria. function setRelativeConvergenceCriteria(this,flag) this.nlscheme.normalizeError = flag; end %------------------------------------------------------------------ % Prints the solution vector 'X' for each node in the model. function printStep(~,X,mdl) for i = 1:mdl.nnodes fprintf(" %4d: \t", i); for j = 1:mdl.ndof_nd fprintf(" %8.4f ", X(mdl.ID(i,j))); end fprintf("\n"); end end end
end