Beispiel #1
0
 double
 System::boundPotentialEnergy(double limit) const
 {
    Distance d;
    double energy = 0.0;
    arma::Col<double> position1, position2, center(3);
    for (int i = 0 ; i < numberOfObject ; ++i)
    {
       for (int j = 0 ; j < numberOfObject ; ++j)
       {
          if (i!=j)
          {
             Object movingObject = objectlist[i];
             Object otherObject = objectlist[j];
             position1 = movingObject.getPosition();
             position2 = otherObject.getPosition();
             if (d.twoObjects(center, position1)<limit)
             {
                double R = d.twoObjects(position1, position2);
                energy += -( 4 * PI * PI * otherObject.getMass() *
                      movingObject.getMass() /R);
             }
          }
       }
    }
    return energy;
 }
Beispiel #2
0
 void
 System::acceleration(Object &mainObject,
                      int i,
                      double time,
                      std::string dimension)
 {
    arma::Col<double> tempAcceleration(3);
    arma::Col<double> acceleration(3);
    acceleration.zeros();
    for (int j = 0; j < numberOfObject; ++j)
    {
       if (j!=i)
       {
          const Object tempObject = objectlist[j];
          Distance d;
          arma::Col<double> position1, position2;
          position1 = mainObject.getPosition();
          position2 = tempObject.getPosition()+ time*tempObject.getVelocity();
          double R = d.twoObjects(position1, position2);

          if (dimension == "ly")
          {
             tempAcceleration = -(tempObject.getMass()*
                                  (mainObject.getPosition()-tempObject.getPosition())/
                                  (R*(R*R+epsilon_*epsilon_)));// ly/yr]
          }
          else if(dimension == "AU")
          {
             tempAcceleration = -4*PI*PI*tempObject.getMass()*
                   (mainObject.getPosition()-tempObject.getPosition())/
                   (R*(R*R+epsilon_*epsilon_));// ly/yr]
          }
          else
          {
             std::cout << "dimension must be AU or ly"<< std::endl;
          }
          acceleration += tempAcceleration;
       } //end if
    } //end for
    mainObject.setAcceleration(acceleration);
 }
Beispiel #3
0
 double
 System::boundKineticEnergi(double limit) const
 {
    double energy = 0;
    arma::Col<double> center(3), position(3);
    center.zeros();
    Distance d;
    for (int i = 0 ; i < numberOfObject ; ++i)
    {
       Object movingObject = objectlist[i];
       position = movingObject.getPosition();
       if (d.twoObjects(center, position)<limit)
       {
          energy += 0.5 * movingObject.getMass() *
                arma::dot(movingObject.getVelocity(),
                          movingObject.getVelocity()) ;
       }
    }

    return energy;
 }
Beispiel #4
0
 double
 System::potentialEnergy() const
 {
    Distance d;
    double energy = 0.0;
    for (int i = 0 ; i < numberOfObject ; ++i)
    {
       for (int j = 0 ; j < numberOfObject ; ++j)
       {
          if (i!=j)
          {
             const Object movingObject = objectlist[i];
             const Object otherObject  = objectlist[j];
             const double R = d.twoObjects(movingObject.getPosition(),
                                           otherObject.getPosition());
             energy += -( 4 * PI * PI * otherObject.getMass() *
                   movingObject.getMass()/R);
          }
       }
    }

    return energy;
 }
Beispiel #5
0
 double
 System::maxTimestep(int i)
 {
    Distance d;
    const Object mainObject = objectlist[i];
    int k;
    if (i == 0)
    {
       k=1;
    }
    else
    {
       k=0;
    }
    Object tempObject = objectlist[k];
    arma::Col<double> position1(3), position2(3);
    arma::Col<double> mainVel = mainObject.getVelocity();

    position1 = mainObject.getPosition();
    position2 = tempObject.getPosition();

    double R = d.twoObjects(position1, position2);
    arma::Col<double> tempVel = tempObject.getVelocity()-mainVel;
    double V = std::sqrt(arma::dot(tempVel,tempVel));
    double maxTime;
    if (V>1e-16)
    {
       maxTime = R/V;
    }
    else
    {
       maxTime = R/1e-16;
    }
    double temptime;

    for (int j = 1; j < numberOfObject; ++j)
    {
       if (j!=i)
       {
          tempObject = objectlist[j];
          position2 = tempObject.getPosition();
          R = d.twoObjects(position1, position2);
          tempVel = tempObject.getVelocity()-mainVel;
          V = std::sqrt(arma::dot(tempVel,tempVel));
          if (V>1e-16)
          {
             maxTime = R/V;
          }
          else
          {
             maxTime = R/1e-16;
          }
          temptime = R/V;
          if (temptime<maxTime)
          {
             maxTime = temptime;
          }
       } //end if
    } //end for
    return maxTime;
 }
