Example #1
0
  void GradGrad<D>::T_CalcElementMatrix (const FiniteElement & base_fel,
			    const ElementTransformation & eltrans, 
			    FlatMatrix<SCAL> elmat,
			    LocalHeap & lh) const {
    
    const CompoundFiniteElement &  cfel  // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    const ScalarFiniteElement<D> & fel_u =  // u space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd1()]);
    const ScalarFiniteElement<D> & fel_e =  // e space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd2()]);

    elmat = SCAL(0.0);

    // u dofs [ru.First() : ru.Next()-1],  e dofs [re.First() : re.Next()-1]
    IntRange ru = cfel.GetRange(GetInd1()); 
    IntRange re = cfel.GetRange(GetInd2()); 
    int ndofe = re.Size();
    int ndofu = ru.Size();

    FlatMatrixFixWidth<D> dum(ndofu,lh); // to store grad(u-basis)  
    FlatMatrixFixWidth<D> dem(ndofe,lh); // to store grad(e-basis)

    ELEMENT_TYPE eltype                  // get the type of element: 
      = fel_u.ElementType();             // ET_TRIG in 2d, ET_TET in 3d.

    const IntegrationRule &              // Note: p = fel_u.Order()-1
      ir = SelectIntegrationRule(eltype, fel_u.Order()+fel_e.Order()-2);
    
    FlatMatrix<SCAL> submat(ndofe,ndofu,lh);
    submat = 0.0;

    for(int k=0; k<ir.GetNIP(); k++) {	
      
      MappedIntegrationPoint<D,D> mip (ir[k],eltrans);
      // set grad(u-basis) and grad(e-basis) at mapped pts in dum and dem.
      fel_u.CalcMappedDShape( mip, dum ); 
      fel_e.CalcMappedDShape( mip, dem );

      // evaluate coefficient
      SCAL fac = coeff_a -> T_Evaluate<SCAL>(mip);
      fac *= mip.GetWeight() ;
      
      //             [ndofe x D] * [D x ndofu]
      submat +=  fac *  dem     * Trans(dum) ;
    }
    
    elmat.Rows(re).Cols(ru) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(ru).Cols(re) += Conj(Trans(submat));
    
  }
Example #2
0
  void FluxFluxBoundary<D> ::
  T_CalcElementMatrix (const FiniteElement & base_fel,
		       const ElementTransformation & eltrans, 
		       FlatMatrix<SCAL> elmat,
		       LocalHeap & lh) const {

    const CompoundFiniteElement &  cfel      // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);
    
    // This FE is already multiplied by normal:
    const HDivNormalFiniteElement<D-1> & fel_q = // q.n space
      dynamic_cast<const HDivNormalFiniteElement<D-1>&> (cfel[GetInd1()]);

    const HDivNormalFiniteElement<D-1> & fel_r = // r.n space
      dynamic_cast<const HDivNormalFiniteElement<D-1>&> (cfel[GetInd2()]);
    
    elmat = SCAL(0.0);

    IntRange rq = cfel.GetRange(GetInd1());
    IntRange rr = cfel.GetRange(GetInd2());
    int ndofq = rq.Size();
    int ndofr = rr.Size();
 
    FlatMatrix<SCAL> submat(ndofr, ndofq, lh);  
    submat = SCAL(0.0);
    
    FlatVector<> qshape(fel_q.GetNDof(), lh);
    FlatVector<> rshape(fel_r.GetNDof(), lh);

    const IntegrationRule ir(fel_q.ElementType(), 
			     fel_q.Order() + fel_r.Order());

    for (int i = 0 ; i < ir.GetNIP(); i++) {

      MappedIntegrationPoint<D-1,D> mip(ir[i], eltrans);

      SCAL cc = coeff_c -> T_Evaluate<SCAL>(mip);

      fel_r.CalcShape (ir[i], rshape);
      fel_q.CalcShape (ir[i], qshape);
      // mapped q.n-shape is simply reference q.n-shape / measure
      qshape *= 1.0/mip.GetMeasure();
      rshape *= 1.0/mip.GetMeasure();
      //                              [ndofr x 1]  [1 x ndofq]
      submat += (cc*mip.GetWeight()) * rshape  * Trans(qshape);
    }       

    elmat.Rows(rr).Cols(rq) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(rq).Cols(rr) += Conj(Trans(submat));
  }
