// Runge-Kutta 4 algorithm void System::RK4(){ vec2dN K1(nObj), K2(nObj), K3(nObj), K4(nObj); vec2dN L1(nObj), L2(nObj), L3(nObj), L4(nObj); vec2dN NewR(nObj), NewV(nObj); if (nObj == 1){ // If only ONE object K1 = h*derX(vec2dN(nObj)); L1 = h*(SunInf(vec2dN(nObj))); K2 = h*derX(L1*0.5); L2 = h*(SunInf(K1*0.5)); K3 = h*derX(L2*0.5); L3 = h*(SunInf(K2*0.5)); K4 = h*derX(L3); L4 = h*(SunInf(K3)); } else { // If more than one object if (!statSun){ // Sun mobile or not pressent K1 = h*derX(vec2dN(nObj)); L1 = h*derV(vec2dN(nObj)); K2 = h*derX(L1*0.5); L2 = h*derV(K1*0.5); K3 = h*derX(L2*0.5); L3 = h*derV(L2*0.5); K4 = h*derX(L3); L4 = h*derV(K4); } else { // If the sun is stationary K1 = h*derX(vec2dN(nObj)); L1 = h*(derV(vec2dN(nObj)) + SunInf(vec2dN(nObj))); K2 = h*derX(L1*0.5); L2 = h*(derV(K1*0.5) + SunInf(K1*0.5)); K3 = h*derX(L2*0.5); L3 = h*(derV(K2*0.5) + SunInf(K2*0.5)); K4 = h*derX(L3); L4 = h*(derV(K3) + SunInf(K3)); } } for (int i = 0 ; i < nObj ; i++){ NewR[i] = sys[i].relR + (K1[i] + 2*K2[i] + 2*K3[i] + K4[i])/(double)6; NewV[i] = sys[i].relV + (L1[i] + 2*L2[i] + 2*L3[i] + L4[i])/(double)6; } calc_potential(); for (int i = 0 ; i < nObj ; i++){ sys[i].update(NewR[i], NewV[i], sys[i].relT+h); } }
void visitFieldRef(FieldRef *Ref) { // The real magic happens here Field *F = Ref->getField(); if (F != TheField) { // This is a reference to a field we are not processing. return; } // Only adjust if this is not the first update (in time order) if (LastTS) { // We're in the last time-step, check if there is a write to // this field before us. std::list<Field*>::const_iterator Curr = std::find(UpdateOrder.begin(), UpdateOrder.end(), Func->getOutput()); assert(Curr != UpdateOrder.end() && "Field not in update list"); bool Found = false; for (std::list<Field*>::const_iterator I = UpdateOrder.begin(); I != Curr; ++I) { const Field *O = *I; if (O == TheField) { Found = true; break; } } if (!Found) { // We are in the last time-step and there is no previous update, // so do not count this field. return; } } unsigned NumDims = InRegion.getNumDimensions(); Region NewR(NumDims); const std::vector<IntConstant*> &Offsets = Ref->getOffsets(); #if 0 llvm::errs() << "Visiting " << Ref->getField()->getName() << "["; for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { if (i != 0) llvm::errs() << "]["; llvm::errs() << Offsets[i]->getValue(); } llvm::errs() << "]\n"; llvm::errs() << "FRegion In: "; FRegion.dump(llvm::errs()); llvm::errs() << "\n"; llvm::errs() << "InRegion In: "; InRegion.dump(llvm::errs()); llvm::errs() << "\n"; #endif for (unsigned i = 0; i < NumDims; ++i) { std::pair<int, unsigned> InBound = InRegion.getBound(i); std::pair<int, unsigned> FBound = FRegion.getBound(i); int Off = Offsets[i]->getValue(); if (InBound.first + Off < FBound.first) { // We need more elements on the lower bound int Diff = FBound.first - (InBound.first + Off); FBound.first -= Diff; FBound.second += Diff; } if (InBound.first + InBound.second + Off > FBound.first + FBound.second) { // We need more elements on the upper bound int Diff = InBound.first + InBound.second + Off - (FBound.first + FBound.second); FBound.second += Diff; } #if 0 llvm::errs() << "FRegion Out: "; FRegion.dump(llvm::errs()); llvm::errs() << "\n"; #endif FRegion.reset(i, FBound); } }