예제 #1
0
int main(int argc, char* argv[])
{
    // Check command line count.
    if( argc < 2 )
    {
        // TODO: Need more consistent error handling.
        std::cerr << "Error: Must specify reaction set XML input file." << std::endl;
        antioch_error();
    }

    int returnval = 0;

    returnval +=
        vectester (argv[1], std::valarray<float>(2*ANTIOCH_N_TUPLES), "valarray<float>");
    returnval +=
        vectester (argv[1], std::valarray<double>(2*ANTIOCH_N_TUPLES), "valarray<double>");
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester (argv[1], std::valarray<long double>(2*ANTIOCH_N_TUPLES), "valarray<ld>");
#ifdef ANTIOCH_HAVE_EIGEN
    returnval +=
        vectester (argv[1], Eigen::Array<float, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXf");
    returnval +=
        vectester (argv[1], Eigen::Array<double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXd");
// We're not getting the full long double precision yet?
//  returnval = returnval ||
//    vectester (argv[1], Eigen::Array<long double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXld");
#endif
#ifdef ANTIOCH_HAVE_METAPHYSICL
    returnval +=
        vectester (argv[1], MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, float> (0), "NumberArray<float>");
    returnval +=
        vectester (argv[1], MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, double> (0), "NumberArray<double>");
//  returnval = returnval ||
//    vectester (argv[1], MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, long double> (0), "NumberArray<ld>");
#endif
#ifdef ANTIOCH_HAVE_VEXCL
    vex::Context ctx_f (vex::Filter::All);
    if (!ctx_f.empty())
        returnval = returnval ||
                    vectester (argv[1], vex::vector<float> (ctx_f, 2*ANTIOCH_N_TUPLES), "vex::vector<float>");

    vex::Context ctx_d (vex::Filter::DoublePrecision);
    if (!ctx_d.empty())
        returnval = returnval ||
                    vectester (argv[1], vex::vector<double> (ctx_d, 2*ANTIOCH_N_TUPLES), "vex::vector<double>");
#endif

    std::cout << "Found " << returnval << " errors" << std::endl;

#ifdef ANTIOCH_HAVE_GRVY
    gt.Finalize();
    gt.Summarize();
#endif

    return (returnval != 0) ? 1 : 0;
}
예제 #2
0
int main()
{
  int returnval = 0;

#ifdef ANTIOCH_HAVE_GSL

  returnval = returnval ||
    vectester (std::valarray<float>(2*ANTIOCH_N_TUPLES), "valarray<float>");
  returnval = returnval ||
    vectester (std::valarray<double>(2*ANTIOCH_N_TUPLES), "valarray<double>");
  returnval = returnval ||
    vectester (std::valarray<long double>(2*ANTIOCH_N_TUPLES), "valarray<ld>");
#ifdef ANTIOCH_HAVE_EIGEN
  returnval = returnval ||
    vectester (Eigen::Array<float, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXf");
  returnval = returnval ||
    vectester (Eigen::Array<double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXd");
  returnval = returnval ||
    vectester (Eigen::Array<long double, 2*ANTIOCH_N_TUPLES, 1>(), "Eigen::ArrayXld");
#endif
#ifdef ANTIOCH_HAVE_METAPHYSICL
  returnval = returnval ||
    vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, float> (0), "NumberArray<float>");
  returnval = returnval ||
    vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, double> (0), "NumberArray<double>");
  returnval = returnval ||
    vectester (MetaPhysicL::NumberArray<2*ANTIOCH_N_TUPLES, long double> (0), "NumberArray<ld>");
#endif
#ifdef ANTIOCH_HAVE_VEXCL
  vex::Context ctx_f (vex::Filter::All);
  if (!ctx_f.empty())
    returnval = returnval ||
      vectester (vex::vector<float> (ctx_f, 2*ANTIOCH_N_TUPLES), "vex::vector<float>");

  vex::Context ctx_d (vex::Filter::DoublePrecision);
  if (!ctx_d.empty())
    returnval = returnval ||
      vectester (vex::vector<double> (ctx_d, 2*ANTIOCH_N_TUPLES), "vex::vector<double>");
#endif

#ifdef ANTIOCH_HAVE_GRVY
  gt.Finalize();
  gt.Summarize();
#endif

#else // ANTIOCH_HAVE_GSL
  // 77 return code tells Automake we skipped this.
  returnval = 77;
#endif

  return returnval;
}
예제 #3
0
int vectester(const PairScalars& example, const std::string& testname)
{
  typedef typename Antioch::value_type<PairScalars>::type Scalar;

  const unsigned int n_data(40);

  std::vector<Scalar> x_ref(n_data,0),y_ref(n_data,0);

  const Scalar min = -5L;
  const Scalar max = 8L;
  fill_ref(x_ref,y_ref,n_data,min, max);

  Antioch::GSLSpliner gsl_spline(x_ref,y_ref);

  // Construct from example to avoid resizing issues
  PairScalars x = example;
  for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
      x[2*tuple]   = -3.5;
      x[2*tuple+1] = 5.1;
    }

  int return_flag = 0;

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

  const PairScalars gsl = gsl_spline.interpolated_value(x);

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

    const PairScalars exact = function(x);
    for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
      {
          return_flag = check_value<Scalar>(exact[2*tuple],   gsl[2*tuple],   x[2*tuple],   "gsl vectorized") || return_flag;
          return_flag = check_value<Scalar>(exact[2*tuple+1], gsl[2*tuple+1], x[2*tuple+1], "gsl vectorized") || return_flag;
      }
  return return_flag;
}
예제 #4
0
int vectester(const PairScalars& example, const std::string& testname)
{
    typedef typename Antioch::value_type<PairScalars>::type Scalar;

    std::vector<std::string> species_str_list;
    const unsigned int n_species = 2;
    species_str_list.reserve(n_species);
    species_str_list.push_back( "N2" );
    species_str_list.push_back( "Air" ); // Yes, I know this doesn't make sense, it's just a test.

    Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );

    Antioch::MixtureViscosity<Antioch::SutherlandViscosity<Scalar>,Scalar> s_mu_mixture(chem_mixture);

    Antioch::MixtureViscosity<Antioch::BlottnerViscosity<Scalar>,Scalar> b_mu_mixture(chem_mixture);

    Antioch::read_sutherland_data_ascii_default<Scalar>( s_mu_mixture );
    Antioch::read_blottner_data_ascii_default<Scalar>( b_mu_mixture );

    std::cout << s_mu_mixture << std::endl;
    std::cout << b_mu_mixture << std::endl;

    PairScalars T = example;
    for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
        T[2*tuple  ] = 1500.1;
        T[2*tuple+1] = 1600.1;
    }

    PairScalars mu = example;

    std::cout << "Blottner:" << std::endl;
    for( unsigned int s = 0; s < n_species; s++ )
    {
#ifdef ANTIOCH_HAVE_GRVY
        const std::string testblottner = testname + "-blottner";
        gt.BeginTimer(testblottner);
#endif

        mu = b_mu_mixture(s,T);

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

        std::cout << "mu(" << species_str_list[s] << ") = " << mu << std::endl;
    }

    std::cout << "Sutherland:" << std::endl;
    for( unsigned int s = 0; s < n_species; s++ )
    {
#ifdef ANTIOCH_HAVE_GRVY
        const std::string testsutherland = testname + "-sutherland";
        gt.BeginTimer(testsutherland);
#endif

        mu = s_mu_mixture(s,T);

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

        std::cout << "mu(" << species_str_list[s] << ") = " << mu << std::endl;
    }

    int return_flag = 0;

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

    std::vector<std::string> species_str_list;
    species_str_list.reserve(n_species);
    species_str_list.push_back( "N2" );
    species_str_list.push_back( "O2" );
    species_str_list.push_back( "N" );
    species_str_list.push_back( "O" );
    species_str_list.push_back( "NO" );

    Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );
    Antioch::ReactionSet<Scalar> reaction_set( chem_mixture );
    Antioch::CEAThermodynamics<Scalar> thermo( chem_mixture );

    Antioch::read_reaction_set_data_xml<Scalar>( input_name, true, reaction_set );

    PairScalars T = example;
    PairScalars P = example;

    // Mass fractions
    PairScalars massfrac = example;

    for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
        T[2*tuple  ] = 1500.0;
        T[2*tuple+1] = 1500.0;

        P[2*tuple  ] = 1.0e5;
        P[2*tuple+1] = 1.0e5;

        massfrac[2*tuple  ] = 0.2;
        massfrac[2*tuple+1] = 0.2;
    }

    const std::vector<PairScalars> Y(n_species,massfrac);
    std::vector<PairScalars> molar_densities(n_species, example);
    std::vector<PairScalars> h_RT_minus_s_R(n_species, example);
    std::vector<PairScalars> dh_RT_minus_s_R_dT(n_species, example);

    Antioch::KineticsEvaluator<Scalar,PairScalars> kinetics( reaction_set, example );

    std::vector<PairScalars> omega_dot(n_species, example);
    std::vector<PairScalars> omega_dot_2(n_species, example);
    std::vector<PairScalars> domega_dot_dT(n_species, example);

    std::vector<std::vector<PairScalars> > domega_dot_drhos
    (n_species, omega_dot); // omega_dot is a good example vec<Pair>


