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