Model Structure

skadia.f90
The main program calls readcontrol to read in the user’s preferences for the model run from the control file control.nml. The information in this file determines several factors within the model; the length of the model run, the mode the model is going to be run in, and the input and output files required and generated, respectively. Call Readoptimfile reads in the initial and the range of values that can be taken for the parameters that are able to be optimized within the model. Depending on the mode that the model is running in determines which set of routines are called next,
 * 1) Mode = 0; Optimisation mode
 * 2) Mode = 1; Phase space mode
 * 3) Mode = 2; Inverse model mode
 * 4) Mode = 3; Forward mode

Valley
This is the main program that runs the valley glacier model. Within this routine the following subroutines and functions are called before the model time step is initiated:
 * 1) call getoptimvalues
 * 2) call initial
 * 3) call readgeometry
 * 4) function calcwdth
 * 5) call readcostdata

Main time loop is controlled by count and determined variables trun, tinc and tstr (all units of years and defined in the control file).

Call readgeometry
to read basic geometry of glacier system. The format of the input file containing the geometry information is shown in the control file.

Module read_files (read_files.f90) subroutine readgeometry This subroutine reads information on the geometry of the glacier to be simulated. The name of this file is given in control.nml as geomfile.

Information to be read: current surface and bedrock elevations, as well as reference widths and thicknesses. The format of this file is described in * and allows branched systems.

All variables are scaled and current thickness is determined from the upper surface and bedrock elevation.

Module mass_balance (mass_balance.f90) function calcmask This function returns a mask that indicates where calculations for ice flow etc need to be performed and where not. In the former case, a unique integer value is given to each cell; while 0 is entered in the latter case. For a point to be included one of the following must be true:
 * the point has ice thickness greater than zero;
 * its mass balance is positive;
 * one of its up- or down-stream neighbours has non-zero ice thickness; or
 * the point is at a branch in the system and one of its branched neighbours has non-zero ice thickness.

This function is called from valley and the returned information is held in array mask.

Module ice_flow (ice_flow.f90) function calcthck This function returns ice thickness along the glacier at the new time including the effects of local mass balance and ice flow. This is done using an implicit technique and is complicated by the need to incorporate the effect of possible branches in the glacier system. The equation to be solved is Note that we are not incorporating changes in bedrock elevation so that. The numerical technique involved is based on Crank-Nicolson time differencing: where we follow the suggestion of Hindmarsh and set =1.5. The calculation is best explained in terms of the matrix equation Ax=b, where the vector x (in vector answ) contains the unknown thickness at the new time level; the vector b (in vector rhsd) contains the known thickness at the old time level, the known mass balance and the known flow at the old time level; and the matrix A contains coefficients relating to the thickness and surface elevation at the new time level (i.e., the finite difference approximations to the two terms within the bracketed quantities on the far right hand side). The algorithm proceeds in four stages. 1.	Determine the diffusivities (D) from available thickness and surface elevation at the old time level; we approximate diffusivity at the new time level by the value at the old level. Diffusivity is calculated on a staggered grid halfway between adjacent thickness points. This is done by calling function getdiff and checking to see if the particular point under consideration is affected by a branch. 2.	Determine the flow convergence (c) from available width and diffusivity at the old time level; again we approximate convergence at the new time level by the value at the old level. Diffusivity is calculated the original thickness grid points. This is done by calling function getconv and checking to see if the particular point under consideration is affected by a branch. 3.	We are now in a position to fill matrix A. We enter a value into the sparse form of A if the mask variable shows that this is appropriate (see calcmask). This is done by repeated calls to putpcgc. In the case of a non-branching system, this results in a simple tridiagonal matrix. A great deal of care is required to enter this information correctly for branched systems. The known vector b is filled at the same time using the diffusive and convergence calculated above. 4.	With the matrix A and vector b filled, we can obtain x by standard matrix inversion algorithms (in this case SLAP, see slapsolve below). We only do this if there is a significant length of glacier etc. 5.	Finally, unpack the new surface elevations from the matrix inversion output to the appropriate positions in the surface elevation array (usrf) using information in mask, and then find new thicknesses using bedrock elevation (topg) and glacier length.