Example #3
0
  void DGFiniteElement<D>:: 
  CalcGradientMatrix (FlatMatrix<> gmat) const
  {
    IntegrationRule ir (this->ElementType(), 2*order);

    Vector<> shape(ndof);
    MatrixFixWidth<D> dshape(ndof);
    Vector<> norms(ndof);
    
    gmat = 0.0;
    norms = 0.0;
    for (int i = 0; i < ir.Size(); i++)
      {
	this -> CalcShape (ir[i], shape);
	this -> CalcDShape (ir[i], dshape);
        
        for (int j = 0; j < ndof; j++)
          for (int k = 0; k < ndof; k++)
            for (int l = 0; l < D; l++)
              gmat(k*D+l, j) += ir[i].Weight() * dshape(j,l) * shape(k);

	for (int j = 0; j < norms.Size(); j++)
	  norms(j) += ir[i].Weight() * sqr (shape(j));
      }
    for (int j = 0; j < ndof; j++)
      gmat.Rows(D*j, D*(j+1)) /= norms(j);
  }
Example #4
0
  void TraceTraceBoundary<D> ::
  T_CalcElementMatrix (const FiniteElement & base_fel,
		       const ElementTransformation & eltrans, 
		       FlatMatrix<SCAL> elmat,
		       LocalHeap & lh) const {

    const CompoundFiniteElement &  cfel      // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    // get surface elements
    const ScalarFiniteElement<D-1> & fel_u = // u space
      dynamic_cast<const ScalarFiniteElement<D-1>&> (cfel[GetInd1()]);
    const ScalarFiniteElement<D-1> & fel_e = // u space
      dynamic_cast<const ScalarFiniteElement<D-1>&> (cfel[GetInd2()]);

    elmat = SCAL(0.0);

    IntRange ru = cfel.GetRange(GetInd1());
    IntRange re = cfel.GetRange(GetInd2());
    int ndofu = ru.Size();
    int ndofe = re.Size();
 
    FlatMatrix<SCAL> submat(ndofe, ndofu, lh);  
    submat = SCAL(0.0);
    
    FlatVector<> ushape(fel_u.GetNDof(), lh);
    FlatVector<> eshape(fel_e.GetNDof(), lh);

    const IntegrationRule ir(fel_u.ElementType(), 
			     fel_u.Order() + fel_e.Order());

    for (int i = 0 ; i < ir.GetNIP(); i++) {

      MappedIntegrationPoint<D-1,D> mip(ir[i], eltrans);

      SCAL cc = coeff_c -> T_Evaluate<SCAL>(mip);

      fel_u.CalcShape (ir[i], ushape);
      fel_e.CalcShape (ir[i], eshape);
      //                             [ndofe x 1]  [1 x ndofu]
      submat += (cc*mip.GetWeight()) * eshape  * Trans(ushape);
    }       

    elmat.Rows(re).Cols(ru) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(ru).Cols(re) += Conj(Trans(submat));
  }
