void LayeredHairMesh::internalUpdate(vector<QVector3D> &state) { //K1 auto K1 = internalForces(state) * timestep; auto K2 = internalForces(state + K1 * (timestep * 0.5)) * timestep; auto K3 = internalForces(state + K2 * (timestep * 0.5)) * timestep; auto K4 = internalForces(state + K3 * timestep) * timestep; double dem = 1.0 / 6.0; state = state + K1 * dem + K2 * (dem * 2) + K3 * (dem * 2) + K4 * dem; int compSize = state.size() / 2; for (int i = 4; i < compSize; i++) { simPts[i] = state[i]; simVel[i] = state[i + compSize]; } }
void LinearStatic :: solveYourselfAt(TimeStep *tStep) { // // creates system of governing eq's and solves them at given time step // // first assemble problem at current time step if ( initFlag ) { #ifdef VERBOSE OOFEM_LOG_DEBUG("Assembling stiffness matrix\n"); #endif // // first step assemble stiffness Matrix // stiffnessMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); if ( !stiffnessMatrix ) { OOFEM_ERROR("sparse matrix creation failed"); } stiffnessMatrix->buildInternalStructure( this, 1, *this->giveEquationNumbering() ); this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness), *this->giveEquationNumbering(), this->giveDomain(1) ); initFlag = 0; } #ifdef VERBOSE OOFEM_LOG_DEBUG("Assembling load\n"); #endif // // allocate space for displacementVector // displacementVector.resize( this->giveNumberOfDomainEquations( 1, *this->giveEquationNumbering() ) ); // km?? replace EModelDefaultEquationNumbering() with this->giveEquationNumbering(). Use pointer? displacementVector.zero(); // // assembling the load vector // loadVector.resize( this->giveNumberOfDomainEquations( 1, *this->giveEquationNumbering() ) ); loadVector.zero(); this->assembleVector( loadVector, tStep, ExternalForceAssembler(), VM_Total, *this->giveEquationNumbering(), this->giveDomain(1) ); // // internal forces (from Dirichlet b.c's, or thermal expansion, etc.) // FloatArray internalForces( this->giveNumberOfDomainEquations( 1, *this->giveEquationNumbering() ) ); internalForces.zero(); this->assembleVector( internalForces, tStep, InternalForceAssembler(), VM_Total, *this->giveEquationNumbering(), this->giveDomain(1) ); loadVector.subtract(internalForces); this->updateSharedDofManagers(loadVector, *this->giveEquationNumbering(), ReactionExchangeTag); // // set-up numerical model // this->giveNumericalMethod( this->giveMetaStep( tStep->giveMetaStepNumber() ) ); // // call numerical model to solve arose problem // #ifdef VERBOSE OOFEM_LOG_INFO("\n\nSolving ...\n\n"); #endif NM_Status s = nMethod->solve(*stiffnessMatrix, loadVector, displacementVector); if ( !( s & NM_Success ) ) { OOFEM_ERROR("No success in solving system."); } tStep->incrementStateCounter(); // update solution state counter }
void DDLinearStatic :: solveYourselfAt(TimeStep *tStep) { /** * Perform DD * Currently this is completely specific, but needs to be generalized * by perhaps creating an DD_interface class to do set of functions */ /**************************************************************************/ int NumberOfDomains = this->giveNumberOfDomains(); // Loop through all the giveNumberOfDomains for (int i = 1; i<= NumberOfDomains; i++) { //Domain *domain = this->giveDomain(i); /// Create a spatial localizer which in effect has services for locating points in element etc. //SpatialLocalizer *sl = domain->giveSpatialLocalizer(); // Perform DD solution at this time step, solution will depend on quantities in the input file /// @todo these have to be defined and initialized earlier /// Each domain for the DD case can have only one material... throw error otherwise //// Also the DD_domains should be intialized with these materials properties during input //// Here i am just using values from input file for algorithmic convenience /* dd::OofemInterface * interface = new dd::OofemInterface(this); */ dd::Domain dd_domain(70e-3, 0.3, NULL); dd::SlipSystem ss0 = dd::SlipSystem(0.0, 0.25e-3); dd_domain.addSlipSystem(&ss0); dd::SlipPlane sp0 = dd::SlipPlane(&dd_domain, &ss0, 0.0); dd::ObstaclePoint o0 = dd::ObstaclePoint(&dd_domain, &sp0, -0.25, 20.0e3); dd::ObstaclePoint o1 = dd::ObstaclePoint(&dd_domain, &sp0, 0.25, 20.0e3); double e = dd_domain.getModulus(); double nu = dd_domain.getPassionsRatio(); double mu = e / (2. * ( 1. + nu)); double fact = mu * ss0.getBurgersMagnitude() / ( 2 * M_PI * (1. - nu)); dd::SourcePoint s1 = dd::SourcePoint(&dd_domain, &sp0, 0, 25e-6, fact / 25e-6); for( dd_domain.dtNo = 1; dd_domain.dtNo < dd_domain.dtNomax; dd_domain.dtNo++) { std::cerr << "Total dislocs in domain: " << sp0.getContainer<dd::DislocationPoint>().size() << "\n"; std::cerr << "Dislocs: " << sp0.dumpToString<dd::DislocationPoint>() << "\n"; std::cerr.flush(); dd_domain.updateForceCaches(); for(auto point : dd_domain.getContainer<dd::DislocationPoint>()) { dd::Vector<2> force, forceGradient; dd::Vector<3> stress; force = dd::Vector<2>({0.0,0.0}); //point->sumCaches(force, forceGradient, stress); force = point->cachedForce(); stress = point->cachedStress(); std::cout << "Cached Force at " << point->slipPlanePosition() << ": " << point->getBurgersSign() << " " << force[0] << " " << stress[2] << " " << point->slipPlanePosition() << "\n"; } dd_domain.updateForceCaches(); dd_domain.moveDislocations(1.0e-11, 1.0e-18); s1.spawn(1, 5); /* for(int bcNo = 1; bcNo <= giveDomain(i)->giveNumberOfBoundaryConditions(); bcNo++) { ManualBoundaryCondition * bc = dynamic_cast<ManualBoundaryCondition *>(giveDomain(i)->giveBc(bcNo)); if(bc == nullptr || bc->giveType() != DirichletBT) { continue; } dd::Vector<2> bcContribution; Domain * d = bc->giveDomain(); Set * set = d->giveSet(bc->giveSetNumber()); for(int nodeNo : set->giveNodeList()) { Node * node = static_cast<Node *>(d->giveDofManager(nodeNo)); for (auto &dofid : bc->giveDofIDs()) { Dof * dof = node->giveDofWithID(dofid); interface->giveNodalBcContribution(node, bcContribution); // TODO: Determine the dimensions without pointer checking double toAdd; if(dof->giveDofID() == D_u) { toAdd = bcContribution[0]; } else if(dof->giveDofID() == D_v) { toAdd = bcContribution[1]; } else { OOFEM_ERROR("DOF must be x-disp or y-disp"); } bc->addManualValue(dof, toAdd); } } std::cout << "BC Contribution: " << bcContribution[0] << " " << bcContribution[1] << "\n"; } */ //delete interface; } // end dtNo loop } /**************************************************************************/ // // creates system of governing eq's and solves them at given time step // // first assemble problem at current time step if ( initFlag ) { #ifdef VERBOSE OOFEM_LOG_DEBUG("Assembling stiffness matrix\n"); #endif // // first step assemble stiffness Matrix // stiffnessMatrix.reset( classFactory.createSparseMtrx(sparseMtrxType) ); if ( !stiffnessMatrix ) { OOFEM_ERROR("sparse matrix creation failed"); } stiffnessMatrix->buildInternalStructure( this, 1, EModelDefaultEquationNumbering() ); this->assemble( *stiffnessMatrix, tStep, TangentAssembler(TangentStiffness), EModelDefaultEquationNumbering(), this->giveDomain(1) ); initFlag = 0; } #ifdef VERBOSE OOFEM_LOG_DEBUG("Assembling load\n"); #endif // // allocate space for displacementVector // displacementVector.resize( this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ) ); displacementVector.zero(); // // assembling the load vector // loadVector.resize( this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ) ); loadVector.zero(); this->assembleVector( loadVector, tStep, ExternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); // // internal forces (from Dirichlet b.c's, or thermal expansion, etc.) // FloatArray internalForces( this->giveNumberOfDomainEquations( 1, EModelDefaultEquationNumbering() ) ); internalForces.zero(); this->assembleVector( internalForces, tStep, InternalForceAssembler(), VM_Total, EModelDefaultEquationNumbering(), this->giveDomain(1) ); loadVector.subtract(internalForces); this->updateSharedDofManagers(loadVector, EModelDefaultEquationNumbering(), ReactionExchangeTag); // // set-up numerical model // this->giveNumericalMethod( this->giveMetaStep( tStep->giveMetaStepNumber() ) ); // // call numerical model to solve arose problem // #ifdef VERBOSE OOFEM_LOG_INFO("\n\nSolving ...\n\n"); #endif NM_Status s = nMethod->solve(*stiffnessMatrix, loadVector, displacementVector); if ( !( s & NM_Success ) ) { OOFEM_ERROR("No success in solving system."); } tStep->incrementStateCounter(); // update solution state counter }