Guest User

hoopdehoop

a guest
May 17th, 2015
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.71 KB | None | 0 0
  1. #include <armadillo>
  2. #include <iostream>
  3. #include <vector>
  4. #include <cmath>
  5.  
  6. constexpr double g       = 9.81;
  7. constexpr double M       = 1.;
  8. constexpr double m       = 1.*M;
  9. constexpr double R       = 1.;
  10. constexpr double dt      = 0.000001;
  11.  
  12. class Entity {
  13. public:
  14.   double m{0.0};
  15.   arma::vec x{0., 0.};
  16.   arma::vec v{0., 0.};
  17.   arma::vec a{0., 0.};
  18. };
  19.  
  20. class System {
  21. public:
  22.        System();
  23.   void takeSteps(unsigned int N) noexcept;
  24.   void printState() const noexcept;
  25. private:
  26.   void realStep() noexcept;
  27.   void trialStep() const noexcept;
  28.   void getConstraints() noexcept;
  29.   arma::vec evalConstraints() const noexcept;
  30. private:
  31.   std::vector<Entity> currentState;
  32.   mutable std::vector<Entity> trialState;
  33.   arma::vec constraints{0., 0.};
  34. };
  35.  
  36. System::System() {
  37.   currentState.resize(3);
  38.   auto& ball1 = currentState[0];
  39.   auto& ball2 = currentState[1];
  40.   auto& loop  = currentState[2];
  41.  
  42.   ball1.x[1] =  R;
  43.   ball2.x[1] =  R;
  44.   ball1.v[0] = -0.01*R;
  45.   ball2.v[0] =  0.01*R;
  46.   ball1.m    =  m;
  47.   ball2.m    =  m;
  48.   loop.m     =  M;
  49.  
  50.   trialState = currentState;
  51. }
  52.  
  53. void System::takeSteps(unsigned int N) noexcept {
  54.   for (int i = 0; i < N; ++i) {
  55.     getConstraints();
  56.     realStep();
  57.   }
  58. }
  59.  
  60. void System::printState() const noexcept {
  61.   auto& ball1 = currentState[0];
  62.   auto& ball2 = currentState[1];
  63.   auto& loop  = currentState[2];
  64.   std::cout << ball1.x[0] << " " << ball1.x[1] << " "
  65.             << ball2.x[0] << " " << ball2.x[1] << " "
  66.             << loop.x[1]  << " " << loop.a[1]  << std::endl;
  67. }
  68.  
  69. void System::realStep() noexcept {
  70.   trialStep();
  71.   using std::swap;
  72.   swap(currentState, trialState);
  73. }
  74.  
  75. void System::trialStep() const noexcept {
  76.   auto& ball1T = trialState[0];
  77.   auto& ball2T = trialState[1];
  78.   auto& loopT  = trialState[2];
  79.  
  80.   auto& ball1 = currentState[0];
  81.   auto& ball2 = currentState[1];
  82.   auto& loop  = currentState[2];
  83.  
  84.   auto lbd1   = constraints[0];
  85.   auto lbd2   = constraints[1];
  86.  
  87.   ball1T.a[0] =  (2.*lbd1 *  ball1.x[0])/ball1.m;
  88.   ball1T.a[1] =  (2.*lbd1 * (ball1.x[1]-loop.x[1]) - ball1.m*g)/ball1.m;
  89.   ball2T.a[0] =  (2.*lbd2 *  ball2.x[0])/ball2.m;
  90.   ball2T.a[1] =  (2.*lbd2 * (ball2.x[1]-loop.x[1]) - ball2.m*g)/ball2.m;
  91.   loopT.a[1]  = (-2.*lbd1 * (ball1.x[1]-loop.x[1])
  92.                  -2.*lbd2 * (ball2.x[1]-loop.x[1]) - loop.m*g)/loop.m;
  93.  
  94.   auto itTrial = trialState.begin();
  95.   for (auto it = currentState.cbegin(); it != currentState.cend(); ++it) {
  96.     (*itTrial).v = (*it).v + .5*dt*((*it).a + (*itTrial).a);
  97.     (*itTrial).x = (*it).x + dt*(*itTrial).v + .5*dt*dt*(*itTrial).a;
  98.     ++itTrial;
  99.   }
  100.  
  101.   if (loopT.x[1] < 0.) {
  102.     loopT.x[1] = 0.;
  103.     if (loopT.v[1] < 0.)
  104.       loopT.v[1] *= -1;
  105.   }
  106. }
  107.  
  108. void System::getConstraints() noexcept {
  109.   constexpr double eps = 0.01;
  110.  
  111.   for (int i = 0; i < 1000; ++i) {
  112.     auto cc = constraints;
  113.     auto kk = -evalConstraints();
  114.     arma::mat J = arma::zeros<arma::mat>(constraints.size(), constraints.size());
  115.  
  116.     for (int j = 0; j < constraints.size(); ++j) {
  117.       constraints[j] = cc[j] + eps;
  118.       auto jcol = evalConstraints();
  119.       constraints[j] = cc[j] - eps;
  120.       jcol -= evalConstraints();
  121.       constraints[j] = cc[j];
  122.       J.col(j) = jcol/(2.*eps);
  123.     }
  124.  
  125.     J = inv(J);
  126.     arma::vec newcc = J*kk;
  127.  
  128.     if (arma::norm(newcc) < 1e-4*arma::norm(cc))
  129.       break;
  130.    
  131.     cc += newcc;
  132.     constraints = cc;
  133.   }
  134. }
  135.  
  136. arma::vec System::evalConstraints() const noexcept {
  137.   trialStep();
  138.   arma::vec val{0., 0.};
  139.   for (int i = 0; i < 2; ++i)
  140.     val[i] = arma::norm(trialState[i].x - trialState[2].x) - R;
  141.   return val;
  142. }
  143.  
  144. int main() {
  145.   System kk;
  146.   for (int i = 0; i < 6000; ++i) {
  147.     kk.takeSteps(1000);
  148.     kk.printState();
  149.   }
  150. }
Advertisement
Add Comment
Please, Sign In to add comment