03 MppLab V1.09

03 MppLab V1.09 preview image

1 collaborator

121210_portrait_of_garvin Garvin Boyle (Author)

Tags

atwood's machine 

Tagged by Garvin Boyle over 7 years ago

biophysical economics 

Tagged by Garvin Boyle over 7 years ago

ecological economics 

Tagged by Garvin Boyle over 7 years ago

maximum power principle 

Tagged by Garvin Boyle over 7 years ago

sustainability 

Tagged by Garvin Boyle over 7 years ago

sustainable economics 

Tagged by Garvin Boyle over 7 years ago

Model group Sustainability | Visible to everyone | Changeable by group members (Sustainability)
Model was written in NetLogo 5.0.5 • Viewed 812 times • Downloaded 44 times • Run 0 times
Download the '03 MppLab V1.09' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;-----------------------------------------------------------------------------|
;; SECTION A – AUTHOR IDENTIFICATION AND CODE ABSTRACT
;;-----------------------------------------------------------------------------|
;;
;; File Name: MppLab_V1.09.nlogo
;; By Orrery Software
;; Dated: 2017-03-25
;; Author contact:
;;   Garvin H Boyle
;;   orrery@rogers.com
;;   http://orrery-software.webs.com

;; As the author, I welcome questions, discussion of issues and suggestions
;;   for improvements.

;;-----------------------------------------------------------------------------|
;; This MppLab app is a laboratory in which students can study aspects 
;;   of the Maximum Power Principle (MPP) of H.T. Odum.

;; Please note that there was one aspect of this model that has caused some
;;   confusion when I explain it.  So, I have modified the terminology within
;;   the code and in the user interface, but the logic of the code has not 
;;   changed.  The confusion arose from my "borrowing" of the mechanics of 
;;   Atwood's Machine (the AM) to model the chemistry of digestion.  In 
;;   particular, I have invented a genetic factor that I am calling the
;;   "genetic energy transfer factor", or getf for short.  The logic
;;   for doing so is as follows:
;; - Odum argued that the dynamics of the AM are a great example of the
;;   trade-off between power and efficiency that is ubiquitous and a
;;   fundamental characteristic of ALL energy transfers.  He also argued that
;;   all energy transfers take time, and that the MPP is the common time
;;   regulator.
;; - I do not have empirical data for chemical digestion of one species by
;;   another.  In fact, to simulate a real-world trophic web, I would need data
;;   for all species trying to digest all other species.  And, for each such
;;   potential transfer, I would need both efficiency and speed of all such 
;;   energy transfers.
;; - On the other hand, we have an exquisitely precise analytic description of
;;   the energy transfer that happens in the AM, providing both efficiency and
;;   power (rate of energy transfer), and implicit therein is the time required
;;   to complete the transfer (called the drop time).
;; - So, I reasoned, I could emulate the efficiency and rate of energy transfer
;;   of digestion using the analytic description of the AM.  Since the mass of
;;   the two components of the AM are the critical factors, I have inserted a
;;   proxy for mass into all organisms, and I call that the genetic-energy-
;;   transfer-factor (or getf).  Whenever two organisms meet, I use their
;;   respective getf values to determine (a) who is predator and who is prey;
;;   (b) how long it takes for predator to digest prey; and (c) how much of the
;;   consumed energy of the prey is turned to waste heat, and how much is 
;;   retained as "still-useful-energy" in the predator.
;; - This does not give me a simulation of any particular act of digestion, but
;;   it does give me a template for emulation of all possible acts of digestion
;;   (all possible efficiencies and powers) and thus allows me to investigate 
;;   the nature of real-world trophic webs.

;; So, to be clear, the concept of mass that we all know and understand as 
;;   playing a significant role in biology IS NOT EXPLICITLY USED ANYWHERE IN 
;;   THIS MODEL.
;; BUT, the ability of one organism to digest another organism is determined by
;;   the interaction of the relative values of the getf factors.
;; AND, I use the mathematics of energy transfers that derives from the AM and
;;   the masses therein to compute the effects of getf values when they
;;   interact.

;; Mass in the AM is a proxy for getf in an organism, playing similar roles in 
;;   determining the dynamics of energetic interactions.

;;-----------------------------------------------------------------------------|
;; SECTION B – INITIAL DECLARATIONS OF GLOBALS AND BREEDS
;;-----------------------------------------------------------------------------|
;;
;;-----------------------------------------------------------------------------|
;; This program was developed on NetLogo Version 5.0.5
;;

;;-----------------------------------------------------------------------------|
;; code-determined global variables
globals
[
  ;; The version should be coded in this global variable to be included in
  ;;   output files.
  gs-Version
  
  ;; Note: Some global variables are declared inside of switches, sliders and 
  ;;   choosers when the interface is constructed and are not declared here.
  ;;   For the sake of clarity and completeness, they are noted here.
  
  ;; There are several uses of global variables:
  ;;  - Toggles (switches), and choosers which enable or disable features;
  ;;  - Numbers (in variables or sliders) which act as parameters;
  ;;  - Numbers (in variables) which collect data.
  ;;
  ;; Those marked as 'native Boolean' have values of true or false.
  ;; Those marked as 'numeric Boolean' have values of 1 or 0.
   
  ;;---------------------
  ;; MODELING ENVIRONMENT
  ;;---------------------
  
  ;; Assumed “Model Settings” on startup
  ;; horizontal wrap: on
  ;; vertical wrap: on
  ;; location of origin: centre
  ;; patch size: 9.63 pixels
  ;;-----------------------------------------------------------------------------|
  ;; Implicit global variables due to model settings – patch locations
  ;; min-pxcor  -15
  ;; max-pxcor   15
  ;; min-pycor  -15
  ;; max-pycor   15
  
  ;;----------------------------
  ;; SCENARIO SELECTION CONTROLS
  ;;----------------------------
  
  ;; gs-scenario         ;; Chooser, string converts to a scenario number
  g-scenario-number      ;; scenario no., 0 or 1; interpretation of gs-scenario
  ;; The possible scenarios.
  ge-scenario-herbivores ;; scenario 0
  ge-scenario-omnivores  ;; scenario 1

  ;; To halt a scenario at a pre-determined tick.
  ;; g-halt-at-tick       ;; Has it's own input box

  ;; Initialize the Pseudo Random Number Generator (PRNG).
  ;; g-use-this-seed      ;; Slider, ( 1 <= g-use-this-seed <= 100 )

  ;;-----------------------------------------------
  ;; BIOPHYSICAL SUB-SYSTEM CONTROLS AND PARAMETERS
  ;;-----------------------------------------------

  ;; Atwood's Machine parameters (Sliders)
  ;; g-drop-distance  ;; The distance a mass falls (D) in the AM.
  ;; g-acceleration   ;; Acceleration due to gravity (g).
  
  ;; Biophyscial life function parameters, autotrophs.
  ;; g-a-target-population  ;; The target carrying capacity [50, 10, 10000].
  g-a-initial-getf    ;; Initial getf (mass) of autotrophs on startup.

  ;; Biophyscial life function parameters, heterotrophs.
  gb-h-heterotrophs-on  ;; Creates heterotrophs
  g-h-initial-getf      ;; Initial getf (mass) of heterotrophs on startup.
  g-h-DAT   ;; Death Age Threshold
  ;; g-h-RET-factor     ;; Repreductive Energy Threshold Slider [0.1,0.01,1.0]
  ;; g-h-EPM-factor     ;; Energy Per Move (expended) Slider [0,.0001,.1]
  ;; g-h-ub-upper-bound ;; Upper bound on the ub gene Slider [2,.1,20]
  ;; g-h-lb-lower-bound ;; lower bound on the lb gene Slider [1,.1,4]
  ;; g-h-initial-population ;; The number of heterotrophs deployed by button.
  ;; g-h-mutation-factor    ;; delta-getf (delta-mass) Slider [0,.01,1]
  ;; g-h-satiation-factor   ;; feeding trigger Slider [0,.01,1]
  ;; gb-h-ub-gene-active ;; Switch activates ub gene for prey selection.
  ;; gb-h-lb-gene-active ;; Switch activates lb gene for prey selection.
  
    
  ;; List to hold counts of cause of death.
  gl-causes-of-death-a-per-tick
  gl-causes-of-death-a-cumulative
  gl-causes-of-death-h-per-tick
  gl-causes-of-death-h-cumulative

  ;; Global enumeration (ge-) codes codes for cause of death.
  ge-cod-none
  ge-cod-hunger
  ge-cod-fission
  ge-cod-old-age
  ge-cod-as-prey
  ge-cod-toggled

  ;; List to hold counts of cause of birth.
  gl-causes-of-birth-a-per-tick
  gl-causes-of-birth-a-cumulative
  gl-causes-of-birth-h-per-tick
  gl-causes-of-birth-h-cumulative

  ;; Global enumeration (ge-) codes for cause of birth.
  ge-cob-generated
  ge-cob-fission

  ;; Control on type of participation in OAM (b-is-in-oam).
  ;; Global enumeration (ge-) codes for status in oam.
  ge-not-in-oam                    ;; Should be assigned a zero.
  ge-rh-hoam                       ;; Should be assigned a one.
  ge-lh-hoam                       ;; Should be assigned a two.
  
  ;;-------------------------------------
  ;; END OF MODEL PARAMETERS AND CONTROLS
  ;;-------------------------------------
  
  ;;-------------------------------------
  ;; DATA COLLECTION AND DISPLAY CONTROLS
  ;;-------------------------------------
  
  ;; The following global variables are not model controls or paramaters, 
  ;;   but, rather, are variables used to collect data about the model 
  ;;   for display in the user interface, in some fashion (monitors or plots),
  ;;   or used to manage all of the debug routines and output.
  
  ;; SYSTEM-WIDE AGGREGATES
  ;; System of energy sinks.
  gl-sinks-per-tick
  gl-sinks-cumulative

  ;; Global enumeration (ge-) codes.
  ge-sinktype-source         ;; Xrg in, from Sun, creation/injection of agents. 
  ge-sinktype-unused-source  ;; Unused after feeding.
  ge-sinktype-a-move         ;; Autotrophs EPM
  ge-sinktype-h-move         ;; Heterotrophs EPM
  ge-sinktype-a-fiss-exergy  ;; 'Usable energy' transferred auto to D1/D2.
  ge-sinktype-h-fiss-exergy  ;; 'Usable energy' transferred hetero to D1/D2.
  ge-sinktype-a-food-exergy  ;; 'Usable energy' transferred auto to pred.
  ge-sinktype-h-food-exergy  ;; 'Usable energy' transferred hetero to pred.
  ge-sinktype-a-food-excess  ;; 'Excess food' exhausted by auto.
  ge-sinktype-h-food-excess  ;; 'Excess food' exhausted by hetero.
  ge-sinktype-a-kinetic      ;; 'Kinetic energy' exhausted by auto.
  ge-sinktype-h-kinetic      ;; 'Kinetic energy' exhausted by hetero.
  ge-sinktype-a-die-fiss     ;; Unused exergy of auto on fission.
  ge-sinktype-h-die-fiss     ;; Unused exergy of hetero on fission.
  ge-sinktype-a-die-hunger   ;; Remaining energy of auto on death.
  ge-sinktype-h-die-hunger   ;; Remaining energy of hetero on death.
  ge-sinktype-a-die-oldage   ;; Remaining energy of auto on death.
  ge-sinktype-h-die-oldage   ;; Remaining energy of hetero on death.
  ge-sinktype-a-die-asprey   ;; Remaining energy of auto on death.
  ge-sinktype-h-die-asprey   ;; Remaining energy of hetero on death.

  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Agent sets
  ga-oams   ;; Set of all turtles as lh-hoams
  
  ;; Counts
  g-no-of-autotrophs        ;; count of all autotrophs
  g-no-of-heterotrophs      ;; count of all heterotrophs
  g-no-of-oams              ;; count of all Open Atwood Machines
  g-no-of-a-as-rh-hoams     ;; count of all autotrophs in rh-hoams
  g-no-of-h-as-rh-hoams     ;; count of all heterotrophs in rh-hoams
  
  ;; Averages
  g-a-ave-getf              ;; getf (mass) of autotrophs
  g-a-ave-max-potential     ;; max pot of autotrophs
  g-a-ave-cur-potential     ;; current pot of autotrophs

  g-h-ave-age               ;; age of heterotrophs
  g-h-ave-getf              ;; getf (mass) of heterotrophs
  g-h-ave-lb-gene           ;; gene controlling size of prey
  g-h-ave-ub-gene           ;; gene controlling size of prey
  g-h-ave-RET               ;; RET of heterotrophs
  g-h-ave-EPM               ;; EPM of heterotrophs
  g-h-ave-max-potential     ;; max pot of heterotrophs
  g-h-ave-cur-potential     ;; current pot of heterotrophs
  g-h-ave-BITE-total        ;; average bite of heterotrophs
  g-h-ave-BITE-xrg          ;; portion to exergy
  g-h-ave-BITE-kinetic      ;; portion to kinetic energy

  g-h-ave-Eu                ;; Odum's efficiency of OAMs
  g-h-ave-max-dt            ;; maximum drop time of OAMs
  g-h-ave-cur-dt            ;; current drop time of OAMs
  g-h-ave-rem-dt            ;; remaining drop time of OAMs
  g-h-ave-dt-ratio          ;; ratio rem/max dt of OAMs

  ;; SWITCHES - These are declared in the switch itself, and so are 
  ;;   commented out here.  They are all native Booleans, having values of
  ;;   true or false.
  gb-stabilize-autotrophs      ;; Enables additional autotrophs to be sprouted.
  ;; gb-plot-data              ;; Enables plotting

  ;; Other - built-in or declared implicitly in plot interface items
  ;; See each plot design dialogue.

  ;;--------------------------
  ;; DATA CAPTURE TO CSV FILES
  ;;--------------------------

  ;; CSV means "Comma Separated Values"
  ;; 
  
  ;;---------------
  ;; DEBUG CONTROLS
  ;;---------------
  
  gb-debug-on                 ;; Numeric Boolean, opens debug log file, 0 or 1.
  gs-debug-status             ;; for monitor, '1 (On)' or '0 (Off)', 
  ;; gs-debug-step-chooser    ;; Chooser, used with gb-debug-flow-on
  gb-debug-flow-on            ;; Numeric Boolean, in association with chooser, 
  gs-log-file-name            ;; name of the debug log file
                              ;;   opens flow to log file
]


