LCOV - code coverage report
Current view: top level - utils - coords_1d.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 40 51 78.4 %
Date: 2025-03-13 18:42:46 Functions: 5 8 62.5 %

          Line data    Source code
       1             : module coords_1d
       2             : 
       3             : ! This module defines the Coords1D type, which is intended to to cache
       4             : ! commonly used information derived from a collection of sets of 1-D
       5             : ! coordinates.
       6             : 
       7             : use shr_kind_mod, only: r8 => shr_kind_r8
       8             : 
       9             : implicit none
      10             : private
      11             : save
      12             : 
      13             : public :: Coords1D
      14             : 
      15             : type :: Coords1D
      16             :    ! Number of sets of coordinates in the object.
      17             :    integer :: n = 0
      18             :    ! Number of coordinates in each set.
      19             :    integer :: d = 0
      20             : 
      21             :    ! All fields below will be allocated with first dimension "n".
      22             :    ! The second dimension is d+1 for ifc, d for mid, del, and rdel, and
      23             :    ! d-1 for dst and rdst.
      24             : 
      25             :    ! Cell interface coordinates.
      26             :    real(r8), allocatable :: ifc(:,:)
      27             :    ! Coordinates at cell mid-points.
      28             :    real(r8), allocatable :: mid(:,:)
      29             :    ! Width of cells.
      30             :    real(r8), allocatable :: del(:,:)
      31             :    ! Distance between cell midpoints.
      32             :    real(r8), allocatable :: dst(:,:)
      33             :    ! Reciprocals: 1/del and 1/dst.
      34             :    real(r8), allocatable :: rdel(:,:)
      35             :    real(r8), allocatable :: rdst(:,:)
      36             :  contains
      37             :    procedure :: section
      38             :    procedure :: finalize
      39             : end type Coords1D
      40             : 
      41             : interface Coords1D
      42             :    module procedure new_Coords1D_from_fields
      43             :    module procedure new_Coords1D_from_int
      44             : end interface
      45             : 
      46             : contains
      47             : 
      48             : ! Constructor to create an object from existing data.
      49           0 : function new_Coords1D_from_fields(ifc, mid, del, dst, &
      50           0 :      rdel, rdst) result(coords)
      51             :   real(r8), USE_CONTIGUOUS intent(in) :: ifc(:,:)
      52             :   real(r8), USE_CONTIGUOUS intent(in) :: mid(:,:)
      53             :   real(r8), USE_CONTIGUOUS intent(in) :: del(:,:)
      54             :   real(r8), USE_CONTIGUOUS intent(in) :: dst(:,:)
      55             :   real(r8), USE_CONTIGUOUS intent(in) :: rdel(:,:)
      56             :   real(r8), USE_CONTIGUOUS intent(in) :: rdst(:,:)
      57             :   type(Coords1D) :: coords
      58             : 
      59           0 :   coords = allocate_coords(size(ifc, 1), size(ifc, 2) - 1)
      60             : 
      61           0 :   coords%ifc = ifc
      62           0 :   coords%mid = mid
      63           0 :   coords%del = del
      64           0 :   coords%dst = dst
      65           0 :   coords%rdel = rdel
      66           0 :   coords%rdst = rdst
      67             : 
      68           0 : end function new_Coords1D_from_fields
      69             : 
      70             : ! Constructor if you only have interface coordinates; derives all the other
      71             : ! fields.
      72      352944 : function new_Coords1D_from_int(ifc) result(coords)
      73             :   real(r8), USE_CONTIGUOUS intent(in) :: ifc(:,:)
      74             :   type(Coords1D) :: coords
      75             : 
      76      176472 :   coords = allocate_coords(size(ifc, 1), size(ifc, 2) - 1)
      77             : 
      78   277340112 :   coords%ifc = ifc
      79   274393440 :   coords%mid = 0.5_r8 * (ifc(:,:coords%d)+ifc(:,2:))
      80   274393440 :   coords%del = coords%ifc(:,2:) - coords%ifc(:,:coords%d)
      81   271446768 :   coords%dst = coords%mid(:,2:) - coords%mid(:,:coords%d-1)
      82   274393440 :   coords%rdel = 1._r8/coords%del
      83   271446768 :   coords%rdst = 1._r8/coords%dst
      84             : 
      85      176472 : end function new_Coords1D_from_int
      86             : 
      87             : ! Create a new Coords1D object that is a subsection of some other object,
      88             : ! e.g. if you want only the first m coordinates, use d_bnds=[1, m].
      89             : !
      90             : ! Originally this used pointers, but it was found to actually be cheaper
      91             : ! in practice just to make a copy, especially since pointers can impede
      92             : ! optimization.
      93      705888 : function section(self, n_bnds, d_bnds)
      94             :   class(Coords1D), intent(in) :: self
      95             :   integer, intent(in) :: n_bnds(2), d_bnds(2)
      96             :   type(Coords1D) :: section
      97             : 
      98      705888 :   section = allocate_coords(n_bnds(2)-n_bnds(1)+1, d_bnds(2)-d_bnds(1)+1)
      99             : 
     100  1045327116 :   section%ifc = self%ifc(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2)+1)
     101  1033540428 :   section%mid = self%mid(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2))
     102  1033540428 :   section%del = self%del(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2))
     103  1021753740 :   section%dst = self%dst(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2)-1)
     104  1033540428 :   section%rdel = self%rdel(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2))
     105  1021753740 :   section%rdst = self%rdst(n_bnds(1):n_bnds(2),d_bnds(1):d_bnds(2)-1)
     106             : 
     107      705888 : end function section
     108             : 
     109             : ! Quick utility to get allocate each array with the correct size.
     110      882360 : function allocate_coords(n, d) result(coords)
     111             :   integer, intent(in) :: n, d
     112             :   type(Coords1D) :: coords
     113             : 
     114      882360 :   coords%n = n
     115      882360 :   coords%d = d
     116             : 
     117     3529440 :   allocate(coords%ifc(coords%n,coords%d+1))
     118     3529440 :   allocate(coords%mid(coords%n,coords%d))
     119     2647080 :   allocate(coords%del(coords%n,coords%d))
     120     3529440 :   allocate(coords%dst(coords%n,coords%d-1))
     121     2647080 :   allocate(coords%rdel(coords%n,coords%d))
     122     2647080 :   allocate(coords%rdst(coords%n,coords%d-1))
     123             : 
     124      882360 : end function allocate_coords
     125             : 
     126             : ! Deallocate and reset to initial state.
     127      176472 : subroutine finalize(self)
     128             :   class(Coords1D), intent(inout) :: self
     129             : 
     130      176472 :   self%n = 0
     131      176472 :   self%d = 0
     132             : 
     133      176472 :   call guarded_deallocate(self%ifc)
     134      176472 :   call guarded_deallocate(self%mid)
     135      176472 :   call guarded_deallocate(self%del)
     136      176472 :   call guarded_deallocate(self%dst)
     137      176472 :   call guarded_deallocate(self%rdel)
     138      176472 :   call guarded_deallocate(self%rdst)
     139             : 
     140             : contains
     141             : 
     142     1058832 :   subroutine guarded_deallocate(array)
     143             :     real(r8), allocatable :: array(:,:)
     144             : 
     145     1058832 :     if (allocated(array)) deallocate(array)
     146             : 
     147     1058832 :   end subroutine guarded_deallocate
     148             : 
     149             : end subroutine finalize
     150             : 
     151           0 : end module coords_1d

Generated by: LCOV version 1.14