function getdiff (contained in calcthck) This function returns the diffusivity of ice flow for a point along the glacier. This is determined from where standard symbols are defined in Table 1. The diffusivity is scaled and is determined on a staggered grid that has points positioned halfway between adjacent thickness grid points. The function is called for each staggered grid point in turn; this means that it is the responsibility of the calling routine to deal with branching in the system. This function is called from calcthck and the returned information is held in array diffus. function getconv (contained in calcthck) This function returns the effect of flow convergence (i.e., varying widths) along the glacier. This is determined from where standard symbols are defined in Table 1. The term is scaled and is determined on the non-staggered grid that is used for thickness calculations. It uses diffusivity from the staggered grid and widths on the non-staggered grid. The function is called for each grid point in turn; this means that it is the responsibility of the calling routine to deal with branching in the system. This function is called from calcthck and the returned information is held in array conver. subroutine putpcgc (contained in calcthck) This simple subroutine fills a sparse matrix using the coefficients supplied. The sparse matrix has a three column format (row, column and value) and can be used with the SLAP matrix algebra library. The subroutine checks to ensure no zero values are entered. The sparse matrix itself is held in module pcgdwk. This subroutine is called from calcthck and is called once per matrix element. subroutine slapsolv (contained in calcthck) This subroutine employs the SLAP matrix algebra library to solve the matrix inversion problem Ax=b, where A and b are known and x is required (in this case, ice thickness). It expects a sparse form of the matrix to exist in module pcgdwk, and will first convert the anticipated three-column format into SLAP’s own storage format (ds2y). The inversion itself is performed using one of a number of preconditioned conjugate-gradient methods available in SLAP (dslucs). Finally, the convergence of the inversion is checked and the program stopped if convergence has not been achieved. This subroutine is called from calcthck. function calcflux This function returns the total horizontal flux of ice along the glacier. This is determined from where standard symbols are defined in Table 1. The flux is scaled and is determined on a staggered grid that has points positioned halfway between adjacent thickness grid points. The algorithm takes into account any branching in the system. If both up and downstream points have no ice then flux is set to zero. Note that this calculation is not needed for the main thickness-evolution calculation and is performed solely for diagnostic reasons. This function is called from valley and the returned information is held in array flux. function calcwdth This function returns the scaled width of the glacier. This is determined using where standard symbols are defined in Table 1, and wr and Hr are (scaled) reference widths and thickness. The parameter p is typically 0.5 and is hard coded in the function, while w1 is a small number incorporated to stop width becoming zero in the vent of zero ice thickness (which is important in the ice thickness solver). This function is called from valley and the returned information is held in array wdth.