#ifdef ANTIOCH_HAVE_GRVY
    const std::string testnormal = testname + "-normal";
    gt.BeginTimer(testnormal);
#endif

    const PairScalars R_mix = chem_mixture.R(Y);

    const PairScalars rho = P/(R_mix*T);

    chem_mixture.molar_densities(rho,Y,molar_densities);

    typedef typename Antioch::CEAThermodynamics<Scalar>::
    template Cache<PairScalars> Cache;
    thermo.h_RT_minus_s_R(Cache(T),h_RT_minus_s_R);
    thermo.dh_RT_minus_s_R_dT(Cache(T),dh_RT_minus_s_R_dT);

    kinetics.compute_mass_sources( T, molar_densities, h_RT_minus_s_R, omega_dot );

    kinetics.compute_mass_sources_and_derivs ( T,
            molar_densities,
            h_RT_minus_s_R,
            dh_RT_minus_s_R_dT,
            omega_dot_2,
            domega_dot_dT,
            domega_dot_drhos );

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

    int return_flag = 0;

#ifdef ANTIOCH_HAVE_EIGEN
    {
        typedef Eigen::Array<PairScalars,n_species,1> SpeciesVecEigenType;

#ifdef ANTIOCH_HAVE_GRVY
        const std::string testeigenA = testname + "-eigenA";
        gt.BeginTimer(testeigenA);
#endif

        SpeciesVecEigenType eigen_Y;
        Antioch::init_constant(eigen_Y, massfrac);

        SpeciesVecEigenType eigen_molar_densities;
        Antioch::init_constant(eigen_molar_densities, example);

        SpeciesVecEigenType eigen_h_RT_minus_s_R;
        Antioch::init_constant(eigen_h_RT_minus_s_R, example);

        SpeciesVecEigenType eigen_dh_RT_minus_s_R_dT;
        Antioch::init_constant(eigen_dh_RT_minus_s_R_dT, example);

        SpeciesVecEigenType eigen_omega_dot;
        Antioch::init_constant(eigen_omega_dot, example);

        SpeciesVecEigenType eigen_domega_dot_dT;
        Antioch::init_constant(eigen_domega_dot_dT, example);

        // FIXME: What to do for domega_dot_drhos type?

        const PairScalars eigen_R = chem_mixture.R(eigen_Y);
        chem_mixture.molar_densities(rho,eigen_Y,eigen_molar_densities);

        thermo.h_RT_minus_s_R(Cache(T),eigen_h_RT_minus_s_R);

        thermo.dh_RT_minus_s_R_dT(Cache(T),eigen_dh_RT_minus_s_R_dT);

        kinetics.compute_mass_sources( T, eigen_molar_densities, eigen_h_RT_minus_s_R, eigen_omega_dot );

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

        return_flag +=
            vec_compare(eigen_R,R_mix,"eigen_R");

        return_flag +=
            vec_compare(eigen_molar_densities, molar_densities,
                        "eigen_molar_densities");

        return_flag +=
            vec_compare(eigen_h_RT_minus_s_R, h_RT_minus_s_R,
                        "eigen_h_RT_minus_s_R");

        return_flag +=
            vec_compare(eigen_dh_RT_minus_s_R_dT, dh_RT_minus_s_R_dT,
                        "eigen_dh_RT_minus_s_R_dT");

        return_flag +=
            vec_compare(eigen_omega_dot,omega_dot,"eigen_omega_dot");
    }

    {
        typedef Eigen::Matrix<PairScalars,Eigen::Dynamic,1> SpeciesVecEigenType;
        SpeciesVecEigenType eigen_Y(n_species,1);
        Antioch::init_constant(eigen_Y, massfrac);

        SpeciesVecEigenType eigen_molar_densities(n_species,1);
        Antioch::init_constant(eigen_molar_densities, example);

        SpeciesVecEigenType eigen_h_RT_minus_s_R(n_species,1);
        Antioch::init_constant(eigen_h_RT_minus_s_R, example);

        SpeciesVecEigenType eigen_dh_RT_minus_s_R_dT(n_species,1);
        Antioch::init_constant(eigen_dh_RT_minus_s_R_dT, example);

        SpeciesVecEigenType eigen_omega_dot(n_species,1);
        Antioch::init_constant(eigen_omega_dot, example);

        SpeciesVecEigenType eigen_domega_dot_dT(n_species,1);
        Antioch::init_constant(eigen_domega_dot_dT, example);

        // FIXME: What to do for domega_dot_drhos type?

#ifdef ANTIOCH_HAVE_GRVY
        const std::string testeigenV = testname + "-eigenV";
        gt.BeginTimer(testeigenV);
#endif

        const PairScalars eigen_R = chem_mixture.R(eigen_Y);

        chem_mixture.molar_densities(rho,eigen_Y,eigen_molar_densities);

        thermo.h_RT_minus_s_R(Cache(T),eigen_h_RT_minus_s_R);

        thermo.dh_RT_minus_s_R_dT(Cache(T),eigen_dh_RT_minus_s_R_dT);

        kinetics.compute_mass_sources( T, eigen_molar_densities, eigen_h_RT_minus_s_R, eigen_omega_dot );

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

        return_flag +=
            vec_compare(eigen_R,R_mix,"eigen_R");

        return_flag +=
            vec_compare(eigen_molar_densities, molar_densities,
                        "eigen_molar_densities");

        return_flag +=
            vec_compare(eigen_h_RT_minus_s_R, h_RT_minus_s_R,
                        "eigen_h_RT_minus_s_R");

        return_flag +=
            vec_compare(eigen_dh_RT_minus_s_R_dT, dh_RT_minus_s_R_dT,
                        "eigen_dh_RT_minus_s_R_dT");

        return_flag +=
            vec_compare(eigen_omega_dot,omega_dot,"eigen_omega_dot");
    }

