void Deformable::timeStep() { externalForces(); //projectPositions(); if( params.isCluster) { for(int i=0; i<mNumClusters; i++) { std::vector<int> cluster= mClusters.at(i); projectPositionsCluster(cluster, i); } for (int i=0; i<mNumVertices; i++) { if (mFixed(i)) continue; //std::cout<<mGoalPos_sum.row(i)<<" "<<indxCount.at(i)<<std::endl; mNewPos.row(i) = mGoalPos_sum.row(i)/indxCount.at(i); //std::cout<<"after: "<<mNewPos.row(i)<<" "<<indxCount.at(i)<<std::endl; //std::cout<<mNewPos.row(i)<<std::endl; } mGoalPos_sum.setZero(); std::fill(indxCount.begin(), indxCount.end(), 0); } else { projectPositions(); } integrate(); }
void SUPG :: solveYourselfAt(TimeStep *tStep) { int neq = this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ); FloatArray *solutionVector = NULL, *prevSolutionVector = NULL; FloatArray externalForces(neq); this->internalForces.resize(neq); if ( tStep->isTheFirstStep() ) { TimeStep *stepWhenIcApply = tStep->givePreviousStep(); if ( materialInterface ) { materialInterface->initialize(); } this->applyIC(stepWhenIcApply); //if (this->fsflag) this->updateDofManActivityMap(tStep); } if ( !requiresUnknownsDictionaryUpdate() ) { VelocityPressureField->advanceSolution(tStep); solutionVector = VelocityPressureField->giveSolutionVector(tStep); prevSolutionVector = VelocityPressureField->giveSolutionVector( tStep->givePreviousStep() ); } if ( initFlag ) { if ( !requiresUnknownsDictionaryUpdate() ) { //previousAccelerationVector.resize(neq); accelerationVector.resize(neq); solutionVector->resize(neq); prevSolutionVector->resize(neq); } incrementalSolutionVector.resize(neq); lhs.reset( classFactory.createSparseMtrx(sparseMtrxType) ); if ( !lhs ) { OOFEM_ERROR("sparse matrix creation failed"); } lhs->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); if ( materialInterface ) { this->updateElementsForNewInterfacePosition(tStep); } initFlag = 0; } else if ( requiresUnknownsDictionaryUpdate() ) { // rebuild lhs structure and resize solution vector incrementalSolutionVector.resize(neq); lhs->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); } if ( !requiresUnknownsDictionaryUpdate() ) { *solutionVector = *prevSolutionVector; } //previousAccelerationVector=accelerationVector; // evaluate element supg and sppg stabilization coeffs this->evaluateElementStabilizationCoeffs(tStep); // // predictor // if ( requiresUnknownsDictionaryUpdate() ) { this->updateDofUnknownsDictionary_predictor(tStep); } else { this->updateSolutionVectors_predictor(* solutionVector, accelerationVector, tStep); } if ( tStep->giveNumber() != 1 ) { if ( materialInterface ) { //if (this->fsflag) updateDofManVals(tStep); #ifdef SUPG_IMPLICIT_INTERFACE #ifdef TIME_REPORT Timer timer; timer.startTimer(); #endif materialInterface->updatePosition( this->giveCurrentStep() ); updateElementsForNewInterfacePosition(tStep); #ifdef TIME_REPORT timer.stopTimer(); OOFEM_LOG_INFO("SUPG info: user time consumed by updating interfaces: %.2fs\n", timer.getUtime(); ); #endif #else //updateElementsForNewInterfacePosition (tStep); #endif //if (this->fsflag) this->updateDofManActivityMap(tStep); } }
void StationaryTransportProblem :: solveYourselfAt(TimeStep *tStep) { // // creates system of governing eq's and solves them at given time step // // first assemble problem at current time step UnknownsField->advanceSolution(tStep); int neq = this->giveNumberOfDomainEquations(1, EModelDefaultEquationNumbering()); if ( tStep->giveNumber() == 1 ) { // allocate space for solution vector FloatArray *solutionVector = UnknownsField->giveSolutionVector(tStep); solutionVector->resize( neq ); solutionVector->zero(); conductivityMatrix = classFactory.createSparseMtrx(sparseMtrxType); if ( conductivityMatrix == NULL ) { _error("solveYourselfAt: sparse matrix creation failed"); } conductivityMatrix->buildInternalStructure( this, 1, EID_ConservationEquation, EModelDefaultEquationNumbering() ); if ( this->keepTangent ) { this->conductivityMatrix->zero(); this->assemble( conductivityMatrix, tStep, EID_ConservationEquation, ConductivityMatrix, EModelDefaultEquationNumbering(), this->giveDomain(1) ); this->assemble( conductivityMatrix, tStep, EID_ConservationEquation, LHSBCMatrix, EModelDefaultEquationNumbering(), this->giveDomain(1) ); } } internalForces.resize(neq); #ifdef VERBOSE OOFEM_LOG_INFO("Assembling external forces\n"); #endif FloatArray externalForces(neq); externalForces.zero(); this->assembleVector( externalForces, tStep, EID_ConservationEquation, ExternalForcesVector, VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); // set-up numerical method this->giveNumericalMethod( this->giveCurrentMetaStep() ); #ifdef VERBOSE OOFEM_LOG_INFO("Solving ...\n"); #endif FloatArray incrementOfSolution; double loadLevel; int currentIterations; this->nMethod->solve(this->conductivityMatrix, & externalForces, NULL, UnknownsField->giveSolutionVector(tStep), & incrementOfSolution, & this->internalForces, this->eNorm, loadLevel, // Only relevant for incrementalBCLoadVector SparseNonLinearSystemNM :: rlm_total, currentIterations, tStep); //nMethod->solve( conductivityMatrix, & rhsVector, UnknownsField->giveSolutionVector(tStep) ); }
void TransientTransportProblem :: solveYourselfAt(TimeStep *tStep) { Domain *d = this->giveDomain(1); int neq = this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ); field->advanceSolution(tStep); field->applyBoundaryCondition(tStep); if ( tStep->isTheFirstStep() ) { this->applyIC(); } field->initialize(VM_Total, tStep, solution, EModelDefaultEquationNumbering()); if ( !effectiveMatrix ) { effectiveMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); effectiveMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); if ( lumped ) { capacityDiag.resize(neq); this->assembleVector( capacityDiag, tStep, LumpedMassVectorAssembler(), VM_Total, EModelDefaultEquationNumbering(), d ); } else { capacityMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); capacityMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); this->assemble( *capacityMatrix, tStep, MassMatrixAssembler(), EModelDefaultEquationNumbering(), d ); } if ( this->keepTangent ) { this->assemble( *effectiveMatrix, tStep, TangentAssembler(TangentStiffness), EModelDefaultEquationNumbering(), d ); effectiveMatrix->times(alpha); if ( lumped ) { effectiveMatrix->addDiagonal(1./tStep->giveTimeIncrement(), capacityDiag); } else { effectiveMatrix->add(1./tStep->giveTimeIncrement(), *capacityMatrix); } } } OOFEM_LOG_INFO("Assembling external forces\n"); FloatArray externalForces(neq); externalForces.zero(); this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), d ); this->updateSharedDofManagers(externalForces, EModelDefaultEquationNumbering(), LoadExchangeTag); // set-up numerical method this->giveNumericalMethod( this->giveCurrentMetaStep() ); OOFEM_LOG_INFO("Solving for %d unknowns...\n", neq); internalForces.resize(neq); FloatArray incrementOfSolution; double loadLevel; int currentIterations; this->nMethod->solve(*this->effectiveMatrix, externalForces, NULL, // ignore this->solution, incrementOfSolution, this->internalForces, this->eNorm, loadLevel, // ignore SparseNonLinearSystemNM :: rlm_total, // ignore currentIterations, // ignore tStep); }
void StaticStructural :: solveYourselfAt(TimeStep *tStep) { int neq; int di = 1; this->field->advanceSolution(tStep); this->field->applyBoundaryCondition(tStep); ///@todo Temporary hack, advanceSolution should apply the boundary conditions directly. neq = this->giveNumberOfDomainEquations( di, EModelDefaultEquationNumbering() ); if (tStep->giveNumber()==1) { this->field->initialize(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering() ); } else { this->field->initialize(VM_Total, tStep->givePreviousStep(), this->solution, EModelDefaultEquationNumbering() ); this->field->update(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering() ); } this->field->applyBoundaryCondition(tStep); ///@todo Temporary hack to override the incorrect values that is set by "update" above. Remove this when that is fixed. FloatArray incrementOfSolution(neq), externalForces(neq); // Create "stiffness matrix" if ( !this->stiffnessMatrix ) { this->stiffnessMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); if ( !this->stiffnessMatrix ) { OOFEM_ERROR("Couldn't create requested sparse matrix of type %d", sparseMtrxType); } this->stiffnessMatrix->buildInternalStructure( this, di, EModelDefaultEquationNumbering() ); } this->internalForces.resize(neq); this->giveNumericalMethod( this->giveCurrentMetaStep() ); this->initMetaStepAttributes( this->giveCurrentMetaStep() ); if ( this->initialGuessType == IG_Tangent ) { OOFEM_LOG_RELEVANT("Computing initial guess\n"); FloatArray extrapolatedForces(neq); this->assembleExtrapolatedForces( extrapolatedForces, tStep, TangentStiffnessMatrix, this->giveDomain(di) ); extrapolatedForces.negated(); ///@todo Need to find a general way to support this before enabling it by default. //this->assembleVector(extrapolatedForces, tStep, LinearizedDilationForceAssembler(), VM_Incremental, EModelDefaultEquationNumbering(), this->giveDomain(di) ); #if 0 // Some debug stuff: extrapolatedForces.printYourself("extrapolatedForces"); this->internalForces.zero(); this->assembleVectorFromElements(this->internalForces, tStep, InternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(di)); this->internalForces.printYourself("internal forces"); #endif OOFEM_LOG_RELEVANT("Computing old tangent\n"); this->updateComponent( tStep, NonLinearLhs, this->giveDomain(di) ); SparseLinearSystemNM *linSolver = nMethod->giveLinearSolver(); OOFEM_LOG_RELEVANT("Solving for increment\n"); linSolver->solve(*stiffnessMatrix, extrapolatedForces, incrementOfSolution); OOFEM_LOG_RELEVANT("Initial guess found\n"); this->solution.add(incrementOfSolution); this->field->update(VM_Total, tStep, this->solution, EModelDefaultEquationNumbering()); this->field->applyBoundaryCondition(tStep); ///@todo Temporary hack to override the incorrect values that is set by "update" above. Remove this when that is fixed. } else if ( this->initialGuessType != IG_None ) { OOFEM_ERROR("Initial guess type: %d not supported", initialGuessType); } else { incrementOfSolution.zero(); } // Build initial/external load externalForces.zero(); this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); this->updateSharedDofManagers(externalForces, EModelDefaultEquationNumbering(), LoadExchangeTag); if ( this->giveProblemScale() == macroScale ) { OOFEM_LOG_INFO("\nStaticStructural :: solveYourselfAt - Solving step %d, metastep %d, (neq = %d)\n", tStep->giveNumber(), tStep->giveMetaStepNumber(), neq); } double loadLevel; int currentIterations; NM_Status status = this->nMethod->solve(*this->stiffnessMatrix, externalForces, NULL, this->solution, incrementOfSolution, this->internalForces, this->eNorm, loadLevel, // Only relevant for incrementalBCLoadVector? SparseNonLinearSystemNM :: rlm_total, currentIterations, tStep); if ( !( status & NM_Success ) ) { OOFEM_ERROR("No success in solving problem"); } }
void TransientTransportProblem :: solveYourselfAt(TimeStep *tStep) { Domain *d = this->giveDomain(1); int neq = this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ); if ( tStep->isTheFirstStep() ) { this->applyIC(); } field->advanceSolution(tStep); #if 1 // This is what advanceSolution should be doing, but it can't be there yet // (backwards compatibility issues due to inconsistencies in other solvers). TimeStep *prev = tStep->givePreviousStep(); for ( auto &dman : d->giveDofManagers() ) { static_cast< DofDistributedPrimaryField* >(field.get())->setInitialGuess(*dman, tStep, prev); } for ( auto &elem : d->giveElements() ) { int ndman = elem->giveNumberOfInternalDofManagers(); for ( int i = 1; i <= ndman; i++ ) { static_cast< DofDistributedPrimaryField* >(field.get())->setInitialGuess(*elem->giveInternalDofManager(i), tStep, prev); } } for ( auto &bc : d->giveBcs() ) { int ndman = bc->giveNumberOfInternalDofManagers(); for ( int i = 1; i <= ndman; i++ ) { static_cast< DofDistributedPrimaryField* >(field.get())->setInitialGuess(*bc->giveInternalDofManager(i), tStep, prev); } } #endif field->applyBoundaryCondition(tStep); field->initialize(VM_Total, tStep, solution, EModelDefaultEquationNumbering()); if ( !effectiveMatrix ) { effectiveMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); effectiveMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); if ( lumped ) { capacityDiag.resize(neq); this->assembleVector( capacityDiag, tStep, LumpedMassVectorAssembler(), VM_Total, EModelDefaultEquationNumbering(), d ); } else { capacityMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); capacityMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); this->assemble( *capacityMatrix, tStep, MassMatrixAssembler(), EModelDefaultEquationNumbering(), d ); } if ( this->keepTangent ) { this->assemble( *effectiveMatrix, tStep, TangentAssembler(TangentStiffness), EModelDefaultEquationNumbering(), d ); effectiveMatrix->times(alpha); if ( lumped ) { effectiveMatrix->addDiagonal(1./tStep->giveTimeIncrement(), capacityDiag); } else { effectiveMatrix->add(1./tStep->giveTimeIncrement(), *capacityMatrix); } } } OOFEM_LOG_INFO("Assembling external forces\n"); FloatArray externalForces(neq); externalForces.zero(); this->assembleVector( externalForces, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), d ); this->updateSharedDofManagers(externalForces, EModelDefaultEquationNumbering(), LoadExchangeTag); // set-up numerical method this->giveNumericalMethod( this->giveCurrentMetaStep() ); OOFEM_LOG_INFO("Solving for %d unknowns...\n", neq); internalForces.resize(neq); FloatArray incrementOfSolution; double loadLevel; int currentIterations; this->nMethod->solve(*this->effectiveMatrix, externalForces, NULL, // ignore NULL, this->solution, incrementOfSolution, this->internalForces, this->eNorm, loadLevel, // ignore SparseNonLinearSystemNM :: rlm_total, // ignore currentIterations, // ignore tStep); }