Skip to content
Snippets Groups Projects
Select Git revision
  • b4369795c8d26b27170cdbcd34596d0b610f9574
  • master default protected
  • develop
  • 1.0
4 results

slab_polarization.c

Blame
  • slab_polarization.c 13.54 KiB
    #include "iteration_functions.h"
    
    gsl_spline2d* Spline_I2d_l;
    gsl_spline2d* Spline_I2d_r;
    gsl_interp_accel* xacc_2d;
    gsl_interp_accel* yacc_2d;
    
    gsl_spline* Spline_sample_Iu;
    gsl_spline* Spline_eval_limbdark;
    gsl_spline* Spline_eval_pdeg;
    
    gsl_spline* Spline_tau_Ak;
    gsl_spline* Spline_tau_Bk;
    gsl_spline* Spline_tau_Ck;
    
    gsl_interp_accel* xacc_1d;
    gsl_interp_accel* yacc_1d;
    
    int Nstep_tau;
    int Nstep_mu;
    double eps;
    double u_min;
    double u_max;
    double tau_s;
    
    /*========================================================================*/
    
    void slab_polarization(int kiter, int seed_location)
    {
      Nstep_mu = 20;
      Nstep_tau = 100;
    
      tau0 = disktau / 2.;
    
      int ii, jj, kk;
    
      double* array_mu;
      double* array_tau;
      double* array_weights;
      double* Ak_array;
      double* Bk_array;
      double* Ck_array;
    
      double error;
    
      printf("tau0=%4.3f\n", tau0);
    
      array_mu = malloc(Nstep_mu * sizeof(double));
      array_weights = malloc(Nstep_mu * sizeof(double));
      array_tau = malloc(Nstep_tau * sizeof(double));
    
      Ak_array = malloc(Nstep_tau * sizeof(double));
      Bk_array = malloc(Nstep_tau * sizeof(double));
      Ck_array = malloc(Nstep_tau * sizeof(double));
    
      eps = 1e-5;
    
      tau_s = 2 * tau0 - tau_c;
    
      /*=================================================================*/
    
      float* roots_u = malloc((Nstep_mu + 1) * sizeof(float));
      float* weights = malloc((Nstep_mu + 1) * sizeof(float));
    
      gauleg(0, 1, roots_u, weights, Nstep_mu);
    
      for (ii = 1; ii <= Nstep_mu; ii++)
      {
        array_mu[ii - 1] = roots_u[ii];
        array_weights[ii - 1] = weights[ii];
      }
    
      u_min = array_mu[0];
      u_max = array_mu[Nstep_mu - 1];
    
      /*make_linarray(u_min, 1, Nstep_mu, array_mu);*/
    
      /* exit(1);*/
      /*=================================================================*/
    
      make_linarray(0, 2. * tau0, Nstep_tau, array_tau);
    
      Ikl_intensity* ptr_Ikl;
      Ikr_intensity* ptr_Ikr;
    
      ptr_Ikl = malloc(kiter * sizeof(Ikl_intensity));
      ptr_Ikr = malloc(kiter * sizeof(Ikr_intensity));
    
      for (ii = 0; ii < kiter; ii++)
      {
        ptr_Ikl[ii].matrix = dmatrix(0, Nstep_tau - 1, 0, Nstep_mu - 1);
        ptr_Ikr[ii].matrix = dmatrix(0, Nstep_tau - 1, 0, Nstep_mu - 1);
      }
    
      /*=================================================================*/
      /*Set the function for photons undegoing no scattering*/
      /*=================================================================*/
    
      for (ii = 0; ii < Nstep_tau; ii++)
      {
        for (jj = 0; jj < Nstep_mu; jj++)
        {
          if (seed_location == SEED_CENTER)
          {
            ptr_Ikl[0].matrix[ii][jj] = I0_center(tau0, array_tau[ii], array_mu[jj]);
            ptr_Ikr[0].matrix[ii][jj] = I0_center(tau0, array_tau[ii], array_mu[jj]);
          }
          else if (seed_location == SEED_UNIFORM)
          {
            ptr_Ikl[0].matrix[ii][jj] = I0_uniform(tau0, array_tau[ii], array_mu[jj]);
            ptr_Ikr[0].matrix[ii][jj] = I0_uniform(tau0, array_tau[ii], array_mu[jj]);
          }
          else if (seed_location == SEED_DELTA)
          {
            ptr_Ikl[0].matrix[ii][jj] = I0_delta(array_tau[ii], tau_s, array_mu[jj]);
            ptr_Ikr[0].matrix[ii][jj] = I0_delta(array_tau[ii], tau_s, array_mu[jj]);
            printf("Do not use this configuration for seed photons fot ST85 algorithm\n");
            exit(1);
          }
          else if (seed_location == SEED_BASE)
          {
            ptr_Ikl[0].matrix[ii][jj] = I0_base(array_tau[ii], tau_s, array_mu[jj], U_POSITIVE);
            ptr_Ikr[0].matrix[ii][jj] = I0_base(array_tau[ii], tau_s, array_mu[jj], U_POSITIVE);
            printf("Do not use this configuration for seed photons fot ST85 algorithm\n");
            exit(1);
          }
          else if (seed_location == SEED_EXP)
          {
            ptr_Ikl[0].matrix[ii][jj] = I0_exp(array_tau[ii], tau0, array_mu[jj]);
            ptr_Ikr[0].matrix[ii][jj] = I0_exp(array_tau[ii], tau0, array_mu[jj]);
            printf("Do not use this configuration for seed photons fot ST85 algorithm\n");
            exit(1);
          }
    
          else
          {
            printf("Wait, do not use this!\n");
            exit(1);
          }
        }
      }
    
      /*=================================================================*/
      /*Setup for 2D interpolation*/
      /*=================================================================*/
    
      double* za = malloc(Nstep_tau * Nstep_mu * sizeof(double));
      const gsl_interp2d_type* T_interp2d = gsl_interp2d_bilinear;
    
      Spline_I2d_l = gsl_spline2d_alloc(T_interp2d, Nstep_tau, Nstep_mu);
      Spline_I2d_r = gsl_spline2d_alloc(T_interp2d, Nstep_tau, Nstep_mu);
    
      xacc_2d = gsl_interp_accel_alloc();
      yacc_2d = gsl_interp_accel_alloc();
    
      /*=================================================================*/
      /*Initialize objects for 1D interpolation*/
      /*=================================================================*/
    
      Spline_tau_Ak = gsl_spline_alloc(gsl_interp_cspline, Nstep_tau);
      Spline_tau_Bk = gsl_spline_alloc(gsl_interp_cspline, Nstep_tau);
      Spline_tau_Ck = gsl_spline_alloc(gsl_interp_cspline, Nstep_tau);
    
      xacc_1d = gsl_interp_accel_alloc();
    
      /*=================================================================*/
    
      AngularFunctionParams* ptr_data = malloc(sizeof(AngularFunctionParams));
      ptr_data->seed_location = seed_location;
      ptr_data->tau_s = tau_s;
    
      /*=============================================================*/
      /*Il and Ir functions*/
      /*=============================================================*/
    
      gsl_function I_l;
      I_l.function = &Il_integral;
    
      gsl_function I_r;
      I_r.function = &Ir_integral;
    
      /*=============================================================*/
    
      gsl_integration_workspace* w = gsl_integration_workspace_alloc(1000);
    
      double params_Ifunct[2];
      double result_Ir;
      double result_Il;
    
      /*=============================================================*/
      /*Here start the iteration over scattering*/
      /*=============================================================*/
    
      printf("Running iteration procedure using ST85 algorithm...\n");
    
      for (kk = 1; kk < kiter; kk++)
      {
        if (kk % 5 == 0)
          printf("iteration k=%d\n", kk);
        /*=============================================*/
        /*Loop over tau*/
        /*=============================================*/
    
        for (ii = 0; ii < Nstep_tau; ii++)
        {
          ptr_data->tau = array_tau[ii];
          ptr_data->k = kk;
    
          Compute_Ak_array(ptr_data, ptr_Ikl[kk - 1].matrix, za, array_tau, array_mu, kk, w, Ak_array);
    
          gsl_spline_init(Spline_tau_Ak, array_tau, Ak_array, Nstep_tau);
    
          Compute_Bk_array(ptr_data, ptr_Ikl[kk - 1].matrix, za, array_tau, array_mu, kk, w, Bk_array);
    
          gsl_spline_init(Spline_tau_Bk, array_tau, Bk_array, Nstep_tau);
    
          Compute_Ck_array(ptr_data, ptr_Ikr[kk - 1].matrix, za, array_tau, array_mu, kk, w, Ck_array);
    
          gsl_spline_init(Spline_tau_Ck, array_tau, Ck_array, Nstep_tau);
    
          /*=============================================*/
          /*Loop over mu*/
          /*=============================================*/
    
          for (jj = 0; jj < Nstep_mu; jj++)
          {
            params_Ifunct[0] = array_tau[ii];
            params_Ifunct[1] = array_mu[jj];
    
            I_l.params = params_Ifunct;
            I_r.params = params_Ifunct;
    
            if (array_tau[ii] == 2 * tau0)
            {
              ptr_Ikl[kk].matrix[ii][jj] = 0;
              ptr_Ikr[kk].matrix[ii][jj] = 0;
            }
            else
            {
              gsl_integration_qags(&I_l, array_tau[ii], 2 * tau0, eps, eps, 1000, w, &result_Il, &error);
              gsl_integration_qags(&I_r, array_tau[ii], 2 * tau0, eps, eps, 1000, w, &result_Ir, &error);
    
              if (isnan(result_Il))
              {
                printf("Warning: Il is nan for tau=%lf mu=%lf\n", array_tau[ii], array_mu[jj]);
                result_Il = 0;
              }
    
              if (isnan(result_Ir))
              {
                printf("Warning: Ir is nan for tau=%lf mu=%lf\n", array_tau[ii], array_mu[jj]);
                result_Ir = 0;
              }
    
              ptr_Ikl[kk].matrix[ii][jj] = result_Il;
              ptr_Ikr[kk].matrix[ii][jj] = result_Ir;
            }
          }
    
        } /*Loop over tau*/
    
      } /*Loop over kiter*/
    
      /*========================================================================*/
      /*Now sum results*/
      /*========================================================================*/
    
      Iklr_intensity* ptr_void = 0;
    
      compute_results(2, kiter, Nstep_tau, Nstep_mu, array_mu, array_weights, ptr_void, ptr_Ikl, ptr_Ikr);
    
    } // End of function
    
    /*==========================================================================*/
    void make_linarray(double a, double b, int nstep, double* my_array)
    {
      int ii;
      double hstep;
    
      hstep = (b - a) / (nstep - 1);
    
      for (ii = 0; ii < nstep; ii++)
      {
        my_array[ii] = a + hstep * ii;
        /*printf("ii=%d value=%lf\n", ii, my_array[ii]);*/
      }
    }
    
    /*========================================================================*/
    /*Distribution of photons with zero scattering*/
    /*========================================================================*/
    
    double theta_funct(double tau, double tau_c)
    {
      double x;
      double flag;
      x = tau_c - tau;
    
      if (x > 0)
      {
        flag = 1;
      }
      else
      {
        flag = 0;
      }
    
      // printf("Argument of theta : tau %lf tau_delta %lf flag= %d \n", tau, tau_c, flag);
      return flag;
    }
    
    double I0_center(double tau0, double tau, double mu)
    {
      double arg_exp, value;
    
      arg_exp = (tau0 - tau) / mu;
    
      value = 1 / mu * theta_funct(tau, tau0) * exp(-arg_exp);
    
      return value;
    }
    
    double I0_delta(double tau, double tau_s, double mu)
    
    {
      double value;
    
      value = 1 / mu * theta_funct(tau, tau_s) * exp(-(tau_s - tau) / mu);
    
      return value;
    }
    
    double I0_uniform(double tau0, double tau, double mu)
    {
      double value;
    
      value = 1 - exp(-(2 * tau0 - tau) / mu);
    
      return value;
    }
    
    double I0_exp(double tau, double tau0, double mu)
    {
      double value;
      double tau_fold = 0.2;
    
      value = tau_fold / (tau_fold - mu) * (exp(-(2 * tau0 - tau) / tau_fold) - exp(-(2 * tau0 - tau) / mu));
    
      return value;
    }
    
    double I0_base(double tau, double tau_s, double mu, int sign_mu)
    {
      double value;
    
      // printf("tau_s=%4.3f tau_c %4.3f\n", tau_s, tau_c);
    
      if (sign_mu > 0)
      {
        if (tau > tau_s)
        {
          value = 1 - exp(-(2 * tau0 - tau) / mu);
        }
        else
        {
          value = (-exp(-(2 * tau0 - tau) / mu) + exp(-(tau_s - tau) / mu));
        }
      }
      else
      {
        if (tau < tau_c)
        {
          value = 1 - exp(-(tau_c - tau) / mu);
        }
        else
        {
          value = 0;
        }
      }
    
      return value;
    }
    
    /*========================================================================*/
    /*Functions A^{k-1}, B^{k-1}, C^{k-1}*/
    /*========================================================================*/
    
    void Compute_Ak_array(AngularFunctionParams* ptr_data,
                          double** Il_funct,
                          double* za,
                          double* array_tau,
                          double* array_mu,
                          int k,
                          gsl_integration_workspace* w,
                          double* Ak_array)
    {
      int ii, tt, qq;
      double result, error;
    
      gsl_function F_Ak;
      F_Ak.function = &Ak_integral;
    
      /*==================================*/
      /*Loop over tau*/
      /*==================================*/
    
      for (ii = 0; ii < Nstep_tau; ii++)
      {
        for (tt = 0; tt < Nstep_tau; tt++)
        {
          for (qq = 0; qq < Nstep_mu; qq++)
          {
            gsl_spline2d_set(Spline_I2d_l, za, tt, qq, Il_funct[tt][qq]);
          }
        }
    
        gsl_spline2d_init(Spline_I2d_l, array_tau, array_mu, za, Nstep_tau, Nstep_mu);
    
        ptr_data->tau = array_tau[ii];
        ptr_data->k = k;
    
        F_Ak.params = ptr_data;
    
        // printf("Integration between %lf - %lf\n", u_min, u_max);
    
        gsl_integration_qags(&F_Ak, u_min, u_max, eps, eps, 1000, w, &result, &error);
        Ak_array[ii] = result;
      }
    }
    
    /*=================================================================================*/
    
    void Compute_Bk_array(AngularFunctionParams* ptr_data,
                          double** Il_funct,
                          double* za,
                          double* array_tau,
                          double* array_mu,
                          int k,
                          gsl_integration_workspace* w,
                          double* Bk_array)
    {
      int ii, tt, qq;
      double result, error;
    
      gsl_function F_Bk;
      F_Bk.function = &Bk_integral;
    
      /*==================================*/
      /*Loop over tau*/
      /*==================================*/
    
      for (ii = 0; ii < Nstep_tau; ii++)
      {
        for (tt = 0; tt < Nstep_tau; tt++)
        {
          for (qq = 0; qq < Nstep_mu; qq++)
          {
            gsl_spline2d_set(Spline_I2d_l, za, tt, qq, Il_funct[tt][qq]);
          }
        }
    
        gsl_spline2d_init(Spline_I2d_l, array_tau, array_mu, za, Nstep_tau, Nstep_mu);
    
        ptr_data->tau = array_tau[ii];
        ptr_data->k = k;
        F_Bk.params = ptr_data;
    
        gsl_integration_qags(&F_Bk, u_min, u_max, eps, eps, 1000, w, &result, &error);
        Bk_array[ii] = result;
      }
    }
    
    /*=========================================================================*/
    
    void Compute_Ck_array(AngularFunctionParams* ptr_data,
                          double** Ir_funct,
                          double* za,
                          double* array_tau,
                          double* array_mu,
                          int k,
                          gsl_integration_workspace* w,
                          double* Ck_array)
    {
      int ii, tt, qq;
      double result, error;
    
      gsl_function F_Ck;
      F_Ck.function = &Ck_integral;
    
      /*==================================*/
      /*Loop over tau*/
      /*==================================*/
    
      for (ii = 0; ii < Nstep_tau; ii++)
      {
        for (tt = 0; tt < Nstep_tau; tt++)
        {
          for (qq = 0; qq < Nstep_mu; qq++)
          {
            gsl_spline2d_set(Spline_I2d_r, za, tt, qq, Ir_funct[tt][qq]);
          }
        }
    
        gsl_spline2d_init(Spline_I2d_r, array_tau, array_mu, za, Nstep_tau, Nstep_mu);
    
        ptr_data->tau = array_tau[ii];
        ptr_data->k = k;
        F_Ck.params = ptr_data;
    
        gsl_integration_qags(&F_Ck, u_min, u_max, eps, eps, 1000, w, &result, &error);
        Ck_array[ii] = result;
      }
    }