Salt-restoring flux from file in MOM5 and MOM6

Has anyone run ACCESS-OM2 or MOM6 with salt restoring fluxes from a file, not calculated adaptively online? For context we want to use salt fluxes saved from control experiments and apply these same salt fluxes in meltwater experiments. We want to do this for both MOM5 and MOM6.

1 Like

Hi Adele,

I have done that with ACCESS-OM2-1deg for the FAFMIP runs (https://doi.org/10.1175/JCLI-D-19-1016.1). I basically saved 6-hourly the ā€œsfc_salt_flux_restoreā€ term, and modified it to be a ā€œsalt_sfc_correction.ncā€ file so to be applied back into MOM5. I have the scripts I used back in the day but will need to refresh my head around the details.

2 Likes

That would be awesome if you can dig up details of how it was done @fabiobdias, we were struggling even to find the input option to read in salt fluxes from a file.

Also, does anyone know what temporal frequency is needed? Would it be really terrible if we just use the monthly salt flux output we have and apply every timestep it’s applied? It should still end up with the same net restoring flux right? But the exact details of where its applied when would be slightly different.

And, does anyone know how to do it in MOM6? @angus-g ?

In MOM6 it depends a little bit on what driver you’re using. With FMS for MOM6-SIS2 coupling, you can turn on RESTORE_SALINITY. Then there’s ADJUST_NET_SRESTORE_TO_ZERO if you want 0 net, ADJUST_NET_SRESTORE_BY_SCALING if you don’t want to move the zero contour.

The actual forcing is controlled by FLUXCONST_SALT giving a piston velocity, and the data is loaded from the variable SALT_RESTORE_VARIABLE in SALT_RESTORE_FILE. I think this uses the FMS time interpolation so you can give it whatever temporal frequency you want, and repeat years if time is specified as a modulo variable…

Similar to what I think @fabiobdias is describing for MOM5, all MOM6 drivers support applying adjustments to the surface salt flux via the data_table:

  • set ALLOW_FLUX_ADJUSTMENTS = True
  • specify the file from which the flux adjustments should be read in the data_table (in kg salt m-2 s-1). Something like:
    # gridname | fieldname_code | fieldname_file            | file_name.          | ongrid | factor
    # ----------------------------------------------------------------------------------------------
    "OCN"      , "sflx_adj"     , "<variable_name_in_file>" , "<path/to/file.nc>" , "none" , 1.0
    

The flux adjustment will get added to the salinity restoring fluxes if RESTORE_SALINITY = True, so I think you’d want to set RESTORE_SALINITY = False. Similar to what @angus-g mentions for SALT_RESTORE_FILE, the data_table uses the FMS time interpolation so you can give it whatever temporal frequency you want, and repeat years if time is specified as a modulo variable.

It’s probably worth looking at the salt_flux_added diagnostic to make sure things are behaving as expected.

I’ve tested different temporal frequency @adele-morrison. In the end, to be able to keep the model stable for the period design by the FAFMIP protocol (80 years), I needed to use 6-hourly fluxes. But in my case I wanted to deactivate the SSS restoring. Not sure you’ll need such high frequency in your case. I remember that I tried daily and monthly before going to finer temporal scale and it didn’t work (e.g. global metrics show clearly large drifts - global temp, salt temp, AMOC).

Similar to what @dougiesquire said, in MOM5 we applied a surface flux adjustment. Roughly these are the steps:

1 - create salt_sfc_correction.nc file:
a) extract sfc_salt_flux_restore from the output file (I used NCO - happy to share the bash script that do this and the steps below)
b) convert salt flux to equivalent freshwater flux (FWF = salt_flux*1000/SSS); the surface correction is applied in freshwater flux (basically pme = pme + pme_correct in ocean_core/ocean_sbc.f90; where pme_correct is the ā€˜pme’ field it reads from the salt_sfc_correction.nc file, more on this below)
c) rename variable name to ā€˜pme’; there’s also a couple attributes to adjust like:
> standard_name = ā€œwater_flux_into_sea_waterā€
> long_name = ā€œWater Flux into Sea Waterā€
> units = ā€œkg m-2 s-1ā€
and a few others - I remember that @Aidan helped on this (just to make it as MOM5 wants - the bash script I mentioned has all the details).

2 - Now we turn on the flux_correction on the input.nml (section ocean_sbc_nml), and it will look for the ā€˜salt_sfc_correction.nc’ file in the input directory:

  • do_flux_correction = .true.
  • salt_correction_scale = 1.0

For the perturbation experiment I had, e.g. FAF-WATER (freshwater anomalies from CMIP5 MMM), we just sum the sfc_salt_flux_restore converted to FWF with the FAFMIP PME anomalies (so these will be combined in the variable ā€˜pme’ in the ā€˜salt_sfc_correction.nc’). In my case I also deactivate the salt restoring.

Awesome, thanks everyone, I think this should give us a great starting point to give it a go from. Will let you know when we run into problems! :grinning_face:

Hi everyone!

The MOM5 way described by fabio (it was great thank you for it!) takes in the restoring as a freshwater flux. If I wanted to apply it as a salt flux, I understand that I could set use_waterflux = .false. in the input.nml file.

I have 2 questions on that regard:

  1. Am I breaking something else?
  2. What metadata should I be setting for the salt flux? I.e., what variable name, what long_name, etc.

Thank you again for your help!

Hi @JuliaN. You’re probably already across this, but note that use_waterflux = .false. is not recommended in MOM5, e.g. see the comment here.

