void LagMultTerm::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const { int nbFF1 = BilinearTerm<SVector3, SVector3>::space1.getNumKeys( ele); // nbVertices*nbcomp of parent int nbFF2 = BilinearTerm<SVector3, SVector3>::space2.getNumKeys( ele); // nbVertices of boundary double jac[3][3]; m.resize(nbFF1, nbFF2); m.setAll(0.); for(int i = 0; i < npts; i++) { double u = GP[i].pt[0]; double v = GP[i].pt[1]; double w = GP[i].pt[2]; const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac); std::vector<TensorialTraits<SVector3>::ValType> Vals; std::vector<TensorialTraits<SVector3>::ValType> ValsT; BilinearTerm<SVector3, SVector3>::space1.f(ele, u, v, w, Vals); BilinearTerm<SVector3, SVector3>::space2.f(ele, u, v, w, ValsT); for(int j = 0; j < nbFF1; j++) { for(int k = 0; k < nbFF2; k++) { m(j, k) += _eqfac * dot(Vals[j], ValsT[k]) * weight * detJ; } } } }
bool fullMatrix<double>::invert(fullMatrix<double> &result) const { int M = size1(), N = size2(), lda = size1(), info; int *ipiv = new int[std::min(M, N)]; if (result.size2() != M || result.size1() != N) { if (result._own_data || !result._data) result.resize(M,N,false); else Msg::Fatal("FullMatrix: Bad dimension, I cannot write in proxy"); } result.setAll(*this); F77NAME(dgetrf)(&M, &N, result._data, &lda, ipiv, &info); if(info == 0){ int lwork = M * 4; double *work = new double[lwork]; F77NAME(dgetri)(&M, result._data, &lda, ipiv, work, &lwork, &info); delete [] work; } delete [] ipiv; if(info == 0) return true; else if(info > 0) Msg::Error("U(%d,%d)=0 in matrix inversion", info, info); else Msg::Error("Wrong %d-th argument in matrix inversion", -info); return false; }
template<class T2> void BilinearTermContract<T2>::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const { fullVector<T2> va; fullVector<T2> vb; a->get(ele,npts,GP,va); b->get(ele,npts,GP,vb); m.resize(va.size(), vb.size()); m.setAll(0.); for (int i=0;i<va.size();++i) for (int j=0;j<vb.size();++j) m(i,j)=dot(va(i),vb(j)); }
void BilinearTermBase::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const { std::vector<fullMatrix<double> > mv(npts); get(ele,npts,GP,mv); m.resize(mv[0].size1(), mv[0].size2()); m.setAll(0.); double jac[3][3]; for (int k=0;k<npts;k++) { const double u = GP[k].pt[0]; const double v = GP[k].pt[1]; const double w = GP[k].pt[2]; const double weight = GP[k].weight; const double detJ = ele->getJacobian(u, v, w, jac); const double coeff=weight*detJ; for (int i=0;i<mv[k].size1();++i) for (int j=0;j<mv[k].size2();++j) m(i,j)+=mv[k](i,j)*coeff; } }
template<class T1> void LaplaceTerm<T1, T1>::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const { int nbFF = BilinearTerm<T1, T1>::space1.getNumKeys(ele); double jac[3][3]; m.resize(nbFF, nbFF); m.setAll(0.); for(int i = 0; i < npts; i++){ const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2]; const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac); std::vector<typename TensorialTraits<T1>::GradType> Grads; BilinearTerm<T1, T1>::space1.gradf(ele, u, v, w, Grads); for(int j = 0; j < nbFF; j++) { for(int k = j; k < nbFF; k++) { double contrib = weight * detJ * dot(Grads[j], Grads[k]) * diffusivity; m(j, k) += contrib; if(j != k) m(k, j) += contrib; } } } }
void IsotropicElasticTerm::get(MElement *ele, int npts, IntPt *GP, fullMatrix<double> &m) const { if(ele->getParent()) ele = ele->getParent(); if(sym) { int nbFF = BilinearTerm<SVector3, SVector3>::space1.getNumKeys(ele); double jac[3][3]; fullMatrix<double> B(6, nbFF); fullMatrix<double> BTH(nbFF, 6); fullMatrix<double> BT(nbFF, 6); m.resize(nbFF, nbFF); m.setAll(0.); // std::cout << m.size1() << " " << m.size2() << std::endl; for(int i = 0; i < npts; i++) { const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2]; const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac); std::vector<TensorialTraits<SVector3>::GradType> Grads; BilinearTerm<SVector3, SVector3>::space1.gradf(ele, u, v, w, Grads); // a optimiser ?? for(int j = 0; j < nbFF; j++) { BT(j, 0) = B(0, j) = Grads[j](0, 0); BT(j, 1) = B(1, j) = Grads[j](1, 1); BT(j, 2) = B(2, j) = Grads[j](2, 2); BT(j, 3) = B(3, j) = Grads[j](0, 1) + Grads[j](1, 0); BT(j, 4) = B(4, j) = Grads[j](1, 2) + Grads[j](2, 1); BT(j, 5) = B(5, j) = Grads[j](0, 2) + Grads[j](2, 0); } BTH.setAll(0.); BTH.gemm(BT, H); m.gemm(BTH, B, weight * detJ, 1.); // m = m + w*detJ*BT*H*B } } else { int nbFF1 = BilinearTerm<SVector3, SVector3>::space1.getNumKeys(ele); int nbFF2 = BilinearTerm<SVector3, SVector3>::space2.getNumKeys(ele); double jac[3][3]; fullMatrix<double> B(6, nbFF2); fullMatrix<double> BTH(nbFF2, 6); fullMatrix<double> BT(nbFF1, 6); m.resize(nbFF1, nbFF2); m.setAll(0.); // Sum on Gauss Points i for(int i = 0; i < npts; i++) { const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2]; const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac); std::vector<TensorialTraits<SVector3>::GradType> Grads; // tableau de matrices... std::vector<TensorialTraits<SVector3>::GradType> GradsT; // tableau de matrices... BilinearTerm<SVector3, SVector3>::space1.gradf(ele, u, v, w, Grads); BilinearTerm<SVector3, SVector3>::space2.gradf(ele, u, v, w, GradsT); for(int j = 0; j < nbFF1; j++) { BT(j, 0) = Grads[j](0, 0); BT(j, 1) = Grads[j](1, 1); BT(j, 2) = Grads[j](2, 2); BT(j, 3) = Grads[j](0, 1) + Grads[j](1, 0); BT(j, 4) = Grads[j](1, 2) + Grads[j](2, 1); BT(j, 5) = Grads[j](0, 2) + Grads[j](2, 0); } for(int j = 0; j < nbFF2; j++) { B(0, j) = GradsT[j](0, 0); B(1, j) = GradsT[j](1, 1); B(2, j) = GradsT[j](2, 2); B(3, j) = GradsT[j](0, 1) + GradsT[j](1, 0); B(4, j) = GradsT[j](1, 2) + GradsT[j](2, 1); B(5, j) = GradsT[j](0, 2) + GradsT[j](2, 0); } BTH.setAll(0.); BTH.gemm(BT, H); // gemm add the product to m so there is a sum on gauss' points here m.gemm(BTH, B, weight * detJ, 1.); } } }