double FEI3dTetQuad :: surfaceEvalNormal(FloatArray &answer, int isurf, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { IntArray snodes(3); FloatArray a,b; this->computeLocalSurfaceMapping(snodes, isurf); double l1, l2, l3; l1 = lcoords.at(1); l2 = lcoords.at(2); l3 = 1.0 - l1 - l2; FloatArray dNdxi(6), dNdeta(6); dNdxi(0) = 4.0 * l1 - 1.0; dNdxi(1) = 0.0; dNdxi(2) = -1.0 * ( 4.0 * l3 - 1.0 ); dNdxi(3) = 4.0 * l2; dNdxi(4) = -4.0 * l2; dNdxi(5) = 4.0 * l3 - 4.0 * l1; dNdeta(0) = 0.0; dNdeta(1) = 4.0 * l2 - 1.0; dNdeta(2) = -1.0 * ( 4.0 * l3 - 1.0 ); dNdeta(3) = 4.0 * l1; dNdeta(4) = 4.0 * l3 - 4.0 * l2; dNdeta(5) = -4.0 * l1; for (int i = 0; i < 6; ++i) { a.add(dNdxi(i), *cellgeo.giveVertexCoordinates(snodes(i))); b.add(dNdeta(i), *cellgeo.giveVertexCoordinates(snodes(i))); } answer.beVectorProductOf(a, b); double J = answer.computeNorm(); answer.times(1/J); return J; }
int LSpace :: computeLoadLSToLRotationMatrix(FloatMatrix &answer, int isurf, GaussPoint *gp) { // returns transformation matrix from // surface local coordinate system // to element local c.s // (same as global c.s in this case) // // i.e. f(element local) = T * f(edge local) // definition of local c.s on surface: // local z axis - perpendicular to surface, pointing outwards from element // local x axis - is in global xy plane (perpendicular to global z axis) // local y axis - completes the righ hand side cs. /* * OOFEM_ERROR("surface local coordinate system not supported"); * return 1; */ FloatArray gc(3); FloatArray h1(3), h2(3), nn(3), n(3); IntArray snodes(4); answer.resize(3, 3); this->interpolation.computeSurfaceMapping(snodes, dofManArray, isurf); for ( int i = 1; i <= 4; i++ ) { gc.add( * domain->giveNode( snodes.at(i) )->giveCoordinates() ); } gc.times(1. / 4.); // determine "average normal" for ( int i = 1; i <= 4; i++ ) { int j = ( i ) % 4 + 1; h1 = * domain->giveNode( snodes.at(i) )->giveCoordinates(); h1.subtract(gc); h2 = * domain->giveNode( snodes.at(j) )->giveCoordinates(); h2.subtract(gc); n.beVectorProductOf(h1, h2); if ( n.computeSquaredNorm() > 1.e-6 ) { n.normalize(); } nn.add(n); } nn.times(1. / 4.); if ( nn.computeSquaredNorm() < 1.e-6 ) { answer.zero(); return 1; } nn.normalize(); for ( int i = 1; i <= 3; i++ ) { answer.at(i, 3) = nn.at(i); } // determine lcs of surface // local x axis in xy plane double test = fabs(fabs( nn.at(3) ) - 1.0); if ( test < 1.e-5 ) { h1.at(1) = answer.at(1, 1) = 1.0; h1.at(2) = answer.at(2, 1) = 0.0; } else { h1.at(1) = answer.at(1, 1) = answer.at(2, 3); h1.at(2) = answer.at(2, 1) = -answer.at(1, 3); } h1.at(3) = answer.at(3, 1) = 0.0; // local y axis perpendicular to local x,z axes h2.beVectorProductOf(nn, h1); for ( int i = 1; i <= 3; i++ ) { answer.at(i, 2) = h2.at(i); } return 1; }
void LSpace :: drawTriad(FloatArray &coords, int isurf) { FloatMatrix jm(3, 3); FloatArray gc(3); GraphicObj *go; WCRec p [ 2 ]; // point double coeff = 1.0; int i, succ; /* * // version I * this->interpolation.giveJacobianMatrixAt (jm, domain, nodeArray, coords); * // determine origin * this->interpolation.local2global (gc, domain, nodeArray, coords, 0.0); * // draw triad * */ // version II // determine surface center IntArray snodes(4); FloatArray h1(3), h2(3), nn(3), n(3); int j; const char *colors[] = { "red", "green", "blue" }; this->interpolation.computeSurfaceMapping(snodes, dofManArray, isurf); for ( i = 1; i <= 4; i++ ) { gc.add( * ( domain->giveNode( snodes.at(i) )->giveCoordinates() ) ); } gc.times(1. / 4.); // determine "average normal" nn.zero(); for ( i = 1; i <= 4; i++ ) { j = ( i ) % 4 + 1; h1 = * domain->giveNode( snodes.at(i) )->giveCoordinates(); h1.subtract(gc); h2 = * domain->giveNode( snodes.at(j) )->giveCoordinates(); h2.subtract(gc); n.beVectorProductOf(h1, h2); if ( n.dotProduct(n, 3) > 1.e-6 ) { n.normalize(); } nn.add(n); } nn.times(1. / 4.); if ( nn.dotProduct(nn, 3) < 1.e-6 ) { return; } nn.normalize(); for ( i = 1; i <= 3; i++ ) { jm.at(i, 3) = nn.at(i); } // determine lcs of surface // local x axis in xy plane double test = fabs(fabs( nn.at(3) ) - 1.0); if ( test < 1.e-5 ) { h1.at(1) = jm.at(1, 1) = 1.0; h1.at(2) = jm.at(2, 1) = 0.0; } else { h1.at(1) = jm.at(1, 1) = jm.at(2, 3); h1.at(2) = jm.at(2, 1) = -jm.at(1, 3); } h1.at(3) = jm.at(3, 1) = 0.0; // local y axis perpendicular to local x,z axes h2.beVectorProductOf(nn, h1); for ( i = 1; i <= 3; i++ ) { jm.at(i, 2) = h2.at(i); } p [ 0 ].x = gc.at(1); p [ 0 ].y = gc.at(2); p [ 0 ].z = gc.at(3); for ( i = 1; i <= 3; i++ ) { p [ 1 ].x = p [ 0 ].x + coeff *jm.at(1, i); p [ 1 ].y = p [ 0 ].y + coeff *jm.at(2, i); p [ 1 ].z = p [ 0 ].z + coeff *jm.at(3, i); EASValsSetColor( ColorGetPixelFromString(const_cast< char * >(colors [ i - 1 ]), & succ) ); go = CreateLine3D(p); EGWithMaskChangeAttributes(WIDTH_MASK | COLOR_MASK | LAYER_MASK, go); EMAddGraphicsToModel(ESIModel(), go); } }