ACCESS-OM2 configurations use use_waterflux = .true. with salt_restore_as_salt_flux=.true., meaning that surface freshwater mass fluxes (liquid and frozen precip, evap, ice melt/formation/discharge) are applied as water fluxes, but salinity restoring is applied as a salt flux.

However, it does not appear to be possible to apply the salt flux correction as a salt flux without setting use_waterflux = .false.. This means freshwater mass fluxes will be applied as a virtual salt flux.

So, to try and answer your questions:

ā€œBreakingā€: I’m not sure. Changing: yes. Freshwater mass fluxes will be applied as virtual salt fluxes so will not alter sea level or the concentration of other tracers. Also, the use_waterflux = .false. option is implemented ā€œat a rudimentary levelā€ according to the source code, so you might want to check it’s doing everything you want before using it.

I think @fabiobdias has answered this above:

Is there something in these instructions that isn’t working for you?

Ah, thanks @dougiesquire. That sounds like using use_waterflux = .false. is a bad idea!

The problem with Fabio’s method we found is that it requires high frequency knowledge of SSS to compute the equivalent freshwater fluxes to apply. @JuliaN tried calculating it with daily output of SSS and salt restoring fluxes and there was still a large mismatch when implemented compared with the original restoring fluxes.

Hmmmm. @fabiobdias used 6-hourly fluxes and presumably the same for SSS? Can you increase the frequency or are you trying to use data from an already-completed run?

Interestingly, with use_waterflux = .false. MOM5 converts the freshwater mass fluxes into virtual salt fluxes using a constant reference salinity…

I think it would be straightforward to add a salt_correct_as_salt_flux option

Hi Dougie and others,

Sorry for the late reply! I was running into problems with Fabio’s method which I’ll try to explain below. For my testing of the method I have:

  1. Ran 1 month of the RYF simulation and saved (i) daily and (ii) monthly restoring fluxes (the diagnostic called sfc_salt_flux_restore). I then converted them to a freshwater flux (*1000/SSS where SSS is surface salinity given in g/kg), and changed the metadata as per the instructions.
  2. Changed in the input.nml file do_flux_correction=.true. and salt_correction_scale=1.0. Re-run that same month in control. My expectation here (if the restoring is being prescribed correctly) is to obtain the same sfc_salt_flux_restore as in the unprescribed simulation above. This was not the case. I tested prescribing daily and monthly values to see if the frequency is the problem, but it is not. The figure below shows what I’m saying for the Antarctic shelf, where I have integrated sfc_salt_flux_restore. The blue line is the 1 month run in point 1. above, and then the orange and green lines are the runs where I’m prescribing either monthly or daily fluxes. You can see they do not match.
  3. Purely by accident, I re-ran the same month prescribing the original sfc_salt_flux_restore as a salt flux, without converting it freshwater. This time it worked as expected:

So I have gone ahead and kept running my simulations giving it a salt flux. From what I can gather, all is working well, I am getting the restoring I expected, and no other flux looks weird. This is very confusing, because on one hand, the model expects to be fed a file called salt_sfc_correction.nc. But on the other, the variable there needs to be called pme and ā€œwater flux into the oceanā€. In the model’s tecnical report it says the ā€œrestoring is applied via a salt fluxā€, and if I am reading the code correctly here it also seems to expect a salt flux.

Anyway, long story short, it seems like giving it salt fluxes does what I’d expect it to do when prescribing restoring. Freshwater fluxes have not done what I wanted. I’m so sorry if this is unclear, happy to clarify anything required, and again, thanks everyone!!

It sounds like you haven’t turned off the salinity restoring in this case. So you are now calculating restoring and applying your correction. To turn off the salinity restoring, set salt_restore_tscale to <= 0.0 (or just remove it from input.nml; the default is -30.0).

So just to be clear, in addition the steps here I need to remove salt_restore_tscale?

1 Like

yes! Sorry I forgot to mention this as I thought it was implied.

you should be able to compare your imposed salt correction flux with what the model is getting by looking at the following diagnostics (assuming you’ll have a zero sfc_salt_flux_restore when you turn off SSS restoring):

id_pme_correct = register_diag_field('ocean_model','pme_correct', Grd%tracer_axes(1:2),&
       Time%model_time, 'precip-evap from flux correction (>0 enters ocean)',            &
       '(kg/m^3)*(m/sec)', missing_value=missing_value,range=(/-1e6,1e6/))   

id_total_ocean_pme_correct = register_diag_field('ocean_model','total_ocean_pme_correct',&
       Time%model_time, 'total precip-evap from flux correction (>0 enters ocean)',        &
       '(kg/sec)/1e15', missing_value=missing_value,range=(/-1e6,1e6/))

Thanks @fabiobdias ! Hopefully my last question: is this conversion here supposed to have a minus sign as well? FWF = -salt_flux*1000/SSS? In the sense that freshwater in is equivalent to salt out?

Yes, that’s right you need the minus sign to convert from salt to freshwater flux…

2 Likes

Hi @dougiesquire !! I have just started trying to do the same for MOM6 (after successfully doing it for ACCESS). The steps I’ve followed are:

  1. Set RESTORE_SALINITY = False
  2. Added ALLOW_FLUX_ADJUSTMENTS = True
  3. Prepared my salt flux and added the specs to the data_table
  4. Ran 2 months to check (after I verified that the flux file is being found correctly by looking at the INPUT paths wit payu setup).

When I compare the salt_flux_added diagnostic to the file I’ve prepared, they are not the same. I think I would have expected them to be. Can you see anything I’ve missed in my steps above?

I appreciate the help so very much. Thanks.