예제 #1
0
void
NonLinearStatic :: assembleIncrementalReferenceLoadVectors(FloatArray &_incrementalLoadVector,
                                                           FloatArray &_incrementalLoadVectorOfPrescribed,
                                                           SparseNonLinearSystemNM :: referenceLoadInputModeType _refMode,
                                                           Domain *sourceDomain, TimeStep *tStep)
{
    _incrementalLoadVector.resize( sourceDomain->giveEngngModel()->giveNumberOfDomainEquations( sourceDomain->giveNumber(), EModelDefaultEquationNumbering() ) );
    _incrementalLoadVector.zero();
    _incrementalLoadVectorOfPrescribed.resize( sourceDomain->giveEngngModel()->giveNumberOfDomainEquations( sourceDomain->giveNumber(), EModelDefaultPrescribedEquationNumbering() ) );
    _incrementalLoadVectorOfPrescribed.zero();

    if ( _refMode == SparseNonLinearSystemNM :: rlm_incremental ) {
        ///@todo This was almost definitely wrong before. It never seems to be used. Is this code even relevant?
        this->assembleVector(_incrementalLoadVector, tStep, ExternalForceAssembler(),
                             VM_Incremental, EModelDefaultEquationNumbering(), sourceDomain);

        this->assembleVector(_incrementalLoadVectorOfPrescribed, tStep, ExternalForceAssembler(),
                             VM_Incremental, EModelDefaultPrescribedEquationNumbering(), sourceDomain);
    } else {
        this->assembleVector(_incrementalLoadVector, tStep, ExternalForceAssembler(),
                             VM_Total, EModelDefaultEquationNumbering(), sourceDomain);

        this->assembleVector(_incrementalLoadVectorOfPrescribed, tStep, ExternalForceAssembler(),
                             VM_Total, EModelDefaultPrescribedEquationNumbering(), sourceDomain);
    }

    this->updateSharedDofManagers(_incrementalLoadVector, EModelDefaultEquationNumbering(), LoadExchangeTag);
}
예제 #2
0
void
NonLinearStatic :: unpackMigratingData(TimeStep *tStep)
{
    Domain *domain = this->giveDomain(1);
    int ndofman = domain->giveNumberOfDofManagers();
    //int myrank = this->giveRank();

    // resize target arrays
    int neq = this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() );
    totalDisplacement.resize(neq);
    incrementOfDisplacement.resize(neq);
    incrementalLoadVector.resize(neq);
    initialLoadVector.resize(neq);
    initialLoadVectorOfPrescribed.resize( giveNumberOfDomainEquations( 1, EModelDefaultPrescribedEquationNumbering() ) );
    incrementalLoadVectorOfPrescribed.resize( giveNumberOfDomainEquations( 1, EModelDefaultPrescribedEquationNumbering() ) );

    for ( int idofman = 1; idofman <= ndofman; idofman++ ) {
        DofManager *_dm = domain->giveDofManager(idofman);
        for ( Dof *_dof: *_dm ) {
            if ( _dof->isPrimaryDof() ) {
                int _eq;
                if ( ( _eq = _dof->__giveEquationNumber() ) ) {
                    // pack values in solution vectors
                    totalDisplacement.at(_eq) = _dof->giveUnknownsDictionaryValue( tStep, VM_Total );
                    initialLoadVector.at(_eq) = _dof->giveUnknownsDictionaryValue( tStep, VM_RhsInitial );
                    incrementalLoadVector.at(_eq) = _dof->giveUnknownsDictionaryValue( tStep, VM_RhsIncremental );

 #if 0
                    // debug print
                    if ( _dm->giveParallelMode() == DofManager_shared ) {
                        fprintf(stderr, "[%d] Shared: %d(%d) -> %d\n", myrank, idofman, idof, _eq);
                    } else {
                        fprintf(stderr, "[%d] Local : %d(%d) -> %d\n", myrank, idofman, idof, _eq);
                    }

 #endif
                } else if ( ( _eq = _dof->__givePrescribedEquationNumber() ) ) {
                    // pack values in prescribed solution vectors
                    initialLoadVectorOfPrescribed.at(_eq) = _dof->giveUnknownsDictionaryValue( tStep, VM_RhsInitial );
                    incrementalLoadVectorOfPrescribed.at(_eq) = _dof->giveUnknownsDictionaryValue( tStep, VM_RhsIncremental );

 #if 0
                    // debug print
                    fprintf(stderr, "[%d] %d(%d) -> %d\n", myrank, idofman, idof, -_eq);
 #endif
                }
            } // end primary dof
        } // end dof loop
    } // end dofman loop

    this->initializeCommMaps(true);
    nMethod->reinitialize();
    // reinitialize error estimator (if any)
    if ( this->giveDomainErrorEstimator(1) ) {
        this->giveDomainErrorEstimator(1)->reinitialize();
    }

    initFlag = true;
}
예제 #3
0
void
StructuralEngngModel :: computeExternalLoadReactionContribution(FloatArray &reactions, TimeStep *tStep, int di)
{
    reactions.resize( this->giveNumberOfDomainEquations( di, EModelDefaultPrescribedEquationNumbering() ) );
    reactions.zero();
    this->assembleVector( reactions, tStep, EID_MomentumBalance, ExternalForcesVector, VM_Total,
                         EModelDefaultPrescribedEquationNumbering(), this->giveDomain(di) );
}
예제 #4
0
void
StructuralEngngModel :: computeReaction(FloatArray &answer, TimeStep *tStep, int di)
{
    FloatArray contribution;

    answer.resize( this->giveNumberOfDomainEquations( di, EModelDefaultPrescribedEquationNumbering() ) );
    answer.zero();

    // Add internal forces
    this->assembleVector( answer, tStep, LastEquilibratedInternalForcesVector, VM_Total,
                         EModelDefaultPrescribedEquationNumbering(), this->giveDomain(di) );
    // Subtract external loading
    ///@todo All engineering models should be using this (for consistency)
    //this->assembleVector( answer, tStep, ExternalForcesVector, VM_Total,
    //                    EModelDefaultPrescribedEquationNumbering(), this->giveDomain(di) );
    ///@todo This method is overloaded in some functions, it needs to be generalized.
    this->computeExternalLoadReactionContribution(contribution, tStep, di);
    answer.subtract(contribution);
    this->updateSharedDofManagers(answer, EModelDefaultPrescribedEquationNumbering(), ReactionExchangeTag);
}
예제 #5
0
void
StructuralEngngModel :: buildReactionTable(IntArray &restrDofMans, IntArray &restrDofs,
                                           IntArray &eqn, TimeStep *tStep, int di)
{
    // determine number of restrained dofs
    Domain *domain = this->giveDomain(di);
    int numRestrDofs = this->giveNumberOfDomainEquations( di, EModelDefaultPrescribedEquationNumbering() );
    int ndofMan = domain->giveNumberOfDofManagers();
    int rindex, count = 0;

    // initialize corresponding dofManagers and dofs for each restrained dof
    restrDofMans.resize(numRestrDofs);
    restrDofs.resize(numRestrDofs);
    eqn.resize(numRestrDofs);

    for ( int i = 1; i <= ndofMan; i++ ) {
        DofManager *inode = domain->giveDofManager(i);
        for ( Dof *jdof: *inode ) {
            if ( jdof->isPrimaryDof() && ( jdof->hasBc(tStep) ) ) { // skip slave dofs
                rindex = jdof->__givePrescribedEquationNumber();
                if ( rindex ) {
                    count++;
                    restrDofMans.at(count) = i;
                    restrDofs.at(count) = jdof->giveDofID();
                    eqn.at(count) = rindex;
                } else {
                    // NullDof has no equation number and no prescribed equation number
                    //_error("No prescribed equation number assigned to supported DOF");
                }
            }
        }
    }
    // Trim to size.
    restrDofMans.resizeWithValues(count);
    restrDofs.resizeWithValues(count);
    eqn.resizeWithValues(count);
}
예제 #6
0
void
MatlabExportModule :: doOutputReactionForces(TimeStep *tStep,    FILE *FID)
{

    int domainIndex = 1;
    Domain *domain  = emodel->giveDomain( domainIndex );

    FloatArray reactions;
    IntArray dofManMap, dofidMap, eqnMap;
#ifdef __SM_MODULE
    StructuralEngngModel *strEngMod = dynamic_cast< StructuralEngngModel * >(emodel);
    if ( strEngMod ) {
        strEngMod->buildReactionTable(dofManMap, dofidMap, eqnMap, tStep, domainIndex);
        strEngMod->computeReaction(reactions, tStep, 1);
    } else
#endif
    {
        OOFEM_ERROR("Cannot export reaction forces - only implemented for structural problems.");
    }

    // Set the nodes and elements to export based on sets
    if ( this->reactionForcesNodeSet > 0 ) {
        Set *set = domain->giveSet( this->reactionForcesNodeSet );
        reactionForcesDofManList = set->giveNodeList();
    }


    int numDofManToExport = this->reactionForcesDofManList.giveSize();
    if ( numDofManToExport == 0 ) { // No dofMan's given - export every dMan with reaction forces

        for (int i = 1; i <= domain->giveNumberOfDofManagers(); i++) {
            if ( dofManMap.contains(i) ) {
                this->reactionForcesDofManList.followedBy(i);
            }
        }
        numDofManToExport = this->reactionForcesDofManList.giveSize();
    }


    // Output header
    fprintf( FID, "\n %%%% Export of reaction forces \n\n" );

    // Output the dofMan numbers that are exported
    fprintf( FID, "\tReactionForces.DofManNumbers = [" );
    for ( int i = 1; i <= numDofManToExport; i++ ) {
        fprintf( FID, "%i ", this->reactionForcesDofManList.at(i) );
    }
    fprintf( FID, "];\n" );


    // Define the reaction forces as a cell object
    fprintf( FID, "\tReactionForces.ReactionForces = cell(%i,1); \n", numDofManToExport );
    fprintf( FID, "\tReactionForces.DofIDs = cell(%i,1); \n", numDofManToExport );


    // Output the reaction forces for each dofMan. If a certain dof is not prescribed zero is exported.
    IntArray dofIDs;
    for ( int i = 1; i <= numDofManToExport; i++ ) {
        int dManNum = this->reactionForcesDofManList.at(i);

        fprintf(FID, "\tReactionForces.ReactionForces{%i} = [", i);
        if ( dofManMap.contains( dManNum ) ) {

            DofManager *dofMan = domain->giveDofManager( dManNum );
            dofIDs.clear();

            for ( Dof *dof: *dofMan ) {
                int num = dof->giveEquationNumber( EModelDefaultPrescribedEquationNumbering() );
                int pos = eqnMap.findFirstIndexOf( num );
                dofIDs.followedBy(dof->giveDofID());
                if ( pos > 0 ) {
                    fprintf(FID, "%e ", reactions.at(pos));
                } else {
                    fprintf( FID, "%e ", 0.0 ); // if not prescibed output zero
                }
            }
        }
        fprintf(FID, "];\n");

        // Output dof ID's

        fprintf( FID, "\tReactionForces.DofIDs{%i} = [", i);
        if ( dofManMap.contains( dManNum ) ) {
            for ( int id: dofIDs ) {
                fprintf( FID, "%i ", id );
            }
        }
        fprintf(FID, "];\n");
    }
}
예제 #7
0
void
AdaptiveNonLinearStatic :: assembleInitialLoadVector(FloatArray &loadVector, FloatArray &loadVectorOfPrescribed,
                                                     AdaptiveNonLinearStatic *sourceProblem, int domainIndx,
                                                     TimeStep *tStep)
{
    IRResultType result;                           // Required by IR_GIVE_FIELD macro

    int mStepNum = tStep->giveMetaStepNumber();
    int hasfixed, mode;
    InputRecord *ir;
    MetaStep *iMStep;
    FloatArray _incrementalLoadVector, _incrementalLoadVectorOfPrescribed;
    SparseNonLinearSystemNM :: referenceLoadInputModeType rlm;
    //Domain* sourceDomain = sourceProblem->giveDomain(domainIndx);

    loadVector.resize( this->giveNumberOfDomainEquations( domainIndx, EModelDefaultEquationNumbering() ) );
    loadVectorOfPrescribed.resize( this->giveNumberOfDomainEquations( domainIndx, EModelDefaultPrescribedEquationNumbering() ) );
    loadVector.zero();
    loadVectorOfPrescribed.zero();
    _incrementalLoadVector.resize( this->giveNumberOfDomainEquations( domainIndx, EModelDefaultEquationNumbering() ) );
    _incrementalLoadVectorOfPrescribed.resize( this->giveNumberOfDomainEquations( domainIndx, EModelDefaultPrescribedEquationNumbering() ) );
    _incrementalLoadVector.zero();
    _incrementalLoadVectorOfPrescribed.zero();

    for ( int imstep = 1; imstep < mStepNum; imstep++ ) {
        iMStep = this->giveMetaStep(imstep);
        ir = iMStep->giveAttributesRecord();
        //hasfixed = ir->hasField("fixload");
        hasfixed = 1;
        if ( hasfixed ) {
            // test for control mode
            // here the algorithm works only for direct load control.
            // Direct displacement control requires to know the quasi-rections, and the controlled nodes
            // should have corresponding node on new mesh -> not supported
            // Indirect control -> the load level from prevous steps is required, currently nt supported.

            // additional problem: direct load control supports the reduction of step legth if convergence fails
            // if this happens, this implementation does not work correctly.
            // But there is NO WAY HOW TO TEST IF THIS HAPPEN

            mode = 0;
            IR_GIVE_OPTIONAL_FIELD(ir, mode, _IFT_AdaptiveNonLinearStatic_controlmode);

            // check if displacement control takes place
            if ( ir->hasField(_IFT_AdaptiveNonLinearStatic_ddm) ) {
                OOFEM_ERROR("fixload recovery not supported for direct displacement control");
            }

            int firststep = iMStep->giveFirstStepNumber();
            int laststep  = iMStep->giveLastStepNumber();

            int _val = 0;
            IR_GIVE_OPTIONAL_FIELD(ir, _val, _IFT_AdaptiveNonLinearStatic_refloadmode);
            rlm = ( SparseNonLinearSystemNM :: referenceLoadInputModeType ) _val;

            if ( mode == ( int ) nls_directControl ) { // and only load control
                for ( int istep = firststep; istep <= laststep; istep++ ) {
                    // bad practise here
                    ///@todo Likely memory leak here with new TimeStep; Check.
                    TimeStep *old = new TimeStep(istep, this, imstep, istep - 1.0, deltaT, 0);
                    this->assembleIncrementalReferenceLoadVectors(_incrementalLoadVector, _incrementalLoadVectorOfPrescribed,
                                                                  rlm, this->giveDomain(domainIndx), EID_MomentumBalance, old);

                    _incrementalLoadVector.times( sourceProblem->giveTimeStepLoadLevel(istep) );
                    loadVector.add(_incrementalLoadVector);
                    loadVectorOfPrescribed.add(_incrementalLoadVectorOfPrescribed);
                }
            } else if ( mode == ( int ) nls_indirectControl ) {
                // bad practise here
                if ( !ir->hasField(_IFT_NonLinearStatic_donotfixload) ) {
                    TimeStep *old = new TimeStep(firststep, this, imstep, firststep - 1.0, deltaT, 0);
                    this->assembleIncrementalReferenceLoadVectors(_incrementalLoadVector, _incrementalLoadVectorOfPrescribed,
                                                                  rlm, this->giveDomain(domainIndx), EID_MomentumBalance, old);

                    _incrementalLoadVector.times( sourceProblem->giveTimeStepLoadLevel(laststep) );
                    loadVector.add(_incrementalLoadVector);
                    loadVectorOfPrescribed.add(_incrementalLoadVectorOfPrescribed);
                }
            } else {
                OOFEM_ERROR("fixload recovery not supported");
            }
        }
    } // end loop over meta-steps

    /* if direct control; add to initial load also previous steps in same metestep */
    iMStep = this->giveMetaStep(mStepNum);
    ir = iMStep->giveAttributesRecord();
    mode = 0;
    IR_GIVE_OPTIONAL_FIELD(ir, mode, _IFT_AdaptiveNonLinearStatic_controlmode);
    int firststep = iMStep->giveFirstStepNumber();
    int laststep  = tStep->giveNumber();
    int _val = 0;
    IR_GIVE_OPTIONAL_FIELD(ir, _val, _IFT_AdaptiveNonLinearStatic_refloadmode);
    rlm = ( SparseNonLinearSystemNM :: referenceLoadInputModeType ) _val;

    if ( mode == ( int ) nls_directControl ) { // and only load control
        for ( int istep = firststep; istep <= laststep; istep++ ) {
            // bad practise here
            TimeStep *old = new TimeStep(istep, this, mStepNum, istep - 1.0, deltaT, 0);
            this->assembleIncrementalReferenceLoadVectors(_incrementalLoadVector, _incrementalLoadVectorOfPrescribed,
                                                          rlm, this->giveDomain(domainIndx), EID_MomentumBalance, old);

            _incrementalLoadVector.times( sourceProblem->giveTimeStepLoadLevel(istep) );
            loadVector.add(_incrementalLoadVector);
            loadVectorOfPrescribed.add(_incrementalLoadVectorOfPrescribed);
        }
    }
}