Testing NSM

From VLECK
Jump to: navigation, search

Unit Tests

At this moment no solution is available for unit testing NSM-code. Unit testing is about repeatable checking whether the written code really implements the intentions of the programmer and continues to run error-free under various conditions and even so after changes in any other part of the code base.

Sensitivity and Behaviour Analysis

A simple sensitivity viewer (download) is available to investigate small pieces of code for the effects of changes to the various inputs. Inputs are parameters and variables, but the viewer does not discriminate between them. When an input is selected, the code is evaluated while making relative changes to the input, and the result is plotted on screen.

QuickSensitivityScreen.jpg

The code that is investigated must be extracted from the model and be able to run independently. However, parameters and variables it depends on can be supplied (see below). In order to be plottable, the result must be a simple series of values.

preparing the code

The test code must contain a function called Calculation(), with three arguments: Parameters, Variables, and the X-values. It must return a structure with any number of named outputs, each containing a series of Y-values matching the X-values:


function Calculation(Parameters; Variables; IndependentVar)    
   Calculation = LightUse(Parameters; Variables:FoliageNConc; Variables:FoliageWeight; IndependentVar);
end of Calculation

It is good practice to use this function only to interface between the calling program and your own code. Thus, in the example, the real calculations are defered to the function LightUse, which was copied wit modifications from the model code.

Both Parameters and Variables must be initialised by the test code, as structures with default values:

   // default Parameter Values, may be overridden in ActualValues.inc:
   Parameters = {
       cJmaxToNitrogen             = 1.5 * 62.404992;
       cInterceptJmaxToNitrogen    = 1.5 * 0.237904;
       deltaSOfJmax                = 807.4;
       cHaOfJmax                   = 37393.0;
       cHdOfJmax                   = 250000.0;
       };
       
   // default Variable Values, may be overridden in ActualValues.inc:
   Variables = {
       FoliageWeight               = 20.0;
       FoliageNConc                = 0.03;
       };

This defines both their names and values. The latter will be manipulated by the calling program. Finally, the independend (X-)variable must be defined.

   // metaInfo for the caller:
   IndependentVar = {
       Name   = "X";
       Info   = "temperature [ºC]";
       MinVal = 0;
       MaxVal = 50;
       };

Copy this structure exactly, and only change the values where required.

Name Name of the variable; better not change it: use Calculation() to interface with your own variable.
Info text that is shown on the x-axis of the plot
MinVal, MaxVal a series of 100 samples between these values aresent to the test code to be tested


That's all, only make sure your code can run. Here is an example of real model code, adapted to be tested:


   function TemperatureEffectOnJmaxVcMax(Ha; Hd; RefTmp; LeafTemperature; deltaS)
       //multiplier for temperature effects on VcMax and Jmax [ - ]
       MolarGasConstant             = 8.314472;    <J mol - 1 K - 1>
       LeafTemperature              = LeafTemperature + 273.15; // from Celsius to Kelvin
       TemperatureEffectOnJmaxVcMax = exp(Ha * (LeafTemperature - RefTmp) / (MolarGasConstant * LeafTemperature * RefTmp))
                                   / (1 + exp((deltaS * LeafTemperature - Hd) /  (MolarGasConstant * LeafTemperature))); 
   end of TemperatureEffectOnJmaxVcMax

   
   
   function LightUse(Par; FoliageNConc; FoliageWeight; Temperature)
   
       TemperatureEffectOnJmax  = TemperatureEffectOnJmaxVcMax(Par:cHaOfJmax;  
                                                               Par:cHdOfJmax;  
                                                               25 + 273.15; 
                                                               Temperature; 
                                                               Par:deltaSOfJmax);
                                                               
       Jmax        = FoliageWeight 
                   * (Par:cJmaxToNitrogen * FoliageNConc - Par:cInterceptJmaxToNitrogen) 
                   * TemperatureEffectOnJmax;    // unit: kg C tree - 1 day(light) - 1
                                                               
       LightUse = {Jmax; TemperatureEffectOnJmax};
   end of LightUse
   
   
   
   function Calculation(Parameters; Variables; IndependentVar)    
       Calculation = LightUse(Parameters; Variables:FoliageNConc; Variables:FoliageWeight; IndependentVar);
   end of Calculation

add the test to Sensitivity Viewer

  • Save or copy the file with the test code to the TestUnits subdirectory of the program
  • Edit CodeToTest.inc so that it refers to this file
  • run SensitivityViewer.exe

problems

the plot is a straight line through 0, there are no inputs and outputs
NSM could not run the program. This can have two causes:
  1. NSM didnot run
  2. NSM run but run into an error

First check NSM.bat. Is the path to NSM.exe correct? Remove the -r-option and run NSM.bat. NSM now should open with SensitivityTest.def loaded. Can you compile the program? Can you run it from here?