Esempio n. 1
0
void
FreeWarping :: computeResultAtCenterOfGravity(TimeStep *tStep)
{
    int noCS = this->giveDomain(1)->giveNumberOfCrossSectionModels(); //number of warping Crosssections
    SolutionAtCG.resize(noCS);
    Element *closestElement;
    FloatArray lcoords,  closest, lcg;
    SpatialLocalizer *sp = this->giveDomain(1)->giveSpatialLocalizer();
    sp->init();
    lcoords.resize(2);
    closest.resize(2);
    lcg.resize(2);

    for ( int j = 1; j <= noCS; ++j ) {
        lcg.at(1) = CG.at(j, 1);
        lcg.at(2) = CG.at(j, 2);
        closestElement = sp->giveElementClosestToPoint(lcoords, closest, lcg, 0);

        StructuralElement *sE = dynamic_cast< StructuralElement * >(closestElement);
        FloatArray u, r, b;
        FloatMatrix N;
        sE->computeNmatrixAt(lcoords, N);
        sE->computeVectorOf(VM_Total, tStep, u);
        u.resizeWithValues(3);
        r.beProductOf(N, u);

        SolutionAtCG.at(j) = r.at(1);
    }
}
Esempio n. 2
0
void
GradDpElement :: computeStiffnessMatrix_kk(FloatMatrix &answer, MatResponseMode rMode, TimeStep *tStep)
{
    StructuralElement *elem = this->giveStructuralElement();
    double dV;
    FloatMatrix lStiff;
    FloatArray Nk;
    FloatMatrix Bk, LBk;
    StructuralCrossSection *cs = elem->giveStructuralCrossSection();

    answer.clear();

    for ( auto &gp: *elem->giveIntegrationRule(0) ) {

        GradDpMaterialExtensionInterface *dpmat = dynamic_cast< GradDpMaterialExtensionInterface * >(
            cs->giveMaterialInterface(GradDpMaterialExtensionInterfaceType, gp) );
        if ( !dpmat ) {
            OOFEM_ERROR("Material doesn't implement the required DpGrad interface!");
        }

        this->computeNkappaMatrixAt(gp, Nk);
        this->computeBkappaMatrixAt(gp, Bk);
        dV = elem->computeVolumeAround(gp);

        dpmat->givePDGradMatrix_kk(lStiff, rMode, gp, tStep);
        answer.plusProductUnsym(Nk, Nk, dV);
        if ( dpmat->giveAveragingType() == 0 || dpmat->giveAveragingType() == 1 ) {
            double l = lStiff.at(1, 1);
            answer.plusProductUnsym(Bk, Bk, l * l * dV);
        } else if ( dpmat->giveAveragingType() == 2 ) {
            LBk.beProductOf(lStiff, Bk);
            answer.plusProductUnsym(Bk, LBk, dV);
        }
    }
}
Esempio n. 3
0
// computes Btransposed*eta for the given Gauss point
// (where eta is the derivative of cum. plastic strain wrt final strain)
void
RankineMatNl :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
                                                        FloatArray &rcontrib, TimeStep *atTime)
{
    RankineMatNlStatus *status = ( RankineMatNlStatus * ) this->giveStatus(gp);
    StructuralElement *elem = ( StructuralElement * )( gp->giveElement() );
    elem->giveLocationArray(rloc, EID_MomentumBalance, s);
    FloatMatrix b;
    elem->computeBmatrixAt(gp, b);
    int ncols = b.giveNumberOfColumns();
    rcontrib.resize(ncols);

    double kappa = status->giveCumulativePlasticStrain();
    double tempKappa = status->giveTempCumulativePlasticStrain();
    if ( tempKappa <= kappa ) {
        rcontrib.zero();
        return;
    }

    int i, j;
    double sum;
    int nsize = 3;
    FloatArray eta(3);
    computeEta(eta, status);
    for ( i = 1; i <= ncols; i++ ) {
        sum = 0.;
        for ( j = 1; j <= nsize; j++ ) {
            sum += eta.at(j) * b.at(j, i);
        }

        rcontrib.at(i) = sum;
    }
}
Esempio n. 4
0
void
TrabBoneNL3D :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
                                                        FloatArray &rcontrib, TimeStep *tStep)
{
    TrabBoneNL3DStatus *nlStatus = static_cast< TrabBoneNL3DStatus * >( this->giveStatus(gp) );
    StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );

    FloatMatrix b;

    elem->giveLocationArray(rloc, s);
    elem->computeBmatrixAt(gp, b);

    double kappa = nlStatus->giveKappa();
    double tempKappa = nlStatus->giveTempKappa();
    double dKappa = tempKappa - kappa;
    if ( dKappa < 10.e-9 ) {
        dKappa = 0;
    }

    if ( dKappa > 0.0 ) {
        FloatArray remoteNu, prodTensor;
        const FloatArray &plasFlowDirec = nlStatus->givePlasFlowDirec();
        const FloatMatrix &SSaTensor = nlStatus->giveSSaTensor();
        double beta = nlStatus->giveBeta();

        prodTensor.beTProductOf(SSaTensor, plasFlowDirec);
        remoteNu = 1 / beta * prodTensor;
        rcontrib.beTProductOf(b, remoteNu);
    } else {
        rcontrib.resize(b.giveNumberOfColumns());
        rcontrib.zero();
    }
}
Esempio n. 5
0
int
MisesMatNl :: giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s,
        FloatArray &lcontrib, TimeStep *atTime)
{
    int nrows, nsize, i, j;
    double sum, nlKappa, damage, tempDamage, dDamF;
    MisesMatNlStatus *status = ( MisesMatNlStatus * ) this->giveStatus(gp);
    StructuralElement *elem = ( StructuralElement * )( gp->giveElement() );
    FloatMatrix b;
    FloatArray stress;

    this->computeCumPlasticStrain(nlKappa, gp, atTime);
    damage = status->giveDamage();
    tempDamage = status->giveTempDamage();
    if ( ( tempDamage - damage ) > 0 ) {
        elem->giveLocationArray(loc, EID_MomentumBalance, s);
        status->giveTempEffectiveStress(stress);
        elem->computeBmatrixAt(gp, b);
        dDamF = computeDamageParamPrime(nlKappa);
        nrows = b.giveNumberOfColumns();
        nsize = stress.giveSize();
        lcontrib.resize(nrows);

        for ( i = 1; i <= nrows; i++ ) {
            sum = 0.0;
            for ( j = 1; j <= nsize; j++ ) {
                sum += b.at(j, i) * stress.at(j);
            }

            lcontrib.at(i) = sum * mm * dDamF;
        }
    }

    return 1;
}
Esempio n. 6
0
void
MisesMatNl :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
                                                      FloatArray &rcontrib, TimeStep *tStep)
{
    double kappa, tempKappa;
    MisesMatNlStatus *status = static_cast< MisesMatNlStatus * >( this->giveStatus(gp) );
    StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );
    FloatMatrix b;
    LinearElasticMaterial *lmat = this->giveLinearElasticMaterial();
    double E = lmat->give('E', gp);

    elem->giveLocationArray(rloc, s);
    elem->computeBmatrixAt(gp, b);
    kappa = status->giveCumulativePlasticStrain();
    tempKappa = status->giveTempCumulativePlasticStrain();

    rcontrib.clear();
    if ( ( tempKappa - kappa ) > 0 ) {
        const FloatArray &stress = status->giveTempEffectiveStress();
        if ( gp->giveMaterialMode() == _1dMat ) {
            double coeff = sgn( stress.at(1) ) * E / ( E + H );
            rcontrib.plusProduct(b, stress, coeff);
            return;
        }
    }
    rcontrib.resize(b.giveNumberOfColumns());
    rcontrib.zero();
}
void
SimpleCrossSection :: giveTemperatureVector(FloatArray &answer, GaussPoint *gp, TimeStep *tStep)
{
    Element *elem = gp->giveElement();
    answer.clear();
    //sum up all prescribed temperatures over an element
    StructuralElement *selem = dynamic_cast< StructuralElement * >(elem);
    selem->computeResultingIPTemperatureAt(answer, tStep, gp, VM_Total);

    /* add external source, if provided */
    FieldManager *fm = this->domain->giveEngngModel()->giveContext()->giveFieldManager();
    FM_FieldPtr tf;

    if ( ( tf = fm->giveField(FT_Temperature) ) ) {
        // temperature field registered
        FloatArray gcoords, et2;
        int err;
        elem->computeGlobalCoordinates( gcoords, gp->giveNaturalCoordinates() );
        if ( ( err = tf->evaluateAt(et2, gcoords, VM_Total, tStep) ) ) {
            OOFEM_ERROR("tf->evaluateAt failed, element %d, error code %d", elem->giveNumber(), err);
        }

        if ( et2.isNotEmpty() ) {
            if ( answer.isEmpty() ) {
                answer = et2;
            } else {
                answer.at(1) += et2.at(1);
            }
        }
    }
}
Esempio n. 8
0
void
FiberedCrossSection :: giveGeneralizedStress_Beam3d(FloatArray &answer, GaussPoint *gp, const FloatArray &strain, TimeStep *tStep)
{
    double fiberThick, fiberWidth, fiberZCoord, fiberYCoord;
    FloatArray fiberStrain, reducedFiberStress;
    StructuralElement *element = static_cast< StructuralElement * >( gp->giveElement() );
    FiberedCrossSectionInterface *interface;

    if ( ( interface = static_cast< FiberedCrossSectionInterface * >( element->giveInterface(FiberedCrossSectionInterfaceType) ) ) == NULL ) {
        OOFEM_ERROR("element with no fiber support encountered");
    }

    answer.resize(6);
    answer.zero();

    for ( int i = 1; i <= numberOfFibers; i++ ) {
        GaussPoint *fiberGp = this->giveSlaveGaussPoint(gp, i - 1);
        StructuralMaterial *fiberMat = static_cast< StructuralMaterial * >( domain->giveMaterial( fiberMaterials.at(i) ) );
        // the question is whether this function should exist ?
        // if yes the element details will be hidden.
        // good idea also should be existence of element::GiveBmatrixOfLayer
        // and computing strains here - but first idea looks better
        // but treating of geometric non-linearities may become more complicated
        // another approach - use several functions with assumed kinematic constraints

        // resolve current layer z-coordinate
        fiberThick  = this->fiberThicks.at(i);
        fiberWidth  = this->fiberWidths.at(i);
        fiberYCoord = fiberGp->giveNaturalCoordinate(1);
        fiberZCoord = fiberGp->giveNaturalCoordinate(2);

        interface->FiberedCrossSectionInterface_computeStrainVectorInFiber(fiberStrain, strain, fiberGp, tStep);

        fiberMat->giveRealStressVector_Fiber(reducedFiberStress, fiberGp, fiberStrain, tStep);

        // perform integration
        // 1) membrane terms N, Qz, Qy
        answer.at(1) += reducedFiberStress.at(1) * fiberWidth * fiberThick;
        answer.at(2) += reducedFiberStress.at(2) * fiberWidth * fiberThick;
        answer.at(3) += reducedFiberStress.at(3) * fiberWidth * fiberThick;
        // 2) bending terms mx, my, mxy
        answer.at(4) += ( reducedFiberStress.at(2) * fiberWidth * fiberThick * fiberYCoord -
                          reducedFiberStress.at(3) * fiberWidth * fiberThick * fiberZCoord );
        answer.at(5) += reducedFiberStress.at(1) * fiberWidth * fiberThick * fiberZCoord;
        answer.at(6) -= reducedFiberStress.at(1) * fiberWidth * fiberThick * fiberYCoord;
    }

    // now we must update master gp ///@ todo simply chosen the first fiber material as master material /JB
    StructuralMaterialStatus *status = static_cast< StructuralMaterialStatus * >
                                       ( domain->giveMaterial( fiberMaterials.at(1) )->giveStatus(gp) );
    status->letTempStrainVectorBe(strain);
    status->letTempStressVectorBe(answer);
}
Esempio n. 9
0
void
TrabBoneNL3D :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
                                                        FloatArray &rcontrib, TimeStep *tStep)
{
    TrabBoneNL3DStatus *nlStatus = static_cast< TrabBoneNL3DStatus * >( this->giveStatus(gp) );
    StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );

    int ncols, nsize;
    double sum, beta;
    FloatArray remoteNu, plasFlowDirec, prodTensor;
    FloatMatrix b, SSaTensor;

    elem->giveLocationArray(rloc, s);
    elem->computeBmatrixAt(gp, b);

    ncols = b.giveNumberOfColumns();
    rcontrib.resize(ncols);


    double kappa = nlStatus->giveKappa();
    double tempKappa = nlStatus->giveTempKappa();
    double dKappa = tempKappa - kappa;
    if ( dKappa < 10.e-9 ) {
        dKappa = 0;
    }

    if ( dKappa > 0.0 ) {
        plasFlowDirec = nlStatus->givePlasFlowDirec();
        SSaTensor = nlStatus->giveSSaTensor();
        beta = nlStatus->giveBeta();

        prodTensor.beTProductOf(SSaTensor, plasFlowDirec);
        remoteNu = 1 / beta * prodTensor;
        nsize = remoteNu.giveSize();

        for ( int i = 1; i <= ncols; i++ ) {
            sum = 0.0;
            for ( int j = 1; j <= nsize; j++ ) {
                sum += remoteNu.at(j) * b.at(j, i);
            }

            rcontrib.at(i) = sum;
        }
    } else {
        for ( int i = 1; i <= ncols; i++ ) {
            rcontrib.at(i) = 0.;
        }
    }
}
Esempio n. 10
0
void GradDpElement :: computeNonlocalDegreesOfFreedom(FloatArray &answer, TimeStep *tStep)
{
    ///@todo Just use this instead! (should work, but I don't have any tests right now)
#if 0
    this->giveStructuralElement()->computeVectorOf({G_0}, VM_Total, tStep, answer);
#else
    StructuralElement *elem = this->giveStructuralElement();
    FloatArray u;
    answer.resize(nlSize);

    elem->computeVectorOf(VM_Total, tStep, u);
    u.resizeWithValues(totalSize);
    for  ( int i = 1; i <= nlSize; i++ ) {
        answer.at(i) = u.at( locK.at(i) );
    }
#endif
}
Esempio n. 11
0
int
TrabBoneNL3D :: giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s,
                                                       FloatArray &lcontrib, TimeStep *tStep)
{
    TrabBoneNL3DStatus *nlStatus = static_cast< TrabBoneNL3DStatus * >( this->giveStatus(gp) );
    StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );

    int nrows, nsize;
    double sum, nlKappa, dDamFunc, dam, tempDam;
    FloatArray localNu;
    FloatMatrix b;

    this->computeCumPlastStrain(nlKappa, gp, tStep);
    dam = nlStatus->giveDam();
    tempDam = nlStatus->giveTempDam();

    if ( ( tempDam - dam ) > 0.0 ) {
        elem->giveLocationArray(loc, s);
        localNu = nlStatus->giveTempEffectiveStress();

        elem->giveLocationArray(loc, EModelDefaultEquationNumbering() );
        elem->computeBmatrixAt(gp, b);
        dDamFunc = expDam * critDam * exp(-expDam * nlKappa);

        nrows = b.giveNumberOfColumns();
        nsize = localNu.giveSize();
        lcontrib.resize(nrows);
        for ( int i = 1; i <= nrows; i++ ) {
            sum = 0.0;
            for ( int j = 1; j <= nsize; j++ ) {
                sum += b.at(j, i) * localNu.at(j);
            }

            lcontrib.at(i) = mParam * dDamFunc * sum;
        }

        return 1;
    } else {
        loc.clear();
        return 0;
    }
}
Esempio n. 12
0
void
MisesMatNl :: giveRemoteNonlocalStiffnessContribution(GaussPoint *gp, IntArray &rloc, const UnknownNumberingScheme &s,
        FloatArray &rcontrib, TimeStep *atTime)
{
    int ncols, nsize, i, j;
    double sum, kappa, tempKappa;
    MisesMatNlStatus *status = ( MisesMatNlStatus * ) this->giveStatus(gp);
    StructuralElement *elem = ( StructuralElement * )( gp->giveElement() );
    FloatMatrix b;
    FloatArray stress;
    LinearElasticMaterial *lmat = this->giveLinearElasticMaterial();
    double E = lmat->give('E', gp);

    elem->giveLocationArray(rloc, EID_MomentumBalance, s);
    elem->computeBmatrixAt(gp, b);
    ncols = b.giveNumberOfColumns();
    rcontrib.resize(ncols);
    kappa = status->giveCumulativePlasticStrain();
    tempKappa = status->giveTempCumulativePlasticStrain();

    if ( ( tempKappa - kappa ) > 0 ) {
        status->giveTempEffectiveStress(stress);
        if ( gp->giveMaterialMode() == _1dMat ) {
            nsize = stress.giveSize();
            double coeff = sgn( stress.at(1) ) * E / ( E + H );
            for ( i = 1; i <= ncols; i++ ) {
                sum = 0.;
                for ( j = 1; j <= nsize; j++ ) {
                    sum += stress.at(j) * coeff * b.at(j, i);
                }

                rcontrib.at(i) = sum;
            }
        }
    } else {
        rcontrib.zero();
    }
}
Esempio n. 13
0
// computes m*gprime*Btransposed*sigmaeff for the given Gauss point
// and returns 0 of damage is not growing, 1 if it is growing
// (if damage is not growing, the contribution is not considered at all)
int
RankineMatNl :: giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s,
                                                       FloatArray &lcontrib, TimeStep *atTime)
{
    int nrows, nsize, i, j;
    double sum, nlKappa, damage, tempDamage;
    RankineMatNlStatus *status = ( RankineMatNlStatus * ) this->giveStatus(gp);
    StructuralElement *elem = ( StructuralElement * )( gp->giveElement() );
    FloatMatrix b;
    FloatArray stress;

    damage = status->giveDamage();
    tempDamage = status->giveTempDamage();
    if ( tempDamage <= damage ) {
        return 0; // no contribution if damage is not growing
    }

    elem->giveLocationArray(loc, EID_MomentumBalance, s);
    status->giveTempEffectiveStress(stress);
    elem->computeBmatrixAt(gp, b);
    this->computeCumPlasticStrain(nlKappa, gp, atTime);
    double factor = computeDamageParamPrime(nlKappa);
    factor *= mm; // this factor is m*gprime
    nrows = b.giveNumberOfColumns();
    nsize = stress.giveSize();
    lcontrib.resize(nrows);
    // compute the product Btransposed*stress and multiply by factor
    for ( i = 1; i <= nrows; i++ ) {
        sum = 0.0;
        for ( j = 1; j <= nsize; j++ ) {
            sum += b.at(j, i) * stress.at(j);
        }

        lcontrib.at(i) = sum * factor;
    }

    return 1; // contribution will be considered
}
Esempio n. 14
0
int
MisesMatNl :: giveLocalNonlocalStiffnessContribution(GaussPoint *gp, IntArray &loc, const UnknownNumberingScheme &s,
                                                     FloatArray &lcontrib, TimeStep *tStep)
{
    double nlKappa, damage, tempDamage, dDamF;
    MisesMatNlStatus *status = static_cast< MisesMatNlStatus * >( this->giveStatus(gp) );
    StructuralElement *elem = static_cast< StructuralElement * >( gp->giveElement() );
    FloatMatrix b;

    this->computeCumPlasticStrain(nlKappa, gp, tStep);
    damage = status->giveDamage();
    tempDamage = status->giveTempDamage();
    if ( ( tempDamage - damage ) > 0 ) {
        const FloatArray &stress = status->giveTempEffectiveStress();
        elem->giveLocationArray(loc, s);
        elem->computeBmatrixAt(gp, b);
        dDamF = computeDamageParamPrime(nlKappa);
        lcontrib.clear();
        lcontrib.plusProduct(b, stress, mm * dDamF);
    }

    return 1;
}
Esempio n. 15
0
 MorphoFilter<T>::MorphoFilter(const StructuralElement& element)
   : NonLinearFilter<T>(&(element.getKernel()[0]), element.getWidth(), element.getHeight(), element.getDepth())
 {}
