Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Leaky Bucket
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook (C) Ken Webb Sun Feb 12 2012 12:14:28 GMT-0500 (EST)-->
Title: Leaky Bucket (from
Description: implementation of Robinson, Walter A. (2001) Modeling Dynamic Climate Systems. section 1.2 "The Leaky Bucket"
InternalName: leakybucket
My Notes
After some period of time, the depth of the water should reach an equilibrium level,
where the volumetric flow rate of the outflow equals the volumetric flow rate of the tap.
This happens after about 1000 timesteps::
water depth_44 (0.065288186023622657 ± 6.9E-18) m [L]
tap volumetricFlowRate_39 (0.00019999999999999998 ± 1.4E-20) m³/s [L]³/[T]
outflow volumetricFlowRate_50 (0.00019997008731409269 ± 1.4E-20) m³/s [L]³/[T]
Test of Leaky Bucket with the Xholon Bestiary applet
This tests the Xholon goal of being able to get any two things working together.
To insert this workbook into the Xholon Bestiary applet::
Press "Save Locally" above to open a new browser window containing just the XML content of this workbook.
Navigate to the new window and press Ctrl-A (Select All).
Copy and paste, or drag and drop, the entire workbook contents into the Bestiary console.
Locate the xholonClassDetails subtree in the console, and uncomment the PhysicalSystem line.
Select a habitat cell in the grid on the Bestiary page.
Press "Submit" on the Bestiary page.
To locate and display the change in depth of the water in the leaky bucket, while the Bestiary applet is running::
Clear the contents of the Bestiary console, and Submit this xpath expression:
xpath PhysicalSystem/Bucket/Water/Depth
Select "Browser JS Template" from the Bestiary menu.
Change "cnode.getName()" to "cnode.getVal()".
Press Submit. The current depth will display at the bottom of the web page.
Keep pressing Submit to see the updated current depth.
To automatically view the updated depth each time step, insert the following behavior as a last child of Depth.
It creates a Java object that continuously invokes the web browser's JavaScript engine, while the applet is running.::
<DepthViewbehavior implName="org.primordion.script.Behavior" lang="BrowserJS">
document.getElementById('usercontent').innerHTML = contextNodeKey.getParentNode().getVal();
To view a line chart of the changing depth::
Insert the following script into the Bestiary console.
<script implName="lang:js:inline:">
var app = applicationKey;
Press Submit. A chart will display at the bottom of the web page.
The chart will update each time Submit is pressed.
To recruit one of the beasts to draw a line chart::
Uncomment the GraphingBeastbehavior node.
Licorice, or another cat or other beast, will obligingly help to draw a graph in the Bestiary grid.
The graph will be made of WallSection nodes, and is therefore a bit blocky.
<script implName="lang:python:inline:"><![CDATA[
print "height = 12.34 m"
<script implName="lang:javascript:inline:"><![CDATA[
print("height = 56.78 meters\n");
<!-- domain objects -->
<Tap xhType="XhtypePureActiveObject">
<port name="vfr" connector="#xpointer(VolumetricFlowRate)"/>
<Bucket xhType="XhtypePureActiveObject">
<port name="radius" connector="#xpointer(Radius)"/>
<port name="area" connector="#xpointer(Area)"/>
<port name="water" connector="#xpointer(Water)"/>
<port name="hole" connector="#xpointer(Hole)"/>
<Water xhType="XhtypePureActiveObject">
<port name="depth" connector="#xpointer(Depth)"/>
<port name="volume" connector="#xpointer(Volume)"/>
<port name="areaOfBucket" connector="#xpointer(../Area)"/>
<port name="vfrOfInflow" connector="#xpointer(ancestor::PhysicalSystem/Tap/VolumetricFlowRate)"/>
<port name="vfrOfOutflow" connector="#xpointer(ancestor::PhysicalSystem/Outflow/VolumetricFlowRate)"/>
<Hole xhType="XhtypePureActiveObject">
<port name="radius" connector="#xpointer(Radius)"/>
<port name="area" connector="#xpointer(Area)"/>
<Outflow xhType="XhtypePureActiveObject">
<port name="g" connector="#xpointer(../AccelerationDueToGravity)"/>
<port name="depth" connector="#xpointer(../Bucket/Water/Depth)"/>
<port name="areaOfHole" connector="#xpointer(../Bucket/Hole/Area)"/>
<port name="vfr" connector="#xpointer(VolumetricFlowRate)"/>
<Depth xhType="XhtypePurePassiveObject"/>
<!--<PhysicalSystem implName=""/>-->
<Tap> <!-- Inflow -->
<VolumetricFlowRate>0.0002 m^3/s</VolumetricFlowRate>
<Radius>0.25 m</Radius>
<Area>0.0 m^2</Area>
<Depth>0.0 m
<!--<GraphingBeastbehavior/>--> <!-- optionally use this in Bestiary -->
<Volume>0.0 m^3</Volume>
<Radius>0.0075 m</Radius>
<Area>0.0 m^2</Area>
<VolumetricFlowRate>0.0 m^3/s</VolumetricFlowRate>
<PhysicalSystembehavior implName="org.primordion.script.Behavior_javascript"><![CDATA[
function postConfigure() {
// set application parameters
var app = applicationKey;
// optional chart
//app.setParam("UseDataPlotter","google2"); // or JFreeChart
//app.setParam("DataPlotterParams","Leaky Bucket,Time (s),Depth (m),./statistics/,leakybucket,1,WRITE_AS_DOUBLE");
//app.invokeDataPlotter(); // call this later to display the chart
<Bucketbehavior implName="org.primordion.script.Behavior_javascript"><![CDATA[
function postConfigure() {
area.setVal(Math.PI * Math.pow(radius.val, 2));
<Holebehavior implName="org.primordion.script.Behavior_javascript"><![CDATA[
function postConfigure() {
area.setVal(Math.PI * Math.pow(radius.val, 2));
<Outflowbehavior implName="org.primordion.script.Behavior_javascript"><![CDATA[
function act() {
var speed = Math.sqrt(2.0 * g.val * depth.val);
vfr.setVal(speed * areaOfHole.val);
<Waterbehavior implName="org.primordion.script.Behavior_javascript"><![CDATA[
function postConfigure() {
volume.setVal(areaOfBucket.val * depth.val);
function act() {
depth.setVal(volume.val / areaOfBucket.val);
volume.incVal((vfrOfInflow.val - vfrOfOutflow.val) * contextNodeKey.getParentNode().getDt());
function toString() {
return( + " depth = " + depth.val + " m");
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="200" height="150" xmlns="">
<title>Leaky Bucket</title>
<title>Layer 1</title>
<g id="PhysicalSystem">
<g id="svg_1">
<rect ry="5" rx="5" x="84" y="13" width="33" height="20" fill="#bfbfbf" id="PhysicalSystem/Tap"/>
<text fill="black" x="88" y="26" id="svg_2">Tap</text>
<g id="svg_3">
<rect stroke="#7f3f00" x="63" y="44" width="76" height="57" fill="#ffd4aa" id="PhysicalSystem/Bucket"/>
<text transform="rotate(-90, 56, 76)" fill="black" x="38" y="80" id="svg_4">Bucket</text>
<g id="svg_5">
<rect x="64" y="97" width="74" height="3" fill="#aad4ff" id="PhysicalSystem/Bucket/Water"/>
<text transform="rotate(-30, 89, 88)" fill="#0000ff" x="73" y="92" id="svg_6">Water</text>
<g id="svg_7">
<rect stroke="#7f3f00" x="98" y="99" width="9" height="5" fill="#ffd4aa" id="PhysicalSystem/Bucket/Hole"/>
<text fill="black" x="110" y="111" id="svg_8">Hole</text>
<g id="svg_9">
<rect ry="5" rx="5" x="76" y="117" width="62" height="20" fill="#bfbfbf" id="PhysicalSystem/Outflow"/>
<text transform="matrix(1.01639, 0, 0, 1, -1.2459, 0)" fill="black" x="84" y="130" id="svg_10">Outflow</text>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment