diff --git a/src/core_ocean/analysis_members/Registry_eddy_product_variables.xml b/src/core_ocean/analysis_members/Registry_eddy_product_variables.xml index 48be8b032c..696466c101 100644 --- a/src/core_ocean/analysis_members/Registry_eddy_product_variables.xml +++ b/src/core_ocean/analysis_members/Registry_eddy_product_variables.xml @@ -39,12 +39,28 @@ - - + + + + + + - - + + + + diff --git a/src/core_ocean/analysis_members/mpas_ocn_eddy_product_variables.F b/src/core_ocean/analysis_members/mpas_ocn_eddy_product_variables.F index a7f7da1666..35f735ebf7 100644 --- a/src/core_ocean/analysis_members/mpas_ocn_eddy_product_variables.F +++ b/src/core_ocean/analysis_members/mpas_ocn_eddy_product_variables.F @@ -44,6 +44,7 @@ module ocn_eddy_product_variables use mpas_stream_manager use ocn_constants + use ocn_config use ocn_diagnostics_routines implicit none @@ -177,15 +178,17 @@ subroutine ocn_compute_eddy_product_variables(domain, timeLevel, err)!{{{ type (mpas_pool_type), pointer :: tracersPool type (mpas_pool_type), pointer :: diagnosticsPool - integer, pointer :: nVertLevels, nCellsSolve - integer :: iTracer, k, iCell + integer, pointer :: nEdges, nVertLevels, nCellsSolve + integer :: iTracer, k, iCell, iEdge, cell1, cell2 integer, pointer :: index_temperature, index_salinity - integer, dimension(:), pointer :: maxLevelCell + integer, dimension(:), pointer :: maxLevelEdgeTop, maxLevelCell + integer, dimension(:,:), pointer :: cellsOnEdge real (kind=RKIND), dimension(:), pointer :: ssh, SSHSquared real (kind=RKIND), dimension(:,:), pointer :: velocityZonal, velocityMeridional, GMBolusVelocityZonal, GMBolusVelocityMeridional, & velocityZonalSquared, velocityMeridionalSquared, velocityZonalTimesTemperature, velocityMeridionalTimesTemperature, & - velocityZonalTimesTemperature_GM, velocityMeridionalTimesTemperature_GM + velocityZonalTimesTemperature_GM, velocityMeridionalTimesTemperature_GM, normalVelocity, normalVelocitySquared, & + normalVelocityTimesTemperature, normalGMBolusVelocity, normalGMBolusVelocityTimesTemperature, normalGMBolusVelocitySquared real (kind=RKIND), dimension(:,:,:), pointer :: activeTracers err = 0 @@ -202,37 +205,107 @@ subroutine ocn_compute_eddy_product_variables(domain, timeLevel, err)!{{{ call mpas_pool_get_dimension(block % dimensions, 'nVertLevels', nVertLevels) call mpas_pool_get_dimension(block % dimensions, 'nCellsSolve', nCellsSolve) + call mpas_pool_get_dimension(block % dimensions, 'nEdges', nEdges) + call mpas_pool_get_array(statePool, 'normalVelocity', normalVelocity, 1) call mpas_pool_get_array(tracersPool, 'activeTracers', activeTracers, 1) call mpas_pool_get_dimension(tracersPool, 'index_temperature', index_temperature) call mpas_pool_get_array(statePool, 'ssh',ssh, 1) call mpas_pool_get_array(diagnosticsPool, 'velocityZonal', velocityZonal) call mpas_pool_get_array(diagnosticsPool, 'velocityMeridional', velocityMeridional) - call mpas_pool_get_array(diagnosticsPool, 'GMBolusVelocityZonal',GMBolusVelocityZonal) - call mpas_pool_get_array(diagnosticsPool, 'GMBolusVelocityMeridional', GMBolusVelocityMeridional) call mpas_pool_get_array(meshPool, 'maxLevelCell', maxLevelCell) + call mpas_pool_get_array(meshPool, 'cellsOnEdge', cellsOnEdge) + call mpas_pool_get_array(meshPool, 'maxLevelEdgeTop', maxLevelEdgeTop) + call mpas_pool_get_array(eddyProductVariablesAMPool, 'SSHSquared', SSHSquared) call mpas_pool_get_array(eddyProductVariablesAMPool, 'velocityZonalSquared', velocityZonalSquared) call mpas_pool_get_array(eddyProductVariablesAMPool, 'velocityMeridionalSquared', velocityMeridionalSquared) call mpas_pool_get_array(eddyProductVariablesAMPool, 'velocityZonalTimesTemperature', velocityZonalTimesTemperature) call mpas_pool_get_array(eddyProductVariablesAMPool, 'velocityMeridionalTimesTemperature', & velocityMeridionalTimesTemperature) - call mpas_pool_get_array(eddyProductVariablesAMPool,'velocityZonalTimesTemperature_GM', velocityZonalTimesTemperature_GM) - call mpas_pool_get_array(eddyProductVariablesAMPool,'velocityMeridionalTimesTemperature_GM', & - velocityMeridionalTimesTemperature_GM) - - do iCell = 1,nCellsSolve - SSHSquared(iCell) = ssh(iCell)**2 - do k = 1, maxLevelCell(iCell) - velocityZonalSquared(k,iCell) = velocityZonal(k,iCell)**2 - velocityMeridionalSquared(k,iCell) = velocityMeridional(k,iCell)**2 - velocityZonalTimesTemperature(k,iCell) = velocityZonal(k,iCell)*activeTracers(index_temperature,k,iCell) - velocityMeridionalTimesTemperature(k,iCell) = velocityMeridional(k,iCell)*activeTracers(index_temperature,k,iCell) - velocityZonalTimesTemperature_GM(k,iCell) = GMBolusVelocityZonal(k,iCell)*activeTracers(index_temperature,k,iCell) - velocityMeridionalTimesTemperature_GM(k,iCell) = GMBolusVelocityMeridional(k,iCell)*activeTracers(index_temperature,k,iCell) - end do - end do + call mpas_pool_get_array(eddyProductVariablesAMPool,'normalVelocityTimesTemperature', normalVelocityTimesTemperature) + call mpas_pool_get_array(eddyProductVariablesAMPool,'normalVelocitySquared', normalVelocitySquared) + + ! if GM is active, include the GM variables. + ! I repeated the block of code here for better performance, rather than + ! split the GM and non-GM variables into separate loops. + if (config_use_GM) then + call mpas_pool_get_array(diagnosticsPool, 'normalGMBolusVelocity', normalGMBolusVelocity) + call mpas_pool_get_array(diagnosticsPool, 'GMBolusVelocityZonal',GMBolusVelocityZonal) + call mpas_pool_get_array(diagnosticsPool, 'GMBolusVelocityMeridional', GMBolusVelocityMeridional) + call mpas_pool_get_array(eddyProductVariablesAMPool,'velocityZonalTimesTemperature_GM', velocityZonalTimesTemperature_GM) + call mpas_pool_get_array(eddyProductVariablesAMPool,'velocityMeridionalTimesTemperature_GM', & + velocityMeridionalTimesTemperature_GM) + call mpas_pool_get_array(eddyProductVariablesAMPool,'normalGMBolusVelocityTimesTemperature', normalGMBolusVelocityTimesTemperature) + call mpas_pool_get_array(eddyProductVariablesAMPool,'normalGMBolusVelocitySquared', normalGMBolusVelocitySquared) + + !$omp parallel + !$omp do schedule(runtime) private(cell1, cell2, k) + do iEdge = 1,nEdges + cell1 = cellsOnEdge(1,iEdge) + cell2 = cellsOnEdge(2,iEdge) + + do k = 1, maxLevelEdgeTop(iEdge) + normalVelocityTimesTemperature(k,iEdge) = 0.5_RKIND*(activeTracers(index_temperature,k,cell1) + & + activeTracers(index_temperature,k,cell2)) * normalVelocity(k,iEdge) + normalVelocitySquared(k,iEdge) = normalVelocity(k,iEdge)**2 + normalGMBolusVelocityTimesTemperature(k,iEdge) = 0.5_RKIND*(activeTracers(index_temperature,k,cell1) + & + activeTracers(index_temperature,k,cell2)) * normalGMBolusVelocity(k,iEdge) + normalGMBolusVelocitySquared(k,iEdge) = normalGMBolusVelocity(k,iEdge)**2 + end do + end do + !$omp end do + !$omp end parallel + + !$omp parallel + !$omp do schedule(runtime) private(k) + do iCell = 1,nCellsSolve + SSHSquared(iCell) = ssh(iCell)**2 + do k = 1, maxLevelCell(iCell) + velocityZonalSquared(k,iCell) = velocityZonal(k,iCell)**2 + velocityMeridionalSquared(k,iCell) = velocityMeridional(k,iCell)**2 + velocityZonalTimesTemperature(k,iCell) = velocityZonal(k,iCell)*activeTracers(index_temperature,k,iCell) + velocityMeridionalTimesTemperature(k,iCell) = velocityMeridional(k,iCell)*activeTracers(index_temperature,k,iCell) + velocityZonalTimesTemperature_GM(k,iCell) = GMBolusVelocityZonal(k,iCell)*activeTracers(index_temperature,k,iCell) + velocityMeridionalTimesTemperature_GM(k,iCell) = GMBolusVelocityMeridional(k,iCell)*activeTracers(index_temperature,k,iCell) + end do + end do + !$omp end do + !$omp end parallel + + ! if GM is not active, do exactly the same computation as above but + ! without the GM variables. + else + !$omp parallel + !$omp do schedule(runtime) private(cell1, cell2, k) + do iEdge = 1,nEdges + cell1 = cellsOnEdge(1,iEdge) + cell2 = cellsOnEdge(2,iEdge) + + do k = 1, maxLevelEdgeTop(iEdge) + normalVelocityTimesTemperature(k,iEdge) = 0.5_RKIND*(activeTracers(index_temperature,k,cell1) + & + activeTracers(index_temperature,k,cell2)) * normalVelocity(k,iEdge) + normalVelocitySquared(k,iEdge) = normalVelocity(k,iEdge)**2 + end do + end do + !$omp end do + !$omp end parallel + + !$omp parallel + !$omp do schedule(runtime) private(k) + do iCell = 1,nCellsSolve + SSHSquared(iCell) = ssh(iCell)**2 + do k = 1, maxLevelCell(iCell) + velocityZonalSquared(k,iCell) = velocityZonal(k,iCell)**2 + velocityMeridionalSquared(k,iCell) = velocityMeridional(k,iCell)**2 + velocityZonalTimesTemperature(k,iCell) = velocityZonal(k,iCell)*activeTracers(index_temperature,k,iCell) + velocityMeridionalTimesTemperature(k,iCell) = velocityMeridional(k,iCell)*activeTracers(index_temperature,k,iCell) + end do + end do + !$omp end do + !$omp end parallel + endif block => block % next end do