#include "MAPL_Generic.h" module mapl3g_VariableSpec use mapl3g_AspectCollection use mapl3g_GeomAspect use mapl3g_VerticalGridAspect use mapl3g_UnitsAspect use mapl3g_TypekindAspect use mapl3g_UngriddedDimsAspect use mapl3g_AttributesAspect use mapl3g_FrequencyAspect use mapl3g_UngriddedDims use mapl3g_VerticalDimSpec use mapl3g_HorizontalDimsSpec use mapl3g_VirtualConnectionPt use mapl3g_ActualConnectionPt use mapl3g_VerticalGrid use mapl_KeywordEnforcerMod use mapl3g_ActualPtVector use mapl_ErrorHandling use mapl3g_StateRegistry use mapl3g_StateItem use mapl3g_EsmfRegridder, only: EsmfRegridderParam use mapl3g_FieldDictionary use esmf use gFTL2_StringVector use nuopc implicit none private public :: VariableSpec ! This type provides components that might be needed for _any_ ! state item. This is largely to support legacy interfaces, but it ! also allows us to defer interpretation until after user ! setservices() have run. type VariableSpec type(AspectCollection) :: aspects ! Mandatory values: type(ESMF_StateIntent_Flag) :: state_intent character(:), allocatable :: short_name ! Metadata character(:), allocatable :: standard_name type(ESMF_StateItem_Flag) :: itemtype = MAPL_STATEITEM_FIELD type(StringVector), allocatable :: service_items character(:), allocatable :: substate real, allocatable :: default_value type(StringVector) :: attributes integer, allocatable :: bracket_size ! Geometry type(VerticalDimSpec) :: vertical_dim_spec = VERTICAL_DIM_UNKNOWN ! none, center, edge type(HorizontalDimsSpec) :: horizontal_dims_spec = HORIZONTAL_DIMS_GEOM ! none, geom type(StringVector) :: dependencies contains procedure :: make_virtualPt procedure :: make_dependencies end type VariableSpec interface VariableSpec module procedure :: new_VariableSpec end interface VariableSpec contains function new_VariableSpec( & state_intent, short_name, unusable, standard_name, geom, & units, substate, itemtype, typekind, vertical_dim_spec, ungridded_dims, default_value, & service_items, attributes, & bracket_size, & dependencies, regrid_param, horizontal_dims_spec, & accumulation_type) result(var_spec) type(VariableSpec) :: var_spec type(ESMF_StateIntent_Flag), intent(in) :: state_intent character(*), intent(in) :: short_name ! Optional args: class(KeywordEnforcer), optional, intent(in) :: unusable character(*), optional, intent(in) :: standard_name type(ESMF_Geom), optional, intent(in) :: geom type(ESMF_StateItem_Flag), optional, intent(in) :: itemtype type(StringVector), optional :: service_items character(*), optional, intent(in) :: units character(*), optional, intent(in) :: substate type(ESMF_TypeKind_Flag), optional, intent(in) :: typekind type(VerticalDimSpec), optional, intent(in) :: vertical_dim_spec type(UngriddedDims), optional, intent(in) :: ungridded_dims real, optional, intent(in) :: default_value type(StringVector), optional, intent(in) :: attributes integer, optional, intent(in) :: bracket_size type(StringVector), optional, intent(in) :: dependencies type(EsmfRegridderParam), optional, intent(in) :: regrid_param type(HorizontalDimsSpec), optional, intent(in) :: horizontal_dims_spec character(len=*), optional, intent(in) :: accumulation_type type(ESMF_RegridMethod_Flag), allocatable :: regrid_method type(EsmfRegridderParam) :: regrid_param_ integer :: status var_spec%state_intent = state_intent var_spec%short_name = short_name #if defined(_SET_OPTIONAL) # undef _SET_OPTIONAL #endif #define _SET_OPTIONAL(attr) if (present(attr)) var_spec%attr = attr call var_spec%aspects%set_units_aspect(UnitsAspect(units)) regrid_param_ = get_regrid_param(regrid_param, standard_name) call var_spec%aspects%set_vertical_grid_aspect(VerticalGridAspect( & vertical_dim_spec=vertical_dim_spec, & geom=geom)) call var_spec%aspects%set_geom_aspect(GeomAspect(geom, regrid_param_, horizontal_dims_spec)) call var_spec%aspects%set_ungridded_dims_aspect(UngriddedDimsAspect(ungridded_dims)) call var_spec%aspects%set_attributes_aspect(AttributesAspect(attributes)) call var_spec%aspects%set_typekind_aspect(TypekindAspect(typekind)) call var_spec%aspects%set_frequency_aspect(FrequencyAspect(accumulation_type=accumulation_type)) _SET_OPTIONAL(standard_name) _SET_OPTIONAL(itemtype) _SET_OPTIONAL(substate) _SET_OPTIONAL(service_items) _SET_OPTIONAL(default_value) _SET_OPTIONAL(vertical_dim_spec) _SET_OPTIONAL(attributes) _SET_OPTIONAL(bracket_size) _SET_OPTIONAL(dependencies) _UNUSED_DUMMY(unusable) end function new_VariableSpec function make_virtualPt(this) result(v_pt) type(VirtualConnectionPt) :: v_pt class(VariableSpec), intent(in) :: this v_pt = VirtualConnectionPt(this%state_intent, this%short_name) if (allocated(this%substate)) then v_pt = v_pt%add_comp_name(this%substate) end if end function make_virtualPt function make_dependencies(this, rc) result(dependencies) type(ActualPtVector) :: dependencies class(VariableSpec), intent(in) :: this integer, optional, intent(out) :: rc integer :: status integer :: i type(ActualConnectionPt) :: a_pt dependencies = ActualPtVector() do i = 1, this%dependencies%size() a_pt = ActualConnectionPt(VirtualConnectionPt(ESMF_STATEINTENT_EXPORT, this%dependencies%of(i))) call dependencies%push_back(a_pt) end do _RETURN(_SUCCESS) end function make_dependencies function get_regrid_param(requested_param, standard_name) result(regrid_param) type(EsmfRegridderParam) :: regrid_param type(EsmfRegridderParam), optional, intent(in) :: requested_param character(*), optional, intent(in) :: standard_name type(ESMF_RegridMethod_Flag) :: regrid_method integer :: status if (present(requested_param)) then regrid_param = requested_param return end if ! if (NUOPC_FieldDictionaryHasEntry(this%standard_name, rc=status)) then ! call NUOPC_FieldDictionaryGetEntry(this%standard_name, regrid_method, rc=status) ! if (status==ESMF_SUCCESS) then ! this%regrid_param = EsmfRegridderParam(regridmethod=regrid_method) ! return ! end if ! end if regrid_param = EsmfRegridderParam() ! last resort - use default regrid method regrid_method = get_regrid_method_from_field_dict_(standard_name, rc=status) if (status==ESMF_SUCCESS) then regrid_param = EsmfRegridderParam(regridmethod=regrid_method) return end if end function get_regrid_param function get_regrid_method_from_field_dict_(standard_name, rc) result(regrid_method) type(ESMF_RegridMethod_Flag) :: regrid_method character(*), optional, intent(in) :: standard_name integer, optional, intent(out) :: rc character(len=*), parameter :: field_dictionary_file = "field_dictionary.yml" type(FieldDictionary) :: field_dict logical :: file_exists integer :: status inquire(file=trim(field_dictionary_file), exist=file_exists) if (.not. file_exists) then rc = _FAILURE return end if field_dict = FieldDictionary(filename=field_dictionary_file, _RC) if (.not. present(standard_name)) then rc = _FAILURE return end if regrid_method = field_dict%get_regrid_method(standard_name, _RC) _RETURN(_SUCCESS) end function get_regrid_method_from_field_dict_ end module mapl3g_VariableSpec