;;-----------------------------------------------------------------------------|
;; Attributes of patches
patches-own 
[
  ;; BUILT-IN ATTRIBUTES 
  ;; pxcor        ;; min-pxcor <= pxcor < max-pxcor
  ;; pycor        ;; min-pxcor <= pxcor < max-pxcor 
  ;; pcolor       ;; color of this patch ( 0 <= color < 140 ) 
  ;; plabel       ;; label of this patch
  ;; plabel-color ;; color of this patch's label ( 0 <= label-color < 140 ) 
   
  ;; MppLab-DETERMINED ATTRIBUTES
  ;; Nil.
]

;;-----------------------------------------------------------------------------|
;; Attributes of links
;; nil
;; I don't understand links and did not use any.

;;-----------------------------------------------------------------------------|
;; Turtles and breeds
breed [ autotrophs    autotroph ]
breed [ heterotrophs  heterotroph ]

;;-----------------------------------------------------------------------------|
;; Attributes of autotrophs
autotrophs-own 
[
  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; fixed id number
  ;; breed       ;; to which breed this turtle belongs [autotroph]
  ;; heading     ;; 0 <= heading < 360, 0 = north
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; size        ;; size relative to a patch, default is 1
  ;; shape       ;; a shape chosen from the shape library
  ;; color       ;; color of this turtle ( 0 <= color < 140 )
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; hidden?     ;; true or false
  ;; label       ;; label of this turtle
  ;; label-color ;; color of this turtle's label ( 0 <= label-color < 140 )
  
  ;; USER-DETERMINED ATTRIBUTES
  ;; Associated with autotroph dynamics.
  mas-who              ;; serial number of parent autotroph.
  default-colour       ;; as it says
  ;; getf is short for genetic-energy-transfer-factor, proxy for mass in the AM.
  getf                 ;; the getf (mass) in this HOAM
  cause-of-death       ;; for statistical purposes
  b-is-ready-to-die    ;; old (in age) or starved (in exergy)

  ;; An autotroph can be unassociated, or in the role of prey in an OAM, 
  ;;   i.e. as an RH-HOAM.

  ;; Unassociated dynamics.
  max-potential     ;; maximum potential energy
  cur-potential     ;; amount of high-grade gravitational potential energy
  
  ;; Associated with RH-HOAM dynamics.
  b-is-in-oam       ;; 0 = no; 1 = as RH-HOAM
  pred-who          ;; the who number of the predator, i.e. the rh-haom
  trophic-level-floated ;; trophic level of this autotroph
]

;;-----------------------------------------------------------------------------|
;; Attributes of heterotrophs
heterotrophs-own 
[
  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; fixed id number
  ;; breed       ;; to which breed this turtle belongs [heterotroph]
  ;; heading     ;; 0 <= heading < 360, 0 = north
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; size        ;; size relative to a patch, default is 1
  ;; shape       ;; a shape chosen from the shape library
  ;; color       ;; color of this turtle ( 0 <= color < 140 )
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; hidden?     ;; true or false
  ;; label       ;; label of this turtle
  ;; label-color ;; color of this turtle's label ( 0 <= label-color < 140 )
  
  ;; USER-DETERMINED ATTRIBUTES
  ;; Associated with heterotroph.
  mas-who              ;; serial number of parent heterotroph.
  heterotroph-sn       ;; serial number of this heterotroph.
  age                  ;; age of this heterotroph
  default-colour       ;; as it says
  ;; getf is short for genetic-energy-transfer-factor, proxy for mass in the AM.
  getf                 ;; the getf (mass) in this heterotroph
  lb-genetic-factor    ;; gene to set lower bound on getf of prey.
  ub-genetic-factor    ;; gene to set upper bound on getf of prey.
  cause-of-death       ;; for statistical purposes
  RET                  ;; Reproductive Energy Threshold for this heterotroph
  EPM                  ;; Energy Per Move for this heterotroph

  b-is-ready-to-move      ;; 0 = no; 1 = ready to move
  b-is-ready-to-reproduce ;; mature (in age) and healthy (in exergy)
  b-is-ready-to-die       ;; old (in age) or starved (in exergy)

  ;; A heterotroph may be in a free-moving unassociated state (predator on the
  ;;   hunt), in an OAM as an RH-HOAM (captured prey), or in an OAM as a
  ;;   LH-HOAM (predatory eating prey).  Variables are layed out here to address
  ;;   four needs:
  ;; - unassociated heterotroph
  ;; - heterotroph in OAM as prey
  ;; - heterotroph in OAM as predator
  ;; - the OAM in which predator and prey are temporarily associated.
  ;;
  ;; Last two are used together.  I.e. the OAM variables are stored in the
  ;;   predator while the OAM exists.
  
  ;; Unassociated dynamics.
  max-potential
  cur-potential ;; amount of high-grade gravitational potential energy

  ;; Associated with OAM dynamics.
  b-is-in-oam           ;; 0 = no; 1 = as RH-HOAM; 2 = as LH-HOAM
  prey-who              ;; the who number of the prey, i.e. the rh-haom
  pred-who              ;; the who number of the predator, i.e. the lh-hoam
  no-of-prey-eaten      ;; the number of prey captured and eaten
  sum-of-t-plus-one     ;; an aggregator for trophic level data
  trophic-level-floated ;; trophic level of this heterotroph
  trophic-level-rounded ;; trophic level of this heterotroph

  Eu-in-oam             ;; Eu is H.T.Odum's efficiency (ML/MH)
  max-drop-time         ;; Drop time for this OAM.
  cur-drop-time         ;; Time since drop started.
  rem-drop-time         ;; Remaining drop time.
  drop-time-ratio       ;; Fraction of drop time remaining.
]

;;-----------------------------------------------------------------------------|
;; SECTION C – INITIALIZATION OR SETUP PROCEDURE( S )
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; The 'autostart' startup routine

to startup
  ;; This routine is to be executed by the observer.

  ;; The manual describes this routine as follows:
  ;; This procedure, if it exists, will be called when a model is first loaded in 
  ;;   the NetLogo application.  Startup does not run when a model is run headless 
  ;;   from the command line, or by parallel BehaviorSpace.

  ;; On loading the model, the debug feature is always off.
  set gb-debug-on 0
  set gs-debug-status "0 (Off)"
  
  ;; On loading the model, the model, the choosers, switches and sliders are
  ;;   always reset to the values that are known to work.  Only the chooser
  ;;   for the scenario is not reset.  The last saved 
  ;;   selection of scenario is persistant.  This allows the 'Reset Defaults'
  ;;   button to NOT reset the scenario.
  f-reset-default-parameters

  ;; Run the setup routine to initialize other globals.
  setup
end 

;;-----------------------------------------------------------------------------|
;; The setup button(s)

