void EigenValueDynamic :: solveYourselfAt(TimeStep *tStep)
{
    //
    // creates system of governing eq's and solves them at given time step
    //
    // first assemble problem at current time step

#ifdef VERBOSE
    OOFEM_LOG_INFO("Assembling stiffness and mass matrices\n");
#endif

    if ( tStep->giveNumber() == 1 ) {
        //
        // first step  assemble stiffness Matrix
        //

        stiffnessMatrix = CreateUsrDefSparseMtrx(sparseMtrxType);
        stiffnessMatrix->buildInternalStructure( this, 1, EID_MomentumBalance, EModelDefaultEquationNumbering() );

        massMatrix = CreateUsrDefSparseMtrx(sparseMtrxType);
        massMatrix->buildInternalStructure( this, 1, EID_MomentumBalance, EModelDefaultEquationNumbering() );

        this->assemble( stiffnessMatrix, tStep, EID_MomentumBalance, StiffnessMatrix,
                       EModelDefaultEquationNumbering(), this->giveDomain(1) );
        this->assemble( massMatrix, tStep, EID_MomentumBalance, MassMatrix,
                       EModelDefaultEquationNumbering(), this->giveDomain(1) );
        //
        // create resulting objects eigVec and eigVal
        //
        eigVec.resize(this->giveNumberOfEquations(EID_MomentumBalance), numberOfRequiredEigenValues);
        eigVec.zero();
        eigVal.resize(numberOfRequiredEigenValues);
        eigVal.zero();
    }

    //
    // set-up numerical model
    //
    this->giveNumericalMethod(  this->giveMetaStep( tStep->giveMetaStepNumber() ) );

    //
    // call numerical model to solve arised problem
    //
#ifdef VERBOSE
    OOFEM_LOG_INFO("Solving ...\n");
#endif

    nMethod->solve(stiffnessMatrix, massMatrix, & eigVal, & eigVec, rtolv, numberOfRequiredEigenValues);

    delete stiffnessMatrix;
    delete massMatrix;
    stiffnessMatrix = massMatrix = NULL;
}
void NonStationaryTransportProblem :: solveYourselfAt(TimeStep *tStep)
{
    // Creates system of governing eq's and solves them at given tStep
    // The solution is stored in UnknownsField. If the problem is growing/decreasing, the UnknownsField is projected on DoFs when needed.
    // If equations are not renumbered, the algorithm is efficient without projecting unknowns to DoFs (nodes).

    //Right hand side
    FloatArray rhs;

    int neq = this->giveNumberOfEquations(EID_ConservationEquation);
#ifdef VERBOSE
    OOFEM_LOG_RELEVANT( "Solving [step number %8d, time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() );
#endif

    //Solution at the first time step needs history. Therefore, return back one time increment and create it.
    if ( tStep->isTheFirstStep() ) {
        this->giveSolutionStepWhenIcApply();

        bcRhs.resize(neq); //rhs vector from solution step i-1
        bcRhs.zero();

        this->applyIC(stepWhenIcApply);

        //project initial conditions to have temorary temperature in integration points
        
        //edge or surface load on elements
        this->assembleVectorFromElements( bcRhs, stepWhenIcApply, EID_ConservationEquation, ElementBCTransportVector,
                                         VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
        //add prescribed value, such as temperature, on nodes
        this->assembleDirichletBcRhsVector( bcRhs, stepWhenIcApply, EID_ConservationEquation, VM_Total,
                                           NSTP_MidpointLhs, EModelDefaultEquationNumbering(), this->giveDomain(1) );
        //add internal source vector on elements
        this->assembleVectorFromElements( bcRhs, stepWhenIcApply, EID_ConservationEquation, ElementInternalSourceVector,
                                         VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
        //add nodal load
        this->assembleVectorFromDofManagers( bcRhs, stepWhenIcApply, EID_ConservationEquation, ExternalForcesVector,
                                            VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
    }

    //Create a new lhs matrix if necessary
    if ( tStep->isTheFirstStep() || this->changingProblemSize ) {
        if ( conductivityMatrix ) {
            delete conductivityMatrix;
        }

        conductivityMatrix = CreateUsrDefSparseMtrx(sparseMtrxType);
        if ( conductivityMatrix == NULL ) {
            _error("solveYourselfAt: sparse matrix creation failed");
        }

        conductivityMatrix->buildInternalStructure( this, 1, EID_ConservationEquation, EModelDefaultEquationNumbering() );

#ifdef VERBOSE
        OOFEM_LOG_INFO("Assembling conductivity and capacity matrices\n");
#endif

        this->assemble( conductivityMatrix, stepWhenIcApply, EID_ConservationEquation, LHSBCMatrix,
                       EModelDefaultEquationNumbering(), this->giveDomain(1) );
        conductivityMatrix->times(alpha);
        this->assemble( conductivityMatrix, stepWhenIcApply, EID_ConservationEquation, NSTP_MidpointLhs,
                       EModelDefaultEquationNumbering(), this->giveDomain(1) );
    }

    //obtain the last Rhs vector from DoFs directly
    if ( !tStep->isTheFirstStep() && this->changingProblemSize ) {
        UnknownsField->initialize(VM_RhsTotal, tStep, bcRhs);
    }

    //prepare position in UnknownsField to store the results
    UnknownsField->advanceSolution(tStep);

    FloatArray *solutionVector = UnknownsField->giveSolutionVector(tStep);
    solutionVector->resize(neq);
    solutionVector->zero();
    
#ifdef VERBOSE
    OOFEM_LOG_INFO("Assembling rhs\n");
#endif
    // assembling load from elements
    rhs = bcRhs;
    rhs.times(1. - alpha);
    bcRhs.zero();
    this->assembleVectorFromElements( bcRhs, tStep, EID_ConservationEquation, ElementBCTransportVector,
                                     VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );
    this->assembleDirichletBcRhsVector( bcRhs, tStep, EID_ConservationEquation, VM_Total, NSTP_MidpointLhs,
                                       EModelDefaultEquationNumbering(), this->giveDomain(1) );
    this->assembleVectorFromElements( bcRhs, tStep, EID_ConservationEquation, ElementInternalSourceVector,
                                     VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) );

    // assembling load from nodes
    this->assembleVectorFromDofManagers( bcRhs, tStep, EID_ConservationEquation, InternalForcesVector, VM_Total,
                                        EModelDefaultEquationNumbering(), this->giveDomain(1) );
    for ( int i = 1; i <= neq; i++ ) {
        rhs.at(i) += bcRhs.at(i) * alpha;
    }

    // add the rhs part depending on previous solution
    assembleAlgorithmicPartOfRhs( rhs, EID_ConservationEquation,
                                 EModelDefaultEquationNumbering(), tStep->givePreviousStep() );
    // set-up numerical model
    this->giveNumericalMethod( this->giveCurrentMetaStep() );

    //
    // call numerical model to solve arised problem
    //
#ifdef VERBOSE
    OOFEM_LOG_INFO("Solving ...\n");
#endif
    UnknownsField->giveSolutionVector(tStep)->resize(neq);
    nMethod->solve( conductivityMatrix, & rhs, UnknownsField->giveSolutionVector(tStep) );
    // update solution state counter
    tStep->incrementStateCounter();
}
示例#3
0
void
NonLinearStatic :: proceedStep(int di, TimeStep *tStep)
{
    //
    // creates system of governing eq's and solves them at given time step
    //
    // first assemble problem at current time step
    //

    if ( initFlag ) {
        //
        // first step  create space for stiffness Matrix
        //
        int neq = this->giveNumberOfEquations(EID_MomentumBalance);
        internalForces.resize(neq);
        internalForces.zero();

        if ( !stiffnessMatrix ) {
            stiffnessMatrix = CreateUsrDefSparseMtrx(sparseMtrxType);
        }

        if ( stiffnessMatrix == NULL ) {
            _error("proceedStep: sparse matrix creation failed");
        }

        if ( nonlocalStiffnessFlag ) {
            if ( !stiffnessMatrix->isAsymmetric() ) {
                _error("proceedStep: stiffnessMatrix does not support asymmetric storage");
            }
        }

        stiffnessMatrix->buildInternalStructure( this, di, EID_MomentumBalance, EModelDefaultEquationNumbering() );
    }

#if 0
     if ((mstep->giveFirstStepNumber() == tStep->giveNumber())) {
#ifdef VERBOSE
        OOFEM_LOG_INFO("Resetting load level\n");
#endif
        if (mstepCumulateLoadLevelFlag) cumulatedLoadLevel += loadLevel;
        else cumulatedLoadLevel = 0.0;
        this->loadLevel = 0.0;
     }
#endif

    if ( loadInitFlag || ( controlMode == nls_directControl ) || ( controlMode == nls_directControl2 ) ) {
#ifdef VERBOSE
        OOFEM_LOG_DEBUG("Assembling reference load\n");
#endif
        //
        // assemble the incremental reference load vector
        //
        this->assembleIncrementalReferenceLoadVectors(incrementalLoadVector, incrementalLoadVectorOfPrescribed,
                                                      refLoadInputMode, this->giveDomain(di), EID_MomentumBalance, tStep);

        loadInitFlag = 0;
    }

    if ( tStep->giveNumber() == 1 ) {
        int neq = this->giveNumberOfEquations(EID_MomentumBalance);
        totalDisplacement.resize(neq);
        totalDisplacement.zero();
        incrementOfDisplacement.resize(neq);
        incrementOfDisplacement.zero();
    }

    //
    //    ->   BEGINNING OF LOAD (OR DISPLACEMENT) STEP  <-
    //

    //
    // set-up numerical model
    //
    this->giveNumericalMethod( this->giveMetaStep( tStep->giveMetaStepNumber() ) );
    //
    // call numerical model to solve arise problem
    //
#ifdef VERBOSE
    OOFEM_LOG_RELEVANT( "\n\nSolving       [step number %5d.%d]\n\n", tStep->giveNumber(), tStep->giveVersion() );
#endif

    if ( this->initialGuessType == IG_Tangent ) {
#ifdef VERBOSE
        OOFEM_LOG_RELEVANT( "Computing initial guess\n");
#endif
        FloatArray extrapolatedForces;
        this->assembleExtrapolatedForces(extrapolatedForces, tStep, EID_MomentumBalance, TangentStiffnessMatrix, this->giveDomain(di));
        extrapolatedForces.negated();

        this->updateComponent(tStep, NonLinearLhs, this->giveDomain(di));
        SparseLinearSystemNM *linSolver = nMethod->giveLinearSolver();
        OOFEM_LOG_RELEVANT( "solving for increment\n");
        linSolver->solve(stiffnessMatrix, &extrapolatedForces, &incrementOfDisplacement);
        OOFEM_LOG_RELEVANT( "initial guess found\n");
        totalDisplacement.add(incrementOfDisplacement);
    } else if ( this->initialGuessType != IG_None ) {
        OOFEM_ERROR2("Initial guess type: %d not supported", initialGuessType);
    } else {
        incrementOfDisplacement.zero();
    }

    if ( initialLoadVector.isNotEmpty() ) {
        numMetStatus = nMethod->solve(stiffnessMatrix, & incrementalLoadVector, & initialLoadVector,
                                      & totalDisplacement, & incrementOfDisplacement, & internalForces,
                                      internalForcesEBENorm, loadLevel, refLoadInputMode, currentIterations, tStep);
    } else {
        numMetStatus = nMethod->solve(stiffnessMatrix, & incrementalLoadVector, NULL,
                                      & totalDisplacement, & incrementOfDisplacement, & internalForces,
                                      internalForcesEBENorm, loadLevel, refLoadInputMode, currentIterations, tStep);
    }

    ///@todo Use temporary variables. updateYourself() should set the final values, while proceedStep should be callable multiple times for each step (if necessary). / Mikael
    OOFEM_LOG_RELEVANT("Equilibrium reached at load level = %f in %d iterations\n", cumulatedLoadLevel + loadLevel, currentIterations);
    prevStepLength =  currentStepLength;
}