Based on the original Rocket Workbench on SourceForge in CVS at: https://sourceforge.net/projects/rocketworkbench
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
3.2 KiB

  1. #include <cmath>
  2. #include <iostream>
  3. #include "lsode.h"
  4. //#include "simulation.h"
  5. #include "c++rocket.h"
  6. //typedef int (* ModelFunc)(const int &, const double &, double *,
  7. // double *, int &);
  8. char *error_msg(State s);
  9. static int ModelNeq[MODEL_LAST] = { 7, 5 };
  10. lsode::lsode(Model_t model) {
  11. memory = 0;
  12. neq = ModelNeq[model];
  13. //dy = new double*[7];
  14. time = 0.0;
  15. itol = 1;
  16. rtol = 1.49012e-08;
  17. atol = 1.49012e-08;
  18. itask = 1;
  19. istate = 1;
  20. iopt = 0;
  21. rwork = new double[20+16*neq];
  22. lrw = 20+16*neq;
  23. iwork = new int[20];
  24. liw = 20;
  25. mf = 10;
  26. state = new double[neq];
  27. if (!rwork) {
  28. cout << "Allocation error\n";
  29. exit(-1);
  30. }
  31. switch (model)
  32. {
  33. case AERO_MODEL:
  34. md = model_1;
  35. break;
  36. case SIMPLE_MODEL:
  37. md = model_2;
  38. break;
  39. default:
  40. exit(-1);
  41. }
  42. }
  43. lsode::~lsode() {
  44. if (memory) {
  45. for (int j = 0; j < neq; j++)
  46. delete [] dy[j];
  47. delete dy;
  48. }
  49. delete [] state;
  50. delete [] iwork;
  51. delete [] rwork;
  52. cout << "Freeing memory...\n" ;
  53. }
  54. int lsode::solve(double *st, double duration, double step)
  55. {
  56. reset();
  57. if (memory) {
  58. for (int j = 0; j < neq; j++)
  59. delete [] dy[j];
  60. delete dy;
  61. memory = 0;
  62. }
  63. length = (int)rint(duration/step);
  64. // on alloue la memoire
  65. dy = new double*[neq];
  66. for (int j = 0; j < neq; j++)
  67. dy[j] = new double[length];
  68. memory = 1; // pour indiquer que l'on a alloue la memoire
  69. // on simule et on remplie l'array
  70. for (int i = 0; i < length; i++) {
  71. tout = i*step;
  72. lsode_((ModelFunc_t)md, neq, st, time, tout, itol, rtol, atol,
  73. itask, istate, iopt, rwork, lrw, iwork, liw, NULL, mf);
  74. for (int j = 0; j < neq ; j++)
  75. dy[j][i] = st[j];
  76. if (istate < 0) // if any error, stop the simulation
  77. {
  78. cout << "ERROR: " << error_msg ((State)istate) << endl;
  79. cout << i << " points out of " << length << " were found."
  80. << endl;
  81. return i;
  82. }
  83. }
  84. cout << "Simulation completed successfully." << endl;
  85. cout << length << " " << "points computed" << endl;
  86. return length;
  87. }
  88. void lsode::reset()
  89. {
  90. tout = 0.0; // restart the simulation at 0
  91. time = 0.0; // restart the time at 0
  92. istate = 1; // should reset the istate
  93. }
  94. void lsode::print() {
  95. for (int i = 0; i < length; i++) {
  96. for (int j = 0; j < neq; j++) {
  97. cout << dy[j][i] << "\t";
  98. }
  99. cout << "\n";
  100. }
  101. }
  102. void lsode::get_data(double** a)
  103. {
  104. for (int i = 0; i < length; i++)
  105. for (int j = 0; j < neq; j++)
  106. a[j][i] = dy[j][i];
  107. }
  108. char *error_msg(State s)
  109. {
  110. switch (s)
  111. {
  112. case TOO_MUCH_WORK:
  113. return "Excess work done on this call (perhaps wrong mf).";
  114. break;
  115. case TOO_MUCH_ACC:
  116. return "Excess Accuracy Requested (Tolerances too small).";
  117. break;
  118. case ILLEGAL_INPUT:
  119. return "Illegal input detected.";
  120. break;
  121. case ERR_FAILURE:
  122. return "Repeated error test failures.";
  123. break;
  124. case CONV_FAILURE:
  125. return "Repeated convergence failures.";
  126. break;
  127. case ERROR_WEIGHT:
  128. return "Error weight became zero during problem.";
  129. break;
  130. case EXIT_IN_FUNCTION:
  131. return "Exit requested in ode function.";
  132. break;
  133. default:
  134. return "Unrecognize error state.";
  135. }
  136. }