Interpolate cell-centered variable at nodes.
The interpolation is linear and based on the volume-weights.
Only internal cells are considered, ghost ones are trimmed.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(block_object), | intent(in) | :: | self | Block. |
||
| real(kind=R8P), | intent(in) | :: | var_cell(1-self%signature%gc(1):,1-self%signature%gc(3):,1-self%signature%gc(5):) | Cell-centered variable. |
||
| real(kind=R8P), | intent(out) | :: | var_node(0-self%signature%gc(1):,0-self%signature%gc(3):,0-self%signature%gc(5):) | Node-centered variable. |
pure subroutine interpolate_at_nodes(self, var_cell, var_node)
!< Interpolate cell-centered variable at nodes.
!<
!< @note The interpolation is linear and based on the volume-weights.
!<
!< @note Only internal cells are considered, ghost ones are trimmed.
class(block_object), intent(in) :: self !< Block.
real(R8P), intent(in) :: var_cell(1-self%signature%gc(1):, &
1-self%signature%gc(3):, &
1-self%signature%gc(5):) !< Cell-centered variable.
real(R8P), intent(out) :: var_node(0-self%signature%gc(1):, &
0-self%signature%gc(3):, &
0-self%signature%gc(5):) !< Node-centered variable.
real(R8P), allocatable :: var_cell_framed(:,:,:) !< Cell-centered var framed.
real(R8P), allocatable :: volume_framed(:,:,:) !< Volume framed.
integer(I4P) :: i !< Counter.
integer(I4P) :: j !< Counter.
integer(I4P) :: k !< Counter.
associate(gc=>self%signature%gc, ni=>self%signature%ni, nj=>self%signature%nj, nk=>self%signature%nk)
! building framed variable and volume
allocate(var_cell_framed(0:ni+1, 0:nj+1, 0:nk+1)) ; var_cell_framed = 0._R8P
var_cell_framed(1:ni, 1:nj, 1:nk) = var_cell(1:ni, 1:nj, 1:nk)
allocate(volume_framed(0:ni+1, 0:nj+1, 0:nk+1)) ; volume_framed = 0._R8P
volume_framed(1:ni, 1:nj, 1:nk) = self%cell(1:ni, 1:nj, 1:nk)%volume
! check frames
if (gc(1)>0) then
var_cell_framed(0, 1:nj, 1:nk) = var_cell( 0, 1:nj, 1:nk)
volume_framed( 0, 1:nj, 1:nk) = self%cell(0, 1:nj, 1:nk)%volume
endif
if (gc(2)>0) then
var_cell_framed(ni+1, 1:nj, 1:nk) = var_cell( ni+1, 1:nj, 1:nk)
volume_framed( ni+1, 1:nj, 1:nk) = self%cell(ni+1, 1:nj, 1:nk)%volume
endif
if (gc(3)>0) then
var_cell_framed(1:ni, 0, 1:nk) = var_cell( 1:ni, 0, 1:nk)
volume_framed( 1:ni, 0, 1:nk) = self%cell(1:ni, 0, 1:nk)%volume
endif
if (gc(4)>0) then
var_cell_framed(ni, 1:nj+1, 1:nk) = var_cell( ni, 1:nj+1, 1:nk)
volume_framed( ni, 1:nj+1, 1:nk) = self%cell(ni, 1:nj+1, 1:nk)%volume
endif
if (gc(5)>0) then
var_cell_framed(1:ni, 1:nj, 0) = var_cell( 1:ni, 1:nj, 0)
volume_framed( 1:ni, 1:nj, 0) = self%cell(1:ni, 1:nj, 0)%volume
endif
if (gc(6)>0) then
var_cell_framed(ni, 1:nj, 1:nk+1) = var_cell( ni, 1:nj, 1:nk+1)
volume_framed( ni, 1:nj, 1:nk+1) = self%cell(ni, 1:nj, 1:nk+1)%volume
endif
! interpolate on nodes
do k=0, nk
do j=0, nj
do i=0, ni
var_node(i, j, k) = (var_cell_framed(i+1, j+1, k+1) * volume_framed(i+1, j+1, k+1) &
+ var_cell_framed(i , j+1, k+1) * volume_framed(i , j+1, k+1) &
+ var_cell_framed(i+1, j , k+1) * volume_framed(i+1, j , k+1) &
+ var_cell_framed(i , j , k+1) * volume_framed(i , j , k+1) &
+ var_cell_framed(i+1, j+1, k ) * volume_framed(i+1, j+1, k ) &
+ var_cell_framed(i , j+1, k ) * volume_framed(i , j+1, k ) &
+ var_cell_framed(i+1, j , k ) * volume_framed(i+1, j , k ) &
+ var_cell_framed(i , j , k ) * volume_framed(i , j , k ))&
/ sum(volume_framed(i:i+1, j:j+1, k:k+1))
enddo
enddo
enddo
endassociate
endsubroutine interpolate_at_nodes