Ejemplo n.º 1
0
// 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);
    }
}
Ejemplo n.º 2
0
  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);
    }
  }