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

📄 matricecreuse.hpp

📁 FreeFem++可以生成高质量的有限元网格。可以用于流体力学
💻 HPP
📖 第 1 页 / 共 3 页
字号:
KN_<R> & operator/=(KN_<R> & x ,const MatriceProfile<R> & a) ;enum FactorizationType {    FactorizationNO=0,    FactorizationCholeski=1,    FactorizationCrout=2,    FactorizationLU=3};template <class R> class MatriceProfile:public MatriceCreuse<R> {public:  mutable R *L;  // lower   mutable R *U;  // upper  mutable R *D;  // diagonal   int *pL; // profile L   int *pU; // profile U   mutable  FactorizationType typefac;  FactorizationType typesolver;   ostream& dump (ostream&) const ;  MatriceProfile(const int  n,const R *a);    template<class FESpace>  MatriceProfile(const FESpace &,bool VF=false);  MatriceProfile(int NbOfDF,R* d,		 R* u, int * pu,		 R* l, int * pl,		 FactorizationType tf=FactorizationNO)     : MatriceCreuse<R>(NbOfDF),L(l),U(u),D(d),pL(pl),pU(pu),      typefac(tf),typesolver(FactorizationNO){}  const MatriceProfile t() const        {return MatriceProfile(this->n,D,L,pL,U,pU,typefac);}  const MatriceProfile lt() const          {return MatriceProfile(this->n,0,L,pL,0,0);}  const MatriceProfile l() const       {return MatriceProfile(this->n,0,0,0,L,pL);}  const MatriceProfile d() const        {return MatriceProfile(this->n,D,0,0,0,0);}  const MatriceProfile ld() const       {return MatriceProfile(this->n,D,0,0,L,pL);}  const MatriceProfile ldt() const      {return MatriceProfile(this->n,D,L,pL,0,0);}  const MatriceProfile du() const       {return MatriceProfile(this->n,D,U,pU,0,0);}  const MatriceProfile u() const        {return MatriceProfile(this->n,0,U,pU,0,0);}  const MatriceProfile ut() const              {return MatriceProfile(this->n,0,0,0,U,pU);}  void Solve(KN_<R> &x,const KN_<R> &b) const {    /*if (typefac==0)  code faux // FH   nov 2006      switch(typefac) 	{	FactorizationCholeski: cholesky() ; break;	FactorizationCrout:   crout(); break;	FactorizationLU:      LU(); break; 	}*/     if (&x != &b) x=b;x/=*this;}     int size() const ;  void  resize(int n,int m)  { AFAIRE("MatriceProfile::resize");}  // a faire ...  add march 2009  FH   ~MatriceProfile();  //  KN_<R>         operator* (const KN_<R> & ) const ;  void addMatMul(const KN_<R> &x,KN_<R> &ax) const;  void addMatTransMul(const KN_<R> &x,KN_<R> &ax) const     { this->t().addMatMul(x,ax);}  MatriceCreuse<R> & operator +=(MatriceElementaire<R> &);  void operator=(const R & v); // Mise a zero   void cholesky(double = EPSILON/8.) const ; //  void crout(double = EPSILON/8.) const ; //  void LU(double = EPSILON/8.) const ; //  R & diag(int i) { return D[i];}  R & operator()(int i,int j) { if(i!=j) ffassert(0); return D[i];} // a faire   R * pij(int i,int j) const { if(i!=j) ffassert(0); return &D[i];} // a faire  Modif FH 31102005  MatriceMorse<R> *toMatriceMorse(bool transpose=false,bool copy=false) const ;    template<class F> void map(const  F & f)  {    for(int i=0;i<this->n;++i)      D[i]=f(D[i]);    if (L)    for(int i=0;i<pL[this->n];++i)      L[i]=f(L[i]);    if (L && (L != U) )    for(int i=0;i<pL[this->m];++i)      U[i]=f(U[i]);  }    template<class RR> MatriceProfile(const MatriceProfile<RR> & A)    : MatriceCreuse<R>(A.n,A.m,0)  {        typefac=A.typefac;    pL=  docpy<int,int>(A.pL,this->n+1);    D = docpy<R,RR>(A.D,this->n);    if ( A.pL == A.pU ) pU=pL;    else pU=  docpy<int,int>(A.pU,this->m+1);          L= docpy<R,RR>(A.L,pL[this->n]);          if ( A.L == A.U ) U=L;    else  U= docpy<R,RR>(A.U,pU[this->m]);        }    bool addMatTo(R coef,std::map< pair<int,int>, R> &mij,bool trans=false,int ii00=0,int jj00=0,bool cnj=false);  // Add FH april 2005  R pscal(const KN_<R> & x,const KN_<R> & y); // produit scalaire    double psor(KN_<R> & x,const  KN_<R> & gmin,const  KN_<R> & gmax , double omega);  void setdiag(const KN_<R> & x) ;  void getdiag( KN_<R> & x) const ;    // end add  // Add FH oct 2005   int NbCoef() const ;   void setcoef(const KN_<R> & x);   void getcoef( KN_<R> & x) const ;  // end add    /*----------------------------------------------------------------    D[i] = A[ii]    L[k] = A[ij]  j < i avec:   pL[i]<= k < pL[i+1] et j = pL[i+1]-k    U[k] = A[ij]  i < j avec:   pU[j]<= k < pU[j+1] et i = pU[i+1]-k     remarque pL = pU generalement     si L = U => la matrice est symetrique     -------------------------------------------------------------------  */   private:   void operator=(const MatriceProfile & A);};template <class R> class MatriceMorse:public MatriceCreuse<R> {//  numebering  is no-symmetric//  the all line  i :  //     k=   lg[i] .. lg[i+1]+1//        j = cl[k]//        aij=a[k]// otherwise  symmetric  case// same but just the  LOWER part is store     (j <= i) // and aii exist always in symmetric case//  -----------------------------------------public:  int nbcoef;  bool symetrique;    R * a;  int * lg;    int * cl;  public: class VirtualSolver :public RefCounter {    friend class MatriceMorse;   virtual void Solver(const MatriceMorse<R> &a,KN_<R> &x,const KN_<R> &b) const  =0;};  MatriceMorse():MatriceCreuse<R>(0),nbcoef(0),symetrique(true),a(0),lg(0),cl(0),solver(0) {};  MatriceMorse(KNM_<R> & A, double tol) ;  MatriceMorse(const int  n,const R *a);//    :MatriceCreuse<R>(n),solver(0) {}  MatriceMorse(istream & f);  template<class FESpace>   explicit   MatriceMorse(const FESpace & Uh,bool sym,bool VF=false)    :MatriceCreuse<R>(Uh.NbOfDF),solver(0) {Build(Uh,Uh,sym,VF);}  template<class FESpace>   explicit   MatriceMorse(const FESpace & Uh,const FESpace & Vh,bool VF=false)    :MatriceCreuse<R>(Uh.NbOfDF,Vh.NbOfDF,0),solver(0)   {Build(Uh,Vh,false,VF);}  template<class FESpace>   explicit   MatriceMorse(const FESpace & Uh,const FESpace & Vh,               void (*build)(MatriceMorse *,const FESpace & Uh,const FESpace & Vh,void *data),void *data=0	       )    :MatriceCreuse<R>(Uh.NbOfDF,Vh.NbOfDF,0),solver(0)   {build(this,Uh,Vh,data);             }  MatriceMorse(int nn,int mm,int nbc,bool sym,R *aa,int *ll,int *cc,bool dd, const VirtualSolver * s=0,bool transpose=false )    :MatriceCreuse<R>(nn,mm,dd && !transpose),     nbcoef(nbc),     symetrique(sym), // transpose = true => dummy false (new matrix)     a(docpyornot(this->dummy,aa,nbc)),     lg(docpyornot(this->dummy,ll,nn+1)),     cl(docpyornot(this->dummy,cc,nbc)),     solver(s)  { if(transpose) dotransposition(); };  void Solve(KN_<R> &x,const KN_<R> &b) const;  int size() const ;  void addMatMul(const KN_<R> &x,KN_<R> &ax) const;  void addMatTransMul(const KN_<R> &x,KN_<R> &ax) const;  MatriceMorse & operator +=(MatriceElementaire<R> &);  void operator=(const R & v)     { for (int i=0;i< nbcoef;i++) a[i]=v;}  virtual ~MatriceMorse(){ if (!this->dummy) { delete [] a; delete [] cl;delete [] lg;}}  ostream&  dump(ostream & f) const ;  R * pij(int i,int j) const ;  R  operator()(int i,int j) const {R * p= pij(i,j) ;throwassert(p); return *p;}  R & operator()(int i,int j)  {R * p= pij(i,j) ;throwassert(p); return *p;}  R & diag(int i)  {R * p= pij(i,i) ;throwassert(p); return *p;}    void SetSolver(const VirtualSolver & s){solver=&s;}  void SetSolverMaster(const VirtualSolver * s){solver.master(s);}  bool sym() const {return symetrique;}  // Add FH april 2005  R pscal(const KN_<R> & x,const KN_<R> & y); // produit scalaire    double psor(KN_<R> & x,const  KN_<R> & gmin,const  KN_<R> & gmax , double omega);  void setdiag(const KN_<R> & x) ;  void getdiag( KN_<R> & x) const ;  // end add    // Add FH oct 2005   int NbCoef() const ;   void setcoef(const KN_<R> & x);   void getcoef( KN_<R> & x) const ;  // end addvoid  resize(int n,int m) ; // add march 2009 ...template<class K>  MatriceMorse(int nn,int mm, std::map< pair<int,int>, K> & m, bool sym);   template<class RB,class RAB> void  prod(const MatriceMorse<RB> & B, MatriceMorse<RAB> & AB);  MatriceMorse<R> *toMatriceMorse(bool transpose=false,bool copy=false) const {     return new MatriceMorse(this->n,this->m,nbcoef,symetrique,a,lg,cl,copy, solver,transpose);}  bool  addMatTo(R coef,std::map< pair<int,int>, R> &mij,bool trans=false,int ii00=0,int jj00=0,bool cnj=false);    template<class K>    MatriceMorse(const MatriceMorse<K> & );  private:  void dotransposition ()  ;  // do the transposition   CountPointer<const VirtualSolver> solver;    void operator=(const MatriceMorse & );  template<class FESpace>  void  Build(const FESpace & Uh,const FESpace & Vh,bool sym,bool VF=false);  };template<class R,class M,class P> int ConjuguedGradient(const M & A,const P & C,const KN_<R> &b,KN_<R> &x,const int nbitermax, double &eps,long kprint=1000000000){//  ConjuguedGradient lineare   A*x est appele avec des conditions au limites //  non-homogene puis homogene  pour calculer le gradient     if (verbosity>50)      kprint=2;   if (verbosity>99)  cout << A << endl;   throwassert(&x && &b && &A && &C);   typedef KN<R> Rn;   int n=b.N();      throwassert(n==x.N());   Rn g(n), h(n), Ah(n), & Cg(Ah);  // on utilise Ah pour stocke Cg     g = A*x;     double xx= real((x,conj(x)));   double epsold=eps;   g -= b;// g = Ax-b   Cg = C*g; // gradient preconditionne    h =-Cg;    double g2 = real((Cg,conj(g)));   if (g2 < 1e-30)     { if(verbosity>1)       cout << "GC  g^2 =" << g2 << " < 1.e-30  Nothing to do " << endl;     return 2;  }   double reps2 =eps >0 ?  eps*eps*g2 : -eps; // epsilon relatif    eps = reps2;   for (int iter=0;iter<=nbitermax;iter++)     {             Ah = A*h;       double hAh =real((h,conj(Ah)));      // if (Abs(hAh)<1e-30) ExecError("CG2: Matrix non defined, sorry ");       R ro =  - real((g,conj(h)))/ hAh; // ro optimal (produit scalaire usuel)       x += ro *h;       g += ro *Ah; // plus besoin de Ah, on utilise avec Cg optimisation       Cg = C*g;       double g2p=g2;        g2 = real((Cg,conj(g)));       if ( !(iter%kprint) && iter && (verbosity>3) )         cout << "CG:" <<iter <<  "  ro = " << ro << " ||g||^2 = " << g2 << endl;        if (g2 < reps2) {          if ( !iter && !xx && g2 && epsold >0 ) {               // change fo eps converge to fast due to the              // penalization of boundary condition.             eps =  epsold*epsold*g2;              if (verbosity>3 )             cout << "CG converge to fast (pb of BC)  restart: " << iter <<  "  ro = "                   << ro << " ||g||^2 = " << g2 << " <= " << reps2 << "  new eps2 =" <<  eps <<endl;               reps2=eps;           }          else           {            if (verbosity>1 )            cout << "CG converge: " << iter <<  "  ro = " << ro << " ||g||^2 = " << g2 << endl;            return 1;// ok           }          }       double gamma = g2/g2p;              h *= gamma;       h -= Cg;  //  h = -Cg * gamma* h            }   cout << " GC: method doesn't converge in " << nbitermax         <<  " iteration , xx= "  << xx<< endl;   return 0; }template<class R,class M,class P> int ConjuguedGradient2(const M & A,const P & C,KN_<R> &x,const KN_<R> &b,const int nbitermax, double &eps,long kprint=1000000000){//  ConjuguedGradient2 affine A*x = 0 est toujours appele avec les condition aux limites //  -------------   throwassert(&x  && &A && &C);   typedef KN<R> Rn;   int n=x.N();   if (verbosity>99) kprint=1;   R ro=1;   Rn g(n),h(n),Ah(n), & Cg(Ah);  // on utilise Ah pour stocke Cg     g = A*x;   g -= b;     Cg = C*g; // gradient preconditionne    h =-Cg;    R g2 = (Cg,g);   if (g2 < 1e-30)     { if(verbosity>1)       cout << "GC  g^2 =" << g2 << " < 1.e-30  Nothing to do " << endl;     return 2;  }   if (verbosity>5 )      cout << " 0 GC  g^2 =" << g2 << endl;   R reps2 =eps >0 ?  eps*eps*g2 : -eps; // epsilon relatif    eps = reps2;   for (int iter=0;iter<=nbitermax;iter++)     {        R rop = ro;        x += rop*h;      //   x+ rop*h  , g=Ax   (x old)       //       ((Ah = A*x - b) - g);       // Ah -= b;        //   Ax + rop*Ah = rop*Ah + g  =       // Ah -= g;         //   Ah*rop         Ah = A*x;       Ah -= b;        //   Ax + rop*Ah = rop*Ah + g  =       Ah -= g;         //   Ah*rop         R hAh =(h,Ah);       if (norm(hAh)<1e-60) ExecError("CG2: Matrix is not defined (/0), sorry ");       ro =  - (g,h)*rop/hAh ; // ro optimal (produit scalaire usuel)       x += (ro-rop) *h;       g += (ro/rop) *Ah; // plus besoin de Ah, on utilise avec Cg optimisation       Cg = C*g;       R g2p=g2;        g2 = (Cg,g);       if ( ( (iter%kprint) == kprint-1)  &&  verbosity >1 )         cout << "CG:" <<iter <<  "  ro = " << ro << " ||g||^2 = " << g2 << endl;        if (g2 < reps2) {          if (verbosity )            cout << "CG converges " << iter <<  "  ro = " << ro << " ||g||^2 = " << g2 << endl;           return 1;// ok           }       R gamma = g2/g2p;              h *= gamma;       h -= Cg;  //  h = -Cg * gamma* h            }     if (verbosity )      cout << "CG does'nt converge: " << nbitermax <<   " ||g||^2 = " << g2 << " reps2= " << reps2 << endl;    return 0; }template <class R> 

⌨️ 快捷键说明

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