コード例 #1
0
  NumProcFluxError ( shared_ptr<PDE>  apde, const Flags & flags) : NumProc(apde) {

    fes    = GetPDE()->GetFESpace(flags.GetStringFlag("fespace",NULL));
    ext    = GetPDE()->GetFESpace(flags.GetStringFlag("extensionspace",NULL));
    hdivip = GetPDE()->GetBilinearForm(flags.GetStringFlag("hdivproduct",NULL));
    q      = GetPDE()->GetGridFunction(flags.GetStringFlag("discreteq",NULL));
    Q      = GetPDE()->GetGridFunction(flags.GetStringFlag("exactq",NULL));
    err    = GetPDE()->GetGridFunction(flags.GetStringFlag("errorsquareq",NULL));
  }
コード例 #2
0
  void Do(LocalHeap & lh) {    
    // We proceed in three steps:
    // 1.  Compute the difference between Q and q
    // 2.  Compute the H(div) Schur complement 
    // 3.  Apply Schur complement to the difference


    // grid function with (interpolated) exact flux, grad(u) 
    BaseVector& vecQ = Q->GetVector();    
    // numerical flux q
    BaseVector& vecq = q->GetVector(); 
    // p.w. constant gridfunction to store element-wise error
    BaseVector& errvec = err->GetVector();   
    errvec.FV<double>() = 0.0;
    double sqer =0.0;   // this will contain the total error square
    
    for(int k=0; k<ma->GetNE(); k++)  {
      
      ElementId ei (VOL, k);
      double elndof = ext->GetFE(k,lh).GetNDof(); 
      Vector<SCAL> diff(elndof);           
      // dof nrs: global, global inner, local inner, local Schur
      Array<int>  Gn,     Ginn,         Linn,        Lsn;

      // compute the difference between Q and q
      ext->GetDofNrs(k,Gn);        // Global# of all dofs on element k
      diff = SCAL(0.0);
      for(int j=0; j<elndof; j++)
	diff[j] = vecQ.FV<SCAL>()[Gn[j]] - vecq.FV<SCAL>()[Gn[j]];
      
      // H(div) Gram matrix (given in two parts in pde file)
      Matrix<double> elmat(elndof), elmat2(elndof);
      elmat = 0.0; elmat2 = 0.0;
      hdivip->GetIntegrator(0)->
	CalcElementMatrix(ext->GetFE(ei,lh),ma->GetTrafo(ei,lh),elmat,lh);
      hdivip->GetIntegrator(1)->
	CalcElementMatrix(ext->GetFE(ei,lh),ma->GetTrafo(ei,lh),elmat2,lh);
      elmat += elmat2;
    
      // compute the H(div) Schur complement 
      ext->GetInnerDofNrs(k,Ginn); // Global# of inner dofs on element k
      for(int j=0; j<elndof; j++)
	if (Ginn.Contains( Gn[j] ))
	  Linn.Append(j);          // Local#  of inner dofs on element k
	else
	  Lsn.Append(j);           // Local#  of Schur dofs on element k

      int ielndof = Linn.Size();
      Matrix<double> elmati(ielndof),elmatiinv(ielndof);
      elmati = elmat.Rows(Linn).Cols(Linn);
      CalcInverse(elmati,elmatiinv);
            
      // apply Schur complement to the difference
      int selndof = elndof - ielndof;
      Vector<SCAL> diffs(selndof);
      Matrix<double> S(selndof), Asi(selndof,ielndof);
      diffs = diff(Lsn);

      //      S  =  A_ss  -  A_si  * inv(A_ii) *  A_is
      Asi = elmat.Rows(Lsn).Cols(Linn);
      S   = elmat.Rows(Lsn).Cols(Lsn);
      S  -= Asi  * elmatiinv * Trans(Asi);
      //      error  = (S * diffs, diffs)
      errvec.FVDouble()[k] = fabs(InnerProduct(diffs,  S * diffs));
      sqer += errvec.FVDouble()[k];
    }
    
    cout<<"Discrete H^(-1/2) norm of error in q = "<<sqrt(sqer)<<endl;
    
    // write file (don't know what the last argument of AddVariable 
    // does, but 6 seems to be the value everywhere! It seems to intializes 
    // an object  of class IM (important message).
    GetPDE()->AddVariable (string("fluxerr.")+GetName()+".value", sqrt(sqer), 6);  

  }
コード例 #3
0
ファイル: space.c プロジェクト: Ninals-GitHub/TRON
/*
 * Set value to a page directory entry 
 *	Note: No TLB purge/cache operations are performed here.
 */
Inline void SetPDE( const void* laddr, PDE pde_v )
{
	PDE* pde = GetPDE(laddr);
	*pde = pde_v;
}