Beispiel #6
0
int
SolveStep::solve(double timestep,
                 double time,
                 std::string name,
                 std::string method,
                 std::string dimension)
{
   /* Solves given system with given parametres using
    * given method
    * timestep: size of timestep
    * time: total simulation time
    * name: name of files where the position of the
    *       particles are saved at some timesteps
    * method: verlet or RK4
    * dimension: ly or AU
    *
    * Ditterent timers have not been used at the
    * same time.*/

   clock_t start, finish;
   Distance d;

   //declaration and intialisation
   omp_set_num_threads(8); //parallelisation
   double limit = 60; //definition of bound system
   arma::Col<double> center(3), position(3);
   center.zeros();
   double t = 0.;
   System newsystem = mysolarsystem_;
   int n = time/timestep;

   //file to store energy of the system
   std::ofstream energy("energy.m");
   energy << "A = [";
   //file to store energy of the bound system
   std::ofstream bound("BoundEnergy.m");
   bound << "A = [";


   //update the objects initial acceleration
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = newsystem.objectlist[i];
      newsystem.acceleration(mainbody, i, 0.0,dimension);
   }

//   start = clock(); //start timer

   //start simulation
   for (int k = 0 ; k < n ; ++k)
   {
      t += timestep;

      //file to store position of particles
      name.append("t");
      std::string filename = name;
      filename.append(".m");
      std::ofstream fout(filename.c_str());
      fout << "t = " << t << "\n A = [";

      //variable needed for calculating intermediate steps
      double addtime = 0.0;

      //simulate all particles for one timestep
#pragma omp parallel for private(i)
      for (int i = 0 ; i < size() ; ++i)
      {
         Object &mainbody = newsystem.objectlist[i];
         System tempSystem = mysolarsystem_;
         double dt = timestep;
         int j = 0;

         double maxTimestep;

         //chose the smallest timestep
         if (mainbody.maxTimestep() < tempSystem.maxTimestep(i))
         {
            maxTimestep = mainbody.maxTimestep();
         }
         else
         {
            maxTimestep = tempSystem.maxTimestep(i);
         }

         //make sure to use small endough timesteps
         while(dt > maxTimestep)
         {
               dt = dt/2.0;

               j += 1;
         }

         //simulate timesteps
         for (int kk = 0 ; kk < std::pow(2,j); ++kk)
         {
            if (method == "rk4")
            {
               start = clock(); //start timer
               rk4Step(dt, i, mainbody, tempSystem, addtime, dimension);
               finish = clock(); //stop timer
               std::cout << "time one rk4 step: " <<
                            static_cast<double>(finish - start)/
                            static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;
//               mainbody.addToFile(name);
               addtime += dt;
            }
            else if(method == "verlet")
            {
               start = clock(); //start timer
               verlet(dt, i, mainbody, tempSystem, addtime, dimension);
               finish = clock(); //stop timer
               std::cout << "time one verlet step: " <<
                            static_cast<double>(finish - start)/
                            static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;
//               mainbody.addToFile(name);
               addtime += dt;
            }
            else
            {
               std::cout << "method must be 'verlet' or 'rk4'" << std::endl;
            }

      }

      mysolarsystem_ = newsystem;

      //save position to file
      for (int i = 0 ; i < size() ; ++i)
      {
         Object &mainbody = mysolarsystem_.objectlist[i];
         position = mainbody.getPosition();
         double dist = d.twoObjects(position,center) ;
         if(dist < limit)
         {
            fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1)
                 << "\t\t" << mainbody.getPosition()(2) << "\n";
         }
//         else
//         {
//            mysolarsystem_.removeObject(i);
//            i-=1;
//         }
      }
      fout << "]; \n";
      fout << "plot3(A(:,1), A(:,2),A(:,3), 'o')\n";
      fout << "t = " << t ;
      fout.close();
      }

         //write energy of the system to file
         bound << t << "\t\t" << mysolarsystem_.boundPotentialEnergy(limit) << "\t\t"
               << mysolarsystem_.boundKineticEnergi(limit) << "\n";

         energy << t << "\t\t" <<  mysolarsystem_.potentialEnergy() << "\t\t"
                << mysolarsystem_.kineticEnergi() << "\n";
         if (k % 100 == 0)
         {
            std::cout << t << std::endl;
         }

   }
//   finish = clock(); //stop timer
//   std::cout << "time: " <<
//                static_cast<double>(finish - start)/
//                static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl;


   energy << "]; \n";
   energy.close();

   bound << "]; \n";
   bound.close();
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = mysolarsystem_.objectlist[i];
      mysolarsystem_.acceleration(mainbody, i, 0.0,dimension);
   }


   //write final postition to file
   std::ofstream fout("end.m");
   fout << "A = [";
   for (int i = 0 ; i < size() ; ++i)
   {
      Object &mainbody = mysolarsystem_.objectlist[i];

      fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1)
           << "\t\t" << mainbody.getPosition()(2) << "\n";
   }
   fout << "] \n";
   fout.close();

   return 0;
}