You are here: Home Process library Carbon capture Source code

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"
Document Actions