DevMatrix (FlatMatrix<T> a2) { h = a2.Height(); w = a2.Width(); cudaMalloc((T**)&dev_data, h*w*sizeof(T)); cudaMemcpy (dev_data, &a2(0,0), sizeof(T)*h*w, cudaMemcpyHostToDevice); }
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)); }
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)); }
vector <vector <BVP_info> > getPrecomputedData(string trajectoryFile, string costFile){ FlatMatrix costMat = text2FlatMatrix(costFile); FlatMatrix trajMat = text2FlatMatrix(trajectoryFile); vector <vector <BVP_info> > precompData; for(int iter4 = 0; iter4 < trajMat.getDimensions().at(3); iter4++){ vector <BVP_info> allCurStateBVPs; for(int iter1 = 0; iter1 < trajMat.getDimensions().at(0); iter1++){ BVP_info curBVP; for(int iter3 = 0; iter3 < trajMat.getDimensions().at(2); iter3++){ vector <double>* curInterpState = new vector <double>(); for(int iter2 = 0; iter2 < trajMat.getDimensions().at(1); iter2++){ vector <int> index; index.push_back(iter1); index.push_back(iter2); index.push_back(iter3); index.push_back(iter4); curInterpState->push_back(trajMat.value_at(index)); } curBVP.trajectory.push_back(curInterpState); } vector <int> index; index.push_back(iter4); index.push_back(iter1); curBVP.cost = costMat.value_at(index); allCurStateBVPs.push_back(curBVP); } precompData.push_back(allCurStateBVPs); } return precompData; }
void DGFiniteElement<D>:: CalcTraceMatrix (int facet, FlatMatrix<> trace) const { ELEMENT_TYPE ftype = ElementTopology::GetFacetType (this->ElementType(), facet); Facet2ElementTrafo f2el(this->ElementType(), FlatArray<int> (8, const_cast<int*> (vnums)) ); const IntegrationRule & ir = SelectIntegrationRule (ftype, 2*order); ScalarFiniteElement<0> * facetfe0 = NULL; ScalarFiniteElement<1> * facetfe1 = NULL; ScalarFiniteElement<2> * facetfe2 = NULL; switch (ftype) { case ET_POINT : facetfe0 = new FE_Point; break; case ET_SEGM : facetfe1 = new L2HighOrderFE<ET_SEGM> (order); break; case ET_TRIG : facetfe2 = new L2HighOrderFE<ET_TRIG> (order); break; case ET_QUAD : facetfe2 = new L2HighOrderFE<ET_QUAD> (order); break; default: ; } int ndof_facet = trace.Height(); Vector<> shape(ndof); Vector<> fshape(ndof_facet); Vector<> norms(ndof_facet); trace = 0.0; norms = 0.0; for (int i = 0; i < ir.Size(); i++) { if (D == 1) facetfe0 -> CalcShape (ir[i], fshape); else if (D == 2) facetfe1 -> CalcShape (ir[i], fshape); else facetfe2 -> CalcShape (ir[i], fshape); this -> CalcShape (f2el (facet, ir[i]), shape); trace += ir[i].Weight() * fshape * Trans (shape); for (int j = 0; j < norms.Size(); j++) norms(j) += ir[i].Weight() * sqr (fshape(j)); } for (int j = 0; j < fshape.Size(); j++) trace.Row(j) /= norms(j); delete facetfe0; delete facetfe1; delete facetfe2; }
void DGFiniteElement<D>:: CalcGradientMatrix (FlatMatrix<> gmat) const { IntegrationRule ir (this->ElementType(), 2*order); Vector<> shape(ndof); MatrixFixWidth<D> dshape(ndof); Vector<> norms(ndof); gmat = 0.0; norms = 0.0; for (int i = 0; i < ir.Size(); i++) { this -> CalcShape (ir[i], shape); this -> CalcDShape (ir[i], dshape); for (int j = 0; j < ndof; j++) for (int k = 0; k < ndof; k++) for (int l = 0; l < D; l++) gmat(k*D+l, j) += ir[i].Weight() * dshape(j,l) * shape(k); for (int j = 0; j < norms.Size(); j++) norms(j) += ir[i].Weight() * sqr (shape(j)); } for (int j = 0; j < ndof; j++) gmat.Rows(D*j, D*(j+1)) /= norms(j); }
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)); }
vector <vector <double>*> getSampledStateID(string stateIDFile){ FlatMatrix stateMat = text2FlatMatrix(stateIDFile); vector <vector <double>*> sampledStates; for(int iter1 = 0; iter1 < stateMat.getDimensions().at(0); iter1++){ vector <double>* curState = new vector <double>(); // instantiate new pointer to a vector of doubles for(int iter2 = 0; iter2 < stateMat.getDimensions().at(1); iter2++){ vector <int> index; index.push_back(iter1); index.push_back(iter2); curState->push_back(stateMat.value_at(index)); } sampledStates.push_back(curState); } return sampledStates; }
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)); }
extern NGS_DLL_HEADER void CalcInverse (FlatMatrix<double> inv, INVERSE_LIB il) { #ifdef LAPACK if (il == INVERSE_LIB::INV_LAPACK) LapackInverse(inv); else if (il == INVERSE_LIB::INV_CHOOSE && inv.Height() >= 20) LapackInverse(inv); else #endif T_CalcInverse (inv); }
void ScalarFiniteElement<D> :: CalcMappedDDShape (const MappedIntegrationPoint<D,D> & mip, FlatMatrix<> ddshape) const { int nd = GetNDof(); double eps = 1e-7; MatrixFixWidth<D> dshape1(nd), dshape2(nd); const ElementTransformation & eltrans = mip.GetTransformation(); for (int i = 0; i < D; i++) { IntegrationPoint ip1 = mip.IP(); IntegrationPoint ip2 = mip.IP(); ip1(i) -= eps; ip2(i) += eps; MappedIntegrationPoint<D,D> mip1(ip1, eltrans); MappedIntegrationPoint<D,D> mip2(ip2, eltrans); CalcMappedDShape (mip1, dshape1); CalcMappedDShape (mip2, dshape2); ddshape.Cols(D*i,D*(i+1)) = (0.5/eps) * (dshape2-dshape1); } for (int j = 0; j < D; j++) { for (int k = 0; k < nd; k++) for (int l = 0; l < D; l++) dshape1(k,l) = ddshape(k, l*D+j); dshape2 = dshape1 * mip.GetJacobianInverse(); for (int k = 0; k < nd; k++) for (int l = 0; l < D; l++) ddshape(k, l*D+j) = dshape2(k,l); } }
void CalcSchurComplement (const FlatMatrix<double> a, FlatMatrix<double> s, const BitArray & used, LocalHeap & lh) { if (s.Height() == 0) return; if (s.Height() == a.Height()) { s = a; return; } HeapReset hr(lh); int n = a.Height(); Array<int> used_dofs(n, lh); Array<int> unused_dofs(n, lh); used_dofs.SetSize(0); unused_dofs.SetSize(0); for (int i = 0; i < n; i++) if (used[i]) used_dofs.Append(i); else unused_dofs.Append(i); s = a.Rows(used_dofs).Cols(used_dofs); FlatMatrix<> b1 = a.Rows(unused_dofs).Cols(used_dofs) | lh; FlatMatrix<> b2 = a.Rows(used_dofs).Cols(unused_dofs) | lh; FlatMatrix<> c = a.Rows(unused_dofs).Cols(unused_dofs) | lh; FlatMatrix<> hb1 (b1.Height(), b1.Width(), lh); if (n > 10) { LapackInverse (c); hb1 = c * b1 | Lapack; s -= b2 * hb1 | Lapack; } else { CalcInverse (c); hb1 = c * b1; s -= b2 * hb1; } }
void CalcEigenSystem (const FlatMatrix<double> & mat1, FlatVector<double> & lami, FlatMatrix<double> & eigenvecs) { int i, j, k, l; int n = mat1.Height(); Matrix<double> mat(n, n); mat = mat1; eigenvecs = 0; for (i = 0; i < n; i++) eigenvecs(i,i) = 1; for (l = 0; l < 100; l++) for (i = 0; i < n; i++) for (j = 0; j < i; j++) { // find eigensystem of a(i-j,i-j) double a11 = mat(i,i); double a12 = mat(i,j); double a22 = mat(j,j); if (a12*a12 <= 1e-32 * fabs(a11*a22)) continue; /* double lam1, lam2; // y is EV from a y = lam y // quadratic eq. for eigenvalues lam: // c0 + c1 lam + c2 lam^2 = 0 double c0 = a11*a22-a12*a12; double c1 = -a22 - a11; double c2 = 1; lam1 = -c1/(2*c2) + sqrt( sqr(c1/(2*c2)) - c0/c2); lam2 = -c1/(2*c2) - sqrt( sqr(c1/(2*c2)) - c0/c2); cout << "lam1,2 = " << lam1 << ", " << lam2 << endl; lam1 = (a11+a22) / 2 + sqrt ( sqr(a11-a22)/4 + a12*a12); lam2 = (a11+a22) / 2 - sqrt ( sqr(a11-a22)/4 + a12*a12); // cout << "lam1,2 = " << lam1 << ", " << lam2 << endl; */ double p = (a22-a11)/2; double q = a12; // compute eigenvectors: double y11, y12, y21, y22, y; y11 = a12; // y12 = lam1-a11; y12 = (p >= 0) ? p + sqrt (p*p + q*q) : -q*q / (p - sqrt (p*p+q*q)); y = sqrt (y11*y11+y12*y12); y11 /= y; y12 /= y; y21 = a12; // y22 = lam2-a11; y22 = (p <= 0) ? p - sqrt (p*p + q*q) : -q*q / (p + sqrt (p*p+q*q)); y = sqrt (y21*y21+y22*y22); y21 /= y; y22 /= y; /* (*testout) << "evecs = " << "(" << y11 << ", " << y12 << "), " << "(" << y21 << ", " << y22 << ")" << endl; (*testout) << "Y Y = " << (y11*y11+y12*y12) << ", " << (y11*y21+y12*y22) << ", " << (y21*y21+y22*y22) << endl; */ // V^T A V = V^T G^{-1} (G^T A G) G^{-1} V for (k = 0; k < n; k++) { double v1 = mat(k,i); double v2 = mat(k,j); mat(k,i) = v1 * y11 + v2 * y12; mat(k,j) = v1 * y21 + v2 * y22; } for (k = 0; k < n; k++) { double v1 = mat(i,k); double v2 = mat(j,k); mat(i,k) = v1 * y11 + v2 * y12; mat(j,k) = v1 * y21 + v2 * y22; } mat(i,j) = 0; mat(j,i) = 0; for (k = 0; k < n; k++) { double v1 = eigenvecs(i,k); double v2 = eigenvecs(j,k); eigenvecs(i,k) = v1 * y11 + v2 * y12; eigenvecs(j,k) = v1 * y21 + v2 * y22; } } for (i = 0; i < n; i++) lami(i) = mat(i,i); }
/// Factor the matrix A FlatCholeskyFactors (const FlatMatrix<T> & a, LocalHeap & lh) { diag = (T*)lh.Alloc(sizeof(T)*RequiredMem(a.Height())); Factor (a); }
/// Factor the matrix A CholeskyFactors (const FlatMatrix<T> & a) : FlatCholeskyFactors<T> (a, new T[this->RequiredMem(a.Height())]) { ; }
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)); }
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)); }
void T_CalcInverse (FlatMatrix<T2> inv) { // static Timer t("CalcInverse"); // RegionTimer reg(t); // Gauss - Jordan - algorithm // Algorithm of Stoer, Einf. i. d. Num. Math, S 145 // int n = m.Height(); int n = inv.Height(); ngstd::ArrayMem<int,100> p(n); // pivot-permutation for (int j = 0; j < n; j++) p[j] = j; for (int j = 0; j < n; j++) { // pivot search double maxval = abs(inv(j,j)); int r = j; for (int i = j+1; i < n; i++) if (abs (inv(j, i)) > maxval) { r = i; maxval = abs (inv(j, i)); } double rest = 0.0; for (int i = j+1; i < n; i++) rest += abs(inv(r, i)); if (maxval < 1e-20*rest) { throw Exception ("Inverse matrix: Matrix singular"); } // exchange rows if (r > j) { for (int k = 0; k < n; k++) swap (inv(k, j), inv(k, r)); swap (p[j], p[r]); } // transformation T2 hr; CalcInverse (inv(j,j), hr); for (int i = 0; i < n; i++) { T2 h = hr * inv(j, i); inv(j, i) = h; } inv(j,j) = hr; for (int k = 0; k < n; k++) if (k != j) { T2 help = inv(n*k+j); T2 h = help * hr; for (int i = 0; i < n; i++) { T2 h = help * inv(n*j+i); inv(n*k+i) -= h; } inv(k,j) = -h; } } // row exchange VectorMem<100,T2> hv(n); for (int i = 0; i < n; i++) { for (int k = 0; k < n; k++) hv(p[k]) = inv(k, i); for (int k = 0; k < n; k++) inv(k, i) = hv(k); } }
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)); }