⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndsolver.cpp

📁 Finite element program for mechanical problem. It can solve various problem in solid problem
💻 CPP
字号:
#include "ndsolver.h"#include "global.h"#include "globmat.h"#include "gmatrix.h"#include "loadcase.h"#include "dloadcase.h"#include "auxdatout.h"#include "mechprint.h"#include "elemswitch.h"void solve_nonlinear_dynamics (){  switch (Mp->tforvib){  case newmark:{    nonlin_newmark_method ();    break;  }  default:{    fprintf (stderr,"\n\n unknown solver of nonlinear dynamics is required");    fprintf (stderr,"\n in function solve_nonlinear_dynamics () (file %s, line %d).\n",__FILE__,__LINE__);  }  }}/**   Nonlinear Newmark method for solution of nonlinear dynamic problems   the method is implicit, equilibrium is solved by the Newton-Raphson method      tam co byla alpha je nyni beta   tam co byla delta je nyni gamma      5.3.2007, JK*/void nonlin_newmark_method (){  long i,j,n;  double beta,gamma,zero,time,dt,end_time;  double *a,*v,*p,*dd,*vv,*lhs,*rhs,*fs,*brhs;    //  number of degrees of freedom  n = Ndofm;  //  computer zero  zero=Mp->zero;  //  coefficient of the method  beta=Mp->alphafvn;  //  coefficient of the method  gamma=Mp->deltafvn;    //  initial time  time=Mp->timecon.starttime ();  //  end time  end_time = Mp->timecon.endtime ();  //  first time increment  dt = Mp->timecon.initialtimeincr ();    //  load case id  //  this solver enables only one load case with respect to nonlinearity  lcid=0;    //  nodal values - displacements  //  (assigment of initial values)  lhs = Lsrs->give_lhs (lcid);  //  time derivatives of nodal values - velocities  //  (assigment of initial values)  v = Lsrs->give_tdlhs (lcid);  //  vector of dynamic load  rhs = Lsrs->give_rhs (2*lcid);  //  vector of static load  fs = Lsrs->give_rhs (2*lcid+1);  //  backup of the right hand side  brhs = new double [n];  //  vector of acceleration  a = Lsrs->give_stdlhs (lcid);  nullv (a,n);  //  predictor of displacements  dd = new double [n];  //  predictor of velocities  vv = new double [n];  //  auxiliary vector  p = new double [n];    //  assembling of static loads    nullv (fs+lcid*n, n);  Mb->lc[lcid].assemble (lcid,fs,1.0);    //  number of step  i=0;  print_init(-1, "wt");    print_step(lcid, i, Mp->time, rhs);  print_flush();      //  time initialization  Mp->time = Mp->timecon.newtime ();  //  time increment  dt = Mp->timecon.actualbacktimeincr ();      //  loop over time interval  do{        //  stiffness matrix    stiffness_matrix (lcid);    //  mass matrix    mass_matrix (lcid);    //  damping matrix    damping_matrix ();        if (Mespr==1)  fprintf (stdout,"\n                                time  %f",Mp->time);        //  assembling of dynamic loads    nullv (rhs+lcid*n, n);    Mb->dlc[lcid].assemble (lcid,rhs,n,Mp->time);        //  total load    addv (rhs,fs,n);        //  modification of vector of prescribed nodal forces    cmulv (dt*dt*beta,rhs,n);    //  copy of the actual prescribed forces    copyv (rhs,brhs,n);        //  predictor vectors    for (j=0;j<n;j++){      dd[j] = lhs[j] + dt*v[j] + dt*dt*(0.5-beta)*a[j];      vv[j] = v[j] + dt*(1.0-gamma)*a[j];    }        //  M.dd    Mmat->gmxv (dd,p);        //  contribution to the right hand side    addv (rhs,p,n);        //  C.dd    Dmat->gmxv (dd,p);    cmulv (dt*gamma,p,n);    addv (rhs,p,n);        //  C.vv    Dmat->gmxv (vv,p);    cmulv (-1.0*dt*dt*beta,p,n);    addv (rhs,p,n);        //  dynamic stiffness matrix    //  (stored in array for stiffness matrix)    //  M + gamma.dt.C + beta.dt.dt.K    Smat->scalgm (dt*dt*beta);    Smat->addgm (1.0,*Mmat);    Smat->addgm (dt*gamma,*Dmat);            //  solution of system of algebraic equations    Smat->solve_system (Gtm,lhs,rhs);        for (j=0;j<n;j++){      a[j] = 1.0/dt/dt/beta*(lhs[j]-dd[j]);      v[j] = vv[j] + gamma*dt*a[j];    }            //  restoration of the prescribed forces    copyv (brhs,rhs,n);            //  inertial forces    //  M.a    Mmat->gmxv (a,p);    cmulv (-1.0*dt*dt*beta,p,n);    addv (rhs,p,n);        //  damping forces    //  C.v    Dmat->gmxv (v,p);    cmulv (-1.0*dt*dt*beta,p,n);    addv (rhs,p,n);        //  internal forces    internal_forces (lcid,p);    cmulv (-1.0*dt*dt*beta,p,n);    addv (rhs,p,n);        //  norm of the residual vector    norres = ss (rhs,rhs,n);    fprintf (stdout,"\n norm of residual vector  %le",norres);    if (norres>err){      //  norm of residual vector is greater than required tolerance      //  the Newton-Raphson method has to be used for reaching equilibrium      for (j=0;j<ni;j++){		//  solution of system of algebraic equations	Smat->solve_system (Gtm,p,rhs);		for (k=0;k<n;k++){	  lhs[k]+=p[k];	  a[k] = 1.0/dt/dt/beta*(lhs[k]-dd[k]);	  v[k] = vv[j] + gamma*dt*a[k];	}		      }                }                compute_req_val (lcid);    print_step(lcid, i, Mp->time, rhs);    print_flush();        //  time increment    Mp->time = Mp->timecon.newtime ();    dt = Mp->timecon.actualbacktimeincr ();    //  step number increment    i++;  }while(Mp->time<end_time);  print_close();    delete [] p;  delete [] dd;  delete [] vv;}/**   difference method for solution of forced dynamic problems   the method is explicit      @param lcid - load case id      JK, 26.7.2005*/void difference_method (long lcid){  long i,j,n;  double zero,time,dt,end_time;  double *a,*v,*p,*da,*dp,*lhs,*rhs,*fs;    //  number of degrees of freedom  n = Ndofm;  //  computer zero  zero=Mp->zero;    //  initial time  time=Mp->timecon.starttime ();  //  end time  end_time = Mp->timecon.endtime ();  //  first time increment  dt = Mp->timecon.initialtimeincr ();    //  nodal values - displacements at next step  //  (assigment of initial values)  lhs = Lsrs->give_lhs (lcid);  //  time derivatives of nodal values - velocities  //  (assigment of initial values)  v = Lsrs->give_tdlhs (lcid);  //  second time derivatives of nodal values - accelerations  a = Lsrs->give_stdlhs (lcid);  //  vector of dynamic load  rhs = Lsrs->give_rhs (2*lcid);  //  vector of static load  fs = Lsrs->give_rhs (2*lcid+1);    //  vector of displacements at previous step  dp = new double [n];  //  vector of displacements at actual step  da = new double [n];  //  auxiliary vector  p = new double [n];    //  assembling of static loads    nullv (fs+lcid*n, n);  Mb->lc[lcid].assemble (lcid,fs,1.0);    i=0;  print_init(-1, "wt");    print_step(lcid, i, Mp->time, rhs);  print_flush();      //  initial values  for (j=0;j<n;j++){    da[j] = lhs[j];    dp[j] = da[j] - dt*v[j];  }    //  loop over time interval  do{        //  stiffness matrix    stiffness_matrix (lcid);    //  mass matrix    mass_matrix (lcid);    //  damping matrix    damping_matrix ();        if (Mespr==1)  fprintf (stdout,"\n                                time  %f",Mp->time);        //  assembling of dynamic loads    nullv (rhs+lcid*n, n);    Mb->dlc[lcid].assemble (lcid,rhs,Ndofm,Mp->time);        //  total load    addv (rhs,fs,n);        //  K.da    Smat->gmxv (da,p);    cmulv (-1.0,p,n);    addv (rhs,p,n);        //  M.da.2/dt/dt    Mmat->gmxv (da,p);    cmulv (2.0/dt/dt,p,n);    addv (rhs,p,n);        //  M.dp/dt/dt    Mmat->gmxv (dp,p);    cmulv (-1.0/dt/dt,p,n);    addv (rhs,p,n);        //  C.vv    Dmat->gmxv (dp,p);    cmulv (1.0/2.0/dt,p,n);    addv (rhs,p,n);        //  dynamic stiffness matrix    //  (stored in array for mass matrix)    //  M/dt/dt + C/2/dt    Mmat->scalgm (1.0/dt/dt);    Mmat->addgm (1.0/2.0/dt,*Dmat);        //  solution of system of algebraic equations    Mmat->solve_system (Gtm,lhs,rhs);        for (j=0;j<n;j++){      v[j]=(lhs[j]-dp[j])/2.0/dt;      a[j]=(lhs[j]-2.0*da[j]+dp[j])/dt/dt;            dp[j]=da[j];      da[j]=lhs[j];    }        //  time increment    Mp->time = Mp->timecon.newtime ();    dt = Mp->timecon.actualbacktimeincr ();    i++;    compute_req_val (lcid);    print_step(lcid, i, Mp->time, rhs);    print_flush();      }while(Mp->time<end_time);  print_close();    delete [] da;  delete [] dp;  delete [] p;}/**   function solves system of ordinary differential equations of second order   such equations are used e.g. in dynamics   function is intended for molecular dynamics      @param lcid - load case id      JK, 24.7.2005*/void verlet_method (long lcid){  long i,n,ni;  double mm,zero,dt,end_time;  double *m,*dp,*da,*dn,*fp,*fi;    //  number of rows of the matrix  n = Ndofm;  //  number of iterations  ni = 0;  //  computer zero  zero = Mp->zero;    //  vector of displacements at previous step  dp = new double [n];  //  vector of displacements at new step  dn = new double [n];  //  vector of displacements at actual step  da = Lsrs->give_lhs (lcid);  //  vector of prescribed forces  fp = Lsrs->give_rhs (lcid);  //  vector of internal forces  fi = new double [n];  //  vector of reciprocal values of weights  m = new double [n];    //  initial time  Mp->time=Mp->timecon.starttime ();  //  end time  end_time = Mp->timecon.endtime ();    //  extraction of weights  for (i=0;i<n;i++){    mm=Mmat->give_entry (i,i);    if (mm<zero){    }    else{      m[i]=1.0/mm;    }  }      //  first step  //  prescribed forces  mefel_right_hand_side (i,fp);    //  internal forces  internal_forces (lcid,fi);    for (i=0;i<n;i++){    //  initial displacements    da[i]=Lsrs->lhsi[i];    //  initial velocities (temporarily stored in vector dn)    dn[i]=Lsrs->tdlhsi[i];    //  computation of vector of displacements at time t_init - dt    dp[i]=da[i]-dt*dn[i]+dt*dt/2.0*m[i]*(fp[i]+fi[i]);  }      print_init(-1, "wt");  //print_step(lcid, i, Mp->time, f);  print_flush();      do{    fprintf (stdout,"\n time %e",Mp->time);        //  prescribed forces    mefel_right_hand_side (i,fp);        //  internal forces    internal_forces (lcid,fi);        for (i=0;i<n;i++){      dn[i]=2.0*da[i]-dp[i]+dt*dt*m[i]*(fi[i]+fp[i]);      dp[i]=da[i];      da[i]=dn[i];    }            //print_step(lcid, i, Mp->time, f);    print_flush();        //  time increment    Mp->time = Mp->timecon.newtime ();    ni++;              }while(Mp->time<end_time);    print_close ();}/**   function solves seismic analysis using response spectrum      @param lcid - load case id      JK, 20.8.2005*/void response_spectrum_method (long lcid){  long i,j,n,m;  double coeff,per;  double *v,*auxv;    //  number of DOFs  n=Ndofm;  //  number of eigenvectors used in analysis  m=Mp->eigsol.neigv;    //  computation of eigenvalues and eigenmodes  solve_eigen_dynamics (Lsrs->lhs+n,Lsrs->w);    v = new double [n];  auxv = new double [n];    nullv (Lsrs->lhs,n);    for (i=0;i<m;i++){    //  period (computed from circular frequency)    per=2.0*3.14159265358979/sqrt(Lsrs->w[i]);        nullv (v,n);        //  vector of directions multiplied by response spectrum values    Mb->dlc[0].stool.assemble (v,per);        //  mass matrix multiplication    Mmat->gmxv (v,auxv);        //  dot product with eigenmode    coeff = ss (auxv,Lsrs->lhs+(i+1)*n,n)/(Lsrs->w[i]);        //fprintf (Out,"\n response spectrum - circ. frequency  %le   period %le     contribution to the %ld-th mode    %le",Lsrs->w[i],per,i,coeff);    for (j=0;j<n;j++){      Lsrs->lhs[j]-=coeff*Lsrs->lhs[(i+1)*n+j];    }      }      for (j=0;j<n;j++){    Lsrs->lhs[j]=Lsrs->lhs[n+j];  }    /*  fprintf (Out,"\n\n\n displacements");  for (i=0;i<n;i++){    fprintf (Out,"\n %5ld   %le",i,Lsrs->lhs[i]);  }  */    compute_ipstresses (0);    /*  long ipp;  fprintf (Out,"\n\n");  for (i=0;i<Mt->ne;i++){    ipp=Mt->elements[i].ipp[0][0];    fprintf (Out,"\n %le %le %le",Mm->ip[ipp].stress[0],Mm->ip[ipp].stress[1],Mm->ip[ipp].stress[2]);    ipp++;    fprintf (Out,"     %le %le %le",Mm->ip[ipp].stress[0],Mm->ip[ipp].stress[1],Mm->ip[ipp].stress[2]);  }  */  delete [] auxv;  delete [] v;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -