implementation of Robinson, Walter A. (2001) Modeling Dynamic Climate Systems. (section 2.2)
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/wb/ (C) Ken Webb Sat May 12 2012 06:46:38 GMT-0400 (EDT)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: One-Layer Atmosphere Model
Description: implementation of Robinson, Walter A. (2001) Modeling Dynamic Climate Systems. (section 2.2)
Url: http://www.primordion.com/Xholon/wb/xholon
InternalName:
YoutubeId:
Keywords:
My Notes
--------
How to run this app ::
Click the Run button above.
Click the Step button in the overlay, to advance the app by one time step.
Each time step, the app will update the graph.
The upper curve is the temperature at Earth's surface (Ts), in degrees Celsius and Kelvin.
The lower curve is the temperature of Earth's atmosphere (Ta).
By year 10, the average surface temperature has stabilized at a bit above 15°C.
I previously implemented the No-Atmosphere Climate Model from the Robinson book. This workbook implements Robinson's One-Layer Atmosphere Model, the next level up in complexity.
I have previously written a complete Java-based implementation of this model, using Xholon jvmEdition. That source code is available at SourceForge ::
http://xholon.cvs.sourceforge.net/viewvc/xholon/xholon/src/org/primordion/user/app/climatechange/mdcs/m2_2mp/
It can be run from the following page. Click on the launch button under Climate Change models ::
http://www.primordion.com/Xholon/jnlp/
Description of what's happening in this model
---------------------------------------------
Every second the Sun releases shortwave (sw) energy in all directions into Space.
A tiny amount of this energy (about 1367.0 Watts per square meter) reaches the circular area in Space where the Earth is located.
Because half of the Earth is always in nighttime, and because the higher latitudes receive less sunlight, the incoming solar energy is divided by 4 to derive a value (about 341.75 Watts per square meter) averaged over 24 hours and all latitudes.
In this model, the top of the Atmosphere reflects over 30% (albedo = 0.307168) of the solar energy back into Space.
The remaining solar energy passes into the Atmosphere, with an arbitrary initial temperature of 0°C.
Initially the Atmosphere cools relatively rapidly, but stabilizes at around -26°C once the incoming shortwave solar energy balances the outgoing longwave energy.
The Surface consists of Water to a depth of 50 meters.
The Surface is given an arbitrary initial temperature of 0°C, and a corresponding amount of energy.
The Surface absorbs all of the energy it receives.
The Surface also emits some of its energy as heat (longwave (lw) energy), back into the Atmosphere.
The Surface temperature stabilizes at around 15 °C.
Surface and atmosphere energy are measured as temperature, and the changing temperatures are plotted on a graph.
Basically, the model calculates the actual surface and atmosphere temperatures, given an initial guess. The graph shows the changing temperatures as they move from the initial guess to the actual value.
Diagrams and Data
=================
Network Diagram
---------------
How to generate a network diagram using Xholon jvmEdition ::
(1) Click the Chameleon_0.jnlp Launch button further down on this page.
When the Xholon Chameleon window appears, select File > Open.
(2) Click the "Save locally" button above. A new browser window will open with the entire contents of this Xholon Workbook.
Select all the text in the Workbook by pressing Ctrl-A while the new browser window is selected.
Drag the selected text to the Xholon Chameleon window.
(3) Click "Refresh" in the Xholon Chameleon window.
Find the theSystem node in the tree.
Right-click that node and select "Graphical Network Viewer".
(4) You can zoom the diagram, move parts around, rotate and stretch it (Shift-Click and Ctrl-Click), and show or hide the vertex labels and/or the edge labels.
Once it's arranged the way you want, click File to save it in JPEG or PNG format.
The network diagram lets you see how the nodes connect with each other. This model is complex enough that it's nice to see all the parts and connectors laid out as a diagram. It uses the structure defined in the xholonClassDetails and TheSystem editors on this page.
See ::
http://www.primordion.com/Xholon/wb/images/networkDiagram2489058.png
Xholon jvmEdition uses the third-party JUNG Java library to display network diagrams.
Tree Diagram
------------
The jvmEdition can also generate a tree diagram of the composite structure ::
http://www.primordion.com/Xholon/wb/images/treeDiagram2489058.png
Xholon jvmEdition uses the third-party JUNG Java library to display tree diagrams.
Displaying the results to a Wikipedia SVG image
-----------------------------------------------
The original jvmEdition implementation (the m2_mp model), using the jnlp link above, downloads an SVG image from Wikipedia, translates it from German to English, and writes data to the image every time step. The original downloaded image is ::
http://upload.wikimedia.org/wikipedia/commons/d/d2/Sun_climate_system_alternative_(German)_2008.svg
At year 10, the diagram looks like this ::
http://www.primordion.com/Xholon/wb/images/wiki_mdcs_m2_2mp.svg
Displaying the results as text
------------------------------
Applying the |Show the contents of the entire CSH tree (jvmEdition)| script from the following workbook, ::
http://www.primordion.com/Xholon/wb/openwb.php?q=2567985&f=gist.github.com/raw/
generates the following text summary. These numbers agree with the numbers in the modified SVG image at year 10 ::
timestep: 10
theSystem_0
solarSystem_1
sun_2
temperature_3 5778 K
space_4
earth_5
topOfAtmosphere_6
albedo_7 0.307168
atmosphere_8
energy_9 2557738703.4730215 J
albedo_10 0
temperature_11 246.70731363518652 K
Ta Ta:celsius_12
mass_13 10326.19776 kg/m^2
specificHeat_14 1004 J/kg/K
heatCapacity_15 10367502.55104 J/m^3/K
absorption_16 0.1
emissivity_17 0.856347
surface_18
energy_19 60831650969.784546 J
albedo_20 0
temperature_21 288.4383640103582 K
Ts Ts:celsius_22 15.288364010358237
water_23
density_24 1000 kg/m^3
specificHeat_25 4218 J/kg/K
mixedLayer_26
depth_27 50 m
heatCapacity_28 210900000 J/m^3/K
fluxes_29
SunSpc_sw SunSpc_sw:flux_30 1367 W/m^2
SpcTpf_sw SpcTpf_sw:flux_31 1367 W/m^2
TpfTpf_sw TpfTpf_sw:flux_32 341.75 W/m^2
TpfAtm_sw TpfAtm_sw:flux_33 236.775336 W/m^2
AtmTpf_sw AtmTpf_sw:flux_34 0 W/m^2
AtmSrf_sw AtmSrf_sw:flux_35 213.0978024 W/m^2
SrfAtm_sw SrfAtm_sw:flux_36 0 W/m^2
TpfSpc_sw TpfSpc_sw:flux_37 104.974664 W/m^2
SrfAtm_sh SrfAtm_sh:flux_38 0 W/m^2
SrfAtm_lh SrfAtm_lh:flux_39 0 W/m^2
SrfAtm_lw SrfAtm_lw:flux_40 392.4185741707109 W/m^2
AtmSrf_lw AtmSrf_lw:flux_41 179.85229669147344 W/m^2
AtmTpf_aw AtmTpf_aw:flux_42 0 W/m^2
AtmTpf_lw AtmTpf_lw:flux_43 236.22243233849244 W/m^2
TpfSpc_lw TpfSpc_lw:flux_44 236.21442229019513 W/m^2
constants_45
stefanBoltzmannConstant_46 5.6696e-8 W/m^2/K^4
secondsPerTimeStep_47 31536000 s
Analyzing the results with XQuery
---------------------------------
The jvmEdition running on the desktop (rather than under jnlp) can use the Saxon implementation of XQuery to operate on the current state of the model. XQuery is a standard for querying XML content. A query for the complete XML structure produces the following ::
http://www.primordion.com/Xholon/wb/images/xquery_mdcs_m2_2mp.xml
Sequence Diagram
----------------
The jvmEdition running on the desktop (rather than under jnlp) can use the Quick Sequence Diagram Editor (a third-party Java library) to generate a UML sequence diagram. It shows the real-time exchange of messages between various nodes in the model. Here's the first part of that extensive interaction ::
http://www.primordion.com/Xholon/wb/images/msc_mdcs_m2_2mp.png
The PNG image is long, so you'll probably need to zoom in to see any details.
Line Chart
----------
The jvmEdition uses JFreeChart, a third-party Java library, to generate a graph showing the changes in temperature over time ::
http://www.primordion.com/Xholon/wb/images/chart_mdcs_m2_2mp.png
Mind Maps
---------
The jvmEdition running on the desktop can also generate a mind map file, in FreeMind .mm format. The file can be opened and edited in FreeMind (I use version 0.9.0 RC6) and in other mind mapping software such as XMind. The mind map software shows all the nodes in the composite structure hierarchy, and the connectors between nodes. The content is similar to the network diagram described above, but it also shows the parent child relationships of the tree structure.
The generated FreeMind file is very simple ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307.mm
FreeMind can export the mind map as an interactive HTML/Flash app that will run in your web browser ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307.html
as an interactive Java applet ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307_applet.html
as an SVG image ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307.svg
as a PNG image ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307.png
as a PDF ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307.pdf
and in other formats.
With FreeMind you can add icons to nodes, change colors and other attributes, hide and show nodes, add new nodes, remove nodes, etc. Here's an example ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307_freemind01.svg
XMind lays out the content of the .mm file in a different way ::
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307_xmind01.png
http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336137685307_xmind01.html
Semantic Web
------------
The jvmEdition can use Jena to write out various semantic web representations of the Xholon model.
The entire model written in the Turtle (Terse RDF Triple Language) serialization format for Resource Description Framework (RDF) graphs ::
http://www.primordion.com/Xholon/wb/images/turtle_mdcs_m2_2mp.ttl
Or the model written in Resource Description Framework (RDF) format ::
http://www.primordion.com/Xholon/wb/images/rdf_mdcs_m2_2mp.rdf
Or the model written in RDF abbrev format ::
http://www.primordion.com/Xholon/wb/images/rdfabbrev_mdcs_m2_2mp.rdf
Or the model written in N-TRIPLE format, "a line-based, plain text serialisation format for RDF graphs, and a subset of the Turtle format" ::
http://www.primordion.com/Xholon/wb/images/ntriple_mdcs_m2_2mp.nt
The W3C offers a RDF validation service ::
http://www.w3.org/RDF/Validator/
Enter the URI for the "the model written in Resource Description Framework (RDF) format" (see above). The W3C service will validate it.
The W3C validator will also display the information in various selectable ways, by default in a table. Some of the table cells are clickable, such as the useful links to dbpedia resources. For example, dbpedia will provide some information from the Wikipedia page for "Sun", if you click on ::
http://dbpedia.org/resource/Sun
The www.primordion.com objects don't link to anything outside this application.
The validator can also generate graphs in various formats, selectable using "Display Result Options". Unfortunately, the graphs are VERY large, and I don't recommend trying to view them, especially the embedded versions. I was able to view the generated SVG image, but it's too big to be useful.
UML Class Diagram
-----------------
The jvmEdition can generate a yUML-compatible file. Paste the contents of that file into the online yUML tool, which will generate and save a UML class diagram. Try these links:
|the generated file| http://www.primordion.com/Xholon/wb/images/yuml_TheSystem_0_1336149415909.txt
|JPEG| http://yuml.me/dc41277f.jpg
|SVG| http://yuml.me/dc41277f.svg
|edit| http://yuml.me/edit/dc41277f
|JSON| http://yuml.me/dc41277f.json
|PDF| http://yuml.me/dc41277f.pdf
|PNG| http://yuml.me/dc41277f
UML Class and Composite Structure Diagrams
------------------------------------------
The jvmEdition can generate PlantUML-compatible files. PlantUML turns these into UML class diagrams, or pseudo composite structure diagrams, as PNG files.
|class diagram generated file| http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336153169955.txt
|class diagram PNG| http://www.primordion.com/Xholon/wb/images/TheSystem_0_1336153169955.png
|composite diagram generated file| http://www.primordion.com/Xholon/wb/images/TheSystem_0_Composite_1336153179830.txt
|composite diagram PNG| http://www.primordion.com/Xholon/wb/images/TheSystem_0_Composite_1336153179830.png
Other Links
-----------
Third-party software mentioned in this workbook, and other useful links:
|JUNG| http://jung.sourceforge.net/
|JFreeChart| http://www.jfree.org/jfreechart/
|Quick Sequence Diagram Editor| http://sdedit.sourceforge.net/
|FreeMind| http://freemind.sourceforge.net/wiki/index.php/Main_Page
|XMind| http://www.xmind.net/
|yUML| http://yuml.me/
|PlantUML| http://plantuml.sourceforge.net/
|Saxon XQuery| http://saxon.sourceforge.net/
|Jena| http://incubator.apache.org/jena/
]]></Notes>
<script implName="lang:python:inline:"><![CDATA[
]]></script>
<script implName="lang:javascript:inline:"><![CDATA[
]]></script>
<_-.XholonClass>
<!-- types of domain objects -->
<TheSystem/>
<SolarSystem/>
<Sun/>
<Planet>
<Earth/>
</Planet>
<Space/>
<TopOfAtmosphere/>
<Atmosphere/>
<Surface/> <!-- "the planet is represented by an average square meter of its surface"; ocean -->
<Water/> <!-- 70% of the Earth's surface is water; for the model we assume 100% of the surface is water -->
<MixedLayer/> <!-- the top layer of the ocean, where significant mixing of heat/etc occurs -->
<!-- quantities -->
<PhysicalProperty>
<!-- properties of the atmosphere -->
<Mass/>
<Absorption/>
<Emissivity/>
<!-- properties of the square meter of surface -->
<Energy/>
<Albedo/>
<Temperature/> <!-- Kelvin -->
<Celsius/> <!-- Temperature in Celsius -->
<!-- properties of the water -->
<Density/>
<SpecificHeat/>
<Depth/>
<HeatCapacity/>
</PhysicalProperty>
<!-- fluxes -->
<Flux/>
<Fluxes/>
<!-- constants -->
<Constant>
<StefanBoltzmannConstant/>
<SecondsPerTimeStep/>
</Constant>
<Constants/>
</_-.XholonClass>
<xholonClassDetails>
<Sun xhType="XhtypePureActiveObject">
<port name="space" connector="#xpointer(ancestor::SolarSystem/Space)"/>
</Sun>
<Space xhType="XhtypePureActiveObject">
<port name="planet" connector="#xpointer(ancestor::SolarSystem/Earth/TopOfAtmosphere)"/>
<port name="solarConstant" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='SunSpc_sw'])"/>
<port name="longwaveRadiation" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='TpfSpc_lw'])"/>
<port name="reflectedShortwaveRadiation" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='TpfSpc_sw'])"/>
</Space>
<TopOfAtmosphere xhType="XhtypePureActiveObject">
<port name="space" connector="#xpointer(ancestor::SolarSystem/Space)"/>
<port name="atmosphere" connector="#xpointer(ancestor::Earth/Atmosphere)"/>
<port name="albedo" connector="#xpointer(Albedo)"/>
<port name="solarConstant" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='SpcTpf_sw'])"/>
<port name="solarConstantDivFour" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='TpfTpf_sw'])"/>
<port name="reflectedShortwaveRadiation" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmTpf_sw'])"/>
<port name="lwOut" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmTpf_lw'])"/>
</TopOfAtmosphere>
<Atmosphere xhType="XhtypePureActiveObject">
<port name="topOfAtmosphere" connector="#xpointer(ancestor::Earth/TopOfAtmosphere)"/>
<port name="surface" connector="#xpointer(ancestor::Earth/Surface)"/>
<port name="energy" connector="#xpointer(Energy)"/>
<port name="temperature" connector="#xpointer(Temperature)"/>
<port name="albedo" connector="#xpointer(Albedo)"/>
<port name="mass" connector="#xpointer(Mass)"/>
<port name="specificHeat" connector="#xpointer(SpecificHeat)"/>
<port name="heatCapacity" connector="#xpointer(HeatCapacity)"/>
<port name="absorption" connector="#xpointer(Absorption)"/>
<port name="emissivity" connector="#xpointer(Emissivity)"/>
<port name="stefanBoltzmannConstant" connector="#xpointer(ancestor::TheSystem/Constants/StefanBoltzmannConstant)"/>
<port name="secondsPerTimeStep" connector="#xpointer(ancestor::TheSystem/Constants/SecondsPerTimeStep)"/>
<port name="swIn" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='TpfAtm_sw'])"/>
<port name="lwIn" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='SrfAtm_lw'])"/>
<port name="lwUp" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmTpf_lw'])"/>
<port name="lwDown" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmSrf_lw'])"/>
<port name="reflectedShortwaveRadiation" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='SrfAtm_sw'])"/>
</Atmosphere>
<Surface xhType="XhtypePureActiveObject">
<port name="atmosphere" connector="#xpointer(ancestor::Earth/Atmosphere)"/>
<port name="energy" connector="#xpointer(Energy)"/>
<port name="albedo" connector="#xpointer(Albedo)"/>
<port name="temperature" connector="#xpointer(Temperature)"/>
<port name="water" connector="#xpointer(Water)"/>
<port name="stefanBoltzmannConstant" connector="#xpointer(ancestor::TheSystem/Constants/StefanBoltzmannConstant)"/>
<port name="secondsPerTimeStep" connector="#xpointer(ancestor::TheSystem/Constants/SecondsPerTimeStep)"/>
<port name="solarIn" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmSrf_sw'])"/>
<port name="infraredIn" connector="#xpointer(ancestor::TheSystem/Fluxes/Flux[@roleName='AtmSrf_lw'])"/>
</Surface>
<Water xhType="XhtypePureActiveObject">
<port name="depth" connector="#xpointer(MixedLayer/Depth)"/>
<port name="heatCapacity" connector="#xpointer(HeatCapacity)"/>
<port name="density" connector="#xpointer(Density)"/>
<port name="specificHeat" connector="#xpointer(SpecificHeat)"/>
</Water>
<Celsius xhType="XhtypePurePassiveObject">
<port name="k" connector="#xpointer(..)"/>
</Celsius>
</xholonClassDetails>
<TheSystem>
<Constants>
<StefanBoltzmannConstant unit="W/m^2/K^4">5.6696e-8</StefanBoltzmannConstant>
<SecondsPerTimeStep unit="s">31536000.0</SecondsPerTimeStep> <!-- SecondsPerYear 365*24*60*60 -->
<!--<SecondsPerTimeStep units="s">86400.0</SecondsPerTimeStep>--> <!-- SecondsPerDay -->
<!--<SecondsPerTimeStep units="s">2592000.0</SecondsPerTimeStep>--> <!-- SecondsPerMonth -->
</Constants>
<SolarSystem>
<Sun>
<Temperature unit="K">5778.0</Temperature>
</Sun>
<Space/>
<!--<xi:include href="./org/primordion/user/app/climatechange/mdcs/m2_2mp/earthRB_csh.xml"/>-->
<Earth>
<TopOfAtmosphere>
<Albedo>0.307168</Albedo> <!-- for use with Robinson STELLA approach -->
</TopOfAtmosphere>
<Atmosphere>
<Energy unit="J"/>
<Albedo>0.0</Albedo> <!-- 77/342 = 0.225146198 K+T -->
<Temperature unit="K">273.15
<Celsius roleName="Ta"/>
</Temperature> <!-- initial temperature -->
<Mass unit="kg/m^2">10326.19776</Mass> <!-- 101300/9.81 -->
<SpecificHeat unit="J/kg/K">1004.0</SpecificHeat>
<HeatCapacity unit="J/m^3/K"/>
<Absorption>0.1</Absorption> <!-- 67/(342-77) = 0.252830188 K+T -->
<Emissivity>0.856347</Emissivity>
</Atmosphere>
<Surface>
<Energy unit="J"/>
<Albedo>0.0</Albedo> <!-- 30/198 = 0.1515 K+T -->
<Temperature unit="K">273.15
<Celsius roleName="Ts"/>
</Temperature> <!-- initial temperature -->
<Water>
<Density unit="kg/m^3">1000.0</Density>
<SpecificHeat unit="J/kg/K">4218.0</SpecificHeat>
<MixedLayer>
<Depth unit="m">50.0</Depth>
</MixedLayer>
<HeatCapacity unit="J/m^3/K"/>
</Water>
</Surface>
</Earth>
</SolarSystem>
<Fluxes> <!-- with optional initial values -->
<!-- sw -->
<Flux roleName="SunSpc_sw" unit="W/m^2">1367.0</Flux> <!-- solar constant -->
<Flux roleName="SpcTpf_sw" unit="W/m^2">1367.0</Flux> <!-- solar constant -->
<Flux roleName="TpfTpf_sw" unit="W/m^2">341.75</Flux> <!-- local to Tpf; solar constant / 4 -->
<Flux roleName="TpfAtm_sw" unit="W/m^2">236.775336</Flux> <!-- solar KT:341.75 RB:236.775336 -->
<Flux roleName="AtmTpf_sw" unit="W/m^2">0.0</Flux> <!-- reflected -->
<Flux roleName="AtmSrf_sw" unit="W/m^2">213.0978024</Flux> <!-- solar KT:341.75 RB:213.0978024 -->
<Flux roleName="SrfAtm_sw" unit="W/m^2">0.0</Flux> <!-- reflected -->
<Flux roleName="TpfSpc_sw" unit="W/m^2">0.0</Flux> <!-- reflected -->
<!-- lw -->
<Flux roleName="SrfAtm_sh" unit="W/m^2">0.0</Flux>
<Flux roleName="SrfAtm_lh" unit="W/m^2">0.0</Flux>
<Flux roleName="SrfAtm_lw" unit="W/m^2">278.0</Flux>
<Flux roleName="AtmSrf_lw" unit="W/m^2">0.0</Flux>
<Flux roleName="AtmTpf_aw" unit="W/m^2">0.0</Flux>
<Flux roleName="AtmTpf_lw" unit="W/m^2">0.0</Flux>
<Flux roleName="TpfSpc_lw" unit="W/m^2">0.0</Flux>
</Fluxes>
</TheSystem>
<Blockbehavior implName="lang:python:inline:"><![CDATA[
]]></Blockbehavior>
<Blockbehavior implName="lang:javascript:inline:"><![CDATA[
]]></Blockbehavior>
<TheSystembehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
$("textarea#btstrp_console").css("font-size", "12px");
$("textarea#btstrp_console").attr("rows", "3");
$("textarea#btstrp_console").attr("cols", "50");
this.application('setConfigParam', 'TimeStepMultiplier', 32); // 32
dt = 1 / this.application('getConfigParam', 'TimeStepMultiplier');
}
function preAct() {
print("\n\nYear: " + this.application('getTimeStep'));
}
]]></TheSystembehavior>
<Sunbehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
this.parent().attr("solarConstant", 1367.0);
}
function preAct() {
this.bindPorts(this.parent());
this.space.sendMessage("SIG_SW", this.parent().attr("solarConstant"), this.parent());
}
]]></Sunbehavior>
<Spacebehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postAct() {
this.bindPorts(this.parent());
this.planet.sendMessage("SIG_SW", this.solarConstant.attr("val"), this.parent());
}
function processReceivedMessage(msg) {
this.bindPorts(this.parent());
switch (msg.signal) {
case "SIG_SW":
this.solarConstant.attr("val", msg.data);
break;
case "SIG_LW":
this.longwaveRadiation.attr("val", msg.data);
break;
case "SIG_SW_REFLECTED":
this.reflectedShortwaveRadiation.attr("val", msg.data);
break;
default: break;
}
}
]]></Spacebehavior>
<TopOfAtmospherebehavior implName="lang:webEditionjs:inline:"><![CDATA[
function act() {
this.bindPorts(this.parent());
this.solarConstantDivFour.attr("val", this.solarConstant.attr("val") / 4.0);
this.atmosphere.sendMessage("SIG_SW", this.solarConstant.attr("val") / 4.0 * (1.0 - this.albedo.attr("val")), this.parent());
if (this.albedo.attr("val") > 0.0) {
this.space.sendMessage("SIG_SW_REFLECTED", this.solarConstant.attr("val") / 4.0 * this.albedo.attr("val"), this.parent());
}
}
function processReceivedMessage(msg) {
this.bindPorts(this.parent());
switch (msg.signal) {
case "SIG_SW":
this.solarConstant.attr("val", msg.data);
break;
case "SIG_LW":
this.lwOut.attr("val", msg.data); // from atmosphere
this.space.sendMessage(msg.signal, msg.data, this.parent()); // relay
break;
case "SIG_SW_REFLECTED":
this.reflectedShortwaveRadiation.attr("val", msg.data); // from atmosphere
this.space.sendMessage(msg.signal, msg.data, this.parent()); // relay
break;
default: break;
}
}
]]></TopOfAtmospherebehavior>
<Waterbehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
this.bindPorts(this.parent());
this.heatCapacity.attr("val", this.density.attr("val") * this.depth.attr("val") * this.specificHeat.attr("val"));
}
]]></Waterbehavior>
<Surfacebehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
this.bindPorts(this.parent());
this.energy.attr("val", this.temperature.attr("val") * this.water.children(".HeatCapacity").attr("val"));
this.parent().attr("solar", this.solarIn.attr("val") * (1.0 - this.albedo.attr("val")));
this.parent().attr("infrared", this.stefanBoltzmannConstant.attr("val") * Math.pow(this.temperature.attr("val"), 4));
}
function act() {
this.bindPorts(this.parent());
this.energy.attr("val", (this.energy.attr("val")-0) + ((this.parent().attr("solar")-0) + (this.infraredIn.attr("val")-0) - this.parent().attr("infrared")) * this.secondsPerTimeStep.attr("val") * dt);
this.temperature.attr("val", this.energy.attr("val") / this.water.children(".HeatCapacity").attr("val"));
this.parent().attr("solar", this.solarIn.attr("val") * (1.0 - this.albedo.attr("val")));
this.parent().attr("infrared", this.stefanBoltzmannConstant.attr("val") * Math.pow(this.temperature.attr("val"), 4));
this.atmosphere.sendMessage("SIG_SW_REFLECTED", this.solarIn.attr("val") * this.albedo.attr("val"), this);
this.atmosphere.sendMessage("SIG_LW", this.parent().attr("infrared"), this);
}
function processReceivedMessage(msg) {
this.bindPorts(this.parent());
switch (msg.signal) {
case "SIG_SW":
this.solarIn.attr("val", msg.data);
break;
case "SIG_LW":
this.infraredIn.attr("val", msg.data);
break;
default: break;
}
}
]]></Surfacebehavior>
<Atmospherebehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
this.bindPorts(this.parent());
this.heatCapacity.attr("val", this.mass.attr("val") * this.specificHeat.attr("val"));
this.energy.attr("val", this.temperature.attr("val") * this.heatCapacity.attr("val"));
this.attr("irAtmosphere", this.stefanBoltzmannConstant.attr("val") * this.emissivity.attr("val") * Math.pow(this.temperature.attr("val"), 4));
// ir is a function of surface temperature
this.attr("ir", this.surface.attr("infrared"));
var val1 = this.attr("ir") * (1.0 - this.emissivity.attr("val"))-0;
this.attr("irToSpace", val1 + (this.attr("irAtmosphere")-0) );
}
function act() {
this.bindPorts(this.parent());
this.attr("reflectedFromAtmosphere", this.swIn.attr("val") * this.albedo.attr("val"));
this.attr("absorbedByAtmosphere", (this.swIn.attr("val") - this.attr("reflectedFromAtmosphere")) * this.absorption.attr("val"));
//Energy_in_Atmosphere(t) = Energy_in_Atmosphere(t - dt) + (IR + Solar_to_atmosphere - IR_down - IR_to_space) * dt
this.energy.attr("val", (this.energy.attr("val")-0) + ((this.lwIn.attr("val")-0) + (this.attr("absorbedByAtmosphere")-0) - this.attr("irAtmosphere") - this.attr("irToSpace")) * this.secondsPerTimeStep.attr("val") * dt);
this.temperature.attr("val", this.energy.attr("val") / this.heatCapacity.attr("val"));
this.attr("irAtmosphere", this.stefanBoltzmannConstant.attr("val") * this.emissivity.attr("val") * Math.pow(this.temperature.attr("val"), 4));
this.attr("ir", this.lwIn.attr("val"));
var val1 = this.attr("ir") * (1.0 - this.emissivity.attr("val"))-0;
this.attr("irToSpace", val1 + (this.attr("irAtmosphere")-0) );
this.surface.sendMessage("SIG_SW", this.swIn.attr("val") - this.attr("reflectedFromAtmosphere") - this.attr("absorbedByAtmosphere"), this);
this.surface.sendMessage("SIG_LW", this.attr("irAtmosphere"), this);
this.topOfAtmosphere.sendMessage("SIG_LW", this.attr("irToSpace"), this);
// no need to send the next msg; it always has val = 0
//this.topOfAtmosphere.sendMessage("SIG_SW_REFLECTED", (this.reflectedShortwaveRadiation.attr("val")-0) + (this.attr("reflectedFromAtmosphere")-0), this);
}
function processReceivedMessage(msg) {
this.bindPorts(this.parent());
switch(msg.signal) {
case "SIG_SW":
this.swIn.attr("val", msg.data);
break;
case "SIG_LW":
this.lwIn.attr("val", msg.data);
break;
case "SIG_SW_REFLECTED":
this.reflectedShortwaveRadiation.attr("val", msg.data); // from surface
break;
default:
break;
}
}
]]></Atmospherebehavior>
<Fluxbehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postAct() {
//print("\n" + this.parent().attr("rolename") + ": " + this.parent().attr("val") + " " + this.parent().attr("unit"));
}
]]></Fluxbehavior>
<Celsiusbehavior implName="lang:webEditionjs:inline:"><![CDATA[
function postConfigure() {
this.bindPorts(this.parent());
this.parent().attr("val", this.k.attr("val") - 273.15);
var kelvin = this.k.attr("val");
var celsius = kelvin - 273.15;
print("\n" + this.parent().attr("roleName") + " Celsius: " + celsius + " Kelvin: " + kelvin);
}
function act() {
// draw a graph
var oldCelsius = this.parent().attr("val");
var newCelsius = this.parent().parent().attr("val") - 273.15;
this.parent().attr("val", newCelsius);
var dCelsius = oldCelsius - newCelsius;
if (isNaN(dCelsius)) {dCelsius = 0;}
var path = this.parent().data("path" + this.parent().attr("roleName"));
if (!path) {
var svg = $($('div#mySVGDiv > object')[0].contentDocument.getElementsByTagNameNS(svgns, 'svg')[0]);
path = svg.children("g").children("g#Graph").children("path#" + this.parent().attr("roleName"));
this.parent().data("path" + this.parent().attr("roleName"), path);
this.parent().data("d", path.attr("d"));
}
var d = this.parent().data("d") + "l1 " + (dCelsius * 5); // 10 5
this.parent().data("d", d);
path.attr("d", d);
}
function postAct() {
this.bindPorts(this.parent());
var kelvin = this.k.attr("val")-0;
var celsius = kelvin - 273.15;
print("\n" + this.parent().attr("roleName") + " Celsius: " + celsius.toFixed(3) + " Kelvin: " + kelvin.toFixed(3));
}
]]></Celsiusbehavior>
<Blockbehavior implName="lang:bsh:inline:"><![CDATA[
]]></Blockbehavior>
<Blockbehavior implName="lang:jruby:inline:"><![CDATA[
]]></Blockbehavior>
<Blockbehavior implName="lang:groovy:inline:"><![CDATA[
]]></Blockbehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="400" height="350" xmlns="http://www.w3.org/2000/svg">
<g>
<g id="Space">
<title>One-Layer Atmosphere Model - Space</title>
<rect id="TheSystem/SolarSystem/Space" fill="black" height="50" width="400"/>
<g>
<title>Sun</title>
<circle id="TheSystem/SolarSystem/Sun" fill="yellow" stroke="black" cx="15" cy="10" r="5"/>
</g>
<g>
<title>Atmosphere</title>
<circle id="TheSystem/SolarSystem/Earth/Atmosphere" fill="#4169E1" cx="370" cy="25" r="24"/>
</g>
<g>
<title>Surface with Water</title>
<circle id="TheSystem/SolarSystem/Earth/Surface/Water" fill="#3CB371" cx="370" cy="25" r="22"/>
</g>
<g>
<title>Earth</title>
<circle id="TheSystem/SolarSystem/Earth" opacity="0.25" fill="#CD853F" cx="370" cy="25" r="20"/>
</g>
</g>
<g id="Graph">
<title>Graph of Earth Surface and Atmosphere Temperatures vs Time</title>
<rect fill="black" y="50" height="300" width="400"/>
<path id="Ta" d="M0 150" stroke="white" stroke-width="1"/>
<path id="Ts" d="M0 150" stroke="white" stroke-width="1"/>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>