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

📄 nssolver.cpp

📁 Finite element program for mechanical problem. It can solve various problem in solid problem
💻 CPP
📖 第 1 页 / 共 4 页
字号:
double displ_controlrv (long lcid, double inilambda, double dmplambda, double rlambda, double errl, long incrdispl)/**  Function solves system of nonlinear algebraicequations by Newton-Raphson method solved system does not contain time variable.Displacement control is assumed and only required value of lambda is reached (initial lambda value is assumed for global Mp->lambda and rlambda is  ).@param lcid      - required load case id@param inilambda - initial value of lambda for displacements@param rlambda   - required value of lambda@param errl      - required error for reaching rlambda@incrdispl       - indicator for increasing Mp->lambda(1=yes/0=no)    9.11.2005    TKo.*/{  long i,j,k,n,ni,ini;  double lambda,blambda,dlambda,dlambdamin,zero,err,norf,norfa;  double *r,*rb,*dr,*f,*fi,*fb,*fc,*fp, *fir2;  //  number of rows of the matrix  n = Ndofm;  //  maximum number of increments  ni = Mp->nlman.ninr;  //  maximum number of iterations in one increment  ini = Mp->nlman.niilnr;  //  computer zero  zero = Mp->zero;  //  required error in inner loop  err = Mp->nlman.errnr;  //  increment size  dlambda=Mp->nlman.incrnr;  //  minimum increment size  dlambdamin=Mp->nlman.minincrnr;  rb = new double [n];  f  = new double [n];  fb = new double [n];  fi = new double [n];  fir2 = new double[n];  dr = new double [n];  memset (rb,0,n*sizeof(double));  memset (f,0,n*sizeof(double));  memset (fi,0,n*sizeof(double));  memset (dr,0,n*sizeof(double));    //  initialization phase  r  = Lsrs->give_lhs (lcid);  fp = Lsrs->give_rhs (lcid*2);  fc = Lsrs->give_rhs (lcid*2+1);  lambda=0.0;  Mp->lambda = inilambda;    // ***************************  //  main iteration loop  ****  // ***************************  print_init(-1, "wt");  print_step(lcid, 0, 0.0, f);  print_flush();  for (i=0;i<ni;i++){        // checking required value of lambda    if (fabs(lambda-rlambda) < errl)      break;    if ((lambda + dlambda) > rlambda)      dlambda = rlambda - lambda;    //  backup of left hand side vector    for (j=0;j<n;j++){      rb[j]=r[j];    }    //  backup of reached lambda parameter    blambda=lambda;    if (incrdispl)      Mp->lambda = inilambda+dmplambda*lambda;       fprintf (stdout,"\n increment %ld   lambda %e,    dlambda %e",i,lambda,dlambda);        //  vector of maximum load and vector of load increment    if (incrdispl)      Mp->lambda += dmplambda*dlambda;    internal_forces(lcid, fir2);    for (j=0;j<n;j++){      f[j]=fc[j]+lambda*fp[j];      fb[j]= f[j] + dlambda*fp[j] - fir2[j];    }        //  assembling of tangent stiffness matrix    if ((Mp->stmat==tangent_stiff) || (i == 0))      stiffness_matrix (lcid);        //  solution of K(r).v=F    //Smat->solve_system (Gtm,dr,fb);    Mp->ssle.solve_system (Gtm,Smat,dr,fb,Out);    for (j=0;j<n;j++){      r[j]+=dr[j];    }        //  computation of internal forces    internal_forces (lcid,fi);        //  vector of unbalanced forces    for (j=0;j<n;j++){      fb[j]=f[j]+dlambda*fp[j];    }    norfa=ss(fb,fb,n);    for (j=0;j<n;j++){      fb[j] -= fi[j];    }    //  norm of vector of unbalanced forces    norf=ss(fb,fb,n);    if (norfa != 0.0)      norf /= norfa;        if (norf<err){      lambda+=dlambda;      Mm->updateipval ();      compute_req_val (lcid);      print_step(lcid, i+1, lambda, f);      print_flush();      continue;    }        //  internal iteration loop    for (j=0;j<ini;j++){            //  solution of K(r).v=F      //Smat->solve_system (Gtm,dr,fb);      Mp->ssle.solve_system (Gtm,Smat,dr,fb,Out);      for (k=0;k<n;k++){	r[k]+=dr[k];      }            //  computation of internal forces      internal_forces (lcid,fi);            //  vector of unbalanced forces      for (k=0;k<n;k++){	fb[k]=f[k]+dlambda*fp[k]-fi[k];      }            //  norm of vector of unbalanced forces      norf=ss(fb,fb,n);      if (norfa != 0.0)        norf /= norfa;            fprintf (stdout,"\n increment %ld   inner loop j %ld     norf=%e  dlambda %e",i,j,norf,dlambda);            if (norf<err)  break;    }        if (j==ini || norf>err)    {      if (dlambda == dlambdamin)      {        if (Mespr==1)  fprintf (stdout,"\n increment cannot be decreased dlambda=%e    norf=%e",dlambda,norf);        break;      }      dlambda/=2.0;      if (dlambda<dlambdamin)  dlambda=dlambdamin;      if (Mespr==1)  fprintf (stdout,"\n increment must be modified (dlambda decrease) dlambda=%e    norf=%e",dlambda,norf);            for (j=0;j<n;j++)      	r[j]=rb[j];      lambda=blambda;         }    else    {      lambda+=dlambda;      Mm->updateipval ();      compute_req_val (lcid);      print_step(lcid, i+1, lambda, f);      print_flush();    }  }  print_close();    delete [] dr;  delete [] fi;  delete [] fb;  delete [] f;  return (lambda);}void newton_raphson_restart (long lcid)  //  function solves system of nonlinear algebraic  //  equations by Newton-Raphson method  //  solved system does not contain time variable  //  //  16.8.2001{  long i,j,k,n,ni,ini,nii;  double lambda,blambda,dlambda,dlambdamin,zero,err,norf,norfa;  double *r,*rb,*dr,*f,*fi,*fb,*fc,*fp;  //  number of rows of the matrix  n = Ndofm;  //  maximum number of increments  ni = Mp->nlman.ninr;  // number of initial increments  nii = Mp->nlman.nienr;  //  maximum number of iterations in one increment  ini = Mp->nlman.niilnr;  //  computer zero  zero = Mp->zero;  //  required error in inner loop  err = Mp->nlman.errnr;  //  increment size  dlambda=Mp->nlman.incrnr;  //  minimum increment size  dlambdamin=Mp->nlman.minincrnr;  rb = new double [n];  f  = new double [n];  fb = new double [n];  fi = new double [n];  dr = new double [n];  memset (rb,0,n*sizeof(double));  memset (f,0,n*sizeof(double));  memset (fi,0,n*sizeof(double));  memset (dr,0,n*sizeof(double));    //  initialization phase  r  = Lsrs->give_lhs (lcid);  fp = Lsrs->give_rhs (lcid*2);  fc = Lsrs->give_rhs (lcid*2+1);  lambda=0.0;  long ncompstr;  double tmp;  FILE *aux;  // if restart from backup file is required  if (Mp->nlman.hdbr)  {    aux = fopen (Mp->nlman.backupfname, "rt");    if (aux == NULL)    {      fprintf(stderr, "\n\nError - unable to open backup file %s\n", Mp->nlman.backupfname);      fprintf(stderr, "file %s, line %d\n", __FILE__, __LINE__);      fprintf(stderr, "Program will be terminated\n");      abort();    }    // searching required backup    fprintf(stdout, "\n");    for (k=0; k<Mp->nlman.hdbid; k++)    {      fprintf(stdout, "\r reading backup record %ld", k+1);      fflush(stdout);      mtsolver_restore(aux, r, fc, i, tmp, j, 39, 8);    }    fprintf(stdout, "\n backup time : %e\n", tmp);    if (j != Ndofm)    {      fprintf(stderr, "\n\nError - incorrect number of DOFs is stored in backup file\n");      fprintf(stderr, "file %s, line %d\n", __FILE__, __LINE__);    }/*  Begining of Hinkley modification*/    for (i=0; i<Mm->tnip; i++)    {      if (Mm->ip[i].ncompeqother >= 8)      {        ncompstr = Mm->ip[i].ncompstr;        for (j=0; j<ncompstr; j++)          Mm->ip[i].stress[j] = Mm->ip[i].eqother[ncompstr+j];      }    }  }  Mp->strcomp = 0;  internal_forces(lcid, fc);  for (i=0; i < Ndofm; i++)    fc[i] *= 1.0e+6;  Mp->strcomp = 1;/* End of Hinkley modification*/  // compute and print values initial values  compute_req_val (lcid);  print_init(-1, "wt");  print_step(lcid, 0, 0, fc);  print_flush();  //  assembling of tangent stiffness matrix  stiffness_matrix (lcid);  // norm of load vector  norfa=ss(fc,fc,n);  //  internal iteration loop  for (j=0;j<nii;j++)  {    //  computation of internal forces    internal_forces (lcid,fi);    //  vector of unbalanced forces    for (k=0;k<n;k++)      fb[k]=fc[k]-fi[k];    //  norm of vector of unbalanced forces    norf=ss(fb,fb,n);    norf /= norfa;        if (norf<err)    {      Mm->updateipval ();      compute_req_val (lcid);      print_step(lcid, j+1, -0.0000001, fc);      print_flush();      break;    }    //Smat->solve_system (Gtm,dr,fb);    Mp->ssle.solve_system (Gtm,Smat,dr,fb,Out);/*    double tmp1, tmp2, tmp3, tmp4;    long ncomp;    tmp1=tmp2=tmp3=tmp4=0.0;    fprintf(Out, "\n\n*Krok %ld\n", j);    fprintf(Out,"\n\nn\tfc\tfi\tfc-fi\tr\tr+dr\tddr\n");    for(k=0; k<n; k++)    {      tmp1+=fc[k]*fc[k];      tmp2+=fi[k]*fi[k];      tmp3+=r[k]*r[k];      r[k]+=dr[k];      tmp4+=r[k]*r[k];      if (k%100==0)        fprintf(Out, "%ld\t%e\t%e\t%e\t%e\t%e\t%e\n",k, tmp1, tmp2, tmp1-tmp2, tmp3, tmp4, tmp3-tmp4);    }    fprintf(Out, "%ld\t%e\t%e\t%e\t%e\t%e\t%e\n",k, tmp1, tmp2, tmp1-tmp2, tmp3, tmp4, tmp3-tmp4);    fprintf(Out,"\n\nIpp\t omega\n");       for (k=0; k < Mm->tnip; k++)    {      if (Mm->ip[k].ncompother > 8)      {        ncomp = 2*Mm->ip[k].ncompstr;        fprintf(Out, "%ld\t%e\t%e\n", k, Mm->ip[k].other[ncomp],Mm->ip[k].other[ncomp+1]);      }    }    fflush(Out);*/    for(k=0; k<n; k++)      r[k]+=dr[k];/*    swap_other();    compute_req_val (lcid);    print_step(lcid, j+1, j+1, fc);    print_flush();    swap_other();*/    fprintf (stdout,"\n Equilibrium interation loop j %ld     norf=%e", j, norf);  }  if ((nii > 0) && (norf > err))  {    fprintf(stdout, "\n Initial equilibrium could not be reached\n");    fprintf(stdout, " Program will be terminated\n");    print_close();    return;  }  else    fprintf(stdout, "\n\n Starting incremental loading . . .\n");  // ***************************  //  main iteration loop  ****  // ***************************  for (i=0;i<ni;i++){        //  backup of left hand side vector    for (j=0;j<n;j++){      rb[j]=r[j];    }    //  backup of reached lambda parameter    blambda=lambda;       fprintf (stdout,"\n increment %ld   lambda %e,    dlambda %e",i,lambda,dlambda);        //  vector of maximum load and vector of load increment    for (j=0;j<n;j++){      f[j]=fc[j]+lambda*fp[j];      fb[j]=dlambda*fp[j];    }        //  assembling of tangent stiffness matrix    if ((Mp->stmat==tangent_stiff) || (i == 0))      stiffness_matrix (lcid);    //  solution of K(r).v=F    //Smat->solve_system (Gtm,dr,fb);    Mp->ssle.solve_system (Gtm,Smat,dr,fb,Out);    for (j=0;j<n;j++){      r[j]+=dr[j];    }    //  computation of internal forces    internal_forces (lcid,fi);    //  vector of unbalanced forces    for (j=0;j<n;j++){      fb[j]=f[j]+dlambda*fp[j];    }    norfa=ss(fb,fb,n);    for (j=0;j<n;j++){      fb[j] -= fi[j];    }    //  norm of vector of unbalanced forces    norf=ss(fb,fb,n);    norf /= norfa;            //    fprintf (Out,"\n norf=%e",norf);    if (norf<err){      lambda+=dlambda;      Mm->updateipval ();      compute_req_val (lcid);      print_step(lcid, i+1, lambda, f);      print_flush();      continue;    }        //  internal iteration loop    for (j=0;j<ini;j++){            //  solution of K(r).v=F      //Smat->solve_system (Gtm,dr,fb);      Mp->ssle.solve_system (Gtm,Smat,dr,fb,Out);      for (k=0;k<n;k++){	r[k]+=dr[k];      }            //  computation of internal forces      internal_forces (lcid,fi);            //  vector of unbalanced forces      for (k=0;k<n;k++){	fb[k]=f[k]+dlambda*fp[k]-fi[k];      }            //  norm of vector of unbalanced forces      norf=ss(fb,fb,n);      norf /= norfa;            fprintf (stdout,"\n increment %ld   inner loop j %ld     norf=%e  dlambda %e",i,j,norf,dlambda);//      fprintf (Out,"\n j=%ld     norf=%e",j,norf);            if (norf<err)  break;    }        if (j==ini || norf>err){      dlambda/=2.0;      if (dlambda<dlambdamin)  dlambda=dlambdamin;      if (Mespr==1){	fprintf (stdout,"\n increment must be modified (dlambda decrease) dlambda=%e    norf=%e",dlambda,norf);//	fprintf (Out,"\n increment must be modified (dlambda decrease) dlambda=%e    norf=%e",dlambda,norf);      }            for (j=0;j<n;j++){      	r[j]=rb[j];      }      lambda=blambda;    }    else{      lambda+=dlambda;      Mm->updateipval ();      compute_req_val (lcid);      print_step(lcid, i+1, lambda, f);      print_flush();    }      }    delete [] dr;  delete [] fi;  delete [] fb;  delete [] f;  print_close();}void seldofinit (){  long i,j,k,l,ndofn;  double x1,x2,y1,y2,z1,z2,length;    switch (Mp->nlman.displnorm){  case alldofs:{  break; }  case seldofs:  case seldofscoord:{    for (i=0;i<Mp->nlman.nsdofal;i++){      j=Mp->nlman.seldofal[i];      Mp->nlman.seldofal[i]=Mt->give_dof (Mp->nlman.selnodal[i],j)-1;    }    break;  }  case selecnodes:{    Mp->nlman.nsdofal=0;    for (i=0;i<Mp->nlman.nsnal;i++){      Mp->nlman.nsdofal+=Mt->give_ndofn (Mp->nlman.selnodal[i]);    }    Mp->nlman.seldofal = new long [Mp->nlman.nsdofal];    k=0;    for (i=0;i<Mp->nlman.nsnal;i++){      ndofn=Mt->give_ndofn (Mp->nlman.selnodal[i]);      for (j=0;j<ndofn;j++){	l=Mt->give_dof (Mp->nlman.selnodal[i],j);	if (l>0){	  Mp->nlman.seldofal[k]=l-1;	  k++;	}      }    }    Mp->nlman.nsdofal=k;    break;  }  case nodesdistincr:{    Mp->nlman.nsdofal=0;    for (i=0;i<Mp->nlman.nsnal;i++){      Mp->nlman.nsdofal+=Mt->give_ndofn (Mp->nlman.selnodal[i]);    }    Mp->nlman.seldofal = new long [Mp->nlman.nsdofal];    k=0;    for (i=0;i<Mp->nlman.nsnal;i++){      ndofn=Mt->give_ndofn (Mp->nlman.selnodal[i]);      for (j=0;j<ndofn;j++){	Mp->nlman.seldofal[k]=Mt->give_dof (Mp->nlman.selnodal[i],j);	k++;      }    }    x1=Gtm->gnodes[Mp->nlman.selnodal[0]].x;    x2=Gtm->gnodes[Mp->nlman.selnodal[1]].x;    y1=Gtm->gnodes[Mp->nlman.selnodal[0]].y;    y2=Gtm->gnodes[Mp->nlman.selnodal[1]].y;    z1=Gtm->gnodes[Mp->nlman.selnodal[0]].z;    z2=Gtm->gnodes[Mp->nlman.selnodal[1]].z;    length=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));    Mp->nlman.nxal=(x2-x1)/length;  Mp->nlman.nyal=(y2-y1)/length;  Mp->nlman.nzal=(z2-z1)/length;    break;  }  default:{    fprintf (stderr,"\n\n unknown displacement norm is required in function seldofinit (%s, line %d)",__FILE__,__LINE__);  }  }}double displincr (double *displincr,long n){  long i;  double norm,u1,u2,v1,v2,w1,w2;    switch (Mp->nlman.displnorm){  case alldofs:{    norm = ss (displincr,displincr,n);    break;  }  case seldofs:  case seldofscoord:  case selecnodes:{    norm=0.0;    for (i=0;i<Mp->nlman.nsdofal;i++){      norm+=displincr[Mp->nlman.seldofal[i]]*displincr[Mp->nlman.seldofal[i]];    }    break;  }  case nodesdistincr:{    if (Mp->nlman.probdimal==2){      u1=0.0;  u2=0.0;  v1=0.0;  v2=0.0;      if (Mp->nlman.seldofal[0]>0)  u1=displincr[Mp->nlman.seldofal[0]-1];      if (Mp->nlman.seldofal[1]>0)  v1=displincr[Mp->nlman.seldofal[1]-1];      if (Mp->nlman.seldofal[2]>0)  u2=displincr[Mp->nlman.seldofal[2]-1];      if (Mp->nlman.seldofal[3]>0)  v2=displincr[Mp->nlman.seldofal[3]-1];            norm=(u2-u1)*Mp->nlman.nxal + (v2-v1)*Mp->nlman.nyal;    }    if (Mp->nlman.probdimal==3){      u1=0.0;  u2=0.0;  v1=0.0;  v2=0.0;  w1=0.0;  w2=0.0;      if (Mp->nlman.seldofal[0]>0)  u1=displincr[Mp->nlman.seldofal[0]-1];      if (Mp->nlman.seldofal[1]>0)  v1=displincr[Mp->nlman.seldofal[1]-1];      if (Mp->nlman.seldofal[2]>0)  w1=displincr[Mp->nlman.seldofal[2]-1];      if (Mp->nlman.seldofal[3]>0)  u2=displincr[Mp->nlman.seldofal[3]-1];      if (Mp->nlman.seldofal[4]>0)  v2=displincr[Mp->nlman.seldofal[4]-1];      if (Mp->nlman.seldofal[5]>0)  w2=displincr[Mp->nlman.seldofal[5]-1];            norm=(u2-u1)*Mp->nlman.nxal + (v2-v1)*Mp->nlman.nyal + (w2-w1)*Mp->nlman.nzal;    }    break;  }  default:{    fprintf (stderr,"\n\n unknown norm of displacement increment is required in function");    fprintf (stderr,"\n displincr (%s, line %d).\n",__FILE__,__LINE__);  }  }  norm=sqrt (norm);  return norm;}void quadeqcoeff (double *ddr,double *v,long n,double ddlambda,double psi,double norfp,double dl,

⌨️ 快捷键说明

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