Tutorial for Plant Modeling

  1. Lets write the 1st agent:

    1. Create a file chpplant.py import abce and create a Plant class.

      import abce
      
      
      class CHPPlant(abce.Agent, abce.Firm):
      
    2. In def init(self): (not __init__!) we need to create some initial goods

      class CHPPlant(...):
      
          ...
          def init(self):
              self.create('biogas', 100)
              self.create('water', 100)
      
    3. Now we need to specify production functions. There are standard production functions like cobb-douglas and leontief already implemented, but our plants get more complicated production functions. We define the production function a firm uses in def init(self). So there add the following lines, class CHPPLant():

      class CHPPlant(...):
      
          def init(self):
              self.create('biogas', 100)
              self.create('water', 100)
      
              def production_function(biogas, water):
                  electricity = biogas ** 0.25 * water ** 0.5
                  steam = min(biogas, water)
                  biogas = 0
                  water = 0
                  return locals()
      
              self.production_function = production_function
      

    The def production_function(biogas, water): returns the production result as a dictionary. (try print(production_function(10, 10))). Each key is a good that is produced or what remains of a good after the production process. If goods are used up they must be set to 0. For example the function above creates electricity and steam. Electricity is produced by a cobb-douglas production function. While steam is the minimum between the amount of water and fuel used.

    The production_function function is local function in the init method. Make sure the return locals() is part of the def production_function(): not of the def init(self): method.

    1. In order to produce create a production method in class CHPPlant(): insert the following code right after the def init(self): method:

      class CHPPlant(...):
           ...
           def production(self):
               self.produce(self.production_function, {'biogas': 100, 'water': 100})
      
    1. also add:

      class CHPPlant(...):
           ...
           def refill(self):
               self.create('biogas', 100)
               self.create('water', 100)
      
  1. Create a file start.py to run this incomplete simulation.

    1. Import abce and the plant:

      import abce
      from chpplant import CHPPlant
      
    2. Create a simulation instance:

      simulation = abce.Simulation()
      
    3. Build an a plant

      chpplant = simulation.build_agents(CHPPlant, 'chpplant', number=1)
      

      With this we create 1 agent of type CHPPLANT, it’s group name will be chpplant and its number 0. Therefore its name is the tuple (‘chpplant’, 0)

    1. Loop over the simulation:

      for r in range(100):
          simulation.advance_round(r)
          chpplant.production()
          chpplant.panel_log(goods=['electricity', 'biogas', 'water', 'steam'], variables=[])
          chpplant.refill()
      
      simulation.graphs()
      simulation.finalize()
      

    This will tell the simulation that in every round, the plant execute the production method we specified in CHPPLant. Then it refills the input goods. Lastly, it creates a snapshot of the goods of chpplant as will be specified in (e).

    simulation.advance_round(r) sets the time r. Lastly :py:`simulation.graphs()` or simulation.finalize() tells the simulation that the loop is done. Otherwise the program hangs at the end.

  1. To run your simulation, the best is to use the terminal and in the directory of your simulation type python start.py. In SPYDER make sure that BEFORE you run the simulation for the first time you modify the ‘Run Setting’ and choose ‘Execute in external System Terminal’. If you the simulation in the IDE without making this changes the GUI might block.
  1. Lets modify the agent so he is ready for trade

    1. now delete the refill function in CHPPlant, both in the agent and in the actionlist delete chpplant.refill()

    2. let’s simplify the production method in CHPPlant to

      def production(self):
          self.produce_use_everything()
      
    3. in init we create money with self.create(‘money’, 1000)

  1. Now let’s create a second agent ADPlant.

    1. copy chpplant.py to applant.py and

    2. in adplant.py change the class name to ADPlant

    3. ADPlant will produce biogas and water out of steam and electricity. In order to achieve this forget about thermodynamics and change the production function to

      def production_function(steam, electricity):
          biogas = min(electricity, steam)
          water = min(electricity, steam)
          electricity = 0
          steam = 0
          return locals()
      
    4. Given the new technology, we need to feed different goods into our machines. Replace the production step

      def production(self):
          self.produce(self.production_function, {'steam': self['steam'], 'electricity': self['electricity']})
      

      self[‘steam’], looks up the amount of steam the company owns. self.not_reserved[‘steam’], would look up the amount of steam a company owns minus all steam that is offered to be sold to a different company.

    5. ADPlant will sell everything it produces to CHPPlant. We know that the group name of chpplant is ‘chpplant and its id number (id) is 0. Add another method to the ADPlant class.

      def selling(self):
          amount_biogas = self['biogas]
          amount_water = self['water']
          self.sell(('chpplant', 0), good='water', quantity=amount_water, price=1)
          self.sell(('chpplant', 0), good='biogas', quantity=amount_biogas, price=1)
      

      This makes a sell offer to chpplant.

    6. In CHPPlant respond to this offer, by adding the following method.

      def buying(self):
          water_offer = self.get_offers('water')[0]
          biogas_offer = self.get_offers('biogas')[0]
      
          if (water_offer.price * water_offer.quantity +
                  biogas_offer.price * biogas_offer.quantity < self['money']):
              self.accept(water_offer)
              self.accept(biogas_offer)
          else:
              quantity_allocationg_half_my_money = self['money'] / water_offer.price
              self.accept(water_offer, min(water_offer.quantity, quantity_allocationg_half_my_money))
              self.accept(biogas_offer, min(biogas_offer, self['money']))
      

      This accepts both offers if it can afford it, if the plant can’t, it allocates half of the money for either good.

    7. reversely in CHPPlant:

      def selling(self):
          amount_electricity = self['electricity']
          amount_steam = self['steam']
          self.sell(('adplant', 0), good='electricity', quantity=amount_electricity, price=1)
          self.sell(('adplant', 0), good='steam', quantity=amount_steam, price=1)
      
    8. and in ADPlant:

      def buying(self):
          el_offer = self.get_offers('electricity')[0]
          steam_offer = self.get_offers('steam')[0]
      
          if (el_offer.price * el_offer.quantity
              + steam_offer.price * steam_offer.quantity < self['money']):
              self.accept(el_offer)
              self.accept(steam_offer)
          else:
              quantity_allocationg_half_my_money = self['money'] / el_offer.price
              self.accept(el_offer, min(el_offer.quantity, quantity_allocationg_half_my_money))
              self.accept(steam_offer, min(steam_offer, self['money']))
      
  2. let’s modify start.py

    1. in start.py import thu ADPlant:

      from adplant import ADPlant
      

      and

      adplant = simulation.build_agents(ADPlant, 'adplant', number=1)
      
    2. change the action list to:

      for r in range(100):
          simulation.advance_round(r)
          (chpplant + adplant).production()
          (chpplant + adplant).selling()
          (chpplant + adplant).buying()
          chpplant.panel()
      
  3. now it should run again.