Example #5
0
  void EyeEye<D>::T_CalcElementMatrix (const FiniteElement & base_fel,
		     const ElementTransformation & eltrans, 
		     FlatMatrix<SCAL> elmat,
		     LocalHeap & lh) const {
   

    const CompoundFiniteElement &  cfel  // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);
    const ScalarFiniteElement<D> & fel_u =  // u space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd1()]);
    const ScalarFiniteElement<D> & fel_e =  // e space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd2()]);

    elmat = SCAL(0.0);

    IntRange ru = cfel.GetRange(GetInd1()); 
    IntRange re = cfel.GetRange(GetInd2()); 
    int ndofe = re.Size();
    int ndofu = ru.Size();

    Vector<> ushape(ndofu);
    Vector<> eshape(ndofe);

    ELEMENT_TYPE eltype = fel_u.ElementType();      
    const IntegrationRule &         
      ir = SelectIntegrationRule(eltype, fel_u.Order()+fel_e.Order());
    FlatMatrix<SCAL> submat(ndofe,ndofu,lh);
    submat = SCAL(0.0);

    for(int k=0; k<ir.GetNIP(); k++) {	
      
      MappedIntegrationPoint<D,D> mip (ir[k],eltrans);

      fel_u.CalcShape( ir[k], ushape ); 
      fel_e.CalcShape( ir[k], eshape );

      SCAL fac = (coeff_a -> T_Evaluate<SCAL>(mip))* mip.GetWeight() ;
      //               [ndofe x D] * [D x ndofu]
      submat +=  fac *  eshape     * Trans(ushape) ;
    }
    
    elmat.Rows(re).Cols(ru) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(ru).Cols(re) += Conj(Trans(submat));
  }
Example #6
0
  void CalcSchurComplement (const FlatMatrix<double> a, 
			    FlatMatrix<double> s,
			    const BitArray & used,
			    LocalHeap & lh)
  {
    if (s.Height() == 0) return;
    if (s.Height() == a.Height())
      {
        s = a;
        return;
      }

    HeapReset hr(lh);

    int n = a.Height();
    Array<int> used_dofs(n, lh);
    Array<int> unused_dofs(n, lh);
    used_dofs.SetSize(0);
    unused_dofs.SetSize(0);
    for (int i = 0; i < n; i++)
      if (used[i])
        used_dofs.Append(i);
      else
        unused_dofs.Append(i);

    s = a.Rows(used_dofs).Cols(used_dofs);
    FlatMatrix<> b1 = a.Rows(unused_dofs).Cols(used_dofs) | lh;
    FlatMatrix<> b2 = a.Rows(used_dofs).Cols(unused_dofs) | lh;
    FlatMatrix<> c = a.Rows(unused_dofs).Cols(unused_dofs) | lh;
    FlatMatrix<> hb1 (b1.Height(), b1.Width(), lh);

    if (n > 10)
      {
        LapackInverse (c);
        hb1 = c * b1 | Lapack;
        s -= b2 * hb1 | Lapack;
      }
    else
      {
        CalcInverse (c);
        hb1 = c * b1;
        s -= b2 * hb1;
      }
  }
Example #7
0
  void FluxTrace<D>::T_CalcElementMatrix (const FiniteElement & base_fel,
			    const ElementTransformation & eltrans, 
			    FlatMatrix<SCAL> elmat,
			    LocalHeap & lh) const {
    
    const CompoundFiniteElement &  cfel  // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    const HDivFiniteElement<D>   & fel_q =  // q space
      dynamic_cast<const HDivFiniteElement<D>&  > (cfel[GetInd1()]);
    const ScalarFiniteElement<D> & fel_e =  // e space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd2()]);

    elmat = SCAL(0.0);

    IntRange rq = cfel.GetRange(GetInd1()); 
    IntRange re = cfel.GetRange(GetInd2());
    int ndofq = rq.Size();
    int ndofe = re.Size();

    FlatMatrix<SCAL> submat(ndofe,ndofq,lh);
    FlatMatrixFixWidth<D> shapeq(ndofq,lh);  // q-basis (vec) values
    FlatVector<>          shapee(ndofe,lh);  // e-basis basis 
    
    ELEMENT_TYPE eltype                      // get the type of element: 
      = fel_q.ElementType();                 // ET_TRIG in 2d, ET_TET in 3d.

    // transform facet integration points to volume integration points
    Facet2ElementTrafo transform(eltype);

    int nfa = ElementTopology::GetNFacets(eltype); /* nfa = number of facets
						      of an element */    
    submat = 0.0;

    for(int k = 0; k<nfa; k++) {
      
      // type of geometry of k-th facet
      ELEMENT_TYPE eltype_facet = ElementTopology::GetFacetType(eltype, k); 
      
      const IntegrationRule & facet_ir =
	SelectIntegrationRule (eltype_facet, fel_q.Order()+fel_e.Order()); 

      // reference element normal vector
      FlatVec<D> normal_ref = ElementTopology::GetNormals(eltype) [k]; 

      for (int l = 0; l < facet_ir.GetNIP(); l++) {

	// map 1D facet points to volume integration points
	IntegrationPoint volume_ip = transform(k, facet_ir[l]);
	MappedIntegrationPoint<D,D> mip (volume_ip, eltrans);
	
	// compute normal on physcial element
	Mat<D> inv_jac = mip.GetJacobianInverse();
	double det = mip.GetJacobiDet();
	Vec<D> normal = fabs(det) * Trans(inv_jac) * normal_ref;       
	double len = L2Norm(normal);
	normal /= len;
	double weight = facet_ir[l].Weight()*len;
	
	// mapped H(div) basis fn values and DG fn (no need to map) values
	fel_q.CalcMappedShape(mip,shapeq); 
	fel_e.CalcShape(volume_ip,shapee); 
	
	// evaluate coefficient
	SCAL dd = coeff_d -> T_Evaluate<SCAL>(mip);

	//                   [ndofe x 1]      [ndofq x D] *  [D x 1] 	
	submat += (dd*weight) * shapee * Trans( shapeq    *  normal ) ;
      }
    }
    elmat.Rows(re).Cols(rq) += submat;
    elmat.Rows(rq).Cols(re) += Conj(Trans(submat));
  }
Example #8
0
  void RobinVolume<D> ::
  T_CalcElementMatrix (const FiniteElement & base_fel,
                       const ElementTransformation & eltrans, 
                       FlatMatrix<SCAL> elmat,
                       LocalHeap & lh) const {
    
    ELEMENT_TYPE eltype                
      = base_fel.ElementType();        
    const CompoundFiniteElement &  cfel     // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    // note how we do NOT refer to D-1 elements here:
    const ScalarFiniteElement<D> & fel_u =  // u space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd1()]);
    const ScalarFiniteElement<D> & fel_e =  // e space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd2()]);
    
    elmat = SCAL(0);
    IntRange ru = cfel.GetRange(GetInd1());
    IntRange re = cfel.GetRange(GetInd2());
    int ndofe = re.Size();
    int ndofu = ru.Size();
            
    FlatVector<> ushape(fel_u.GetNDof(), lh);
    FlatVector<> eshape(fel_e.GetNDof(), lh);
    FlatMatrix<SCAL> submat(ndofe,ndofu,lh);
    submat = SCAL(0);

    int nfacet = ElementTopology::GetNFacets(eltype);
    Facet2ElementTrafo transform(eltype); 
    FlatVector< Vec<D> > normals = ElementTopology::GetNormals<D>(eltype);    
    const MeshAccess & ma = *(const MeshAccess*)eltrans.GetMesh();

    Array<int> fnums, sels;
    ma.GetElFacets (eltrans.GetElementNr(), fnums);
      
    for (int k = 0; k < nfacet; k++)    {

      ma.GetFacetSurfaceElements (fnums[k], sels);

      // if interior element, then do nothing:
      if (sels.Size() == 0) continue; 

      // else: 

      Vec<D> normal_ref = normals[k];

      ELEMENT_TYPE etfacet=ElementTopology::GetFacetType(eltype, k);

      IntegrationRule ir_facet(etfacet, fel_e.Order()+fel_u.Order());
      
      // map the facet integration points to volume reference elt ipts
      IntegrationRule & ir_facet_vol = transform(k, ir_facet, lh);
      // ... and further to the physical element 
      MappedIntegrationRule<D,D> mir(ir_facet_vol, eltrans, lh);
        
      for (int i = 0 ; i < ir_facet_vol.GetNIP(); i++) {
	
	SCAL val = coeff_c->T_Evaluate<SCAL> (mir[i]);

	// this is contrived to get the surface measure in "len"
	Mat<D> inv_jac = mir[i].GetJacobianInverse();
	double det = mir[i].GetMeasure();
	Vec<D> normal = det * Trans (inv_jac) * normal_ref;       
	double len = L2Norm (normal);    

	val *= len * ir_facet[i].Weight();
	
	fel_u.CalcShape (ir_facet_vol[i], ushape);
	fel_e.CalcShape (ir_facet_vol[i], eshape);
        
	submat += val * eshape * Trans(ushape);
      }    
    }
    elmat.Rows(re).Cols(ru) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(ru).Cols(re) += Conj(Trans(submat));
  }
