CSR Parameter-mechanism

From VLECK
Jump to: navigation, search

definition of parameters

Parameters are defined in the parameters-section of the type file. A parameter addressed in code that has no corresponding definition will cause an exception. A parameter given a value in the typology section of the type file on the other hand will just go undetected (it will not instantiate a parameter object).

The definition is enclosed by the tag paramdef. The tag has three required attributes:

  1. name: the name of the parameter (case sensitive!)
  2. unit: the unit declaration. Compound units have their elemets connected by dots (eg. "kW.h") may be entered either in power notation or with a single forward slash. So: "kg.m2.s-1" is equivalent to "kg.m2/s".
  3. description: any text describing the parameter.


parameter definition
<paramdef name="Gmax" unit="mmol.m-2.s-1" description="water vapour max. conductance"/>



valuation of parameters

Parameters get their values in the types-section of the type file. Please refer to that article for details of the syntax.

See the following example:

simple example
<typology>
   <parameter_definitions>
      <paramdef name="pA" units="-" description=""/>
      <paramdef name="pB" units="-" description=""/>
      <paramdef name="pC" units="-" description=""/>
   </parameter_definitions>
   <types>
      <type name="Whole" implementation="Component">
        <parameter name="pA">1.</parameter>
        <parameter name="pB">1.</parameter>
        <parameter name="pC">1.</parameter>
      </type>
    </types>
</typology>


Three parameters, pA, pB, and pC are defined. All three of them get value 1.0 in the type "Whole":

result
Whole: -----
   · parameters:
     º pA = 1.000000 []
     º pB = 1.000000 []
     º pC = 1.000000 []


which parameters are available to simulated objects

See the following example:

parameter "inheritance"
<typology>
   <parameter_definitions>
      <paramdef name="pA" units="-" description=""/>
      <paramdef name="pB" units="-" description=""/>
      <paramdef name="pC" units="-" description=""/>
   </parameter_definitions>
   <types>
      <type name="Part">
        <parameter name="pA">0.</parameter>
      </type>
      <type name="Whole" implementation="Component">
        <parameter name="pB">1.</parameter>
        <component name="PartRedefined" type="Part">
          <parameter name="pC">2.</parameter>
        </component>        
      </type>
    </types>
</typology>


Three parameters, pA, pB, and pC are defined. One of them, pA, gets value 1.0 in the type "Part". An instance of Part is included as a component of type "Whole". This component keeps pA of its ow type, but in addidion has access to pB which is defined by its owner. Further more, the componentt defines its own parameter pC:


result
Whole: -----
   · components:
     º PartRedefined
       · parameters:
         º pA = 0.000000 []
         º pB = 1.000000 []
         º pC = 2.000000 []
   · parameters:
     º pB = 1.000000 []


Note that Processes are Components and behave the same in this respect.
Note that due to their dependence on the owner-object, parameters can change due to setting an owner on their ownership chain. Especially __init__() is therefore not a good place to use any parameter values.

precedence of parameter values

See the following example:

parameter precedence
<typology>
   <parameter_definitions>
      <paramdef name="pA" units="-" description=""/>
      <paramdef name="pB" units="-" description=""/>
      <paramdef name="pC" units="-" description=""/>
   </parameter_definitions>
   <types>
      <type name="Part">
        <parameter name="pA">1.</parameter>
        <parameter name="pB">1.</parameter>
      </type>
      <type name="Whole" implementation="Component">        
        <parameter name="pA">0.</parameter>
        <parameter name="pB">0.</parameter>
        <parameter name="pC">0.</parameter>
        <component name="PartIncluded" type="Part" />        
        <component name="PartRedefined" type="Part">
          <parameter name="pA">2.</parameter>
        </component>        
      </type>
    </types>
</typology>


Two parameters, pA, and pB are defined. Both of them get the value 0.0 in the type "Part". Two instances of Part are included as components of type "Whole". One of them, "PartIncuded", without a change; the other one, "PartRedefined", assignes a new value to parameter pA (2.0). At he same time, the owner "Whole" defines all parameters to value 1.0.

Which values will the parameters have?

The precedence of assignments is from inner to outer:

  1. highest priority gets the value assigned by the (component-)type itself.
  2. next are values assigned within the chain of inheritance of the component
  3. lowest are values assigned within the chain of inheritance of the component
There is a technical reason rather than a choice for this order of precedence: Th parameter list of the type is composed during the construction of the typology-object, which is in a much earlier stage than the assigment of an owner-object. Therefore, once the parameter list of the object is made in cooperation with its owner, inherited type-parameters cannot be distinguished from late-added type-parameters. An in-to-out order of precedence might have been more intuitive, but would be hard to implement.

Component "Whole" sets the values of the three parameters to zero.

Component "PartIncluded" gets pA and pB from type "Part" (value=1.0). Even if its owner "Whole" tries to set their values to 0.0, rule #2 has priority over rule 3.

Component "PartRedefined" gets pA and pB from type "Part" (value=1.0). Even if its owner "Whole" tries to set their values to 0.0, rule #2 has priority over rule 3. But it does assign a new value to pA, so according to rule 1 the actual value of pA will be 2.0


result
Whole: -----
   · components:
     º PartIncluded
       · parameters:
         º pA = 1.000000 []
         º pB = 1.000000 []
         º pC = 0.000000 []
     º PartRedefined
       · parameters:
         º pA = 2.000000 []
         º pB = 1.000000 []
         º pC = 0.000000 []
   · parameters:
     º pA = 0.000000 []
     º pB = 0.000000 []
     º pC = 0.000000 []


economy of using parameters

Parameters are rather complex objects that use the SI-conversion classes to automatically convert the values to the desired units and magnitudes. Also, they keep track of their usage, so unused parameters can be detected to keep the definition files as clean as possible. The down-side of this object-intelligence is that they are not economic to use. It is best, therefore, to copy the required parameters to local variables in an early stage of the run. The initializeAtT0()-method is a good place to do so. Processes have the method _initializeParameters() dedicated to this chore.