Skip to content

File VirtualColumn_Mod.F90

File List > core > VirtualColumn_Mod.F90

Go to the documentation of this file

module virtualcolumn_mod
   use precision_mod, only: fp
   use error_mod, only: cc_success, cc_failure

   implicit none
   private

   public :: virtualcolumntype, virtualmettype

#include "virtualmet_type.inc"

   type :: virtualcolumntype
      ! Meteorological data (pointers managed by VirtualMetType)
      type(VirtualMetType) :: met

      ! Chemical and emission data (still use arrays for modification)
      real(fp), allocatable :: chem_data(:,:)
      real(fp), allocatable :: emis_data(:,:)

      ! Grid position and metadata
      integer :: grid_i = 0
      integer :: grid_j = 0
      integer :: column_id = 0
      real(fp) :: lat = 0.0_fp                               
      real(fp) :: lon = 0.0_fp                               
      real(fp) :: area = 0.0_fp                              

      ! Dimensions
      integer :: nlev = 0
      integer :: nspec_chem = 0
      integer :: nspec_emis = 0

      ! Status
      logical :: is_valid = .false.                          

   contains
      procedure :: init => virtual_column_init
      procedure :: get_met => virtual_column_get_met
      procedure :: get_chem_field => virtual_column_get_chem_field
      procedure :: get_emis_field => virtual_column_get_emis_field
      procedure :: set_chem_field => virtual_column_set_chem_field
      procedure :: set_emis_field => virtual_column_set_emis_field
      procedure :: get_position => virtual_column_get_position
      procedure :: get_metadata => virtual_column_get_metadata
      procedure :: get_dimensions => virtual_column_get_dimensions
      procedure :: is_initialized => virtual_column_is_initialized
      procedure :: cleanup => virtual_column_cleanup
   end type virtualcolumntype

contains

   !=========================================================================
   ! VirtualMetType Implementation
   !=========================================================================

   subroutine virtual_met_cleanup(this)
      class(VirtualMetType), intent(inout) :: this

      !print *, '[DEBUG] Entering virtual_met_cleanup'
      if (associated(this%T)) then
         !   print *, '[DEBUG] Cleaning up T, associated before nullify'
      else
         !   print *, '[DEBUG] T not associated'
      endif

      ! Generated cleanup code from MetState field definitions
