geco-bern/rsofun

Month-of-year dependent logic

Closed this issue · 6 comments

soiltemp computes the average temperature in the past month. Since months have different numbers of days (let alone leap years), ndaymonth is used. But there is no reason why the soil temperature would care whether it is February with 28 days, or March with 31 days. A mean over the last 30 days could be used instead, using a fixed length rolling window, simplifying greatly the code. doy and moy arguments could then also be removed.

The reason why the implementation is an issue is because I am removing doy and moy from the biomeE driver. Without these, I cannot call soiltemp as it is today to generate soil temperatures from air temperature. I am therefore asking permission to re-implement it using a fixed size rolling window instead.

I think it is reasonable to change it to a 30-day rolling window.
E.g. on Jan 31 it uses the average from Jan 01 to 30 (or 02 to 31).
E.g. on Feb 15 it uses the average from Jan 16 to Feb 14 (or +1).

Was the current implementation already doing a rolling window? Or did it use for all days in January the values from Jan 01 to 31? Make sure to initialize correctly in the first year.

Note that the vector ndaymonth will still be needed to make the daily loops in both biosphere_biomee_model.mod.f90 and biosphere_pmodel.mod.f90 (all occurrences here).

Yes it does some kind of rolling widows but using the specific lengths of each month, which I find a bit odd (and overcomplicated). Regarding ndaymonth, I know, I am attacking it in #231 ;)

This is legacy from LPX which dealt with months explicitly. Of course, one could find a different solution that does it with a rolling window or - as we have it in other places - use dampen_variability() with a corresponding time scale of about 30 days.

The explicit reference to month is not used anywhere else than in soiltemp. Yet, there is a loop in biosphere_annual() over months (and days within months).

    !----------------------------------------------------------------
    ! LOOP THROUGH MONTHS
    !----------------------------------------------------------------
    doy=0
    monthloop: do moy=1,nmonth

      !----------------------------------------------------------------
      ! LOOP THROUGH DAYS
      !----------------------------------------------------------------
      dayloop: do dm=1,ndaymonth(moy)
        doy=doy+1

The vector ndaymonth(:) is for a non-leap year. Again, this could be changed to get rid of months. But I recommend not to for the following reason: The forcing data frame is daily. If ever we will use rsofun for multi-millennia simulations, this will become excessively large. In that case, it would be nice if we maintain certain structures to deal with monthly forcing (and generate daily from monthly during run-time). Therefore, let's not drop 'months'. But in soiltemp, if you can easily find a neater way of doing it without the monthly averages, go ahead.

Anyways, this should not have high priority since the current implementation works and the changed implementation would, if all goes well, give very similar results as the current.

This is related to #231

I closed and re-opened this issue because I think it's a valid point to make the forcing time step automatically determine the model time step and because BiomeE does this (see code above). Note however, that there are additional quirks that need to be done:

  • Provide the number of rows in the forcing array as an argument to Fortran. In sofun_r.f90:
integer(kind=c_int), intent(in) :: nt
...
real(kind=c_double), dimension(nt,13), intent(in) :: forcing
...

In run_biomee_f_bysite.R:

n = as.integer(nrow(forcing)), # n here is for hourly (forcing is hourly), add n for daily and annual outputs

I added a parameter steps_per_day in param_siml to be provided by the user.