int vtCStreamLine::AdvectOneStep(TIME_DIR time_dir, INTEG_ORD integ_ord, TIME_DEP time_dep, PointInfo& seedInfo, VECTOR3& finalP) { int istat; PointInfo thisParticle; VECTOR3 vel; float curTime = m_fCurrentTime; float dt = m_fInitialStepSize; finalP.Set(-1, -1, -1); thisParticle = seedInfo; // the first point istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, seedInfo, m_fCurrentTime, vel); if(istat == OUT_OF_BOUND) return OUT_OF_BOUND; if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; float error; if(integ_ord == SECOND) istat = runge_kutta2(time_dir, time_dep, thisParticle, &curTime, dt); else if(integ_ord == FOURTH) istat = runge_kutta4(time_dir, time_dep, thisParticle, &curTime, dt); else if(integ_ord == RK45) istat = runge_kutta45(time_dir, time_dep, thisParticle, &curTime, dt, &error); else return OUT_OF_BOUND; if(istat == OUT_OF_BOUND) // out of boundary return OUT_OF_BOUND; m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, thisParticle, m_fCurrentTime, vel); if((fabs(vel[0]) < m_fStationaryCutoff) && (fabs(vel[1]) < m_fStationaryCutoff) && (fabs(vel[2]) < m_fStationaryCutoff)) return CRITICAL_POINT; else finalP = thisParticle.phyCoord; return OKAY; }
////////////////////////////////////////////////////////////////////////// // Perform one proper integration step, taking into account error metrics. This // is used for integration methods that rely on a geometric error analysis // based on the angle greated by the new step. // // return FAIL or OKAY // ////////////////////////////////////////////////////////////////////////// int vtCFieldLine::oneStepGeometric(INTEG_ORD integ_ord, TIME_DIR time_dir, TIME_DEP time_dep, PointInfo& thisParticle, PointInfo prevParticle, PointInfo second_prevParticle, float* curTime, float* dt, int count) { int istat; PointInfo tempParticle = thisParticle; float prevTime = *curTime; int pass = 0; while(!pass) { // take a step if(integ_ord == SECOND) istat = runge_kutta2(time_dir, time_dep, thisParticle, curTime,*dt); else if(integ_ord == FOURTH) istat = runge_kutta4(time_dir, time_dep, thisParticle, curTime,*dt); else return OUT_OF_BOUND; if(istat == FAIL) return FAIL; if(count >= 2) { pass = adapt_step(second_prevParticle.phyCoord, prevParticle.phyCoord, thisParticle.phyCoord, dt); if(!pass) { // revert to before the step was taken *curTime = prevTime; thisParticle = tempParticle; } } else { pass = 1; } } return OKAY; }
////////////////////////////////////////////////////////////////////////// // advect the particle from initialTime to finalTime ////////////////////////////////////////////////////////////////////////// int vtCTimeVaryingFieldLine::advectParticle(INTEG_ORD int_order, vtParticleInfo& initialPoint, float initialTime, vtParticleInfo& finalPoint, float finalTime) { int istat; float curTime, dt; PointInfo pt; pt = initialPoint.m_pointInfo; if(m_itsTimeAdaptionFlag == 1) dt = (finalTime - initialTime) * 0.5; else dt = finalTime - initialTime; curTime = initialTime; while(curTime < finalTime) { float error; if(int_order == SECOND) istat = runge_kutta2(m_timeDir, UNSTEADY, pt, &curTime, dt); else if(int_order == FOURTH) istat = runge_kutta4(m_timeDir, UNSTEADY, pt, &curTime, dt); else if(int_order == RK45) istat = runge_kutta45(m_timeDir, UNSTEADY, pt, &curTime,dt,&error); else return OUT_OF_BOUND; if(istat != OKAY) return istat; } finalPoint.m_pointInfo = pt; return istat; }
std::vector<double> crk4(class Container1<functor_type>::iterator funct_iter1, class Container1<functor_type>::iterator funct_iter2, class Container2<coord_type>::iterator coord_iter1, class Container2<coord_type>::iterator coord_iter2, t_type t, double h) { auto k1 = init(funct_iter1, funct_iter2, coord_iter1, coord_iter2, t); auto m1 = midpt(k1, coord_iter1, h); t += 0.5*h; auto k2 = init(funct_iter1, funct_iter2, coord_iter1, coord_iter2, t); auto m2 = midpt(k1, coord_iter1, h); auto k3 = init(funct_iter1, funct_iter2, coord_iter1, coord_iter2, t); auto m3 = midpt(k1, coord_iter1, h); t += 0.5*h; auto k4 = init(funct_iter1, funct_iter2, coord_iter1, coord_iter2, t); auto coord_next = runge_kutta4(coord_iter1, coord_iter2, k1.begin(), k2.begin(), k3.begin(), k4.begin(), h); return coord_next; }