Source code
C++ source code for process model
Qco2capture.cc
—
C++ source code,
67 kB (69004 bytes)
File contents
/** @file Qco2capture.cc
@brief Main file
This file is part of LIBPF
All rights reserved; do not distribute without permission.
@author (C) Copyright 2008-2010 Paolo Greppi 3iP
Repository revision: $Rev: 571 $
File revision date: $Date: 2010-05-28 03:56:55 +0200 (ven, 28 mag 2010) $
*/
static const int verbositySubSystem = 0;
#include "models.h"
#include "stream.h"
#include "graph.h"
#include "usermodels.h"
#include "purecomps.h"
#include <boost/assign/list_of.hpp>
#include <boost/assign/list_inserter.hpp>
void setComponents(void) {
static const int verbosityLocal = 0;
try {
// define components
components.addcomp(new purecomps::water);
components.addcomp(new purecomps::N2);
components.addcomp(new purecomps::O2);
components.addcomp(new purecomps::methane);
components.addcomp(new purecomps::CO);
components.addcomp(new purecomps::CO2);
components.addcomp(new purecomps::H2);
components.addcomp(new purecomps::nhexadecane);
components.addcomp(new purecomps::carbon);
components.addcomp(new purecomps::silica("ASH"));
components.addcomp(new purecomps::Fe);
components.addcomp(new purecomps::Fe2O3);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // void setComponents(void)
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////// reactionC16H34_TC /////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Model to represent the total combustion of n-Hexadecane with specified fixed conversion
/// Stoichiometry: C16H34 + 24.5*O2 = 16*CO2+ 17*H2O
/// 226.4463 + 24.5 31.9988 - 16*44.0098 + 17*18.0153
class reactionC16H34_TC : virtual public reactionYield {
private:
static std::string type_;
// it actually only implements:
void maketables(long);
public:
reactionC16H34_TC(const std::string &t, const std::string &d);
reactionC16H34_TC(long cid);
~reactionC16H34_TC() {}
virtual void setup(void) {}
virtual const std::string &type(void) const {
return type_;
}
// virtual void calculate(int MAXITS, int level) { reactionYield::calculate(MAXITS, level); }
}; // class reactionC16H34_TC
std::string reactionC16H34_TC::type_("reactionC16H34_TC");
reactionC16H34_TC::reactionC16H34_TC(const std::string &t, const std::string &d) :
persistent_item_interface(-1),
persistent_item(-1, t, d),
modelBaseInterface(-1),
reactionYield(-1) {
maketables(-1);
} // reactionC16H34_TC::reactionC16H34_TC
reactionC16H34_TC::reactionC16H34_TC(long cid) :
persistent_item_interface(cid),
persistent_item(cid, "", ""),
modelBaseInterface(cid),
reactionYield(cid) {
maketables(cid);
} // reactionC16H34_TC::reactionC16H34_TC
void reactionC16H34_TC::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << id());
I("keycomp")->set_val(components.lookup("C16H34"));
*Q("coeff", "C16H34") = -1.0;
*Q("coeff", "O2") = -24.5;
*Q("coeff", "CO2") = 16;
*Q("coeff", "H2O") = 17;
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reactionC16H34_TC::maketables
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////// reactionC16H34_decomp ///////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Model to represent the decompositition of n-Hexadecane with specified fixed conversion
/// Stoichiometry: C16H34 + 8*H2O = 8*CH4 + 8*CO + 9*H2
class reactionC16H34_decomp : virtual public reactionYield {
private:
static std::string type_;
// it actually only implements:
void maketables(long);
public:
reactionC16H34_decomp(const std::string &t, const std::string &d);
reactionC16H34_decomp(long cid);
~reactionC16H34_decomp() {}
virtual void setup(void) {}
virtual const std::string &type(void) const {
return type_;
}
// virtual void calculate(int MAXITS, int level) { reactionYield::calculate(MAXITS, level); }
}; // class reactionC16H34_decomp
std::string reactionC16H34_decomp::type_("reactionC16H34_decomp");
reactionC16H34_decomp::reactionC16H34_decomp(const std::string &t, const std::string &d) :
persistent_item_interface(-1),
persistent_item(-1, t, d),
modelBaseInterface(-1),
reactionYield(-1) {
maketables(-1);
} // reactionC16H34_decomp::reactionC16H34_decomp
reactionC16H34_decomp::reactionC16H34_decomp(long cid) :
persistent_item_interface(cid),
persistent_item(cid, "", ""),
modelBaseInterface(cid),
reactionYield(cid) {
maketables(cid);
} // reactionC16H34_decomp::reactionC16H34_decomp
void reactionC16H34_decomp::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << id());
I("keycomp")->set_val(components.lookup("C16H34"));
*Q("coeff", "C16H34") = -1.0;
*Q("coeff", "H2O") = -8.0;
*Q("coeff", "CH4") = 8.0;
*Q("coeff", "CO") = 8.0;
*Q("coeff", "H2") = 9.0;
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reactionC16H34_decomp::maketables
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////// reactionC_decomp //////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Model to represent the decompositition of carbon with specified fixed conversion
/// Stoichiometry: C + H2O = CO + H2
class reactionC_decomp : virtual public reactionYield {
private:
static std::string type_;
// it actually only implements:
void maketables(long);
public:
reactionC_decomp(const std::string &t, const std::string &d);
reactionC_decomp(long cid);
~reactionC_decomp() {}
virtual void setup(void) {}
virtual const std::string &type(void) const {
return type_;
}
// virtual void calculate(int MAXITS, int level) { reactionYield::calculate(MAXITS, level); }
}; // class reactionC_decomp
std::string reactionC_decomp::type_("reactionC_decomp");
reactionC_decomp::reactionC_decomp(const std::string &t, const std::string &d) :
persistent_item_interface(-1),
persistent_item(-1, t, d),
modelBaseInterface(-1),
reactionYield(-1) {
maketables(-1);
} // reactionC_decomp::reactionC_decomp
reactionC_decomp::reactionC_decomp(long cid) :
persistent_item_interface(cid),
persistent_item(cid, "", ""),
modelBaseInterface(cid),
reactionYield(cid) {
maketables(cid);
} // reactionC_decomp::reactionC_decomp
void reactionC_decomp::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << id());
I("keycomp")->set_val(components.lookup("C"));
*Q("coeff", "C") = -1.0;
*Q("coeff", "H2O") = -1.0;
*Q("coeff", "CO") = 1.0;
*Q("coeff", "H2") = 1.0;
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reactionC_decomp::maketables
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////// reactionFe_OX ///////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Model to represent the oxidation of iron to the III-oxide
/// Stoichiometry: 2*Fe + 1.5*O2 = Fe2O3
class reactionFe_OX : virtual public reactionYield {
private:
static std::string type_;
// it actually only implements:
void maketables(long);
public:
reactionFe_OX(const std::string &t, const std::string &d);
reactionFe_OX(long cid);
~reactionFe_OX() {}
virtual void setup(void) {}
virtual const std::string &type(void) const {
return type_;
}
// virtual void calculate(int MAXITS, int level) { reactionYield::calculate(MAXITS, level); }
}; // class reactionFe_OX
std::string reactionFe_OX::type_("reactionFe_OX");
reactionFe_OX::reactionFe_OX(const std::string &t, const std::string &d) :
persistent_item_interface(-1),
persistent_item(-1, t, d),
modelBaseInterface(-1),
reactionYield(-1) {
maketables(-1);
} // reactionFe_OX::reactionFe_OX
reactionFe_OX::reactionFe_OX(long cid) :
persistent_item_interface(cid),
persistent_item(cid, "", ""),
modelBaseInterface(cid),
reactionYield(cid) {
maketables(cid);
} // reactionFe_OX::reactionFe_OX
void reactionFe_OX::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << id());
I("keycomp")->set_val(components.lookup("Fe"));
*Q("coeff", "Fe") = -2.0;
*Q("coeff", "O2") = -1.5;
*Q("coeff", "Fe2O3") = 1;
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reactionFe_OX::maketables
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////// reactionFe_RED //////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Model to represent the reduction of the III-oxide to iron
/// Stoichiometry: Fe2O3 = 2*Fe + 1.5*O2
class reactionFe_RED : virtual public reactionYield {
private:
static std::string type_;
// it actually only implements:
void maketables(long);
public:
reactionFe_RED(const std::string &t, const std::string &d);
reactionFe_RED(long cid);
~reactionFe_RED() {}
virtual void setup(void) {}
virtual const std::string &type(void) const {
return type_;
}
// virtual void calculate(int MAXITS, int level) { reactionYield::calculate(MAXITS, level); }
}; // class reactionFe_RED
std::string reactionFe_RED::type_("reactionFe_RED");
reactionFe_RED::reactionFe_RED(const std::string &t, const std::string &d) :
persistent_item_interface(-1),
persistent_item(-1, t, d),
modelBaseInterface(-1),
reactionYield(-1) {
maketables(-1);
} // reactionFe_RED::reactionFe_RED
reactionFe_RED::reactionFe_RED(long cid) :
persistent_item_interface(cid),
persistent_item(cid, "", ""),
modelBaseInterface(cid),
reactionYield(cid) {
maketables(cid);
} // reactionFe_RED::reactionFe_RED
void reactionFe_RED::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << id());
I("keycomp")->set_val(components.lookup("Fe2O3"));
*Q("coeff", "Fe2O3") = -1;
*Q("coeff", "Fe") = 2.0;
*Q("coeff", "O2") = 1.5;
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reactionFe_RED::maketables
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////// coal ///////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class coal {
public:
static void set_feed(modelBaseInterface *s);
}; // class coal
void coal::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nw");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(20.0, "kmol/h");
s->O("Tphase")->Q("w", "C")->set(0.95);
s->O("Tphase")->Q("w", "H2")->set(0.01);
s->O("Tphase")->Q("w", "ASH")->set(0.04);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // coal::set_feed
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////////// pure_carbon ///////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class pure_carbon {
public:
static void set_feed(modelBaseInterface *s);
}; // class pure_carbon
void pure_carbon::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nw");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(20.0, "kmol/h");
s->O("Tphase")->Q("w", "C")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pure_carbon::set_feed
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////////// pure_methane //////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class pure_methane {
public:
static void set_feed(modelBaseInterface *s);
}; // class pure_methane
void pure_methane::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nx");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(10.0, "kmol/h");
s->O("Tphase")->Q("x", "CH4")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pure_methane::set_feed
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////// pure_CO /////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class pure_CO {
public:
static void set_feed(modelBaseInterface *s);
}; // class pure_CO
void pure_CO::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nx");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(10.0, "kmol/h");
s->O("Tphase")->Q("x", "CO")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pure_CO::set_feed
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////// pure_hydrogen ///////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class pure_hydrogen {
public:
static void set_feed(modelBaseInterface *s);
}; // class pure_hydrogen
void pure_hydrogen::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nx");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(10.0, "kmol/h");
s->O("Tphase")->Q("x", "H2")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pure_hydrogen::set_feed
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////// natural_gas ////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class natural_gas {
public:
static void set_feed(modelBaseInterface *s);
}; // class natural_gas
void natural_gas::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nx");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(10.0, "kmol/h");
s->O("Tphase")->Q("x", "CH4")->set(0.95);
s->O("Tphase")->Q("x", "CO2")->set(0.03);
s->O("Tphase")->Q("x", "N2")->set(0.02);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // natural_gas::set_feed
// /////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////// gasoil ///////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class gasoil {
public:
static void set_feed(modelBaseInterface *s);
}; // class gasoil
void gasoil::set_feed(modelBaseInterface *s) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << s->tag());
s->S("flowoption")->set("Nx");
my_cast<stream *>(s, CURRENT_FUNCTION)->clearcomposition();
s->O("Tphase")->Q("ndot")->set(0.75, "kmol/h");
s->O("Tphase")->Q("x", "C16H34")->set(1);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // gasoil::set_feed
Qdouble LHV(modelBaseInterface *s) {
static Qdouble LHV_CH4(802618.0, "kJ/kmol");
static Qdouble LHV_H2(241814.0, "kJ/kmol");
static Qdouble LHV_CO(282980.0, "kJ/kmol");
static Qdouble LHV_C16H34(9951936.36308, "kJ/kmol");
static Qdouble LHV_C(393510.035998, "kJ/kmol");
Qdouble lhv = *s->O("Tphase")->Q("ndotcomps", "CH4") * LHV_CH4 +
*s->O("Tphase")->Q("ndotcomps", "H2") * LHV_H2 +
*s->O("Tphase")->Q("ndotcomps", "CO") * LHV_CO +
*s->O("Tphase")->Q("ndotcomps", "C16H34") * LHV_C16H34 +
*s->O("Tphase")->Q("ndotcomps", "C") * LHV_C;
return lhv;
} // LHV
// /////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////// deltah ///////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
template<class T> class deltah : public modelBase, public flowsheet<zero_zero> {
private:
static std::string type_;
void maketables(long);
public:
deltah(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
maketables(-1);
};
deltah(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<zero_zero>(cid) {
maketables(cid);
readtables(cid);
}
Qdouble duty; /// actual reactor duty
Qdouble duty_calc; /// calculated duty based on LHV
Qdouble deltaH0_comb; ///< reaction enthalpy at reference conditions for combustion reaction
Qdouble deltaH0_comb_mass; ///< reaction enthalpy at reference conditions for combustion reaction on mass basis
void makeuserassembly(std::list<assignment *>::iterator &p);
void setup(void);
void calculate(int MAXITS = 100, int level = 0);
const std::string &type(void) const {
return type_;
}
}; // deltah
template<class T> void deltah<T>::maketables(long cid) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
// Non embedded objects
MAKEQDOUBLE(deltaH0_comb, 0.0, "J/kmol", "reaction enthalpy at reference conditions for combustion reaction");
MAKEQDOUBLE(deltaH0_comb_mass, 0.0, "J/kg", "reaction enthalpy at reference conditions for combustion reaction on mass basis");
MAKEQDOUBLE(duty, 0.0, "W", "reaction enthalpy at reference conditions for combustion reaction");
MAKEQDOUBLE(duty_calc, 0.0, "W", "calculated duty based on LHV");
if (cid == -1) {
diagnostic(2, "Define unit operations");
std::list<std::string> r = boost::assign::list_of("reactionCH4_TC")
("reactionH2_TC")
("reactionCO_TC")
("reactionC16H34_TC")
("reactionC_TC");
makeVertex<genflashN1>("RX", "Reactor", r, cid);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("S01", "Fuel", "source", "out", "RX", "in", cid);
makeEdge<stream_VL_ideal>("S02", "Oxygen", "source", "out", "RX", "in", cid);
makeEdge<stream_VS_ideal>("S03", "Flue gases", "RX", "out", "sink", "in", cid);
}
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // deltah::maketables
template<class T> void deltah<T>::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
diagnostic(3, "Calling flowsheet::setup to initialize any embedded flowsheet");
flowsheet<zero_zero>::setup();
double dummy(100.0);
diagnostic(3, "Setting input variables");
// fuel
T::set_feed(O("S01"));
// oxygen
O("S02")->Q("T")->set(T0);
O("S02")->Q("P")->set(P0);
O("S02")->S("flashoption")->set("PT");
O("S02")->S("flowoption")->set("N");
my_cast<stream *>(O("S02"), CURRENT_FUNCTION)->clearcomposition();
O("S02")->O("Tphase")->Q("ndotcomps", "O2")->set(100.0, "kmol/h");
O("RX")->Q("deltaP")->set(0.0, "mbar");
O("RX")->Q("T")->set(T0);
O("RX")->S("option")->set("DT");
O("RX")->O("reactions", 0)->Q("z")->set(1.0);
O("RX")->O("reactions", 1)->Q("z")->set(1.0);
O("RX")->O("reactions", 2)->Q("z")->set(1.0);
O("RX")->O("reactions", 3)->Q("z")->set(1.0);
O("RX")->O("reactions", 4)->Q("z")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // deltah::setup
template<class T> void deltah<T>::calculate(int MAXITS, int level) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
reset_errors();
flowsheet<zero_zero>::calculate(MAXITS, level);
duty = *O("RX")->Q("duty");
duty_calc = LHV(O("S01"));
deltaH0_comb = duty / *O("S01:Tphase")->Q("ndot");
deltaH0_comb_mass = duty / *O("S01:Tphase")->Q("mdot");
diagnostic(0, "deltaH0_comb = " << deltaH0_comb);
diagnostic(0, "RX.alfa = " << *O("RX")->Q("alfa"));
diagnostic(0, "S01:Vphase.fraction = " << *Q("S01:Vphase.fraction"));
diagnostic(0, "S02:Vphase.fraction = " << *Q("S02:Vphase.fraction"));
diagnostic(0, "S03:Vphase.fraction = " << *Q("S03:Xphase.fraction"));
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // deltah::calculate
template<class T> void deltah<T>::makeuserassembly(std::list<assignment *>::iterator &p) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
long i(0);
// pseudo actual vapor pressure if all water were in the vapor phase
Qdouble PH2O = *O("S03")->O("Tphase")->Q("x", "H2O") * *O("S02")->Q("P");
// desired vapor pressure, equal to 80% RH
Qdouble setPH2O = components["H2O"]->psat(*O("S03")->Q("T")) * 0.8;
if (PH2O.val() > 0.0)
MakeAssignment(*O("S02")->O("Tphase")->Q("ndotcomps", "O2"),
*O("S02")->O("Tphase")->Q("ndotcomps", "O2") * PH2O / setPH2O, "Target RH in flue gas");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // deltah::makeuserassembly
template<> std::string deltah<coal>::type_("deltah<coal>");
template<> std::string deltah<pure_carbon>::type_("deltah<pure_carbon>");
template<> std::string deltah<pure_methane>::type_("deltah<pure_methane>");
template<> std::string deltah<pure_CO>::type_("deltah<pure_CO>");
template<> std::string deltah<pure_hydrogen>::type_("deltah<pure_hydrogen>");
template<> std::string deltah<natural_gas>::type_("deltah<natural_gas>");
template<> std::string deltah<gasoil>::type_("deltah<gasoil>");
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////// base ////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// basic power plant configuration, abstract class
class base : public modelBase, public flowsheet<zero_zero> {
private:
void maketables(long);
public:
base(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
maketables(-1);
};
base(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<zero_zero>(cid) {
maketables(cid);
readtables(cid);
}
void setup(void);
// inputs
Qdouble setPower; ///< Desired net electrical power production
Qdouble setFlueO2; ///< Desired residual molar fraction of oxygen in flue gas
// results
Qdouble powerThFuel; ///< Thermal power input from fuel in terms of LHV
Qdouble power; ///< Actual net electrical power production
Qdouble eta; ///< yield to electrical energy based on input fuel LHV
Qdouble CO2; ///< CO2 emissions per unit produced electrical energy
Qdouble Q; ///< inlet fuel mass flow
Qdouble flueO2; ///< Actual residual molar fraction of oxygen in flue gas
}; // base
void base::maketables(long cid) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
MAKEQDOUBLE(setPower, 1.0, "MW", "Desired net electrical power production");
MAKEQDOUBLE(setFlueO2, 0.07, "", "Desired residual molar fraction of oxygen in flue gas");
MAKEQDOUBLE(powerThFuel, 0.0, "W", "Thermal power input from fuel in terms of LHV");
MAKEQDOUBLE(power, 0.0, "W", "Actual net electrical power production");
MAKEQDOUBLE(eta, 0.0, "", "yield to electrical energy based on input fuel LHV");
MAKEQDOUBLE(CO2, 0.0, "kg/J", "CO2 emissions per unit produced electrical energy");
MAKEQDOUBLE(Q, 0.0, "kg/s", "inlet fuel mass flow");
MAKEQDOUBLE(flueO2, 0.0, "", "Actual residual molar fraction of oxygen in flue gas");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // base::maketables
void base::setup(void) {
static const int verbosityLocal = 0;
diagnostic(2, " entered for " << tag());
setPower.set(1.0, "MW");
setFlueO2.set(0.07);
diagnostic(3, "Making selected outputs visible in GUI");
power.setOutput();
eta.setOutput();
CO2.setOutput();
Q.setOutput();
} // base::setup
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////// separation /////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// General-purpose separation section
/// in
/// out1: Depleted stream
/// out2: Enriched stream
template<int N> class separation : public modelBase, public flowsheet<vertex<1,2> > {
private:
static std::string type_;
void maketables(long);
public:
separation(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
maketables(-1);
};
separation(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<vertex<1,2> >(cid) {
maketables(cid);
readtables(cid);
};
void setup(void);
// inputs
Qdouble recovery; ///< recovery to out2
Qdouble purity; ///< molar purity in out2
Qdouble alpha; ///< entropic empirical coefficient
Qdouble beta; ///< enthalpy empirical coefficient
// results
Qdouble xIn; ///< inlet molar fraction
Qdouble recovery_others; ///< recovery to out2 of the other components
Qdouble power; ///< net electrical power production
Qdouble smixS01; ///< entropy flux of mixing for stream S01
Qdouble smixS02; ///< entropy flux of mixing for stream S02
Qdouble smixS03; ///< entropy flux of mixing for stream S03
Qdouble deltaS; ///< entropy flux of mixing change
void calculate(int MAXITS = 100, int level = 0);
void makeuserassembly(std::list<assignment *>::iterator &p) { }
const std::string &type(void) const {
return type_;
}
}; // separation
template<int N> void separation<N>::maketables(long CID) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
DOT = "width=\"2.0\",height=\"2.0\",shapefile = \"gensep.png\",shape=plaintext,color=lightgrey, fixedsize=true";
// Non embedded objects
MAKEQDOUBLE(recovery, 0.95, "", "recovery to out2");
MAKEQDOUBLE(purity, 0.9, "", "molar purity in out2");
MAKEQDOUBLE(alpha, 2.0, "", "entropic empirical coefficient");
MAKEQDOUBLE(beta, 5.0, "", "enthalpy empirical coefficient");
MAKEQDOUBLE(xIn, 0.0, "", "inlet molar fraction");
MAKEQDOUBLE(recovery_others, 0.0, "", "recovery to out2 of the other components");
MAKEQDOUBLE(power, 0.0, "W", "net electrical power production");
MAKEQDOUBLE(smixS01, 0.0, "W/K", "entropy flux of mixing for stream S01");
MAKEQDOUBLE(smixS02, 0.0, "W/K", "entropy flux of mixing for stream S02");
MAKEQDOUBLE(smixS03, 0.0, "W/K", "entropy flux of mixing for stream S03");
MAKEQDOUBLE(deltaS, 0.0, "W/K", "entropy flux of mixing change");
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<gensep<2> >("SEPARATOR", "Fixed yield separation", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VS_ideal>("S01", "Syngas or fluegas", "source", "out", "SEPARATOR", "in", CID);
makeEdge<stream_VS_ideal>("S02", "Depleted stream", "SEPARATOR", "out1", "sink", "in", CID);
makeEdge<stream_V>("S03", "Enriched stream", "SEPARATOR", "out2", "sink", "in", CID);
} else
readtables(CID);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // separation::maketables
template<int N> void separation<N>::calculate(int MAXITS, int level) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << fulltag());
diagnostic(3, "Setting input streams");
my_cast<stream *>(O("S01"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in1")->val()], CURRENT_FUNCTION));
diagnostic(3, "Setting input values");
O("SEPARATOR")->S("option")->set(std::string("D"));
*O("SEPARATOR")->Q("deltaP") = Qdouble(0.0, "bar");
*O("SEPARATOR")->Q("T") = Qdouble(200.0 + 273.15, "K");
xIn = *O("S01")->O("Tphase")->Q("x", N);
recovery_others = xIn * recovery * (one - purity) / purity / (one - xIn);
// Splits to depleted stream
*O("SEPARATOR")->Q("outSplit", 0, N) = one - recovery;
for (int i = 0; i < NCOMPONENTS; i++) {
if (components[i]->isSolid())
*O("SEPARATOR")->Q("outSplit", 0, i) = one;
else if (i != N)
*O("SEPARATOR")->Q("outSplit", 0, i) = one - recovery_others;
} // for each component
flowsheet<vertex<1,2> >::calculate(MAXITS, level);
smixS01 = smixS02 = smixS03 = Qdouble(0.0, "W/K");
for (int i = 0; i < NCOMPONENTS; i++) {
if (O("S01")->O("Tphase")->Q("x", i)->val() > zero)
smixS01 -= *O("S01")->O("Tphase")->Q("ndot") * R * *O("S01")->O("Tphase")->Q("x", i) * log(*O("S01")->O("Tphase")->Q("x", i));
if (O("S02")->O("Tphase")->Q("x", i)->val() > zero)
smixS02 -= *O("S02")->O("Tphase")->Q("ndot") * R * *O("S02")->O("Tphase")->Q("x", i) * log(*O("S02")->O("Tphase")->Q("x", i));
if (O("S03")->O("Tphase")->Q("x", i)->val() > zero)
smixS03 -= *O("S03")->O("Tphase")->Q("ndot") * R * *O("S03")->O("Tphase")->Q("x", i) * log(*O("S03")->O("Tphase")->Q("x", i));
} // for each component
deltaS = smixS03 + smixS02 - smixS01;
power = deltaS * *O("SEPARATOR")->Q("T") * alpha - *O("SEPARATOR")->Q("duty") / beta;
diagnostic(3, "Setting output streams");
(my_cast<stream *>(catalogRAM[I("out1")->val()], CURRENT_FUNCTION))->copyscale(my_cast<stream *>(O("S02"), CURRENT_FUNCTION));
(my_cast<stream *>(catalogRAM[I("out2")->val()], CURRENT_FUNCTION))->copyscale(my_cast<stream *>(O("S03"), CURRENT_FUNCTION));
setfirstpass(false);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // separation::calculate
template<int N> void separation<N>::setup(void) {
static const int verbosityLocal = 0;
diagnostic(2, " entered for " << tag());
recovery.set(0.95);
purity.set(0.9);
alpha.set(2.0);
beta.set(5.0);
} // separation::setup
template<> std::string separation<1>::type_("separation<1>");
template<> std::string separation<5>::type_("separation<5>");
// /////////////////////////////////////////////////////////////////////////////
// ///////////////////////////////// reformer //////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Reforming or gasification section
/// in1: fuel
/// in2: air
/// in3: water
/// out: Syngas
class reformer : public modelBase, public flowsheet<vertex<3,1> > {
private:
static std::string type_;
void maketables(long);
public:
reformer(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
maketables(-1);
};
reformer(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<vertex<3,1> >(cid) {
maketables(cid);
readtables(cid);
};
// inputs
// results
Qdouble power; ///< net electrical power production
void calculate(int MAXITS = 100, int level = 0);
void setup(void);
void makeuserassembly(std::list<assignment *>::iterator &p) { }
const std::string &type(void) const {
return type_;
}
}; // reformer
std::string reformer::type_("reformer");
void reformer::maketables(long CID) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
DOT = "width=\"2.0\",height=\"2.0\",shapefile = \"gensep.png\",shape=plaintext,color=lightgrey, fixedsize=true";
// Non embedded objects
MAKEQDOUBLE(power, 0.0, "W", "net electrical power production");
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<mixer>("MIX", "Feeds mixer", CID);
makeVertex<genflashN1>("RX", "Reforming reactor", CID,
boost::assign::map_list_of<std::string, long>("nReactions", 4),
boost::assign::map_list_of<std::string, std::string>
("embeddedTypeReactions[0]", "reactionC16H34_decomp")
("embeddedTypeReactions[1]", "reactionC_decomp")
("embeddedTypeReactions[2]", "reactionCH4_Ref_Eq")
("embeddedTypeReactions[3]", "reactionWGS_Eq"));
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("S01", "Fuel", "source", "out", "MIX", "in", CID);
makeEdge<stream_V>("S02", "Air", "source", "out", "MIX", "in", CID);
makeEdge<stream_L>("S03", "Water", "source", "out", "MIX", "in", CID);
makeEdge<stream_VLS_ideal>("S04", "Feed mixture", "MIX", "out", "RX", "in", CID);
makeEdge<stream_V>("S05", "Syngas", "RX", "out", "sink", "in", CID);
} else
readtables(CID);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reformer::maketables
void reformer::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
O("RX")->S("option")->set("PT");
O("RX")->Q("P")->set(1.0, "bar");
O("RX")->Q("T")->set(600.0 + 273.15, "K");
O("RX")->O("reactions", 0)->Q("z")->set(1.0);
O("RX")->O("reactions", 1)->Q("z")->set(1.0);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reformer::setup
void reformer::calculate(int MAXITS, int level) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << fulltag());
diagnostic(3, "Setting input streams");
my_cast<stream *>(O("S01"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in1")->val()], CURRENT_FUNCTION));
my_cast<stream *>(O("S02"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in2")->val()], CURRENT_FUNCTION));
my_cast<stream *>(O("S03"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in3")->val()], CURRENT_FUNCTION));
flowsheet<vertex<3,1> >::calculate(MAXITS, level);
power = *O("RX")->Q("duty") * 0.1;
diagnostic(3, "Setting output streams");
(my_cast<stream *>(catalogRAM[I("out1")->val()], CURRENT_FUNCTION))->copyscale(my_cast<stream *>(O("S05"), CURRENT_FUNCTION));
setfirstpass(false);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // reformer::calculate
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////// conversion /////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// Energy conversion section
/// in1: Fuel
/// in2: Oxydant
/// out1: Flue gas
/// out2: Metal (if CLC)
class conversion : public modelBase, public flowsheet<vertex<2,2> > {
private:
static std::string type_;
void maketables(long);
public:
conversion(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
maketables(-1);
};
conversion(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<vertex<2,2> >(cid) {
maketables(cid);
readtables(cid);
};
// inputs
Qdouble eta; ///< yield to electrical energy based on combustion duty
// results
Qdouble power; ///< net electrical power production
void calculate(int MAXITS = 100, int level = 0);
void setup(void);
void makeuserassembly(std::list<assignment *>::iterator &p) { }
const std::string &type(void) const {
return type_;
}
}; // conversion
std::string conversion::type_("conversion");
void conversion::maketables(long CID) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
DOT = "width=\"2.0\",height=\"2.0\",shapefile = \"gensep.png\",shape=plaintext,color=lightgrey, fixedsize=true";
// Non embedded objects
MAKEQDOUBLE(eta, 0.5, "", "yield to electrical energy based on combustion duty");
MAKEQDOUBLE(power, 0.0, "W", "net electrical power production");
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<mixer>("MIX", "Feeds mixer", CID);
std::list<std::string> r = boost::assign::list_of("reactionFe_RED")
("reactionCH4_TC")
("reactionH2_TC")
("reactionCO_TC")
("reactionC16H34_TC")
("reactionC_TC");
makeVertex<genflashN1>("RX", "Combustion reactor", r, CID);
makeVertex<gensep<2> >("SEPARATOR", "Fixed yield separation", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("S01", "Fuel", "source", "out", "MIX", "in", CID);
makeEdge<stream_VS_ideal>("S02", "Oxydant", "source", "out", "MIX", "in", CID);
makeEdge<stream_VLS_ideal>("S03", "Feed mixture", "MIX", "out", "RX", "in", CID);
makeEdge<stream_VS_ideal>("S04", "Reaction products", "RX", "out", "SEPARATOR", "in", CID);
makeEdge<stream_VS_ideal>("S05", "Fluegas", "SEPARATOR", "out1", "sink", "in", CID);
makeEdge<stream_VS_ideal>("S06", "Metal", "SEPARATOR", "out2", "sink", "in", CID);
} else
readtables(CID);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // conversion::maketables
void conversion::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
eta.set(0.5);
O("RX")->S("option")->set("PT");
O("RX")->Q("P")->set(1.0, "bar");
O("RX")->Q("T")->set(200.0 + 273.15, "K");
O("RX")->O("reactions", 0)->Q("z")->set(1.0);
O("RX")->O("reactions", 1)->Q("z")->set(1.0);
O("RX")->O("reactions", 2)->Q("z")->set(1.0);
O("RX")->O("reactions", 3)->Q("z")->set(1.0);
O("RX")->O("reactions", 4)->Q("z")->set(1.0);
O("RX")->O("reactions", 5)->Q("z")->set(1.0);
O("SEPARATOR")->Q("T")->set(200.0 + 273.15, "K");
// separations factors to fluegas
for (int i = 0; i < NCOMPONENTS; i++) {
if ((components[i]->name() == "Fe") || (components[i]->name() == "Fe2O3"))
*O("SEPARATOR")->Q("outSplit", 0, i) = zero;
else
*O("SEPARATOR")->Q("outSplit", 0, i) = one;
} // for each component
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // conversion::setup
void conversion::calculate(int MAXITS, int level) {
static const int verbosityLocal = 0;
try {
diagnostic(2, "Entered for " << fulltag());
diagnostic(3, "Setting input streams");
my_cast<stream *>(O("S01"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in1")->val()], CURRENT_FUNCTION));
my_cast<stream *>(O("S02"), CURRENT_FUNCTION)->copyscale(my_cast<stream *>(catalogRAM[I("in2")->val()], CURRENT_FUNCTION));
flowsheet<vertex<2, 2> >::calculate(MAXITS, level);
power = *O("RX")->Q("duty") * eta;
diagnostic(3, "Setting output streams");
(my_cast<stream *>(catalogRAM[I("out1")->val()], CURRENT_FUNCTION))->copyscale(my_cast<stream *>(O("S05"), CURRENT_FUNCTION));
(my_cast<stream *>(catalogRAM[I("out2")->val()], CURRENT_FUNCTION))->copyscale(my_cast<stream *>(O("S06"), CURRENT_FUNCTION));
setfirstpass(false);
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // conversion::calculate
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////// pre ////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// pre-reforming of fuel
template<class T> class pre : public base {
private:
static std::string type_;
void maketables(long);
public:
pre(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), base(cid) {
maketables(cid);
readtables(cid);
}
void makeuserassembly(std::list<assignment *>::iterator &p);
void setup(void);
const std::string &type(void) const {
return type_;
}
bool supports_simultaneous(void);
// inputs
Qdouble STC; ///< Steam to carbon ratio
// results
}; // pre
template<class T> bool pre<T>::supports_simultaneous(void) {
return true;
} // pre::supports_simultaneous
template<class T> void pre<T>::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
MAKEQDOUBLE(STC, 3.0, "", "Steam to carbon ratio");
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<reformer>("REF", "Reforming or gasification section", CID);
makeVertex<separation<5> >("CAP", "Carbon separation section", CID);
makeVertex<conversion>("COMB", "Energy conversion section", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("FUEL", "Feed fuel", "source", "out", "REF", "in1", CID);
makeEdge<stream_V>("AIR", "Ambient air feed to reforming or gasification", "source", "out", "REF", "in2", CID);
makeEdge<stream_L>("WATER", "Water feed", "source", "out", "REF", "in3", CID);
makeEdge<stream_VS_ideal>("SYNGAS", "Synthesis gas from reforming or gasification", "REF", "out1", "CAP", "in", CID);
makeEdge<stream_VS_ideal>("H2", "Concentrated hydrogen", "CAP", "out1", "COMB", "in1", CID);
makeEdge<stream_V>("CO2", "Concentrated carbon dioxide stream", "CAP", "out2", "sink", "in", CID);
makeEdge<stream_V>("AIR1", "Ambient air feed to energy conversion", "source", "out", "COMB", "in2", CID);
makeEdge<stream_VS_ideal>("FLUE", "Fluegas", "COMB", "out1", "sink", "in", CID);
makeEdge<stream_VS_ideal>("DUMMY", "", "COMB", "out2", "sink", "in", CID);
}
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pre::maketables
template<class T> void pre<T>::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
diagnostic(3, "Calling flowsheet::setup to initialize any embedded flowsheet");
flowsheet<zero_zero>::setup();
base::setup();
STC.set(3.0);
diagnostic(3, "Setting input variables");
// Feed fuel
T::set_feed(O("FUEL"));
// Ambient air feed to reforming or gasification
O("AIR")->S("flowoption")->set("Nx");
my_cast<stream *>(O("AIR"), CURRENT_FUNCTION)->clearcomposition();
O("AIR")->O("Tphase")->Q("ndot")->set(0.0, "kmol/h");
O("AIR")->O("Tphase")->Q("x", "N2")->set(0.79);
O("AIR")->O("Tphase")->Q("x", "O2")->set(0.2);
O("AIR")->O("Tphase")->Q("x", "H2O")->set(0.01);
// Water feed
O("WATER")->S("flowoption")->set("Nx");
my_cast<stream *>(O("WATER"), CURRENT_FUNCTION)->clearcomposition();
O("WATER")->O("Tphase")->Q("ndot")->set(10.0 * 4.0, "kmol/h");
O("WATER")->O("Tphase")->Q("x", "H2O")->set(one);
// Ambient air feed to energy conversion
O("AIR1")->S("flowoption")->set("Nx");
my_cast<stream *>(O("AIR1"), CURRENT_FUNCTION)->clearcomposition();
O("AIR1")->O("Tphase")->Q("ndot")->set(35.0 * 3.0, "kmol/h");
O("AIR1")->O("Tphase")->Q("x", "N2")->set(0.79);
O("AIR1")->O("Tphase")->Q("x", "O2")->set(0.2);
O("AIR1")->O("Tphase")->Q("x", "H2O")->set(0.01);
diagnostic(3, "Unit operations inputs");
O("CAP")->Q("recovery")->set(0.95);
O("CAP")->Q("purity")->set(0.9);
O("COMB")->Q("eta")->set(0.5);
diagnostic(3, "Initializing cut streams");
diagnostic(3, "Defining cut streams");
// addcut("S06");
diagnostic(3, "Making selected outputs visible in GUI");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pre::setup
template<class T> void pre<T>::makeuserassembly(std::list<assignment *>::iterator &p) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
long i(0);
// compute base results
// Thermal power input from fuel in terms of LHV
powerThFuel = LHV(O("FUEL"));
// Actual net electrical power production
power = *O("REF")->Q("power") + *O("CAP")->Q("power") + *O("COMB")->Q("power");
// yield to electrical energy based on input fuel LHV
eta = power / powerThFuel;
// CO2 emissions per unit produced electrical energy
CO2 = *O("FLUE")->O("Tphase")->Q("mdotcomps", "CO2") / power;
// inlet fuel mass flow
Q = *O("FUEL")->O("Tphase")->Q("mdot");
// residual molar fraction of oxygen in flue gas
flueO2 = *O("FLUE")->O("Tphase")->Q("x", "O2");
MakeAssignment(*O("FUEL")->O("Tphase")->Q("ndot"), *O("FUEL")->O("Tphase")->Q("ndot") * setPower / power, "Target electrical power production");
MakeAssignment(*O("WATER")->O("Tphase")->Q("ndot"), *O("FUEL")->O("Tphase")->Q("ndot") * STC, "Maintain steam to carbon ratio");
MakeAssignment(*O("AIR1")->O("Tphase")->Q("ndot"), *O("AIR1")->O("Tphase")->Q("ndot") * setFlueO2 / flueO2, "Maintain residual molar fraction of oxygen in flue gas");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // pre::makeuserassembly
template<> std::string pre<coal>::type_("pre<coal>");
template<> std::string pre<natural_gas>::type_("pre<natural_gas>");
template<> std::string pre<gasoil>::type_("pre<gasoil>");
// /////////////////////////////////////////////////////////////////////////////
// /////////////////////////////////// post ////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// post-reforming of fuel
template<class T> class post : public base {
private:
static std::string type_;
void maketables(long);
public:
post(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), base(cid) {
maketables(cid);
readtables(cid);
}
void makeuserassembly(std::list<assignment *>::iterator &p);
void setup(void);
const std::string &type(void) const {
return type_;
}
// inputs
// results
}; // post
template<class T> void post<T>::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<conversion>("COMB", "Energy conversion section", CID);
makeVertex<separation<5> >("CAP", "Carbon separation section", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("FUEL", "Feed fuel", "source", "out", "COMB", "in1", CID);
makeEdge<stream_V>("AIR", "Ambient air feed to energy conversion", "source", "out", "COMB", "in2", CID);
makeEdge<stream_VS_ideal>("FLUE", "Untreated flue gases", "COMB", "out1", "CAP", "in", CID);
makeEdge<stream_VS_ideal>("DUMMY", "", "COMB", "out2", "sink", "in", CID);
makeEdge<stream_VS_ideal>("FLUE1", "Fluegas", "CAP", "out1", "sink", "in", CID);
makeEdge<stream_V>("CO2", "Concentrated carbon dioxide stream", "CAP", "out2", "sink", "in", CID);
}
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // post::maketables
template<class T> void post<T>::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
diagnostic(3, "Calling flowsheet::setup to initialize any embedded flowsheet");
flowsheet<zero_zero>::setup();
base::setup();
diagnostic(3, "Setting input variables");
// Feed fuel
T::set_feed(O("FUEL"));
// Ambient air feed to energy conversion
O("AIR")->S("flowoption")->set("Nx");
my_cast<stream *>(O("AIR"), CURRENT_FUNCTION)->clearcomposition();
O("AIR")->O("Tphase")->Q("ndot")->set(35.0 * 3.0, "kmol/h");
O("AIR")->O("Tphase")->Q("x", "N2")->set(0.79);
O("AIR")->O("Tphase")->Q("x", "O2")->set(0.2);
O("AIR")->O("Tphase")->Q("x", "H2O")->set(0.01);
diagnostic(3, "Unit operations inputs");
O("CAP")->Q("recovery")->set(0.95);
O("CAP")->Q("purity")->set(0.9);
O("COMB")->Q("eta")->set(0.5);
diagnostic(3, "Initializing cut streams");
diagnostic(3, "Defining cut streams");
// addcut("S06");
diagnostic(3, "Making selected outputs visible in GUI");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // post::setup
template<class T> void post<T>::makeuserassembly(std::list<assignment *>::iterator &p) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
long i(0);
// compute base results
// Thermal power input from fuel in terms of LHV
powerThFuel = LHV(O("FUEL"));
// Actual net electrical power production
power = *O("CAP")->Q("power") + *O("COMB")->Q("power");
// yield to electrical energy based on input fuel LHV
eta = power / powerThFuel;
// CO2 emissions per unit produced electrical energy
CO2 = *O("FLUE1")->O("Tphase")->Q("mdotcomps", "CO2") / power;
// inlet fuel mass flow
Q = *O("FUEL")->O("Tphase")->Q("mdot");
// residual molar fraction of oxygen in flue gas
flueO2 = *O("FLUE")->O("Tphase")->Q("x", "O2");
MakeAssignment(*O("FUEL")->O("Tphase")->Q("ndot"), *O("FUEL")->O("Tphase")->Q("ndot") * setPower / power, "Target electrical power production");
MakeAssignment(*O("AIR")->O("Tphase")->Q("ndot"), *O("AIR")->O("Tphase")->Q("ndot") * setFlueO2 / flueO2, "Maintain residual molar fraction of oxygen in flue gas");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // post::makeuserassembly
template<> std::string post<coal>::type_("post<coal>");
template<> std::string post<natural_gas>::type_("post<natural_gas>");
template<> std::string post<gasoil>::type_("post<gasoil>");
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////// oxy ////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// oxy-reforming of fuel
template<class T> class oxy : public base {
private:
static std::string type_;
void maketables(long);
public:
oxy(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), base(cid) {
maketables(cid);
readtables(cid);
}
void makeuserassembly(std::list<assignment *>::iterator &p);
void setup(void);
bool supports_simultaneous(void);
const std::string &type(void) const {
return type_;
}
// inputs
// results
}; // oxy
template<class T> bool oxy<T>::supports_simultaneous(void) {
return true;
} // oxy::supports_simultaneous
template<class T> void oxy<T>::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
if (CID == -1) {
diagnostic(2, "Define unit operations");
makeVertex<separation<1> >("AIRSEP", "Air separation section", CID);
makeVertex<conversion>("COMB", "Energy conversion section", CID);
makeVertex<separation<5> >("CAP", "Carbon separation section", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_V>("AIR", "Ambient air feed to air separation", "source", "out", "AIRSEP", "in", CID);
makeEdge<stream_V>("N2", "Concentrated nitrogen stream", "AIRSEP", "out2", "sink", "in", CID);
makeEdge<stream_VS_ideal>("O2", "Oxygen enriched stream", "AIRSEP", "out1", "COMB", "in2", CID);
makeEdge<stream_VLS_ideal>("FUEL", "Feed fuel", "source", "out", "COMB", "in1", CID);
makeEdge<stream_VS_ideal>("FLUE", "Untreated flue gases", "COMB", "out1", "CAP", "in", CID);
makeEdge<stream_VS_ideal>("DUMMY", "", "COMB", "out2", "sink", "in", CID);
makeEdge<stream_VS_ideal>("FLUE1", "Fluegas", "CAP", "out1", "sink", "in", CID);
makeEdge<stream_V>("CO2", "Concentrated carbon dioxide stream", "CAP", "out2", "sink", "in", CID);
}
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // oxy::maketables
template<class T> void oxy<T>::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
diagnostic(3, "Calling flowsheet::setup to initialize any embedded flowsheet");
flowsheet<zero_zero>::setup();
base::setup();
diagnostic(3, "Setting input variables");
// Feed fuel
T::set_feed(O("FUEL"));
// Ambient air feed to energy conversion
O("AIR")->S("flowoption")->set("Nx");
my_cast<stream *>(O("AIR"), CURRENT_FUNCTION)->clearcomposition();
O("AIR")->O("Tphase")->Q("ndot")->set(35.0 * 5.0, "kmol/h");
O("AIR")->O("Tphase")->Q("x", "N2")->set(0.79);
O("AIR")->O("Tphase")->Q("x", "O2")->set(0.2);
O("AIR")->O("Tphase")->Q("x", "H2O")->set(0.01);
diagnostic(3, "Unit operations inputs");
O("CAP")->Q("recovery")->set(0.95);
O("CAP")->Q("purity")->set(0.9);
O("AIRSEP")->Q("recovery")->set(0.8);
O("AIRSEP")->Q("purity")->set(0.9);
O("COMB")->Q("eta")->set(0.5);
diagnostic(3, "Initializing cut streams");
diagnostic(3, "Defining cut streams");
// addcut("S06");
diagnostic(3, "Making selected outputs visible in GUI");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // oxy::setup
template<class T> void oxy<T>::makeuserassembly(std::list<assignment *>::iterator &p) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
long i(0);
// compute base results
// Thermal power input from fuel in terms of LHV
powerThFuel = LHV(O("FUEL"));
// Actual net electrical power production
power = *O("CAP")->Q("power") + *O("AIRSEP")->Q("power") + *O("COMB")->Q("power");
// yield to electrical energy based on input fuel LHV
eta = power / powerThFuel;
// CO2 emissions per unit produced electrical energy
CO2 = *O("FLUE1")->O("Tphase")->Q("mdotcomps", "CO2") / power;
// inlet fuel mass flow
Q = *O("FUEL")->O("Tphase")->Q("mdot");
// residual molar fraction of oxygen in flue gas
flueO2 = *O("FLUE")->O("Tphase")->Q("x", "O2");
MakeAssignment(*O("FUEL")->O("Tphase")->Q("ndot"), *O("FUEL")->O("Tphase")->Q("ndot") * setPower / power, "Target electrical power production");
// MakeAssignment(*O("AIR")->O("Tphase")->Q("ndot"), *O("AIR")->O("Tphase")->Q("ndot") * sqrt(setFlueO2 / flueO2), "Maintain residual molar fraction of oxygen in flue gas");
// MakeAssignment(*O("AIR")->O("Tphase")->Q("ndot"), *O("AIR")->O("Tphase")->Q("ndot") * sqrt((setFlueO2/(One-setFlueO2)) / (flueO2/(One-flueO2))), "Maintain residual molar fraction of oxygen in flue gas");
MakeAssignment(*O("AIR")->O("Tphase")->Q("ndot"), *O("AIR")->O("Tphase")->Q("ndot") * pow(setFlueO2 / flueO2, 0.2), "Maintain residual molar fraction of oxygen in flue gas");
// diagnostic(0, "AIR:Tphase.ndot = " << *O("AIR")->O("Tphase")->Q("ndot"));
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // oxy::makeuserassembly
template<> std::string oxy<coal>::type_("oxy<coal>");
template<> std::string oxy<natural_gas>::type_("oxy<natural_gas>");
template<> std::string oxy<gasoil>::type_("oxy<gasoil>");
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////////////// clc ////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
/// chemical looping combustion
template<class T> class clc : public base {
private:
static std::string type_;
void maketables(long);
public:
clc(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), base(cid) {
maketables(cid);
readtables(cid);
}
void makeuserassembly(std::list<assignment *>::iterator &p);
void setup(void);
const std::string &type(void) const {
return type_;
}
// inputs
// results
Qdouble stoich_ratio; ///< stechioimetric ratio of oxidant to carbon containing fuels
bool supports_simultaneous(void);
// int smiter_precalc(void);
}; // class clc
template<class T> bool clc<T>::supports_simultaneous(void) {
return true;
} // clc::supports_simultaneous
template<class T> void clc<T>::maketables(long CID) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
// Non embedded objects
MAKEQDOUBLE(stoich_ratio, 0.0, "", "stechioimetric ratio of oxidant to carbon containing fuels");
if (CID == -1) {
diagnostic(2, "Define unit operations");
std::list<std::string> r = boost::assign::list_of("reactionFe_OX");
makeVertex<hx>("HX", "Air preheat", CID);
makeVertex<genflashNX<stream_VS_ideal> >("OX", "Air reactor", r, CID);
makeVertex<conversion>("COMB", "Energy conversion section", CID);
makeVertex<separation<5> >("CAP", "Carbon separation section", CID);
makeVertex<gensep<2> >("SEPARATOR", "Purge stream", CID);
diagnostic(2, "Define stream objects and connect");
makeEdge<stream_VLS_ideal>("FUEL", "Feed fuel", "source", "out", "COMB", "in1", CID);
makeEdge<stream_V>("AIR", "Ambient air feed", "source", "out", "HX", "coldin", CID);
makeEdge<stream_V>("HOT_AIR", "Ambient air feed to air reactor", "HX", "coldout", "OX", "in", CID);
makeEdge<stream_S>("MEO", "Oxidized metal", "OX", "solid1", "COMB", "in2", CID);
makeEdge<stream_VS_ideal>("FLUE", "Untreated flue gases", "COMB", "out1", "CAP", "in", CID);
makeEdge<stream_V>("DAIR", "Depleted air", "OX", "vapor", "HX", "hotin", CID);
makeEdge<stream_V>("COLD_DAIR", "Cold depleted air", "HX", "hotout", "sink", "in", CID);
makeEdge<stream_VS_ideal>("M", "Metal", "COMB", "out2", "SEPARATOR", "in", CID);
makeEdge<stream_VS_ideal>("M_PURGE", "Metal purge", "SEPARATOR", "out1", "sink", "in", CID);
makeEdge<stream_VS_ideal>("M_RECY", "Metal recycled", "SEPARATOR", "out2", "OX", "in", CID);
makeEdge<stream_VS_ideal>("M_MAKEUP", "Metal makeup", "source", "out", "OX", "in", CID);
makeEdge<stream_VS_ideal>("FLUE1", "Fluegas", "CAP", "out1", "sink", "in", CID);
makeEdge<stream_V>("CO2", "Concentrated carbon dioxide stream", "CAP", "out2", "sink", "in", CID);
}
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // clc::maketables
template<class T> void clc<T>::setup(void) {
static const int verbosityLocal = 0;
try {
diagnostic(2, " entered for " << tag());
diagnostic(3, "Calling flowsheet::setup to initialize any embedded flowsheet");
flowsheet<zero_zero>::setup();
base::setup();
diagnostic(3, "Setting input variables");
// Feed fuel
T::set_feed(O("FUEL"));
// Ambient air feed
O("AIR")->S("flowoption")->set("Nx");
my_cast<stream *>(O("AIR"), CURRENT_FUNCTION)->clearcomposition();
O("AIR")->O("Tphase")->Q("ndot")->set(150.0, "kmol/h");
O("AIR")->O("Tphase")->Q("x", "N2")->set(0.79);
O("AIR")->O("Tphase")->Q("x", "O2")->set(0.2);
O("AIR")->O("Tphase")->Q("x", "H2O")->set(0.01);
// Metal makeup
O("M_MAKEUP")->Q("T")->set(200.0 + 273.15, "K");
O("M_MAKEUP")->S("flowoption")->set("Nx");
my_cast<stream *>(O("M_MAKEUP"), CURRENT_FUNCTION)->clearcomposition();
O("M_MAKEUP")->O("Tphase")->Q("ndot")->set(2.0, "kmol/h");
O("M_MAKEUP")->O("Tphase")->Q("x", "Fe")->set(1.0);
diagnostic(3, "Unit operations inputs");
O("CAP")->Q("recovery")->set(0.95);
O("CAP")->Q("purity")->set(0.9);
O("COMB")->Q("eta")->set(0.5);
O("HX")->Q("U")->set(500.0, "W/(m2*K)");
O("OX")->S("option")->set("DH");
O("OX")->Q("deltaP")->set(0.0, "mbar");
O("OX")->Q("duty")->set(0.0, "W");
O("OX")->O("reactions", 0)->I("keycomp")->set_val(components.lookup("O2"));
*O("OX")->O("reactions", 0)->Q("z") = 0.7;
O("SEPARATOR")->S("option")->set(std::string("D"));
*O("SEPARATOR")->Q("deltaP") = Qdouble(0.0, "bar");
*O("SEPARATOR")->Q("T") = Qdouble(200.0 + 273.15, "K");
for (int i = 0; i < NCOMPONENTS; i++) {
*O("SEPARATOR")->Q("outSplit", 0, i) = 0.01;
} // for each component
diagnostic(3, "Initializing cut streams");
// Initialize depleted air
O("DAIR")->S("flowoption")->set("Nx");
O("DAIR")->Q("T")->set(1400.0 + 273.15, "K");
my_cast<stream *>(O("DAIR"), CURRENT_FUNCTION)->clearcomposition();
O("DAIR")->O("Tphase")->Q("ndot")->set(150.0, "kmol/h");
O("DAIR")->O("Tphase")->Q("x", "N2")->set(0.79);
O("DAIR")->O("Tphase")->Q("x", "O2")->set(0.2);
O("DAIR")->O("Tphase")->Q("x", "H2O")->set(0.01);
// Initialize metal stream
O("M")->Q("T")->set(200.0 + 273.15, "K");
O("M")->S("flowoption")->set("Nx");
my_cast<stream *>(O("M"), CURRENT_FUNCTION)->clearcomposition();
O("M")->O("Tphase")->Q("ndot")->set(200.0, "kmol/h"); // about 5-fold excess
O("M")->O("Tphase")->Q("x", "Fe")->set(1.0);
diagnostic(3, "Defining cut streams");
addcut("M");
addcut("DAIR");
diagnostic(3, "Making selected outputs visible in GUI");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // clc::setup
template<class T> void clc<T>::makeuserassembly(std::list<assignment *>::iterator &p) {
static const int verbosityLocal = -1;
try {
diagnostic(2, " entered for " << tag());
long i(0);
// compute base results
// Thermal power input from fuel in terms of LHV
powerThFuel = LHV(O("FUEL"));
// Actual net electrical power production
power = *O("CAP")->Q("power") + *O("COMB")->Q("power");
// yield to electrical energy based on input fuel LHV
eta = power / powerThFuel;
// CO2 emissions per unit produced electrical energy
CO2 = *O("FLUE1")->O("Tphase")->Q("mdotcomps", "CO2") / power;
// inlet fuel mass flow
Q = *O("FUEL")->O("Tphase")->Q("mdot");
// residual molar fraction of oxygen in flue gas
flueO2 = *O("FLUE")->O("Tphase")->Q("x", "O2");
stoich_ratio = ((*O("COMB:S03:Tphase")->Q("ndotcomps", "CH4") * 2.0 +
*O("COMB:S03:Tphase")->Q("ndotcomps", "CO") * 0.5 +
*O("COMB:S03:Tphase")->Q("ndotcomps", "H2") * 0.5 +
*O("COMB:S03:Tphase")->Q("ndotcomps", "C16H34") * 24.5 +
*O("COMB:S03:Tphase")->Q("ndotcomps", "C") * 1.0) / 1.5) / *O("MEO:Tphase")->Q("ndotcomps", "Fe2O3");
MakeAssignment(*O("FUEL")->O("Tphase")->Q("ndot"), *O("FUEL")->O("Tphase")->Q("ndot") * pow(setPower / power, 0.5), "Target electrical power production");
MakeAssignment(*O("AIR")->O("Tphase")->Q("ndot"), *O("AIR")->O("Tphase")->Q("ndot") * stoich_ratio, "Maintain stechiometric ratio of Fe2O3");
MakeAssignment(*O("HX")->Q("U"), *O("HX")->Q("U") * pow((*O("DAIR")->Q("T") - Qdouble(200.0 + 273.15, "K")) / (*O("DAIR")->Q("T") - *O("COLD_DAIR")->Q("T")), 0.1), "Set hot side outlet temperature");
MakeAssignment(*O("M_MAKEUP")->O("Tphase")->Q("ndot"), *O("M_MAKEUP")->O("Tphase")->Q("ndot") * (*O("OX")->Q("T") / Qdouble(1500.0, "K")), "Set air reactor temperature");
} // try
catch (error &e) {
e.append(CURRENT_FUNCTION);
throw;
} // catch
} // clc::makeuserassembly
template<> std::string clc<coal>::type_("clc<coal>");
template<> std::string clc<natural_gas>::type_("clc<natural_gas>");
template<> std::string clc<gasoil>::type_("clc<gasoil>");
// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////// registrar_mymodels /////////////////////////////
// /////////////////////////////////////////////////////////////////////////////
class registrar_mymodels : public registrar {
private:
static bool done_;
public:
registrar_mymodels(void);
}; // class registrar_mymodels
registrar_mymodels::registrar_mymodels(void) {
static const int verbosityLocal = 0;
diagnostic(2, "Entered");
if (!done_) {
diagnostic(3, "Registering");
model_factory().Register<reformer>("reformer");
model_factory().Register<separation<1> >("separation<1>");
model_factory().Register<separation<5> >("separation<5>");
model_factory().Register<conversion>("conversion");
model_factory().Register<deltah<coal> >("deltah<coal>");
model_factory().Register<deltah<pure_carbon> >("deltah<pure_carbon>");
model_factory().Register<deltah<pure_methane> >("deltah<pure_methane>");
model_factory().Register<deltah<pure_CO> >("deltah<pure_CO>");
model_factory().Register<deltah<pure_hydrogen> >("deltah<pure_hydrogen>");
model_factory().Register<deltah<natural_gas> >("deltah<natural_gas>");
model_factory().Register<deltah<gasoil> >("deltah<gasoil>");
model_factory().Register<reactionC16H34_TC>("reactionC16H34_TC");
model_factory().Register<reactionC16H34_decomp>("reactionC16H34_decomp");
model_factory().Register<reactionC_decomp>("reactionC_decomp");
model_factory().Register<reactionFe_OX>("reactionFe_OX");
model_factory().Register<reactionFe_RED>("reactionFe_RED");
model_factory().Register<pre<coal> >("pre<coal>");
model_factory().Register<pre<natural_gas> >("pre<natural_gas>");
model_factory().Register<pre<gasoil> >("pre<gasoil>");
model_factory().Register<post<coal> >("post<coal>");
model_factory().Register<post<natural_gas> >("post<natural_gas>");
model_factory().Register<post<gasoil> >("post<gasoil>");
model_factory().Register<oxy<coal> >("oxy<coal>");
model_factory().Register<oxy<natural_gas> >("oxy<natural_gas>");
model_factory().Register<oxy<gasoil> >("oxy<gasoil>");
model_factory().Register<clc<coal> >("clc<coal>");
model_factory().Register<clc<natural_gas> >("clc<natural_gas>");
model_factory().Register<clc<gasoil> >("clc<gasoil>");
done_ = true;
}
} // registrar_mymodels::registrar_mymodels
bool registrar_mymodels::done_(false);
static registrar_mymodels r_;
const char *default_type = "pre<natural_gas>";
void sensitivity_ndot(flowsheet<zero_zero> *pflowsheet) {
static const int verbosityLocal = 0;
diagnostic(-1,
"FUEL:Tphase.ndot kmol/h," <<
"power W, " <<
"eta, " <<
"Errors, " <<
"Warning, " <<
"Flowsheet iterations");
for (*pflowsheet->O("FUEL:Tphase")->Q("ndot") = Qdouble(9.0, "kmol/h");
*pflowsheet->O("FUEL:Tphase")->Q("ndot") < Qdouble(11.0, "kmol/h");
*pflowsheet->O("FUEL:Tphase")->Q("ndot") += Qdouble(0.1, "kmol/h")) {
pflowsheet->calculate(pflowsheet->maxit(), 0);
pflowsheet->report_messages();
diagnostic(-1,
pflowsheet->O("FUEL:Tphase")->Q("ndot")->operator()("kmol/h") << ", " <<
pflowsheet->Q("power")->val() << ", " <<
pflowsheet->Q("eta")->val() << ", " <<
pflowsheet->errors() << ", " <<
pflowsheet->warnings() << ", " <<
pflowsheet->I("NITER")->val());
} // end for sensitivity
} // sensitivity_ndot
#include "Q.cc"

