Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XML Parsing for TransportMixture #265

Merged
merged 5 commits into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/parsing/include/antioch/parsing_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ namespace Antioch
TROE_F_ALPHA,
TROE_F_TS,
TROE_F_TSS,
TROE_F_TSSS
TROE_F_TSSS,
//
TRANSPORT,
LJ_WELLDEPTH,
LJ_DIAMETER,
DIPOLE_MOMENT,
POLARIZABILITY,
ROT_RELAX
};

// GRI30 compatibility
Expand Down
10 changes: 10 additions & 0 deletions src/parsing/include/antioch/xml_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ namespace Antioch{
{antioch_error_msg("ERROR: XML Parsing only supports parsing for NASA7CurveFit and NASA9CurveFit!");}


virtual void read_transport_data(TransportMixture<NumericType> & transport_mixture);

/// reaction

/*! go to next reaction*/
Expand Down Expand Up @@ -235,6 +237,14 @@ namespace Antioch{

private:

//! Read the transport property given by the particular ParsingKey
/*! Currently, we don't support unit conversion for these properties,
so we just error out if the specified units aren't what we expected. */
NumericType read_transport_property(const std::string & species_name,
tinyxml2::XMLElement * species_elem,
ParsingKey key,
const std::string & expected_unit);

//! reads the thermo, NASA generalist
template <typename ThermoType>
void read_thermodynamic_data_root(ThermoType & thermo);
Expand Down
107 changes: 107 additions & 0 deletions src/parsing/src/xml_parser.C
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "antioch/nasa_mixture.h"
#include "antioch/cea_curve_fit.h"
#include "antioch/nasa7_curve_fit.h"
#include "antioch/transport_mixture.h"

//XML
#include "antioch/tinyxml2_imp.h"
Expand Down Expand Up @@ -132,6 +133,14 @@ namespace Antioch
_map[ParsingKey::TROE_F_TSS] = "T2";
_map[ParsingKey::TROE_F_TSSS] = "T3";

// Transport
_map[ParsingKey::TRANSPORT] = "transport";
_map[ParsingKey::LJ_WELLDEPTH] = "LJ_welldepth";
_map[ParsingKey::LJ_DIAMETER] = "LJ_diameter";
_map[ParsingKey::DIPOLE_MOMENT] = "dipoleMoment";
_map[ParsingKey::POLARIZABILITY] = "polarizability";
_map[ParsingKey::ROT_RELAX] = "rotRelax";

// typically Cantera files list
// pre-exponential parameters in (m3/kmol)^(m-1)/s
// activation energy in cal/mol, but we want it in K.
Expand Down Expand Up @@ -993,7 +1002,105 @@ namespace Antioch
} // end species loop
}

template <typename NumericType>
void XMLParser<NumericType>::read_transport_data(TransportMixture<NumericType> & transport_mixture)
{
// The _thermo_block points to the beginning of the relevant speciesData section
if(!_thermo_block)
antioch_error_msg("ERROR: No "+_map.at(ParsingKey::SPECIES_DATA)+" section found! Cannot parse transport!");

const ChemicalMixture<NumericType> & chem_mixture = transport_mixture.chemical_mixture();
const std::vector<ChemicalSpecies<NumericType>*> & chem_species = chem_mixture.chemical_species();

// Step to first species block
tinyxml2::XMLElement * species_block =
_thermo_block->FirstChildElement(_map.at(ParsingKey::SPECIES).c_str());

if(!species_block)
antioch_error_msg("ERROR: No "+_map.at(ParsingKey::SPECIES)+" block found within "+_map.at(ParsingKey::SPECIES_DATA)+" section! Cannot parse transport!");

// Now go through each species in our mixture, parse the transport data and add the
// species to our transport mixture
for(unsigned int s = 0; s < chem_mixture.n_species(); s++)
{
const std::string & name = chem_species[s]->species();

tinyxml2::XMLElement * species = nullptr;
species = this->find_element_with_attribute( species_block,
_map.at(ParsingKey::SPECIES),
"name",
name );

if(!species)
antioch_error_msg("ERROR: Species "+name+" has not been found in the "+_map.at(ParsingKey::SPECIES_DATA)+" section! Cannot parse transport!");

species = species->FirstChildElement(_map.at(ParsingKey::TRANSPORT).c_str());

if(!species)
antioch_error_msg("ERROR: No "+_map.at(ParsingKey::TRANSPORT)+" block found for species "+name+"! Cannot parse transport!");

// The number of transport numbers we are reading
// 0 --> LJ_welldepth
// 1 --> LJ_diameter
// 2 --> dipoleMoment
// 3 --> polarizability
// 4 --> rotRelax
const unsigned int n_data = 5;
std::vector<NumericType> data(n_data);

data[0] = this->read_transport_property(name,species,ParsingKey::LJ_WELLDEPTH,"K");
data[1] = this->read_transport_property(name,species,ParsingKey::LJ_DIAMETER,"A");
data[2] = this->read_transport_property(name,species,ParsingKey::DIPOLE_MOMENT,"Debye");
data[3] = this->read_transport_property(name,species,ParsingKey::POLARIZABILITY,"A3");
data[4] = this->read_transport_property(name,species,ParsingKey::ROT_RELAX,"");

unsigned int species_idx = chem_mixture.species_name_map().at(name);
NumericType species_molar_mass = chem_mixture.M(species_idx);

transport_mixture.add_species(species_idx,data[0],data[1],data[2],data[3],data[4],species_molar_mass);
}
}