to setup
  ;; This routine is to be executed by the observer.

  ;; NOTE: The contents of switches, sliders, and choosers seem to be 
  ;;   immune to these 'clear' commands.
  clear-ticks
  clear-turtles
  clear-patches
  clear-drawing
  clear-all-plots
  clear-output
  ;; clear-globals   ;; Suppressed to make gb-debug-on value persistent.
  ;; NOTE: Instead of 'clear-globals', you must ensure all globals are 
  ;;   initialized properly in 'setup'.
  
  ;; import-drawing "01-B OrrSW.jpg"
  
  ;; The version should be coded in this global variable to be included in
  ;;   output files.
  set gs-Version "MppLab_V1.09" 

  ;; Debug features may be off or on depending on history.
  ;;   - Perhaps 'Setup' was called by 'to Startup'.
  ;;   - Perhaps 'setup' was called during a 'BehaviorSpace' run.
  ;;   - Perhaps 'setup' was called by a user-pushed 'setup' button.
  ;; Setup needs to handle some quasi-persistant values correctly regardless of
  ;;   the history.  For gb-debug-on, in particular, I want it to be 
  ;;   persistant so I can have debug output from the 'setup' routine routed
  ;;   to the debug log file, or to the command centre.
  
  ;; 'startup' automatically sets gb-debug-on to 0 when the application is first
  ;;   loaded.  I want to be able to (A) toggle debug on, then, (B) press 
  ;;   'setup' and watch the debug output of the 'setup' command.  The gb-debug-on
  ;;   must be persistant through the above 'clear' commands.  The debug log 
  ;;   file name and status, however, should not be persistent and must be 
  ;;   reset when setup runs, if appropriate.
  ifelse ( gb-debug-on = 1 )
  [
    ;; Debug is on due to user setting, so file name and status should be 
    ;;   reset.  I do this by turn the feature off then on.
    ;; First toggle it off, closing any remnant log file, if needed.
    f-toggle-debug
    ;; Then toggle it back on, opening a new time-stamped log file.
    f-toggle-debug
  ]
  ;; else
  [
    ;; Debug is off, possibly due to startup execution, possibly due to user 
    ;;   choice.
    ;; Ensure associated variables have compatible settings.
    set gb-debug-on 0              ;; Redundant but ensures consistency.
    set gs-debug-status "0 (Off)"  ;; Redundant but ensures consistency.
    set gb-debug-flow-on 0         ;; Step-specific flow is off.
    file-close-all                 ;; Close the debug log file.
    set gs-log-file-name "dummyname"
  ]
  
  ;; Now, do the standard check that is done at the start of each debuggable 
  ;;   routine.  This must follow the clear commands, which reset everything 
  ;;   except globals, switches, sliders and choosers.
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "setup" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-setup: Debug on; tick = " 0 ]
    [ set gb-debug-flow-on 0 ]
  ]

  ;; g-use-this-seed comes from a slider, and is persistant.
  random-seed g-use-this-seed      ;; Tells the PRNG to use this seed.
  
  ;; Declare values of hidden declarations from sliders.
  LOG-TO-FILE ( "" )
  LOG-TO-FILE ( "  Do-set: ATWOOD MACHINE PARAMETERS (Sliders):" )
  LOG-TO-FILE ( word  "  Do-set: g-drop-distance - " g-drop-distance )
  LOG-TO-FILE ( word  "  Do-set: g-acceleration - "  g-acceleration )
  LOG-TO-FILE ( "" )

  LOG-TO-FILE ( "  Do-set: AUTOTROPH POPULATION PARAMETERS (Sliders):" )
  LOG-TO-FILE ( word  "  Do-set: g-a-target-population - " g-a-target-population )
  LOG-TO-FILE ( "" )

  ;; Biophysical life function parameters, autotrophs.
  set g-a-initial-getf 128 ;; Initial getf (mass) of autotrophs on startup.
  ;; g-a-target-population  ;; The target carrying capacity [50, 10, 10000].

  LOG-TO-FILE ( "  Do-set: INTERNAL AUTOTROPH PARAMETERS:" )
  LOG-TO-FILE ( word "  Do-set: g-a-initial-getf - " g-a-initial-getf )

  LOG-TO-FILE ( "" )
  LOG-TO-FILE ( "  Do-set: HETEROTROPH POPULATION PARAMETERS:" )
  
  ;; Biophysical life function parameters, autotrophs.
  set g-h-initial-getf 100 ;; Initial getf (mass) of heterotrophs on startup.
  ;; Biophysical life function parameters, heterotrophs.
  set g-h-DAT   1600       ;; Death Age Threshold
  ;; g-h-mutation-factor   ;; delta-getf (delta-mass); Slider [0,.01,1]
  ;; g-h-satiation-factor  ;; feeding trigger; Slider [0,.01,1]
  ;; g-h-ub-upper-bound    ;; Upper bound on the ub gene; Slider [2,.1,20]
  ;; g-h-lb-lower-bound    ;; lower bound on the lb gene; Slider [1,.1,4]
  
  LOG-TO-FILE ( word "  Do-set: g-h-initial-population - " g-h-initial-population )
  LOG-TO-FILE ( word "  Do-set: g-h-initial-getf - "       g-h-initial-getf )
  LOG-TO-FILE ( word "  Do-set: g-h-DAT - "                g-h-DAT )
  LOG-TO-FILE ( word "  Do-set: g-h-mutation-factor - "    g-h-mutation-factor )
  LOG-TO-FILE ( word "  Do-set: g-h-satiation-factor - "   g-h-satiation-factor )
  LOG-TO-FILE ( word "  Do-set: g-h-ub-upper-bound - "     g-h-ub-upper-bound )
  LOG-TO-FILE ( word "  Do-set: g-h-lb-lower-bound - "     g-h-lb-lower-bound )

  ;; List to hold counts of cause of death.
  set gl-causes-of-death-a-per-tick   ( n-values 6 [0] )
  set gl-causes-of-death-a-cumulative ( n-values 6 [0] )
  set gl-causes-of-death-h-per-tick   ( n-values 6 [0] )
  set gl-causes-of-death-h-cumulative ( n-values 6 [0] )
  ;; Enumeration codes for cause of death.
  set ge-cod-none     0
  set ge-cod-hunger   1
  set ge-cod-fission  2
  set ge-cod-old-age  3
  set ge-cod-as-prey  4
  set ge-cod-toggled  5
  
  ;; List to hold counts of cause of birth.
  set gl-causes-of-birth-a-per-tick   ( n-values 2 [0] )
  set gl-causes-of-birth-a-cumulative ( n-values 2 [0] )
  set gl-causes-of-birth-h-per-tick   ( n-values 2 [0] )
  set gl-causes-of-birth-h-cumulative ( n-values 2 [0] )
  ;; Enumeration codes for cause of birth.
  set ge-cob-generated 0
  set ge-cob-fission   1
  
  ;; Control on type of participation in OAM (b-is-in-oam).
  ;; These are enumeration values, having no meaning beyond the name.
  set ge-not-in-oam  0  ;; Should be assigned a zero.
  set ge-rh-hoam     1  ;; Should be assigned a one.
  set ge-lh-hoam     2  ;; Should be assigned a two.
  
  ;; System of energy sinks.
  set gl-sinks-per-tick ( n-values 20 [0] )
  set gl-sinks-cumulative ( n-values 20 [0] )
  ;; Global enumeration (ge-) variables.
  set ge-sinktype-source        0 ;; Xrg in, from Sun, creation/injection of agents. 
  set ge-sinktype-unused-source 1 ;; Unused after feeding.
  set ge-sinktype-a-move        2 ;; Autotrophs EPM
  set ge-sinktype-h-move        3 ;; Heterotrophs EPM
  set ge-sinktype-a-fiss-exergy 4 ;; 'Usable energy' transferred auto to D1/D2.
  set ge-sinktype-h-fiss-exergy 5 ;; 'Usable energy' transferred hetero to D1/D2.
  set ge-sinktype-a-food-exergy 6 ;; 'Usable energy' transferred auto to pred.
  set ge-sinktype-h-food-exergy 7 ;; 'Usable energy' transferred hetero to pred.
  set ge-sinktype-a-food-excess 8 ;; 'Excess food' transferred auto to pred.
  set ge-sinktype-h-food-excess 9 ;; 'Excess food' transferred hetero to pred.
  set ge-sinktype-a-kinetic    10 ;; 'Kinetic energy' exhausted by auto.
  set ge-sinktype-h-kinetic    11 ;; 'Kinetic energy' exhausted by hetero.
  set ge-sinktype-a-die-fiss   12 ;; Unused exergy of auto on fission.
  set ge-sinktype-h-die-fiss   13 ;; Unused exergy of hetero on fission.
  set ge-sinktype-a-die-hunger 14 ;; Remaining energy of auto on death.
  set ge-sinktype-h-die-hunger 15 ;; Remaining energy of hetero on death.
  set ge-sinktype-a-die-oldage 16 ;; Remaining energy of auto on death.
  set ge-sinktype-h-die-oldage 17 ;; Remaining energy of hetero on death.
  set ge-sinktype-a-die-asprey 18 ;; Remaining energy of auto on death.
  set ge-sinktype-h-die-asprey 19 ;; Remaining energy of hetero on death.
  
  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Agent sets
  set ga-oams turtles ;; Set of all turtles as lh-hoams
  
  ;; Counts
  set g-no-of-autotrophs      0  ;; count of all autotrophs
  set g-no-of-heterotrophs    0  ;; count of all heterotrophs
  set g-no-of-oams            0  ;; count of all Open Atwood Machines
  set g-no-of-a-as-rh-hoams   0  ;; count of all autotrophs in rh-hoams
  set g-no-of-h-as-rh-hoams   0  ;; count of all heterotrophs in rh-hoams
  
  ;; Averages - autotrophs
  set g-a-ave-getf            0  ;; getf (mass) of autotrophs
  set g-a-ave-max-potential   0  ;; max pot of autotrophs
  set g-a-ave-cur-potential   0  ;; current pot of autotrophs

  ;; Averages - heterotrophs
  set g-h-ave-age             0  ;; age of heterotrophs
  set g-h-ave-getf            0  ;; getf (mass) of heterotrophs
  set g-h-ave-lb-gene         0  ;; gene controlling size of prey
  set g-h-ave-ub-gene         0  ;; gene controlling size of prey
  set g-h-ave-RET             0  ;; RET of heterotrophs
  set g-h-ave-EPM             0  ;; EPM of heterotrophs
  set g-h-ave-max-potential   0  ;; max pot of heterotrophs
  set g-h-ave-cur-potential   0  ;; current pot of heterotrophs
  set g-h-ave-BITE-total      0  ;; average bite of heterotrophs
  set g-h-ave-BITE-xrg        0  ;; portion to exergy
  set g-h-ave-BITE-kinetic    0  ;; portion to kinetic energy

  ;; Averages - OAMs
  set g-h-ave-Eu              0  ;; Odum's efficiency of OAMs
  set g-h-ave-max-dt          0  ;; maximum drop time of OAMs
  set g-h-ave-cur-dt          0  ;; current drop time of OAMs
  set g-h-ave-rem-dt          0  ;; remaining drop time of OAMs
  set g-h-ave-dt-ratio        0  ;; ratio rem/max dt of OAMs

  ;; There are 3 scenarios possible
  set ge-scenario-herbivores  0  ;; Heterotrophs eat autotrophs
  set ge-scenario-omnivores   1  ;; Heterotrophs eat anything

  ;; Use the input from the chooser gs-scenario to invoke the selected scenario.
  f-set-scenario-number
  
  ;; For debugging the setup procedure, log the values of the globals.
  LOG-TO-FILE ( word "  Do-set: Scenario number - " g-scenario-number ) 
  LOG-TO-FILE ( word "  Do-set: Scenario name - "   gs-scenario )
  LOG-TO-FILE ( word "  Do-set: Random seed - "     g-use-this-seed )

  ;; For debugging the debug feature!!!  Suppressed now.
  ;; show ( word "SETUP: Debug Is " gb-debug-on )
  ;; show ( word "SETUP: Debug Status Is " gs-debug-status )
  ;; show ( word "SETUP: Step Chooser Is " gs-debug-step-chooser )
  ;; show ( word "SETUP: Flow Control Is " gb-debug-flow-on )

  set-default-shape autotrophs  "flower"  ;; pulled from shapes library
  set-default-shape heterotrophs  "arrow" ;; pulled from shapes library

  ask patches 
  [ 
    set pcolor brown
  ]
   
  reset-ticks      ;; restarts tick counter and runs setup commands within plots

  ;; Set the switches to default setup values.
  set gb-plot-data             true ;; Enables all plotting calls.
  set gb-stabilize-autotrophs  true ;; Enables autotroph stabilization.
  set gb-h-heterotrophs-on        1 ;; Enables heterotrophs.
  set gb-h-ub-gene-active      true ;; Activates ub gene for prey selection.
  set gb-h-lb-gene-active      true ;; Activates lb gene for prey selection.

  if( g-scenario-number = ge-scenario-herbivores )
  [
    set gb-plot-data            true ;; Enables all plotting calls.
    set gb-stabilize-autotrophs true ;; Enables autotroph stabilization.
    set gb-h-heterotrophs-on       1 ;; Enables heterotrophs.
    set gb-h-ub-gene-active     true ;; Activates ub gene for prey selection.
    set gb-h-lb-gene-active     true ;; Activates lb gene for prey selection.
  ]
  if( g-scenario-number = ge-scenario-omnivores )
  [
    set gb-plot-data            true ;; Enables all plotting calls.
    set gb-stabilize-autotrophs true ;; Enables autotroph stabilization.
    set gb-h-heterotrophs-on       1 ;; Enables heterotrophs.
    set gb-h-ub-gene-active     true ;; Activates ub gene for prey selection.
    set gb-h-lb-gene-active     true ;; Activates lb gene for prey selection.
  ]
  
  f-initialize-autotrophs
  if( gb-h-heterotrophs-on = 1 )
  [
    f-initialize-heterotrophs
  ]
  
  ;; This call requires that 'reset-ticks' be called first.
  ;; Update the aggregates again, after energetics computed.
  f-update-aggregates  ;; Totals and averages.
 
  ;; Clears unwanted zeros in plots.
  clear-all-plots
  setup-plots
  
  ;; Debug controls
  set gb-debug-flow-on 0 ;; Boolean, in association with chooser, turns debug LOG-TO-FILE on/off
  set g-halt-at-tick -1  ;; input variable to set a tick for stopping

  ;; ASSERT ( frb-EMgr-is-valid ) ( "EMgr validity check: D-Setup" ) -1
  LOG-TO-FILE "  Do-set: procedure completed" 

  ;; end of to-setup
end 

;;-----------------------------------------------------------------------------|
;; Set the scenario number using the input from the chooser.

to f-set-scenario-number
  ;; This routine is to be executed by the observer.

  set g-scenario-number ge-scenario-herbivores  ;; default
  if( gs-scenario = "Omnivores" )
    [ set g-scenario-number ge-scenario-omnivores ]

  ;; End f-set-scenario-number
end 


;;-----------------------------------------------------------------------------|
;; Initialize a population of autotrophs.

to f-initialize-autotrophs
  ;; This routine is to be executed by the observer.

  create-autotrophs g-a-target-population 
  [ 
    f-initialize-new-autotroph 
    
    set heading 0
    
    ;; Stagger the amount of high-grade exergy from a 
    ;;   half load to a full load.
    let exergy floor( max-potential / 2 )
    set cur-potential ( exergy + ( random exergy ) ) 
    
    ;; Move each to a random point.
    setxy random-xcor random-ycor

    f-store-data-in-sink ge-sinktype-source cur-potential
    f-increment-cob-list breed ge-cob-generated
  ]

  ;; End f-initialize-autotrophs
end 

;;-----------------------------------------------------------------------------|
;; Initialize a single autotroph.

to f-initialize-new-autotroph
  ;; This routine is to be executed by a autotroph.

  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; set automatically
  set heading 0  ;; direction of motion
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; size        ;; size relative to a patch, default is 1
  set color green

  ;; USER-DETERMINED ATTRIBUTES
  ;; Associated with autotroph dynamics.
  set mas-who -1                 ;; serial number of parent autotroph
  set default-colour      green  ;; distinctive colour for autotrophs
  set getf     g-a-initial-getf  ;; the getf (mass) in this autotroph
  set cause-of-death ge-cod-none ;; for statistical purposes
  set b-is-ready-to-die        0 ;; old (in age) or starved (in exergy)

  ;; Recalculate the life function controls that are scaled to getf (mass).
  f-set-getf-derived-autotroph-characters

  ;; An autotroph can only be in the role of prey, i.e. RH-HOAM.
  set b-is-in-oam ge-not-in-oam ;; 0 = no; 1 = RH-HOAM
  set pred-who             -1   ;; who number of predator haom.
  set trophic-level-floated 0   ;; trophic level of this autotroph

  ;; end f-initialize-new-autotroph
end 


;;-----------------------------------------------------------------------------|
;; Calculate all of the control variables that derive from getf.

to f-set-getf-derived-autotroph-characters
  ;; This routine is to be executed by an autotroph.
  
  ;; getf is the genetic-energy-transfer-factor.  In Atwood's Machine (the AM)
  ;;   the mass of the two weights determine this.  In organisms, some aspect
  ;;   of the composition of the prey and the digestive system of the predator
  ;;   determines this.  E.g. Panda bears and bamboo go together well, but 
  ;;   panda bears and eucalyptis leaves do not.  I call this the getf.
  
  
  ;; I use the mechanics of the AM to emulate the chemistry of digestion.  This
  ;;   affects both efficiency and duration of energy transfer.
  set max-potential ( getf * g-acceleration * g-drop-distance )
  LOG-TO-FILE ( word "  Do-pre-tick: A(max-xrg) - (" floor max-potential ")" )

  ;; End of f-set-getf-derived-autotroph-characters
end 

;;-----------------------------------------------------------------------------|
;; Initialize a population of heterotrophs.

to f-initialize-heterotrophs
  ;; This routine is to be executed by the observer.

  create-heterotrophs g-h-initial-population 
  [ 
    f-initialize-new-heterotroph 
    
    let heading-list [ 0 45 90 135 180 225 270 315 ]
    let delta-heading 0
    set delta-heading ( item ( random 8 ) heading-list )
    set heading ( heading + delta-heading )

    set age ( random g-h-DAT )
    
    ;; Stagger the amount of high-grade exergy from a 
    ;;   half load to a full load.
    let exergy floor( max-potential / 2 )
    set cur-potential ( exergy + ( random exergy ) ) 
    
    f-store-data-in-sink ge-sinktype-source cur-potential
    f-increment-cob-list breed ge-cob-generated

    ;; Make one step forward - well back from prey, giving them a head start.
    forward 1
  ]

  ;; End f-initialize-heterotrophs
end 

;;-----------------------------------------------------------------------------|
;; Initialize a single heterotroph.

to f-initialize-new-heterotroph
  ;; This routine is to be executed by a heterotroph.

  ;; BUILT-IN ATTRIBUTES
  ;; who         ;; set automatically
  set heading 0
  ;; xcor        ;; min-pxcor <= xcor < max-pxcor
  ;; ycor        ;; min-pxcor <= xcor < max-pxcor
  ;; pen-mode    ;; "up" or "down"
  ;; pen-size    ;; in pixels
  ;; size        ;; size relative to a patch, default is 1
  set color red

  ;; USER-DETERMINED ATTRIBUTES
  ;; Associated with heterotroph.
  set mas-who -1         ;; serial number of parent heterotroph
  set age              0 ;; age of this heterotroph
  set default-colour red ;; distinctive colour for heterotrophs
  set getf g-h-initial-getf ;; the getf (mass) in this heterotroph.
  set lb-genetic-factor g-h-lb-lower-bound ;; lower bound on prey getf (mass).
  set ub-genetic-factor g-h-ub-upper-bound ;; upper bound on prey getf (mass).
  set cause-of-death ge-cod-none ;; for statistical purposes

  ;; Compute value of controls scaled to getf (scaled to mass).
  f-set-getf-derived-heterotroph-characters

  ;; Set the logic trigger flags.
  set b-is-ready-to-move      1 ;; i.e. true
  set b-is-ready-to-reproduce 0 ;; i.e. false
  set b-is-ready-to-die       0 ;; i.e. false
  
  ;; Unassociated dynamics.
  set max-potential ( getf * g-acceleration * g-drop-distance )
  set cur-potential 0 ;; amount of gravitational potential energy 

  ;; Associated with OAM dynamics.
  set b-is-in-oam ge-not-in-oam ;; 0=no; 1=RH-HOAM; 2=LH-HOAM
  
  ;; Associated with OAM dynamics.
  ;; These contain data for the OAM consisting of coupled predator/prey.
  set prey-who        -1 ;; an invalid value; who number of prey haom.
  set pred-who        -1 ;; an invalid value; who number of predator haom.
  set no-of-prey-eaten      0 ;; the number of prey captured and eaten
  set sum-of-t-plus-one     0 ;; an aggregator for trophic level data
  set trophic-level-floated 1 ;; trophic level of this heterotroph
  set trophic-level-rounded 1 ;; trophic level of this heterotroph

  set Eu-in-oam        1 ;; Eu is Odum's efficiency.
  set max-drop-time    0 ;; Drop time for this OAM.
  set cur-drop-time    0 ;; Time since drop started.
  set rem-drop-time    0 ;; Remaining drop time.
  set drop-time-ratio  0 ;; Fraction of drop time remaining.

  ;; end f-initialize-new-heterotroph
