Esempio n. 1
0
typename Antioch::value_type<VectorScalar>::type k_photo(const VectorScalar &solar_lambda, const VectorScalar &solar_irr, 
                                                         const VectorScalar &sigma_lambda, const VectorScalar &sigma_sigma)
{
  Antioch::SigmaBinConverter<VectorScalar> bin;
  VectorScalar sigma_rescaled(solar_lambda.size());
  bin.y_on_custom_grid(sigma_lambda,sigma_sigma,solar_lambda,sigma_rescaled);

  typename Antioch::value_type<VectorScalar>::type _k(0.L);
  for(unsigned int il = 0; il < solar_irr.size() - 1; il++)
  {
     _k += sigma_rescaled[il] * solar_irr[il] * (solar_lambda[il+1] - solar_lambda[il]);
  }

  return _k;
}
int tester()
{
  std::vector<Scalar> bin_ref_x,bin_ref_y;

  make_reference(bin_ref_x,bin_ref_y);

  Antioch::SigmaBinConverter<std::vector<Scalar> > bin;

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 10;

  int return_flag = 0;

  // 4 cases:
  //   - custom inside ref
  //   - ref inside custom
  //   - custom beyond only min ref
  //   - custom beyond only max ref
  for(unsigned int i = 0; i < 4; i++)
  {
    std::vector<Scalar> bin_custom_x, exact_sol_y;
    make_custom(i,bin_custom_x,exact_sol_y);
    std::vector<Scalar> bin_custom_y(bin_custom_x.size());

    bin.y_on_custom_grid(bin_ref_x,bin_ref_y,
                         bin_custom_x,bin_custom_y);


    for(unsigned int il = 0; il < bin_custom_x.size() - 1; il++)
    {
      const Scalar dist = (exact_sol_y[il] < tol)?std::abs(bin_custom_y[il] - exact_sol_y[il]):std::abs(bin_custom_y[il] - exact_sol_y[il])/exact_sol_y[il];
      if( dist > tol )
      {
        std::cout << std::scientific << std::setprecision(16)
                  << "Error: Mismatch in bin values."                                                  << std::endl
                  << "case ("            << bin_custom_x[il]   << ";"   << bin_custom_x[il+1]   << ")" << std::endl 
                  << "bin = "            << bin_custom_y[il]                                           << std::endl
                  << "bin_exact = "      << exact_sol_y[il]                                            << std::endl
                  << "relative error = " << dist                                                       << std::endl
                  << "tolerance = "      << tol                                                        << std::endl;

        return_flag = 1;
      }
    }
  }

  return return_flag;
}
int vectester(const PairScalars& example, const std::string& testname)
{
  typedef typename Antioch::value_type<PairScalars>::type Scalar;

  std::vector<Scalar> bin_ref_x,bin_ref_y;

  make_reference(bin_ref_x,bin_ref_y);

  Antioch::SigmaBinConverter<std::vector<Scalar> > bin;

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 10;

  int return_flag = 0;

#ifdef ANTIOCH_HAVE_GRVY
  gt.BeginTimer(testname);
#endif

  // 2 * 2  cases:
  //   - custom inside ref, ref inside custom
  //   - custom beyond only min ref, custom beyond only max ref
  for(unsigned int i = 0; i < 2; i++)
  {
    std::vector<PairScalars> bin_custom_x, exact_sol_y;
    make_custom(i,example,bin_custom_x,exact_sol_y);
    std::vector<PairScalars> bin_custom_y(bin_custom_x.size(),Antioch::zero_clone(bin_custom_x[0]));

    bin.y_on_custom_grid(bin_ref_x,bin_ref_y,
                         bin_custom_x,bin_custom_y);


    for(unsigned int il = 0; il < bin_custom_x.size() - 1; il++)
    {
      for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
      {
//tuple

        Scalar dist = Antioch::if_else(exact_sol_y[il][2*tuple] < tol,
                                                std::abs(bin_custom_y[il][2*tuple] - exact_sol_y[il][2*tuple]),
                                                std::abs(bin_custom_y[il][2*tuple] - exact_sol_y[il][2*tuple])/exact_sol_y[il][2*tuple]);
        if( dist > tol )
        {
         std::cout << std::scientific << std::setprecision(16)
                   << "Error: Mismatch in bin values for " << testname                                                      << std::endl
                   << "case ("            << bin_custom_x[il][2*tuple]   << ";"   << bin_custom_x[il + 1][2*tuple]   << ")" << std::endl 
                   << "bin = "            << bin_custom_y[il][2*tuple]                                                      << std::endl
                   << "bin_exact = "      << exact_sol_y[il][2*tuple]                                                       << std::endl
                   << "relative error = " << dist                                                                           << std::endl
                   << "tolerance = "      << tol                                                                            << std::endl;

         return_flag = 1;
        }

//tuple + 1
        dist = Antioch::if_else(exact_sol_y[il][2*tuple + 1] < tol,
                                                std::abs(bin_custom_y[il][2*tuple + 1] - exact_sol_y[il][2*tuple + 1]),
                                                std::abs(bin_custom_y[il][2*tuple + 1] - exact_sol_y[il][2*tuple + 1])/exact_sol_y[il][2*tuple + 1]);
        if( dist > tol )
        {
         std::cout << std::scientific << std::setprecision(16)
                   << "Error: Mismatch in bin values for " << testname                                                      << std::endl
                   << "case ("            << bin_custom_x[il][2*tuple + 1]   << ";"   << bin_custom_x[il+1][2*tuple + 1]   << ")" << std::endl 
                   << "bin = "            << bin_custom_y[il][2*tuple + 1]                                                        << std::endl
                   << "bin_exact = "      << exact_sol_y[il][2*tuple + 1]                                                         << std::endl
                   << "relative error = " << dist                                                                                 << std::endl
                   << "tolerance = "      << tol                                                                                  << std::endl;

         return_flag = 1;
        }


      }
    }
  }

#ifdef ANTIOCH_HAVE_GRVY
  gt.EndTimer(testname);
#endif

  return return_flag;
}
int tester(std::string path_to_files)
{
  std::ifstream CH4(path_to_files + "/CH4_hv_cs.dat");
  std::ifstream  hv(path_to_files + "/solar_flux.dat");

  std::string first_line;

  getline(CH4,first_line);
  getline(hv,first_line);

  std::vector<Scalar> CH4_cs;
  std::vector<Scalar> CH4_lambda;
  std::vector<Scalar> hv_irr;
  std::vector<Scalar> hv_lambda;

  while(!CH4.eof())
  {
    Scalar cs,l;
    CH4 >> l >> cs;
    CH4_lambda.push_back(l);
    CH4_cs.push_back(cs);
    if(CH4_lambda.size() == 137)break;
  }
  CH4.close();

  while(!hv.eof())
  {
    Scalar w,l,dw;
    hv >> l >> w >> dw;
    hv_lambda.push_back(l * 10.L); //nm -> Angström
    hv_irr.push_back(w * 1e-4L  // * 1e-4: m-2 -> cm-2 
                       / (Antioch::Constants::Planck_constant<Scalar>() * Antioch::Constants::light_celerity<Scalar>() / l)// /(h*c/lambda): energy -> number of photons
                       / 10.); // by Angström
    if(hv_lambda.size() == 796)break;
  }
  hv.close();

  Scalar T(1500.L);

  Antioch::PhotochemicalRate<Scalar, std::vector<Scalar> > rate_hv(CH4_cs,CH4_lambda);

  Antioch::SigmaBinConverter<std::vector<Scalar> > bin;
  std::vector<Scalar> sigma_rescaled;
  bin.y_on_custom_grid(CH4_lambda,CH4_cs,hv_lambda,sigma_rescaled);

  rate_hv.calculate_rate_constant(hv_irr, hv_lambda);
  Scalar rate = rate_hv.rate(T);

  const Scalar tol = std::numeric_limits<Scalar>::epsilon() * 100;
  Scalar rate_exact(0.L);

  for(unsigned int il = 0; il < hv_lambda.size() - 1; il++)
  {
      rate_exact += sigma_rescaled[il] * hv_irr[il] * (hv_lambda[il+1] - hv_lambda[il]);
  }

  int return_flag = (rate_exact == Scalar(0.L));
  if(return_flag)std::cout << "Error: rate is null" << std::endl;
  if( std::abs( (rate - rate_exact)/rate_exact ) > tol )
  {
    std::cout << std::scientific << std::setprecision(16)
              << "Error: Mismatch in rate values."     << std::endl
              << "rate = "           << rate           << std::endl
              << "rate_exact = "     << rate_exact     << std::endl
              << "relative error = " << std::abs(rate_exact - rate)/rate_exact << std::endl
              << "tolerance = "      << tol            << std::endl;

    return_flag = 1;
  }

  return return_flag;
}