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(); }
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; }