Esempio n. 16
0
void LSPrimaryVariableMapper :: mapPrimaryVariables(FloatArray &oU, Domain &iOldDom, Domain &iNewDom, ValueModeType iMode, TimeStep &iTStep)
{
    EngngModel *engngMod = iNewDom.giveEngngModel();
    EModelDefaultEquationNumbering num;


    const int dim = iNewDom.giveNumberOfSpatialDimensions();

    int numElNew = iNewDom.giveNumberOfElements();

    // Count dofs
    int numDofsNew = engngMod->giveNumberOfDomainEquations( 1, num );


    oU.resize(numDofsNew);
    oU.zero();

    FloatArray du(numDofsNew);
    du.zero();

    FloatArray res(numDofsNew);

    std :: unique_ptr< SparseMtrx > K;
    std :: unique_ptr< SparseLinearSystemNM > solver;

    solver.reset( classFactory.createSparseLinSolver(ST_Petsc, & iOldDom, engngMod) );
    if (!solver) {
        solver.reset( classFactory.createSparseLinSolver(ST_Direct, & iOldDom, engngMod) );
    }
    K.reset( classFactory.createSparseMtrx(solver->giveRecommendedMatrix(true)) );

    K->buildInternalStructure( engngMod, iNewDom.giveNumber(), num );

    int maxIter = 1;

    for ( int iter = 0; iter < maxIter; iter++ ) {
        K->zero();
        res.zero();


        // Contribution from elements
        for ( int elIndex = 1; elIndex <= numElNew; elIndex++ ) {
            StructuralElement *elNew = dynamic_cast< StructuralElement * >( iNewDom.giveElement(elIndex) );
            if ( elNew == NULL ) {
                OOFEM_ERROR("Failed to cast Element new to StructuralElement.");
            }

            ///////////////////////////////////
            // Compute residual

            // Count element dofs
            int numElNodes = elNew->giveNumberOfDofManagers();
            int numElDofs = 0;
            for ( int i = 1; i <= numElNodes; i++ ) {
                numElDofs += elNew->giveDofManager(i)->giveNumberOfDofs();
            }

            FloatArray elRes(numElDofs);
            elRes.zero();

            IntArray elDofsGlob;
            elNew->giveLocationArray( elDofsGlob, num );


            // Loop over Gauss points
            for ( int intRuleInd = 0; intRuleInd < elNew->giveNumberOfIntegrationRules(); intRuleInd++ ) {

                for ( GaussPoint *gp: *elNew->giveIntegrationRule(intRuleInd) ) {

                    // New N-matrix
                    FloatMatrix NNew;
                    elNew->computeNmatrixAt(gp->giveNaturalCoordinates(), NNew);


                    //////////////
                    // Global coordinates of GP
                    const FloatArray &localCoord = gp->giveNaturalCoordinates();
                    FloatArray globalCoord;
                    elNew->computeGlobalCoordinates(globalCoord, localCoord);
                    //////////////


                    // Localize element and point in the old domain
                    FloatArray localCoordOld(dim), pointCoordOld(dim);
                    StructuralElement *elOld = dynamic_cast< StructuralElement * >( iOldDom.giveSpatialLocalizer()->giveElementClosestToPoint(localCoordOld, pointCoordOld, globalCoord, 0) );
                    if ( elOld == NULL ) {
                        OOFEM_ERROR("Failed to cast Element old to StructuralElement.");
                    }


                    // Compute N-Matrix for the old element
                    FloatMatrix NOld;
                    elOld->computeNmatrixAt(localCoordOld, NOld);

                    // Fetch nodal displacements for the new element
                    FloatArray nodeDispNew( elDofsGlob.giveSize() );


                    int dofsPassed = 1;
                    for ( int elNode: elNew->giveDofManArray() ) {
//                        DofManager *dMan = iNewDom.giveNode(elNode);
                        DofManager *dMan = iNewDom.giveDofManager(elNode);

                        for ( Dof *dof: *dMan ) {
                            if ( elDofsGlob.at(dofsPassed) != 0 ) {
                                nodeDispNew.at(dofsPassed) = oU.at( elDofsGlob.at(dofsPassed) );
                            } else {
                                if ( dof->hasBc(& iTStep) ) {
                                    nodeDispNew.at(dofsPassed) = dof->giveBcValue(iMode, & iTStep);
                                }
                            }

                            dofsPassed++;
                        }
                    }


                    FloatArray newDisp;
                    newDisp.beProductOf(NNew, nodeDispNew);


                    // Fetch nodal displacements for the old element
                    FloatArray nodeDispOld;
                    dofsPassed = 1;
                    IntArray elDofsGlobOld;
                    elOld->giveLocationArray( elDofsGlobOld, num );

//                    elOld->computeVectorOf(iMode, &(iTStep), nodeDisp);
                    int numElNodesOld = elOld->giveNumberOfDofManagers();
                    for(int nodeIndOld = 1; nodeIndOld <= numElNodesOld; nodeIndOld++) {
                        DofManager *dManOld = elOld->giveDofManager(nodeIndOld);

                        for ( Dof *dof: *dManOld ) {
                            if ( elDofsGlobOld.at(dofsPassed) != 0 ) {
                                FloatArray dofUnknowns;

                                if(dof->giveEqn() > 0) {
                                    dof->giveUnknowns(dofUnknowns, iMode, &iTStep);

#ifdef DEBUG
                                    if(!dofUnknowns.isFinite()) {
                                        OOFEM_ERROR("!dofUnknowns.isFinite()")
                                    }

                                    if(dofUnknowns.giveSize() < 1) {
                                        OOFEM_ERROR("dofUnknowns.giveSize() < 1")
                                    }
#endif
                                    nodeDispOld.push_back(dofUnknowns.at(1));
                                }
                                else {
                                    // TODO: Why does this case occur?
                                    nodeDispOld.push_back(0.0);
                                }
                            } else {
                                if ( dof->hasBc(& iTStep) ) {
//                                    printf("hasBC.\n");
#ifdef DEBUG
                                    if(!std::isfinite(dof->giveBcValue(iMode, & iTStep))) {
                                        OOFEM_ERROR("!std::isfinite(dof->giveBcValue(iMode, & iTStep))")
                                    }
#endif
                                    nodeDispOld.push_back( dof->giveBcValue(iMode, & iTStep) );
                                }
                                else {
//                                    printf("Unhandled case in LSPrimaryVariableMapper :: mapPrimaryVariables().\n");
                                    nodeDispOld.push_back( 0.0 );
                                }
                            }

                            dofsPassed++;
                        }

                    }
Esempio n. 17
0
void
ZZErrorEstimatorInterface :: ZZErrorEstimatorI_computeElementContributions(double &eNorm, double &sNorm,
                                                                           ZZErrorEstimator :: NormType norm,
                                                                           InternalStateType type,
                                                                           TimeStep *tStep)
{
    int nDofMans;
    FEInterpolation *interpol = element->giveInterpolation();
    const FloatArray *recoveredStress;
    FloatArray sig, lsig, diff, ldiff, n;
    FloatMatrix nodalRecoveredStreses;

    nDofMans = element->giveNumberOfDofManagers();
    // assemble nodal recovered stresses
    for ( int i = 1; i <= element->giveNumberOfNodes(); i++ ) {
        element->giveDomain()->giveSmoother()->giveNodalVector( recoveredStress,
                                                            element->giveDofManager(i)->giveNumber() );
        if ( i == 1 ) {
            nodalRecoveredStreses.resize( nDofMans, recoveredStress->giveSize() );
        }
        for ( int j = 1; j <= recoveredStress->giveSize(); j++ ) {
            nodalRecoveredStreses.at(i, j) = recoveredStress->at(j);
        }
    }
    /* Note: The recovered stresses should be in global coordinate system. This is important for shells, for example, to make
     * sure that forces and moments in the same directions are averaged. For elements where local and global coordina systems
     * are the same this does not matter.
     */

    eNorm = sNorm = 0.0;

    // compute  the e-norm and s-norm
    if ( norm == ZZErrorEstimator :: L2Norm ) {
        for ( GaussPoint *gp: *this->ZZErrorEstimatorI_giveIntegrationRule() ) {
            double dV = element->computeVolumeAround(gp);
            interpol->evalN( n, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(element) );

            diff.beTProductOf(nodalRecoveredStreses, n);

            element->giveIPValue(sig, gp, type, tStep);
            /* the internal stress difference is in global coordinate system */
            diff.subtract(sig);

            eNorm += diff.computeSquaredNorm() * dV;
            sNorm += sig.computeSquaredNorm() * dV;
        }
    } else if ( norm == ZZErrorEstimator :: EnergyNorm ) {
        FloatArray help, ldiff_reduced, lsig_reduced;
        FloatMatrix D, DInv;
        StructuralElement *selem = static_cast< StructuralElement * >(element);

        for ( GaussPoint *gp: *this->ZZErrorEstimatorI_giveIntegrationRule() ) {
            double dV = element->computeVolumeAround(gp);
            interpol->evalN( n, * gp->giveNaturalCoordinates(), FEIElementGeometryWrapper(element) );
            selem->computeConstitutiveMatrixAt(D, TangentStiffness, gp, tStep);
            DInv.beInverseOf(D);

            diff.beTProductOf(nodalRecoveredStreses, n);

            element->giveIPValue(sig, gp, type, tStep); // returns full value now
            diff.subtract(sig);
            /* the internal stress difference is in global coordinate system */
            /* needs to be transformed into local system to compute associated energy */
            this->ZZErrorEstimatorI_computeLocalStress(ldiff, diff);
            StructuralMaterial :: giveReducedSymVectorForm( ldiff_reduced, ldiff, gp->giveMaterialMode() );

            help.beProductOf(DInv, ldiff_reduced);
            eNorm += ldiff_reduced.dotProduct(help) * dV;
            this->ZZErrorEstimatorI_computeLocalStress(lsig, sig);
            StructuralMaterial :: giveReducedSymVectorForm( lsig_reduced, lsig, gp->giveMaterialMode() );
            help.beProductOf(DInv, lsig_reduced);
            sNorm += lsig_reduced.dotProduct(help) * dV;
        }
    } else {
        OOFEM_ERROR("unsupported norm type");
    }

    eNorm = sqrt(eNorm);
    sNorm = sqrt(sNorm);
}
Esempio n. 18
0
void
HOMExportModule :: doOutput(TimeStep *tStep, bool forcedOutput)
{
    if ( !( testTimeStepOutput(tStep) || forcedOutput ) ) {
        return;
    }

    Domain *d = emodel->giveDomain(1);
    int nelem = d->giveNumberOfElements();
    double dV, VolTot = 0.;
    FloatArray vecState, vecFlow, sumFlow(3);
    FloatArray internalSource, capacity;
    FloatArray answerArr, answerArr1;
    FloatMatrix answerMtrx;
    IntArray Mask;
    FloatMatrix baseGCS;

    sumFlow.zero();
    domainType domType = d->giveDomainType();

    if ( domType == _HeatTransferMode || domType == _HeatMass1Mode ) {
#ifdef __TM_MODULE
        double sumState = 0.;
        TransportElement *transpElem;
        for ( int ielem = 1; ielem <= nelem; ielem++ ) {
            Element *elem = d->giveElement(ielem);
            if ( this->matnum.giveSize() == 0 || this->matnum.contains( elem->giveMaterial()->giveNumber() ) ) {
                for ( GaussPoint *gp: *elem->giveDefaultIntegrationRulePtr() ) {
                    dV  = elem->computeVolumeAround(gp);
                    VolTot += dV;
                    elem->giveIPValue(vecState, gp, IST_Temperature, tStep);
                    elem->giveIPValue(vecFlow, gp, IST_TemperatureFlow, tStep);
                    sumState += vecState.at(1) * dV;
                    vecFlow.resize(3);
                    vecFlow.times(dV);
                    sumFlow += vecFlow;
                }
            }
        }

        sumState *= ( 1. / VolTot * this->scale );
        fprintf(this->stream, "%e  % e       ", tStep->giveTargetTime(), sumState);
        sumFlow.times(1. / VolTot * this->scale);
        fprintf( this->stream, "% e  % e  % e       ", sumFlow.at(1), sumFlow.at(2), sumFlow.at(3) );
        //add total heat for each material - accumulated energy due to material capacity (J for heat) and internal source (J for heat)
        internalSource.resize( d->giveNumberOfCrossSectionModels() );
        capacity.resize( d->giveNumberOfCrossSectionModels() );
        for ( int ielem = 1; ielem <= nelem; ielem++ ) {
            transpElem = static_cast< TransportElement * >( d->giveElement(ielem) );
            transpElem->computeInternalSourceRhsVectorAt(answerArr, tStep, VM_Total);
            internalSource.at( transpElem->giveCrossSection()->giveNumber() ) += answerArr.sum();

            transpElem->giveCharacteristicMatrix(answerMtrx, CapacityMatrix, tStep);
            transpElem->computeVectorOf(VM_Incremental, tStep, answerArr);
            answerArr1.beProductOf(answerMtrx, answerArr);
            capacity.at( transpElem->giveCrossSection()->giveNumber() ) -= answerArr1.sum();
        }
        internalSource.times( tStep->giveTimeIncrement() );
        internalSourceEnergy.add(internalSource);
        capacityEnergy.add(capacity);
        for ( int i = 1; i <= internalSourceEnergy.giveSize(); i++ ) {
            fprintf( this->stream, "% e ", internalSourceEnergy.at(i) );
        }
        fprintf(this->stream, "     ");
        for ( int i = 1; i <= capacityEnergy.giveSize(); i++ ) {
            fprintf( this->stream, "% e ", capacityEnergy.at(i) );
        }
        fprintf(this->stream, "\n");
#endif
    } else { //structural analysis
#ifdef __SM_MODULE
        StructuralElement *structElem;
        //int nnodes = d->giveNumberOfDofManagers();
        FloatArray VecStrain, VecStress, VecEigStrain, VecEigStrainReduced, tempStrain(6), tempStress(6), tempEigStrain(6), SumStrain(6), SumStress(6), SumEigStrain(6), tempFloatAr, damage;
        double sumDamage = 0.;
        //stress and strain vectors are always in global c.s.
        SumStrain.zero(); //xx, yy, zz, yz, zx, xy
        SumStress.zero();
        SumEigStrain.zero();

        for ( int ielem = 1; ielem <= nelem; ielem++ ) {
            Element *elem = d->giveElement(ielem);
            tempStrain.zero();
            tempStress.zero();
            tempEigStrain.zero();

            if ( this->matnum.giveSize() == 0 || this->matnum.contains( elem->giveMaterial()->giveNumber() ) ) {
                for ( GaussPoint *gp: *elem->giveDefaultIntegrationRulePtr() ) {
                    structElem = static_cast< StructuralElement * >(elem);
                    // structElem->computeResultingIPEigenstrainAt(VecEigStrain, tStep, gp, VM_Incremental);
                    structElem->computeResultingIPEigenstrainAt(VecEigStrainReduced, tStep, gp, VM_Total);
                    if ( VecEigStrainReduced.giveSize() == 0 ) {
                        VecEigStrain.resize(0);
                    } else {
                        ( ( StructuralMaterial * ) structElem->giveMaterial() )->giveFullSymVectorForm( VecEigStrain, VecEigStrainReduced,  gp->giveMaterialMode() );
                    }
                    dV  = elem->computeVolumeAround(gp);
                    elem->giveIPValue(VecStrain, gp, IST_StrainTensor, tStep);
                    elem->giveIPValue(VecStress, gp, IST_StressTensor, tStep);
                    elem->giveIPValue(damage, gp, IST_DamageTensor, tStep);

                    //truss element has strains and stresses in the first array so transform them to global coordinates
                    ///@todo Should this be the job of giveIPValue to ensure that vectors are given in global c.s.?
                    if ( dynamic_cast< Truss3d * >(elem) ) {
                        MaterialMode mmode = _3dMat;
                        tempStress.at(1) = VecStress.at(1);
                        tempStrain.at(1) = VecStrain.at(1);
                        if ( VecEigStrain.giveSize() ) {
                            tempEigStrain.at(1) = VecEigStrain.at(1);
                        }
                        StressVector stressVector1(tempStress, mmode); //convert from array
                        StressVector stressVector2(mmode);
                        StrainVector strainVector1(tempStrain, mmode); //convert from array
                        StrainVector strainVector2(mmode);
                        StrainVector strainEigVector1(tempEigStrain, mmode); //convert from array
                        StrainVector strainEigVector2(mmode);
                        elem->giveLocalCoordinateSystem(baseGCS);

                        stressVector1.transformTo(stressVector2, baseGCS, 0);
                        strainVector1.transformTo(strainVector2, baseGCS, 0);
                        strainEigVector1.transformTo(strainEigVector2, baseGCS, 0);

                        stressVector2.convertToFullForm(VecStress);
                        strainVector2.convertToFullForm(VecStrain);
                        strainEigVector2.convertToFullForm(VecEigStrain);
                    }

                    VolTot += dV;
                    VecStrain.times(dV);
                    VecStress.times(dV);
                    VecEigStrain.times(dV);
                    if ( damage.giveSize() ) { //only for models with damage
                        sumDamage += damage.at(1) * dV;
                    }

                    SumStrain.add(VecStrain);
                    SumEigStrain.add(VecEigStrain);
                    SumStress.add(VecStress);

                    //VecStrain.printYourself();
                    //VecEigStrain.printYourself();
                    //SumStrain.printYourself();
                }
            }
        }

        //averaging
        SumStrain.times(1. / VolTot * this->scale);
        SumEigStrain.times(1. / VolTot * this->scale);
        SumStress.times(1. / VolTot * this->scale);
        sumDamage *= ( 1. / VolTot );
        //SumStrain.printYourself();
        //SumEigStrain.printYourself();
        //SumStress.printYourself();
        fprintf( this->stream, "%f   ", tStep->giveTargetTime() );
        for ( double s: SumStrain ) { //strain
            fprintf( this->stream, "%06.5e ", s );
        }

        fprintf(this->stream, "    ");
        for ( double s: SumStress ) { //stress
            fprintf( this->stream, "%06.5e ", s );
        }

        fprintf(this->stream, "    ");
        for ( double s: SumEigStrain ) { //eigenstrain
            fprintf( this->stream, "%06.5e ", s );
        }

        fprintf(this->stream, "Vol %06.5e ", VolTot);
        fprintf(this->stream, "AvrDamage %06.5e ", sumDamage);
        fprintf(this->stream, "\n");

#endif
    }
    fflush(this->stream);
}
void
OrthotropicLinearElasticMaterial :: giveTensorRotationMatrix(FloatMatrix &answer, GaussPoint *gp)
//
// returns [3,3] rotation matrix from local principal axes of material
// to local axes used at gp (element) level
//
{
    int elementCsFlag;
    FloatMatrix elementCs;
    StructuralElement *element = static_cast< StructuralElement * >( gp->giveElement() );

    if ( gp->giveMaterialMode() == _1dMat ) { //do not rotate 1D materials on trusses and beams
        answer.resize(3, 3);
        answer.beUnitMatrix();
        return;
    }

    elementCsFlag = element->giveLocalCoordinateSystem(elementCs);
    //
    // in localCoordinateSystem the directional cosines are stored columwise (exception)
    // in elementCs rowwise.
    //
    if ( this->cs_type == localCS ) {
        //
        // in localCoordinateSystem are stored directional cosines
        //
        if ( elementCsFlag ) {
            answer.beProductOf(elementCs, * this->localCoordinateSystem);
        } else {
            answer = * this->localCoordinateSystem;
        }
    } else if ( this->cs_type == shellCS ) {
        FloatArray elementNormal, helpx, helpy;
        localCoordinateSystem = new FloatMatrix(3, 3);

        element->computeMidPlaneNormal(elementNormal, gp);
        helpx.beVectorProductOf(* ( this->helpPlaneNormal ), elementNormal);
        // test if localCoordinateSystem is uniquely
        // defined by elementNormal and helpPlaneNormal
        if ( helpx.computeNorm() < ZERO_LENGTH ) {
            OOFEM_ERROR("element normal parallel to plane normal encountered");
        }

        helpy.beVectorProductOf(elementNormal, helpx);
        for ( int i = 1; i < 4; i++ ) {
            localCoordinateSystem->at(i, 1) = helpx.at(i);
            localCoordinateSystem->at(i, 2) = helpy.at(i);
            localCoordinateSystem->at(i, 3) = elementNormal.at(i);
        }

        //
        // possible rotation about local z-axis should be considered in future
        //
        /*
         * //
         * // GiveZRotationMtrx assembles rotMtrx from cs rotated from curent about rotAngle
         * // to current cs
         * //
         * zRotMtrx = GiveZRotationMtrx (rotAngle); // rotAngle supplied by user
         * rotatedLocalCoordinateSystem = localCoordinateSystem->Times (zRotMtrx);
         * delete localCoordinateSystem;
         * localCoordinateSystem = rotatedLocalCoordinateSystem;
         */
        if ( elementCsFlag ) {
            answer.beProductOf(elementCs, * this->localCoordinateSystem);
        } else {
            answer = * this->localCoordinateSystem;
        }

        delete localCoordinateSystem;
        localCoordinateSystem = NULL;
    } else {
        OOFEM_ERROR("internal error no cs defined");
    }
    // t at (i,j) contains cosine of angle between elementAxis(i) and localMaterialAxis(j).
}
Esempio n. 20
0
void
XFEMStatic :: terminate(TimeStep *tStep)
{
    this->doStepOutput(tStep);
    this->printReactionForces(tStep, 1);
    // update load vectors before storing context
    fflush( this->giveOutputStream() );
    this->updateLoadVectors(tStep);
    this->saveStepContext(tStep);

    // Propagate fronts
    for ( auto &domain: domainList ) {
        XfemManager *xMan = domain->giveXfemManager();
        xMan->propagateFronts();
    }


    // Update element subdivisions if necessary
    // (e.g. if a crack has moved and cut a new element)
    for ( int domInd = 1; domInd <= this->giveNumberOfDomains(); domInd++ ) {
        Domain *domain = this->giveDomain(domInd);

        // create a new set containing all elements
        Set elemSet(0, domain);
        elemSet.addAllElements();

        if ( domain->giveXfemManager()->hasPropagatingFronts() || mForceRemap ) {
            // If domain cloning is performed, there is no need to
            // set values from the dof map.
            mSetValsFromDofMap = false;

            // Take copy of the domain to allow mapping of state variables
            // to the new Gauss points.
            Domain *dNew = domain->Clone();

            bool deallocateOld = false;
            setDomain(1, dNew, deallocateOld);
            forceEquationNumbering();

            // Map primary variables
            LSPrimaryVariableMapper primMapper;
            FloatArray u;
            primMapper.mapPrimaryVariables(u, * domain, * dNew, VM_Total, * tStep);


            if ( totalDisplacement.giveSize() == u.giveSize() ) {
                FloatArray diff;
                diff.beDifferenceOf(totalDisplacement, u);

                printf( "diff norm: %e\n", diff.computeNorm() );
            }

            totalDisplacement = u;


            primMapper.mapPrimaryVariables(incrementOfDisplacement, * domain, * dNew, VM_Incremental, * tStep);


            int numEl = dNew->giveNumberOfElements();

            for ( int i = 1; i <= numEl; i++ ) {
                ////////////////////////////////////////////////////////
                // Map state variables for regular Gauss points
                StructuralElement *el = dynamic_cast< StructuralElement * >( dNew->giveElement(i) );
                el->createMaterialStatus();
                el->mapStateVariables(* domain, * tStep);


                ////////////////////////////////////////////////////////
                // Map state variables for cohesive zone if applicable
                XfemStructuralElementInterface *xFemEl = dynamic_cast< XfemStructuralElementInterface * >(el);
                if ( xFemEl != NULL ) {
                    if ( xFemEl->mpCZMat != NULL ) {
                        size_t numCzRules = xFemEl->mpCZIntegrationRules.size();

                        for ( size_t czIndex = 0; czIndex < numCzRules; czIndex++ ) {
                            if ( xFemEl->mpCZIntegrationRules [ czIndex ] != NULL ) {
                                for ( GaussPoint *gp: *xFemEl->mpCZIntegrationRules [ czIndex ] ) {

                                    MaterialStatus *ms = xFemEl->mpCZMat->giveStatus(gp);
                                    if ( ms == NULL ) {
                                        OOFEM_ERROR("Failed to fetch material status.");
                                    }

                                    MaterialStatusMapperInterface *interface = dynamic_cast< MaterialStatusMapperInterface * >
                                                                               ( xFemEl->mpCZMat->giveStatus(gp) );

                                    if ( interface == NULL ) {
                                        OOFEM_ERROR("Failed to fetch MaterialStatusMapperInterface.");
                                    }


                                    MaterialStatus *matStat = dynamic_cast< MaterialStatus * >( xFemEl->mpCZMat->giveStatus(gp) );
                                    StructuralInterfaceMaterialStatus *siMatStat = dynamic_cast< StructuralInterfaceMaterialStatus * >(matStat);
                                    if ( siMatStat == NULL ) {
                                        OOFEM_ERROR("Failed to cast to StructuralInterfaceMaterialStatus.");
                                    }
                                    interface->MSMI_map_cz(* gp, * domain, elemSet, * tStep, * siMatStat);
                                }
                            }
                        }
                    }
                }
            }


            delete domain;
            domain = this->giveDomain(1);

            // Set domain pointer to various components ...
            this->nMethod->setDomain(domain);

            int numExpModules = this->exportModuleManager->giveNumberOfModules();
            for ( int i = 1; i <= numExpModules; i++ ) {
                //  ... by diving deep into the hierarchies ... :-/
                VTKXMLExportModule *vtkxmlMod = dynamic_cast< VTKXMLExportModule * >( this->exportModuleManager->giveModule(i) );
                if ( vtkxmlMod != NULL ) {
                    vtkxmlMod->giveSmoother()->setDomain(domain);
                    vtkxmlMod->givePrimVarSmoother()->setDomain(domain);
                }
            }


            this->setUpdateStructureFlag(true);
        } // if( domain->giveXfemManager()->hasPropagatingFronts() )

        //#endif
    }

    // Fracture/failure mechanics evaluation
    for ( auto &domain: domainList ) {
        if ( domain->hasFractureManager() ) { // Will most likely fail if numDom > 1
            FractureManager *fracMan = domain->giveFractureManager();
            fracMan->evaluateYourself(tStep);
            fracMan->updateXFEM(tStep); // Update XFEM structure based on the fracture manager

            this->setUpdateStructureFlag( fracMan->giveUpdateFlag() ); // if the internal structure need to be updated
        }
    }
}
Esempio n. 21
0
void
SimpleInterfaceMaterial :: giveStiffnessMatrix(FloatMatrix &answer,
                                               MatResponseMode rMode,
                                               GaussPoint *gp, TimeStep *tStep)
//
// Returns characteristic material stiffness matrix of the receiver
//
{
    MaterialMode mMode = gp->giveElement()->giveMaterialMode();

    FloatArray strainVector;
    StructuralElement *el = static_cast< StructuralElement * >( gp->giveElement() );
    double normalStrain;

    el->computeStrainVector(strainVector, gp, tStep);
    normalStrain = strainVector.at(1);
    answer.zero();
    switch ( mMode ) {
    case _1dInterface:
        answer.resize(1, 1);
        if ( rMode == SecantStiffness || rMode == TangentStiffness ) {
            if ( normalStrain + normalClearance <= 0 ) {
                answer.at(1, 1) = this->kn; //in compression and after the clearance gap closed
            } else {
                answer.at(1, 1) = this->kn * this->stiffCoeff;
            }
        } else {
            if ( rMode == ElasticStiffness ) {
                answer.at(1, 1) = this->kn;
            } else {
                OOFEM_ERROR("unknown MatResponseMode (%s)", __MatResponseModeToString(rMode) );
            }
        }

        return;

    case _2dInterface:
        answer.resize(2, 2);
        if ( rMode == SecantStiffness || rMode == TangentStiffness ) {
            if ( normalStrain + normalClearance <= 0. ) {
                answer.at(1, 1) = answer.at(2, 2) = this->kn; //in compression and after the clearance gap closed
            } else {
                answer.at(1, 1) = answer.at(2, 2) = this->kn * this->stiffCoeff;
            }
        } else {
            if ( rMode == ElasticStiffness ) {
                answer.at(1, 1) = answer.at(2, 2) = this->kn;
            } else {
                OOFEM_ERROR("unknown MatResponseMode (%s)", __MatResponseModeToString(rMode) );
            }
        }

        return;

    case _3dInterface:
        answer.resize(3, 3);
        if ( rMode == SecantStiffness || rMode == TangentStiffness ) {
            if ( normalStrain + normalClearance <= 0. ) {
                answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = this->kn; //in compression and after the clearance gap closed
            } else {
                answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = this->kn * this->stiffCoeff;
            }
        } else {
            if ( rMode == ElasticStiffness ) {
                answer.at(1, 1) = answer.at(2, 2) = answer.at(3, 3) = this->kn;
            } else {
                OOFEM_ERROR("unknown MatResponseMode (%s)", __MatResponseModeToString(rMode) );
            }
        }

        return;

    default:
        StructuralMaterial :: giveStiffnessMatrix(answer, rMode, gp, tStep);
    }
}
Esempio n. 22
0
void
SimpleInterfaceMaterial :: giveRealStressVector(FloatArray &answer, GaussPoint *gp,
                                                //const FloatArray &totalStrain,// @todo temporary -should not be here /JB
                                                const FloatArray &strainVector,
                                                TimeStep *tStep)
//
// returns real stress vector in 3d stress space of receiver according to
// previous level of stress and current
// strain increment, the only way, how to correctly update gp records
//
{
    SimpleInterfaceMaterialStatus *status = static_cast< SimpleInterfaceMaterialStatus * >( this->giveStatus(gp) );
    //this->initGpForNewStep(gp);
    this->initTempStatus(gp);
    FloatArray shearStrain(2), shearStress; //, strainVector;
    StructuralElement *el = static_cast< StructuralElement * >( gp->giveElement() );
    //el->computeStrainVector(strainVector, gp, tStep);

    FloatArray tempShearStressShift = status->giveTempShearStressShift();
    const double normalStrain = strainVector.at(1);
    double normalStress, maxShearStress, dp;
    double shift = -this->kn * this->stiffCoeff * normalClearance;

    MaterialMode mMode = el->giveMaterialMode();
    //answer.resize(giveSizeOfReducedStressStrainVector(mMode));
    answer.zero();
    if ( normalStrain + normalClearance <= 0. ) {
        normalStress = this->kn * ( normalStrain + normalClearance ) + shift; //in compression and after the clearance gap closed
        maxShearStress = fabs(normalStress) * this->frictCoeff;
    } else {
        normalStress = this->kn * this->stiffCoeff * ( normalStrain + normalClearance ) + shift;
        maxShearStress = 0.;
    }

    switch ( mMode ) {
    case _1dInterface:
        answer.resize(1);
        break;
    case _2dInterface:
        answer.resize(2);
        shearStrain.at(1) = strainVector.at(2);
        shearStress.beScaled(this->kn, shearStrain);
        shearStress.subtract(tempShearStressShift);
        dp = shearStress.dotProduct(shearStress, 1);
        if ( dp > maxShearStress * maxShearStress ) {
            shearStress.times( maxShearStress / sqrt(dp) );
        }

        tempShearStressShift.beScaled(this->kn, shearStrain);
        tempShearStressShift.subtract(shearStress);
        answer.at(2) = shearStress.at(1);
        break;
    case _3dInterface:
    case _3dMat: //JB
        answer.resize(3);
        shearStrain.at(1) = strainVector.at(2);
        shearStrain.at(2) = strainVector.at(3);
        shearStress.beScaled(this->kn, shearStrain);
        shearStress.subtract(tempShearStressShift);
        dp = shearStress.dotProduct(shearStress, 2);
        if ( dp > maxShearStress * maxShearStress ) {
            shearStress.times( maxShearStress / sqrt(dp) );
        }

        tempShearStressShift.beScaled(this->kn, shearStrain);
        tempShearStressShift.subtract(shearStress);
        answer.at(2) = shearStress.at(1);
        answer.at(3) = shearStress.at(2);
        break;
    default:
        OOFEM_ERROR("Unsupported interface mode");
    }

    double lim = 1.e+50;
    answer.at(1) = min(normalStress, lim);  //threshold on maximum
    answer.at(1) = max(answer.at(1), -lim);  //threshold on minimum
    //answer.at(1) = normalStress > lim ? lim : normalStress < -lim ? -lim : normalStress;
    // update gp
    status->setTempShearStressShift(tempShearStressShift);
    status->letTempStrainVectorBe(strainVector);
    status->letTempStressVectorBe(answer);
}
Esempio n. 23
0
void LSPrimaryVariableMapper :: mapPrimaryVariables(FloatArray &oU, Domain &iOldDom, Domain &iNewDom, ValueModeType iMode, TimeStep &iTStep)
{
    EngngModel *engngMod = iNewDom.giveEngngModel();
    EModelDefaultEquationNumbering num;


    const int dim = iNewDom.giveNumberOfSpatialDimensions();

    int numElNew = iNewDom.giveNumberOfElements();

    // Count dofs
    int numDofsNew = engngMod->giveNumberOfDomainEquations( 1, num );


    oU.resize(numDofsNew);
    oU.zero();

    FloatArray du(numDofsNew);
    du.zero();

    FloatArray res(numDofsNew);

#ifdef __PETSC_MODULE
    PetscSparseMtrx *K = dynamic_cast<PetscSparseMtrx*>( classFactory.createSparseMtrx(SMT_PetscMtrx) );
    SparseLinearSystemNM *solver = classFactory.createSparseLinSolver(ST_Petsc, & iOldDom, engngMod);
#else
    SparseMtrx *K = classFactory.createSparseMtrx(SMT_Skyline);
    SparseLinearSystemNM *solver = classFactory.createSparseLinSolver(ST_Direct, & iOldDom, engngMod);
#endif


    K->buildInternalStructure( engngMod, 1, num );

    int maxIter = 1;

    for ( int iter = 0; iter < maxIter; iter++ ) {
        K->zero();
        res.zero();


        // Contribution from elements
        for ( int elIndex = 1; elIndex <= numElNew; elIndex++ ) {
            StructuralElement *elNew = dynamic_cast< StructuralElement * >( iNewDom.giveElement(elIndex) );
            if ( elNew == NULL ) {
                OOFEM_ERROR("Failed to cast Element new to StructuralElement.");
            }

            ///////////////////////////////////
            // Compute residual

            // Count element dofs
            int numElNodes = elNew->giveNumberOfDofManagers();
            int numElDofs = 0;
            for ( int i = 1; i <= numElNodes; i++ ) {
                numElDofs += elNew->giveDofManager(i)->giveNumberOfDofs();
            }

            FloatArray elRes(numElDofs);
            elRes.zero();

            IntArray elDofsGlob;
            elNew->giveLocationArray( elDofsGlob, num );


            // Loop over Gauss points
            for ( int intRuleInd = 0; intRuleInd < elNew->giveNumberOfIntegrationRules(); intRuleInd++ ) {
                IntegrationRule *iRule = elNew->giveIntegrationRule(intRuleInd);

                for ( GaussPoint *gp: *iRule ) {

                    // New N-matrix
                    FloatMatrix NNew;
                    elNew->computeNmatrixAt(* ( gp->giveNaturalCoordinates() ), NNew);


                    //////////////
                    // Global coordinates of GP
                    const int nDofMan = elNew->giveNumberOfDofManagers();

                    FloatArray Nc;
                    FEInterpolation *interp = elNew->giveInterpolation();
                    const FloatArray &localCoord = * ( gp->giveNaturalCoordinates() );
                    interp->evalN( Nc, localCoord, FEIElementGeometryWrapper(elNew) );

                    const IntArray &elNodes = elNew->giveDofManArray();

                    FloatArray globalCoord(dim);
                    globalCoord.zero();

                    for ( int i = 1; i <= nDofMan; i++ ) {
                        DofManager *dMan = elNew->giveDofManager(i);

                        for ( int j = 1; j <= dim; j++ ) {
                            globalCoord.at(j) += Nc.at(i) * dMan->giveCoordinate(j);
                        }
                    }
                    //////////////


                    // Localize element and point in the old domain
                    FloatArray localCoordOld(dim), pointCoordOld(dim);
                    StructuralElement *elOld = dynamic_cast< StructuralElement * >( iOldDom.giveSpatialLocalizer()->giveElementClosestToPoint(localCoordOld, pointCoordOld, globalCoord, 0) );
                    if ( elOld == NULL ) {
                        OOFEM_ERROR("Failed to cast Element old to StructuralElement.");
                    }


                    // Compute N-Matrix for the old element
                    FloatMatrix NOld;
                    elOld->computeNmatrixAt(localCoordOld, NOld);

                    // Fetch nodal displacements for the new element
                    FloatArray nodeDispNew( elDofsGlob.giveSize() );


                    int dofsPassed = 1;
                    for ( int i = 1; i <= elNodes.giveSize(); i++ ) {
                        DofManager *dMan = elNew->giveDofManager(i);

                        for ( Dof *dof: *dMan ) {
                            if ( elDofsGlob.at(dofsPassed) != 0 ) {
                                nodeDispNew.at(dofsPassed) = oU.at( elDofsGlob.at(dofsPassed) );
                            } else {
                                if ( dof->hasBc(& iTStep) ) {
                                    nodeDispNew.at(dofsPassed) = dof->giveBcValue(iMode, & iTStep);
                                }
                            }

                            dofsPassed++;
                        }
                    }


                    FloatArray newDisp;
                    newDisp.beProductOf(NNew, nodeDispNew);


                    // Fetch nodal displacements for the old element
                    FloatArray nodeDispOld;
                    dofsPassed = 1;
                    IntArray elDofsGlobOld;
                    elOld->giveLocationArray( elDofsGlobOld, num );

//                    elOld->computeVectorOf(iMode, &(iTStep), nodeDisp);
                    int numElNodesOld = elOld->giveNumberOfDofManagers();
                    for(int nodeIndOld = 1; nodeIndOld <= numElNodesOld; nodeIndOld++) {
                        DofManager *dManOld = elOld->giveDofManager(nodeIndOld);

                        for ( Dof *dof: *dManOld ) {
                            if ( elDofsGlobOld.at(dofsPassed) != 0 ) {
                                FloatArray dofUnknowns;
                                dof->giveUnknowns(dofUnknowns, iMode, &iTStep);

#ifdef DEBUG
                                if(!dofUnknowns.isFinite()) {
                                    OOFEM_ERROR("!dofUnknowns.isFinite()")
                                }

                                if(dofUnknowns.giveSize() < 1) {
                                    OOFEM_ERROR("dofUnknowns.giveSize() < 1")
                                }
#endif
                                nodeDispOld.push_back(dofUnknowns.at(1));
                            } else {
                                if ( dof->hasBc(& iTStep) ) {
//                                    printf("hasBC.\n");
#ifdef DEBUG
                                    if(!std::isfinite(dof->giveBcValue(iMode, & iTStep))) {
                                        OOFEM_ERROR("!std::isfinite(dof->giveBcValue(iMode, & iTStep))")
                                    }
#endif
                                    nodeDispOld.push_back( dof->giveBcValue(iMode, & iTStep) );
                                }
                                else {
//                                    printf("Unhandled case in LSPrimaryVariableMapper :: mapPrimaryVariables().\n");
                                    nodeDispOld.push_back( 0.0 );
                                }
                            }

                            dofsPassed++;
                        }

                    }


                    FloatArray oldDisp;
                    oldDisp.beProductOf(NOld, nodeDispOld);

                    FloatArray temp, du;

#ifdef DEBUG
                    if(!oldDisp.isFinite()) {
                        OOFEM_ERROR("!oldDisp.isFinite()")
                    }

                    if(!newDisp.isFinite()) {
                        OOFEM_ERROR("!newDisp.isFinite()")
                    }
#endif

                    du.beDifferenceOf(oldDisp, newDisp);
                    temp.beTProductOf(NNew, du);
                    double dV = elNew->computeVolumeAround(gp);
                    elRes.add(dV, temp);
                }
            }