Module mass_balance (mass_balance.f90) function calcacab This function controls the calculation of the glacier’s surface mass balance. It uses unscaled variables to do this except where variables have been scalled elsewhere (e.g., surface elevation). t offer two mthods of determining ablation (day degree and simple energy balance) and has simple model for melt water retention as superimposed ice. The function is called once per year from the main valley model and has a daily time step. 1.	There are stores for the depths of snow, super-imposed ice and glacier ice along the glacier. The latter is set the zero every year and is a relative store, while the other two inherit depths from the end of the previous year. 2.	The main loops are for days in the year (leap years are determined elsewhere and dayinyr is corrected for them) and points along the glacier. Mass balance is determined at end point on the transect (glacier or not). 3.	The loop proceeds by determining surface air temperatures using a lapse rate and the daily mean temperature at the met. station (or equivalent model-based data or assumed elevation). 4.	A similar procedure is used to estimate daily precipitation totals along the glacier. Note that this is only done if precipitation actually occurred on the day in question. 5.	An estimation of the amount of precipitation falling as snow is then made based on diurnal air temperatures. 6.	Total potential melt rates are then determined for the day using either day-degree or a simple energy-balance model. In the former case, snow is initially assumed but a correction for ice is made within the surface mass balance subroutine. 7.	The evolution of the snow, superimposed ice and glacier ice along the transect is then determined using the potential melt totals, as well as daily rainfall and total precipitation. 8.	After the main loops, we tidy up by remembering the end of year depths of snow and super-imposed ice and sorting out the mass-balance season information required in the cost function. function massbalseasons This function … function rainorsnw This function determines whether precipitation falls as rain or snow (it returns amount of rainfall) using air temperature. If it is called with the flag not equal to 1, a simple comparison between daily mean temperature and a prescribed rain-snow transition temperature is made: if the daily mean is above the threshold then all precipitation falls as rain, otherwise none. If the function is called with flag set to 1, it estimates the rainfall by assuming a cosine for the diurnal variation of temperature about its mean with prescribed range ( from mean to peak NOT peak to peak) which can be rearranged to give time of day  (in radians) at which the threshold  is equaled . The proportion of the day for which temperatures exceed the threshold is therefore. If we assume that there is an equal probability of the precipitation falling at any time during the day then we simply need to multiply by the daily precipitation total to get the amount of rainfall. function finddegdays This function finds the number of positive day degrees during a day using air temperature. If it is called with the flag not equal to 1, the number of day degrees is simply the daily mean temperature if its is above zero otherwise nothing. If the function is called with flag set to 1, it estimates the number of positive day degrees by assuming a cosine for the diurnal variation of temperature about its mean with prescribed range ( from mean to peak NOT peak to peak) which can be rearranged to give time of day  (in radians) at which the temperature equals zero . We now need to integrate  from the this time to midday  and scale from radians into fractions of a day function lapsecalc This function simply applies the prescribed lapse rate to what ever variable is given. This is usually done for air temperature (daily means but not amplitudes) and precipitation. In the latter case, there is a guard in the calling routine that avoids creating precipitation if there was none in the base met. data. The lapse rate is applied relative to the prescribed elevation of the met. data and everything is done in scaled units. function surfacemodel This function takes the estimated daily precipitation (total), rainfall and meltwater depths and evolves the accumulated snow, super-imposed ice and glacier ice stores. We call firn the combined depths of snow and super-imposed ice. The logic of the process is as follows. 1.	The depth of snow is increased by snowfall (total precipitation minus rainfall). 2.	The depth of super-imposed ice is increased by rainfall (assumed to refreeze). 3.	Use the total potential melt to melt snow. If there is snow left then set melt to zero, otherwise reduce it by amount of snow melted. Any melted snow is assumed to refreeze and become super-imposed ice. 4.	Estimate the depth of super-imposed ice that would result in the firn reaching its capacity. Here firn is assumed to be the sum of the snow (s) and super-imposed ice (i) depths. We assume that only a fixed proportion (w or wmax) of the firn can be super-imposed ice and estimate this depth as 5.	Any super-imposed ice above this capacity is assumed to have run off – or more accurately the melt water that would have formed super-imposed ice is rejected before it gets a chance to freeze. 6.	If any melt potential remains then proceed to melt super-imposed ice (reducing potential and increasing runoff accordingly). If the melt potential exceeds the amount of super-imposed ice, remove all of and amend runoff and potential melt figures accordingly. Note that in the case of the degree day model, this requires a re-determination of the appropriate degree-day factor from that of snow to ice. 7.	If any melt potential remains then proceed to melt glacier ice ice (reducing potential and increasing runoff accordingly). Module energy_balance (energy_balance.f90) subroutine initialstart_ebm Sets up a number of parameters that are used in the energy balance calculation of surface melt. Points to note include: scaling of time from second in day to radians. subroutine initial4day_ebm Calculate energy-budget parameters that vary daily. In this case, this is the solar declination which is then used later on with the latitude  to calculate the solar zenith (z) and azimuth where  is the julian day expressed in radians, and

the primes indicates that these are parameters used in the final calculation of zenith and azimuths. subroutine nexttimestep_ebm This is the main solver for the energy-balance model and steps both the surface temperature (T) and the accumulated melt forward in time. The equation being solved is

where  is the surface’s aspect and   its slope (in radians);   is the fraction of the day expressed in radians and relative to midday; A, B and C are free parameters;  is the co-albedo of the surface; d is the depth of the thermally-active layer,  its density and c its specific heat capacity (we currently assume snow throughout); the 2-m air temperature (T2m) is based on the daily mean and amplitude value supplied; and temperatures are in K.  Appropriate sets are taken to ensure that the sun does not sun when it is below the horizon.

We use an implicit time-marching scheme

In these subroutines, time through the day is in radians. If the new temperature is above the melt point then we estimate an amount of melt by converting energy with active layer into an equivalent melt depth. We use the trapezium rule to do this. There are two cases. The first is where the preceeding temperature is at the melt point also; this is easy. The second in when the preceeding temperature is below the melt point, in which case we need to estimate the fraction of the time step during which temperature was above the melt point (using linear interpolation).