#include "virtualmet_cleanup.inc"

      !print *, '[DEBUG] Exiting virtual_met_cleanup'
   end subroutine virtual_met_cleanup

   !=========================================================================
   ! VirtualColumnType Implementation
   !=========================================================================

   subroutine virtual_column_init(this, nlev, nspec_chem, nspec_emis, grid_i, grid_j, column_id, lat, lon, area, rc)
      class(VirtualColumnType), intent(inout) :: this
      integer, intent(in) :: nlev, nspec_chem, nspec_emis
      integer, intent(in) :: grid_i, grid_j, column_id
      real(fp), intent(in) :: lat, lon, area
      integer, intent(out) :: rc

      rc = cc_success

      ! Store dimensions
      this%nlev = nlev
      this%nspec_chem = nspec_chem
      this%nspec_emis = nspec_emis

      ! Store position/metadata
      this%grid_i = grid_i
      this%grid_j = grid_j
      this%column_id = column_id
      this%lat = lat
      this%lon = lon
      this%area = area

      ! Allocate meteorological field arrays for testing
      if (nlev > 0) then
         if (.not. associated(this%met%T)) then
            allocate(this%met%T(nlev))
            this%met%T = 288.15_fp  ! Initialize with default temperature value
         endif
      endif

      ! Allocate chemical and emission data arrays
      if (nlev > 0 .and. nspec_chem > 0) then
         allocate(this%chem_data(nlev, nspec_chem), stat=rc)
         if (rc /= 0) then
            rc = cc_failure
            return
         endif
         this%chem_data = 0.0_fp
      endif

      if (nlev > 0 .and. nspec_emis > 0) then
         allocate(this%emis_data(nlev, nspec_emis), stat=rc)
         if (rc /= 0) then
            rc = cc_failure
            return
         endif
         this%emis_data = 0.0_fp
      endif

      this%is_valid = .true.
      rc = cc_success
   end subroutine virtual_column_init

   function virtual_column_get_met(this) result(met_ptr)
      class(VirtualColumnType), intent(in), target :: this
      type(VirtualMetType), pointer :: met_ptr

      met_ptr => this%met
   end function virtual_column_get_met

   function virtual_column_get_chem_field(this, ispec, k) result(value)
      class(VirtualColumnType), intent(in) :: this
      integer, intent(in) :: ispec, k
      real(fp) :: value

      if (allocated(this%chem_data) .and. &
         k >= 1 .and. k <= this%nlev .and. &
         ispec >= 1 .and. ispec <= this%nspec_chem) then
         value = this%chem_data(k, ispec)
      else
         value = 0.0_fp
      endif
   end function virtual_column_get_chem_field

   function virtual_column_get_emis_field(this, ispec, k) result(value)
      class(VirtualColumnType), intent(in) :: this
      integer, intent(in) :: ispec, k
      real(fp) :: value

      if (allocated(this%emis_data) .and. &
         k >= 1 .and. k <= this%nlev .and. &
         ispec >= 1 .and. ispec <= this%nspec_emis) then
         value = this%emis_data(k, ispec)
      else
         value = 0.0_fp
      endif
   end function virtual_column_get_emis_field

   subroutine virtual_column_set_chem_field(this, k, ispec, value)
      class(VirtualColumnType), intent(inout) :: this
      integer, intent(in) :: k, ispec
      real(fp), intent(in) :: value

      if (allocated(this%chem_data) .and. &
         k >= 1 .and. k <= this%nlev .and. &
         ispec >= 1 .and. ispec <= this%nspec_chem) then
         this%chem_data(k, ispec) = value
      endif
   end subroutine virtual_column_set_chem_field

   subroutine virtual_column_set_emis_field(this, k, ispec, value)
      class(VirtualColumnType), intent(inout) :: this
      integer, intent(in) :: k, ispec
      real(fp), intent(in) :: value

      if (allocated(this%emis_data) .and. &
         k >= 1 .and. k <= this%nlev .and. &
         ispec >= 1 .and. ispec <= this%nspec_emis) then
         this%emis_data(k, ispec) = value
      endif
   end subroutine virtual_column_set_emis_field

   subroutine virtual_column_get_position(this, grid_i, grid_j)
      class(VirtualColumnType), intent(in) :: this
      integer, intent(out) :: grid_i, grid_j

      grid_i = this%grid_i
      grid_j = this%grid_j
   end subroutine virtual_column_get_position

   subroutine virtual_column_get_metadata(this, lat, lon, area)
      class(VirtualColumnType), intent(in) :: this
      real(fp), intent(out) :: lat, lon, area

      lat = this%lat
      lon = this%lon
      area = this%area
   end subroutine virtual_column_get_metadata

   subroutine virtual_column_get_dimensions(this, nlev, nspec_chem, nspec_emis)
      class(VirtualColumnType), intent(in) :: this
      integer, intent(out) :: nlev, nspec_chem, nspec_emis

      nlev = this%nlev
      nspec_chem = this%nspec_chem
      nspec_emis = this%nspec_emis
   end subroutine virtual_column_get_dimensions

   function virtual_column_is_initialized(this) result(initialized)
      class(VirtualColumnType), intent(in) :: this
      logical :: initialized

      initialized = this%is_valid
   end function virtual_column_is_initialized

   subroutine virtual_column_cleanup(this)
      class(VirtualColumnType), intent(inout) :: this

      !print *, '[DEBUG] Entering virtual_column_cleanup'

      ! Clean up meteorological pointers
      call this%met%cleanup()

      ! Deallocate chemical and emission data
      if (allocated(this%chem_data)) then
         !print *, '[DEBUG] Deallocating chem_data'
         deallocate(this%chem_data)
      endif
      if (allocated(this%emis_data)) then
         !print *, '[DEBUG] Deallocating emis_data'
         deallocate(this%emis_data)
      endif

      this%nlev = 0
      this%nspec_chem = 0
      this%nspec_emis = 0
      this%is_valid = .false.

      !print *, '[DEBUG] Exiting virtual_column_cleanup'
   end subroutine virtual_column_cleanup

end module virtualcolumn_mod