SpaceQuester

Untitled

Nov 10th, 2025
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.91 KB | None | 0 0
  1. #define _USE_MATH_DEFINES
  2. #include "math.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <locale.h>
  6. #include <time.h>
  7. #include <stdbool.h>
  8.  
  9. #define N 8
  10.  
  11. #define Ca  f[0]
  12. #define IP3 f[1]
  13. #define z   f[2]
  14. #define V   f[3]
  15. #define m   f[4]
  16. #define n   f[5]
  17. #define h   f[6]
  18. #define G   f[7]
  19.  
  20. double f[N];
  21.  
  22. double k[N][4];
  23. double phi_k1[N];
  24. double phi_k2[N];
  25. double phi_k3[N];
  26.  
  27. double c_0 = 2;
  28. double c_1 = 0.185;
  29. double v_1 = 6;
  30. double v_2 = 0.11;
  31. double v_3 = 2.2;
  32. double v_4 = 0.0;
  33. double v_5 = 0.025;
  34. double v_6 = 0.2;
  35. double k_1 = 0.5;
  36. double k_2 = 1;
  37. double k_3 = 0.1;
  38. double k_4 = 1.1;
  39. double a_2 = 0.14;
  40. double d_1 = 0.13;
  41. double d_2 = 1.049;
  42. double d_3 = 0.9434;
  43. double d_5 = 0.082;
  44. double alpha_G = 25;
  45. double beta_G = 500;
  46. double alpha = 0.8;
  47. double tau_IP3 = 7.143;
  48. double IP3_star = 0.16;
  49. double alpha_Glu = 2;
  50. //double d_Ca = 0.001;
  51. //double d_IP3 = 0.12;
  52.  
  53. double C = 1; // muF/cm^2
  54. double g_K  =  35; // mS/cm^2
  55. double g_Na =  40; // mS/cm^2
  56. double g_L  = 0.3; // mS/cm^2
  57. double E_K  = -77; // mV
  58. double E_Na =  55; // mV
  59. double E_L  = -65; // mV
  60. double I_app = 1.2;
  61.  
  62. int RandomI(int min, int max)
  63. {
  64.     return ((double)rand() / (RAND_MAX - 1)) * (max - min) + min;
  65. }
  66.  
  67. double RandomD(double min, double max)
  68. {
  69.     return ((double)rand() / RAND_MAX) * (max - min) + min;
  70. }
  71.  
  72. double J_channel(double f[N])
  73. {
  74.     return c_1 * v_1 * pow(IP3, 3) * pow(Ca, 3) * pow(z, 3) * (c_0 / c_1 - (1 + 1 / c_1) * Ca) / pow((IP3 + d_1) * (Ca + d_5), 3);
  75. }
  76.  
  77. double J_pump(double f[N])
  78. {
  79.     return v_3 * pow(Ca, 2) / (pow(k_3, 2) + pow(Ca, 2));
  80. }
  81.  
  82. double J_leak(double f[N])
  83. {
  84.     return c_1 * v_2 * (c_0 / c_1 - (1 + 1 / c_1) * Ca);
  85. }
  86.  
  87. double J_in(double f[N])
  88. {
  89.     return v_5 + v_6 * pow(IP3, 2) / (pow(k_2, 2) + pow(IP3, 2));
  90. }
  91.  
  92. double J_out(double f[N])
  93. {
  94.     return k_1 * Ca;
  95. }
  96.  
  97. double J_PLC(double f[N])
  98. {
  99.     return v_4 * (Ca + (1 - alpha) * k_4) / (Ca + k_4);
  100. }
  101.  
  102. double J_Glu(double f[N])
  103. {
  104.     return alpha_Glu / (1 + exp(-(G - 0.25) / 0.01));
  105. }
  106.  
  107. double alpha_n(double f[N])
  108. {
  109.     return 0.02 * (V - 25) / (1 - exp(-(V - 25) / 9));
  110. }
  111.  
  112. double beta_n(double f[N])
  113. {
  114.     return -0.002 * (V - 25) / (1 - exp((V - 25) / 9));
  115. }
  116.  
  117. double alpha_m(double f[N])
  118. {
  119.     return 0.182 * (V + 35) / (1 - exp(-(V + 35) / 9));
  120. }
  121.  
  122. double beta_m(double f[N])
  123. {
  124.     return -0.124 * (V + 35) / (1 - exp((V + 35) / 9));
  125. }
  126.  
  127. double alpha_h(double f[N])
  128. {
  129.     return 0.25 * exp(-(V + 90) / 12);
  130. }
  131.  
  132. double beta_h(double f[N])
  133. {
  134.     return 0.25 * exp((V + 62) / 6) / exp((V + 90) / 12);
  135. }
  136.  
  137. double UllahJung_HodgkinHuxley(int i, double f[N])
  138. {
  139.     switch (i)
  140.     {
  141.     case 0: // Ca
  142.         return J_channel(f) - J_pump(f) + J_leak(f) + J_in(f) - J_out(f);
  143.  
  144.     case 1: // IP3
  145.         return (IP3_star - IP3) / tau_IP3 + J_PLC(f) + J_Glu(f);
  146.  
  147.     case 2: // z
  148.         return a_2 * ( d_2 * ((IP3 + d_1) / (IP3 + d_3)) * (1 - z) - Ca * z );
  149.    
  150.     case 3: // V
  151.         return 1000 * ((g_Na * pow(m, 3) * h * (E_Na - V) + g_K * n * (E_K - V) + g_L * (E_L - V) + I_app) / C);
  152.  
  153.     case 4: // m
  154.         return 1000 * (alpha_m(f) * (1 - m) - beta_m(f) * m);
  155.  
  156.     case 5: // n
  157.         return 1000 * (alpha_n(f) * (1 - n) - beta_n(f) * n);
  158.  
  159.     case 6: // h
  160.         return 1000 * (alpha_h(f) * (1 - h) - beta_h(f) * h);
  161.        
  162.     case 7: // G
  163.         return -alpha_G * G + beta_G * (1 / (1 + exp(-V / 0.5)));
  164.     }
  165.  
  166.     return 0;
  167. }
  168.  
  169. void RungeKutta(double dt, double f[N], double f_next[N])
  170. {
  171.     #pragma omp parallel for
  172.     for (int i = 0; i < N; i++)
  173.     {
  174.         k[i][0] = UllahJung_HodgkinHuxley(i, f) * dt;
  175.         phi_k1[i] = f[i] + k[i][0] / 2;
  176.         k[i][1] = UllahJung_HodgkinHuxley(i, phi_k1) * dt;
  177.         phi_k2[i] = f[i] + k[i][1] / 2;
  178.         k[i][2] = UllahJung_HodgkinHuxley(i, phi_k2) * dt;
  179.         phi_k3[i] = f[i] + k[i][2] / 2;
  180.         k[i][3] = UllahJung_HodgkinHuxley(i, phi_k3) * dt;
  181.  
  182.         f_next[i] = f[i] + (k[i][0] + 2 * k[i][1] + 2 * k[i][2] + k[i][3]) / 6;
  183.     }
  184. }
  185.  
  186. void CopyArray(double source[N], double target[N])
  187. {
  188.     for (int i = 0; i < N; i++)
  189.         target[i] = source[i];
  190. }
  191.  
  192. bool Approximately(double a, double b)
  193. {
  194.     if (a < 0)
  195.         a = -a;
  196.  
  197.     if (b < 0)
  198.         b = -b;
  199.  
  200.     return a - b <= 0.000001;
  201. }
  202.  
  203. int main()
  204. //main(int argc, char *argv[])
  205. {
  206.     //sscanf(argv[1], "%lf", &v_4);
  207.  
  208.     FILE *fp0;
  209.     srand(time(NULL));
  210.  
  211.     double Ca_0  = 0.07;
  212.     double IP3_0 = 0.16;
  213.     double z_0   = 0.67;
  214.    
  215.     double V_0 = -58.7085;
  216.     double m_0 = 0.0953;
  217.     double n_0 = 0.000913;
  218.     double h_0 = 0.3662;
  219.    
  220.     double G_0 = 0;
  221.    
  222.     //Initial values at t = 0
  223.     f[0] = Ca_0;
  224.     f[1] = IP3_0;
  225.     f[2] = z_0;
  226.    
  227.     f[3] = V_0;
  228.     f[4] = m_0;
  229.     f[5] = n_0;
  230.     f[6] = h_0;
  231.    
  232.     f[7] = G_0;
  233.        
  234.     /*fp0 = fopen("last_values.txt", "r");
  235.     for (int i = 0; i < N; i++)
  236.     {
  237.         fscanf(fp0, "%lf", &f[i]);
  238.     }
  239.     fclose(fp0);*/
  240.  
  241.     const double t_start = 0;
  242.     const double t_max   = 120; // sec
  243.     const double dt      = 0.00001;
  244.  
  245.     double t = t_start;
  246.  
  247.     //fp0 = fopen("v_4.txt", "w+");
  248.     //fprintf(fp0, "%f\n", v_4);
  249.     //fclose(fp0);
  250.  
  251.     fp0 = fopen("results.txt", "w+");
  252.     //setlocale(LC_NUMERIC, "French_Canada.1252");
  253.  
  254.     clock_t start_rk4, end_rk4;
  255.     start_rk4 = clock();
  256.     int lastPercent = -1;
  257.  
  258.     while (t < t_max || Approximately(t, t_max))
  259.     {
  260.         fprintf(fp0, "%f\t", t);
  261.         for (int i = 0; i < N; i++)
  262.         {
  263.             fprintf(fp0, i == N - 1 ? "%f" : "%f\t", f[i]);
  264.         }
  265.         fprintf(fp0, "\n");
  266.  
  267.         double f_next[N];
  268.  
  269.         RungeKutta(dt, f, f_next);
  270.         CopyArray(f_next, f);
  271.  
  272.         t += dt;
  273.  
  274.         int percent = (int)(100 * (t - t_start) / (t_max - t_start));
  275.         if (percent != lastPercent)
  276.         {
  277.             printf("Progress: %d%%\n", percent);
  278.             lastPercent = percent;
  279.         }
  280.     }
  281.  
  282.     end_rk4 = clock();
  283.     double extime_rk4 = (double)(end_rk4 - start_rk4) / CLOCKS_PER_SEC;
  284.     int minutes = (int)extime_rk4 / 60;
  285.     int seconds = (int)extime_rk4 % 60;
  286.     printf("\nExecution time is: %d minutes %d seconds\n ", minutes, seconds);
  287.  
  288.     fclose(fp0);
  289.  
  290.     fp0 = fopen("time_exec.txt", "w+");
  291.     fprintf(fp0, "%f\n", extime_rk4);
  292.     fclose(fp0);
  293.  
  294.     /*fp0 = fopen("last_values.txt", "w+");
  295.     for (int i = 0; i < N; i++)
  296.     {
  297.         fprintf(fp0, i == N - 1 ? "%f" : "%f\t", f[i]);
  298.     }
  299.     fclose(fp0);*/
  300. }
  301.  
Advertisement
Add Comment
Please, Sign In to add comment