Repository navigation
Add sample Chemistry diagnostics - #751
James Bruten (james-bruten-mo) merged 15 commits into
Conversation
…de stash infrastructure in UKCA*. Involves making use of API developed for diagnostics
… status arrays populated once via UKCA API call and needed throughout run
iboutle
left a comment
There was a problem hiding this comment.
Hi Mohit,
I have a slight concern about this, which I'm not sure if can be improved upon...
If I understand correctly, n_ukca_diags_3d is going to be the maximum possible number of diagnostics requestable from UKCA. Currently this is 2, but potentially it could be 100s. The first loop in initialise_ukca_diagnostics has to look over all options to check whether they are requested or not, but subsequent loops (in output_ukca_diagnostics and aerosol_ukca_kernel shouldn't need to perform this entire looping, they should be able to immediately jump to a smaller list of the diagnostics which are actually requested on the current timestep, i.e. a variable n_ukca_diags_req, set by the initial call in initialise_ukca_diagnostics.
The point here is that diagnostic requests are a sparse problem - the vast majority of model runs will not request any ukca diagnostics on the vast majority of timesteps. However, currently we are allocating space for, and checking, all possible diagnostics on every timestep. The do loops probably aren't that much of a problem, but the allocation of diag_fullht_real to be this enormous size every time ukca is called is a worry - the memory overhead of this will be unnecessarily huge.
Is it possible to change this?
A couple of more minor comments:
- is the setting of
diag_fullht_real=0inaerosol_ukca_kernelreally necessary - again, this is a costly action on a large array that will happen every timestep regardless of whether it's required or not. It would be better to only do it where necessary, if at all. - same question for
setval_c(rxnflux_oh_ch4_trop, 0.0_r_def)etc ininitialise_ukca_diagnostics- I'm fairly sure this is not needed because every element of the array is written to inaerosol_ukca_kernel - Please ensure the diagnostic map is updated with the stashcode mapping for these new fields.
Thanks!
…s- now only requested, active fields handled. Fix bug while copying o3_column_do data from level=1 to level=0
Alan J Hewitt (alanjhewitt)
left a comment
There was a problem hiding this comment.
have a look if case default is needed in a few places and check that "DU" is the approved cf for dobson units please.
Alan J Hewitt (alanjhewitt)
left a comment
There was a problem hiding this comment.
Am happy with the code changes. I just need to see the updated trac.log
Matthew Hambley (MatthewHambley)
left a comment
There was a problem hiding this comment.
No new global variables please.
There was a problem hiding this comment.
This file should only ever be removed from. Never added to. Why are there new global variables?
There was a problem hiding this comment.
Matthew Hambley (@MatthewHambley) A masterlist of all requested diagnostics is built up once at the initialisation stage by querying XIOS, and then whittled down each timestep depending on whether the field is to be output/ sampled in that call.
The alternative will involve defining the field name arrays at two locations (initialisation and algorithm level) and querying XIOS twice on each timestep as the ordering/ indexing of the master vs active list is important.
One option not to increase the dirtylist could be to define these in um_ukca_init_mod which is already in there, although this does not address the issue of global variables itself.
iboutle
There was a problem hiding this comment.
Thinking of alternatives -could the masterlist be somehow stored in modeldb? (key_value/ linked_list?) It could then be extracted and passed in to aerosol_ukca_alg.
There was a problem hiding this comment.
I think Copilot has got me partly there using modeldb%values (but not removed all global vairables), so will continue on this and see if it actually works.
There was a problem hiding this comment.
Matthew Hambley (@MatthewHambley) , iboutle Alan J Hewitt (@alanjhewitt)
I have reworked the change to avoid global variables by trying to use modeldb%values to pass data between initialisation and algorithm levels. This does not seem to support storing of arrays (although the base key_value_collection appears to) so each component of the names array is stored separately. I can open an issue to change this when the array functionality is added in future.
Since there does not seem to be a way to pass character arrays GH_CHAR to the kernel, instead of individual fields a diagnostic super array is being used to obtain the fields from UKCA API and unpacked in the algorithm layer.
I have reused the photol_diags_kernel to extract individual fields from the multi-data field. After release, or on main after #584, this can be converted into a generic kernel routine.
Apologies for sending this back to you so close to the deadline.
There was a problem hiding this comment.
Hi Mohit,
Sorry, I'm just back from leave and catching up on this. I would probably have said to keep the global variables in this instance - as you well know, the UKCA API is designed around these global lists which are setup at initialisation, and used throughout the code. As we have no plans to change this on the UKCA side, it doesn't really seem too problematic for LFRic to accommodate it, as it does with all the other lists.
However, since you've managed to rework it, I'd be inclined to keep what you've done. I like the super array passed into the kernel, as this will avoid having to add new arguments for new diagnostics. I am a bit worried about the computational cost of all the extra work which is having to be done to avoid the global variables, e.g. the extra setup in the algorithm each timestep and copying the data back out of the super array, but we can monitor this and change if necessary.
I've a couple of minor suggestions I'll add to the relevant lines...
… modeldb%values. Also pass a multi-dimensional data array to kernel instead of individual fields as not possible to access accompanying diagnames list via module
… Correct population of multi-data array and ensure zeroth level is copied from first.
| diagnostics_fullht_real( map_wdiag(1, i) + ((m-1)*(nlayers+1)) + k ) = & | ||
| real( diag_fullht_real( i, 1, k, m ), r_def ) | ||
| end do | ||
| diagnostics_fullht_real( map_wdiag(1, i) + ((m-1)*(nlayers+1)) + 0 ) = & |
There was a problem hiding this comment.
This setting of level 0 is done twice - once here and once in photol_diags_kernel - could one or other be removed?
There was a problem hiding this comment.
Removed from kernel routine
| l_diag_requested = .false. | ||
| select case (trim(ukca_req_diagnames_fullht(n))) | ||
| case (trim(nm_rxnflux_oh_ch4_trop)) | ||
| l_diag_requested = init_diag(rxnflux_oh_ch4_trop, & |
There was a problem hiding this comment.
Now we pass the super array into the kernel, we don't actually need to allocate the diagnostic fields (rxnflux_oh_ch4_trop) here any more. We could use "diagnostic_to_be_sampled" to establish if it's requested on the current timestep, and then use init_diag to allocate the field inside output_ukca_diagnostics. That would avoid having to plumb the arrays between the initialise and output routines.
There was a problem hiding this comment.
Thanks that is a handy function to check request status! Fields now local to output_ukca_diagnostics.
… to be written, and local to output routine. Remove duplicate level=1 to level=0 copy.
| diagnames_fullht_real(:) = tmp_diagnames_fullht_real(1:n_req_ukca_diags_3d) | ||
| idiag_status_3d(:) = tmp_diag_status_3d(1:n_req_ukca_diags_3d) | ||
|
|
||
| deallocate(tmp_diag_status_3d) |
There was a problem hiding this comment.
I dont want to hold up getting this into code review. When you have time, make sure that the deallocate order is the reverse of the allocate order
Alan J Hewitt (alanjhewitt)
left a comment
There was a problem hiding this comment.
Hi Mohit,
The changes are good, thanks for all the hard work.
I dont want to hold this up to get into code review, but it would be worth going back to interfaces/physics_schemes_interface/source/support/ukca_diag_setup_mod.f90 and making sure that the deallocate order is the reverse of the allocate order.
SciTech approved.
Alan
…e variables declared in algorithm routine.
| if ( modeldb%config%namelist_exists('chemistry') ) then | ||
| chem_scheme = modeldb%config%chemistry%chem_scheme() | ||
| if ( chem_scheme == chem_scheme_strattrop ) & |
There was a problem hiding this comment.
Just a drive-by comment. If the only purpose of the chem_scheme variable is to check its value, there should be no need to extract it first. i.e. if ( modeldb$config%chemistry%chem_scheme() == chem_scheme_strattrop ).
This has been addressed
7247d7d
into
MetOffice:main


PR Summary
Sci/Tech Reviewer: Alan J Hewitt (@alanjhewitt)
Code Reviewer: James Bruten (@james-bruten-mo)
This PR adds two sample diagnostics from the UKCA Chemistry sub-model (OH + CH4 reaction flux and Total Ozone in column).
Note: These fields are already defined outside the STASH framework in UKCA and accessible via its diagnostics API (mosrs:ukca#29) so no modifications are required to ukca repo
Technical Debt The OH+CH4 diagnostic calculation temporarily uses a fixed tropopause level for masking out the stratosphere. Using active/ live tropopause level (which will be essential for some future chemistry diagnostics) will require some pipeline work between LFRic and UKCA.
Code Quality Checklist
Testing
trac.log
Test Suite Results - lfric_apps - apps3.2_sample_chem_diag/run3
Suite Information
Task Information
✅ succeeded tasks - 1210
Security Considerations
Performance Impact
AI Assistance and Attribution
GitHub Copilot via VSCode
Documentation
PSyclone Approval
Sci/Tech Review
(Please alert the code reviewer via a tag when you have approved the SR)
Code Review