Exemplo n.º 1
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));
  }
Exemplo n.º 2
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));    
  }