void FE2FluidMaterial :: giveDeviatoricStiffnessMatrix(FloatMatrix &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp));
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        answer = ms->giveDeviatoricTangent();
#ifdef DEBUG_TANGENT
        // Numerical ATS for debugging
        FloatArray tempStrain(3); tempStrain.zero();
        FloatArray sig, strain, sig11, sig22, sig12;
        double epspvol;
        computeDeviatoricStressVector (sig, epspvol, gp, tempStrain, 0.0, tStep);
        double h = 0.001; // Linear problem, size of this doesn't matter.
        strain.resize(3);
        strain = tempStrain; strain.at(1) += h;
        computeDeviatoricStressVector (sig11, epspvol, gp, strain, 0.0, tStep);
        strain = tempStrain; strain.at(2) += h;
        computeDeviatoricStressVector (sig22, epspvol, gp, strain, 0.0, tStep);
        strain = tempStrain; strain.at(3) += h;
        computeDeviatoricStressVector (sig12, epspvol, gp, strain, 0.0, tStep);

        FloatArray dsig11; dsig11.beDifferenceOf(sig11,sig); dsig11.times(1/h);
        FloatArray dsig22; dsig22.beDifferenceOf(sig22,sig); dsig22.times(1/h);
        FloatArray dsig12; dsig12.beDifferenceOf(sig12,sig); dsig12.times(1/h);

        FloatMatrix numericalATS;
        numericalATS.resize(3,3);
        numericalATS.zero();
        numericalATS.setColumn(dsig11,1);
        numericalATS.setColumn(dsig22,2);
        numericalATS.setColumn(dsig12,3);
        printf("Analytical deviatoric tangent = "); answer.printYourself();
        printf("Numerical deviatoric tangent = "); numericalATS.printYourself();
        numericalATS.subtract(answer);
        double norm = numericalATS.computeFrobeniusNorm();
        if (norm > answer.computeFrobeniusNorm()*DEBUG_ERR && norm > 0.0) {
            OOFEM_ERROR("Error in deviatoric tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
void FE2FluidMaterial :: giveVolumetricDeviatoricStiffness(FloatArray &answer, MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast<FE2FluidMaterialStatus*> (this->giveStatus(gp));
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        answer = ms->giveVolumetricDeviatoricTangent();
#ifdef DEBUG_TANGENT
        // Numerical ATS for debugging
        FloatArray tempStrain(3); tempStrain.zero();
        FloatArray sig, strain;
        double epspvol, epspvol11, epspvol22, epspvol12, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector (sig, epspvol, gp, tempStrain, pressure, tStep);
        strain = tempStrain; strain.at(1) += h;
        computeDeviatoricStressVector(sig, epspvol11, gp, strain, pressure, tStep);
        strain = tempStrain; strain.at(2) += h;
        computeDeviatoricStressVector(sig, epspvol22, gp, strain, pressure, tStep);
        strain = tempStrain; strain.at(3) += h;
        computeDeviatoricStressVector(sig, epspvol12, gp, strain, pressure, tStep);

        FloatArray dvol(3);
        dvol.at(1) = (epspvol11 - epspvol)/h;
        dvol.at(2) = (epspvol22 - epspvol)/h;
        dvol.at(3) = (epspvol12 - epspvol)/h;
        dvol.at(1) += 1.0;
        dvol.at(2) += 1.0;

        printf("Analytical volumetric deviatoric tangent = "); answer.printYourself();
        printf("Numerical volumetric deviatoric tangent = "); dvol.printYourself();
        dvol.subtract(answer);
        double norm = dvol.computeNorm();
        if (norm > answer.computeNorm()*DEBUG_ERR && norm > 0.0) {
            OOFEM_ERROR("Error in volumetric deviatoric tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
Exemple #3
0
void FE2FluidMaterial :: giveStiffnessMatrices(FloatMatrix &dsdd, FloatArray &dsdp, FloatArray &dedd, double &dedp,
                                               MatResponseMode mode, GaussPoint *gp, TimeStep *tStep)
{
    FE2FluidMaterialStatus *ms = static_cast< FE2FluidMaterialStatus * >( this->giveStatus(gp) );
    ms->computeTangents(tStep);
    if ( mode == TangentStiffness ) {
        dsdd = ms->giveDeviatoricTangent();
        dsdp = ms->giveDeviatoricPressureTangent();
        dedd = ms->giveVolumetricDeviatoricTangent();
        dedp = ms->giveVolumetricPressureTangent();
#if 0
        // Numerical ATS for debugging
        FloatMatrix numericalATS(6, 6);
        FloatArray dsig;
        FloatArray tempStrain(6);

        tempStrain.zero();
        FloatArray sig, strain, sigPert;
        double epspvol;
        computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, 0., tStep);
        double h = 0.001; // Linear problem, size of this doesn't matter.
        for ( int k = 1; k <= 6; ++k ) {
            strain = tempStrain;
            strain.at(k) += h;
            double tmp = strain.at(1) + strain.at(2) + strain.at(3);
            strain.at(1) -= tmp/3.0;
            strain.at(2) -= tmp/3.0;
            strain.at(3) -= tmp/3.0;
            strain.printYourself();
            computeDeviatoricStressVector(sigPert, epspvol, gp, strain, 0., tStep);
            sigPert.printYourself();
            dsig.beDifferenceOf(sigPert, sig);
            numericalATS.setColumn(dsig, k);
        }
        numericalATS.times(1. / h);

        printf("Analytical deviatoric tangent = ");
        dsdd.printYourself();
        printf("Numerical deviatoric tangent = ");
        numericalATS.printYourself();
        numericalATS.subtract(dsdd);
        double norm = numericalATS.computeFrobeniusNorm();
        if ( norm > dsdd.computeFrobeniusNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in deviatoric tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray strain(3);
        strain.zero();
        FloatArray sig, sigh;
        double epspvol, pressure = 0.0;
        double h = 1.00; // Linear problem, size of this doesn't matter.
        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sigh, epspvol, gp, strain, pressure + h, tStep);

        FloatArray dsigh;
        dsigh.beDifferenceOf(sigh, sig);
        dsigh.times(1 / h);

        printf("Analytical deviatoric pressure tangent = ");
        dsdp.printYourself();
        printf("Numerical deviatoric pressure tangent = ");
        dsigh.printYourself();
        dsigh.subtract(dsdp);
        double norm = dsigh.computeNorm();
        if ( norm > dsdp.computeNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in deviatoric pressure tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray tempStrain(3);
        tempStrain.zero();
        FloatArray sig, strain;
        double epspvol, epspvol11, epspvol22, epspvol12, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, tempStrain, pressure, tStep);
        strain = tempStrain;
        strain.at(1) += h;
        computeDeviatoricStressVector(sig, epspvol11, gp, strain, pressure, tStep);
        strain = tempStrain;
        strain.at(2) += h;
        computeDeviatoricStressVector(sig, epspvol22, gp, strain, pressure, tStep);
        strain = tempStrain;
        strain.at(3) += h;
        computeDeviatoricStressVector(sig, epspvol12, gp, strain, pressure, tStep);

        FloatArray dvol(3);
        dvol.at(1) = ( epspvol11 - epspvol ) / h;
        dvol.at(2) = ( epspvol22 - epspvol ) / h;
        dvol.at(3) = ( epspvol12 - epspvol ) / h;
        dvol.at(1) += 1.0;
        dvol.at(2) += 1.0;

        printf("Analytical volumetric deviatoric tangent = ");
        dedd.printYourself();
        printf("Numerical volumetric deviatoric tangent = ");
        dvol.printYourself();
        dvol.subtract(dedd);
        double norm = dvol.computeNorm();
        if ( norm > dedd.computeNorm() * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in volumetric deviatoric tangent");
        }
#endif
#if 0
        // Numerical ATS for debugging
        FloatArray strain(3);
        strain.zero();
        FloatArray sig;
        double epspvol, epspvolh, pressure = 0.0;
        double h = 1.0; // Linear problem, size of this doesn't matter.

        computeDeviatoricStressVector(sig, epspvol, gp, strain, pressure, tStep);
        computeDeviatoricStressVector(sig, epspvolh, gp, strain, pressure + h, tStep);

        double dvol = -( epspvolh - epspvol ) / h;

        printf("Analytical volumetric pressure tangent = %e\n", dedp);
        printf("Numerical volumetric pressure tangent = %e\n", dvol);

        double norm = fabs(dvol - dedp);
        if ( norm > fabs(dedp) * DEBUG_ERR && norm > 0.0 ) {
            OOFEM_ERROR("Error in volumetric pressure tangent");
        }
#endif
    } else {
        OOFEM_ERROR("Mode not implemented");
    }
}
Exemple #4
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);
}