In this example two streams of type StreamIdealLiquidVapor are connected to a reaxtive FlashDrum unit. The Water Gas Shift reaction is set with complete conversion, and the duty of the reaction at constant temperature is computed.

Start from the Hello world tutorial, and perform these steps:

  1. in the #include section, add the following include files:

    #include <libpf/units/reactions.h> // for ReactionWaterGasShift
    #include <libpf/phases/phases.h> // required because the stream pulls in the phases from the object factory
    #include <libpf/ListComponents.h> // for components and NCOMPONENTS
    
  2. in the main function, remove the "Hello, world !" statement and replace it as follows:

  3. define carbon dioxide, water, carbon monoxide and hydrogen as components:

    components.addcomp(new purecomps::CO2);
    components.addcomp(new purecomps::water);
    components.addcomp(new purecomps::CO);
    components.addcomp(new purecomps::H2);
    
  4. create the feed and product streams:

    StreamIdealLiquidVapor feed(Libpf::User::Defaults("FEED", "reactants"));
    StreamIdealLiquidVapor product(Libpf::User::Defaults("PRODUCT", "Educts"));
    
  5. add the actual units manipulation:

    FlashDrum reactor(Libpf::User::Defaults("R1", "Test reactor")
      ("nReactions", 1)
      ("embeddedTypeReactions[0]", "ReactionWaterGasShift"));
    
    // connect
    std::string in("in");
    reactor.attach(feed, in);
    std::string out("out");
    reactor.attach(product, out);
    
    // initialize variables
    reactor.reactions[0]->z.set(1.0);
    reactor.T = feed.T = Value(370.0, "K");
    
    // calculate
    feed.calculate();
    reactor.calculate();
    
    // print selected results
    diagnostic(0, "mass in = " << feed.Tphase->mdot << " mass out = " << product.Tphase->mdot)
    diagnostic(0, "duty = " << reactor.duty);
    diagnostic(0, "amount of key component " << components[reactor.reactions[0]->keycomp.value()]->name() <<
                " in feed = " << feed.Tphase->mdotcomps[reactor.reactions[0]->keycomp.value()]);
    diagnostic(0, "amount of key component " << components[reactor.reactions[0]->keycomp.value()]->name() <<
                " in product = " << product.Tphase->mdotcomps[reactor.reactions[0]->keycomp.value()]);
    diagnostic(0, "Reaction heat per mass unit of key components = " <<
                reactor.duty /
                (feed.Tphase->mdotcomps[reactor.reactions[0]->keycomp.value()] -
                product.Tphase->mdotcomps[reactor.reactions[0]->keycomp.value()]));
    

This is the expected output:

* ****************** LIBPF 01.00.2193 [2015/06/07 15:28:37] ******************
* (C) Copyright 2004-2015 Paolo Greppi simevo s.r.l.
* ****************************************************************************
* All rights reserved; do not distribute without permission.
* ****************************************************************************

main * mass in = 3.55136496914 kg s^-1 mass out = 3.55136574074 kg s^-1
main * duty = -1573610.13975 m^2 kg s^-3
main * amount of key component CO2 in feed = 1.69790895062 kg s^-1
main * amount of key component CO2 in product = 0 kg s^-1
main * Reaction heat per mass unit of key components = -926793.005702 m^2 s^-2

How to get on

  1. check the FlashDrum chapter in the LIBPF™ SDK Classes overview

  2. Proceed to the tutorial for the Pasteurization example