Update master with the developments that went into the neXtSIM v2 paper#662
Update master with the developments that went into the neXtSIM v2 paper#662tdcwilliams merged 83 commits intomasterfrom
Conversation
This addresses issue #634, by adding I (the penetrating short-wave radiation) as an output to IABulkFluxes and using this in the Winton and Semtner models.
The value of I_0 is quite uncertain it seems, but let's use the Winton (2000) value for now (30%).
I put the arguments in the wrong place in the IABulkFlux function, compared to the call. This is fixed. I also added t1 and t2 as output variables for the moorings.
Issue634 pen sw
The initial code written by me and Dani. It compiles, but it needs an option to turn on the meltpond scheme and mooring outputs.
It had a misspelling in its name - and more importantly, the permeability was incorrectly calculated.
It's called thermo.use_meltponds
We can now output "meltpond_volume", "meltpond_lid_volume", and "meltpond_fraction". All are averaged over the entire grid cell.
There were lots of minor problems with the initial implementation. Most of them are now fixed. The model runs and produces not unreasonable looking meltponds. The main remaining problems are - For some reason the meltpond volume recovers almost immediately after flushing - I get very deep meltponds in the oldest and most ridged ice. These can be deeper than the ice is thick and they never go away, because they don't flush and the lid becomes more than a meter thick and grows very slowly.
The isPermiable function now takes all temperatures into account and selects the Assur or Notz formulation, depending on temperature.
Some code clean-up of isPermeable. No functionality change or bug fixing.
A less convoluted and more obvious way of growing, melting, or forming a lid on top of a melt pond.
There's a risk that the ponds become unrealistically deep. The can even become deeper than the ice is thick. This patch prevents this, and (arbitrarily) limits the depth to 1/3 of the ice thickness by flushing excess water via the runoff variable. The limit can be thought out more carefully.
I was missing the melting term for the lid. This is now fixed.
In this version, the meltponds don't affect the freshwater balance (EMP). I also added a code to remove meltponds if the lid gets too thick (more then 30 cms).
I simply added a constant (tunable) albedo for the fraction of ponds without a lid (or a lid thinner than 5 cm - arbitrary number). This has a substantial effect in initial tests, but much more testing is needed.
This adds an alb_scheme == 4 option. It simply assumes constant snow, ice, and meltpond albedos. Something like alb_ice = 0.54, alb_sn = 0.83, and alb_pnd = 0.3 makes sense.
…T in alb scheme 4 + fixes
This adds a check on the MLD in checkFieldsFast, which throws an std::runtime_error if MLD is outside [0, 10 km]. The lower bound is quite strict (could also be a few mm) and the upper bound is just there because the code requires an upper bound. In reality we just want to check the lower bound.
…T in alb scheme 4 + fixes
We're still in the CICE spirit, but this includes some important fixes.
This way, we don't have to calculate the specific humidity too often. It also fits better within the code.
A correct calculation of the Obukov length this time! Some minor additional adjustments.
I multiplied the flux with cp + cpv. Not sure why, it should just be cp.
But the default is to do it. This is really only useful for debugging!
The new drag was not given correctly to the dynamics because I forgot to multiply with wind speed and atmospheric density(!)
This moves the calculation of some of the more complex constants out of the element loop to save time. Also adds the limiting length scale as an option, to put a sensible limit on the Obukov length (Richard says 100 m is good).
I missed a factor two when transcribing the equations. Fixing this actually improves the results!
I managed to introduce a bug in the ocean drag calculation in a misguided attempt for minor optimisation. Remember Knuth!
I went through the constants yet again, and everything looks fine. Also changed the default Linv limit to something that makes more sense (and what I've used for my tests the whole time).
It should be the Mellor and Kantha one, as this is implied in the paper we're writing.
Change the default value of melt_type
Change licence to MIT
tdcwilliams
left a comment
There was a problem hiding this comment.
some minor clarifications to add + typos
| longName = "Meltpond fraction"; | ||
| stdName = "meltpond_fraction"; | ||
| Units = "1"; | ||
| cell_methods = "area: mean"; |
There was a problem hiding this comment.
is this area fraction, and is it fraction of the total grid area or just of the ice-covered area? Perhaps change the long name to "Meltpond area fraction"
There was a problem hiding this comment.
ps if it is the fraction of ice-covered area use cell_methods = "area: mean where ice";
- same for the other new melt-pond and drag variables
There was a problem hiding this comment.
after reading the rest of the code the drags should be "area: mean where ice" but the melt pond variables can stay as "area: mean"
| ("thermo.force_neutral_atmosphere", po::value<bool>()->default_value(false), | ||
| "Don't modify the neutral (default) atmospheric drag coefficient to take atmospheric stability into account.") | ||
| ("thermo.limiting_lengthscale", po::value<double>()->default_value( 1. ), | ||
| "A limit for the Obukov lenght (m).") |
There was a problem hiding this comment.
| "A limit for the Obukov lenght (m).") | |
| "A limit for the Obukov length (m).") |
| M_age_det[i] += dt*M_conc[i]; | ||
| double w_age = old_conc <= 0? 0.: std::min(old_conc/M_conc[i], 1.); | ||
| // no ice => w_age = 0 => age = dt | ||
| // melting => old_conc > M_conc => w_age = 1 |
There was a problem hiding this comment.
| // melting => old_conc > M_conc => w_age = 1 | |
| // melting => old_conc > M_conc => w_age = 1 => age += dt |
| double del_vi_thick = M_thick[i] - old_vol; | ||
| w_age = old_vol <= 0 ? 0. : std::min(old_vol/M_thick[i], 1.); | ||
| // no ice => w_age = 0 => age = dt | ||
| // melting => old_vol > M_thick => w_age = 1 |
There was a problem hiding this comment.
| // melting => old_vol > M_thick => w_age = 1 | |
| // melting => old_vol > M_thick => w_age = 1 => => age += dt |
| psih = 2.*std::log(0.5*(1.+x*x)); | ||
| } | ||
|
|
||
| // 4. The drag coefficients: ( \frac{k}{\ln{z/z_0} - \Pshi} )^2 |
There was a problem hiding this comment.
| // 4. The drag coefficients: ( \frac{k}{\ln{z/z_0} - \Pshi} )^2 | |
| // 4. The drag coefficients: ( \frac{k}{\ln{z/z_0} - \Psi} )^2 |
| // double const roff = (0.85 - 0.7*M_conc[cpt]) ; Holland et al. 2012 | ||
| M_pond_volume[cpt] += (1-roff)*availableWater*M_conc[cpt]; | ||
|
|
||
| // Flush the pond if there's not enough ice. Skip everyting if there's no pond. |
There was a problem hiding this comment.
| // Flush the pond if there's not enough ice. Skip everyting if there's no pond. | |
| // Flush the pond if there's not enough ice. Skip everything if there's no pond. |
| D_pond_fraction[cpt] = std::sqrt(M_pond_volume[cpt]/dep2frac); | ||
|
|
||
| // Make sure there is no pond on snow | ||
| D_pond_fraction[cpt] = std::min(D_pond_fraction[cpt], 1.-hs/(hs+0.2)); |
There was a problem hiding this comment.
if hs = 0, D_pond_fraction = 1?
There was a problem hiding this comment.
No, but it can only happen that D_pond_fraction = 1 if hs = 0.
| M_lid_volume[cpt] += delLidVolume; | ||
| M_pond_volume[cpt] -= delLidVolume; | ||
|
|
||
| // Remove lid if the pond is frozen solid or if it's too thick |
There was a problem hiding this comment.
should M_thick and/or M_h_young increase if pond freezes solid?
There was a problem hiding this comment.
No, the pond volume is just an inactive tracer. It doesn't hold any mass.
|
Because of branch protection (both master and develop are protected), it's best to merge this as it is and then fix everything in a separate PR. |
Only changes to comments and metadata for output files.
Address comments from Tim on PR #662
Merge pull request #662 from nansencenter/develop
This PR contains the most recent developments that made it into the neXtSIM v2 paper. This includes