예제 #1
0
 void DGFiniteElement<D>:: 
 GetTraceTrans (int facet, FlatVector<> fcoefs, FlatVector<> coefs) const
 {
   Matrix<> trace(fcoefs.Size(), coefs.Size());
   CalcTraceMatrix(facet, trace);
   coefs = Trans (trace) * fcoefs;
 }
예제 #2
0
파일: densemat.hpp 프로젝트: cgogn/SCHNApps
  DLL_HEADER void Mult (const FlatVector & v, FlatVector & prod) const
  {
    double sum;
    const double * mp, * sp;
    double * dp;
    
#ifdef DEBUG
    if (prod.Size() != height)
      {
	(*myerr) << "Mult: wrong vector size " << std::endl;
      }
    if (!height) 
      {
		std::cout << "DenseMatrix::Mult height = 0" << std::endl;
      }
    if (!width) 
      {
		std::cout << "DenseMatrix::Mult width = 0" << std::endl;
      }
    
    if (width != v.Size())
      {
	(*myerr) << "\nMatrix and Vector don't fit" << std::endl;
      }
    else if (Height() != prod.Size())
      {
	(*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << std::endl;
      }
    else
#endif
      {      
	mp = data;
	dp = &prod(0);
        for (int i = 0; i < height; i++)
	  {
	    sum = 0;
	    sp = &v(0);
	    
	    for (int j = 0; j < width; j++)
	      {
		//        sum += Get(i,j) * v.Get(j);
		sum += *mp * *sp;
		mp++;
		sp++;
	      }
	    
	    *dp = sum;
	    dp++;
	  }
      }
  }
예제 #3
0
 void DGFiniteElement<D>:: 
 GetGradientTrans (FlatMatrixFixWidth<D> grad, FlatVector<> coefs) const 
 {
   Matrix<> gmat(D*grad.Height(), coefs.Size());
   CalcGradientMatrix (gmat);
   FlatVector<> vgrad(gmat.Height(), &grad(0,0));
   coefs = Trans (gmat) * vgrad;
 }
예제 #4
0
 void DGFiniteElement<D>:: 
 GetGradient (FlatVector<> coefs, FlatMatrixFixWidth<D> grad) const
 {
   Matrix<> gmat(D*grad.Height(), coefs.Size());
   CalcGradientMatrix (gmat);
   FlatVector<> vgrad(gmat.Height(), &grad(0,0));
   vgrad = gmat * coefs;
 }
예제 #5
0
  void SolveM (FlatVector<double> res, FlatVector<double> vecu,
	       LocalHeap & lh)
  {
    int ne = ma->GetNE();
    const L2HighOrderFESpace & fes = 
      dynamic_cast<const L2HighOrderFESpace&> (*gfu->GetFESpace());

#pragma omp single
    timer_mass.Start();

#pragma omp for
    for (int i = 0; i < ne; i++)
      {
	IntRange dn = fes.GetElementDofs (i);
	vecu.Range (dn) = elementdata[i]->invmass * res.Range (dn);
      }

#pragma omp single
    timer_mass.Stop();
  }
int main(int argc, char* argv[])
{
    using DGtal::trace;
    using std::endl;
    using DGtal::PRIMAL;
    using DGtal::DUAL;

    const Options options = parse_options(argc, argv);

    const KSpace kspace;

    const Calculus calculus;
    const FlatVector original_face_normals;

    if (!ends_with(options.image_filename, ".csv"))
    {
        ASSERT( !options.image_filename.empty() );
        typedef DGtal::Z3i::Domain Domain;
        typedef DGtal::ImageSelector<Domain, unsigned char>::Type ImageUChar;
        trace.info() << "image_filename=" << options.image_filename << endl;
        ImageUChar image_uchar = DGtal::GenericReader<ImageUChar>::import(options.image_filename);
        const Domain domain = image_uchar.domain();
        trace.info() << "domain=" << domain << endl;
        const Point center = (domain.upperBound()+domain.lowerBound())/2;
        trace.info() << "center=" << center << endl;
        const ImageShape<ImageUChar> shape(&image_uchar, center);

        const_cast<KSpace&>(kspace).init(domain.lowerBound()-center-Point::diagonal(1), domain.upperBound()-center+Point::diagonal(1), true);

        std::tie(const_cast<Calculus&>(calculus), const_cast<FlatVector&>(original_face_normals)) =
            initCalculusAndNormalsWithNoise(kspace, shape, options.normal_radius, options.noise_level);
    }

    if (ends_with(options.image_filename, ".csv"))
    {
        ASSERT( !options.image_filename.empty() );
        trace.info() << "csv_filename=" << options.image_filename << endl;
        std::tie(const_cast<Calculus&>(calculus), const_cast<FlatVector&>(original_face_normals)) =
            initCalculusAndNormalsFromSurfelNormalsCSV(options.image_filename);
    }

    const FlatVector original_vertex_normals = vertexNormals(calculus, original_face_normals);

    const FlatVector original_positions;
    const FlatVector regularized_positions;
    const FlatVector original_centers;
    const FlatVector regularized_centers;
    std::tie(const_cast<FlatVector&>(original_positions),
             const_cast<FlatVector&>(regularized_positions),
             const_cast<FlatVector&>(original_centers),
             const_cast<FlatVector&>(regularized_centers)) =
             approximateSurface(calculus, original_face_normals,
             ApproxParams({options.regularization_position, options.regularization_center, options.align, options.fairness, options.barycenter}));
    ASSERT( original_positions.size() == 3*calculus.kFormLength(0, PRIMAL) );
    ASSERT( regularized_positions.size() == 3*calculus.kFormLength(0, PRIMAL) );
    ASSERT( original_centers.size() == 3*calculus.kFormLength(2, PRIMAL) );
    ASSERT( regularized_centers.size() == 3*calculus.kFormLength(2, PRIMAL) );

    {
      trace.beginBlock( "computing energies" );

      {
        double position_energy = 0;
        double align_energy    = 0;
        std::tie( position_energy, align_energy ) = approximateSurfaceEnergies(
        calculus, original_face_normals, original_positions );
        align_energy *= options.align;
        position_energy *= options.regularization_position;
        trace.info() << "original_energies=" << position_energy << " "
                     << align_energy << " " << position_energy + align_energy
                     << endl;
        }

        {
            double position_energy = 0;
            double align_energy = 0;
            std::tie(position_energy, align_energy) = approximateSurfaceEnergies(calculus, original_face_normals, regularized_positions);
            align_energy *= options.align;
            position_energy *= options.regularization_position;
            trace.info() << "regularized_energies=" << position_energy << " " << align_energy << " " << position_energy+align_energy << endl;
        }

        trace.endBlock();
    }

    {
        ASSERT( !options.regularized_obj_filename.empty() );
        trace.info() << "regularized_obj_filename=" << options.regularized_obj_filename << endl;
        exportOBJ(calculus, regularized_positions, options.regularized_obj_filename);
    }

    if (!options.cubical_obj_filename.empty())
    {
        ASSERT( !options.cubical_obj_filename.empty() );
        trace.info() << "cubical_obj_filename=" << options.cubical_obj_filename << endl;
        exportOBJ(calculus, original_positions, options.cubical_obj_filename);
    }

    return 0;
}
예제 #7
0
  virtual void Do(LocalHeap & lh)
  {
    cout << "solve conservation equation" << endl;



    // prepare ...

    const L2HighOrderFESpace & fes = 
      dynamic_cast<const L2HighOrderFESpace&> (*gfu->GetFESpace());


    int ne = ma->GetNE();
    int nf = ma->GetNFacets();

    elementdata.SetSize (ne);
    facetdata.SetSize (nf);

    ConstantCoefficientFunction one(1);
    MassIntegrator<D> bfi(&one);

    for (int i = 0; i < ne; i++)
      {
	HeapReset hr(lh);
	
	const DGFiniteElement<D> & fel = dynamic_cast<const DGFiniteElement<D>&> (fes.GetFE (i, lh));
	const IntegrationRule ir(fel.ElementType(), 2*fel.Order());

        const_cast<DGFiniteElement<D>&> (fel).PrecomputeShapes (ir);
        const_cast<DGFiniteElement<D>&> (fel).PrecomputeTrace ();


	MappedIntegrationRule<D,D> mir(ir, ma->GetTrafo (i, 0, lh), lh);
	
	elementdata[i] = new ElementData (fel.GetNDof(), ir.Size());
	ElementData & edi = *elementdata[i];

	cfflow -> Evaluate (mir, FlatMatrix<> (edi.flowip));
			    
	for (int j = 0; j < ir.Size(); j++)
	  {
	    Vec<D> flow = mir[j].GetJacobianInverse() * edi.flowip.Row(j);
	    flow *= ir[j].Weight() * mir[j].GetMeasure();		
	    edi.flowip.Row(j) = flow;
	  }


	FlatMatrix<> mass(fel.GetNDof(), lh);
	bfi.CalcElementMatrix (fel, ma->GetTrafo(i, 0, lh), mass, lh);
	CalcInverse (mass, edi.invmass);
      }



    Array<int> elnums, fnums, vnums;
    
    for (int i = 0; i < nf; i++)
      {
	HeapReset hr(lh);
	
	const DGFiniteElement<D-1> & felfacet = 
	  dynamic_cast<const DGFiniteElement<D-1>&> (fes.GetFacetFE (i, lh));
	IntegrationRule ir (felfacet.ElementType(), 2*felfacet.Order());
        const_cast<DGFiniteElement<D-1>&> (felfacet).PrecomputeShapes (ir);
	

	facetdata[i] = new FacetData (ir.Size());
	FacetData & fai = *facetdata[i];

	ma->GetFacetElements (i, elnums);
	
	fai.elnr[1] = -1;
	for (int j = 0; j < elnums.Size(); j++)
	  {
	    fai.elnr[j] = elnums[j];
	    ma->GetElFacets (elnums[j], fnums);
	    for (int k = 0; k < fnums.Size(); k++)
	      if (fnums[k] == i) fai.facetnr[j] = k;
	  }

	
	ELEMENT_TYPE eltype = ma->GetElType(elnums[0]);

	ma->GetElVertices (elnums[0], vnums);
	Facet2ElementTrafo transform(eltype, vnums); 
	FlatVec<D> normal_ref = ElementTopology::GetNormals(eltype) [fai.facetnr[0]];
	
	int nip = ir.Size();
	
	// transform facet coordinates to element coordinates
	IntegrationRule & irt = transform(fai.facetnr[0], ir, lh);  
	MappedIntegrationRule<D,D> mir(irt, ma->GetTrafo(elnums[0], 0, lh), lh);
	
	FlatMatrixFixWidth<D> flowir(nip, lh);
	
	cfflow -> Evaluate (mir, flowir);
	
	for (int j = 0; j < nip; j++)
	  {
	    Vec<D> normal = Trans (mir[j].GetJacobianInverse()) * normal_ref;       
	    
	    fai.flown(j) = InnerProduct (normal, flowir.Row(j));
	    fai.flown(j) *= ir[j].Weight() * mir[j].GetJacobiDet();
	  }
      }
    







    FlatVector<> vecu = gfu->GetVector().FVDouble();
    Vector<> conv(vecu.Size());
    Vector<> w(vecu.Size());
    Vector<> hu(vecu.Size());
    
#pragma omp parallel
    {
      LocalHeap lh2 = lh.Split();
      

      for (double t = 0; t < tend; t += dt)
        {

#pragma omp single
          cout << "\rt = " << setw(6) << t << flush;
          
          CalcConvection (vecu, conv, lh2);
          SolveM (conv, w, lh2);
          
#pragma omp single
          {
            hu = vecu + (0.5*dt) * w;
          }

          CalcConvection (hu, conv, lh2);
          SolveM (conv, w, lh2);
          
#pragma omp single
          {
            vecu += dt * w;
            
            /*
              cout << " time T/F/M [us] = "
              << 1e6 * timer_element.GetTime()/timer_element.GetCounts()/vecu.Size() << " / "
              << 1e6 * timer_facet.GetTime()/timer_facet.GetCounts()/vecu.Size() << " / "
              << 1e6 * timer_mass.GetTime()/timer_mass.GetCounts()/vecu.Size() 
              << "\r";
            */
            Ng_Redraw();
          }
        }
    }
  }
예제 #8
0
  void CalcConvection (FlatVector<double> vecu, FlatVector<double> conv,
		       LocalHeap & lh)
  {
    
    const L2HighOrderFESpace & fes = 
      dynamic_cast<const L2HighOrderFESpace&> (*gfu->GetFESpace());
    
    
#pragma omp single
    timer_element.Start();
    
    
    int ne = ma->GetNE();
      
#pragma omp for
      for (int i = 0; i < ne; i++)
	{
	  HeapReset hr(lh);
	  
	  const ScalarFiniteElement<D> & fel = 
            static_cast<const ScalarFiniteElement<D>&> (fes.GetFE (i, lh));
	  const IntegrationRule ir(fel.ElementType(), 2*fel.Order());

	  FlatMatrixFixWidth<D> flowip = elementdata[i]->flowip;

	  /*
	  // use this for time-dependent flow
	  MappedIntegrationRule<D,D> mir(ir, ma->GetTrafo (i, 0, lh), lh);
	  FlatMatrixFixWidth<D> flowip(mir.Size(), lh);
	  cfflow -> Evaluate (mir, flowip);
	  for (int j = 0; j < ir.Size(); j++)
	    {
	      Vec<D> flow = mir[j].GetJacobianInverse() * flowip.Row(j);
	      flow *= mir[j].GetWeight();		
	      flowip.Row(j) = flow;
	    }
	  */

	  IntRange dn = fes.GetElementDofs (i);
	  
	  int nipt = ir.Size();
	  FlatVector<> elui(nipt, lh);
	  FlatMatrixFixWidth<D> flowui (nipt, lh);
	  
	  fel.Evaluate (ir, vecu.Range (dn), elui);
	  
	  flowui = flowip;
	  for (int k = 0; k < nipt; k++)
	    flowui.Row(k) *= elui(k);
	  
	  fel.EvaluateGradTrans (ir, flowui, conv.Range(dn));
	}


#pragma omp single
      {
        timer_element.Stop();
        timer_facet.Start();
      }


      int nf = ma->GetNFacets();
      
#pragma omp for
      for (int i = 0; i < nf; i++)
	{
	  HeapReset hr(lh);
	  
	  const FacetData & fai = *facetdata[i];
	  if (fai.elnr[1] != -1)
	    {
	      const DGFiniteElement<D> & fel1 = 
		static_cast<const DGFiniteElement<D>&> (fes.GetFE (fai.elnr[0], lh));
	      const DGFiniteElement<D> & fel2 = 
		static_cast<const DGFiniteElement<D>&> (fes.GetFE (fai.elnr[1], lh));
	      const DGFiniteElement<D-1> & felfacet = 
		static_cast<const DGFiniteElement<D-1>&> (fes.GetFacetFE (i, lh));

	      IntRange dn1 = fes.GetElementDofs (fai.elnr[0]);
	      IntRange dn2 = fes.GetElementDofs (fai.elnr[1]);

	      int ndoffacet = felfacet.GetNDof();
	      int ndof1 = fel1.GetNDof();
	      int ndof2 = fel2.GetNDof();

	      FlatVector<> aelu1(ndof1, lh), aelu2(ndof2, lh);
	      FlatVector<> trace1(ndoffacet, lh), trace2(ndoffacet, lh);

	      fel1.GetTrace (fai.facetnr[0], vecu.Range (dn1), trace1);
	      fel2.GetTrace (fai.facetnr[1], vecu.Range (dn2), trace2);

	      IntegrationRule ir(felfacet.ElementType(), 2*felfacet.Order());
	      int nip = ir.Size();

	      FlatVector<> flown = fai.flown;
	    
	      FlatVector<> tracei1(nip, lh), tracei2(nip, lh);
	      FlatVector<> tracei(nip, lh);

	      felfacet.Evaluate (ir, trace1, tracei1);
	      felfacet.Evaluate (ir, trace2, tracei2);
		    
	      for (int j = 0; j < nip; j++)
		tracei(j) = flown(j) * ( (flown(j) > 0) ? tracei1(j) : tracei2(j) );

	      felfacet.EvaluateTrans (ir, tracei, trace1);
	      fel1.GetTraceTrans (fai.facetnr[0], trace1, aelu1);
	      fel2.GetTraceTrans (fai.facetnr[1], trace1, aelu2);

#pragma omp critical (addres)
	      {
		conv.Range (dn1) -= aelu1;
		conv.Range (dn2) += aelu2;
	      }
	    }
	  else
	    {
	      const DGFiniteElement<D> & fel1 = 
		dynamic_cast<const DGFiniteElement<D>&> (fes.GetFE (fai.elnr[0], lh));
	      const DGFiniteElement<D-1> & felfacet = 
		dynamic_cast<const DGFiniteElement<D-1>&> (fes.GetFacetFE (i, lh));

	      IntRange dn1 = fes.GetElementDofs (fai.elnr[0]);

	      int ndoffacet = felfacet.GetNDof();
	      int ndof1 = fel1.GetNDof();

	      FlatVector<> elu1(ndof1, lh);
	      FlatVector<> trace1(ndoffacet, lh);

	      fel1.GetTrace (fai.facetnr[0], vecu.Range (dn1), trace1);

	      IntegrationRule ir(felfacet.ElementType(), 2*felfacet.Order());
	      int nip = ir.Size();

	      FlatVector<> flown = fai.flown; 
	      FlatVector<> tracei1(nip, lh), tracei(nip, lh);

	      felfacet.Evaluate (ir, trace1, tracei1);
		    
	      for (int j = 0; j < nip; j++)
		tracei(j) = flown(j) * ( (flown(j) > 0) ? tracei1(j) : 0 );

	      felfacet.EvaluateTrans (ir, tracei, trace1);
	      fel1.GetTraceTrans (fai.facetnr[0], trace1, elu1);
	    
#pragma omp critical (addres)
	      {
		conv.Range (dn1) -= elu1;
	      }
	    }
	}

#pragma omp single    
      timer_facet.Stop(); 
      


  }
예제 #9
0
파일: cuda_bla.hpp 프로젝트: ddrake/ngsolve
 DevVector (FlatVector<T> a2)
 {
   size = a2.Size();
   cudaMalloc((T**)&dev_data, size*sizeof(T));
   cudaMemcpy (dev_data, &a2[0], sizeof(T)*size, cudaMemcpyHostToDevice);
 }
예제 #10
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;
  }