end 

;;-----------------------------------------------------------------------------|
;; Calculate all of the control variables that derive from getf (mass).

to f-set-getf-derived-heterotroph-characters
  ;; This routine is to be executed by a heterotroph.
  
  ;; getf is the genetic-energy-transfer-factor.  In Atwood's Machine (the AM)
  ;;   the mass of the two weights determine this.  In organisms, some aspect
  ;;   of the composition of the prey and the digestive system of the predator
  ;;   determines this.  E.g. Panda bears and bamboo go together well, but 
  ;;   panda bears and eucalyptis leaves do not.  I call this the getf.
  
  
  ;; I use the mechanics of the AM to emulate the chemistry of digestion.  This
  ;;   affects both efficiency and duration of energy transfer.
  set max-potential ( getf * g-acceleration * g-drop-distance )
  set RET ( g-h-RET-factor * max-potential ) ;; Reproductive Energy Threshold
  set EPM ( g-h-EPM-factor * max-potential ) ;; Energy Per Move
  LOG-TO-FILE ( word "  Do-xxx: H(max-xrg,RET,EPM) - (" 
    floor max-potential "," 
    floor RET "," 
    floor EPM ")" )

  ;; End of f-set-getf-derived-heterotroph-characters
end 

;;-----------------------------------------------------------------------------|
;; Reset the default values for the interface-declared items.

to f-reset-default-parameters 
  ;; The observer executes this routine.

  ;; Switches, sliders and choosers implicitly declare global variables.  The
  ;;   values in these variables are parameters for the model, and many 
  ;;   combinations of those parameters are not sustainable.  However, the
  ;;   values in those user interface devices are stored with the model and
  ;;   are persistant across a save/load action.  The default values must
  ;;   be reset on load, or available to a user as a parameter set.  The
  ;;   purpose of this routine is to store at least one viable set of 
  ;;   parameter values.
  
  ;; Initialize the Pseudo Random Number Generator (PRNG).
  set g-use-this-seed 7
  
  ;; Restore the values of the lb and ub switches.
  set gb-h-ub-gene-active true
  set gb-h-lb-gene-active true
   
  ;;-----------------------------------------------
  ;; BIOPHYSICAL SUB-SYSTEM CONTROLS AND PARAMETERS
  ;;-----------------------------------------------

  ;; Slider range settings are shown as (Min,Increment,Max)
  set g-drop-distance        100       ;; ( 50,  5,   200 ) meters
  set g-acceleration           1       ;; (  1,  0.10, 12 ) m/s/s
  set g-a-target-population  500       ;; Target carrying capacity (50, 10, 10000).

  set g-h-initial-population 100       ;; # of heterotrophs (10,1,100) heterotrophs
  set g-h-RET-factor           0.95    ;; ( 0.10, 0.01, 1.00 ) Joules/Joule
  ifelse( g-scenario-number = ge-scenario-herbivores )
  [
    set g-h-EPM-factor         0.0050  ;; ( 0.00, 0.0001, 0.10 ) Joules/Joule
  ]
  ;; Else
  [
    set g-h-EPM-factor         0.0125  ;; ( 0.00, 0.0001, 0.10 ) Joules/Joule
  ]
  set g-h-mutation-factor      0.10    ;; delta-getf; Slider (0,0.01,1)
  set g-h-satiation-factor     0.98    ;; feeding trigger; Slider (0,0.01,1)
  ;; NOTE: The satiation-factor must be greater than the RET-factor.
  set g-h-ub-upper-bound       4       ;; Upper bound on the ub gene; Slider (2,0.1,20)
  set g-h-lb-lower-bound       1       ;; lower bound on the lb gene; Slider (1,0.1,4)
end 


;;-----------------------------------------------------------------------------|
;; SECTION D – GO OR MAIN-LOOP PROCEDURE( S )
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; The go button

to go
  ;; This routine is to be executed by the observer.

  ;; Stop codes:
  ;; All stop decisions must be here in the 'go' procedure, as it causes an
  ;;   exit from the current procdure only.

  if( g-halt-at-tick = ticks  ) 
  [
    set g-halt-at-tick -1
    stop
  ]
  
  let b-should-stop-now false
  if( count turtles <= 0 ) [ set b-should-stop-now true ]
  if( b-should-stop-now = true )
  [
    stop
  ]

  ;; MANUAL CHANGE FOR DEBUG
  ;; If needed, each check for validity can be enabled between steps.
  ;; They have been suppressed (turned into comments) for the sake 
  ;;   of speed of execution, but can be re-enabled if a bug has 
  ;;   somehow been re-introduced.
  ;; A single call to the validity check has been left active inside of the
  ;;   Do-Post-Tick step.  If it flags a problem, re-activate these to
  ;;   narrow down where the problem starts.
  
  ;; Major steps or functions, done once per tick, in order of execution.
  do-pre-tick
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-pre-tick." ) ]

  do-move
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-move." ) ]

  do-feed
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: do-feed." ) ]

  do-reproduce
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-reproduce." ) ]

  do-die
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-die." ) ]

  do-post-tick
  ;; if( frb-agents-are-all-valid = false ) 
  ;;   [ LOG-TO-FILE ( word "Agents failed validity test: Do-post-tick." ) ]
end 

;;-----------------------------------------------------------------------------|
;; D1 - do-pre-tick procedure( s )
;;-----------------------------------------------------------------------------|

to do-pre-tick
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "pre-tick" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-pre-tick: Debug on.; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Enter all commands that need to be done before a tick begins.
  ;; Supressed. f-update-aggregates
  
  ;; Advance the tick counter by 1 tick.
  ifelse( gb-plot-data = true )
  [
    ;; Advance the ticks by one and update the plots.
    tick
    ;; 'tick' is exactly the same as 'update-plots' except that the tick counter 
    ;;   is incremented before the plot commands are executed.
    
  ]
  ;; else
  [
    ;; Advance ticks by one but do not update the plots.
    tick-advance 1
  ]
  ;; End else

  ;; Once the data is plotted, the per-tick counts can be cleared.
  ;; List to hold counts of cause of death.
  set gl-causes-of-death-a-per-tick   ( n-values 6 [0] )
  set gl-causes-of-death-h-per-tick   ( n-values 6 [0] )
  ;; List to hold counts of cause of birth.
  set gl-causes-of-birth-a-per-tick   ( n-values 2 [0] )
  set gl-causes-of-birth-h-per-tick   ( n-values 2 [0] )

  ;; Reset the scenario number, in case the chooser has been changed.
  f-set-scenario-number
  
  ;; Clear the per-tick data for energy sinks.
  ;; This call must happen before the autotroph population is stabilized.
  set gl-sinks-per-tick ( n-values 20 [0] )
  
  ;; Stabilize the autotroph population at the target population size.
  f-stabilize-autotroph-population
  
  ;; Re-set g-h-satiation-factor in case g-h-RET-factor has changed.
  ;; Hunger must set in at or above the cost of reproduction.
  if( g-h-satiation-factor < g-h-RET-factor )
    [ set g-h-satiation-factor ( 0.01 + precision g-h-RET-factor 2 ) ]
  if( g-h-satiation-factor >= 0.99 ) 
    [ 
      set g-h-satiation-factor 0.99 
      set g-h-RET-factor 0.98
    ]
  
  if( gb-h-heterotrophs-on = 1 )
  [
    ask heterotrophs [ set age ( age + 1 ) ]
    LOG-TO-FILE ( word "  Do-pre-tick: heterotrophs aged." )
  ]
  
  LOG-TO-FILE ( word "  Do-pre-tick: Halt at tick - " g-halt-at-tick  ) 
  LOG-TO-FILE ( word "  Do-pre-tick: Current tick - " ticks ) 

  LOG-TO-FILE "  Do-pre-tick: Routine completed."
end 

;;-----------------------------------------------------------------------------|
;; Stabilize the autotroph population
;;-----------------------------------------------------------------------------|

to f-stabilize-autotroph-population
  ;; This routine is to be executed by the observer.

  if( gb-stabilize-autotrophs = true )
  [
    let current-a-population ( count autotrophs )
    if( current-a-population < g-a-target-population )
    [
      let add-this-many ( g-a-target-population - current-a-population )
      let this-patch patch 0 0
      ask this-patch
      [
        sprout-autotrophs add-this-many
        [
          f-initialize-new-autotroph
          set heading 0

          ;; Set the amount of high-grade exergy at a full load.
          set cur-potential max-potential 

          ;; Move each to a random point.
          setxy random-xcor random-ycor

          f-store-data-in-sink ge-sinktype-source cur-potential
          f-increment-cob-list breed ge-cob-generated
        ]
      ]
    ]
  ]

  ;; End f-stabilize-autotroph-population
end 
  
;;-----------------------------------------------------------------------------|
;; D2 – do-move procedure(s)
;;-----------------------------------------------------------------------------|

to do-move
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "move" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-move: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Implement 'arrow' behaviour from PSoup application.  I.e. a strong 
  ;;   probability of movement directly forward, and small probability of a 
  ;;   slight turn.  This represents the most effective search pattern for
  ;;   an arena that is wrapped on all sides.  Of course, it doesn't matter for
  ;;   the autotrophs that get energy from the sun, but it will matter 
  ;;   for the heterotrophs.
  
  let heading-list [ -45 0 0 0 0 0 0 0 0 45 ]

  ;; Autotrophs are plants, and normally would not move, but I don't want
  ;;   bias to leak in due to plants being stationary.  In order to ensure that
  ;;   plants are equally accessible to all heterotrophs regardless of their
  ;;   parentage or location of birth I want them to roam far from parents and
  ;;   circumstances of birth.  They must be independently discovered and eaten.

  ;; Then the heterotrophs move.
  if( gb-h-heterotrophs-on = 1 )
  [
    ;; Heterotrophs move later.  Same 'arrow' search pattern.
    ask heterotrophs
    [
      if( b-is-ready-to-move = 1 )
      [
        let delta-heading ( item ( random length heading-list ) heading-list )
        set heading ( heading + delta-heading )
        forward 1
        
        ;; The heterotroph converts some exergy to waste kinetic energy as it moves.
        f-heterotroph-expends-EPM
      ]  ;; End if( b-is-ready-to-move = 1 )
    ]  ;; End ask autotrophs

    ;; A heterotroph which is acting as lh-hoam (predator, eating) does not move
    ;;   but nevertheless expends energy on life functions.
    let feeding-predator-agentset ( heterotrophs with [b-is-in-oam = ge-lh-hoam] )
    if( count feeding-predator-agentset > 0 )
    [
      ask feeding-predator-agentset
      [
        ;; Exact the price of living from this predator.
        ;; The heterotroph converts some exergy to waste kinetic energy as it moves.
        f-heterotroph-expends-EPM
      ]  ;; End ask feeding-predator-agentset
    ]  ;; End if( count feeding-predator-agentset > 0 )
  ]  ;; End if( gb-h-heterotrophs-on = 1 )

  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-move: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; A heterotroph expends EPM of energy from the appropriate pool to the sink.

to f-heterotroph-expends-EPM
  ;; This routine is to be executed by a heterotroph.

  if( ( b-is-in-oam = ge-not-in-oam ) or
      ( b-is-in-oam = ge-lh-hoam ) )
  [
    ;; When a heterotroph moves it expends energy out of the pool of exergy.
    ;; Determine if this heterotroph has sufficient energy.
    ifelse ( cur-potential >= EPM )
    [
      f-store-data-in-sink ge-sinktype-h-move EPM
      set cur-potential ( cur-potential - EPM ) 
    ]
    ;; Else
    [
      f-store-data-in-sink ge-sinktype-h-move cur-potential
      set cur-potential 0 
      set cause-of-death ge-cod-hunger
    ]
    ;; End else
    LOG-TO-FILE ( word "  Do-move: H(heading,xrg,die-flag) - (" 
      heading "," floor cur-potential "," b-is-ready-to-die ")" )
  ]
  
  if( b-is-in-oam = ge-rh-hoam )
  [
    ;; When a heterotroph is associated with a heterotroph as prey in an OAM 
    ;;   then it expends energy out of the "rh" pool of exergy (-una-).
    ;; This would only take action in parasite mode.  
    ;;  - In predator mode the autotroph is not able to move or function, 
    ;;    and essentially behaves as dead until all of the exergy is removed.  
    ;;    this is the dedault mode.
    ;;  - In parasite mode the autotroph is not able to move, but still functions
    ;;    and expends exergy during each move.
    
    ;; TODO: Leave empty until parasite mode implemented.
  ]
  
  ;; End of f-heterotroph-expends-EPM  
