void DGFiniteElement<D>:: GetTraceTrans (int facet, FlatVector<> fcoefs, FlatVector<> coefs) const { Matrix<> trace(fcoefs.Size(), coefs.Size()); CalcTraceMatrix(facet, trace); coefs = Trans (trace) * fcoefs; }
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++; } } }
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; }
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; }
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; }
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(); } } } }
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(); }
DevVector (FlatVector<T> a2) { size = a2.Size(); cudaMalloc((T**)&dev_data, size*sizeof(T)); cudaMemcpy (dev_data, &a2[0], sizeof(T)*size, cudaMemcpyHostToDevice); }
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; }