#endif // ANTIOCH_HAVE_EIGEN

    for( unsigned int s = 0; s < n_species; s++)
    {
        std::cout << std::scientific << std::setprecision(16)
                  << "omega_dot(" << chem_mixture.chemical_species()[s]->species() << ") = "
                  << omega_dot[s] << std::endl;
    }

    for( unsigned int s = 0; s < n_species; s++)
    {
        std::cout << std::scientific << std::setprecision(16)
                  << "domega_dot_dT(" << chem_mixture.chemical_species()[s]->species() << ") = "
                  << domega_dot_dT[s] << std::endl;
    }

    for( unsigned int s = 0; s < n_species; s++)
    {
        for( unsigned int t = 0; t < n_species; t++)
        {
            std::cout << std::scientific << std::setprecision(16)
                      << "domega_dot_drhos(" << chem_mixture.chemical_species()[s]->species()
                      << ", " << chem_mixture.chemical_species()[t]->species() << ") = "
                      << domega_dot_drhos[s][t] << std::endl;
        }
    }

    // Regression values for omega_dot
    std::vector<PairScalars> omega_dot_reg(n_species,example);

    // Regression values for domega_dot_drhos
    std::vector<std::vector<PairScalars> > domega_dot_drhos_reg
    (n_species, omega_dot); // omega_dot is the right size for an example

    // Regression values for domega_dot_dT
    std::vector<PairScalars> domega_dot_dT_reg(n_species, example);

    for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
        omega_dot_reg[0][2*tuple  ] =  9.1627505878744108e+04;
        omega_dot_reg[1][2*tuple  ] = -3.3462516012726480e+05;
        omega_dot_reg[2][2*tuple  ] = -2.1139750128059302e+05;
        omega_dot_reg[3][2*tuple  ] =  1.9782333785216609e+05;
        omega_dot_reg[4][2*tuple  ] =  2.5657181767694763e+05;
        omega_dot_reg[0][2*tuple+1] = Scalar(omega_dot_reg[0][0]);
        omega_dot_reg[1][2*tuple+1] = Scalar(omega_dot_reg[1][0]);
        omega_dot_reg[2][2*tuple+1] = Scalar(omega_dot_reg[2][0]);
        omega_dot_reg[3][2*tuple+1] = Scalar(omega_dot_reg[3][0]);
        omega_dot_reg[4][2*tuple+1] = Scalar(omega_dot_reg[4][0]);

        domega_dot_dT_reg[0][2*tuple  ] =  1.8015258435766250e+02;
        domega_dot_dT_reg[1][2*tuple  ] = -5.2724938565430807e+02;
        domega_dot_dT_reg[2][2*tuple  ] = -3.0930274177637205e+02;
        domega_dot_dT_reg[3][2*tuple  ] =  3.7973350053870610e+02;
        domega_dot_dT_reg[4][2*tuple  ] =  2.7666604253431154e+02;
        domega_dot_dT_reg[0][2*tuple+1] = Scalar(domega_dot_dT_reg[0][0]);
        domega_dot_dT_reg[1][2*tuple+1] = Scalar(domega_dot_dT_reg[1][0]);
        domega_dot_dT_reg[2][2*tuple+1] = Scalar(domega_dot_dT_reg[2][0]);
        domega_dot_dT_reg[3][2*tuple+1] = Scalar(domega_dot_dT_reg[3][0]);
        domega_dot_dT_reg[4][2*tuple+1] = Scalar(domega_dot_dT_reg[4][0]);

        domega_dot_drhos_reg[0][0][2*tuple  ] = 1.9677528466713775e+04;
        domega_dot_drhos_reg[0][1][2*tuple  ] = 1.7227676257862015e+04;
        domega_dot_drhos_reg[0][2][2*tuple  ] = 3.2160890543181915e+06;
        domega_dot_drhos_reg[0][3][2*tuple  ] = 1.4766530417926086e+05;
        domega_dot_drhos_reg[0][4][2*tuple  ] = 2.3225848421202623e+06;

        domega_dot_drhos_reg[1][0][2*tuple  ] =  8.8931540715994815e+03;
        domega_dot_drhos_reg[1][1][2*tuple  ] = -9.9561695971970223e+06;
        domega_dot_drhos_reg[1][2][2*tuple  ] = -9.8750240128648076e+06;
        domega_dot_drhos_reg[1][3][2*tuple  ] =  4.6145192628627969e+05;
        domega_dot_drhos_reg[1][4][2*tuple  ] =  8.3491261619680736e+03;

        domega_dot_drhos_reg[2][0][2*tuple  ] = -2.2422758857735978e+04;
        domega_dot_drhos_reg[2][1][2*tuple  ] = -4.3813526690025711e+06;
        domega_dot_drhos_reg[2][2][2*tuple  ] = -6.8345704383742884e+06;
        domega_dot_drhos_reg[2][3][2*tuple  ] = -5.4147327282847988e+05;
        domega_dot_drhos_reg[2][4][2*tuple  ] = -1.2268436930952054e+06;

        domega_dot_drhos_reg[3][0][2*tuple  ] = -1.2028768453121129e+04;
        domega_dot_drhos_reg[3][1][2*tuple  ] =  4.9714465900642881e+06;
        domega_dot_drhos_reg[3][2][2*tuple  ] =  5.7419784571182663e+06;
        domega_dot_drhos_reg[3][3][2*tuple  ] = -9.1126114233336027e+05;
        domega_dot_drhos_reg[3][4][2*tuple  ] =  1.2432112953400959e+06;

        domega_dot_drhos_reg[4][0][2*tuple  ] =  5.8808447725438464e+03;
        domega_dot_drhos_reg[4][1][2*tuple  ] =  9.3488479998774435e+06;
        domega_dot_drhos_reg[4][2][2*tuple  ] =  7.7515269398026383e+06;
        domega_dot_drhos_reg[4][3][2*tuple  ] =  8.4361718469629961e+05;
        domega_dot_drhos_reg[4][4][2*tuple  ] = -2.3473015705271205e+06;

        for (unsigned int i = 0; i != 5; ++i)
            for (unsigned int j = 0; j != 5; ++j)
                domega_dot_drhos_reg[i][j][2*tuple+1] =
                    Scalar(domega_dot_drhos_reg[i][j][2*tuple  ]);
    }

    return_flag +=
        vec_compare(omega_dot, omega_dot_reg, "omega_dot");

    return_flag +=
        vec_compare(omega_dot_2, omega_dot_reg, "omega_dot_2");

    return_flag +=
        vec_compare(domega_dot_dT, domega_dot_dT_reg, "domega_dot_dT");

    char vecname[] = "domega_dot_drho_0";
    for (unsigned int i = 0; i != 5; ++i)
    {
        return_flag +=
            vec_compare(domega_dot_drhos[i], domega_dot_drhos_reg[i], vecname);

        // Should b=e safe to assume "1"+1 = "2" etc.
        ++vecname[16];
    }

    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 vectester(const PairScalars& example, const std::string& testname)
{

  typedef typename Antioch::value_type<PairScalars>::type Scalar;

  std::vector<std::string> species_str_list;
  const unsigned int n_species = 1;
  species_str_list.reserve(n_species);
  species_str_list.push_back( "N2" );

  const Scalar LJ_depth_N2 = 97.53L;
  const Scalar Z_298 = 4.0L;

  Antioch::ChemicalMixture<Scalar> chem_mixture( species_str_list );

  Antioch::StatMechThermodynamics<Scalar> thermo( chem_mixture );

  Antioch::KineticsTheoryThermalConductivity<Antioch::StatMechThermodynamics<Scalar>, Scalar > k( thermo, Z_298, LJ_depth_N2);

  // Construct from example to avoid resizing issues
  PairScalars mu  = example;
  PairScalars dss = example;
  PairScalars rho = example;
  PairScalars T = example;
  for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
      T[2*tuple]     = 1500.1;
      T[2*tuple+1]   = 1600.1;
      mu[2*tuple]    = 3.14e-3;
      mu[2*tuple+1]  = 3.14e-3;
      dss[2*tuple]   = 5.23e-5;
      dss[2*tuple+1] = 5.23e-5;
      rho[2*tuple]   = 1.4;
      rho[2*tuple+1] = 1.4;
    }
  
  const Scalar k_exact0 = 3.19434291925996020233442116364270671873509961381739235964650684;
  const Scalar k_exact1 = 3.2021908709042895344166123247634817043607657971633006497668;

  int return_flag = 0;

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

  const PairScalars k_ps = k(0,mu,T,rho,dss);

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

  const Scalar tol = (std::numeric_limits<Scalar>::epsilon()*10 < 7e-17)?
                        7e-17:
                        std::numeric_limits<Scalar>::epsilon()*10;

  for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {

      return_flag = test_k( k_ps[2*tuple], k_exact0, tol ) || return_flag;
      return_flag = test_k( k_ps[2*tuple+1], k_exact1, tol ) || return_flag;
    }

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

  const Scalar a = 3.14e-3L;
  const Scalar b = 2.71e-2L;
  const Scalar c = 42.0e-5L;

  Antioch::BlottnerViscosity<Scalar> mu(a,b,c);

  std::cout << mu << std::endl;

  PairScalars T = example;
  PairScalars mu_exact = example;
  PairScalars mu_exact2 = example;

  for (unsigned int tuple=0; tuple != ANTIOCH_N_TUPLES; ++tuple)
    {
      T[2*tuple]   = 1521.2L;
      T[2*tuple+1] = 1621.2L;

      // bc gives
      mu_exact[2*tuple]   = 0.1444222341677025337305172031086891L;
      mu_exact[2*tuple+1] = 0.1450979382180072302532592937776388L;

      mu_exact2[2*tuple]   = .1221724955488799960527696821225472L;
      mu_exact2[2*tuple+1] = .1224428450807678499433510473203746L;
    }

  int return_flag = 0;

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

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

  const PairScalars mu_T = mu(T);

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

  return_flag = test_viscosity( mu_T, mu_exact, tol, testname );
  
  const Scalar a2 = 1e-3L;
  const Scalar b2 = 2e-2L;
  const Scalar c2 = 3e-5L;

  mu.reset_coeffs( a2, b2, c2 );

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

  const PairScalars mu2_T = mu(T);

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

  return_flag = test_viscosity( mu2_T, mu_exact2, tol, testname );

  return return_flag;
}