Feature request: MOM6 Time Handling
Use case
Run MOM6-DART experiments using correctly specified model time
Is your feature request related to a problem?
Yes. Currently, DART assigns the reference/base time for MOM6 to Year 1. In Kate's experiments for instance MOM6 starts on Jan 1st, 1958 based on the available forcing. So, the time variable that is being read from the restart file should be days since 01-01-1958. Note that MOM6 doesn't use an actual calendar. Simulations start from simply 1.
Describe your preferred solution
I discussed this with Ian. After checking, it seems like it won't be possible to add in additional time attributes (because of limitations within the CESM framework). However, Ian and Kate know the reference date of their problem, i.e., 01-01-1958. So, my proposed solution is to add two namelist parameters to &model_nml: [1] reference_date and [2] calendar_type. These can be defined by the user depending on their specific applications. In Kate's case, these can be set to: reference_date = 01-01-1958 and calendar_type = NOLEAP. Internally, DART can parse the calendar's type in static_init_model and the reference date in read_model_time.
Describe any alternatives you have considered
We tried enforcing the starting time using init_time_days and init_time_seconds but that did't seem to solve the problem. The filter wanted to advance the model, probably because the observation sequence files had observations beyond the assimilation window (but not sure).
I think it is worth taking a closer look at this.
I have a MOM6 run in /glade/derecho/scratch/hkershaw/g.e22.G_JRA.TL319_t232.001.multi.3/run
If we take a look at the Time variable in this file: ncdump -v Time g.e22.G_JRA.TL319_t232.001.multi.3.mom6.r.2018-05-06-00000._0001.nc
which is a run with CALENDAR=GREGORIAN, RUN_STARTDATE=2018-05-01 + 5 days run:
double Time(Time) ;
Time:long_name = "Time" ;
Time:units = "days" ;
Time:cartesian_axis = "T" ;
...
data:
Time = 736819 ;
}
The time is in days (no reference date given in the file)
using gregorian_time.c with a base year of 1
diff --git a/assimilation_code/modules/utilities/gregorian_time.c b/assimilation_code/modules/utilities/gregorian_time.c
index ee6a72f03..e8fccb87d 100644
--- a/assimilation_code/modules/utilities/gregorian_time.c
+++ b/assimilation_code/modules/utilities/gregorian_time.c
@@ -20,7 +20,7 @@
#include <stdlib.h>
/* the start of gregorian numbered days */
-#define BASE_YEAR 1601
+#define BASE_YEAR 1
gcc gregorian_time.c
./a.out 736819 0
gives 2018/05/06 which matches the time of the restart file:
736819 0 == 2018/05/06 00:00:00
using a base year of 1958 gives 736819 0 == 3975/05/06 00:00:00
We tried enforcing the starting time using init_time_days and init_time_seconds but that did't seem to solve the problem. The filter wanted to advance the model, probably because the observation sequence files had observations beyond the assimilation window (but not sure).
I think this could be because if you are using WOD times (dart times) as the observation sequence times, which will have leap years but your model time does not have leap years. This can be a big difference, e.g. example from issue #494
If you don't have leap years switched on you end up with inconstant time information like this: Restart filename has the time 2015-02-11-00000. The Time variable is Time = 735151, which is 2013/10/11
=> dart will want to advance the model to 2015.
I am not sure how MOM6 behaves with NOLEAP ( I think it is still year 1, but there a probably a bunch of ways to configure MOM6 that I have no idea about) If you switch the base year to 1958, you would still see the mismatch in obs seq with gregorian dart_time vs no_leap.
There reference date suggested in the issue: 01-01-1958 is only valid for Kate's experiments. This will be different depending on the application. It's no surprise it didn't match for your restart file.
To clarify, because MOM6 doesn't provide a reference date as part of the time attributes, we need to read it in another way. The suggestion is to ask the user to add it in as a namelist parameter. This reference time is often tied to the forcing data used while running MOM6.
@mgharamti can you send along the path to Kate's restarts on Cheyenne. I'd like to wrap my head around why the perfect_model run was ok (?) but the filter run isnt.
Sounds good. This is one of the runs:
/glade/derecho/scratch/kboden/g.e30_b06.G_JRA.TL319_t232_zstar_N75.2025.SKEB_DA.rr.7_3
It seems that she has adjusted the obs_seq files so filter is running using init_time_days and ini_time_seconds. Though, I would like to still address the restart time within read_model_time
An update:
The time handling issue seems to affect other programs that read the state for instance fill_inflation_restart. The code errors out when it computes a negative time. Perhaps, we need to implement a namelist switch to ignore time computation for certain programs. Or just give it a dummy positive number if it finds a negative time.
this solves the problem in the short term, but it does leave a way for users to make runs with bad times without knowing it. perhaps the code in the mom6 model_mod:read_model_time needs some namelist options to handle alternative ways of that model doing time? like an option to set the reference time for a run (assuming some mom6 times are in days counting up), and another option in case the time is really gregorian, and maybe another option to set 0 as the reference time if the time is in days since year 0? that way the read_model_time() routine can return a real gregorian time in all cases which seems safer in the long run.