Пример #1
0
  void NeumannVolume<D> ::
  T_CalcElementVector (const FiniteElement & base_fel,
		       const ElementTransformation & eltrans, 
		       FlatVector<SCAL> elvec,
		       LocalHeap & lh) const {

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

    const ScalarFiniteElement<D> & fel = 
      dynamic_cast<const ScalarFiniteElement<D>&> (cfel[indx]);

    FlatVector<> ushape(fel.GetNDof(), lh);
    elvec = SCAL(0);    
    IntRange re = cfel.GetRange(indx);
    int ndofe = re.Size();
    FlatVector<SCAL> subvec(ndofe,lh);
    subvec = SCAL(0);

    const IntegrationRule ir(fel.ElementType(), 2*fel.Order());
    ELEMENT_TYPE eltype = base_fel.ElementType();        
    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, 2*fel.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 G[3] ;
	G[0] = coeff_Gx -> T_Evaluate<SCAL>(mir[i]);
	G[1] = coeff_Gy -> T_Evaluate<SCAL>(mir[i]);
	if (D==3)  G[2] = coeff_Gz -> T_Evaluate<SCAL>(mir[i]);
	FlatVector<SCAL> Gval(D,lh);	
	for (int dd=0; dd<D; dd++)  Gval[dd] = G[dd];
	SCAL g = coeff_g -> 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);    
	
	SCAL gg = (InnerProduct(Gval,normal) + g*len)
	          * ir_facet[i].Weight();
		
	fel.CalcShape (ir_facet_vol[i], ushape);
	        
	subvec += gg * ushape;
      }   
    }
    elvec.Rows(re) += subvec;
  }
Пример #2
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));
  }