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; }
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; } } } }
void fullMatrix<double>::multOnBlock(const fullMatrix<double> &b, const int ncol, const int fcol, const int alpha_, const int beta_, fullVector<double> &c) const { int M = 1, N = ncol, K = b.size1() ; int LDA = _r, LDB = b.size1(), LDC = 1; double alpha = alpha_, beta = beta_; F77NAME(dgemm)("N", "N", &M, &N, &K, &alpha, _data, &LDA, &(b._data[fcol*K]), &LDB, &beta, &(c._data[fcol]), &LDC); }
void fullMatrix<double>::mult(const fullMatrix<double> &b, fullMatrix<double> &c) const { int M = c.size1(), N = c.size2(), K = _c; int LDA = _r, LDB = b.size1(), LDC = c.size1(); double alpha = 1., beta = 0.; F77NAME(dgemm)("N", "N", &M, &N, &K, &alpha, _data, &LDA, b._data, &LDB, &beta, c._data, &LDC); }
void fullMatrix<double>::gemm(const fullMatrix<double> &a, const fullMatrix<double> &b, double alpha, double beta, bool transposeA, bool transposeB) { int M = size1(), N = size2(), K = transposeA ? a.size1() : a.size2(); int LDA = a.size1(), LDB = b.size1(), LDC = size1(); F77NAME(dgemm)(transposeA ? "T" : "N", transposeB ? "T" :"N", &M, &N, &K, &alpha, a._data, &LDA, b._data, &LDB, &beta, _data, &LDC); }
void PViewFactory::setEntry (int id, const fullMatrix<double> &val) { std::vector<double> &vv = _values[id]; vv.resize(val.size1()*val.size2()); int k=0; for (int i=0;i<val.size1(); i++) { for (int j=0;j<val.size2(); j++) { vv[k++] = val(i,j); } } }
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)); }
bool fullMatrix<double>::svd(fullMatrix<double> &V, fullVector<double> &S) { fullMatrix<double> VT(V.size2(), V.size1()); int M = size1(), N = size2(), LDA = size1(), LDVT = VT.size1(), info; int lwork = std::max(3 * std::min(M, N) + std::max(M, N), 5 * std::min(M, N)); fullVector<double> WORK(lwork); F77NAME(dgesvd)("O", "A", &M, &N, _data, &LDA, S._data, _data, &LDA, VT._data, &LDVT, WORK._data, &lwork, &info); V = VT.transpose(); if(info == 0) return true; if(info > 0) Msg::Error("SVD did not converge"); else Msg::Error("Wrong %d-th argument in SVD decomposition", -info); return false; }
void polynomialBasis::df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const { double dfv[1256][3]; dfm.resize(coord.size1() * 3, coefficients.size1(), false); int dimCoord = coord.size2(); for(int iPoint = 0; iPoint < coord.size1(); iPoint++) { df(coord(iPoint, 0), dimCoord > 1 ? coord(iPoint, 1) : 0., dimCoord > 2 ? coord(iPoint, 2) : 0., dfv); for(int i = 0; i < coefficients.size1(); i++) { dfm(iPoint * 3 + 0, i) = dfv[i][0]; dfm(iPoint * 3 + 1, i) = dfv[i][1]; dfm(iPoint * 3 + 2, i) = dfv[i][2]; } } }
void polynomialBasis::f(const fullMatrix<double> &coord, fullMatrix<double> &sf) const { double p[1256]; sf.resize(coord.size1(), coefficients.size1()); for(int iPoint = 0; iPoint < coord.size1(); iPoint++) { evaluateMonomials(coord(iPoint, 0), coord.size2() > 1 ? coord(iPoint, 1) : 0, coord.size2() > 2 ? coord(iPoint, 2) : 0, p); for(int i = 0; i < coefficients.size1(); i++) { sf(iPoint, i) = 0.; for(int j = 0; j < coefficients.size2(); j++) sf(iPoint, i) += coefficients(i, j) * p[j]; } } }
void epsRRod(fullVector<double>& xyz, fullMatrix<Complex>& epsR){ epsR.scale(0); epsR(0, 0) = Complex(epsRRodRe, epsRRodIm); epsR(1, 1) = Complex(epsRRodRe, epsRRodIm); epsR(2, 2) = Complex(epsRRodRe, epsRRodIm); }
void nuRRod(fullVector<double>& xyz, fullMatrix<Complex>& nuR){ nuR.scale(0); nuR(0, 0) = 1; nuR(1, 1) = 1; nuR(2, 2) = 1; }
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; } }
void ana(double (*f)(fullVector<double>& xyz), const fullMatrix<double>& point, fullMatrix<double>& eval){ // Alloc eval for Scalar Values // const size_t nPoint = point.size1(); eval.resize(nPoint, 1); // Loop on point and evaluate f // fullVector<double> xyz(3); for(size_t i = 0; i < nPoint; i++){ xyz(0) = point(i, 0); xyz(1) = point(i, 1); xyz(2) = point(i, 2); eval(i, 0) = f(xyz); } }
double l2Norm(const fullMatrix<double>& valA, const fullMatrix<double>& valB){ const size_t nPoint = valA.size1(); const size_t dim = valA.size2(); double norm = 0; double modSquare = 0; for(size_t i = 0; i < nPoint; i++){ modSquare = 0; for(size_t j = 0; j < dim; j++) modSquare += (valA(i, j) - valB(i, j)) * (valA(i, j) - valB(i, j)); norm += modSquare; } return norm = sqrt(norm); }
void pyramidalBasis::f(const fullMatrix<double> &coord, fullMatrix<double> &sf) const { const int N = bergot->size(), NPts = coord.size1(); sf.resize(NPts, N); double *fval = new double[N]; for (int iPt=0; iPt<NPts; iPt++) { bergot->f(coord(iPt,0), coord(iPt,1), coord(iPt,2), fval); for (int i = 0; i < N; i++) { sf(iPt,i) = 0.; for (int j = 0; j < N; j++) sf(iPt,i) += coefficients(i,j)*fval[j]; } } delete[] fval; }
void Quadrature::point(fullMatrix<double>& gC, fullVector<double>& gW){ gW.resize(1); gC.resize(1, 1); gW(0) = 1; gC(0, 0) = 0; gC(0, 1) = 0; gC(0, 2) = 0; }
void solve( const fullMatrix & A, fullMatrix& X, const fullMatrix& Y ) { // find X s.t. A X = Y using Gausian Elimination with // row pivoting -- no scaling this version if( A.row != A.col ){ std::cerr << "solve only works for square matrices\n"; return; } int i, j, k, n = A.col, m=Y.col; double s, pa; // initialize X to Y and copy A X = Y; fullMatrix B(A); // could scale here // next do forward elimination and forward solution for( i=0; i<n; i++ ){ // clean up the i-th column // find the pivot k = i; // row with the pivot pa = std::abs(B(i,i)); for( j=i+1; j<n; j++ ) if( std::abs(B(j,i)) > pa ){ pa = std::abs(B(j,i)); k = j; } if( pa == 0.0 ) error( "solve: singular matrix"); B.swapRows(i,k); X.swapRows(i,k); // the pivot is now in B(i,i) for( j=i+1; j<n; j++ ){ // for each row below row i s = B(j,i)/B(i,i); for( k=i+1; k<n; k++ ) // modifications that make B(j,i) zero B(j,k) -= s*B(i,k); for( k=0; k<m; k++ ) // change the rhs too X(j,k) -= s*X(i,k); } } // now B is upper triangular for( i=n-1; i>=0; i-- ){ // do back solution for(j = i+1; j<n; j++ ){ for( k=0; k<m; k++ ) X(i,k) -= B(i,j)*X(j,k); } for( k=0; k<m; k++ ) X(i,k) /= B(i,i); } }
void pyramidalBasis::df(const fullMatrix<double> &coord, fullMatrix<double> &dfm) const { const int N = bergot->size(), NPts = coord.size1(); double (*dfv)[3] = new double[N][3]; dfm.resize (N, 3*NPts, false); for (int iPt=0; iPt<NPts; iPt++) { df(coord(iPt,0), coord(iPt,1), coord(iPt,2), dfv); for (int i = 0; i < N; i++) { dfm(i, 3*iPt) = dfv[i][0]; dfm(i, 3*iPt+1) = dfv[i][1]; dfm(i, 3*iPt+2) = dfv[i][2]; } } delete[] dfv; }
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; } } } }
double taylorDistanceSq1D(const GradientBasis *gb, const fullMatrix<double> &nodesXYZ, const std::vector<SVector3> &tanCAD) { const int nV = nodesXYZ.size1(); fullMatrix<double> dxyzdX(nV, 3); gb->getGradientsFromNodes(nodesXYZ, &dxyzdX, 0, 0); // const double dx = nodesXYZ(1, 0) - nodesXYZ(0, 0), dy = nodesXYZ(1, 1) - nodesXYZ(0, 1), // dz = nodesXYZ(1, 2) - nodesXYZ(0, 2), h = 0.5*sqrt(dx*dx+dy*dy+dz*dz)/double(nV-1); double distSq = 0.; for (int i=0; i<nV; i++) { SVector3 tanMesh(dxyzdX(i, 0), dxyzdX(i, 1), dxyzdX(i, 2)); const double h = 0.25*tanMesh.normalize(); // Half of "local edge length" SVector3 diff = (dot(tanCAD[i], tanMesh) > 0) ? tanCAD[i] - tanMesh : tanCAD[i] + tanMesh; distSq += h*h*diff.normSq(); } return distSq; }
double taylorDistanceSq2D(const GradientBasis *gb, const fullMatrix<double> &nodesXYZ, const std::vector<SVector3> &normCAD) { const int nV = nodesXYZ.size1(); fullMatrix<double> dxyzdX(nV, 3), dxyzdY(nV, 3); gb->getGradientsFromNodes(nodesXYZ, &dxyzdX, &dxyzdY, 0); double distSq = 0.; for (int i=0; i<nV; i++) { const double nz = dxyzdX(i, 0) * dxyzdY(i, 1) - dxyzdX(i, 1) * dxyzdY(i, 0); const double ny = -dxyzdX(i, 0) * dxyzdY(i, 2) + dxyzdX(i, 2) * dxyzdY(i, 0); const double nx = dxyzdX(i, 1) * dxyzdY(i, 2) - dxyzdX(i, 2) * dxyzdY(i, 1); SVector3 normMesh(nx, ny, nz); const double h = 0.25*sqrt(normMesh.normalize()); // Half of sqrt of "local area", to be adjusted w.r.t. el. type? SVector3 diff = (dot(normCAD[i], normMesh) > 0) ? normCAD[i] - normMesh : normCAD[i] + normMesh; distSq += h*h*diff.normSq(); } return distSq; }
void linearSystemPETSc<fullMatrix<double> >::addToMatrix(int row, int col, const fullMatrix<double> &val) { if (!_entriesPreAllocated) preAllocateEntries(); #ifdef PETSC_USE_COMPLEX fullMatrix<std::complex<double> > modval(val.size1(), val.size2()); for (int ii = 0; ii < val.size1(); ii++) { for (int jj = 0; jj < val.size1(); jj++) { modval(ii, jj) = val (jj, ii); modval(jj, ii) = val (ii, jj); } } #else fullMatrix<double> &modval = *const_cast<fullMatrix<double> *>(&val); for (int ii = 0; ii < val.size1(); ii++) { for (int jj = 0; jj < ii; jj++) { PetscScalar buff = modval(ii, jj); modval(ii, jj) = modval (jj, ii); modval(jj, ii) = buff; } } #endif PetscInt i = row, j = col; MatSetValuesBlocked(_a, 1, &i, 1, &j, &modval(0,0), ADD_VALUES); //transpose back so that the original matrix is not modified #ifndef PETSC_USE_COMPLEX for (int ii = 0; ii < val.size1(); ii++) for (int jj = 0; jj < ii; jj++) { PetscScalar buff = modval(ii,jj); modval(ii, jj) = modval (jj,ii); modval(jj, ii) = buff; } #endif _valuesNotAssembled = true; }
// Calculate (signed) Jacobian and its gradients for one element, with normal vectors to straight element // for regularization. Evaluation points depend on the given matrices for shape function gradients. void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const { switch (_dim) { case 0 : { for (int i = 0; i < nJacNodes; i++) { for (int j = 0; j < numMapNodes; j++) { JDJ (i,j) = 0.; JDJ (i,j+1*numMapNodes) = 0.; JDJ (i,j+2*numMapNodes) = 0.; } JDJ(i,3*numMapNodes) = 1.; } break; } case 1 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dPhidX * dzdY * dydZ; JDJ (i,j+1*numMapNodes) = dPhidX * dzdY * dxdZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dPhidX * dxdY * dydZ - dPhidX * dydY * dxdZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 2 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = normals(0,0), &dydZ = normals(0,1), &dzdZ = normals(0,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); const double &dPhidY = gSMatY(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ + dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ; JDJ (i,j+1*numMapNodes) = dxdX * dPhidY * dzdZ + dPhidX * dzdY * dxdZ - dzdX * dPhidY * dxdZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dPhidX * dxdY * dydZ + dydX * dPhidY * dxdZ - dPhidX * dydY * dxdZ - dxdX * dPhidY * dydZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 3 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3), dxyzdZ(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); gSMatZ.mult(nodesXYZ, dxyzdZ); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); const double &dPhidY = gSMatY(i,j); const double &dPhidZ = gSMatZ(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ + dydX * dzdY * dPhidZ - dzdX * dydY * dPhidZ - dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ; JDJ (i,j+1*numMapNodes) = dxdX * dPhidY * dzdZ + dzdX * dxdY * dPhidZ + dPhidX * dzdY * dxdZ - dzdX * dPhidY * dxdZ - dxdX * dzdY * dPhidZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dxdX * dydY * dPhidZ + dPhidX * dxdY * dydZ + dydX * dPhidY * dxdZ - dPhidX * dydY * dxdZ - dxdX * dPhidY * dydZ - dydX * dxdY * dPhidZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } } }
bool fullMatrix<double>::invert(fullMatrix<double> &result) const { if(_r != _c) return false; // Copy the matrix result.resize(_r,_c); // to find out Determinant double det = this->determinant(); if(det == 0) return false; // Matrix of cofactor put this in a function? fullMatrix<double> cofactor(_r,_c); if(_r == 2) { cofactor(0,0) = (*this)(1,1); cofactor(0,1) = -(*this)(1,0); cofactor(1,0) = -(*this)(0,1); cofactor(1,1) = (*this)(0,0); } else if(_r >= 3) { std::vector<std::vector<fullMatrix<double> > > temp(_r,std::vector<fullMatrix<double> >(_r,fullMatrix<double>(_r-1,_r-1))); for(int k1 = 0; k1 < _r; k1++) { for(int k2 = 0; k2 < _r; k2++) { int i1 = 0; for(int i = 0; i < _r; i++) { int j1 = 0; for(int j = 0; j < _r; j++) { if(k1 != i && k2 != j) temp[k1][k2](i1,j1++) = (*this)(i,j); } if(k1 != i) i1++; } } } bool flagPositive; for(int k1 = 0; k1 < _r; k1++) { flagPositive = (k1 % 2) == 0 ? true : false; for(int k2 = 0; k2 < _r; k2++) { if(flagPositive) { cofactor(k1,k2) = temp[k1][k2].determinant(); flagPositive = false; } else { cofactor(k1,k2) = -temp[k1][k2].determinant(); flagPositive = true; } } } } // end cofactor // inv = transpose of cofactor / Determinant for(int i = 0; i < _r; i++) { for(int j = 0; j < _c; j++) { result(j,i) = cofactor(i,j) / det; } } return true; }
void fMaterial(fullVector<double>& xyz, fullMatrix<double>& tensor){ tensor.scale(0); tensor(0, 0) = 1; tensor(1, 1) = 2; tensor(2, 2) = 1; }
void write(bool isScalar, const fullMatrix<double>& l2, string name){ // Stream ofstream stream; string fileName; if(isScalar) fileName = name + "Node.m"; else fileName = name + "Edge.m"; stream.open(fileName.c_str()); // Matrix data const size_t l2Row = l2.size1(); const size_t l2ColMinus = l2.size2() - 1; // Clean Octave stream << "close all;" << endl << "clear all;" << endl << endl; // Mesh (Assuming uniform refinement) stream << "h = [1, "; for(size_t i = 1; i < l2ColMinus; i++) stream << 1 / pow(2, i) << ", "; stream << 1 / pow(2, l2ColMinus) << "];" << endl; // Order (Assuming uniform refinement) stream << "p = [1:" << l2Row << "];" << endl << endl; // Matrix of l2 error (l2[Order][Mesh]) stream << "l2 = ..." << endl << " [..." << endl; for(size_t i = 0; i < l2Row; i++){ stream << " "; for(size_t j = 0; j < l2ColMinus; j++) stream << scientific << showpos << l2(i, j) << " , "; stream << scientific << showpos << l2(i, l2ColMinus) << " ; ..." << endl; } stream << " ];" << endl << endl; // Delta stream << "P = size(p, 2);" << endl << "H = size(h, 2);" << endl << endl << "delta = zeros(P, H - 1);" << endl << endl << "for i = 1:H-1" << endl << " delta(:, i) = ..." << endl << " (log10(l2(:, i + 1)) - log10(l2(:, i))) / ..." << endl << " (log10(1/h(i + 1)) - log10(1/h(i)));" << endl << "end" << endl << endl << "delta" << endl << endl; // Plot stream << "figure;" << endl << "loglog(1./h, l2', '-*');" << endl << "grid;" << endl; // Title stream << "title(" << "'" << name << ": "; if(isScalar) stream << "Nodal"; else stream << "Edge"; stream << "');" << endl << endl; // Axis stream << "xlabel('1/h [-]');" << endl << "ylabel('L2 Error [-]');" << endl; // Close stream.close(); }
inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY, const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const { switch (_dim) { case 0 : { const int numEl = nodesX.size2(); for (int iEl = 0; iEl < numEl; iEl++) for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = 1.; break; } case 1 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); for (int iEl = 0; iEl < numEl; iEl++) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } fullMatrix<double> normals(2,3); const double invScale = getPrimNormals1D(nodesXYZ,normals); if (scaling) { const double scale = 1./invScale; normals(0,0) *= scale; normals(0,1) *= scale; normals(0,2) *= scale; // Faster to scale 1 normal than afterwards } const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY,dydY,dzdY, dxdZ,dydZ,dzdZ); } break; } case 2 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY); for (int iEl = 0; iEl < numEl; iEl++) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } fullMatrix<double> normal(1,3); const double invScale = getPrimNormal2D(nodesXYZ,normal); if (scaling) { const double scale = 1./invScale; normal(0,0) *= scale; normal(0,1) *= scale; normal(0,2) *= scale; // Faster to scale normal than afterwards } const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl), dxdZ,dydZ,dzdZ); } break; } case 3 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl); fullMatrix<double> dxdZ(nJacNodes,numEl), dydZ(nJacNodes,numEl), dzdZ(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY); gSMatZ.mult(nodesX, dxdZ); gSMatZ.mult(nodesY, dydZ); gSMatZ.mult(nodesZ, dzdZ); for (int iEl = 0; iEl < numEl; iEl++) { for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl), dxdZ(i,iEl),dydZ(i,iEl),dzdZ(i,iEl)); if (scaling) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } const double scale = 1./getPrimJac3D(nodesXYZ); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) *= scale; } } break; } } }
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.); } } }
inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { switch (_dim) { case 0 : { for (int i = 0; i < nJacNodes; i++) jacobian(i) = 1.; break; } case 1 : { fullMatrix<double> normals(2,3); const double invScale = getPrimNormals1D(nodesXYZ,normals); if (scaling) { const double scale = 1./invScale; normals(0,0) *= scale; normals(0,1) *= scale; normals(0,2) *= scale; // Faster to scale 1 normal than afterwards } fullMatrix<double> dxyzdX(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 2 : { fullMatrix<double> normal(1,3); const double invScale = getPrimNormal2D(nodesXYZ,normal); if (scaling) { const double scale = 1./invScale; normal(0,0) *= scale; normal(0,1) *= scale; normal(0,2) *= scale; // Faster to scale normal than afterwards } fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 3 : { fullMatrix<double> dum; fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3), dxyzdZ(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); gSMatZ.mult(nodesXYZ, dxyzdZ); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } if (scaling) { const double scale = 1./getPrimJac3D(nodesXYZ); jacobian.scale(scale); } break; } } }