void
NonStationaryTransportProblem :: updateYourself(TimeStep *tStep)
{
    this->updateInternalState(tStep);
    EngngModel :: updateYourself(tStep);

    ///@todo Find a cleaner way to do these cemhyd hacks
#ifdef __CEMHYD_MODULE
    for ( auto &domain: this->domainList ) {
        for ( int i = 1; i <= domain->giveNumberOfElements(); ++i ) {
            TransportElement *elem = static_cast< TransportElement * >( domain->giveElement(i) );
            //store temperature and associated volume on each GP before performing averaging
            CemhydMat *cem = dynamic_cast< CemhydMat * >( elem->giveMaterial() );
            if ( cem ) {
                cem->clearWeightTemperatureProductVolume(elem);
                cem->storeWeightTemperatureProductVolume(elem, tStep);
            }
        }
        //perform averaging on each material instance
        for ( int i = 1; i <= domain->giveNumberOfMaterialModels(); i++ ) {
            CemhydMat *cem = dynamic_cast< CemhydMat * >( domain->giveMaterial(i) );
            if ( cem ) {
                cem->averageTemperature();
            }
        }
    }
 #ifdef VERBOSE
    VERBOSE_PRINT0("Updated Materials ", 0)
 #endif
#endif
}
// needed for CemhydMat
void
NonStationaryTransportProblem :: averageOverElements(TimeStep *tStep)
{
    ///@todo Verify this, the function is completely unused.
    Domain *domain = this->giveDomain(1);
    int nelem = domain->giveNumberOfElements();
    FloatArray vecTemperature;

    for ( int ielem = 1; ielem <= nelem; ielem++ ) {
        TransportElement *element = static_cast< TransportElement * >( domain->giveElement(ielem) );
        TransportMaterial *mat = static_cast< CemhydMat * >( element->giveMaterial() );
        if ( mat ) {
            for ( GaussPoint *gp: *element->giveDefaultIntegrationRulePtr() ) {
                element->giveIPValue(vecTemperature, gp, IST_Temperature, tStep);
                //mat->IP_volume += dV;
                //mat->average_temp += vecState.at(1) * dV;
            }
        }
    }

    for ( int i = 1; i <= domain->giveNumberOfMaterialModels(); i++ ) {
        CemhydMat *mat = static_cast< CemhydMat * >( domain->giveMaterial(i) );
        if ( mat ) {
            //mat->average_temp /= mat->IP_volume;
        }
    }
}
void
NLTransientTransportProblem :: applyIC(TimeStep *stepWhenIcApply)
{
    Domain *domain = this->giveDomain(1);

    NonStationaryTransportProblem :: applyIC(stepWhenIcApply);

    // update element state according to given ic
    for ( auto &elem : domain->giveElements() ) {
        TransportElement *element = static_cast< TransportElement * >( elem.get() );
        element->updateInternalState(stepWhenIcApply);
        element->updateYourself(stepWhenIcApply);
    }
}
void
TransientTransportProblem :: applyIC()
{
    Domain *domain = this->giveDomain(1);
    OOFEM_LOG_INFO("Applying initial conditions\n");

    this->field->applyDefaultInitialCondition();

    ///@todo It's rather strange that the models need the initial values.
    // update element state according to given ic
    TimeStep *s = this->giveSolutionStepWhenIcApply();
    for ( auto &elem : domain->giveElements() ) {
        TransportElement *element = static_cast< TransportElement * >( elem.get() );
        element->updateInternalState(s);
        element->updateYourself(s);
    }
}
// needed for CemhydMat
void
NonStationaryTransportProblem :: averageOverElements(TimeStep *tStep)
{
    Domain *domain = this->giveDomain(1);
    int ielem, i;
    int nelem = domain->giveNumberOfElements();
    double dV;
    TransportElement *element;
    IntegrationRule *iRule;
    GaussPoint *gp;
    FloatArray vecTemperature;
    TransportMaterial *mat;




    for ( ielem = 1; ielem <= nelem; ielem++ ) {
        element = ( TransportElement * ) domain->giveElement(ielem);
        mat = ( TransportMaterial * ) element->giveMaterial();
        if ( mat->giveClassID() == CemhydMatClass ) {
            iRule = element->giveDefaultIntegrationRulePtr();
            for ( i = 0; i < iRule->getNumberOfIntegrationPoints(); i++ ) {
                gp  = iRule->getIntegrationPoint(i);
                dV  = element->computeVolumeAround(gp);
                element->giveIPValue(vecTemperature, gp, IST_Temperature, tStep);
                //mat->IP_volume += dV;
                //mat->average_temp += vecState.at(1) * dV;
            }
        }
    }

    for ( i = 1; i <= domain->giveNumberOfMaterialModels(); i++ ) {
        mat = ( TransportMaterial * ) domain->giveMaterial(i);
        if ( mat->giveClassID() == CemhydMatClass ) {
            //mat->average_temp /= mat->IP_volume;
        }
    }
}
Beispiel #6
0
void TransportMaterialStatus :: printOutputAt(FILE *File, TimeStep *tNow)
// Print the state variable and the flow vector on the data file.
{
    FloatArray flowVec;
    TransportElement *transpElem = static_cast< TransportElement * >( gp->giveElement() );

    MaterialStatus :: printOutputAt(File, tNow);

    fprintf(File, "  state");

    for ( int i = 1; i <= field.giveSize(); i++ ) {
        fprintf( File, " % .4e", field.at(i) );
    }

    transpElem->computeFlow(flowVec, gp, tNow);

    fprintf(File, "   flow");
    for ( int i = 1; i <= flowVec.giveSize(); i++ ) {
        fprintf( File, " % .4e", flowVec.at(i) );
    }

    fprintf(File, "\n");
}
Beispiel #7
0
int
TransportMaterial :: giveIPValue(FloatArray &answer, GaussPoint *gp, InternalStateType type, TimeStep *tStep)
// IST_Humidity must be overriden!
{
    TransportMaterialStatus *ms = static_cast< TransportMaterialStatus * >( this->giveStatus(gp) );
    if ( type == IST_Temperature || type == IST_MassConcentration_1 || type == IST_Humidity ) {
        FloatArray vec = ms->giveField();
        answer = FloatArray{vec.at( ( type == IST_Temperature ) ? 1 : 2 ) };
        return 1;
    } else if ( type == IST_TemperatureFlow ) {
        TransportElement *transpElem = static_cast< TransportElement * >( gp->giveElement() );
        transpElem->computeFlow(answer, gp, tStep);
        return 1;
    } else if ( type == IST_Velocity ) { ///@todo Shouldn't be named velocity.. instead, "MassFlow" or something suitable like that.
        answer = ms->giveFlux();
        answer.resizeWithValues(3);
        return 1;
    } else if ( type == IST_PressureGradient ) {
        answer = ms->giveGradient();
        answer.resizeWithValues(3);
        return 1;
    } else if ( type == IST_Density ) {
        answer = FloatArray{ this->give('d', gp) };
        return 1;
    } else if ( type == IST_HeatCapacity ) {
        answer = FloatArray{ this->give('c', gp) };
        return 1;
    } else if ( type == IST_ThermalConductivityIsotropic ) {
        answer = FloatArray{ this->give('k', gp) };
        return 1;
    } else if ( type == IST_Maturity ) {
        answer = FloatArray{ ms->giveMaturity() };
        return 1;
    }
    return Material :: giveIPValue(answer, gp, type, tStep);
}
void
NonStationaryTransportProblem :: applyIC(TimeStep *stepWhenIcApply)
{
    Domain *domain = this->giveDomain(1);
    int neq =  this->giveNumberOfEquations(EID_ConservationEquation);
    FloatArray *solutionVector;
    double val;

#ifdef VERBOSE
    OOFEM_LOG_INFO("Applying initial conditions\n");
#endif
    int nDofs, j, k, jj;
    int nman  = domain->giveNumberOfDofManagers();
    DofManager *node;
    Dof *iDof;

    UnknownsField->advanceSolution(stepWhenIcApply);
    solutionVector = UnknownsField->giveSolutionVector(stepWhenIcApply);
    solutionVector->resize(neq);
    solutionVector->zero();

    for ( j = 1; j <= nman; j++ ) {
        node = domain->giveDofManager(j);
        nDofs = node->giveNumberOfDofs();

        for ( k = 1; k <= nDofs; k++ ) {
            // ask for initial values obtained from
            // bc (boundary conditions) and ic (initial conditions)
            iDof  =  node->giveDof(k);
            if ( !iDof->isPrimaryDof() ) {
                continue;
            }

            jj = iDof->__giveEquationNumber();
            if ( jj ) {
                val = iDof->giveUnknown(EID_ConservationEquation, VM_Total, stepWhenIcApply);
                solutionVector->at(jj) = val;
                //update in dictionary, if the problem is growing/decreasing
                if ( this->changingProblemSize ) {
                    iDof->updateUnknownsDictionary(stepWhenIcApply, EID_MomentumBalance, VM_Total, val);
                }
            }
        }
    }

    int nelem = domain->giveNumberOfElements();
    
    //project initial temperature to integration points

//     for ( j = 1; j <= nelem; j++ ) {
//         domain->giveElement(j)->updateInternalState(stepWhenIcApply);
//     }

#ifdef __CEMHYD_MODULE
    // Not relevant in linear case, but needed for CemhydMat for temperature averaging before solving balance equations
    // Update element state according to given ic
    TransportElement *element;
    CemhydMat *cem;
    for ( j = 1; j <= nelem; j++ ) {
        element = ( TransportElement * ) domain->giveElement(j);
        //assign status to each integration point on each element
        if ( element->giveMaterial()->giveClassID() == CemhydMatClass ) {
            element->giveMaterial()->initMaterial(element); //create microstructures and statuses on specific GPs
            element->updateInternalState(stepWhenIcApply);   //store temporary unequilibrated temperature
            element->updateYourself(stepWhenIcApply);   //store equilibrated temperature
            cem = ( CemhydMat * ) element->giveMaterial();
            cem->clearWeightTemperatureProductVolume(element);
            cem->storeWeightTemperatureProductVolume(element, stepWhenIcApply);
        }
    }

    //perform averaging on each material instance of CemhydMatClass
    int nmat = domain->giveNumberOfMaterialModels();
    for ( j = 1; j <= nmat; j++ ) {
        if ( domain->giveMaterial(j)->giveClassID() == CemhydMatClass ) {
            cem = ( CemhydMat * ) domain->giveMaterial(j);
            cem->averageTemperature();
        }
    }
#endif //__CEMHYD_MODULE
}
void
NonStationaryTransportProblem :: applyIC(TimeStep *stepWhenIcApply)
{
    Domain *domain = this->giveDomain(1);
    int neq =  this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() );
    FloatArray *solutionVector;
    double val;

#ifdef VERBOSE
    OOFEM_LOG_INFO("Applying initial conditions\n");
#endif

    UnknownsField->advanceSolution(stepWhenIcApply);
    solutionVector = UnknownsField->giveSolutionVector(stepWhenIcApply);
    solutionVector->resize(neq);
    solutionVector->zero();

    for ( auto &node : domain->giveDofManagers() ) {

        for ( Dof *dof: *node ) {
            // ask for initial values obtained from
            // bc (boundary conditions) and ic (initial conditions)
            if ( !dof->isPrimaryDof() ) {
                continue;
            }

            int jj = dof->__giveEquationNumber();
            if ( jj ) {
                val = dof->giveUnknown(VM_Total, stepWhenIcApply);
                solutionVector->at(jj) = val;
                //update in dictionary, if the problem is growing/decreasing
                if ( this->changingProblemSize ) {
                    dof->updateUnknownsDictionary(stepWhenIcApply, VM_Total, val);
                }
            }
        }
    }


    //project initial temperature to integration points

    //     for ( int j = 1; j <= nelem; j++ ) {
    //         domain->giveElement(j)->updateInternalState(stepWhenIcApply);
    //     }

#ifdef __CEMHYD_MODULE
    // Not relevant in linear case, but needed for CemhydMat for temperature averaging before solving balance equations
    // Update element state according to given ic
    for ( auto &elem : domain->giveElements() ) {
        TransportElement *element = static_cast< TransportElement * >( elem.get() );
        CemhydMat *cem = dynamic_cast< CemhydMat * >( element->giveMaterial() );
        //assign status to each integration point on each element
        if ( cem ) {
            cem->initMaterial(element); //create microstructures and statuses on specific GPs
            element->updateInternalState(stepWhenIcApply);   //store temporary unequilibrated temperature
            element->updateYourself(stepWhenIcApply);   //store equilibrated temperature
            cem->clearWeightTemperatureProductVolume(element);
            cem->storeWeightTemperatureProductVolume(element, stepWhenIcApply);
        }
    }

    //perform averaging on each material instance of CemhydMatClass
    for ( auto &mat : domain->giveMaterials() ) {
        CemhydMat *cem = dynamic_cast< CemhydMat * >( mat.get() );
        if ( cem ) {
            cem->averageTemperature();
        }
    }

#endif //__CEMHYD_MODULE
}
Beispiel #10
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);
}