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

📄 edsolver.cpp

📁 Finite element program for mechanical problem. It can solve various problem in solid problem
💻 CPP
字号:
#include <math.h>#include "edsolver.h"#include "global.h"#include "globmat.h"#include "mechprint.h"#include "elemswitch.h"#include "gmatrix.h"#include "eigsol.h"#include "vector.h"void solve_eigen_dynamics (double *x,double *w){  long i;    //  stiffness matrix  stiffness_matrix (0);  //  mass matrix  mass_matrix (0);    switch (Mp->eigsol.teigsol){  case inv_iteration:{    inverse_iteration (x,w);    break;  }  case subspace_it_jacobi:{    subspace_iter_jac (x,w);    break;  }  case subspace_it_gsortho:{    subspace_iter_ortho (x,w);    break;  }  default:{    fprintf (stderr,"\n\n unknown eigenvalue solver is required in");    fprintf (stderr,"\n function solve_eigen_dynamics (file %s, line %d).\n",__FILE__,__LINE__);  }  }    print_eigenvalues (w);  print_eigenvectors ();  //print_eigenvect_martin (Out);      print_init(-1, "wt");      for (i=0;i<Mp->eigsol.neigv;i++){    //  computes and prints required quantities    //compute_ipstrains (i);    //compute_ipstresses (i);    //compute_req_val (i);    //print_step(i, i+1, w[i], NULL);      }  print_close();  //Mm->allipstresses (0);    }/**   function computes the smallest eigenvalue and appropriate eigenvector   of the generalized problem Ax=wBx   the eigenvector of the smallest eigenvalue is stored in Lsrs in lhs   @param w - the smallest eigenvalue      3.11.2001*/void inverse_iteration (double *x,double *w){  long i,ni,n;  double nom,denom,zero,rho,prevrho,err,error;  double *p,*z;    //  maximum number of iterations  ni=Mp->eigsol.nies;  //  required error  err=Mp->eigsol.erres;  //  number of unknowns  n=Ndofm;  //  computer zero  zero=Mp->zero;    //Smat->tlinsol=Mp->tlinsol;  p = new double [n];  z = new double [n];  //x = Lsrs->give_lhs(0);    //  LDL decomposition of matrix A  //Sm_sky->ldl_sky (z,z,zero,2);    //  initial value of vector x  for (i=0;i<n;i++){    x[i]=1.0;  }  //  initial vector z  //massxvect (x,z);  Mmat->gmxv (x,z);  //  main iteration loop  for (i=0;i<ni;i++){    //  copy of vector z which will be overwriten in back substitution    copyv (z,p,n);    //  back substitution    //Sm_sky->ldl_sky (x,p,zero,3);    //Smat->solve_system (Gtm,x,p);    Mp->ssle.solve_system (Gtm,Smat,x,p,Out);        //  x.K.x    nom=ss(x,z,n);    //  new vector z    //massxvect (x,z);    Mmat->gmxv (x,z);    //  x.M.x    denom=ss(x,z,n);    rho=nom/denom;    denom=1.0/sqrt(denom);    //  normed vector z    cmulv (denom,z,n);    if (Mespr==1)  printf ("\n iterace %4ld     rho %e",i,rho);    if (i!=0){      error=(prevrho-rho)/prevrho;      if (error<err){	cmulv (denom,x,n);  break;      }    }    prevrho=rho;  }  Mp->eigsol.anies=i;  Mp->eigsol.aerres=error;  w[0]=rho;  delete [] z;  delete [] p;}/**   function computes eigenvalues and eigenvectors   subspace iteration with Gram-Schmidt orthonormalization is used      @param w - array containing eigenvalues      4.11.2001*/void subspace_iter_ortho (double *x,double *w){  long i,j,k,l,ii,ni,n,nv,nrv;  double err,error,maxerror,zero,nom,denom,alpha;  double *z,*p,*wo;    //  problem size  n=Ndofm;  //  maximum number of iterations  ni=Mp->eigsol.nies;  //  required error  err=Mp->eigsol.erres;  //  number of required eigenvectors and eigenvalues  nrv=Mp->eigsol.neigv;  //  number of vectors used for iteration process  nv=Mp->eigsol.nev;  //  computer zero  zero=Mp->zero;    //Smat->tlinsol=Mp->tlinsol;  //x=Lsrs->give_lhs(0);  z = new double [n];  p = new double [n];  wo = new double [nv];  //  LDL decomposition of matrix A  //Sm_sky->ldl_sky (z,z,zero,2);  //  initial value of vector x  for (i=0;i<nv*n;i++){    x[i]=1.0;  }      //  main iteration loop  for (i=0;i<ni;i++){    for (j=0;j<nv;j++){      //  right hand side vector      //massxvect (x+j*n,z);      Mmat->gmxv (x+j*n,z);      copyv (z,p,n);      //  back substitution      //Sm_sky->ldl_sky (x+j*n,z,zero,3);      //Smat->solve_system (Gtm,x+j*n,z);      Mp->ssle.solve_system (Gtm,Smat,x+j*n,z,Out);      //  Rayleigh' quotients      nom=ss(x+j*n,p,n);      //massxvect (x+j*n,z);      Mmat->gmxv (x+j*n,z);      denom=ss(x+j*n,z,n);      w[j]=nom/denom;    }        //  Gram-Schmidt orthonormalization    for (j=0;j<nv;j++){      //massxvect (x+j*n,z);      Mmat->gmxv (x+j*n,z);            for (k=0;k<j;k++){	alpha=ss(x+k*n,z,n);	for (l=0;l<n;l++){	  x[j*n+l]-=alpha*x[k*n+l];	}      }      //massxvect (x+j*n,z);      Mmat->gmxv (x+j*n,z);      alpha=ss(x+j*n,z,n);      alpha=1.0/sqrt(alpha);      cmulv (alpha,x+j*n,n);    }        //  convergence check    if (i!=0){      ii=0;  maxerror=0.0;      for (j=0;j<nrv;j++){	error=(wo[j]-w[j])/w[j];	if (error>maxerror)  maxerror=error;	if (error<err)  ii++;      }            if (Mespr==1)  printf ("\n iterace  %4ld    pocet doiterovanych tvaru %4ld  max. odchylka %e",i,ii,maxerror);      //if (Mespr==1)  printf ("\n iterace  %4ld    w[0] %30.20e",i,w[0]);            if (ii==nrv){	//  for fuzzy computation	//for (j=0;j<nrv;j++){	//max=0.0;	//for (k=0;k<n;k++){	//if (fabs(x[j*n+k])>max)  max = x[j*n+k];	//}	//if (max<0.0){	//for (k=0;k<n;k++){	//x[j*n+k]*=-1.0;	//}	//}	//}			//  modification for fuzzy computation	/*	for (j=0;j<nrv;j++){	  if (x[j*n]<0.0){	    for (k=0;k<n;k++){	      x[j*n+k]*=-1.0;	    }	  }	}	*/		break;      }    }        for (j=0;j<nv;j++){      wo[j]=w[j];    }  }  Mp->eigsol.anies=i;  Mp->eigsol.aerres=maxerror;    /*  //  kontrola  //  stiffness matrix  stiffness_matrix (0);  //  mass matrix  mass_matrix (0);    double *jk,*kj;  jk = new double [n];  kj = new double [n];  Smat->gmxv (x,jk);  Mmat->gmxv (x,kj);  cmulv(w[0],kj,n);    fprintf (Out,"\n\n kontrola jk a kj \n");  for (i=0;i<n;i++){    fprintf (Out,"\n %le %le  %le",jk[i],kj[i],jk[i]-kj[i]);  }  fprintf (Out,"\n\n konec kontroly\n");  */  delete [] z;  delete [] wo;  delete [] p;}/**   function is not ready for computation   initial vectors must be assembled      function computes eigenvalues and eigenvectors   subspace iteration with Jacobi method of rotations is used   @param w - array containing eigenvalues   4.11.2001*/void subspace_iter_jac (double *x,double *w){  long i,j,k,l,ii,ni,n,nv,nrv,nij,njacthr,stop,*ind;  double err,error,maxerror,zero,alpha;  double *z,*p,*wo,*redstiff,*redmass,*redeigv,*jacthr,*aux,*invec;    //  problem size  n=Ndofm;  //  maximum number of iterations  ni=Mp->eigsol.nies;  //  required error  err=Mp->eigsol.erres;  //  number of required eigenvectors and eigenvalues  nrv=Mp->eigsol.neigv;  //  number of vectors used for iteration process  nv=Mp->eigsol.nev;  //  maximum number of iterations in Jacobi method  nij=Mp->eigsol.nijmr;  //  number of thresholds in Jacobi' method  njacthr=Mp->eigsol.njacthr;  //  computer zero  zero=Mp->zero;    stop=0;  jacthr=Mp->eigsol.jacthr;  //x=Lsrs->give_lhs(0);  z = new double [n*nv];  p = new double [n*nv];  wo = new double [nv];  redstiff = new double [nv*nv];  redmass = new double [nv*nv];  redeigv = new double [nv*nv];  aux = new double [nv];  invec = new double [n];  ind = new long [n];  for (i=0;i<n;i++){    //invec[i]=Mm_sky->a[Mm_sky->adr[i]]/Sm_sky->a[Sm_sky->adr[i]];  }  for (i=0;i<n;i++){    alpha=invec[i];  k=i;    for (j=i+1;j<n;j++){      if (alpha<invec[j]){	alpha=invec[j];  k=j;      }    }    ind[i]=k;    alpha=invec[i];    invec[i]=invec[k];    invec[k]=alpha;  }    //  LDL decomposition of matrix A  //Sm_sky->ldl_sky (z,z,zero,2);  //Smat->solve_system (Gtm,z,z);  Mp->ssle.solve_system (Gtm,Smat,z,z,Out);  //  initial value of vector x  for (i=0;i<nv*n;i++){    x[i]=0.0;  }  for (i=0;i<n;i++){    x[i]=1.0;  }  for (i=1;i<nv;i++){    x[i*n+ind[i]]=1.0;  }  //  right hand side vector  for (j=0;j<nv;j++){    //massxvect (x+j*n,z+j*n);    Mmat->gmxv (x+j*n,z+j*n);  }    /*  fprintf (Out,"\n\n\n Matice hmotnosti");  for (i=0;i<n;i++){    fprintf (Out,"\n");    for (j=Mm_sky->adr[i];j<Mm_sky->adr[i+1];j++){      fprintf (Out," %lf",Mm_sky->a[j]);    }  }  fprintf (Out,"\n\n slozky soucinu M.x=z");  for (i=0;i<nv;i++){    fprintf (Out,"\n");    for (j=0;j<n;j++){      fprintf (Out," %lf",z[i*n+j]);    }  }  */  //  main iteration loop  for (i=0;i<ni;i++){        //  A.x_new = z = B.x_old => x_new    for (j=0;j<nv;j++){      //  backup of B.x_old (will be overwritten)      copyv (z+j*n,p+j*n,n);      //  back substitution - solution x_new      //Sm_sky->ldl_sky (x+j*n,z+j*n,zero,3);      //Smat->solve_system (Gtm,x+j*n,z+j*n);      Mp->ssle.solve_system (Gtm,Smat,x+j*n,z+j*n,Out);    }        /*    fprintf (Out,"\n\n slozky x");    for (long kk=0;kk<nv;kk++){      fprintf (Out,"\n");      for (j=0;j<n;j++){	fprintf (Out," %lf",x[kk*n+j]);      }    }    */    //  reduced stiffness matrix computaion    //  K_red = x.K.x = x.z    mtxmccr (x,p,redstiff,n,nv,nv);        //  new right hand side - z = B.x    for (j=0;j<nv;j++){      //massxvect (x+j*n,z+j*n);      Mmat->gmxv (x+j*n,z+j*n);    }        //  reduced mass matrix computation    //  M_red = x.M.x = x.z    mtxmccr (x,z,redmass,n,nv,nv);        /*    fprintf (Out,"\n\n\n iterace cislo %ld",i);    for (long kk=0;kk<nv;kk++){      fprintf (Out,"\n");      for (long jj=0;jj<nv;jj++){	fprintf (Out,"\n %4ld %4ld k %30.15lf     m %30.15lf",kk,jj,redstiff[kk*nv+jj],redmass[kk*nv+jj]);      }    }    */        //  solution of reduced system by Jacobi' method of rotations    gen_jacobi (redstiff,redmass,redeigv,w,nv,nij,jacthr,njacthr,zero);        /*    for (long kk=0;kk<nv;kk++){      fprintf (Out,"\n w %30.15lf",w[kk]);      for (long jj=0;jj<nv;jj++){	fprintf (Out,"\n %4ld %4ld x %30.15lf",kk,jj,redeigv[jj*nv+kk]);      }    }    */    //  updated right hand side - z = p.redeigv    for (j=0;j<n;j++){      for (k=0;k<nv;k++){	aux[k]=0.0;	for (l=0;l<nv;l++){	  aux[k]+=z[l*n+j]*redeigv[l*nv+k];	}      }      for (k=0;k<nv;k++){	z[k*n+j]=aux[k];      }    }                //  normalization process    double norm = sqrt(ss (z,z,n*nv));    cmulv (1.0/norm,z,n*nv);        //  convergence check    if (i!=0){      ii=0;  maxerror=0.0;      for (j=0;j<nrv;j++){	error=(wo[j]-w[j])/w[j];	if (error>maxerror)  maxerror=error;	if (error<err)  ii++;      }            if (Mespr==1)  fprintf (stdout,"\n iterace  %4ld    pocet doiterovanych tvaru %4ld  max. odchylka %e",i,ii,maxerror);      if (ii==nrv)  stop=1;    }        for (j=0;j<nv;j++){      wo[j]=w[j];    }        if (stop==1)  break;  }  Mp->eigsol.anies=i;  Mp->eigsol.aerres=maxerror;    delete [] z;}

⌨️ 快捷键说明

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