end 

;;-----------------------------------------------------------------------------|
;; Store data in the lists of sinks.

to f-store-data-in-sink [ sinktype value ]
  ;; This routine is to be executed by anyone.
  
  ;; Record it in the per-tick list.
  let old-value ( item sinktype gl-sinks-per-tick )
  let new-value ( old-value + value )
  set gl-sinks-per-tick ( replace-item sinktype gl-sinks-per-tick new-value )

  ;; Record it in the cumulative list.
  set old-value ( item sinktype gl-sinks-cumulative )
  set new-value ( old-value + value )
  set gl-sinks-cumulative ( replace-item sinktype gl-sinks-cumulative new-value )
end 

;;-----------------------------------------------------------------------------|
;; Increment the count in the lists of causes of death.

to f-increment-cod-list [ breedtype codtype ]
  ;; This routine is to be executed by anyone.
  
  ifelse( breedtype = autotrophs )
  [
    ;; Record it in the per-tick list.
    let old-count ( item codtype gl-causes-of-death-a-per-tick )
    let new-count ( old-count + 1 )
    set gl-causes-of-death-a-per-tick 
      ( replace-item codtype gl-causes-of-death-a-per-tick new-count )
    
    ;; Record it in the cumulative list.
    set old-count ( item codtype gl-causes-of-death-a-cumulative )
    set new-count ( old-count + 1 )
    set gl-causes-of-death-a-cumulative 
      ( replace-item codtype gl-causes-of-death-a-cumulative new-count )
  ]
  ;; Else breed is heterotrophs
  [
    ;; Record it in the per-tick list.
    let old-count ( item codtype gl-causes-of-death-h-per-tick )
    let new-count ( old-count + 1 )
    set gl-causes-of-death-h-per-tick 
      ( replace-item codtype gl-causes-of-death-h-per-tick new-count )
    
    ;; Record it in the cumulative list.
    set old-count ( item codtype gl-causes-of-death-h-cumulative )
    set new-count ( old-count + 1 )
    set gl-causes-of-death-h-cumulative 
      ( replace-item codtype gl-causes-of-death-h-cumulative new-count )
  ]
  ;; End else
end 

;;-----------------------------------------------------------------------------|
;; Increment the count in the lists of causes of birth.

to f-increment-cob-list [ breedtype cobtype ]
  ;; This routine is to be executed by anyone.
  ifelse( breedtype = autotrophs )
  [
    ;; show cobtype
    ;; Record it in the per-tick list.
    let old-count ( item cobtype gl-causes-of-birth-a-per-tick )
    let new-count ( old-count + 1 )
    set gl-causes-of-birth-a-per-tick 
      ( replace-item cobtype gl-causes-of-birth-a-per-tick new-count )
    
    ;; Record it in the cumulative list.
    set old-count ( item cobtype gl-causes-of-birth-a-cumulative )
    set new-count ( old-count + 1 )
    set gl-causes-of-birth-a-cumulative 
      ( replace-item cobtype gl-causes-of-birth-a-cumulative new-count )
  ]
  ;; Else breed is heterotrophs
  [
    ;; Record it in the per-tick list.
    let old-count ( item cobtype gl-causes-of-birth-h-per-tick )
    let new-count ( old-count + 1 )
    set gl-causes-of-birth-h-per-tick 
      ( replace-item cobtype gl-causes-of-birth-h-per-tick new-count )
    
    ;; Record it in the cumulative list.
    set old-count ( item cobtype gl-causes-of-birth-h-cumulative )
    set new-count ( old-count + 1 )
    set gl-causes-of-birth-h-cumulative 
      ( replace-item cobtype gl-causes-of-birth-h-cumulative new-count )
  ]
  ;; End else
end 

;;-----------------------------------------------------------------------------|
;; D3 – do-feed procedure(s)
;;-----------------------------------------------------------------------------|

to do-feed
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "feed" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-feed: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  if( gb-h-heterotrophs-on = 1 )
  [
    ;; Heterotrophs feed on other HOAMs.
    ;; Heterotrophs feed second.
    ask heterotrophs
    [
      ASSERT ( breed = heterotrophs ) ( "Is not heterotroph." ) who
      ;; This predator may be in one of three states:
      ;;  - Currently hunting for prey.
      ;;  - Currently eating prey.
      ;;  - Currently being eaten by another predator.
      ifelse( b-is-in-oam = ge-not-in-oam )
      [ f-hunt-for-prey ]
      ;; Else - is in oam already.
      [ f-eat-or-be-eaten ]
      ;; End Else
    ] ;; End of ask heterotrophs
  ] ;; End of if( gb-h-heterotrophs-on = 1 )
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-feed: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; Heterotrophs hunt for prey.

