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

📄 epsolver.cpp

📁 Finite element program for mechanical problem. It can solve various problem in solid problem
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "epsolver.h"#include "global.h"#include "globmat.h"#include "mechprint.h"#include "loadcase.h"#include "dloadcase.h"#include "nssolver.h"#include "springel.h"#include "intpoints.h"#include "auxdatout.h"#include "vector.h"#include "matrix.h"#include "mathem.h"#include "gmatrix.h"#include "tensor.h"#include "vecttens.h"#include <math.h>#include <string.h>/**  This function controls run of earth pressure problem computation.*/void solve_epressure (){  long i;  double *rhs, *lhs;  for (i=0;i<Lsrs->nlc;i++){    rhs=Lsrs->give_rhs (i);    lhs=Lsrs->give_lhs (i);    //  load vectors    nullv (rhs+i*2*Ndofm, 2*Ndofm);    if (Mp->tepsol < epplast_sol)    {      Mb->lc[i].assemble (i,rhs+i*Ndofm,1.0);      Mb->dlc[i].assemble (rhs+i*Ndofm, lhs+i*Ndofm);    }    else    {      Mb->lc[i*2+0].assemble (i*2+0,rhs+(i*2+0)*Ndofm,1.0);      Mb->lc[i*2+1].assemble (i*2+1,rhs+(i*2+1)*Ndofm,1.0);    }    //  solver    epressure_solver (i);  }}/**  This function calls appropriate solver for the earth pressure problem  @param lcid - load case id.*/void epressure_solver (long lcid){  switch (Mp->tepsol){  case gep_sol:{    general_epressure (lcid);    break;  }  case gepvarsup_sol:{    general_epressure_varsup (lcid);    break;  }  case epplast_sol:{    femplast_epressure (lcid);    break;  }  default:{    fprintf (stderr,"\n\n unknown solver of nonlinear equation system is required");    fprintf (stderr,"\n in function nonlinear_solver (solver.cpp).\n");  }  }}/**  This function solves erath pressure problem using GLPT. Iteration of load is used.  @param lcid - load case id.*/void general_epressure (long lcid){  long i, j, n, ni;  double zero, err, norf, dl;  double *r,*f,*fi,*fb, *fc, lambda, rlam;  //  number of rows of the matrix  n = Ndofm;  //  maximum number of increments  ni = Mp->niep;  //  computer zero  zero = Mp->zero;  // required norm of unbalanced forces  err = Mp->errep;  // required dynamic load step  dl = Mp->stepep;  fb = new double [n];  fi = new double [n];  memset (fb,0,n*sizeof(double));  memset (fi,0,n*sizeof(double));  //  initialization phase  r  = Lsrs->give_lhs (lcid);  f  = Lsrs->give_rhs (2*lcid);  fc = Lsrs->give_rhs (2*lcid+1);  //***************************  //  main iteration loop  ****  //***************************  lambda = 0;  for (i=0;i<ni;i++){    print_init(i, "wt");    //  vectors of loading    nullv (f+lcid*n, n);    Mb->lc [lcid].assemble (0,f+2*lcid*n,1.0);    Mb->dlc[lcid].assemble (f+2*lcid*n, r+lcid*n);    //  backup of load vector    for (j=0;j<n;j++){      f[j] = (f[j] - fb[j]); // difference between new and backupped load vector       if (lambda < 1.0) // in case that the load is not fully applied        f[j] *= dl/(1.0-lambda);     // use only required increment      fc[j] = fb[j]; // store previously reached load      fb[j] += f[j]; // add new increment to previously reached load    }    lambda += dl;    if (lambda > 1.0)      lambda = 1.0;    //    memset (r,0,n*sizeof(double));    rlam = arclengthrv(lcid, 1.0, Mp->rlerrep);        if (fabs(rlam-1.0) > Mp->rlerrep)    {      fprintf(stderr, "\n\n Arclength could not reach required lambda\n");      fprintf(stderr, "(file %s, line %d)\n", __FILE__, __LINE__);      abort();    }    //  computation of internal forces, updating strains in the integration points//    internal_forces (lcid,fi);    print_step(lcid, i+1, lambda, fb);    nullv (f+lcid*n, n);    Mb->lc [lcid].assemble (0,f+2*lcid*n,1.0);    Mb->dlc[lcid].assemble (f+2*lcid*n, r+lcid*n);    for (j = 0; j < n; j++)      fi[j] = f[j] - fb[j];    norf = ss(fi, fi, n);    norf /= ss(f, f, n);    fprintf (stdout, "\n\n MAIN ITERATION LOOP : NORF=%e, lambda = %e\n", norf, lambda);    fprintf (stdout, "********************************************\n\n");    if ((norf < err) && (lambda == 1.0))      break;    print_close();  }  print_close();  delete [] fi;  delete [] fb;}/**  This function solves erath pressure problem using GLPT. Temporary supports are used for  better algorithm convergence.  @param lcid - load case id.*/void general_epressure_varsup (long lcid){  long i, j, n, ni;  double zero, err, norf;  double *r,*rb,*f,*fi,*fb, lambda;  double **br;  //  number of rows of the matrix  n = Ndofm;  //  maximum number of increments  ni = Mp->niep;  //  computer zero  zero = Mp->zero;  // required norm of unbalanced forces  err = Mp->errep;  rb = new double [n];  fb = new double [n];  fi = new double [n];  br = new double*[Mt->nn];  memset (rb,0,n*sizeof(double));  memset (fb,0,n*sizeof(double));  memset (fi,0,n*sizeof(double));  memset (br,0,Mt->nn*sizeof(*br));  for (i = 0; i < Mt->nn; i++)    br[i] = new double[Gtm->give_ndofn(i)];  //  initialization phase  r  = Lsrs->give_lhs (lcid);  f  = Lsrs->give_rhs (lcid);  //***************************  //  main iteration loop  ****  //***************************  for (i=0;i<ni;i++)   {    print_init(i, "wt");    //  vectors of loading    nullv (f+lcid*n, n);    Mb->lc [lcid].assemble (0,f+lcid*n,1.0);    Mb->dlc[lcid].assemble (f+lcid*n, r+lcid*n);    //  backup of load vector    for (j=0;j<n;j++){      fb[j] = f[j];    }    memset (r,0,n*sizeof(double));    lambda = arclengthrv(lcid, 1.0, Mp->rlerrep);    //  computation of internal forces, updating strains in the integration points    internal_forces (lcid,fi);    for (j = 0; j < n; j++)      f[j] = fb[j] - fi[j];    print_step(lcid, i+1, lambda, fb);    norf = ss(f, f, n);    fprintf (stdout, "\n MAIN ITERATION LOOP : NORF=%e", norf);    if ((norf < err) && (i >= Mp->nselnodep))      break;    if (i < Mp->nselnodep)    {      // restore original support state      Gtm->restore_codnum();      fprintf(stdout, "\n removing support in the node number %ld", Mp->selnodep[i]+1);      for (j = 0; j <= i; j++)      {        // remove support in the x direction from the selected nodes depending current iteration step        Gtm->gnodes[Mp->selnodep[j]].cn[0] = 1;      }      // generation new code numbers      n = Ndofm = Gtm->gencodnum();      // backup of displacements in the nodes      for (j = 0; j < Mt->nn; j++)        noddispl(lcid, br[j], j);      //  initialization phase for next step      //  left and right hand sides should be deleted      delete Lsrs;      delete Smat;  // size of global matrix will grow -> we can delete it      Smat = NULL;      delete [] fi;      delete [] fb;      delete [] rb;      Lsrs = new lhsrhs;      Lsrs->alloc ();      rb = new double [n];      fb = new double [n];      fi = new double [n];      memset (rb,0,n*sizeof(double));      memset (fb,0,n*sizeof(double));      memset (fi,0,n*sizeof(double));      r  = Lsrs->give_lhs (lcid);      f  = Lsrs->give_rhs (lcid);      restore_displ(lcid, br);    }    print_close();  }  print_close();  delete [] fi;  delete [] fb; delete [] rb;  for (i = 0; i < Gtm->nn; i++)    delete [] br;  delete [] br;}/**  This function solves erath pressure problem using FEM plasticity models.   Iteration of rigid spring support is used. Spring supports are incrementally   removed during each itreation step. Removed supports are expected to be ordered  as last elements, each step is removed the last element and number of elements is   decremented. So the user should order removed spring elements so the first removed  spring element is the last element (element with the greatest number) and so on.  Newton-Raphson method is used for given plasticity problem solution. This solver supposes  the static load equal to dead weight of excaved soil is applied to the bottom of   excaved part of the soil body and this static load is decremented in the each step when   the spring support is removed.  @param lcid - load case id.*/void femplast_epressure (long lcid){  long i,j,idxp, idxs,ni, *nod, ndofn, *cnum;  double *rhs, *rb, *react, *fpb, *fsb, *forig, lambda;  vector ifor;  ivector cn;  vector sig;  matrix sigt(3,3);  double *p = new double[Mm->tnip];  double *porig = new double[Mm->tnip];  char fn[1001];  char fn2[1001];  FILE *femcad;  ni = Mp->niep+1;  //***************************  //  main iteration loop  ****  //***************************  rb    = new double[Ndofm];  fpb   = new double[Ndofm];  fsb   = new double[Ndofm];  forig = new double[Ndofm];  nod   = new long  [Mp->niep];  react = new double[Mp->niep];  cnum  = new long  [Mp->niep];   for (i=0;i<ni;i++)  {    print_init(i+1, "wt");    if (i < 1)      fprintf (stdout, "\n MAIN ITERATION LOOP : step %ld\n", i+1);    else      fprintf (stdout, "\n MAIN ITERATION LOOP : step %ld, elem. %ld was removed\n", i+1, Mt->ne+1);    fprintf(stdout, " ---------------------------------------\n\n");    rhs=Lsrs->give_rhs (lcid);    idxs = (lcid*2+1)*Ndofm;    idxp = (lcid*2+0)*Ndofm;    if (i == 0)    {      copyv (rhs+idxp, fpb, Ndofm);      copyv (rhs+idxs, fsb, Ndofm);      addv(rhs+idxp, fsb, Ndofm);      nullv (rhs+idxs, Ndofm);      nullv (forig, Ndofm);    }    if (i > 0)    {            nullv (rhs+idxp, Ndofm);      for (j = 0; j < Ndofm; j++)      {        if (i == 1)          rhs[idxp+j] = (Mp->loadcoef[i-1]-1.0)*fsb[j];        else          rhs[idxp+j] = (Mp->loadcoef[i-1]-Mp->loadcoef[i-2])*fsb[j];      }/*      if (cnum[i-1] > 0)	rhs[idxp+cnum[i-1]-1] += react[i-1];*/    }    lambda = newton_raphsonep(lcid, forig);//    nonlinear_solver (lcid);    for (j=0; j < Ndofm; j++)         forig[j] += lambda * (rhs+idxp)[j];        Mm->computenlstresses(0);    for (j=0; j<Mm->tnip; j++)    {      allocv(Mm->ip[j].ncompstr, sig);      Mm->givestress (0,j,sig);      vector_tensor (sig, sigt, Mm->ip[j].ssst, stress);      p[j] = first_invar (sigt)/3;      destrv(sig);    }    if (i == 0)      copyv(p, porig,Ndofm);    else    {      for (j=0; j<Mm->tnip; j++)      {        p[j] -= porig[j];            }      sprintf(fn,"%s%s.jk0", Mp->path, Mp->filename);      sprintf(fn2,"%s%s.jk0.%ld", Mp->path, Mp->filename,i);      femcad = fopen(fn, "at");      char dlcid[50];      sprintf(dlcid, "%ld", i+1);       write_elemscalar(femcad, p, "p", dlcid);      fclose(femcad);      rename (fn, fn2);    }	         if (i == Mp->niep)      break;    nod[i] = Gtm->gelements[Gtm->ne-1].nodes[0];    ndofn = Mt->give_ndofn(nod[i]);    allocv(ndofn, ifor);    allocv(ndofn, cn);    Spring->res_internal_forces (lcid, Mt->ne-1, ifor);    react[i] = ifor[0];    Mt->give_node_code_numbers (nod[i],cn.a);    cnum[i] = cn[0];    // removing currently last spring support element.    Mt->ne--;    Gtm->ne--;    destrv(ifor);    destrv(cn);    print_close();  }  print_close();  delete [] rb;  delete [] fpb;  delete [] fsb;  delete [] nod;  delete [] react;  delete [] cnum;}/**  This function extracts nodal displacements bckr to the displacement %vector of Lsrs.  @param lcid  - number of load case  @param bckr  - array with displacement in the each node  //  3.12.2002*/void restore_displ(long lcid, double **bckr){  long i, j, ii;  for (i = 0; i < Gtm->nn; i++)  {    for (j = 0; j < Gtm->gnodes[i].ndofn; j++)    {      ii=Gtm->gnodes[i].cn[j];      if (ii >  0)   Lsrs->lhs[lcid*Ndofm+ii-1] = bckr[i][j];    }  }}/**  This function solves system of nonlinear algebraic equations  by the arc-length method. This method was modified to stop iteration  on the given value rlambda of the lambda parameter. Rlambda value is reached with  required error rlerr. Only one right hand side vector is supported with respect  to nonlinearity and absence of superposition.  @param lcid    - load case id  @param rlambda - required value of lambda parameter  @param rlerr   - required error between lambda and rlambda  @retval The function returns reached lambda parameter.*/double arclengthrv (long lcid, double rlambda, double rlerr){  long i,j,k,n,ni,ini,stop,modif,li,newmesh, numr;  double a0,a1,a2,l1,l2,dl,dlmax,dlmin,psi,lambda,blambda,dlambda,ddlambda,norf,norfp,norv,norfa,zero,ierr;  double lambdao,ss1,ss2,ss3,ss4,ss5;  double *r,*ra,*ddr,*u,*v,*f,*fa,*fp,*fc,*fi;  long cn, ecn[6];  char file[255];  char *mode;//  FILE *gr;  FILE *grout;        //  number of rows of the matrix  n = Ndofm;  //  maximum number of increments  ni = Mp->nlman.nial;

⌨️ 快捷键说明

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