void IncrementalLinearStatic :: updateDofUnknownsDictionary(DofManager *inode, TimeStep *tStep) { // update DOF unknowns dictionary, where // unknowns are hold instead of keeping them in global unknowns // vectors in engng instances // this is necessary, because during solution equation numbers for // particular DOFs may changed, and it is necessary to keep them // in DOF level. int ndofs = inode->giveNumberOfDofs(); Dof *iDof; double val; for ( int i = 1; i <= ndofs; i++ ) { iDof = inode->giveDof(i); // skip slave DOFs (only master (primary) DOFs have to be updated). if (!iDof->isPrimaryDof()) continue; val = iDof->giveUnknown(VM_Total, tStep); if ( !iDof->hasBc(tStep) ) { val += this->incrementOfDisplacementVector.at( iDof->__giveEquationNumber() ); } iDof->updateUnknownsDictionary(tStep, VM_Total_Old, val); iDof->updateUnknownsDictionary(tStep, VM_Total, val); } }
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 IncrementalLinearStatic :: solveYourselfAt(TimeStep *tStep) { // Creates system of governing eq's and solves them at given time step // Initiates the total displacement to zero. if ( tStep->isTheFirstStep() ) { Domain *d = this->giveDomain(1); for ( int i = 1; i <= d->giveNumberOfDofManagers(); i++ ) { DofManager *dofman = d->giveDofManager(i); for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) { dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total_Old, 0.); dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total, 0.); // This is actually redundant now; //dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Incremental, 0.); } } int nbc = d->giveNumberOfBoundaryConditions(); for ( int ibc = 1; ibc <= nbc; ++ibc ) { GeneralBoundaryCondition *bc = d->giveBc(ibc); ActiveBoundaryCondition *abc; if ( ( abc = dynamic_cast< ActiveBoundaryCondition * >( bc ) ) ) { int ndman = abc->giveNumberOfInternalDofManagers(); for ( int i = 1; i <= ndman; i++ ) { DofManager *dofman = abc->giveInternalDofManager(i); for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) { dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total_Old, 0.); dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Total, 0.); // This is actually redundant now; //dofman->giveDof(j)->updateUnknownsDictionary(tStep, VM_Incremental, 0.); } } } } } // Apply dirichlet b.c's on total values Domain *d = this->giveDomain(1); for ( int i = 1; i <= d->giveNumberOfDofManagers(); i++ ) { DofManager *dofman = d->giveDofManager(i); for ( int j = 1; j <= dofman->giveNumberOfDofs(); j++ ) { Dof *d = dofman->giveDof(j); double tot = d->giveUnknown(VM_Total_Old, tStep); if ( d->hasBc(tStep) ) { tot += d->giveBcValue(VM_Incremental, tStep); } d->updateUnknownsDictionary(tStep, VM_Total, tot); } } #ifdef VERBOSE OOFEM_LOG_RELEVANT( "Solving [step number %8d, time %15e]\n", tStep->giveNumber(), tStep->giveTargetTime() ); #endif int neq = this->giveNumberOfDomainEquations(1, EModelDefaultEquationNumbering()); if (neq == 0) { // Allows for fully prescribed/empty problems. return; } incrementOfDisplacementVector.resize(neq); incrementOfDisplacementVector.zero(); #ifdef VERBOSE OOFEM_LOG_INFO("Assembling load\n"); #endif // Assembling the element part of load vector internalLoadVector.resize(neq); internalLoadVector.zero(); this->assembleVector( internalLoadVector, tStep, EID_MomentumBalance, InternalForcesVector, VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); loadVector.resize(neq); loadVector.zero(); this->assembleVector( loadVector, tStep, EID_MomentumBalance, ExternalForcesVector, VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); loadVector.subtract(internalLoadVector); #ifdef VERBOSE OOFEM_LOG_INFO("Assembling stiffness matrix\n"); #endif if ( stiffnessMatrix ) { delete stiffnessMatrix; } stiffnessMatrix = classFactory.createSparseMtrx(sparseMtrxType); if ( stiffnessMatrix == NULL ) { _error("solveYourselfAt: sparse matrix creation failed"); } stiffnessMatrix->buildInternalStructure( this, 1, EID_MomentumBalance, EModelDefaultEquationNumbering() ); stiffnessMatrix->zero(); this->assemble( stiffnessMatrix, tStep, EID_MomentumBalance, StiffnessMatrix, EModelDefaultEquationNumbering(), this->giveDomain(1) ); #ifdef VERBOSE OOFEM_LOG_INFO("Solving ...\n"); #endif this->giveNumericalMethod( this->giveCurrentMetaStep() ); NM_Status s = nMethod->solve(stiffnessMatrix, & loadVector, & incrementOfDisplacementVector); if ( !(s & NM_Success) ) { OOFEM_ERROR("IncrementalLinearStatic :: solverYourselfAt - No success in solving system."); } }