LCOV - code coverage report
Current view: top level - src/systems - newmark_system.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 103 113 91.2 %
Date: 2025-08-19 19:27:09 Functions: 9 11 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : // Local includes
      21             : #include "libmesh/newmark_system.h"
      22             : #include "libmesh/equation_systems.h"
      23             : #include "libmesh/sparse_matrix.h"
      24             : #include "libmesh/libmesh_logging.h"
      25             : #include "libmesh/numeric_vector.h"
      26             : 
      27             : namespace libMesh
      28             : {
      29             : 
      30             : // ------------------------------------------------------------
      31             : // NewmarkSystem static members
      32             : const Real NewmarkSystem::_default_alpha    = .25;
      33             : const Real NewmarkSystem::_default_delta    = .5;
      34             : const Real NewmarkSystem::_default_timestep = 1.;
      35             : 
      36             : 
      37             : 
      38          71 : NewmarkSystem::NewmarkSystem (EquationSystems & es,
      39             :                               const std::string & name_in,
      40          71 :                               const unsigned int number_in) :
      41             :   LinearImplicitSystem (es, name_in, number_in),
      42          67 :   _a_0                 (1./(_default_alpha*_default_timestep*_default_timestep)),
      43          67 :   _a_1                 (_default_delta/(_default_alpha*_default_timestep)),
      44          67 :   _a_2                 (1./(_default_alpha*_default_timestep)),
      45          67 :   _a_3                 (1./(2.*_default_alpha)-1.),
      46          67 :   _a_4                 (_default_delta/_default_alpha -1.),
      47          67 :   _a_5                 (_default_timestep/2.*(_default_delta/_default_alpha-2.)),
      48          67 :   _a_6                 (_default_timestep*(1.-_default_delta)),
      49          67 :   _a_7                 (_default_delta*_default_timestep),
      50          71 :   _finished_assemble   (false)
      51             : 
      52             : {
      53             :   // default values of the newmark parameters
      54          71 :   es.parameters.set<Real>("Newmark alpha") = _default_alpha;
      55          71 :   es.parameters.set<Real>("Newmark delta") = _default_delta;
      56             : 
      57             :   // time step size.
      58             :   // should be handled at a later stage through EquationSystems?
      59          71 :   es.parameters.set<Real>("Newmark time step") = _default_timestep;
      60             : 
      61             :   // add additional matrices and vectors that will be used in the
      62             :   // newmark algorithm to the data structure
      63             :   // functions LinearImplicitSystem::add_matrix and LinearImplicitSystem::add_vector
      64             :   // are used so we do not have to bother about initialization and
      65             :   // dof mapping
      66             : 
      67             :   // system matrices
      68          71 :   this->add_matrix ("stiffness");
      69          71 :   this->add_matrix ("damping");
      70          71 :   this->add_matrix ("mass");
      71             : 
      72             :   // load vector
      73          71 :   this->add_vector ("force");
      74             : 
      75             :   // the displacement and the time derivatives
      76          71 :   this->add_vector ("displacement");
      77          71 :   this->add_vector ("velocity");
      78          71 :   this->add_vector ("acceleration");
      79             : 
      80             :   // contributions to the rhs
      81          71 :   this->add_vector ("rhs_m");
      82          71 :   this->add_vector ("rhs_c");
      83             : 
      84             :   // results from the previous time step
      85          71 :   this->add_vector ("old_solution");
      86          71 :   this->add_vector ("old_acceleration");
      87          71 : }
      88             : 
      89             : 
      90             : 
      91         134 : NewmarkSystem::~NewmarkSystem () = default;
      92             : 
      93             : 
      94             : 
      95           0 : void NewmarkSystem::clear ()
      96             : {
      97             :   // use parent clear this will also clear the
      98             :   // matrices and vectors added in the constructor
      99           0 :   LinearImplicitSystem::clear();
     100             : 
     101             :   // Get a reference to the EquationSystems
     102             :   EquationSystems & es =
     103           0 :     this->get_equation_systems();
     104             : 
     105             :   // default values of the newmark parameters
     106           0 :   es.parameters.set<Real>("Newmark alpha") = _default_alpha;
     107           0 :   es.parameters.set<Real>("Newmark delta") = _default_delta;
     108             : 
     109             :   // time step size.  should be handled at a later stage through EquationSystems?
     110           0 :   es.parameters.set<Real>("Newmark time step") = _default_timestep;
     111             : 
     112             :   // set bool to false
     113           0 :   _finished_assemble = false;
     114           0 : }
     115             : 
     116             : 
     117             : 
     118           0 : void NewmarkSystem::reinit ()
     119             : {
     120           0 :   libmesh_not_implemented();
     121             : }
     122             : 
     123             : 
     124             : 
     125       21371 : void NewmarkSystem::assemble ()
     126             : {
     127       21371 :   if (!_finished_assemble)
     128             :     {
     129             :       // prepare matrix with the help of the _dof_map,
     130             :       // fill with sparsity pattern
     131           2 :       LinearImplicitSystem::assemble();
     132             : 
     133             :       // compute the effective system matrix
     134          71 :       this->compute_matrix();
     135             : 
     136             :       // apply initial conditions
     137          71 :       this->initial_conditions();
     138             : 
     139          71 :       _finished_assemble = true;
     140             :     }
     141       21371 : }
     142             : 
     143             : 
     144          71 : void NewmarkSystem::initial_conditions ()
     145             : {
     146             :   // libmesh_assert(init_cond_fptr);
     147             : 
     148             :   // Log how long the user's matrix assembly code takes
     149           4 :   LOG_SCOPE("initial_conditions ()", "NewmarkSystem");
     150             : 
     151             :   // Set all values to 0, then
     152             :   // call the user-specified function for initial conditions.
     153          71 :   this->get_vector("displacement").zero();
     154          71 :   this->get_vector("velocity").zero();
     155          71 :   this->get_vector("acceleration").zero();
     156          71 :   this->user_initialization();
     157          71 : }
     158             : 
     159             : 
     160             : 
     161          71 : void NewmarkSystem::compute_matrix ()
     162             : {
     163             :   // close the component matrices
     164          71 :   this->get_matrix ("stiffness").close();
     165          71 :   this->get_matrix ("mass"     ).close();
     166          71 :   this->get_matrix ("damping"  ).close();
     167             : 
     168             :   // close & zero the system matrix
     169          71 :   this->matrix->close (); this->matrix->zero();
     170             : 
     171             :   // add up the matrices
     172          71 :   this->matrix->add (1.,   this->get_matrix ("stiffness"));
     173          71 :   this->matrix->add (_a_0, this->get_matrix ("mass"));
     174          71 :   this->matrix->add (_a_1, this->get_matrix ("damping"));
     175             : 
     176          71 : }
     177             : 
     178             : 
     179             : 
     180       21300 : void NewmarkSystem::update_rhs ()
     181             : {
     182         600 :   LOG_SCOPE("update_rhs ()", "NewmarkSystem");
     183             : 
     184             :   // zero the rhs-vector
     185       21300 :   NumericVector<Number> & the_rhs = *this->rhs;
     186       21300 :   the_rhs.zero();
     187             : 
     188             :   // get writable references to some vectors
     189       21300 :   NumericVector<Number> & rhs_m = this->get_vector("rhs_m");
     190       21300 :   NumericVector<Number> & rhs_c = this->get_vector("rhs_c");
     191             : 
     192             :   // zero the vectors for matrix-vector product
     193       21300 :   rhs_m.zero();
     194       21300 :   rhs_c.zero();
     195             : 
     196             :   // compute auxiliary vectors rhs_m and rhs_c
     197       21300 :   rhs_m.add(_a_0, this->get_vector("displacement"));
     198       21300 :   rhs_m.add(_a_2, this->get_vector("velocity"));
     199       21300 :   rhs_m.add(_a_3, this->get_vector("acceleration"));
     200             : 
     201       21300 :   rhs_c.add(_a_1, this->get_vector("displacement"));
     202       21300 :   rhs_c.add(_a_4, this->get_vector("velocity"));
     203       21300 :   rhs_c.add(_a_5, this->get_vector("acceleration"));
     204             : 
     205             :   // compute rhs
     206       21300 :   NumericVector<Number> & force = this->get_vector("force");
     207       21300 :   force.close();
     208       21300 :   the_rhs.add(force);
     209       21300 :   the_rhs.add_vector(rhs_m, this->get_matrix("mass"));
     210       21300 :   the_rhs.add_vector(rhs_c, this->get_matrix("damping"));
     211       21300 : }
     212             : 
     213             : 
     214             : 
     215       21300 : void NewmarkSystem::update_u_v_a ()
     216             : {
     217        1200 :   LOG_SCOPE("update_u_v_a ()", "NewmarkSystem");
     218             : 
     219             :   // get some references for convenience
     220         600 :   const NumericVector<Number> &  solu = *this->solution;
     221             : 
     222       21300 :   NumericVector<Number> &  disp_vec   = this->get_vector("displacement");
     223       21300 :   NumericVector<Number> &  vel_vec    = this->get_vector("velocity");
     224       21300 :   NumericVector<Number> &  acc_vec    = this->get_vector("acceleration");
     225       21300 :   NumericVector<Number> &  old_acc    = this->get_vector("old_acceleration");
     226       21300 :   NumericVector<Number> &  old_solu   = this->get_vector("old_solution");
     227             : 
     228             :   // copy data
     229       21300 :   old_solu = disp_vec;
     230       21300 :   disp_vec = solu;
     231       21300 :   old_acc  = acc_vec;
     232             : 
     233             :   // compute the new acceleration vector
     234       21300 :   acc_vec.scale(-_a_3);
     235       21300 :   acc_vec.add(_a_0, disp_vec);
     236       21300 :   acc_vec.add(-_a_0, old_solu);
     237       21300 :   acc_vec.add(-_a_2,vel_vec);
     238             : 
     239             :   // compute the new velocity vector
     240       21300 :   vel_vec.add(_a_6,old_acc);
     241       21300 :   vel_vec.add(_a_7,acc_vec);
     242       21300 : }
     243             : 
     244             : 
     245             : 
     246          71 : void NewmarkSystem::set_newmark_parameters (const Real delta_T,
     247             :                                             const Real alpha,
     248             :                                             const Real delta)
     249             : {
     250           2 :   libmesh_assert_not_equal_to (delta_T, 0.);
     251             : 
     252             :   // Get a reference to the EquationSystems
     253             :   EquationSystems & es =
     254           4 :     this->get_equation_systems();
     255             : 
     256             :   // the newmark parameters
     257          71 :   es.parameters.set<Real>("Newmark alpha") = alpha;
     258          71 :   es.parameters.set<Real>("Newmark delta") = delta;
     259             : 
     260             :   // time step size.
     261             :   // should be handled at a later stage through EquationSystems?
     262          71 :   es.parameters.set<Real>("Newmark time step") = delta_T;
     263             : 
     264             :   // the constants for time integration
     265          71 :   _a_0 = 1./(alpha*delta_T*delta_T);
     266          71 :   _a_1 = delta/(alpha*delta_T);
     267          71 :   _a_2 = 1./(alpha*delta_T);
     268          71 :   _a_3 = 1./(2.*alpha)-1.;
     269          71 :   _a_4 = delta/alpha -1.;
     270          71 :   _a_5 = delta_T/2.*(delta/alpha-2.);
     271          71 :   _a_6 = delta_T*(1.-delta);
     272          71 :   _a_7 = delta*delta_T;
     273          71 : }
     274             : 
     275             : } // namespace libMesh

Generated by: LCOV version 1.14