You are here: Home Process library Inorganic Source code

Source code

C++ source code for process model

Qinorg6.cc — C++ source code, 27 kB (28165 bytes)

File contents

static const int verbositySubSystem = 0;

#define standalone 1

#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::H2);
    components.addcomp(new dipprComponent("Chemical1", ... ));
    components.addcomp(new dipprComponent("Chemical2", ... ));
    components.addcomp(new pdipprComponent("Chemical4",... ));
    components.addcomp(new dipprComponent("Salt1", ... ));
    components.addcomp(new pdipprComponent("Chemical3"... ));
    components.addcomp(new purecomps::...("Inert"));
    components.addcomp(new purecomps::...("Metal2"));
    components.addcomp(new purecomps::...("Salt2"));
    //    components.addcomp(new purecomps::FeCl2);
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // void setComponents(void)

class reactionSalt2 : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionSalt2(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionSalt2(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionSalt2() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionSalt2

std::string reactionSalt2::type_("reactionSalt2");

void reactionSalt2::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Metal2"));
    *Q("coeff", "Metal2") = -1.0;
    *Q("coeff", "Chemical1") = -2.0;
    *Q("coeff", "Salt2") = 1.0;
    *Q("coeff", "H2") = 1.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionSalt2::maketables

/// H2O + Chemical3 = Inert + 6 Chemical1
class reactionChemical3 : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionChemical3(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionChemical3(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionChemical3() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionChemical3

std::string reactionChemical3::type_("reactionChemical3");

void reactionChemical3::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Chemical3"));
    *Q("coeff", "H2O") = -2.0;
    *Q("coeff", "Chemical3") = -1.0;
    *Q("coeff", "Inert") = 1.0;
    *Q("coeff", "Chemical1") = 6.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionChemical3::maketables

/// Inert + 6 Chemical1 = Chemical3 + 2 H2O
class reactionInert : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionInert(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionInert(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionInert() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionInert

std::string reactionInert::type_("reactionInert");

void reactionInert::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Inert"));
    *Q("coeff", "Inert") = -1.0;
    *Q("coeff", "Chemical1") = -6.0;
    *Q("coeff", "H2O") = 2.0;
    *Q("coeff", "Chemical3") = 1.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionInert::maketables

/// Metal1 + 2 Chemical4 + 6 Chemical1 = Chemical3 + 4 H2O
class reactionMetal1 : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionMetal1(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionMetal1(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionMetal1() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionMetal1

std::string reactionMetal1::type_("reactionMetal1");

void reactionMetal1::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Metal1"));
    *Q("coeff", "Metal1") = -1.0;
    *Q("coeff", "Chemical4") = -2.0;
    *Q("coeff", "Chemical1") = -6.0;
    *Q("coeff", "H2O") = 4.0;
    *Q("coeff", "Chemical3") = 1.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionMetal1::maketables

/// Metal1 + 2 Chemical4 = Inert + 2 H2O
class reactionChemical4 : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionChemical4(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionChemical4(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionChemical4() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionChemical4

std::string reactionChemical4::type_("reactionChemical4");

void reactionChemical4::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Metal1"));
    *Q("coeff", "Metal1") = -1.0;
    *Q("coeff", "Chemical4") = -2.0;
    *Q("coeff", "Inert") = 1.0;
    *Q("coeff", "H2O") = 2.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionChemical4::maketables

/// Metal1 + H2O = Inert + 2H2
class reactionMetal1Decomposition : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionMetal1Decomposition(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionMetal1Decomposition(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionMetal1Decomposition() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionMetal1Decomposition

std::string reactionMetal1Decomposition::type_("reactionMetal1Decomposition");

void reactionMetal1Decomposition::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Metal1"));
    *Q("coeff", "Metal1") = -1.0;
    *Q("coeff", "H2O") = -2.0;
    *Q("coeff", "Inert") = 1.0;
    *Q("coeff", "H2") = 2.0;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionMetal1Decomposition::maketables

/// Eliminazione dell'acqua ossigenata
class reactionH2O2 : virtual public reactionYield {
private:
  static std::string type_;
  void maketables(long);
public:
  reactionH2O2(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), reactionYield(-1) {
    maketables(-1);
  }

  reactionH2O2(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), reactionYield(cid) {
    maketables(cid);
  }

  ~reactionH2O2() {}

  void setup(void) {}

  const std::string &type(void) const {
    return type_;
  }
};  // class reactionH2O2

std::string reactionH2O2::type_("reactionH2O2");

void reactionH2O2::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, "Entered for " << id());

    I("keycomp")->set_val(components.lookup("Chemical4"));
    *Q("coeff", "Chemical4") = -1.0;
    *Q("coeff", "H2O") = 1.0;
    *Q("coeff", "O2") = 0.5;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // reactionH2O2::maketables

// /////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////// inorg6 ///////////////////////////////////
// /////////////////////////////////////////////////////////////////////////////

class inorg6 : public modelBase, public flowsheet<zero_zero> {
private:
  static std::string type_;
  void maketables(long);
public:
  inorg6(const std::string &t, const std::string &d) : persistent_item_interface(-1), persistent_item(-1, t, d), modelBaseInterface(-1), modelBase(t, d) {
    maketables(-1);
  };
  inorg6(long cid) : persistent_item_interface(cid), persistent_item(cid, "", ""), modelBaseInterface(cid), modelBase(cid), flowsheet<zero_zero>(cid) {
    maketables(cid);
    readtables(cid);
  }

  // inputs
  Qdouble hum;          ///< Contenuto in acqua della torta
  Qdouble inert_fraction;    ///< Frazione massica di inerte nel prodotto in ingresso
  Qdouble metal2_fraction;   ///< Frazione massica dei metalli espressi come Metal2 nel prodotto in ingresso
  Qdouble pH;   ///< pH di acqua osmotizzata a lavaggi
  Qdouble w_C1;     ///< concentrazione in massa del Chemical1 commerciale
  Qdouble w_C2;    ///< concentrazione in massa del Chemical2 commerciale
  Qdouble w_C4;   ///< concentrazione in massa del Chemical4 commerciale

  Qdouble k0;          ///< rapporto di risospensione

  Qdouble k1C1;        ///< 1 attacco, specifico per Chemical1 al 100% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble k1C2;       ///< 1 attacco, specifico per Chemical2 al 100% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble k2C4;      ///< 2 attacco, specifico per Chemical4 al 100% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble k2C2;       ///< 2 attacco, specifico per Chemical2 al 100% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble k3C1;        ///< 3 attacco, specifico per Chemical1 al 100% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100

  // results
  Qdouble K1C1_xx;     ///< 1 attacco, specifico per Chemical1 al xx% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble K1C2_xx;    ///< 1 attacco, specifico per Chemical2 al yy% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble K2C4_zz;   ///< 2 attacco, specifico per Chemical4 al zz% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble K2C2_yy;    ///< 2 attacco, specifico per Chemical2 al yy% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100
  Qdouble K3C1_xx;     ///< 3 attacco, specifico per Chemical1 al xx% in termini di rapporto in massa rispetto al solido in ingresso alla sezione 100

  void makeuserassembly(std::list<assignment *>::iterator &p);
  void setup(void);
  const std::string &type(void) const {
    return type_;
  }

  bool supports_simultaneous(void);
  int smiter_precalc(void);
}; // inorg6

std::string inorg6::type_("inorg6");

void inorg6::maketables(long cid) {
  static const int verbosityLocal = 0;
  try {
    diagnostic(2, " entered for " << tag());

    MAKEQDOUBLE(hum, 0.3, "", "Contenuto in acqua della torta");
    MAKEQDOUBLE(inert_fraction, 0.4, "", "Frazione massica di inerte nel prodotto in ingresso");
    MAKEQDOUBLE(metal2_fraction, 100.0E-6, "", "Frazione massica dei metalli espressi come Metal2 nel prodotto in ingresso");
    MAKEQDOUBLE(pH, 2.0, "", "pH di acqua osmotizzata a lavaggi");
    MAKEQDOUBLE(w_C1, 0.4, "", "concentrazione in massa del Chemical1 commerciale");
    MAKEQDOUBLE(w_C2, 0.33, "", "concentrazione in massa del Chemical2 commerciale");
    MAKEQDOUBLE(w_C4, 0.33, "", "concentrazione in massa del Chemical4 commerciale");

    MAKEQDOUBLE(k0, 3.0, "", "rapporto di risospensione");
    MAKEQDOUBLE(k1C1, 0.3, "", "specifico Chemical1 puro ad attacco 1");
    MAKEQDOUBLE(k1C2, 0.3, "", "specifico Chemical2 puro ad attacco 1");
    MAKEQDOUBLE(k2C4, 0.165, "", "specifico Chemical4 puro ad attacco 2");
    MAKEQDOUBLE(k2C2, 0.1, "", "specifico Chemical2 puro ad attacco 2");
    MAKEQDOUBLE(k3C1, 0.01, "", "specifico Chemical1 puro ad attacco 3");

    // Non embedded objects
    if (cid == -1) {
      diagnostic(2, "Define unit operations");

      std::list<std::string> my_reactionlist = boost::assign::list_of("reactionInert");

      makeVertex<attacco<1> >("A1", "attacco 1", cid);
      makeVertex<attacco<1> >("A2", "attacco 2", cid);
      makeVertex<attacco<3> >("A3", "attacco 3", cid);

      makeVertex<mixer>("MIX1", "Miscelatore acque a bassa acidita", cid);
      makeVertex<mixer>("MIX2", "Miscelatore acque ad alta acidita", cid);

      diagnostic(2, "Define stream objects and connect");
      makeEdge<stream_LS_ideal>("S01", "Metal1 metalli Inert", "source", "out", "A1", "in1", cid);
      makeEdge<stream_LS_ideal>("S02", "Solido da 1 attacco", "A1", "out1", "A2", "in1", cid);
      makeEdge<stream_LS_ideal>("S03", "Solido da 2 attacco", "A2", "out1", "A3", "in1", cid);
      makeEdge<stream_LS_ideal>("S04", "Solido da 3 attacco", "A3", "out1", "sink", "in", cid);

      makeEdge<stream_L>("S10", "Reagenti attacco 1", "source", "out", "A1", "in2", cid);
      makeEdge<stream_L>("S11", "Reagenti attacco 2", "source", "out", "A2", "in2", cid);
      makeEdge<stream_L>("S12", "Reagenti attacco 3", "source", "out", "A3", "in2", cid);

      makeEdge<stream_LS_ideal>("S20", "Acque acidule da lavaggi in controcorrente post 3 attacco", "A3", "out3", "A1", "in3", cid);
      makeEdge<stream_LS_ideal>("S21", "Acqua osmotizzata a lavaggio post 2 attacco", "source", "out", "A2", "in3", cid);
      makeEdge<stream_LS_ideal>("S22", "Acqua osmotizzata a lavaggio post 3 attacco", "source", "out", "A3", "in3", cid);

      makeEdge<stream_LS_ideal>("S30", "Filtrato da filtrazione 1 attacco", "A1", "out2", "MIX1", "in", cid);
      makeEdge<stream_LS_ideal>("S31", "Acque acidule da lavaggio post 1 attacco", "A1", "out3", "MIX2", "in", cid);
      makeEdge<stream_LS_ideal>("S32", "Filtrato da filtrazione 2 attacco", "A2", "out2", "MIX1", "in", cid);
      makeEdge<stream_LS_ideal>("S33", "Acque acidule da lavaggio post 1 attacco", "A2", "out3", "MIX2", "in", cid);
      makeEdge<stream_LS_ideal>("S34", "Filtrato da filtrazione 3 attacco", "A3", "out2", "MIX1", "in", cid);

      makeEdge<stream_LS_ideal>("S40", "Acque ad alta acidita", "MIX1", "out", "sink", "in", cid);
      makeEdge<stream_LS_ideal>("S41", "Acque a bassa acidita", "MIX2", "out", "sink", "in", cid);
    }
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // inorg6::maketables

void inorg6::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();

    hum.set(0.3);
    inert_fraction.set(0.15);
    metal2_fraction.set(100.0E-6);
    pH.set(10.0);
    w_C1.set(0.2);
    w_C2.set(0.2);
    w_C4.set(0.33);
    k0.set(3.0);
    k1C2.set(0.2);
    k2C4.set(0.165);
    k2C2.set(0.1);

    Qdouble wHCl(pow(10.0, -pH.val()) * 36.4606 / 1000.0);

    // Metal1 metalli Inert
    O("S01")->Q("P")->set(1.0, "atm");
    O("S01")->Q("T")->set(25.0 + 273.15, "K");
    O("S01")->S("flowoption")->set("M");
    my_cast<stream *>(O("S01"), CURRENT_FUNCTION)->clearcomposition();
    *O("S01")->O("Tphase")->Q("mdotcomps", "Metal2") = Qdouble(1000.0, "kg/h") * metal2_fraction / (One - inert_fraction - metal2_fraction);
    *O("S01")->O("Tphase")->Q("mdotcomps", "Inert") = Qdouble(1000.0, "kg/h") * inert_fraction / (One - inert_fraction - metal2_fraction);
    *O("S01")->O("Tphase")->Q("mdotcomps", "Metal1") = Qdouble(1000.0, "kg/h");
    *O("S01")->O("Tphase")->Q("mdotcomps", "H2O") = (One - wHCl) * Qdouble(Qdouble(1000.0, "kg/h") / (One - inert_fraction - metal2_fraction)) * hum / (One - hum);
    *O("S01")->O("Tphase")->Q("mdotcomps", "Chemical2") = wHCl * Qdouble(1000.0, "kg/h") / (One - inert_fraction - metal2_fraction) * hum / (One - hum);

    // acqua osmotizzata a lavaggio post 2 attacco
    O("S21")->Q("P")->set(1.0, "atm");
    O("S21")->Q("T")->set(25.0 + 273.15, "K");
    O("S21")->S("flowoption")->set("Mw");
    my_cast<stream *>(O("S21"), CURRENT_FUNCTION)->clearcomposition();
    *O("S21")->O("Tphase")->Q("mdot") = Qdouble(1000.0, "kg/h") * (1.5 - hum / (one - hum));
    O("S21")->O("Tphase")->Q("w", "H2O")->set(one - wHCl);
    O("S21")->O("Tphase")->Q("w", "Chemical2")->set(wHCl);

    // acqua osmotizzata a lavaggio post 3 attacco
    O("S22")->Q("P")->set(1.0, "atm");
    O("S22")->Q("T")->set(25.0 + 273.15, "K");
    O("S22")->S("flowoption")->set("Mw");
    my_cast<stream *>(O("S22"), CURRENT_FUNCTION)->clearcomposition();
    *O("S22")->O("Tphase")->Q("mdot") = Qdouble(1000.0, "kg/h") * (1.5 - hum / (one - hum));
    O("S22")->O("Tphase")->Q("w", "H2O")->set(one - wHCl);
    O("S22")->O("Tphase")->Q("w", "Chemical2")->set(wHCl);

    k1C1 = 1.25 * 6.0 * components["Chemical1"]->MW() * *O("S01")->O("Tphase")->Q("mdotcomps", "Inert") / *O("S01")->O("Tphase")->Q("mdotcomps", "Metal1") / components["Inert"]->MW();
    K1C1_xx = k1C1 / w_C1;
    K1C2_xx = k1C2 / w_C2;
    K2C4_zz = k2C4 / w_C4;
    K2C2_yy = k2C2 / w_C2;
    K3C1_xx = k3C1 / w_C1;

    double attacco1(K1C1_xx.val() + K1C2_xx.val());
    double attacco2(K2C4_zz.val() + K2C2_yy.val());
    double attacco3(K3C1_xx.val());

    // 1 attacco
    O("S10")->Q("P")->set(5.0, "atm");
    O("S10")->Q("T")->set(25.0 + 273.15, "K");
    O("S10")->S("flowoption")->set("M");
    my_cast<stream *>(O("S10"), CURRENT_FUNCTION)->clearcomposition();
    O("S10")->O("Tphase")->Q("mdotcomps", "Chemical1")->set(1000.0 * k1C1.val(), "kg/h");
    O("S10")->O("Tphase")->Q("mdotcomps", "Chemical2")->set(1000.0 * k1C2.val(), "kg/h");
    O("S10")->O("Tphase")->Q("mdotcomps", "H2O")->set(1000.0 * attacco1 - 1000.0 * k1C1.val() - 1000.0 * k1C2.val(), "kg/h");

    // 2 attacco
    O("S11")->Q("P")->set(5.0, "atm");
    O("S11")->Q("T")->set(25.0 + 273.15, "K");
    O("S11")->S("flowoption")->set("M");
    my_cast<stream *>(O("S11"), CURRENT_FUNCTION)->clearcomposition();
    O("S11")->O("Tphase")->Q("mdotcomps", "Chemical4")->set(1000.0 * k2C4.val(), "kg/h");
    O("S11")->O("Tphase")->Q("mdotcomps", "Chemical2")->set(1000.0 * k2C2.val(), "kg/h");
    O("S11")->O("Tphase")->Q("mdotcomps", "H2O")->set(1000.0 * attacco2 - 1000.0 * k2C4.val() - 1000.0 * k2C2.val(), "kg/h");

    // 3 attacco
    O("S12")->Q("P")->set(5.0, "atm");
    O("S12")->Q("T")->set(25.0 + 273.15, "K");
    O("S12")->S("flowoption")->set("M");
    my_cast<stream *>(O("S12"), CURRENT_FUNCTION)->clearcomposition();
    O("S12")->O("Tphase")->Q("mdotcomps", "Chemical1")->set(1000.0 * k3C1.val(), "kg/h");
    O("S12")->O("Tphase")->Q("mdotcomps", "H2O")->set(1000.0 * attacco3 - 1000.0 * k3C1.val(), "kg/h");

    my_cast<genflash*>(O("A1")->O("A")->O("R"), CURRENT_FUNCTION)->resizeReactionList(3);
    my_cast<genflash*>(O("A1")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionMetal1Decomposition");
    my_cast<genflash*>(O("A1")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionSalt2");
    my_cast<genflash*>(O("A1")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionInert");
    O("A1")->O("A")->O("R")->O("reactions", 0)->Q("z")->set(0.001); // Metal1 + H2O = Inert + H2
    O("A1")->O("A")->O("R")->O("reactions", 1)->Q("z")->set(1.0); // Metal2 + 2 Chemical1 = Salt2 + H2
    O("A1")->O("A")->O("R")->O("reactions", 2)->Q("z")->set(0.98); // Inert + 6 Chemical1 = Chemical3 + 2 H2O

    my_cast<genflash*>(O("A2")->O("A")->O("R"), CURRENT_FUNCTION)->resizeReactionList(2);
    my_cast<genflash*>(O("A2")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionMetal1");
    my_cast<genflash*>(O("A2")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionChemical4");
    O("A2")->O("A")->O("R")->O("reactions", 0)->Q("z")->set(1.0); // Metal1 + 2 Chemical4 + 6 Chemical1 = Chemical3 + 4 H2O, keycomp = Metal1
    O("A2")->O("A")->O("R")->O("reactions", 1)->Q("z")->set(0.05); // Metal1 + 2 Chemical4 = Inert + 2 H2O, keycomp = Metal1

    my_cast<genflash*>(O("A3")->O("A")->O("R"), CURRENT_FUNCTION)->resizeReactionList(1);
    my_cast<genflash*>(O("A3")->O("A")->O("R"), CURRENT_FUNCTION)->addReaction("reactionInert");
    O("A3")->O("A")->O("R")->O("reactions", 0)->Q("z")->set(1.0); // Inert + 6 Chemical1 = Chemical3 + 2 H2O

    // initalizing streams to be cut
    // Acque acidule da lavaggi in controcorrente post 3 attacco
    O("S20")->Q("P")->set(5.0, "atm");
    O("S20")->Q("T")->set(25.0 + 273.15, "K");
    O("S20")->S("flowoption")->set("M");
    my_cast<stream *>(O("S20"), CURRENT_FUNCTION)->clearcomposition();
    O("S20")->O("Tphase")->Q("mdotcomps", "H2O")->set(1000.0, "kg/h");

    diagnostic(3, "Defining cut streams");
    addcut("S20");
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // inorg6::setup

void inorg6::makeuserassembly(std::list<assignment *>::iterator &p) {
  static const int verbosityLocal = -1;
  try {
    diagnostic(2, " entered for " << tag());

    long i(0);

    diagnostic(3, "inorg6 flowsheet specific equations");
    MakeAssignment(k3C1, 1.25 * 6.0 * components["Chemical1"]->MW() *
                   (*O("S03")->O("Tphase")->Q("mdotcomps", "Inert") +
                    components["Inert"]->MW() *
                    *O("S03")->O("Tphase")->Q("mdotcomps", "Chemical4")
                    / components["Chemical4"]->MW() / 2.0
                   ) / *O("S01")->O("Tphase")->Q("mdotcomps", "Metal1")
                   / components["Inert"]->MW(),
                   "Imposta lo specifico Chemical1 puro ad attacco 3");

    MakeAssignment(k1C1, 1.25 * 6.0 * components["Chemical1"]->MW() *
                   *O("S01")->O("Tphase")->Q("mdotcomps", "Inert") /
                   *O("S01")->O("Tphase")->Q("mdotcomps", "Metal1") /
                   components["Inert"]->MW(),
                   "Imposta lo specifico Chemical1 puro ad attacco 1");

    Qdouble current11 = Qdouble(1.0, "kg/s") * O("S11")->O("Tphase")->Q("mdot")->inactivated();
    MakeAssignment(*O("S11")->O("Tphase")->Q("mdotcomps", "H2O"),
                   current11 / ((*O("A2:A:S04:Xphase")->Q("mdot") / *O("A2:A:S04:Sphase")->Q("mdot")) / k0),
                   "Imposta il rapporto di risospensione in A2:A:S04");

    Qdouble current12 = Qdouble(1.0, "kg/s") * O("S12")->O("Tphase")->Q("mdot")->inactivated();
    MakeAssignment(*O("S12")->O("Tphase")->Q("mdotcomps", "H2O"),
                   current12 / ((*O("A3:A:S04:Xphase")->Q("mdot") / *O("A3:A:S04:Sphase")->Q("mdot")) / k0),
                   "Imposta il rapporto di risospensione in A3:A:S04");

    Qdouble current21 = Qdouble(1.0, "kg/s") * O("S21")->O("Tphase")->Q("mdot")->inactivated();
    MakeAssignment(*O("S21")->O("Tphase")->Q("mdot"),
                   current21 / ((*O("A2:L:S[0]:S03:Xphase")->Q("mdot") / *O("A2:L:S[0]:S03:Sphase")->Q("mdot")) / k0),
                   "Imposta il rapporto di risospensione in A2:L:S[0]:S03");

    Qdouble current22 = Qdouble(1.0, "kg/s") * O("S22")->O("Tphase")->Q("mdot")->inactivated();
    MakeAssignment(*O("S22")->O("Tphase")->Q("mdot"),
                   current22 / ((*O("A3:L:S[0]:S03:Xphase")->Q("mdot") / *O("A3:L:S[0]:S03:Sphase")->Q("mdot")) / k0),
                   "Imposta il rapporto di risospensione in A3:L:S[0]:S03");

    *O("A1")->Q("hum") = hum;
    *O("A2")->Q("hum") = hum;
    *O("A3")->Q("hum") = hum;

    Qdouble wHCl(pow(10.0, -pH.val()) * 36.4606 / 1000.0);

    *O("S01")->O("Tphase")->Q("mdotcomps", "Metal2") = Qdouble(1000.0, "kg/h") * metal2_fraction / (One - inert_fraction - metal2_fraction);
    *O("S01")->O("Tphase")->Q("mdotcomps", "Inert") = Qdouble(1000.0, "kg/h") * inert_fraction / (One - inert_fraction - metal2_fraction);
    *O("S01")->O("Tphase")->Q("mdotcomps", "H2O") = (One - wHCl) * Qdouble(Qdouble(1000.0, "kg/h") / (One - inert_fraction - metal2_fraction)) * hum / (One - hum);
    *O("S01")->O("Tphase")->Q("mdotcomps", "Chemical2") = wHCl * Qdouble(1000.0, "kg/h") / (One - inert_fraction - metal2_fraction) * hum / (One - hum);

    O("S21")->O("Tphase")->Q("w", "H2O")->set(one - wHCl);
    O("S21")->O("Tphase")->Q("w", "Chemical2")->set(wHCl);

    O("S22")->O("Tphase")->Q("w", "H2O")->set(one - wHCl);
    O("S22")->O("Tphase")->Q("w", "Chemical2")->set(wHCl);

    K1C1_xx = k1C1 / w_C1;
    K1C2_xx = k1C2 / w_C2;
    K2C4_zz = k2C4 / w_C4;
    K2C2_yy = k2C2 / w_C2;
    K3C1_xx = k3C1 / w_C1;
    Qdouble attacco1(K1C1_xx + K1C2_xx);
    Qdouble attacco2(K2C4_zz + K2C2_yy);
    Qdouble attacco3(K3C1_xx);
    *O("S10")->O("Tphase")->Q("mdotcomps", "Chemical2") = Qdouble(1000.0, "kg/h") * k1C2;
    *O("S10")->O("Tphase")->Q("mdotcomps", "H2O") = Qdouble(1000.0, "kg/h") * (attacco1 - k1C1 - k1C2);
    *O("S11")->O("Tphase")->Q("mdotcomps", "Chemical4") = Qdouble(1000.0, "kg/h") * k2C4;
    *O("S11")->O("Tphase")->Q("mdotcomps", "Chemical2") = Qdouble(1000.0, "kg/h") * k2C2;
    *O("S12")->O("Tphase")->Q("mdotcomps", "Chemical1") = Qdouble(1000.0, "kg/h") * k3C1;

    return;
  } // try
  catch (error &e) {
    e.append(CURRENT_FUNCTION);
    throw;
  } // catch
} // inorg6::makeuserassembly

bool inorg6::supports_simultaneous(void) {
  return true;
} // inorg6::supports_simultaneous

int inorg6::smiter_precalc(void) {
  return 5;
} // inorg6::smiter_precalc

const char *default_type = "inorg6";

// /////////////////////////////////////////////////////////////////////////////
// //////////////////////////// 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<reactionSalt2>("reactionSalt2");
    model_factory().Register<reactionInert>("reactionInert");
    model_factory().Register<reactionChemical4>("reactionChemical4");
    model_factory().Register<reactionMetal1Decomposition>("reactionMetal1Decomposition");
    model_factory().Register<reactionMetal1>("reactionMetal1");
    model_factory().Register<reactionH2O2>("reactionH2O2");
    model_factory().Register<reactionChemical3>("reactionChemical3");
    model_factory().Register<inorg6>("inorg6");

    done_ = true;
  }
} // registrar_mymodels::registrar_mymodels

bool registrar_mymodels::done_(false);

static registrar_mymodels r_;

#include "Q.cc"
Document Actions