Bugfix checkin to get the duplMyselfAsThermoPhase() routines working.

Bugs include quite a few errors in the copy constructors and
assignment operator functions, which, for most of them, have been
checked against a sample problem, HMW_dupl_test, for the very first time.

Note, the duplMyselfAsThermoPhase() routines are now working.
This commit is contained in:
Harry Moffat 2007-06-01 23:44:24 +00:00
parent 92c76dd5af
commit 16c8a59ca5
23 changed files with 350 additions and 147 deletions

View file

@ -52,6 +52,10 @@ namespace Cantera {
}
SpeciesThermo *ConstDensityThermo::duplMyselfAsSpeciesThermo() const {
ConstDensityThermo *cdt = new ConstDensityThermo(*this);
return (SpeciesThermo *) cdt;
}
int ConstDensityThermo::
eosType() const { return cIncompressible; }

View file

@ -71,8 +71,19 @@ namespace Cantera {
*/
ConstDensityThermo& operator=(const ConstDensityThermo &right);
// overloaded methods of class ThermoPhase
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const;
//! overloaded methods of class ThermoPhase
virtual int eosType() const;
//! Return the Molar Enthalpy. Units: J/kmol.

View file

@ -51,8 +51,8 @@ namespace Cantera {
Constituents::Constituents(Elements* ptr_Elements) :
m_kk(0),
m_speciesFrozen(false) ,
m_Elements(ptr_Elements) {
m_Elements(ptr_Elements)
{
if (!m_Elements) m_Elements = new Elements();
// Register subscription to Elements object whether or not we
@ -456,48 +456,63 @@ namespace Cantera {
}
}
/**
* This copy constructor just calls the assignment operator
* for this class.
* The assignment operator does a deep copy.
/*
* This copy constructor just calls the assignment operator
* for this class.
* The assignment operator does a deep copy.
*/
Constituents::Constituents(const Constituents& right) :
m_kk(0),
m_speciesFrozen(false),
m_Elements(0)
{
*this = right;
}
/*
* Assignment operator for the Constituents class.
* Right now we pretty much do a straight uncomplicated
* copy of all of the protected data.
*/
Constituents& Constituents::operator=(const Constituents& right) {
/*
* Check for self assignment.
*/
Constituents::Constituents(const Constituents& right) {
*this = right;
}
/**
* Assignment operator for the Constituents class.
* Right now we pretty much do a straight uncomplicated
* copy of all of the protected data.
if (this == &right) return *this;
/*
* We do a straight assignment operator on all of the
* data. The vectors are copied.
*/
Constituents& Constituents::operator=(const Constituents& right) {
/*
* Check for self assignment.
*/
if (this == &right) return *this;
/*
* We do a straight assignment operator on all of the
* data. The vectors are copied.
*/
m_kk = right.m_kk;
m_weight = right.m_weight;
m_speciesFrozen = right.m_speciesFrozen;
if (m_Elements) {
m_Elements->unsubscribe();
m_kk = right.m_kk;
m_weight = right.m_weight;
m_speciesFrozen = right.m_speciesFrozen;
if (m_Elements) {
int nleft = m_Elements->unsubscribe();
if (nleft <= 0) {
vector<Elements *>::iterator it;
for (it = Elements::Global_Elements_List.begin();
it != Elements::Global_Elements_List.end(); ++it) {
if (*it == m_Elements) {
Elements::Global_Elements_List.erase(it);
break;
}
}
m_Elements = right.m_Elements;
if (m_Elements) {
m_Elements->subscribe();
}
m_speciesNames = right.m_speciesNames;
m_speciesComp = right.m_speciesComp;
m_speciesCharge = right.m_speciesCharge;
m_speciesSize = right.m_speciesSize;
/*
* Return the reference to the current object
*/
return *this;
delete m_Elements;
}
}
m_Elements = right.m_Elements;
if (m_Elements) {
m_Elements->subscribe();
}
m_speciesNames = right.m_speciesNames;
m_speciesComp = right.m_speciesComp;
m_speciesCharge = right.m_speciesCharge;
m_speciesSize = right.m_speciesSize;
/*
* Return the reference to the current object
*/
return *this;
}
}

View file

@ -120,7 +120,19 @@ namespace Cantera {
* has a working copy constructor
*/
DebyeHuckel::DebyeHuckel(const DebyeHuckel &b) :
MolalityVPSSTP(b)
MolalityVPSSTP(),
m_formDH(DHFORM_DILUTE_LIMIT),
m_formGC(2),
m_IionicMolality(0.0),
m_maxIionicStrength(30.0),
m_useHelgesonFixedForm(false),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_CONST),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_B_Debye(3.28640E9), // units = sqrt(kg/gmol) / m
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0)
{
/*
* Use the assignment operator to do the brunt

View file

@ -40,8 +40,15 @@ namespace Cantera {
GeneralSpeciesThermo(const GeneralSpeciesThermo &b) :
m_tlow_max(b.m_tlow_max),
m_thigh_min(b.m_thigh_min),
m_kk(b.m_kk) {
m_sp = b.m_sp;
m_kk(b.m_kk)
{
m_sp.resize(m_kk, 0);
for (int k = 0; k < m_kk; k++) {
SpeciesThermoInterpType *bk = b.m_sp[k];
if (bk) {
m_sp[k] = bk->duplMyselfAsSpeciesThermoInterpType();
}
}
}
GeneralSpeciesThermo&
@ -49,8 +56,22 @@ namespace Cantera {
if (&b != this) {
m_tlow_max = b.m_tlow_max;
m_thigh_min = b.m_thigh_min;
for (int k = 0; k < m_kk; k++) {
SpeciesThermoInterpType *sp = m_sp[k];
if (sp) {
delete sp;
m_sp[k] = 0;
}
}
m_kk = b.m_kk;
m_sp = b.m_sp;
m_sp.resize(m_kk, 0);
for (int k = 0; k < m_kk; k++) {
SpeciesThermoInterpType *bk = b.m_sp[k];
if (bk) {
m_sp[k] = bk->duplMyselfAsSpeciesThermoInterpType();
}
}
}
return *this;
}
@ -95,6 +116,8 @@ namespace Cantera {
m_sp.resize(index+1, 0);
m_kk = index+1;
}
AssertThrow(m_sp[index] == 0,
"Index position isn't null, duplication of assignment: " + int2str(index));
/*
* Create the necessary object

View file

@ -110,7 +110,20 @@ namespace Cantera {
* has a working copy constructor
*/
HMWSoln::HMWSoln(const HMWSoln &b) :
MolalityVPSSTP(b)
MolalityVPSSTP(),
m_formPitzer(PITZERFORM_BASE),
m_formPitzerTemp(PITZER_TEMP_CONSTANT),
m_formGC(2),
m_IionicMolality(0.0),
m_maxIionicStrength(100.0),
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
m_debugCalc(0)
{
/*
* Use the assignment operator to do the brunt

View file

@ -115,9 +115,24 @@ namespace Cantera {
return *this;
}
//! destructor
virtual ~NasaThermo() {}
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
NasaThermo *nt = new NasaThermo(*this);
return (SpeciesThermo *) nt;
}
//! install a new species thermodynamic property
//! parameterization for one species.
/*!

View file

@ -27,6 +27,19 @@ namespace Cantera {
/**
* Basic list of constructors and duplicators
*/
PDSS::PDSS() :
m_temp(-1.0),
m_dens(-1.0),
m_tp(0),
m_mw(0.0),
m_spindex(-1),
m_spthermo(0),
m_cp0_R_ptr(0),
m_h0_RT_ptr(0),
m_s0_R_ptr(0),
m_g0_RT_ptr(0)
{
}
PDSS::PDSS(ThermoPhase *tp, int spindex) :
m_temp(-1.0),

View file

@ -39,6 +39,7 @@ namespace Cantera {
/**
* Basic list of constructors and duplicators
*/
PDSS();
PDSS(ThermoPhase *tp, int spindex);
PDSS(const PDSS &b);
PDSS& operator=(const PDSS&b);

View file

@ -29,6 +29,8 @@ namespace Cantera {
* then calls the assignment operator.
*/
Phase::Phase(const Phase &right) :
Constituents(),
State(),
m_kk(-1),
m_ndim(3),
m_index(-1),
@ -51,7 +53,7 @@ namespace Cantera {
* we have to copy our own data, making sure to do a
* deep copy on the XML_Node data owned by this object.
*/
const Phase &Phase::operator=(const Phase &right) {
Phase &Phase::operator=(const Phase &right) {
/*
* Check for self assignment.
*/
@ -74,13 +76,28 @@ namespace Cantera {
* to have our own individual copies of the XML data tree
* in each object
*/
m_xml = new XML_Node(*(right.m_xml));
if (m_xml) {
delete m_xml;
m_xml = 0;
}
if (right.m_xml) {
m_xml = new XML_Node();
(right.m_xml)->copy(m_xml);
}
m_id = right.m_id;
m_name = right.m_name;
return *this;
}
// Destructor.
Phase::~Phase() {
if (m_xml) {
delete m_xml;
m_xml = 0;
}
}
void Phase::saveState(vector_fp& state) const {
state.resize(nSpecies() + 2);

View file

@ -149,25 +149,22 @@ namespace Cantera {
m_xml(new XML_Node("phase")),
m_id("<phase>"), m_name("") {}
/// Destructor.
virtual ~Phase(){
delete m_xml;
m_xml = 0;
}
/// Destructor.
virtual ~Phase();
/**
* Copy Constructor
*
* @param c Reference to the class to be used in the copy
* @param right Reference to the class to be used in the copy
*/
Phase(const Phase &c);
Phase(const Phase &right);
/**
* Assignment operator
*
* @param c Reference to the class to be used in the copy
* @param right Reference to the class to be used in the copy
*/
const Phase &operator=(const Phase &c);
Phase &operator=(const Phase &right);
//! Returns a reference to the XML_Node storred for the phase
/*!

View file

@ -121,6 +121,21 @@ namespace Cantera {
return *this;
}
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
ShomateThermo *st = new ShomateThermo(*this);
return (SpeciesThermo *) st;
}
//! Install a new species thermodynamic property
//! parameterization for one species using Shomate polynomials
//!

View file

@ -106,6 +106,20 @@ namespace Cantera {
return *this;
}
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
SimpleThermo *nt = new SimpleThermo(*this);
return (SpeciesThermo *) nt;
}
//! Install a new species thermodynamic property
//! parameterization for one species.
/*!

View file

@ -177,7 +177,7 @@ namespace Cantera {
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
// virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const = 0;
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const = 0;
//! Install a new species thermodynamic property
//! parameterization for one species.

View file

@ -153,10 +153,10 @@ namespace Cantera {
public:
//! Constructor
SpeciesThermoDuo() {}
//! Destructor
virtual ~SpeciesThermoDuo(){}
//! copy constructor
SpeciesThermoDuo(const SpeciesThermoDuo &right) {
*this = operator=(right);
@ -167,7 +167,7 @@ namespace Cantera {
* @param right Object to be copied
*/
SpeciesThermoDuo& operator=(const SpeciesThermoDuo &right) {
if (right == *this) return *this;
if (&right == this) return *this;
m_thermo1 = right.m_thermo1;
m_thermo2 = right.m_thermo2;
@ -177,10 +177,20 @@ namespace Cantera {
return *this;
}
//virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
// SpeciesThermoDuo *std = new SpeciesThermoDuo(*this);
// return (SpeciesThermo *) std;
//}
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
SpeciesThermoDuo<T1,T2> *nt = new SpeciesThermoDuo<T1,T2>(*this);
return (SpeciesThermo *) nt;
}
/**
* install a new species thermodynamic property
* parameterization for one species.
@ -409,13 +419,27 @@ namespace Cantera {
* @param right Object to be copied
*/
SpeciesThermo1 & operator=(const SpeciesThermo1 &right) {
if (right == *this) return *this;
if (&right == this) return *this;
m_thermo = right.m_thermo;
m_pref = right.m_pref;
return *this;
}
//! Duplication routine for objects which inherit from
//! %SpeciesThermo
/*!
* This virtual routine can be used to duplicate %SpeciesThermo objects
* inherited from %SpeciesThermo even if the application only has
* a pointer to %SpeciesThermo to work with.
* ->commented out because we first need to add copy constructors
* and assignment operators to all of the derived classes.
*/
virtual SpeciesThermo *duplMyselfAsSpeciesThermo() const {
SpeciesThermo1<SPM> *nt = new SpeciesThermo1<SPM>(*this);
return (SpeciesThermo *) nt;
}
//! Install one species into this Species Thermo Manager
/*!

View file

@ -30,44 +30,46 @@ using namespace std;
namespace Cantera {
State::State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) {}
State::State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) {}
State::~State() {}
State::State(const State& right) :
m_kk(0),
m_temp(0.0),
m_dens(0.001),
m_mmw(0.0) {
/*
* Call the assignment operator.
*/
*this = operator=(right);
}
State::~State() {}
State::State(const State& right) :
m_kk(0),
m_temp(0.0),
m_dens(0.001),
m_mmw(0.0) {
/*
* Assignment operator for the State Class
* Call the assignment operator.
*/
State& State::operator=(const State& right) {
/*
* Check for self assignment.
*/
if (this == &right) return *this;
/*
* We do a straight assignment operator on all of the
* data. The vectors are copied.
*/
m_temp = right.m_temp;
m_dens = right.m_dens;
m_mmw = right.m_mmw;
m_y = right.m_y;
m_molwts = right.m_molwts;
m_rmolwts = right.m_rmolwts;
/*
* Return the reference to the current object
*/
return *this;
}
*this = operator=(right);
}
/*
* Assignment operator for the State Class
*/
State& State::operator=(const State& right) {
/*
* Check for self assignment.
*/
if (this == &right) return *this;
/*
* We do a straight assignment operator on all of the
* data. The vectors are copied.
*/
m_kk = right.m_kk;
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;
/*
* Return the reference to the current object
*/
return *this;
}
doublereal State::moleFraction(int k) const {
if (k >= 0 && k < m_kk) {

View file

@ -76,7 +76,9 @@ namespace Cantera {
* Check for self assignment.
*/
if (this == &right) return *this;
/*
* Call the base class assignment operator
*/
(void)Phase::operator=(right);
/*
@ -86,17 +88,10 @@ namespace Cantera {
if (m_spthermo) {
delete m_spthermo;
}
//m_spthermo = (right.m_spthermo)->duplMyselfAsSpeciesThermo();
throw CanteraError("ThermoPhase::operator=()", "SpeciesThermo dupl not impl");
m_spthermo = (right.m_spthermo)->duplMyselfAsSpeciesThermo();
/// Pointer to the XML tree containing the species
/// data for this phase. This is used to access data needed to
/// construct the transport manager and other properties
/// later in the initialization process.
// We don't do a deep copy here, because we don't own this
m_speciesData = right.m_speciesData;
m_index = right.m_index;
m_phi = right.m_phi;

View file

@ -26,16 +26,33 @@ namespace Cantera {
/**
* Basic list of constructors and duplicators
*/
WaterPDSS::WaterPDSS(ThermoPhase *tp, int spindex) :
PDSS(tp, spindex),
WaterPDSS::WaterPDSS() :
PDSS(),
m_sub(0),
m_iState(-1),
m_temp(0.0),
m_dens(0.0),
m_iState(-3000),
EW_Offset(0.0),
SW_Offset(0.0),
m_verbose(0),
m_allowGasPhase(false)
{
m_sub = new WaterPropsIAPWS();
m_spthermo = 0;
}
WaterPDSS::WaterPDSS(ThermoPhase *tp, int spindex) :
PDSS(tp, spindex),
m_sub(0),
m_temp(0.0),
m_dens(0.0),
m_iState(-3000),
EW_Offset(0.0),
SW_Offset(0.0),
m_verbose(0),
m_allowGasPhase(false)
{
m_sub = new WaterPropsIAPWS();
constructPDSS(tp, spindex);
m_spthermo = 0;
}
@ -45,13 +62,15 @@ namespace Cantera {
std::string inputFile, std::string id) :
PDSS(tp, spindex),
m_sub(0),
m_iState(-1),
m_mw(0.0),
m_temp(0.0),
m_dens(0.0),
m_iState(-3000),
EW_Offset(0.0),
SW_Offset(0.0),
m_verbose(0),
m_allowGasPhase(false)
{
m_sub = new WaterPropsIAPWS();
constructPDSSFile(tp, spindex, inputFile, id);
m_spthermo = 0;
}
@ -60,13 +79,15 @@ namespace Cantera {
XML_Node& phaseRoot, std::string id) :
PDSS(tp, spindex),
m_sub(0),
m_iState(-1),
m_mw(0.0),
m_temp(0.0),
m_dens(0.0),
m_iState(-3000),
EW_Offset(0.0),
SW_Offset(0.0),
m_verbose(0),
m_allowGasPhase(false)
{
m_sub = new WaterPropsIAPWS();
constructPDSSXML(tp, spindex, phaseRoot, id) ;
m_spthermo = 0;
}
@ -74,16 +95,17 @@ namespace Cantera {
WaterPDSS::WaterPDSS(const WaterPDSS &b) :
PDSS(b),
PDSS(),
m_sub(0),
m_iState(-1),
m_mw(b.m_mw),
m_temp(0.0),
m_dens(0.0),
m_iState(-3000),
EW_Offset(b.EW_Offset),
SW_Offset(b.SW_Offset),
m_verbose(b.m_verbose),
m_allowGasPhase(b.m_allowGasPhase)
{
m_sub = new WaterPropsIAPWS(*(b.m_sub));
m_sub = new WaterPropsIAPWS();
/*
* Use the assignment operator to do the brunt
* of the work for the copy construtor.
@ -102,7 +124,12 @@ namespace Cantera {
PDSS::operator=(b);
m_sub->operator=(*(b.m_sub));
m_verbose = b.m_verbose;
m_temp = b.m_temp;
m_dens = b.m_dens;
m_iState = b.m_iState;
EW_Offset = b.EW_Offset;
SW_Offset = b.SW_Offset;
m_verbose = b.m_verbose;
m_allowGasPhase = b.m_allowGasPhase;
return *this;
}

View file

@ -64,6 +64,7 @@ namespace Cantera {
/**
* Basic list of constructors and duplicators
*/
WaterPDSS();
WaterPDSS(ThermoPhase *tp, int spindex);
WaterPDSS(const WaterPDSS &b);
WaterPDSS& operator=(const WaterPDSS&b);
@ -172,21 +173,6 @@ private:
*/
int m_iState;
/**
* Thermophase which this species belongs to
*/
ThermoPhase *m_tp;
/**
* Species index in the thermophase corresponding to this species.
*/
int m_spindex;
/*
* Molecular Weight
*/
doublereal m_mw;
/**
* Offset constants used to obtain consistency with the NIST database.
* This is added to all internal energy and enthalpy results.

View file

@ -50,7 +50,9 @@ namespace Cantera {
/**
* Copy constructor
*/
WaterProps::WaterProps(const WaterProps &b)
WaterProps::WaterProps(const WaterProps &b) :
m_waterIAPWS(0),
m_own_sub(false)
{
*this = b;
}
@ -69,10 +71,21 @@ namespace Cantera {
*/
WaterProps& WaterProps::operator=(const WaterProps&b) {
if (&b == this) return *this;
/*
* add content here.
*/
if (m_own_sub) {
if (m_waterIAPWS) {
delete m_waterIAPWS;
m_waterIAPWS = 0;
}
}
if (b.m_own_sub) {
m_waterIAPWS = new WaterPropsIAPWS();
m_own_sub = true;
} else {
m_waterIAPWS = b.m_waterIAPWS;
m_own_sub = false;
}
return *this;
}

View file

@ -20,9 +20,9 @@
/*
* Critical Point values in mks units
*/
static const double T_c = 647.096; // Kelvin
const double T_c = 647.096; // Kelvin
static const double P_c = 22.064E6; // Pascals
static const double Rho_c = 322.; // kg m-3
const double Rho_c = 322.; // kg m-3
static const double M_water = 18.015268; // kg kmol-1
/*
* Note, this is the Rgas value quoted in the paper. For consistency

View file

@ -136,10 +136,10 @@ public:
WaterPropsIAPWS();
//! Copy constructor
WaterPropsIAPWS(const WaterPropsIAPWS &);
WaterPropsIAPWS(const WaterPropsIAPWS &b);
//! assignment constructor
WaterPropsIAPWS & operator=(const WaterPropsIAPWS &);
WaterPropsIAPWS & operator=(const WaterPropsIAPWS &b);
//! destructor
~WaterPropsIAPWS();

View file

@ -362,6 +362,12 @@ WaterPropsIAPWSphi::WaterPropsIAPWSphi() :
TAUsqrt(-1.0),
DELTAsave(-1.0)
{
for (int i = 0; i < 52; i++) {
TAUp[i] = 1.0;
}
for (int i = 0; i < 16; i++) {
DELTAp[i] = 1.0;
}
}
/*