to f-hunt-for-prey
  ;; This routine is to be executed by an heterotroph.
  ;; This heterotroph is not in an oam.  It is not feeding.  It is not being
  ;;   fed upon.  It will check whether suitable prey is within reach, and,
  ;;   if yes, will form an oam as the lh-hoam, and begin feeding upon such 
  ;;   prey.
   
  ;; Is this heterotroph already satiated?  Is it hungry?
  let satiation-level ( cur-potential / max-potential )
  ;; TODO: put satiation-factor in slider.
  ifelse( satiation-level < g-h-satiation-factor ) 
  [
    ;; It is hungry.
    LOG-TO-FILE ( "  Do-feed: Hunting." )
    ;; Establish which patch it is in.
    let my-who who
    let my-getf getf
    let lb-getf ( getf * lb-genetic-factor )
    let ub-getf ( getf * ub-genetic-factor )
      
    ;; Establish a list of potential prey.
    ;; Potential prey must be mobile (i.e. not already part of an immobile
    ;;   predator-prey feeding pair, an OAM).
    ;; Potential prey must be within reach, in this patch or an immediately 
    ;;   neighbouring patch.
    ;; Potential prey must have sufficient getf (proxy-mass) to act as an 
    ;;   RH-HOAM when forming an Open Atwood's Machine.  I.e. getf > my-getf.
    ;; Organism is not a potential prey for itself.
    
    ;; Within the above restrictions, some switches or operational choices
    ;;   restrict the prey list further.
    ;; - If the scenario allows onmivores, heterotrophs may eat heterotrophs.
    ;; - If the lb gene is active, the getf of the prey must be > lb-getf.
    ;; - If the ub gene is active, the getf of the prey must be < ub-getf.

    ;; A dummy let statement.
    let prey-list []
    
    ifelse( g-scenario-number = ge-scenario-omnivores )
    [
      ;; Heterotrophs can feed on other heterotrophs or autotrophs 
      ;;   (i.e. all turtles).
      set prey-list ( ( turtles-on neighbors ) with 
        [ ( b-is-in-oam = ge-not-in-oam ) and 
          ( who != my-who ) and 
          ( getf > my-getf ) ] )

      ;; Test the lb gene.
      if( ( any? prey-list ) and ( gb-h-lb-gene-active = true ) )
        [ set prey-list ( prey-list with [getf > lb-getf] ) ]

      ;; Test the ub gene.
      if( ( any? prey-list ) and ( gb-h-ub-gene-active = true ) )
        [ set prey-list ( prey-list with [getf < ub-getf] ) ]


      ;; Select the most energetic of available prey.
      if( any? prey-list )
        [
          set prey-list ( prey-list with 
            [cur-potential = ( max [cur-potential] of prey-list ) ] )
        ]
    ]
    ;; Else herbivores
    [
      ;; Heterotrophs feed on autotrophs only.
      set prey-list ( ( autotrophs-on neighbors ) with 
        [ ( b-is-in-oam = ge-not-in-oam ) and 
          ( who != my-who ) and 
          ( getf > my-getf ) ] )

      ;; Test the lb gene.
      if( ( any? prey-list ) and ( gb-h-lb-gene-active = true ) )
        [ set prey-list ( prey-list with [getf > lb-getf] ) ]

      ;; Test the ub gene.
      if( ( any? prey-list ) and ( gb-h-ub-gene-active = true ) )
        [ set prey-list ( prey-list with [getf < ub-getf] ) ]


      ;; Select the most energetic of available prey.
      if( any? prey-list )
        [
          set prey-list ( prey-list with 
            [cur-potential = ( max [cur-potential] of prey-list ) ] )
        ]
    ]
    ;; End else Herbivores
    
    if( any? prey-list )
    [
      ;; These two HOAMs (Halves of an Open Atwood's Machine) are now coupled
      ;;   together as an Open Atwood's Machine (OAM).  Using the terminology
      ;;   of the AM, the exergy in the RH-HOAM is transformed into:
      ;;     (a) kinetic energy that will be exhausted as waste heat; and 
      ;;     (b) gravitational potential energy as the mass of the LH-HOAM 
      ;;         is raised.
      
      ;; The two HOAMs are so linked and immobile until the consumption of 
      ;;   the RH-HOAM (i.e. the prey) is completed, at which time the predator
      ;;   will continue the hunt and the prey is removed from the model.

      let prey one-of prey-list
      
      ;; The hunt is successful.
      set prey-who ( [who] of prey )
      let predator-who ( [who] of self )
      ask prey
      [
        ;; Mark this HOAM as captured prey.
        if( breed = heterotrophs )
        [
          set b-is-ready-to-move 0
        ]
        set b-is-in-oam ge-rh-hoam
        set color violet
        set pred-who predator-who
      ]
      ;; Mark this HOAM as predator.
      set b-is-ready-to-move 0
      set b-is-in-oam ge-lh-hoam
      set color yellow
      face turtle prey-who
      LOG-TO-FILE ( word "  Do-feed: Captured - " prey )
      
      ;; Adjust the trophic level data for this predator.
      set no-of-prey-eaten ( no-of-prey-eaten + 1 )
      set sum-of-t-plus-one 
        ( sum-of-t-plus-one + ( 1 + ( [trophic-level-floated] of prey ) ) )
      set trophic-level-floated ( sum-of-t-plus-one / no-of-prey-eaten )
      set trophic-level-rounded round( trophic-level-floated )
      
      ;; The predator/prey pair are now locked in an OAM.
      ;; The predator takes a first bite.
      f-effect-per-tick-xrg-xfer-in-oam
    ]
  ]  ;; End of if( g-h-satiation-factor )
  ;; Else
  [
    LOG-TO-FILE ( word "  Do-feed: Satiated!  Not hunting." )
  ]
  ;; End Else
  
  ;; End of f-hunt-for-prey
end 

;;-----------------------------------------------------------------------------|
;; Effect the exergy transfer within the OAM associated with one tick of time.

to f-effect-per-tick-xrg-xfer-in-oam
  ;; This routine is to be executed by a heterotroph, in the role of lh-hoam.
  
  ASSERT ( b-is-in-oam = ge-lh-hoam ) ( "Not an lh-hoam." ) who
  let rh-hoam ( turtle prey-who )
  let prey-breed ( [breed] of rh-hoam )
  
  ;; getf stands for genetic-energy-transfer-factor, and is a proxy for
  ;;   mass in an AM.  So "heavy" and "light" are in reference to mass.
  let heavy-mass ( [getf] of rh-hoam )
  let light-mass ( [getf] of self    )
  set Eu-in-oam ( light-mass / heavy-mass )
  let mass-total ( heavy-mass + light-mass )
  let mass-diff  ( heavy-mass - light-mass )
  
  LOG-TO-FILE ( word "    Do-feed: self - " self )
  LOG-TO-FILE ( word "    Do-feed: rh-hoam - " rh-hoam )
  LOG-TO-FILE ( word "    Do-feed: light-mass - " light-mass )
  LOG-TO-FILE ( word "    Do-feed: heavy-mass - " heavy-mass )
  LOG-TO-FILE ( word "    Do-feed: Eu-in-oam - " Eu-in-oam )
  LOG-TO-FILE ( word "    Do-feed: mass-total - " mass-total )
  LOG-TO-FILE ( word "    Do-feed: mass-diff - " mass-diff )
  
  let max-rh-potential ( [max-potential] of rh-hoam )
  let cur-rh-potential ( [cur-potential] of rh-hoam )
  let numerator ( max-rh-potential - cur-rh-potential ) 
  
  LOG-TO-FILE ( word "    Do-feed: max-rh-potential - " max-rh-potential )
  LOG-TO-FILE ( word "    Do-feed: cur-rh-potential - " cur-rh-potential )
  LOG-TO-FILE ( word "    Do-feed: numerator - " numerator )

  let mass-assembly-ratio ( mass-diff / mass-total )
  let factor ( heavy-mass * g-acceleration * g-acceleration / 2 )
  let denominator ( mass-assembly-ratio * factor )

  LOG-TO-FILE ( word "    Do-feed: mass-assembly-ratio - " mass-assembly-ratio )
  LOG-TO-FILE ( word "    Do-feed: factor - " factor )
  LOG-TO-FILE ( word "    Do-feed: denominator - " denominator )

  let time ( ( numerator / denominator ) ^ 0.5 )
  let time-plus-one ( time + 1 )
  let time-plus-two ( time + 2 )
  
  LOG-TO-FILE ( word "    Do-feed: time - " time )
  LOG-TO-FILE ( word "    Do-feed: time-plus-one - " time-plus-one )

  set max-drop-time ( ( ( 2 * g-drop-distance ) / 
      ( g-acceleration * mass-assembly-ratio ) ) ^ 0.5 ) ;; Drop time for this OAM.
  set cur-drop-time    time ;; Effective time since drop started.
  set rem-drop-time    ( max-drop-time - cur-drop-time )
  set drop-time-ratio  ( rem-drop-time / max-drop-time ) ;; Fraction of drop time remaining.

  ;; The variable 'time' is the effective time, as if this OAM had started to 
  ;;   drop with current rh potential equal to its maximum. 
  ;; Now, I need to calculate, using the discrete time OAM formulae, the
  ;;   amount of potential that is transferred/transformed in the next tick.
  let delta-rh-potential 
    ( -1 * denominator * ( ( time ^ 2 ) - ( time-plus-one ^ 2 ) ) )
  ;; The sign has been reversed to make this a positive value.
  let next-delta-rh-potential 
    ( -1 * denominator * ( ( time-plus-one ^ 2 ) - ( time-plus-two ^ 2 ) ) )
  
  LOG-TO-FILE ( word "    Do-feed: delta-rh-potential - " delta-rh-potential )

  ;; I cannot remove more potential energy than is currently there.
  if( delta-rh-potential > cur-rh-potential )
    [ set delta-rh-potential cur-rh-potential ]
  
  LOG-TO-FILE ( word "    Do-feed: delta-rh-potential - " delta-rh-potential )

  ;; Use the efficiency to break this into potential and kinetic.
  let delta-lh-potential ( Eu-in-oam * delta-rh-potential )
  let delta-oam-kinetic ( delta-rh-potential - delta-lh-potential )
  
  LOG-TO-FILE ( word "    Do-feed: delta-lh-potential - " delta-lh-potential )
  LOG-TO-FILE ( word "    Do-feed: delta-oam-kinetic - " delta-oam-kinetic )

  LOG-TO-FILE ( word "    Do-feed: (ticks,epm,bite) - (" ticks "," epm "," floor delta-lh-potential ")" )

  ;; Now, I need to transfer the appropriate potential energy to the lh-hoam.
  let available-room ( max-potential - cur-potential )
  let excess-potential 0

  LOG-TO-FILE ( word "    Do-feed: available-room - " available-room )
  LOG-TO-FILE ( word "    Do-feed: excess-potential - " excess-potential )

  if( available-room < delta-lh-potential ) 
  [ 
    ;; To maintain the rate of transformation of energy from the OAM I do not
    ;;   want to pro-rate the amount taken from the RH-HOAM down, nor do I
    ;;   want to reduce the kinetic energy exhausted.  I only want to reduce
    ;;   the amount received by the predator, and send the rest to two sinks,
    ;;   one sink for kinetic, and one for excess exergy.
    set excess-potential ( delta-lh-potential - available-room )
    set delta-lh-potential available-room 
  ]
  
  ;; Transfer the energy and expel the exhaust of both types.
  ;; Store energy in the predator.
  set cur-potential ( cur-potential + delta-lh-potential )
  ask rh-hoam
  [
    ;; Remove the energy from the prey.
    set cur-potential ( cur-potential - delta-rh-potential )
  ]
  
  ;; Send the kinetic energy to the sink now.  In a normal OAM the kinetic energy is
  ;;   not expelled to sink until MH hits the floor.  However, because I want to
  ;;   put new potential in and take it out whenever it is appropriate, so I don't
  ;;   want to hold kinetic energy for a moment that may not come in a long while.
  ;; So, I expel it immediately.
  
  ;; Exhaust kinetic energy and excess potential to appropriate sinks.
  ifelse( prey-breed = autotrophs )
  [
    ;; Prey is an autotroph.
    f-store-data-in-sink ge-sinktype-a-food-exergy delta-lh-potential
    f-store-data-in-sink ge-sinktype-a-kinetic   delta-oam-kinetic
    f-store-data-in-sink ge-sinktype-a-food-excess excess-potential
  ]
  ;; Else
  [
    ;; Prey is a heterotroph.
    f-store-data-in-sink ge-sinktype-h-food-exergy delta-lh-potential
    f-store-data-in-sink ge-sinktype-h-kinetic delta-oam-kinetic
    f-store-data-in-sink ge-sinktype-h-food-excess excess-potential
  ]
  ;; End else
  
  ;; Finally, if the prey is almost emptied, such that it is inefficient
  ;;   for the predator to continue eating, and it would be more efficient
  ;;   to release this prey and start eating another, then the prey is
  ;;   released.  The real reason for this little piece of logic is to
  ;;   ensure that there is no noise or bias introduced due to a mismatch
  ;;   of bite size and energy available in the prey.  I want every energy
  ;;   transfer, in every tick, to perfectly represent a transfer consistent
  ;;   with the dynamics of the AM.  So partial bites are not allowed.
  if( next-delta-rh-potential > ( [cur-potential] of rh-hoam ) )
  [
    f-predator-releases-prey
  ]
  
  ;; End of f-effect-per-tick-xrg-xfer-in-oam
end 

;;-----------------------------------------------------------------------------|
;; Heterotrophs eat or are eaten

to f-eat-or-be-eaten
  ;; This routine is to be executed by a heterotroph in an OAM.
  
  ;; The heterotroph is in an OAM.
  ifelse( b-is-in-oam = ge-lh-hoam )
  [
    ;; Access the prey.
    let rh-hoam ( turtle prey-who )
    let cur-rh-potential ( [cur-potential] of rh-hoam )
        
    ;; The heterotroph is in predator mode.
    if( cur-rh-potential > 0 )
    [
      ;; And there is food on the table.
      f-effect-per-tick-xrg-xfer-in-oam
    ]
  ]
  ;; Else
  [
    ;; Heterotroph is prey.  No action required.
    LOG-TO-FILE ( word "  Do-feed: Heterotroph is prey." )
  ]
  ;; End else.
  
  ;; End of f-eat-or-be-eaten
end 


;;-----------------------------------------------------------------------------|
;; D4 – do-reproduce procedure(s)
;;-----------------------------------------------------------------------------|

to do-reproduce
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "reproduce" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-reproduce: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; Autotrophs come from forcible maintenance of population.
  ;;   The population is topped up with sufficient fully energized 
  ;;   autotrophs in the 'do-pre-tick' function.
  
  if( gb-h-heterotrophs-on = 1 )
  [
    ask heterotrophs
    [
      f-set-heterotroph-repro-flag
      f-reproduce-heterotroph
    ]
  ]
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-reproduce: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; f-set-heterotroph-repro-flag

to f-set-heterotroph-repro-flag
  ;; This routine is to be executed by a heterotroph.
  
  set b-is-ready-to-reproduce 1        ;; i.e. true
  if( cur-potential < RET )
    [ set b-is-ready-to-reproduce 0 ]  ;; i.e. false due to lack of health.
  ;; TODO: if( age < g-h-RAT )
  ;; TODO:   [ set b-is-ready-to-reproduce 0 ]  ;; i.e. false due to lack of maturity.
  if( b-is-in-oam = ge-rh-hoam ) 
    [ set b-is-ready-to-reproduce 0 ]  ;; i.e. false due to being eaten.
  
  if( b-is-ready-to-reproduce = 1 )
  [
    LOG-TO-FILE 
      ( word "  Do-reproduce: H(age,xrg,oam-flag,rep-flag) - (" 
        age "," floor cur-potential "," b-is-in-oam "," b-is-ready-to-reproduce ")" )
  ]
    
  ;; End f-set-heterotroph-repro-flag
end 

;;-----------------------------------------------------------------------------|
;; A heterotroph reproduces via fission, one mother having two daughters.

to f-reproduce-heterotroph
  ;; This routine is to be executed by a heterotroph.
  
  if( b-is-ready-to-reproduce = 1 )   ;; 1 = true
  [
    LOG-TO-FILE ( word "  Do-reproduce: Heterotroph Ma - " who )

    ;; If this heterotroph is in the process of eating prey at the moment that
    ;;   it reproduces, the prey is set free, with a total exergy equal to the
    ;;   unexpended exergy plus associated kinetic energy.
    if( b-is-in-oam = ge-lh-hoam ) [ f-predator-releases-prey ]
    
    let my-who who
    let my-exergy cur-potential
    let one-share-of-exergy floor( my-exergy / 2 )
    let excess-exergy ( my-exergy - ( 2 * one-share-of-exergy ) )
    
    let my-patch patch-here
    let mothers-getf ( [getf] of self )
    let mothers-lb-gene ( [lb-genetic-factor] of self )
    let mothers-ub-gene ( [ub-genetic-factor] of self )
    ask my-patch
    [
      sprout-heterotrophs 2
      [
        f-initialize-new-heterotroph
        ;; Note the mother of this daughter.
        set mas-who my-who
        ;; Cause the getf of this heterotroph to mutate.
        ;; Remember that getf is a proxy for mass in the AM.
        
        LOG-TO-FILE ( word "  Do-reproduce: Heterotroph Dx - " who )
        ;; Copy the getf, then mutate it.
        ;; Remember that getf is a proxy for mass in the AM.
        set getf mothers-getf
        set lb-genetic-factor mothers-lb-gene
        set ub-genetic-factor mothers-ub-gene
        f-mutate-new-heterotroph
        ;; In rare cases a mother may be full of exergy and a daughter may be
        ;;   unable to accept a full share, due to mutation of getf downwards.
        ;;   getf scales the maximum amount of energy that can be held because
        ;;   it is analogous to mass in the AM.
        let endowment-rejected 
          ( fr-heterotroph-accepts-endowment one-share-of-exergy )
        LOG-TO-FILE ( word "  Do-reproduce: endowment-rejected - " endowment-rejected )
        set excess-exergy ( excess-exergy + endowment-rejected )
        f-increment-cob-list breed ge-cob-fission
      ]
    ]
    f-store-data-in-sink ge-sinktype-h-die-fiss excess-exergy
    set cause-of-death ge-cod-fission
    ;; die  ;; The mother disappears after fission, leaving two daughters.
  ]
    
  ;; End f-reproduce-heterotroph
end 

;;-----------------------------------------------------------------------------|
;; An new heterotroph mutates, chainging the ability to store exergy or attack
;;   suitable prey.

to f-mutate-new-heterotroph
  ;; This routine is to be executed by an heterotroph.
  
  ;; First, mutate the getf (mass) that controls the ability to store exergy.
  ;; Remember that getf is a proxy for mass in the AM.
  ;; Determine whether it mutates upwards or downwards.
  let old-getf getf
  let sign ( -1 + 2 * ( random 2 ) )  ;; either a -1 or a 1.
  let delta-getf ( g-h-mutation-factor * getf * sign )
  set delta-getf ( delta-getf * ( random-float 1 ) )
  set getf ( getf + delta-getf )
  LOG-TO-FILE ( word "  Do-reproduce: Mutate getf - H(old,delta,new) - (" 
    floor old-getf "," floor delta-getf "," floor getf ")" )
  
  ;; Recalculate the life function controls that are scaled to getf (mass).
  ;; Remember that getf is a proxy for mass in the AM.
  f-set-getf-derived-heterotroph-characters
  
  ;; Next, mutate the gene that controls the minimum getf (mass) of prey.
  ;; Remember that getf is a proxy for mass in the AM.
  ;; Determine whether it mutates upwards or downwards.
  let old-gene lb-genetic-factor
  set sign ( -1 + 2 * ( random 2 ) )  ;; either a -1 or a 1.
  let delta-gene ( g-h-mutation-factor * 2.5 * sign ) ;; 2.5 = scaling factor
  set delta-gene ( delta-gene * ( random-float 1 ) )
  set lb-genetic-factor ( lb-genetic-factor + delta-gene )
  ;; If its less than one, reflect the overage above one.
  if( lb-genetic-factor < g-h-lb-lower-bound ) 
    [ set lb-genetic-factor ( ( 2 * g-h-lb-lower-bound ) - lb-genetic-factor ) ]
  LOG-TO-FILE ( word "  Do-reproduce: Mutate lb gene - H(old,delta,new) - (" 
    precision old-gene 4 "," 
    precision delta-gene 4 "," 
    precision lb-genetic-factor 4 ")" )
  
  ;; Last, mutate the gene that controls the maximum getf (mass) of prey.
  ;; Remember that getf is a proxy for mass in the AM.
  ;; Determine whether it mutates upwards or downwards.
  set old-gene ub-genetic-factor
  set sign ( -1 + 2 * ( random 2 ) )  ;; either a -1 or a 1.
  set delta-gene ( g-h-mutation-factor * 2.5 * sign ) ;; 2.5 = scaling factor
  set delta-gene ( delta-gene * ( random-float 1 ) )
  set ub-genetic-factor ( ub-genetic-factor + delta-gene )
  ;; If its more than four, reflect the overage below four.
  if( ub-genetic-factor > g-h-ub-upper-bound ) 
    [ set ub-genetic-factor ( ( 2 * g-h-ub-upper-bound ) - ub-genetic-factor ) ]
  LOG-TO-FILE ( word "  Do-reproduce: Mutate ub gene - H(old,delta,new) - (" 
    precision old-gene 4 "," 
    precision delta-gene 4 "," 
    precision ub-genetic-factor 4 ")" )
  
  ;; End of f-mutate-new-heterotroph
end 
  
;;-----------------------------------------------------------------------------|
;; An new heterotroph accepts what exergy it can.

to-report fr-heterotroph-accepts-endowment [endowment-offered]
  ;; This routine is to be executed by a heterotroph.
  
  LOG-TO-FILE ( word "  Do-reproduce: endowment-offered - " endowment-offered )
  let endowment-remaining 0
  
  ;; Calculate the maximum energy charge allowed for this heterotroph.
  ;;   Remember that getf is a proxy for mass in the AM.
  let max-exergy ( getf * g-acceleration * g-drop-distance ) 
  ;; Determine how much of the endowment this heterotroph can accept.
  let energy-to-reject ( endowment-offered - max-exergy )
  
  ;; If there is too much energy offered, reject some.  Otherwise, store all 
  ;;   of it.
  ifelse( energy-to-reject > 0 )
  [ 
    set cur-potential ( max-exergy ) 
    f-store-data-in-sink ge-sinktype-h-fiss-exergy cur-potential
    set endowment-remaining energy-to-reject
    LOG-TO-FILE ( word "  Do-reproduce: energy accepted - " max-exergy )
    LOG-TO-FILE ( word "  Do-reproduce: energy-to-reject - " energy-to-reject )
  ]
  ;; Else
  [
    set cur-potential ( endowment-offered ) 
    f-store-data-in-sink ge-sinktype-h-fiss-exergy cur-potential
    LOG-TO-FILE ( word "  Do-reproduce: energy accepted - " endowment-offered )
    set endowment-remaining 0
  ]
  ;; End else
  
  report endowment-remaining
  ;; End of fr-heterotroph-accepts-endowment
end 
  
;;-----------------------------------------------------------------------------|
;; D5 – do-die procedure(s)
;;-----------------------------------------------------------------------------|

to do-die
  ;; This routine is to be executed by the observer.
  
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "die" ) )
    [ set gb-debug-flow-on 1 LOG-TO-FILE "" LOG-TO-FILE word "Do-die: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  if( ( count autotrophs ) > 0 )
  [
    ask autotrophs
    [
      f-set-autotroph-death-flag
      f-autotroph-dies
    ]
  ]
  
  if( ( count heterotrophs ) > 0 )
  [
    ask heterotrophs
    [
      f-set-heterotroph-death-flag
      f-heterotroph-dies
    ]
  ]
  
  ;; Supressed. f-update-aggregates

  LOG-TO-FILE "  Do-die: procedure completed"
end 

;;-----------------------------------------------------------------------------|
;; f-set-autotroph-death-flag

to f-set-autotroph-death-flag
  ;; This routine is to be executed by a autotroph.
  
  set b-is-ready-to-die 0        ;; i.e. false, default.

  ;; If a cause of death has already been noted, it dies.
  if( cause-of-death > ge-cod-none )
  [
    ;; A cause of death has been previously flagged.
    set b-is-ready-to-die 1 
    LOG-TO-FILE ( WORD "  Do-die: A(xrg,cod) - ("
      floor cur-potential "," cause-of-death ")" )
  ]
    
  ;; End f-set-autotroph-death-flag
end 

;;-----------------------------------------------------------------------------|
;; f-autotroph-dies

to f-autotroph-dies
  ;; This routine is to be executed by a autotroph.
  
  if( b-is-ready-to-die = 1 )
  [
    ;; If this autotroph is in the process of being eaten as prey at the 
    ;;   moment that it dies it must be released from the oam.
    if( b-is-in-oam = ge-rh-hoam ) 
    [ 
      let predator ( turtle pred-who )
      ask predator
      [
        f-predator-releases-prey 
      ]
    ]
    
    LOG-TO-FILE ( word "  Do-die: A(xrg,die-flag,cod) - (" 
      floor cur-potential "," 
      b-is-ready-to-die "," 
      cause-of-death ")" ) 

    ;; Record the cause of death in the statistics.
    if( cause-of-death > 0 )
    [
      if( cause-of-death = ge-cod-as-prey )
        [ f-store-data-in-sink ge-sinktype-a-die-asprey cur-potential ]
      f-increment-cod-list breed cause-of-death
   ]
    
    die  ;; The autotroph disappears from the system.    
  ]

  ;; End f-autotroph-dies
end 

;;-----------------------------------------------------------------------------|
;; f-set-heterotroph-death-flag

to f-set-heterotroph-death-flag
  ;; This routine is to be executed by a heterotroph.
  
  set b-is-ready-to-die 0        ;; i.e. false, default.

  ;; If a cause of death has already been noted, it dies.
  if( cause-of-death > ge-cod-none )
  [
    ;; A cause of death has been previously flagged.
    set b-is-ready-to-die 1 
    LOG-TO-FILE ( WORD "  Do-die: A(age,xrg,oam,cod) - ("
      age "," floor cur-potential "," b-is-in-oam "," cause-of-death ")" )
  ]

  ;; No cause of death has been set yet.  Check basic vital signs.
  if( cur-potential <= EPM )  ;; Effectively, this is g-h-DET.
  [ 
    set b-is-ready-to-die 1 
    set cause-of-death ge-cod-hunger 
    LOG-TO-FILE ( WORD "  Do-die: A(age,xrg,oam,cod) - ("
      age "," floor cur-potential "," b-is-in-oam "," cause-of-death ")" )
  ]
    
  if( age > g-h-DAT )
  [ 
    set b-is-ready-to-die 1 
    set cause-of-death ge-cod-old-age 
    LOG-TO-FILE ( WORD "  Do-die: A(age,xrg,oam,cod) - ("
      age "," floor cur-potential "," b-is-in-oam "," cause-of-death ")" )
  ]

  ;; If it dies as prey, that over-rides all other causes of death.
  if( ( b-is-in-oam = ge-rh-hoam ) and ( b-is-ready-to-die = 1 ) )
  [
    set cause-of-death ge-cod-as-prey 
    LOG-TO-FILE ( WORD "  Do-die: A(age,xrg,oam,cod) - ("
      age "," floor cur-potential "," b-is-in-oam "," cause-of-death ")" )
  ]
    
  ;; End f-set-heterotroph-death-flag
end 

;;-----------------------------------------------------------------------------|
;; f-heterotroph-dies

to f-heterotroph-dies
  ;; This routine is to be executed by a heterotroph.
  
  if( b-is-ready-to-die = 1 )
  [
    ;; If this heterotroph is in the process of eating prey at the moment that
    ;;   it dies, the prey is set free.
    if( b-is-in-oam = ge-lh-hoam ) 
    [ 
      f-predator-releases-prey 
    ]
    
    ;; If this heterotroph is in the process of being eaten as prey at the 
    ;;   moment that it dies it must be released from the oam.
    if( b-is-in-oam = ge-rh-hoam ) 
    [ 
      let predator ( turtle pred-who )
      ask predator
      [
        f-predator-releases-prey 
      ]
    ]
    
    LOG-TO-FILE ( word "Do-die: H(xrg,die-flag,cod) - (" 
      floor cur-potential "," 
      b-is-ready-to-die "," 
      cause-of-death ")" ) 

    ;; TODO debug cause of death.
    
    ;; Record the cause of death in the statistics.
    if( cause-of-death > 0 )
    [
      if( cause-of-death = ge-cod-hunger )
        [ f-store-data-in-sink ge-sinktype-h-die-hunger cur-potential ]
      if( cause-of-death = ge-cod-old-age )
        [ f-store-data-in-sink ge-sinktype-h-die-oldage cur-potential ]
      if( cause-of-death = ge-cod-as-prey )
        [ f-store-data-in-sink ge-sinktype-h-die-asprey cur-potential ]
      f-increment-cod-list breed cause-of-death
   ]
    
    die  ;; The heterotroph disappears from the system.    
  ]

  ;; End f-heterotroph-dies
end 

;;-----------------------------------------------------------------------------|
;; f-predator-releases-prey

to f-predator-releases-prey
  ;; This routine is to be executed by a heterotroph.
  
  ;; This heterotroph is currently eating prey.  The prey is released.
  
  let prey turtle prey-who
  ask prey
  [
    set color default-colour
    if( breed = heterotrophs )
    [
      set b-is-ready-to-move 1    ;; true
    ]
    set b-is-in-oam ge-not-in-oam
    set cause-of-death ge-cod-as-prey
  ]
  
  set color default-colour
  set b-is-ready-to-move 1    ;; true
  set b-is-in-oam ge-not-in-oam
  
  ;; Return OAM-related variables to defaults.
  ;; These contain data for the OAM consisting of coupled predator/prey.
  set prey-who        -1 ;; an invalid value; who number of prey haom.
  set pred-who        -1 ;; an invalid value; who number of predator haom.
  set Eu-in-oam        1 ;; Eu is Odum's efficiency.

  set max-drop-time    0 ;; Drop time for this OAM.
  set cur-drop-time    0 ;; Time since drop started.
  set rem-drop-time    0 ;; Remaining drop time.
  set drop-time-ratio  0 ;; Fraction of drop time remaining.


  ;; End f-predator-releases-prey
end 
;;-----------------------------------------------------------------------------|
;; D6 - do-post-tick procedure(s)
;;-----------------------------------------------------------------------------|

to do-post-tick
  ;; This routine is to be executed by the observer.
   
  if( gb-debug-on = 1 )
  [
    ifelse( ( gs-debug-step-chooser = "all" ) or ( gs-debug-step-chooser = "post-tick" ) )
    [ set gb-debug-flow-on 1  LOG-TO-FILE "" LOG-TO-FILE word "Do-Post-tick: Debug on; tick = " ticks ]
    [ set gb-debug-flow-on 0 ]
  ]
  
  ;; MANUAL CHANGE FOR DEBUG.
  ;; This is a call to a debug routine which could be suppressed if all is okay.
  ;; This is one of a group of such calls, most of which are between steps in 
  ;;   the 'Go' routine.  They are suppressed there, but can be enabled again.
  ;; I have decided to leave this one active, for now.
  ;; It checks all agents, every tick, to ensure that all values are greater than
  ;;   or equal to zero.  
  if( frb-agents-are-all-valid = false ) 
    [ LOG-TO-FILE ( word "Agents failed validity test." ) ]
  
  ;; Update the aggregates for display in the monitors.
  f-update-aggregates

  display

  LOG-TO-FILE "  Do-post-tick: procedure completed."
end 

;;-----------------------------------------------------------------------------|
;; SECTION E – DRAWING AND MAINTENANCE PROCEDURE(S)
;;-----------------------------------------------------------------------------|



;;-----------------------------------------------------------------------------|
;; Update the values of global aggregate numbers.

to f-update-aggregates
  ;; This routine is to be executed by the observer.

  ;; Although this is a display-only routine, it may implicitly call the PRNG and
  ;;   so may have an effect on the trajectory of the model.  In a standard 'go'
  ;;   run it is called only once per tick, before graphs are updated.  If you
  ;;   use the one-step debug buttons, it is called once after each step, so
  ;;   debug runs that use those buttons will not replicate a real run.
  
  ;;---------------------------------------------------------------------------|
  ;; The following agent sets, counts and averages are for data collection 
  ;;   and display in monitors and plots.
  
  ;; Agent sets
  ;; Set of all turtles as lh-hoams
  set ga-oams 
    ( heterotrophs with [b-is-in-oam = ge-lh-hoam] ) 
  
  ;; Counts
  set g-no-of-autotrophs ( count autotrophs )     ;; count of all autotrophs
  set g-no-of-heterotrophs ( count heterotrophs ) ;; count of all heterotrophs
  set g-no-of-oams ( count ga-oams )  ;; count of all Open Atwood Machines
  set g-no-of-a-as-rh-hoams ( count autotrophs with [b-is-in-oam = ge-rh-hoam] )  
  set g-no-of-h-as-rh-hoams ( count heterotrophs with [b-is-in-oam = ge-rh-hoam] )  
  
  ;; Averages - autotrophs
  ifelse( g-no-of-autotrophs = 0 )
  [
    set g-a-ave-getf 0
    set g-a-ave-max-potential 0
    set g-a-ave-cur-potential 0
  ]
  ;; Else
  [
    set g-a-ave-getf ( sum [getf] of autotrophs ) / g-no-of-autotrophs
    set g-a-ave-max-potential ( sum [max-potential] of autotrophs ) / g-no-of-autotrophs
    set g-a-ave-cur-potential ( sum [cur-potential] of autotrophs ) / g-no-of-autotrophs
  ]
  ;; End else
  
  ;; Averages - heterotrophs
  ifelse( g-no-of-heterotrophs = 0 )
  [
    set g-h-ave-age 0
    set g-h-ave-getf 0
    set g-h-ave-lb-gene 0
    set g-h-ave-ub-gene 0
    set g-h-ave-RET 0
    set g-h-ave-EPM 0
    set g-h-ave-max-potential 0
    set g-h-ave-cur-potential 0
  ]
  ;; Else
  [
    set g-h-ave-age ( sum [age] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-getf ( sum [getf] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-lb-gene ( sum [lb-genetic-factor] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-ub-gene ( sum [ub-genetic-factor] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-RET ( sum [RET] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-EPM ( sum [EPM] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-max-potential ( sum [max-potential] of heterotrophs ) / g-no-of-heterotrophs
    set g-h-ave-cur-potential ( sum [cur-potential] of heterotrophs ) / g-no-of-heterotrophs
  ]
  ;; End else

  ;; Averages - OAMs
  ifelse( g-no-of-oams = 0 )
  [
    set g-h-ave-Eu 0
    set g-h-ave-max-dt 0
    set g-h-ave-cur-dt 0
    set g-h-ave-rem-dt 0
    set g-h-ave-dt-ratio 0
    set g-h-ave-BITE-total 0
    set g-h-ave-BITE-xrg 0
    set g-h-ave-BITE-kinetic 0 
  ]
  ;; Else
  [
    set g-h-ave-Eu ( sum [Eu-in-oam] of ga-oams ) / g-no-of-oams
    set g-h-ave-max-dt ( sum [max-drop-time] of ga-oams ) / g-no-of-oams
    set g-h-ave-cur-dt ( sum [cur-drop-time] of ga-oams ) / g-no-of-oams
    set g-h-ave-rem-dt ( sum [rem-drop-time] of ga-oams ) / g-no-of-oams
    set g-h-ave-dt-ratio ( sum [drop-time-ratio] of ga-oams ) / g-no-of-oams
    
    set g-h-ave-BITE-xrg  
      ( 
        ( item ge-sinktype-a-food-exergy gl-sinks-per-tick ) +
        ( item ge-sinktype-h-food-exergy gl-sinks-per-tick ) 
      ) / g-no-of-oams
    set g-h-ave-BITE-kinetic  
      ( 
        ( item ge-sinktype-a-kinetic gl-sinks-per-tick ) +
        ( item ge-sinktype-h-kinetic gl-sinks-per-tick ) 
      ) / g-no-of-oams 
    set g-h-ave-BITE-total ( g-h-ave-BITE-xrg + g-h-ave-BITE-kinetic )
  ]
  ;; End else
  
;;-----------------------------------------------------------------------------|
  ;; To ensure that the PRNG is called whether or not plots are displayed, the
  ;;   calculations needed for the histogram plots which invoke the PRNG
  ;;   implicitly should be carried out here where they will happen every tick.

;;-----------------------------------------------------------------------------|
  ;; Setup for Plot "AAAAAA"
  
  ;; This log entry may come from any step during debug operations.  
  LOG-TO-FILE "  Do-xxx: All aggregates updated."  
end 

;;-----------------------------------------------------------------------------|
;; Report the status of a switch.

to-report fr-h-lb-switch-status
  ;; This routine is to be executed by the observer.
  let answer "Non-phenotypic"
  if( gb-h-lb-gene-active = true )
  [ set answer "phenotypic" ]
  report answer  
end 

;;-----------------------------------------------------------------------------|
;; Report the status of a switch.

to-report fr-h-ub-switch-status
  ;; This routine is to be executed by the observer.
  let answer "Non-phenotypic"
  if( gb-h-ub-gene-active = true )
  [ set answer "phenotypic" ]
  report answer  
end 

;;--------------------------
;; DATA CAPTURE TO CSV FILES
;;--------------------------
  
;;-----------------------------------------------------------------------------|
;; Record the data is several selected plots to CSV files

to f-record-selected-plots
  ;; This routine is to be executed by the observer.
  
  ;; The template for the export command is:
  ;; export-plot plotname filename

  ;; Get a common timestamp for all plots.
  let timestamp fr-get-time-stamp
  
  ;; Plot 01
  let plotname "Populations"
  let plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl01_POPS.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 02
  set plotname "Ave Eu of OAMs"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl02_OAMS.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 03
  set plotname "Prey Numbers"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl03_PREY.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 04
  set plotname "Counts By T-Level"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl04_TCNTS.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 05
  set plotname "Eu By T-Level"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl05_EUBYTL.CSV" )
  export-plot plotname plot-filename
  
  ;; Plot 06
  set plotname "Max Trophic Level"
  set plot-filename 
    ( word timestamp 
           "_Sc" g-scenario-number 
           "_Se" g-use-this-seed 
           "_Pl06_MAXTL.CSV" )
  export-plot plotname plot-filename
  
  ;; End f-record-selected-plots
end 

;;-----------------------------------------------------------------------------|
;; Construct a time stamp for a file name for data in CSV format.

to-report fr-get-time-stamp
  ;; This routine is to be executed by the observer.
  ;;
  ;; Date-string format "01:19:36.685 PM 19-Sep-2002"
  let date-string date-and-time
  let time-stamp ""
  ;; Append the year as yy.
  set time-stamp word time-stamp ( substring date-string 25 27 )
  ;; Append the month as Mmm.
  set time-stamp word time-stamp fr-convert-mmm-mm ( substring date-string 19 22 )
  ;; Append the day as dd.
  set time-stamp word time-stamp ( substring date-string 16 18 )
  ;; Append a dash.
  set time-stamp word time-stamp "_"

  ;; Append the hour as hh.
  set time-stamp word time-stamp fr-convert1224 ( substring date-string 0 2 ) ( substring date-string 13 15 )
  ;; Append the minute as mm.
  set time-stamp word time-stamp ( substring date-string 3 5 )
  ;; Append the second as ss.
  set time-stamp word time-stamp ( substring date-string 6 8 )

  report time-stamp
  ;; End fr-get-time-stamp
end 

;;-----------------------------------------------------------------------------|
;; DEBUG AND DEBUG LOG FILE MANAGEMENT FUNCTIONS
;;-----------------------------------------------------------------------------|

;;-----------------------------------------------------------------------------|
;; Open a log file for debug output.

to f-open-log-file
  ;; This routine is to be executed by the observer.
  
  ;; Ensure previous log file is closed.
  if ( is-string? gs-log-file-name )
  [
    if ( file-exists? gs-log-file-name )
    [
      file-close-all
    ]
  ]
  
  ;; Date-string format "01:19:36.685 PM 19-Sep-2002"
  let date-string date-and-time
  set gs-log-file-name "MppLab_Log_"
  ;; Append the year as yy.
  set gs-log-file-name word gs-log-file-name ( substring date-string 25 27 )
  ;; Append the month as Mmm.
  set gs-log-file-name word gs-log-file-name fr-convert-mmm-mm ( substring date-string 19 22 )
  ;; Append the day as dd.
  set gs-log-file-name word gs-log-file-name ( substring date-string 16 18 )
  ;; Append a dash.
  set gs-log-file-name word gs-log-file-name "_"

  ;; Append the hour as hh.
  set gs-log-file-name word gs-log-file-name fr-convert1224 ( substring date-string 0 2 ) ( substring date-string 13 15 )
  ;; Append the minute as mm.
  set gs-log-file-name word gs-log-file-name ( substring date-string 3 5 )
  ;; Append the second as ss.
  set gs-log-file-name word gs-log-file-name ( substring date-string 6 8 )
  ;; Append the .txt extension.
  set gs-log-file-name word gs-log-file-name ".txt"

  file-open gs-log-file-name
  file-show "Log File for a MppLab (NetLogo) Model."
  file-show word "File Name: " gs-log-file-name
  file-show word "File opened at:" date-and-time
  file-show ""
  
  ;; Send a message directly to the command centre.
  ifelse ( file-exists? gs-log-file-name )
  [
    show word gs-log-file-name " opened."
  ]
  [
    show word gs-log-file-name " not opened."
  ]
end 

;;-----------------------------------------------------------------------------|
;; Convert month in text form to digital form.

to-report fr-convert-mmm-mm [ mmm ]
  ;; This routine is to be executed by the observer.
  ;; It converts a string in the form mmm ( alpha text ) to the form mm ( digit-text ).
  
  let mm "00"
  if( mmm = "Jan" ) [ set mm "01" ]
  if( mmm = "Feb" ) [ set mm "02" ]
  if( mmm = "Mar" ) [ set mm "03" ]
  if( mmm = "Apr" ) [ set mm "04" ]
  if( mmm = "May" ) [ set mm "05" ]
  if( mmm = "Jun" ) [ set mm "06" ]
  if( mmm = "Jul" ) [ set mm "07" ]
  if( mmm = "Aug" ) [ set mm "08" ]
  if( mmm = "SeP" ) [ set mm "09" ]
  if( mmm = "Oct" ) [ set mm "10" ]
  if( mmm = "Nov" ) [ set mm "11" ]
  if( mmm = "Dec" ) [ set mm "12" ]
  report mm
end 

;;-----------------------------------------------------------------------------|
;; Convert hour in 12 format to 24 hour format.

to-report fr-convert1224 [ hh ampm ]
  ;; This routine is to be executed by the observer.
  ;; It converts a string in 12 hour format to 24 hour format.
  
  let hour read-from-string hh
  if( ampm = "PM" ) [ set hour ( hour + 12 ) ]
  
  let dd ( word "00" hour )
  let d2 last dd
  set dd but-last dd
  let d1 last dd
  set dd ( word d1 d2 )
  report dd
end 

;;-----------------------------------------------------------------------------|
;; Close a log file for debug output.

to f-close-log-file
  ;; This routine is to be executed by the observer.
  
  let b-filename-exists 0
  if ( is-string? gs-log-file-name ) 
  [
    if ( file-exists? gs-log-file-name )
    [
      set b-filename-exists 1
    ]
  ] 

  ifelse( b-filename-exists = 1 )
  [
    ;; Ensure the file is selected.
    file-open gs-log-file-name
      
    ;; Stanp it.
    LOG-TO-FILE word "File closed at: " date-and-time
      
    ;; Flush the buffers.
    file-flush 
      
    ;; Close it.
    file-close-all
      
    ;; Note sent to command centre.
    show word gs-log-file-name " closed."
    
    ;; Revert to dummy name.
    set gs-log-file-name "dummyname"
  ]
  [
    if( gs-log-file-name = "dummyname" )
      [ show "No log file is open.  Cannot close it." ]
  ]
end 

;;-----------------------------------------------------------------------------|
;; Select an already opened log file.

to f-select-log-file
  ;; This routine is to be executed by the observer.
  
  ifelse ( file-exists? gs-log-file-name )
  [
    ;; Ensure the file is selected.
    file-open gs-log-file-name
    
    ;; Ensure it is open for writing.
    LOG-TO-FILE ""
    LOG-TO-FILE "SELECTED"    
  ]
  [
    show word gs-log-file-name " is not open.  Cannot select it."
  ]
end 

;;-----------------------------------------------------------------------------|
;; Change the debug mode from on to off, or vice versa.

to f-toggle-debug
  ;; This routine is to be executed by the observer, and is activated by a 
  ;;   button.
  
  ifelse( gb-debug-on = 1 )
  [
    ;; Debug is On, turn it Off.
    ;; Close the file before turning debug logging off.
    f-close-log-file
    set gs-debug-status "0 (Off)"  ;; This appears in the monitor.
    set gb-debug-on 0              ;; But this controls the debug feature.
  ]
  [
    ;; Debug is Off, turn it On.
    set gs-debug-status "1 (On)"   ;; This appears in the monitor.
    set gb-debug-on 1              ;; But this controls the debug feature.
    ;; The switches, if needed, are reset manually by the user.
    ;; Open the log file after turning debug logging on.
    f-open-log-file
  ]
end 

;;-----------------------------------------------------------------------------|
;; 'Show' a string in a debug log.

to LOG-TO-FILE [ log-this-string ]
  ;; This routine may be executed by observer, autotroph, or heterotroph.
  ;; It should be invoked as a debug routine only, and would not be used for 
  ;;    normal output.  It sends output to the debug log file, or, optionally,
  ;;    also to the command centre.
  
  
  ;; gb-debug-on is a global Boolean and has value 1 (true) or 0 (false).
  if( gb-debug-on = 1 )
  [
    ;; gb-debug-flow-on is declared as a global Boolean variable, and its value 
    ;;   is 0 ( false ) or 1 ( true ) and is set on or off at the beginning of each 
    ;;   function ( each do-step ).  It is controlled by the chooser that selects 'all' 
    ;;   or a specific do-function.
    ;; 
    ;; When it is 'on' you can assume the debug log file exists and is open for
    ;;   write.
    
    if( gb-debug-flow-on = 1 )
    [
      file-show log-this-string
      show log-this-string
    ] 
  ]
end 

;;-----------------------------------------------------------------------------|
;; This replicates the effect of an 'ASSERTION' in C++

to ASSERT [ error-test error-string error-who ]
;; This routine can be run by observer, autotroph or heterotroph (I think).

if( error-test = false )
[
  show ( word error-test " " error-string " " error-who )
  ;; Cause a run-time error and display a message.
  error ( word "Agent: " error-who " - " error-string )
]
end 


;;-----------------------------------------------------------------------------|
;; Check whether the agents are all valid.

to-report frb-agents-are-all-valid 
;; This routine can be run by the observer.

  let b-agents-are-all-valid true
  
  if( gb-debug-on = 1 )
  [
    ;; Do the check only if debug is on.
    
    ;; Check the autotrophs.
    ask autotrophs
    [
      if( frb-autotroph-is-valid = false ) [ set b-agents-are-all-valid false ]
    ]
    
    ;; Check the heterotrophs.
    ask heterotrophs
    [
      if( frb-heterotroph-is-valid = false ) [ set b-agents-are-all-valid false ]
    ]
  ]
  
  report b-agents-are-all-valid
end 

;;-----------------------------------------------------------------------------|
;; Check whether a autotroph is valid.

to-report frb-autotroph-is-valid 
;; This routine can be run by a autotroph.

  let b-autotroph-is-valid true
  
  report b-autotroph-is-valid
end 

;;-----------------------------------------------------------------------------|
;; Check whether a heterotroph is valid.

to-report frb-heterotroph-is-valid 
;; This routine can be run by a heterotroph.

  let b-heterotroph-is-valid true

  if( getf < 0 ) 
  [ 
    set b-heterotroph-is-valid false 
    LOG-TO-FILE ( word "getf = " getf "; at tick = " ticks )
  ]
  

  report b-heterotroph-is-valid
end 

There are 2 versions of this model.

Uploaded by When Description Download
Garvin Boyle over 7 years ago Loaded the wrong file. This fixes it. Download this version
Garvin Boyle over 7 years ago Initial upload Download this version

Attached files

File Type Description Last updated
03 MppLab V1.09.png preview Preview for '03 MppLab V1.09' over 7 years ago, by Garvin Boyle Download
141129 NTF - NetLogo Stds for OrrerySW R2.pdf pdf Prepared standards for Orrery Software for NetLogo projects. over 7 years ago, by Garvin Boyle Download
150101 NTF Atwood's Machine R4.pdf pdf An analysis of the functioning of Atwood's Machine. over 7 years ago, by Garvin Boyle Download
150105 NTF AM Shape Study R1.pdf pdf A study of the shape of the power vs efficiency curve of Atwood's Machine. over 7 years ago, by Garvin Boyle Download
150113 NTF Atwoods Machine Revisited R4.pdf pdf More thoughts on the operations of Atwood's Machine as a model for energy transfers. over 7 years ago, by Garvin Boyle Download
150418 NTF Three Shapes of AM Revisited R2.pdf pdf A more detailed study of the power vs efficiency curves associated with Atwood's Machine. over 7 years ago, by Garvin Boyle Download
160509 NTF Video of MppLab - Trophic Levels - On Youtube.pdf pdf A document with a link to a youtube video produced using MppLab. over 7 years ago, by Garvin Boyle Download
170324 NTF MppLab Change Diary R4.pdf pdf The most recent change diary. over 7 years ago, by Garvin Boyle Download
170326 NTF High-Level Design - MppLab R2.pdf pdf A high-level technical description of the model. over 7 years ago, by Garvin Boyle Download

This model does not have any ancestors.

This model does not have any descendants.