bool CCTPlate3d :: computeLocalCoordinates(FloatArray &answer, const FloatArray &coords) //converts global coordinates to local planar area coordinates, //does not return a coordinate in the thickness direction, but //does check that the point is in the element thickness { // rotate the input point Coordinate System into the element CS FloatArray inputCoords_ElCS; std::vector< FloatArray > lc(3); FloatArray llc; this->giveLocalCoordinates( inputCoords_ElCS, const_cast< FloatArray & >(coords) ); for ( int _i = 0; _i < 3; _i++ ) { this->giveLocalCoordinates( lc [ _i ], * this->giveNode(_i + 1)->giveCoordinates() ); } FEI2dTrLin _interp(1, 2); bool inplane = _interp.global2local(llc, inputCoords_ElCS, FEIVertexListGeometryWrapper(lc)) > 0; answer.resize(2); answer.at(1) = inputCoords_ElCS.at(1); answer.at(2) = inputCoords_ElCS.at(2); GaussPoint _gp(NULL, 1, new FloatArray ( answer ), 2.0, _2dPlate); // now check if the third local coordinate is within the thickness of element bool outofplane = ( fabs( inputCoords_ElCS.at(3) ) <= this->giveCrossSection()->give(CS_Thickness, & _gp) / 2. ); return inplane && outofplane; }
double Quad1_ht :: computeEdgeVolumeAround(GaussPoint *gp, int iEdge) { double result = this->interpolation.edgeGiveTransformationJacobian( iEdge, * gp->giveCoordinates(), FEIElementGeometryWrapper(this) ); FloatArray gc; this->interpolation.edgeLocal2global( gc, iEdge, * gp->giveCoordinates(), FEIElementGeometryWrapper(this) ); // temporary gauss point on element (not edge) to evaluate thickness GaussPoint _gp( NULL, 1, new FloatArray ( gc ), 1.0, gp->giveMaterialMode() ); double thick = this->giveCrossSection()->give(CS_Thickness, & _gp); // 't' return result *thick *gp->giveWeight(); }
bool RerShell :: computeLocalCoordinates(FloatArray &answer, const FloatArray &coords) { //set size of return value to 3 area coordinates answer.resize(3); //rotate the input point Coordinate System into the element CS FloatArray inputCoords_ElCS; this->giveLocalCoordinates( inputCoords_ElCS, const_cast< FloatArray & >(coords) ); //Nodes are defined in the global CS, so they also need to be rotated into the element CS, therefore get the node points and //rotate them into the element CS FloatArray nodeCoords; double x1, x2, x3, y1, y2, y3, z1, z2, z3; this->giveLocalCoordinates( nodeCoords, * ( this->giveNode(1)->giveCoordinates() ) ); x1 = nodeCoords.at(1); y1 = nodeCoords.at(2); z1 = nodeCoords.at(3); this->giveLocalCoordinates( nodeCoords, * ( this->giveNode(2)->giveCoordinates() ) ); x2 = nodeCoords.at(1); y2 = nodeCoords.at(2); z2 = nodeCoords.at(3); this->giveLocalCoordinates( nodeCoords, * ( this->giveNode(3)->giveCoordinates() ) ); x3 = nodeCoords.at(1); y3 = nodeCoords.at(2); z3 = nodeCoords.at(3); //Compute the area coordinates corresponding to this point double area; area = 0.5 * ( x2 * y3 + x1 * y2 + y1 * x3 - x2 * y1 - x3 * y2 - x1 * y3 ); answer.at(1) = ( ( x2 * y3 - x3 * y2 ) + ( y2 - y3 ) * inputCoords_ElCS.at(1) + ( x3 - x2 ) * inputCoords_ElCS.at(2) ) / 2. / area; answer.at(2) = ( ( x3 * y1 - x1 * y3 ) + ( y3 - y1 ) * inputCoords_ElCS.at(1) + ( x1 - x3 ) * inputCoords_ElCS.at(2) ) / 2. / area; answer.at(3) = ( ( x1 * y2 - x2 * y1 ) + ( y1 - y2 ) * inputCoords_ElCS.at(1) + ( x2 - x1 ) * inputCoords_ElCS.at(2) ) / 2. / area; //get midplane location at this point double midplZ; midplZ = z1 * answer.at(1) + z2 *answer.at(2) + z3 *answer.at(3); //check that the z is within the element StructuralCrossSection *cs = this->giveStructuralCrossSection(); GaussPoint _gp(NULL, 1, new FloatArray ( answer ), 1.0, _2dPlate); double elthick; elthick = cs->give(CS_Thickness, & _gp); if ( elthick / 2.0 + midplZ - fabs( inputCoords_ElCS.at(3) ) < -POINT_TOL ) { answer.zero(); return false; } //check that the point is in the element and set flag for ( int i = 1; i <= 3; i++ ) { if ( answer.at(i) < ( 0. - POINT_TOL ) ) { return false; } if ( answer.at(i) > ( 1. + POINT_TOL ) ) { return false; } } return true; }