subroutine Field_IcGrid2D_new( &
  & cptr, cptr_icgrid2D, name, field_rank, long_name, units &
  & ) bind(C, name='Field_IcGrid2D_new')
  
  use, intrinsic :: iso_c_binding

  use dc_types, only: &
    & TOKEN, STRING

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, Field_IcGrid2D_Init

  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM, get_glevel, get_effsize_max

  use CBinding_Utility, only: &
    & c_f_string

  implicit none

  type(c_ptr), intent(out) :: cptr
  type(c_ptr), value :: cptr_icgrid2D
  character(kind=c_char), intent(in) :: name(*)
  integer(c_int), value :: field_rank
  character(kind=c_char), intent(in) :: long_name(*)
  character(kind=c_char), intent(in) :: units(*)
  
  type(Field_IcGrid2D), pointer :: ptr
  type(IcGrid2D_FVM), pointer :: ptr_icgrid2D
  character(TOKEN) :: fname
  character(STRING) :: flong_name
  character(STRING) :: funits

  allocate(ptr)
  call c_f_pointer(cptr_icgrid2D, ptr_icgrid2D)
  
  call c_f_string(name, fname)
  call c_f_string(long_name, flong_name)
  call c_f_string(units, funits)

  call Field_IcGrid2D_Init( &
     & ptr, &
     & ptr_icgrid2D, fname, field_rank, flong_name, funits)
  
  cptr = c_loc(ptr)

end subroutine Field_IcGrid2D_new

subroutine Field_IcGrid2D_del( &
  & cptr &
  & ) bind(C, name='Field_IcGrid2D_del')

  use, intrinsic :: iso_c_binding

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, Field_IcGrid2D_Final

  implicit none
  type(c_ptr), intent(inout) :: cptr

  type(Field_IcGrid2D), pointer :: ptr

  call c_f_pointer(cptr, ptr)
  call Field_IcGrid2D_Final(ptr)
  deallocate(ptr)

  cptr = c_null_ptr

end subroutine Field_IcGrid2D_del

subroutine Field_IcGrid2D_get_Physical_Field( &
  & cptr, cptr_base &
  & ) bind(C, name='Field_IcGrid2D_get_Physical_Field')

  use, intrinsic :: iso_c_binding

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, get_Physical_Field
  use Physical_Field_Manager, only: &
    & Physical_Field

  implicit none
  type(c_ptr), value :: cptr
  type(c_ptr), intent(out) :: cptr_base

  type(Field_IcGrid2D), pointer :: ptr
  type(Physical_Field), pointer :: ptr_base

  call c_f_pointer(cptr, ptr)
  ptr_base => get_Physical_Field(ptr)

  cptr_base = c_loc(ptr_base)

end subroutine Field_IcGrid2D_get_Physical_Field

subroutine Field_IcGrid2D_get_icgrid( &
  & cptr, cptr_icgrid &
  & ) bind(C, name='Field_IcGrid2D_get_icgrid')

  use, intrinsic :: iso_c_binding

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, get_icgrid

  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM

  implicit none
  type(c_ptr), value :: cptr
  type(c_ptr), intent(inout) :: cptr_icgrid

  type(Field_IcGrid2D), pointer :: ptr
  type(IcGrid2D_FVM), pointer :: ptr_icgrid

  call c_f_pointer(cptr, ptr)
  ptr_icgrid => get_icgrid(ptr)

  cptr_icgrid = c_loc(ptr_icgrid)

end subroutine Field_IcGrid2D_get_icgrid


subroutine Field_IcGrid2D_paste_field2D_margin( &
  & cptr &
  & ) bind(C, name='Field_IcGrid2D_paste_field2d_margin')

  use, intrinsic :: iso_c_binding

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, paste_field2D_margin

  implicit none
  type(c_ptr), value :: cptr

  type(Field_IcGrid2D), pointer :: ptr

  call c_f_pointer(cptr, ptr)
  call paste_field2D_margin(ptr)

end subroutine Field_IcGrid2D_paste_field2d_margin

function Field_IcGrid2D_global_mean( &
  & cptr &
  & ) result(val) bind(C, name='Field_IcGrid2D_global_mean')

  use, intrinsic :: iso_c_binding

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D, global_mean

  use dc_types, only: &
    & DP

  implicit none
  type(c_ptr), value :: cptr
  real(DP) :: val

  type(Field_IcGrid2D), pointer :: ptr

  call c_f_pointer(cptr, ptr)
  val = global_mean(ptr)

end function Field_IcGrid2D_global_mean

subroutine Field_IcGrid2D_fill_value( &
  & cptr, val &
  & ) bind(C, name='Field_IcGrid2D_fill_value')

  use, intrinsic :: iso_c_binding

  use dc_types, only: &
    & DP

  use Field_IcGrid2D_Manager, only: &
    & Field_IcGrid2D

  implicit none
  type(c_ptr), value :: cptr
  real(DP), value :: val

  type(Field_IcGrid2D), pointer :: ptr

  call c_f_pointer(cptr, ptr)
  ptr%val(:,:,:,:) = val

end subroutine Field_IcGrid2D_fill_value
