Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamics control logic and implementation #619

Open
apcraig opened this issue Jul 19, 2021 · 1 comment
Open

Dynamics control logic and implementation #619

apcraig opened this issue Jul 19, 2021 · 1 comment

Comments

@apcraig
Copy link
Contributor

apcraig commented Jul 19, 2021

The are a number of questions about the dynamics control logic and implementation including what features work together and plans. We may need/want to refactor portions of the implementation and namelist control to make this easier and cleaner to use. In particular,

  • are revised_evp and the 1d solver compatible
  • will there be a 1d implementation for eap
  • are the vp namelist names reasonable
  • are there areas where code reuse can be improved
  • simplify/clarify namelist options and interactions and improve documentation

See also #568, #279, #575

@apcraig
Copy link
Contributor Author

apcraig commented Nov 22, 2021

As we move forward, I think an important thing to think about is how we're calling various subroutines in terms of memory. Some calls are by gridcell, some by block, and some by all-blocks on a task. And when by gridcell or block, some block info may be passed in but not all.

I wonder if it makes sense to try to unify/aggregate some of the calls (between B and CD, between different dynamics options (i.e. evp, eap, vp) and between different dynamics subroutines) to call on blocks whenever possible and to pass in iblk and then only significant in/out arrays. If iblk is passed in, then we should be able to access all the info about the block (size, etc) and we should also be able to access info from full arrays that are NOT passed into the block subroutine. It might allow us to move away from passing in all arrays when there is little benefit to doing so. For instance, if a current subroutine looks like

call something (nx_block, ny_block, ilo, ihi, jlo, jhi, uvel(:,:,iblk), vvel(:,:,iblk), tarea(:,:,iblk), uarea(:,:,iblk))
integer, intent(in) :: nx_block, ny_block, ilo, ihi, jlo, jhi
real, intent(in) :: tarea(:,:), uarea(:,:)
real, intent(inout) :: uvel(:,:),vvel(:,:)

maybe this could be refactored as

call something (iblk, uvel(:,:,iblock), vvel(:,:,iblock))
use ice_blocks, only: nx_block, ny_block
integer, intent(in) :: iblk
real, intent(inout) :: uvel(:,:),vvel(:,:)
! local
real,... :: tarea_loc(:,:), uarea_loc(:,:)

  this_block = get_block(blocks_ice(iblk),iblk)
  ilo = this_block%ilo
  ihi = this_block%ihi
  jlo = tihs_block%jlo
  jhi = tihs_block%jhi
  tarea_loc(:,:) = tarea(:,:,iblk)
  uarea_loc(:,:) = uarea(:,:,iblk)

This should make it much easier to extend subroutine implementations without always having to fuss about the arguments in subroutine calls in multiple places in the dynamics. It would also (hopefully) bring some greater unification to the calling/memory strategy in the dynamics (which is pretty reasonable already). Subroutine reuse may require many arrays be passed in. But we could also leverage kdyn, ktransport, grid_system within subroutines as well if we want to differentiate implementations (using if statements). There may be some performance issues to consider, but I can't imagine setting a handful of scalars for block info in subroutines is expensive. And I also suspect accessing memory via use may be faster than passing it thru a subroutine. We don't even have to copy into local memory, we can just use tarea(i,j,iblk) directly in the implementation if iblk is passed in.

This was referenced Dec 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants