double ShapeFunction::det_jacobian(const Element *el, const GaussPoint &g) const { double result; if(sfcache[g.order()]->query_jac(el, g, result)) return result; // don't be tempted to rewrite this in terms of // det_jacobian(Element*, MasterCoord&) because that one doesn't use // the precomputed values of the shape function derivatives! #if DIM==2 result = el->jacobian(0, 0, g) * el->jacobian(1, 1, g) - el->jacobian(0, 1, g) * el->jacobian(1, 0, g); #elif DIM==3 // typing out a closed form in code is messy for 3d double m[DIM][DIM]; int ii, jj; for(ii=0; ii<DIM; ++ii) { for(jj=0; jj<DIM; ++jj) { m[ii][jj] = el->jacobian(ii,jj,g); } } result = vtkMath::Determinant3x3(m); #endif sfcache[g.order()]->store_jac(el, g, result); return result; }
double ShapeFunction::realderiv(const Element *el, ShapeFunctionIndex n, SpaceIndex i, const GaussPoint &g) const { // Trace("ShapeFunction::realderiv 1"); double result = 0; if(sfcache[g.order()]->query_dsf(el, n, i, g, result)) return result; // don't be tempted to rewrite this in terms of // realderiv(Element*, ..., MasterCoord&) because that one doesn't use // the precomputed values of the shape function derivatives! for(SpaceIndex j=0; j<DIM; ++j) result += el->Jdmasterdx(j, i, g)*masterderiv(n, j, g); result /= el->det_jacobian(g); sfcache[g.order()]->store_dsf(el, n, i, g, result); return result; }
double ShapeFunction::value(ShapeFunctionIndex n, const GaussPoint &g) const { return sftable[g.order()]->f_table[g.index()][n]; }
// derivative wrt master coordinates double ShapeFunction::masterderiv(ShapeFunctionIndex n, SpaceIndex j, const GaussPoint &g) const { // Trace("ShapeFunction::masterderiv sf=" + to_string(n) + " gpt=" + to_string(g.mastercoord())); return sftable[g.order()]->df_table[g.index()][n][j]; }