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; }
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(); } } } }
DevVector (FlatVector<T> a2) { size = a2.Size(); cudaMalloc((T**)&dev_data, size*sizeof(T)); cudaMemcpy (dev_data, &a2[0], sizeof(T)*size, cudaMemcpyHostToDevice); }