Example #9
0
  void TraceTrace<D>::T_CalcElementMatrix (const FiniteElement & base_fel,
			    const ElementTransformation & eltrans, 
			    FlatMatrix<SCAL> elmat,
			    LocalHeap & lh) const {
    
    const CompoundFiniteElement &  cfel  // product space 
      =  dynamic_cast<const CompoundFiniteElement&> (base_fel);

    const ScalarFiniteElement<D> & fel_u =  // u space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd1()]);
    const ScalarFiniteElement<D> & fel_e =  // e space
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[GetInd2()]);

    elmat = SCAL(0.0);

    IntRange ru = cfel.GetRange(GetInd1()); 
    IntRange re = cfel.GetRange(GetInd2()); 
    int ndofe = re.Size();
    int ndofu = ru.Size();
    FlatVector<>      shapee(ndofe,lh);  
    FlatVector<>      shapeu(ndofu,lh);  
    FlatMatrix<SCAL>  submat(ndofe,ndofu, lh);  
    submat = SCAL(0.0);

    ELEMENT_TYPE eltype = fel_u.ElementType();         
    Facet2ElementTrafo transform(eltype);
    int nfa = ElementTopology :: GetNFacets(eltype); 

    for(int k = 0; k<nfa; k++) {
      
      // type of geometry of k-th facet
      ELEMENT_TYPE eltype_facet = ElementTopology::GetFacetType(eltype, k); 
      
      const IntegrationRule & facet_ir =
	SelectIntegrationRule (eltype_facet, fel_u.Order()+fel_e.Order()); 

      // reference element normal vector
      FlatVec<D> normal_ref = ElementTopology::GetNormals(eltype) [k]; 

      for (int l = 0; l < facet_ir.GetNIP(); l++) {

	// map 1D facet points to volume integration points
	IntegrationPoint volume_ip = transform(k, facet_ir[l]);
	MappedIntegrationPoint<D,D> mip (volume_ip, eltrans);
	
	// compute normal on physcial element
	Mat<D> inv_jac = mip.GetJacobianInverse();
	double det = mip.GetJacobiDet();
	Vec<D> normal = fabs(det) * Trans(inv_jac) * normal_ref;       
	double len = L2Norm(normal);
	normal /= len;
	double weight = facet_ir[l].Weight()*len;
	
	fel_e.CalcShape(volume_ip,shapee); 
	fel_u.CalcShape(volume_ip,shapeu); 

	SCAL cc = coeff_c  -> T_Evaluate<SCAL>(mip);

	//                     [ndofe x 1]  [1 x ndofu] 
	submat +=  (cc*weight) * shapee * Trans(shapeu);
      }
    }
    
    elmat.Rows(re).Cols(ru) += submat;
    if (GetInd1() != GetInd2())
      elmat.Rows(ru).Cols(re) += Conj(Trans(submat));    
  }