Exemplo n.º 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));
    
  }
Exemplo n.º 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));
  }
Exemplo n.º 3
0
//! Parse the command line.
static void ParseCommandLine( int argc, char* argv[] ) {
    int i = 1;
        if( i<argc && !isdigit(argv[i][0]) ) { 
        // Command line is garbled.
        Usage(argv[0]);
        exit(1);
    }
    if( i<argc )
        NThread.set_from_string(argv[i++]);
    if( i<argc && !isdigit(argv[i][0]) ) { 
        // Command line is garbled.
        Usage(argv[0]);
        exit(1);
    }
    if (i<argc) {
        ntrial = strtol(argv[i++], 0, 0);
    }
    if (ntrial == 0) {
        // Command line is garbled.
        Usage(argv[0]);
        exit(1);
    }
    if (i<argc && strcmp( argv[i], "pause" )==0 ) {
        PauseFlag = true;
    }
}
Exemplo n.º 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));
  }
Exemplo n.º 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));
  }
Exemplo n.º 6
0
    void Add (int blocknr, IntRange range)
    {
      switch (mode)
	{
	case 1:
	  if (blocknr+1 > nd) nd = blocknr+1; 
	  break;
	case 2:
	  cnt[blocknr]+=range.Size();
	  break;
	case 3:
	  for (int j = 0; j < range.Size(); j++)
	    (*table)[blocknr][cnt[blocknr]+j] = range.First()+j;
	  cnt[blocknr]+=range.Size();
          /*
	  for (int j = 0; j < range.Size(); j++)
	    table->Data()[cnt[blocknr]+j] = range.First()+j;
	  cnt[blocknr]+=range.Size();
          */
	  break;
	}
    }
Exemplo n.º 7
0
int main()
{
	int I;				// Holds user input

	IntRange input;		// Create a IntRange object named input
						// and prompt user for integer range

	// Prompt the user to enter an integer
	cout << "Enter any integer between " << input.getLower();
	cout << " and " << input.getUpper() << endl;
	cout << "Entering " << input.getUpper() << " will stop this program.\n";

	// Call an input member function to accept the user input and 
	// validate it before returning it to be assigned to variable int
	I = input.getInt();

	// Continue allowing integers to be entered until -99 is input
	while (I != input.getUpper())
	{
		cout << "You entered " << I << endl;
		I = input.getInt();
	}
	return 0;
}
Exemplo n.º 8
0
bool operator <(const IntRange& r1, const IntRange& r2) {
    return r1.min() < r2.min() ||
            (r1.min() == r2.min() && r1.max() < r2.max());
}
Exemplo n.º 9
0
int hashCode(const IntRange& r) {
    return hashCode(r.min(), r.max());
}
Exemplo n.º 10
0
bool operator ==(const IntRange& r1, const IntRange& r2) {
    return r1.min() == r2.min() && r1.max() == r2.max();
}
Exemplo n.º 11
0
  void TaskManager :: Loop(int thd)
  {
    /*
    static Timer tADD("add entry counter");
    static Timer tCASready1("spin-CAS ready tick1");
    static Timer tCASready2("spin-CAS ready tick2");
    static Timer tCASyield("spin-CAS yield");
    static Timer tCAS1("spin-CAS wait");
    static Timer texit("exit zone");
    static Timer tdec("decrement");
    */
    thread_id = thd;

    int thds = GetNumThreads();

    int mynode = num_nodes * thd/thds;

    NodeData & mynode_data = *(nodedata[mynode]);



    TaskInfo ti;
    ti.nthreads = thds;
    ti.thread_nr = thd;
    // ti.nnodes = num_nodes;
    // ti.node_nr = mynode;

      
#ifdef USE_NUMA
    numa_run_on_node (mynode);
#endif
    active_workers++;
    workers_on_node[mynode]++;
    int jobdone = 0;


#ifdef USE_MKL
    auto mkl_max = mkl_get_max_threads();
    mkl_set_num_threads_local(1);
#endif

    
    while (!done)
      {
        if (complete[mynode] > jobdone)
          jobdone = complete[mynode];

        if (jobnr == jobdone)
          {
            // RegionTracer t(ti.thread_nr, tCASyield, ti.task_nr);            
            if(sleep)
              this_thread::sleep_for(chrono::microseconds(sleep_usecs));
            else
              {
#ifdef WIN32
                this_thread::yield();
#else  // WIN32
                sched_yield();
#endif // WIN32
              }
            continue;
          }

        {
          // RegionTracer t(ti.thread_nr, tADD, ti.task_nr);

          // non-atomic fast check ...
          if ( (mynode_data.participate & 1) == 0) continue;

          int oldval = mynode_data.participate += 2;
          if ( (oldval & 1) == 0)
            { // job not active, going out again
              mynode_data.participate -= 2;
              continue;
            }
        }

        if (startup_function) (*startup_function)();
        
        IntRange mytasks = Range(int(ntasks)).Split (mynode, num_nodes);
          
        try
          {
            
            while (1)
              {
                if (mynode_data.start_cnt >= mytasks.Size()) break;
		int mytask = mynode_data.start_cnt.fetch_add(1, memory_order_relaxed);
                if (mytask >= mytasks.Size()) break;
                
                ti.task_nr = mytasks.First()+mytask;
                ti.ntasks = ntasks;
                
                {
                  RegionTracer t(ti.thread_nr, jobnr, RegionTracer::ID_JOB, ti.task_nr);
                  (*func)(ti);
                }
              }

          }
        catch (Exception e)
          {
            {
              // cout << "got exception in TM" << endl; 
              lock_guard<mutex> guard(copyex_mutex);
              delete ex;
              ex = new Exception (e);
              mynode_data.start_cnt = mytasks.Size();
            }
          }

#ifndef __MIC__
        atomic_thread_fence (memory_order_release);     
#endif // __MIC__

        if (cleanup_function) (*cleanup_function)();

        jobdone = jobnr;

        mynode_data.participate-=2;

	{
	  int oldpart = 1;
	  if (mynode_data.participate.compare_exchange_strong (oldpart, 0))
	    {
              if (jobdone < jobnr.load())
                { // reopen gate
                  mynode_data.participate |= 1;                  
                }
              else
                {
                  if (mynode != 0)
                    mynode_data.start_cnt = 0;
                  complete[mynode] = jobnr.load(); 
                }
	    }	      
	}
      }
    

#ifdef USE_MKL
    mkl_set_num_threads_local(mkl_max);
#endif

    workers_on_node[mynode]--;
    active_workers--;
  }
Exemplo n.º 12
0
  void TaskManager :: CreateJob (const function<void(TaskInfo&)> & afunc,
                                 int antasks)
  {
    if (num_threads == 1 || !task_manager || func)
      {
        if (startup_function) (*startup_function)();
        
        TaskInfo ti;
        ti.ntasks = antasks;
        ti.thread_nr = 0; ti.nthreads = 1;
        // ti.node_nr = 0; ti.nnodes = 1;
        for (ti.task_nr = 0; ti.task_nr < antasks; ti.task_nr++)
          afunc(ti);

        if (cleanup_function) (*cleanup_function)();        
        return;
      }

    
    trace->StartJob(jobnr, afunc.target_type());

    func = &afunc;

    ntasks.store (antasks); // , memory_order_relaxed);
    ex = nullptr;


    nodedata[0]->start_cnt.store (0, memory_order_relaxed);

    jobnr++;
    
    for (int j = 0; j < num_nodes; j++)
      nodedata[j]->participate |= 1;

    if (startup_function) (*startup_function)();
    
    int thd = 0;
    int thds = GetNumThreads();
    int mynode = num_nodes * thd/thds;

    IntRange mytasks = Range(int(ntasks)).Split (mynode, num_nodes);
    NodeData & mynode_data = *(nodedata[mynode]);

    TaskInfo ti;
    ti.nthreads = thds;
    ti.thread_nr = thd;
    // ti.nnodes = num_nodes;
    // ti.node_nr = mynode;

    try
      {
        while (1)
          {
            int mytask = mynode_data.start_cnt++;
            if (mytask >= mytasks.Size()) break;
            
            ti.task_nr = mytasks.First()+mytask;
            ti.ntasks = ntasks;

            {
              RegionTracer t(ti.thread_nr, jobnr, RegionTracer::ID_JOB, ti.task_nr);
              (*func)(ti); 
            }
          }

      }
    catch (Exception e)
      {
        {
          lock_guard<mutex> guard(copyex_mutex);
          delete ex;
          ex = new Exception (e);
          mynode_data.start_cnt = mytasks.Size();
        }
      }

    if (cleanup_function) (*cleanup_function)();
    
    for (int j = 0; j < num_nodes; j++)
      if (workers_on_node[j])
        {
          while (complete[j] != jobnr)
            _mm_pause();
        }

    func = nullptr;
    if (ex)
      throw Exception (*ex);

    trace->StopJob();
  }
Exemplo n.º 13
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.º 14
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;
  }
Exemplo n.º 15
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));
  }
Exemplo n.º 16
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));    
  }