template <typename NumericType>
NumericType XMLParser<NumericType>::read_transport_property(const std::string & species_name,
tinyxml2::XMLElement * species_elem,
ParsingKey key,
const std::string & expected_unit)
{
antioch_assert(species_elem);

// Copy pointer so we don't muck where this is pointing
tinyxml2::XMLElement * data = species_elem;

data = species_elem->FirstChildElement(_map.at(key).c_str());

if(!data)
antioch_error_msg("ERROR: NO "+_map.at(key)+" block found for species "+species_name+"! Cannot parse transport!");

const char * unit = data->Attribute(_map.at(ParsingKey::UNIT).c_str());

// There's no unit, then either we're dimensionless (and expected_unit should be empty
// or it's an error because it's not supposed to be dimensionless
if(!unit)
{
if(!expected_unit.empty() )
antioch_error_msg("ERROR: No unit specified for "+_map.at(key)+" block for species "+species_name+", but expected a unit of "+expected_unit+"!\n");
}
else
{
std::string parsed_unit(data->Attribute(_map.at(ParsingKey::UNIT).c_str()));

if( expected_unit.empty() )
antioch_error_msg("ERROR: Unit of " " specified for "+_map.at(key)+" block for species "+species_name+", but expected a unit of "+expected_unit+"!\n");

if( parsed_unit != expected_unit )
antioch_error_msg("ERROR: Specified unit for "+_map.at(key)+" block for species "+species_name+" was "+parsed_unit+", but we expected units of "+expected_unit+"!\n");
}

NumericType value = string_to_T<NumericType>(data->GetText());

return value;
}

// Instantiate
ANTIOCH_NUMERIC_TYPE_CLASS_INSTANTIATE(XMLParser);
Expand Down
60 changes: 56 additions & 4 deletions test/standard_unit/gri30_xml_parsing_test.C
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "antioch/xml_parser.h"
#include "antioch/reaction_set.h"
#include "antioch/read_reaction_set_data.h"
#include "antioch/transport_mixture.h"

namespace AntiochTesting
{
Expand All @@ -36,10 +37,10 @@ namespace AntiochTesting

void test_gri30_xml()
{
std::string thermo_filename = std::string(ANTIOCH_SHARE_XML_INPUT_FILES_SOURCE_PATH)+"gri30.xml";
std::string filename = std::string(ANTIOCH_SHARE_XML_INPUT_FILES_SOURCE_PATH)+"gri30.xml";
const std::string phase("gri30_mix");

Antioch::XMLParser<Scalar> xml_parser(thermo_filename,phase,false);
Antioch::XMLParser<Scalar> xml_parser(filename,phase,false);
std::vector<std::string> species_str_list = xml_parser.species_list();

this->check_species_list(species_str_list);
Expand All @@ -51,12 +52,15 @@ namespace AntiochTesting
Antioch::NASAThermoMixture<Scalar, Antioch::NASA7CurveFit<Scalar> > nasa_mixture( chem_mixture );

//xml_parser.read_thermodynamic_data(nasa_mixture);
Antioch::read_nasa_mixture_data( nasa_mixture, thermo_filename, Antioch::XML );
Antioch::read_nasa_mixture_data( nasa_mixture, filename, Antioch::XML );
this->check_curve_fits(nasa_mixture);

Antioch::ReactionSet<Scalar> reaction_set( chem_mixture );
Antioch::read_reaction_set_data_xml<Scalar>(thermo_filename, true, reaction_set);
Antioch::read_reaction_set_data_xml<Scalar>(filename, true, reaction_set);
this->check_reaction_set(reaction_set);

Antioch::TransportMixture<Scalar> trans_mixture( chem_mixture, &xml_parser );
this->check_transport_mixture(trans_mixture);
}

void check_species_list(const std::vector<std::string> & species_list)
Expand Down Expand Up @@ -253,6 +257,54 @@ namespace AntiochTesting

}

void check_transport_mixture( const Antioch::TransportMixture<Scalar> & trans_mixture )
{
CPPUNIT_ASSERT_EQUAL( (int)_species_exact.size(), (int)trans_mixture.n_species() );


// H2
{
const Antioch::TransportSpecies<Scalar> & trans_species =
trans_mixture.transport_species(_H2_species_id);

CPPUNIT_ASSERT_DOUBLES_EQUAL(38.000, trans_species.LJ_depth(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(2.920, trans_species.LJ_diameter(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(0., trans_species.dipole_moment(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.790, trans_species.polarizability(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(280.000, trans_species.rotational_relaxation(), this->tol() );

}

// N2
{
const Antioch::TransportSpecies<Scalar> & trans_species =
trans_mixture.transport_species(_N2_species_id);

// For floats, we don't get padded zeros, so we lose a little tolerance in the test
CPPUNIT_ASSERT_DOUBLES_EQUAL(97.530, trans_species.LJ_depth(), this->tol()*2 );

CPPUNIT_ASSERT_DOUBLES_EQUAL(3.620, trans_species.LJ_diameter(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(0., trans_species.dipole_moment(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(1.760, trans_species.polarizability(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(4., trans_species.rotational_relaxation(), this->tol() );
}

// HCNO
{
const Antioch::TransportSpecies<Scalar> & trans_species =
trans_mixture.transport_species(_HCNO_species_id);

// For floats, we don't get padded zeros, so we lose a little tolerance in the test
CPPUNIT_ASSERT_DOUBLES_EQUAL(232.4, trans_species.LJ_depth(), this->tol()*10 );

CPPUNIT_ASSERT_DOUBLES_EQUAL(3.83, trans_species.LJ_diameter(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(0., trans_species.dipole_moment(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(0., trans_species.polarizability(), this->tol() );
CPPUNIT_ASSERT_DOUBLES_EQUAL(1., trans_species.rotational_relaxation(), this->tol() );
}

}

protected:

std::vector<std::string> _species_exact;
Expand Down