void
TrPlanestressRotAllman :: computeNmatrixAt(const FloatArray &iLocCoord, FloatMatrix &answer)
// Returns the displacement interpolation matrix {N} of the receiver, eva-
// luated at gp.
{
    FloatArray L, n;
    std::vector< FloatArray > lxy;

    answer.resize(3, 9);
    answer.zero();

    this->computeLocalNodalCoordinates(lxy); // get ready for tranformation into 3d
    this->qinterpolation.evalN( n, iLocCoord, FEIVertexListGeometryWrapper(lxy) );
    this->interp.evalN( L, iLocCoord, FEIVertexListGeometryWrapper(lxy));

    answer.at(1, 1) = answer.at(2, 2) = n.at(1) + n.at(4) / 2. + n.at(6) / 2.;
    answer.at(1, 4) = answer.at(2, 5) = n.at(2) + n.at(4) / 2. + n.at(5) / 2.;
    answer.at(1, 7) = answer.at(2, 8) = n.at(3) + n.at(5) / 2. + n.at(6) / 2.;
    answer.at(1, 3) = n.at(6) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0 - n.at(4) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0;
    answer.at(1, 6) = n.at(4) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0 - n.at(5) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0;
    answer.at(1, 9) = n.at(5) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0 - n.at(6) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0;
    answer.at(2, 3) = -n.at(6) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0 + n.at(4) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0;
    answer.at(2, 6) = -n.at(4) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0 + n.at(5) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0;
    answer.at(2, 9) = -n.at(5) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0 + n.at(6) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0;
    // linear approx for rotations
    answer.at(3, 3) = L.at(1);
    answer.at(3, 6) = L.at(2);
    answer.at(3, 9) = L.at(3);
}
示例#2
0
void
Quad1MindlinShell3D :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
{
    FloatArray n, ns;
    FloatMatrix dn, dns;
    const FloatArray &localCoords = * gp->giveNaturalCoordinates();

    this->interp.evaldNdx( dn, localCoords, FEIVertexListGeometryWrapper(lnodes) );
    this->interp.evalN( n, localCoords,  FEIVoidCellGeometry() );

    answer.resize(8, 4 * 5);
    answer.zero();

    // enforce one-point reduced integration if requested
    if ( this->reducedIntegrationFlag ) {
        FloatArray lc(2);
        lc.zero(); // set to element center coordinates

        this->interp.evaldNdx( dns, lc, FEIVertexListGeometryWrapper(lnodes) );
        this->interp.evalN( ns, lc,  FEIVoidCellGeometry() );
    } else {
        dns = dn;
        ns = n;
    }


    // Note: This is just 5 dofs (sixth column is all zero, torsional stiffness handled separately.)
    for ( int i = 0; i < 4; ++i ) {
        ///@todo Check the rows for both parts here, to be consistent with _3dShell material definition
        // Part related to the membrane (columns represent coefficients for D_u, D_v)
        answer(0, 0 + i * 5) = dn(i, 0);//eps_x = du/dx
        answer(1, 1 + i * 5) = dn(i, 1);//eps_y = dv/dy
        answer(2, 0 + i * 5) = dn(i, 1);//gamma_xy = du/dy+dv/dx
        answer(2, 1 + i * 5) = dn(i, 0);

        // Part related to the plate (columns represent the dofs D_w, R_u, R_v)
        ///@todo Check sign here
        answer(3 + 0, 2 + 2 + i * 5) = dn(i, 0);// kappa_x = d(fi_y)/dx
        answer(3 + 1, 2 + 1 + i * 5) =-dn(i, 1);// kappa_y = -d(fi_x)/dy
        answer(3 + 2, 2 + 2 + i * 5) = dn(i, 1);// kappa_xy=d(fi_y)/dy-d(fi_x)/dx
        answer(3 + 2, 2 + 1 + i * 5) =-dn(i, 0);

        // shear strains
        answer(3 + 3, 2 + 0 + i * 5) = dns(i, 0);// gamma_xz = fi_y+dw/dx
        answer(3 + 3, 2 + 2 + i * 5) = ns(i);
        answer(3 + 4, 2 + 0 + i * 5) = dns(i, 1);// gamma_yz = -fi_x+dw/dy
        answer(3 + 4, 2 + 1 + i * 5) = -ns(i);
    }
}
void
Quad1MindlinShell3D :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
{
    FloatArray n;
    FloatMatrix dn;

    this->interp.evaldNdx(dn, *gp->giveCoordinates(), FEIVertexListGeometryWrapper(4, (const FloatArray **)lnodes));
    this->interp.evalN(n, *gp->giveCoordinates(),  FEIVoidCellGeometry());

    answer.resize(8, 4*5);
    answer.zero();

    // Note: This is just 5 dofs (sixth column is all zero, torsional stiffness handled separately.)
    for (int i = 0; i < 4; ++i) {
        ///@todo Check the rows for both parts here, to be consistent with _3dShell material definition
        // Part related to the membrane (columns represent coefficients for D_u, D_v)
        answer(0, 0 + i*5) = dn(i,0);
        answer(1, 1 + i*5) = dn(i,1);
        answer(2, 0 + i*5) = dn(i,1);
        answer(2, 1 + i*5) = dn(i,0);

        // Part related to the plate (columns represent the dofs D_w, R_u, R_v)
        ///@todo Check sign here
        answer(3 + 0, 2 + 1 + i*5) = dn(i,0);
        answer(3 + 1, 2 + 2 + i*5) = dn(i,1);
        answer(3 + 2, 2 + 1 + i*5) = dn(i,1);
        answer(3 + 2, 2 + 2 + i*5) = dn(i,0);

        answer(3 + 3, 2 + 0 + i*5) = -dn(i,1);
        answer(3 + 3, 2 + 2 + i*5) = n(i);
        answer(3 + 4, 2 + 0 + i*5) = -dn(i,0);
        answer(3 + 4, 2 + 1 + i*5) = n(i);
    }
}
void
TrPlanestressRotAllman :: computeNmatrixAt(GaussPoint *aGaussPoint, FloatMatrix &answer)
// Returns the displacement interpolation matrix {N} of the receiver, eva-
// luated at aGaussPoint.
{
    FloatArray L(3), n(6), lxy[6];
    const FloatArray *lxyptr[]= {lxy, lxy+1, lxy+2, lxy+3, lxy+4, lxy+5};

    answer.resize(3, 9);
    answer.zero();

    this->computeLocalCoordinates(lxy); // get ready for tranformation into 3d
    this->qinterpolation.evalN( n, * aGaussPoint->giveCoordinates(), FEIVertexListGeometryWrapper(6, lxyptr) );
    this->interp.evalN (L, * aGaussPoint->giveCoordinates(), FEIElementGeometryWrapper(this) );

    answer.at(1,1) = answer.at(2,2) = n.at(1)+n.at(4)/2.+n.at(6)/2.;
    answer.at(1,4) = answer.at(2,5) = n.at(2)+n.at(4)/2.+n.at(5)/2.;
    answer.at(1,7) = answer.at(2,8) = n.at(3)+n.at(5)/2.+n.at(6)/2.;
    answer.at(1,3) = n.at(6)*(lxy[0].at(2)-lxy[2].at(2))/8.0-n.at(4)*(lxy[1].at(2)-lxy[0].at(2))/8.0;
    answer.at(1,6) = n.at(4)*(lxy[1].at(2)-lxy[0].at(2))/8.0-n.at(5)*(lxy[2].at(2)-lxy[1].at(2))/8.0;
    answer.at(1,9) = n.at(5)*(lxy[2].at(2)-lxy[1].at(2))/8.0-n.at(6)*(lxy[0].at(2)-lxy[2].at(2))/8.0;
    answer.at(2,3) =-n.at(6)*(lxy[0].at(1)-lxy[2].at(1))/8.0+n.at(4)*(lxy[1].at(1)-lxy[0].at(1))/8.0;
    answer.at(2,6) =-n.at(4)*(lxy[1].at(1)-lxy[0].at(1))/8.0+n.at(5)*(lxy[2].at(1)-lxy[1].at(1))/8.0;
    answer.at(2,9) =-n.at(5)*(lxy[2].at(1)-lxy[1].at(1))/8.0+n.at(6)*(lxy[0].at(1)-lxy[2].at(1))/8.0;
    // linear approx for rotations
    answer.at(3,3) = L.at(1);
    answer.at(3,6) = L.at(2);
    answer.at(3,9) = L.at(3);
}
void
TrPlanestressRotAllman :: computeEgdeNMatrixAt(FloatMatrix &answer, int iedge, GaussPoint *gp)
{
    FloatArray lxy[6];
    const FloatArray *lxyptr[]= {lxy, lxy+1, lxy+2, lxy+3, lxy+4, lxy+5};
    FloatArray l, n;
    IntArray en;
    FEI2dTrQuad qi (1,2);

    this->computeLocalCoordinates(lxy); // get ready for tranformation into 3d
    qi.edgeEvalN( n, iedge, *gp->giveCoordinates(), FEIVertexListGeometryWrapper(6, lxyptr) );
    qi.computeLocalEdgeMapping (en, iedge); // get edge mapping
    this->interp.edgeEvalN( l, iedge, *gp->giveCoordinates(), FEIElementGeometryWrapper(this) );
    answer.resize(3,6);

    answer.at(1, 1) = answer.at(2,2) = n.at(1) + n.at(3)/2.0;
    answer.at(1, 4) = answer.at(2,5) = n.at(2) + n.at(3)/2.0;
    answer.at(1, 3) = n.at(3)*(lxy[en.at(2)-1].at(2)-lxy[en.at(1)-1].at(2))/8.0;
    answer.at(1, 6) = -answer.at(1, 3);
    answer.at(2, 3) = n.at(3)*(lxy[en.at(2)-1].at(1)-lxy[en.at(1)-1].at(1))/8.0;
    answer.at(2, 6) = -answer.at(2, 3);
    answer.at(3, 3) = l.at(1);
    answer.at(3, 6) = l.at(2);

}
示例#6
0
文件: cct3d.C 项目: xyuan/oofem
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;
}
示例#7
0
void
Quad1MindlinShell3D :: computeEdgeIpGlobalCoords(FloatArray &answer, GaussPoint *gp, int iEdge)
{
    FloatArray local;
    this->interp.edgeLocal2global( local, iEdge, * gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lnodes)  );
    local.resize(3);
    local.at(3) = 0.;
    answer.beProductOf(this->lcsMatrix, local);
}
double
Quad1MindlinShell3D :: computeVolumeAround(GaussPoint *gp)
{
    double detJ, weight;

    weight = gp->giveWeight();
    detJ = fabs( this->interp.giveTransformationJacobian( * gp->giveCoordinates(), FEIVertexListGeometryWrapper(4, (const FloatArray **)lnodes) ) );
    return detJ * weight;
}
void
TrPlanestressRotAllman :: computeBmatrixAt(GaussPoint *aGaussPoint, FloatMatrix &answer, int li, int ui)
// Returns the [3x12] strain-displacement matrix {B} of the receiver, eva-
// luated at aGaussPoint.
{
    FloatMatrix dnx;
    FloatArray  lxy[6];
    const FloatArray *lxyptr[]= {lxy, lxy+1, lxy+2, lxy+3, lxy+4, lxy+5};

    this->computeLocalCoordinates(lxy); // get ready for tranformation into 3d
    this->qinterpolation.evaldNdx( dnx, * aGaussPoint->giveCoordinates(), FEIVertexListGeometryWrapper(6, lxyptr) );

    answer.resize(3, 9);
    answer.zero();

    // epsilon_x
    answer.at(1,1)=dnx.at(1, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(6, 1);
    answer.at(1,4)=dnx.at(2, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(5, 1);
    answer.at(1,7)=dnx.at(3, 1) + 0.5*dnx.at(5, 1) + 0.5*dnx.at(6, 1);
    answer.at(1,3)=dnx.at(6, 1)*(lxy[0].at(2)-lxy[2].at(2))/8.0-dnx.at(4, 1)*(lxy[1].at(2)-lxy[0].at(2))/8.0;
    answer.at(1,6)=dnx.at(4, 1)*(lxy[1].at(2)-lxy[0].at(2))/8.0-dnx.at(5, 1)*(lxy[2].at(2)-lxy[1].at(2))/8.0;
    answer.at(1,9)=dnx.at(5, 1)*(lxy[2].at(2)-lxy[1].at(2))/8.0-dnx.at(6, 1)*(lxy[0].at(2)-lxy[2].at(2))/8.0;

    // epsilon_y
    answer.at(2,2)=dnx.at(1, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(6, 2);
    answer.at(2,5)=dnx.at(2, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(5, 2);
    answer.at(2,8)=dnx.at(3, 2) + 0.5*dnx.at(5, 2) + 0.5*dnx.at(6, 2);
    answer.at(2,3)=-dnx.at(6, 2)*(lxy[0].at(1)-lxy[2].at(1))/8.0+dnx.at(4, 2)*(lxy[1].at(1)-lxy[0].at(1))/8.0;
    answer.at(2,6)=-dnx.at(4, 2)*(lxy[1].at(1)-lxy[0].at(1))/8.0+dnx.at(5, 2)*(lxy[2].at(1)-lxy[1].at(1))/8.0;
    answer.at(2,9)=-dnx.at(5, 2)*(lxy[2].at(1)-lxy[1].at(1))/8.0+dnx.at(6, 2)*(lxy[0].at(1)-lxy[2].at(1))/8.0;

    // gamma_xy (shear)
    answer.at(3,1)=dnx.at(1, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(6, 2);
    answer.at(3,2)=dnx.at(1, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(6, 1);
    answer.at(3,4)=dnx.at(2, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(5, 2);
    answer.at(3,5)=dnx.at(2, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(5, 1);
    answer.at(3,7)=dnx.at(3, 2) + 0.5*dnx.at(5, 2) + 0.5*dnx.at(6, 2);
    answer.at(3,8)=dnx.at(3, 1) + 0.5*dnx.at(5, 1) + 0.5*dnx.at(6, 1);

    answer.at(3,3) = dnx.at(6, 2)*(lxy[0].at(2)-lxy[2].at(2))/8.0-dnx.at(4, 2)*(lxy[1].at(2)-lxy[0].at(2))/8.0;
    answer.at(3,3)+=-dnx.at(6, 1)*(lxy[0].at(1)-lxy[2].at(1))/8.0+dnx.at(4, 1)*(lxy[1].at(1)-lxy[0].at(1))/8.0;
    answer.at(3,6) = dnx.at(4, 2)*(lxy[1].at(2)-lxy[0].at(2))/8.0-dnx.at(5, 2)*(lxy[2].at(2)-lxy[1].at(2))/8.0;
    answer.at(3,6)+=-dnx.at(4, 1)*(lxy[1].at(1)-lxy[0].at(1))/8.0+dnx.at(5, 1)*(lxy[2].at(1)-lxy[1].at(1))/8.0;
    answer.at(3,9) = dnx.at(5, 2)*(lxy[2].at(2)-lxy[1].at(2))/8.0-dnx.at(6, 2)*(lxy[0].at(2)-lxy[2].at(2))/8.0;
    answer.at(3,9)+=-dnx.at(5, 1)*(lxy[2].at(1)-lxy[1].at(1))/8.0+dnx.at(6, 1)*(lxy[0].at(1)-lxy[2].at(1))/8.0;
}
void
TrPlanestressRotAllman :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
// Returns the [3x12] strain-displacement matrix {B} of the receiver, eva-
// luated at gp.
{
    FloatMatrix dnx;
    std::vector< FloatArray > lxy;

    this->computeLocalNodalCoordinates(lxy); // get ready for tranformation into 3d
    this->qinterpolation.evaldNdx( dnx, gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lxy) );

    answer.resize(3, 9);
    answer.zero();

    // epsilon_x
    answer.at(1, 1) = dnx.at(1, 1) + 0.5 * dnx.at(4, 1) + 0.5 * dnx.at(6, 1);
    answer.at(1, 4) = dnx.at(2, 1) + 0.5 * dnx.at(4, 1) + 0.5 * dnx.at(5, 1);
    answer.at(1, 7) = dnx.at(3, 1) + 0.5 * dnx.at(5, 1) + 0.5 * dnx.at(6, 1);
    answer.at(1, 3) =+dnx.at(6, 1) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0 - dnx.at(4, 1) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0;
    answer.at(1, 6) =+dnx.at(4, 1) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0 - dnx.at(5, 1) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0;
    answer.at(1, 9) =+dnx.at(5, 1) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0 - dnx.at(6, 1) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0;

    // epsilon_y
    answer.at(2, 2) = dnx.at(1, 2) + 0.5 * dnx.at(4, 2) + 0.5 * dnx.at(6, 2);
    answer.at(2, 5) = dnx.at(2, 2) + 0.5 * dnx.at(4, 2) + 0.5 * dnx.at(5, 2);
    answer.at(2, 8) = dnx.at(3, 2) + 0.5 * dnx.at(5, 2) + 0.5 * dnx.at(6, 2);
    answer.at(2, 3) =-dnx.at(6, 2) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0 + dnx.at(4, 2) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0;
    answer.at(2, 6) =-dnx.at(4, 2) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0 + dnx.at(5, 2) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0;
    answer.at(2, 9) =-dnx.at(5, 2) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0 + dnx.at(6, 2) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0;

    // gamma_xy (shear)
    answer.at(3, 1) = dnx.at(1, 2) + 0.5 * dnx.at(4, 2) + 0.5 * dnx.at(6, 2);
    answer.at(3, 2) = dnx.at(1, 1) + 0.5 * dnx.at(4, 1) + 0.5 * dnx.at(6, 1);
    answer.at(3, 4) = dnx.at(2, 2) + 0.5 * dnx.at(4, 2) + 0.5 * dnx.at(5, 2);
    answer.at(3, 5) = dnx.at(2, 1) + 0.5 * dnx.at(4, 1) + 0.5 * dnx.at(5, 1);
    answer.at(3, 7) = dnx.at(3, 2) + 0.5 * dnx.at(5, 2) + 0.5 * dnx.at(6, 2);
    answer.at(3, 8) = dnx.at(3, 1) + 0.5 * dnx.at(5, 1) + 0.5 * dnx.at(6, 1);

    answer.at(3, 3) = dnx.at(6, 2) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0 - dnx.at(4, 2) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0;
    answer.at(3, 3) += -dnx.at(6, 1) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0 + dnx.at(4, 1) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0;
    answer.at(3, 6) = dnx.at(4, 2) * ( lxy [ 1 ].at(2) - lxy [ 0 ].at(2) ) / 8.0 - dnx.at(5, 2) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0;
    answer.at(3, 6) += -dnx.at(4, 1) * ( lxy [ 1 ].at(1) - lxy [ 0 ].at(1) ) / 8.0 + dnx.at(5, 1) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0;
    answer.at(3, 9) = dnx.at(5, 2) * ( lxy [ 2 ].at(2) - lxy [ 1 ].at(2) ) / 8.0 - dnx.at(6, 2) * ( lxy [ 0 ].at(2) - lxy [ 2 ].at(2) ) / 8.0;
    answer.at(3, 9) += -dnx.at(5, 1) * ( lxy [ 2 ].at(1) - lxy [ 1 ].at(1) ) / 8.0 + dnx.at(6, 1) * ( lxy [ 0 ].at(1) - lxy [ 2 ].at(1) ) / 8.0;
}
void
TrPlanestressRotAllman :: computeStiffnessMatrixZeroEnergyStabilization(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
{
    FloatMatrix b(1,9), d(1,1);
    FloatMatrix dnx;
    FloatArray  lxy[6], lec;
    const FloatArray *lxyptr[]= {lxy, lxy+1, lxy+2, lxy+3, lxy+4, lxy+5};

    lec.setValues(3, 0.333333333333, 0.333333333333, 0.333333333333); // element center in local coordinates
    this->computeLocalCoordinates(lxy); // get ready for tranformation into 3d
    this->qinterpolation.evaldNdx( dnx, lec, FEIVertexListGeometryWrapper(6, lxyptr) );

    // evaluate (dv/dx-du/dy)/2. at element center
    b.at(1,1)=-1.0*(dnx.at(1, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(6, 2));
    b.at(1,2)=dnx.at(1, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(6, 1);
    b.at(1,4)=-1.0*(dnx.at(2, 2) + 0.5*dnx.at(4, 2) + 0.5*dnx.at(5, 2));
    b.at(1,5)=dnx.at(2, 1) + 0.5*dnx.at(4, 1) + 0.5*dnx.at(5, 1);
    b.at(1,7)=-1.0*(dnx.at(3, 2) + 0.5*dnx.at(5, 2) + 0.5*dnx.at(6, 2));
    b.at(1,8)=dnx.at(3, 1) + 0.5*dnx.at(5, 1) + 0.5*dnx.at(6, 1);

    b.at(1,3) =-dnx.at(6, 2)*(lxy[0].at(2)-lxy[2].at(2))/8.0+dnx.at(4, 2)*(lxy[1].at(2)-lxy[0].at(2))/8.0;
    b.at(1,3)+=-dnx.at(6, 1)*(lxy[0].at(1)-lxy[2].at(1))/8.0+dnx.at(4, 1)*(lxy[1].at(1)-lxy[0].at(1))/8.0;
    b.at(1,6) =-dnx.at(4, 2)*(lxy[1].at(2)-lxy[0].at(2))/8.0+dnx.at(5, 2)*(lxy[2].at(2)-lxy[1].at(2))/8.0;
    b.at(1,6)+=-dnx.at(4, 1)*(lxy[1].at(1)-lxy[0].at(1))/8.0+dnx.at(5, 1)*(lxy[2].at(1)-lxy[1].at(1))/8.0;
    b.at(1,9) =-dnx.at(5, 2)*(lxy[2].at(2)-lxy[1].at(2))/8.0+dnx.at(6, 2)*(lxy[0].at(2)-lxy[2].at(2))/8.0;
    b.at(1,9)+=-dnx.at(5, 1)*(lxy[2].at(1)-lxy[1].at(1))/8.0+dnx.at(6, 1)*(lxy[0].at(1)-lxy[2].at(1))/8.0;
    b.times(0.5);
    // add -1.0*sum(r_w)/3.0
    b.at(1,3)-=1.0/3.0;
    b.at(1,6)-=1.0/3.0;
    b.at(1,9)-=1.0/3.0;
    // add alpha*Volume*B^T[G]B to element stiffness matrix
    double coeff = this->giveMaterial()->give (Gxy, this->giveDefaultIntegrationRulePtr()->getIntegrationPoint(0)) *
                   this->giveArea() * this->giveCrossSection()->give(CS_Thickness) * 1.e-6;
    answer.beTProductOf (b,b);
    answer.times(coeff);
}
示例#12
0
double
Quad1MindlinShell3D :: computeEdgeVolumeAround(GaussPoint *gp, int iEdge)
{
    double detJ = this->interp.edgeGiveTransformationJacobian( iEdge, * gp->giveNaturalCoordinates(), FEIVertexListGeometryWrapper(lnodes) );
    return detJ *gp->giveWeight();
}
示例#13
0
void
Quad1MindlinShell3D :: computeBmatrixAt(GaussPoint *gp, FloatMatrix &answer, int li, int ui)
{
    FloatArray n, ns;
    FloatMatrix dn, dns;
    const FloatArray &localCoords = gp->giveNaturalCoordinates();

    this->interp.evaldNdx( dn, localCoords, FEIVertexListGeometryWrapper(lnodes) );
    this->interp.evalN( n, localCoords,  FEIVoidCellGeometry() );

    answer.resize(8, 4 * 5);
    answer.zero();

    // enforce one-point reduced integration if requested
    if ( this->reducedIntegrationFlag ) {
        FloatArray lc(2);
        lc.zero(); // set to element center coordinates

        this->interp.evaldNdx( dns, lc, FEIVertexListGeometryWrapper(lnodes) );
        this->interp.evalN( ns, lc,  FEIVoidCellGeometry() );
    } else {
        dns = dn;
        ns = n;
    }


    // Note: This is just 5 dofs (sixth column is all zero, torsional stiffness handled separately.)
    for ( int i = 0; i < 4; ++i ) {
        ///@todo Check the rows for both parts here, to be consistent with _3dShell material definition
        // Part related to the membrane (columns represent coefficients for D_u, D_v)
        answer(0, 0 + i * 5) = dn(i, 0);//eps_x = du/dx
        answer(1, 1 + i * 5) = dn(i, 1);//eps_y = dv/dy
        answer(2, 0 + i * 5) = dn(i, 1);//gamma_xy = du/dy+dv/dx
        answer(2, 1 + i * 5) = dn(i, 0);

        // Part related to the plate (columns represent the dofs D_w, R_u, R_v)
        ///@todo Check sign here
        answer(3 + 0, 2 + 2 + i * 5) = dn(i, 0);// kappa_x = d(fi_y)/dx
        answer(3 + 1, 2 + 1 + i * 5) =-dn(i, 1);// kappa_y = -d(fi_x)/dy
        answer(3 + 2, 2 + 2 + i * 5) = dn(i, 1);// kappa_xy=d(fi_y)/dy-d(fi_x)/dx
        answer(3 + 2, 2 + 1 + i * 5) =-dn(i, 0);

        // shear strains
        answer(3 + 3, 2 + 0 + i * 5) = dns(i, 0);// gamma_xz = fi_y+dw/dx
        answer(3 + 3, 2 + 2 + i * 5) = ns(i);
        answer(3 + 4, 2 + 0 + i * 5) = dns(i, 1);// gamma_yz = -fi_x+dw/dy
        answer(3 + 4, 2 + 1 + i * 5) = -ns(i);
    }


#if 0
    // Experimental MITC4 support.
    // Based on "Short communication A four-node plate bending element based on mindling/reissner plate theory and a mixed interpolation"
    // KJ Bathe, E Dvorkin

    double x1, x2, x3, x4;
    double y1, y2, y3, y4;
    double Ax, Bx, Cx, Ay, By, Cy;

    double r = localCoords[0];
    double s = localCoords[1];

    x1 = lnodes[0][0];
    x2 = lnodes[1][0];
    x3 = lnodes[2][0];
    x4 = lnodes[3][0];

    y1 = lnodes[0][1];
    y2 = lnodes[1][1];
    y3 = lnodes[2][1];
    y4 = lnodes[3][1];

    Ax = x1 - x2 - x3 + x4;
    Bx = x1 - x2 + x3 - x4;
    Cx = x1 + x2 - x3 - x4;

    Ay = y1 - y2 - y3 + y4;
    By = y1 - y2 + y3 - y4;
    Cy = y1 + y2 - y3 - y4;

    FloatMatrix jac;
    this->interp.giveJacobianMatrixAt(jac, localCoords, FEIVertexListGeometryWrapper(lnodes) );
    double detJ = jac.giveDeterminant();

    double rz = sqrt( sqr(Cx + r*Bx) + sqr(Cy + r*By)) / ( 16 * detJ );
    double sz = sqrt( sqr(Ax + s*Bx) + sqr(Ay + s*By)) / ( 16 * detJ );

    // TODO: Not sure about this part (the reference is not explicit about these angles. / Mikael
    // Not sure about the transpose either.
    OOFEM_WARNING("The MITC4 implementation isn't verified yet. Highly experimental");
    FloatArray dxdr = {jac(0,0), jac(0,1)};
    dxdr.normalize();
    FloatArray dxds = {jac(1,0), jac(1,1)};
    dxds.normalize();

    double c_b = dxdr(0); //cos(beta);
    double s_b = dxdr(1); //sin(beta);
    double c_a = dxds(0); //cos(alpha);
    double s_a = dxds(1); //sin(alpha);

    // gamma_xz = "fi_y+dw/dx" in standard formulation
    answer(6, 2 + 5*0) = rz * s_b * ( (1+s)) - sz * s_a * ( (1+r));
    answer(6, 2 + 5*1) = rz * s_b * (-(1+s)) - sz * s_a * ( (1-r));
    answer(6, 2 + 5*2) = rz * s_b * (-(1-s)) - sz * s_a * (-(1-r));
    answer(6, 2 + 5*3) = rz * s_b * ( (1-s)) - sz * s_a * (-(1+r));

    answer(6, 3 + 5*0) = rz * s_b * (y2-y1) * 0.5 * (1+s) - sz * s_a * (y4-y1) * 0.5 * (1+r); // tx1
    answer(6, 4 + 5*0) = rz * s_b * (x1-x2) * 0.5 * (1+s) - sz * s_a * (x1-x4) * 0.5 * (1+r); // ty1

    answer(6, 3 + 5*1) = rz * s_b * (y2-y1) * 0.5 * (1+s) - sz * s_a * (y3-x2) * 0.5 * (1+r); // tx2
    answer(6, 4 + 5*1) = rz * s_b * (x1-x2) * 0.5 * (1+s) - sz * s_a * (x2-x3) * 0.5 * (1+r); // ty2

    answer(6, 3 + 5*2) = rz * s_b * (y3-y4) * 0.5 * (1-s) - sz * s_a * (y3-y2) * 0.5 * (1-r); // tx3
    answer(6, 4 + 5*2) = rz * s_b * (x4-x3) * 0.5 * (1-s) - sz * s_a * (x2-x3) * 0.5 * (1-r); // ty3

    answer(6, 3 + 5*3) = rz * s_b * (y3-y4) * 0.5 * (1-s) - sz * s_a * (y4-y1) * 0.5 * (1-r); // tx4
    answer(6, 4 + 5*3) = rz * s_b * (x4-x3) * 0.5 * (1-s) - sz * s_a * (x1-x4) * 0.5 * (1-r); // ty4

    // gamma_yz = -fi_x+dw/dy in standard formulation
    answer(7, 2 + 5*0) = - rz * c_b * ( (1+s)) + sz * c_a * ( (1+r));
    answer(7, 2 + 5*1) = - rz * c_b * (-(1+s)) + sz * c_a * ( (1-r));
    answer(7, 2 + 5*2) = - rz * c_b * (-(1-s)) + sz * c_a * (-(1-r));
    answer(7, 2 + 5*3) = - rz * c_b * ( (1-s)) + sz * c_a * (-(1+r));

    answer(7, 3 + 5*0) = - rz * c_b * (y2-y1) * 0.5 * (1+s) + sz * c_a * (y4-y1) * 0.5 * (1+r); // tx1
    answer(7, 4 + 5*0) = - rz * c_b * (x1-x2) * 0.5 * (1+s) + sz * c_a * (x1-x4) * 0.5 * (1+r); // ty1

    answer(7, 3 + 5*1) = - rz * c_b * (y2-y1) * 0.5 * (1+s) + sz * c_a * (y3-x2) * 0.5 * (1+r); // tx2
    answer(7, 4 + 5*1) = - rz * c_b * (x1-x2) * 0.5 * (1+s) + sz * c_a * (x2-x3) * 0.5 * (1+r); // ty2

    answer(7, 3 + 5*2) = - rz * c_b * (y3-y4) * 0.5 * (1-s) + sz * c_a * (y3-y2) * 0.5 * (1-r); // tx3
    answer(7, 4 + 5*2) = - rz * c_b * (x4-x3) * 0.5 * (1-s) + sz * c_a * (x2-x3) * 0.5 * (1-r); // ty3

    answer(7, 3 + 5*3) = - rz * c_b * (y3-y4) * 0.5 * (1-s) + sz * c_a * (y4-y1) * 0.5 * (1-r); // tx4
    answer(7, 4 + 5*3) = - rz * c_b * (x4-x3) * 0.5 * (1-s) + sz * c_a * (x1-x4) * 0.5 * (1-r); // ty4
#endif
}
示例#14
0
double
InterfaceElement3dTrLin :: computeVolumeAround(GaussPoint *gp)
// Returns the length of the receiver. This method is valid only if 1
// Gauss point is used.
{
    double determinant, weight, thickness, volume;
    // first compute local nodal coordinates in element plane
    std::vector< FloatArray > lncp(3);
    FloatMatrix lcs(3, 3);
    this->computeLCS(lcs);
    for ( int i = 1; i <= 3; i++ ) {
        lncp[ i - 1 ].beProductOf(lcs, *this->giveNode(i)->giveCoordinates());
    }

    determinant = fabs( this->interpolation.giveTransformationJacobian( * gp->giveCoordinates(), FEIVertexListGeometryWrapper(lncp) ) );
    weight      = gp->giveWeight();
    thickness   = this->giveCrossSection()->give(CS_Thickness, gp);
    volume      = determinant * weight * thickness;

    return volume;
}
int
PatchIntegrationRule :: SetUpPointsOnTriangle(int nPoints, MaterialMode mode)
{
    int pointsPassed = 0;

    // TODO: set properly
    firstLocalStrainIndx = 1;
    lastLocalStrainIndx = 3;


    ////////////////////////////////////////////
    // Allocate Gauss point array


    // It may happen that the patch contains triangles with
    // zero area. This does no harm, since their weights in
    // the quadrature will be zero. However, they invoke additional
    // computational cost and therefore we want to avoid them.
    // Thus, count the number of triangles with finite area
    // and keep only those triangles.

    double totArea = 0.0;
    for(size_t i = 0; i < mTriangles.size(); i++) {
    	totArea += mTriangles[i].getArea();
    }

    std::vector<int> triToKeep;
    const double triTol = ( 1.0e-6 )*totArea;

    for(size_t i = 0; i < mTriangles.size(); i++) {
    	if( mTriangles[i].getArea() > triTol ) {
    		triToKeep.push_back(i);
    	}
    }

    int nPointsTot = nPoints * triToKeep.size();
    FloatArray coords_xi1, coords_xi2, weights;
    this->giveTriCoordsAndWeights(nPoints, coords_xi1, coords_xi2, weights);
    this->gaussPointArray = new GaussPoint * [ nPointsTot ];
    ////////////////////////////////////////////


    std :: vector< FloatArray >newGPCoord;

    double parentArea = this->elem->computeArea();

    // Loop over triangles
    for ( int i = 0; i < int( triToKeep.size() ); i++ ) {
        // TODO: Probably unnecessary to allocate here
        const FloatArray **coords = new const FloatArray * [ mTriangles [ triToKeep[i] ].giveNrVertices() ];
        // this we should put into the function before
        for ( int k = 0; k < mTriangles [ triToKeep[i] ].giveNrVertices(); k++ ) {
            coords [ k ] = new FloatArray( ( mTriangles [ triToKeep[i] ].giveVertex(k + 1) ) );
        }

        // Can not be used because it writes to the start of the array instead of appending.
        //		int nPointsTri = GaussIntegrationRule :: SetUpPointsOnTriangle(nPoints, mode);

        for ( int j = 0; j < nPoints; j++ ) {
            FloatArray global;
            GaussPoint * &gp = this->gaussPointArray [ pointsPassed ];

            FloatArray *coord = new FloatArray(2);
            coord->at(1) = coords_xi1.at(j + 1);
            coord->at(2) = coords_xi2.at(j + 1);
            gp = new GaussPoint(this, pointsPassed + 1, coord, weights.at(j + 1), mode);



            mTriInterp.local2global( global, * gp->giveCoordinates(),
                                     FEIVertexListGeometryWrapper(mTriangles [ triToKeep[i] ].giveNrVertices(), coords) );

            newGPCoord.push_back(global);


            FloatArray local;
            this->elem->computeLocalCoordinates(local, global);

            gp->setCoordinates(local);




            double refElArea = this->elem->giveParentElSize();

            gp->setWeight(2.0 * refElArea * gp->giveWeight() * mTriangles [ triToKeep[i] ].getArea() / parentArea); // update integration weight


            pointsPassed++;
        }


        for ( int k = 0; k < mTriangles [ triToKeep[i] ].giveNrVertices(); k++ ) {
            delete coords [ k ];
        }

        delete [] coords;
    }

#if PATCH_INT_DEBUG > 0

    double time = 0.0;

    Element *el = this->elem;
    if(el != NULL) {
    	Domain *dom = el->giveDomain();
    	if(dom != NULL) {
    		EngngModel *em = dom->giveEngngModel();
    		if(em != NULL) {
    			TimeStep *ts = em->giveCurrentStep();
    			if(ts != NULL) {
    				time = ts->giveTargetTime();
    			}
    		}
    	}
    }
    int elIndex = this->elem->giveGlobalNumber();
    std :: stringstream str;
    str << "GaussPointsTime" << time << "El" << elIndex << ".vtk";
    std :: string name = str.str();

    XFEMDebugTools :: WritePointsToVTK(name, newGPCoord);
#endif

    numberOfIntegrationPoints = pointsPassed;


    return numberOfIntegrationPoints;
}
示例#16
0
int
PatchIntegrationRule :: SetUpPointsOnWedge(int nPointsTri, int nPointsDepth, MaterialMode mode)
{
    //int pointsPassed = 0;

    // TODO: set properly
    firstLocalStrainIndx = 1;
    lastLocalStrainIndx = 3;

    double totArea = 0.0;
    for ( size_t i = 0; i < mTriangles.size(); i++ ) {
        totArea += mTriangles [ i ].getArea();
    }

    std :: vector< int >triToKeep;
    const double triTol = ( 1.0e-6 ) * totArea;

    for ( size_t i = 0; i < mTriangles.size(); i++ ) {
        if ( mTriangles [ i ].getArea() > triTol ) {
            triToKeep.push_back(i);
        }
    }

    int nPointsTot = nPointsTri * nPointsDepth * triToKeep.size();
    FloatArray coords_xi1, coords_xi2, coords_xi3, weightsTri, weightsDepth;
    this->giveTriCoordsAndWeights(nPointsTri, coords_xi1, coords_xi2, weightsTri);
    this->giveLineCoordsAndWeights(nPointsDepth, coords_xi3, weightsDepth);
    this->gaussPoints.resize(nPointsTot);

    std :: vector< FloatArray >newGPCoord;

    double parentArea = this->elem->computeArea();
    int count = 0;

    // Loop over triangles
    for ( int i = 0; i < int( triToKeep.size() ); i++ ) {

        Triangle triangle = mTriangles [ triToKeep [ i ] ];
        
        // global coords of the the triangle verticies
        std::vector< FloatArray > gCoords( triangle.giveNrVertices() );
        for ( int j = 0; j < triangle.giveNrVertices(); j++ ) {
            gCoords[j] = (triangle.giveVertex(j + 1));
        }
        

        for ( int k = 1; k <= nPointsTri; k++ ) {
            for ( int m = 1; m <= nPointsDepth; m++ ) {
                // local coords in the parent triangle
                FloatArray *lCoords = new FloatArray(3);
                lCoords->at(1) = coords_xi1.at(k);
                lCoords->at(2) = coords_xi2.at(k);
                lCoords->at(3) = coords_xi3.at(m);

                double refElArea = 0.5;
                double oldWeight = weightsTri.at(k) * weightsDepth.at(m);
                double newWeight = 2.0 * refElArea * oldWeight * triangle.getArea() / parentArea; 
                
                GaussPoint *gp = new GaussPoint(this, count + 1, lCoords, newWeight, mode);
                this->gaussPoints[count] = gp;
                count++;
                
                
                // Compute global gp coordinate in the element from local gp coord in the sub triangle
                FloatArray global;
                mTriInterp.local2global( global, * gp->giveNaturalCoordinates(),
                                    FEIVertexListGeometryWrapper(gCoords) );
                 
                
                // Compute local gp coordinate in the element from global gp coord in the element
                FloatArray local;
                this->elem->computeLocalCoordinates(local, global);
                local.at(3) = coords_xi3.at(m); // manually set third coordinate
                // compute global coords again, since interpolator dosn't give the z-coord 
                this->elem->computeGlobalCoordinates(global, local);
                
                gp->setGlobalCoordinates(global);
                gp->setNaturalCoordinates(local);
                gp->setSubPatchCoordinates(local);

                // Store new global gp coord for vtk output
                newGPCoord.push_back(global);
            }
        }


        //for ( int k = 0; k < mTriangles [ triToKeep [ i ] ].giveNrVertices(); k++ ) {
        //    delete gCoords [ k ];
        //}

        //delete [] gCoords;
    }

    XfemManager *xMan = elem->giveDomain()->giveXfemManager();
    if ( xMan != NULL ) {
        if ( xMan->giveVtkDebug() ) {
            double time = 0.0;

            Element *el = this->elem;
            if ( el != NULL ) {
                Domain *dom = el->giveDomain();
                if ( dom != NULL ) {
                    EngngModel *em = dom->giveEngngModel();
                    if ( em != NULL ) {
                        TimeStep *ts = em->giveCurrentStep();
                        if ( ts != NULL ) {
                            time = ts->giveTargetTime();
                        }
                    }
                }
            }

            int elIndex = this->elem->giveGlobalNumber();
            std :: stringstream str;
            str << "GaussPointsTime" << time << "El" << elIndex << ".vtk";
            std :: string name = str.str();

            XFEMDebugTools :: WritePointsToVTK(name, newGPCoord);
        }
    }

    
    return this->giveNumberOfIntegrationPoints();
}