예제 #1
0
Phase& Phase::operator=(const Phase& right)
{
    // Check for self assignment.
    if (this == &right) {
        return *this;
    }

    // Handle our own data
    m_kk = right.m_kk;
    m_ndim = right.m_ndim;
    m_undefinedElementBehavior = right.m_undefinedElementBehavior;
    m_temp = right.m_temp;
    m_dens = right.m_dens;
    m_mmw = right.m_mmw;
    m_ym = right.m_ym;
    m_y = right.m_y;
    m_molwts = right.m_molwts;
    m_rmolwts = right.m_rmolwts;
    m_stateNum = -1;

    m_speciesNames = right.m_speciesNames;
    m_speciesComp = right.m_speciesComp;
    m_speciesCharge = right.m_speciesCharge;
    m_speciesSize = right.m_speciesSize;
    m_mm = right.m_mm;
    m_atomicWeights = right.m_atomicWeights;
    m_atomicNumbers = right.m_atomicNumbers;
    m_elementNames = right.m_elementNames;
    m_entropy298 = right.m_entropy298;
    m_elem_type = right.m_elem_type;

    // This is a little complicated. -> Because we delete m_xml in the
    // destructor, we own m_xml completely, and we need to have our own
    // individual copies of the XML data tree in each object
    if (m_xml) {
        XML_Node* rroot = &m_xml->root();
        delete rroot;
        m_xml = 0;
    }
    if (right.m_xml) {
        XML_Node *rroot = &right.m_xml->root();
        XML_Node *root_xml = new XML_Node();
        rroot->copy(root_xml);
        m_xml = findXMLPhase(root_xml, right.m_xml->id());
        if (!m_xml) {
          throw CanteraError("Phase::operator=()", "Confused: Couldn't find original phase " + right.m_xml->id());
        }
        if (&m_xml->root() != root_xml) {
          throw CanteraError("Phase::operator=()", "confused: root changed");
        }
    }
    m_id = right.m_id;
    m_name = right.m_name;
    return *this;
}
예제 #2
0
void Phase::setXMLdata(XML_Node& xmlPhase)
{
    XML_Node* xroot = &xmlPhase.root();
    XML_Node *root_xml = new XML_Node();
    xroot->copy(root_xml);
    if (m_xml) {
       XML_Node *rOld = &m_xml->root();
       delete rOld;
       m_xml = 0;
    }
    m_xml = findXMLPhase(root_xml, xmlPhase.id());
    if (!m_xml) {
        throw CanteraError("Phase::setXMLdata()", "XML 'phase' node not found");
    }
    if (&m_xml->root() != root_xml) {
        throw CanteraError("Phase::setXMLdata()", "Root XML node not found");
    }
}
예제 #3
0
  /*
   * Import a phase specification.
   *   Here we read an XML description of the phase.
   *   We import descriptions of the elements that make up the
   *   species in a phase.
   *   We import information about the species, including their
   *   reference state thermodynamic polynomials. We then freeze
   *   the state of the species, and finally call initThermoXML(phase, id)
   *   a member function of the ThermoPhase object to "finish"
   *   the description.
   *
   *
   * @param phase This object must be the phase node of a
   *             complete XML tree
   *             description of the phase, including all of the
   *             species data. In other words while "phase" must
   *             point to an XML phase object, it must have
   *             sibling nodes "speciesData" that describe
   *             the species in the phase.
   * @param th   Pointer to the ThermoPhase object which will
   *             handle the thermodynamics for this phase.
   *             We initialize part of the Thermophase object
   *             here, especially for those objects which are
   *             part of the Cantera Kernel.
   */
  bool importPhase(XML_Node& phase, ThermoPhase* th, 
		   SpeciesThermoFactory* spfactory) {

    // Check the the supplied XML node in fact represents a 
    // phase.
    if (phase.name() != "phase") {
      throw CanteraError("importPhase",
			 "Current const XML_Node named, " + phase.name() + 
			 ", is not a phase element.");
    }

    /*
     * In this section of code, we get the reference to the 
     * phase xml tree within the ThermoPhase object. Then,
     * we clear it and fill it with the current information that
     * we are about to use to construct the object. We will then
     * be able to resurrect the information later by calling xml().
     */
    XML_Node &phaseNode_XML = th->xml();
    phaseNode_XML.clear();
    phase.copy(&phaseNode_XML);

    // set the id attribute of the phase to the 'id' attribute 
    // in the XML tree.
    th->setID(phase.id());
    th->setName(phase.id());

    // Number of spatial dimensions. Defaults to 3 (bulk phase)
    if (phase.hasAttrib("dim")) {
      int idim = intValue(phase["dim"]);
      if (idim < 1 || idim > 3)
	throw CanteraError("importPhase",
			   "phase, " + th->id() + 
			   ", has unphysical number of dimensions: " + phase["dim"]);
      th->setNDim(idim);
    }
    else {
      th->setNDim(3);     // default
    }
	
    // Set equation of state parameters. The parameters are
    // specific to each subclass of ThermoPhase, so this is done
    // by method setParametersFromXML in each subclass.
    if (phase.hasChild("thermo")) {
      const XML_Node& eos = phase.child("thermo");
      th->setParametersFromXML(eos);
    } else {
      throw CanteraError("importPhase", 
			 " phase, " + th->id() + 
			 ", XML_Node does not have a \"thermo\" XML_Node");
    }

    VPStandardStateTP *vpss_ptr = 0;
    int ssConvention = th->standardStateConvention();
    if (ssConvention == cSS_CONVENTION_VPSS) {
      vpss_ptr = dynamic_cast <VPStandardStateTP *>(th);
      if (vpss_ptr == 0) {
	throw CanteraError("importPhase",
			   "phase, " + th->id() + ", was VPSS, but dynamic cast failed");
      }
    } 

    // if no species thermo factory was supplied,
    // use the default one. 
    if (!spfactory) {
      spfactory = SpeciesThermoFactory::factory();
    }

    /***************************************************************
     * Add the elements.
     ***************************************************************/
    th->addElementsFromXML(phase);

    /***************************************************************
     * Add the species. 
     *
     * Species definitions may be imported from multiple
     * sources. For each one, a speciesArray element must be
     * present.
     ***************************************************************/
    XML_Node* db = 0;
    vector<XML_Node*> sparrays;
    phase.getChildren("speciesArray", sparrays);
    int jsp, nspa = static_cast<int>(sparrays.size());
    if (nspa == 0) {
      throw CanteraError("importPhase",
			 "phase, " + th->id() + ", has zero \"speciesArray\" XML nodes.\n"
			 + " There must be at least one speciesArray nodes "
			 "with one or more species");
    }
    vector<XML_Node*> dbases;
    vector_int sprule(nspa,0);

    // loop over the speciesArray elements
    for (jsp = 0; jsp < nspa; jsp++) {

      const XML_Node& speciesArray = *sparrays[jsp];

      // If the speciesArray element has a child element
      //
      //   <skip element="undeclared"> 
      //
      // then set sprule[jsp] to 1, so
      // that any species with an undeclared element will be
      // quietly skipped when importing species.
      // Additionally, if the skip node has the following attribute:
      //
      // <skip species="duplicate">
      //
      // then duplicate species names will not cause Cantera to
      // throw an exception. Instead, the duplicate entry will 
      // be discarded.
      if (speciesArray.hasChild("skip")) {
	const XML_Node& sk = speciesArray.child("skip");
	string eskip = sk["element"];
	if (eskip == "undeclared") {
	  sprule[jsp] = 1;
	}
	string dskip = sk["species"];
	if (dskip == "duplicate") {
	  sprule[jsp] += 10;
	}
      }

      string fname, idstr;

      // Get a pointer to the node containing the species
      // definitions for the species declared in this 
      // speciesArray element. This may be in the local file
      // containing the phase element, or may be in another
      // file.            
      db = get_XML_Node(speciesArray["datasrc"], &phase.root());
      if (db == 0) {
	throw CanteraError("importPhase",
			   " Can not find XML node for species database: " 
			   + speciesArray["datasrc"]);
      }

      // add this node to the list of species database nodes.
      dbases.push_back(db);
    }

    // Now, collect all the species names and all the XML_Node * pointers
    // for those species in a single vector. This is where we decide what
    // species are to be included in the phase.
    // The logic is complicated enough that we put it in a separate routine.
    std::vector<XML_Node *>  spDataNodeList;
    std::vector<std::string> spNamesList;
    std::vector<int> spRuleList;
    formSpeciesXMLNodeList(spDataNodeList, spNamesList, spRuleList,
			   sparrays, dbases, sprule);

    // If the phase has a species thermo manager already installed,
    // delete it since we are adding new species.
    delete &th->speciesThermo();

    // Decide whether the the phase has a variable pressure ss or not
    SpeciesThermo* spth = 0;
    VPSSMgr* vp_spth = 0;
    if (ssConvention == cSS_CONVENTION_TEMPERATURE) {
      // Create a new species thermo manager.  Function
      // 'newSpeciesThermoMgr' looks at the species in the database
      // to see what thermodynamic property parameterizations are
      // used, and selects a class that can handle the
      // parameterizations found.
      spth = newSpeciesThermoMgr(spDataNodeList);
      
      // install it in the phase object
      th->setSpeciesThermo(spth);
    } else {
      vp_spth = newVPSSMgr(vpss_ptr, &phase, spDataNodeList);
      vpss_ptr->setVPSSMgr(vp_spth);
      spth = vp_spth->SpeciesThermoMgr();
      th->setSpeciesThermo(spth);
    }


    int k = 0;

    int nsp = spDataNodeList.size();
    for (int i = 0; i < nsp; i++) {
      XML_Node *s = spDataNodeList[i];
      AssertTrace(s != 0);
      bool ok = installSpecies(k, *s, *th, spth, spRuleList[i], 
			       &phase, vp_spth, spfactory);
      if (ok) {
	th->saveSpeciesData(k, s);
	++k;
      }
    }

    // done adding species. 
    th->freezeSpecies();

    // Perform any required subclass-specific initialization.
    th->initThermo();

    // Perform any required subclass-specific initialization
    // that requires the XML phase object
    string id = "";
    th->initThermoXML(phase, id);

    return true;
  }