Skip to content

Commit

Permalink
add object-oriented AgSysCropType
Browse files Browse the repository at this point in the history
(1) separate parameters into different crop types
(2) add crop-specific behaviors into different crop types
(3) change arguments to phenology routines
  • Loading branch information
pengbinpeluo committed Nov 14, 2019
1 parent 80ca522 commit c127f40
Show file tree
Hide file tree
Showing 13 changed files with 676 additions and 476 deletions.
11 changes: 3 additions & 8 deletions src/agsys/ctsm_interface/AgSysInterface.F90
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ module AgSysInterface
! index the params by crop type or cultivar: a given call for a single patch only
! has access to the parameters for the appropriate crop type and cultivar for that
! patch.)
type(agsys_crop_cultivar_params_type) :: crop_cultivar_params(crop_type_maxval)

! Information about the phases for each crop type
type(agsys_phases_type) :: crop_phases(crop_type_maxval)
type(agsys_cultivars_of_crop_type) :: crops(crop_type_maxval)

type(agsys_type) :: agsys_inst

Expand Down Expand Up @@ -110,7 +107,7 @@ subroutine AgSysDriver(this, num_pcropp, filter_pcropp, &
if (crop_type /= crop_type_not_handled) then
g = patch%gridcell(p)
c = patch%column(p)
cultivar = this%agsys_inst%cultivar_patch(p)
cultivar_type = this%agsys_inst%cultivar_patch(p)

call AgsysAbioticStress_Placeholder( &
! Inputs, time-varying
Expand All @@ -122,9 +119,7 @@ subroutine AgSysDriver(this, num_pcropp, filter_pcropp, &

call DoTimeStep_Phenology_Placeholder( &
! Inputs, time-constant
croptype = crop_type, &
phases = this%crop_phases(crop_type), &
cultivar_params = this%crop_cultivar_params(crop_type)%cultivar_params(cultivar), &
crop = this%crops(crop_type)%cultivars(cultivar_type), &

! Inputs, time-varying
photoperiod = grc%dayl(g), &
Expand Down
109 changes: 51 additions & 58 deletions src/agsys/ctsm_interface/AgSysParamReader.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,93 +6,86 @@ module AgSysParamReader
!
! !USES:
#include "shr_assert.h"
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use AgSysParams , only : agsys_crop_cultivar_params_type
use AgSysPhases , only : agsys_phases_type, &
max_str_len_for_phase_def, &
phase_type_generic, phase_type_germinating, phase_type_emerging, &
phase_type_leaf_appearance
use AgSysConstants , only : crop_type_maxval, crop_type_maize
use shr_kind_mod, only : r8 => shr_kind_r8
use shr_infnan_mod, only : nan => shr_infnan_nan, assignment(=)
use AgSysCropTypeGeneric, only : agsys_cultivars_of_crop_type, agsys_crop_type_generic
use AgSysCropTypePhotoSensitive, only : agsys_crop_type_photosensitive
use AgSysCropTypeMaize, only : agsys_crop_type_maize
use AgSysConstants, only : crop_type_maxval, crop_type_maize
!
implicit none
private

! !PUBLIC ROUTINES:
public :: ReadParams
public :: ReadPhases

character(len=*), parameter, private :: sourcefile = &
__FILE__

contains

!-----------------------------------------------------------------------
subroutine ReadParams(crop_cultivar_params)
subroutine ReadParams(crops)
!
! !DESCRIPTION:
! Read parameters
!
! !ARGUMENTS:
type(agsys_crop_cultivar_params_type), intent(inout) :: crop_cultivar_params(:)
type(agsys_cultivars_of_crop_type), intent(inout) :: crops(:)
!
! !LOCAL VARIABLES:

character(len=*), parameter :: subname = 'ReadParams'
!-----------------------------------------------------------------------

SHR_ASSERT_FL((size(crop_cultivar_params) == crop_type_maxval), sourcefile, __LINE__)
SHR_ASSERT_FL((size(crops) == crop_type_maxval), sourcefile, __LINE__)

allocate(crop_cultivar_params(crop_type_maize)%cultivar_params(1))

associate(cultivar_params => crop_cultivar_params(crop_type_maize)%cultivar_params(1))
allocate(agsys_crop_type_photosensitive :: crops(crop_type_maize)%cultivar(1))

!!currently we hard-coded parameters for one maize cultivar (Pioneer_P04612XR_106)
!!check the parameter values in the Maize.xml of APSIM
!!http://apsrunet.apsim.info/websvn/filedetails.php?repname=apsim&path=%2Ftrunk%2FModel%2FMaize.xml
!!TODO(pb, 2019-11-14) read parameters from files
associate(cultivar => crops(crop_type_maize)%cultivar(1))
! can access params like this:
! cultivar_params%shoot_lag
cultivar_params%p_sowing_depth = 50._r8 ! [mm], this is information about management and can be put
! into a separate structure later [TODO (2019-11-12, pb)]
cultivar_params%p_shoot_lag = 15._r8 ! [degree-days]
cultivar_params%p_shoot_rate = 0.6_r8 ! [degree-days per mm depth]

cultivar_params%rc_tair_tt%x=[0._r8, 18._r8, 26._r8, 34._r8, 44._r8]
cultivar_params%rc_tair_tt%y=[0._r8, 10._r8, 18._r8, 26._r8, 0._r8]
cultivar_params%rc_tair_tt%num_pts=5

cultivar_params%rc_sw_avail_phenol%x=[0._r8, 0.16_r8]
cultivar_params%rc_sw_avail_phenol%y=[0._r8, 1._r8]
cultivar_params%rc_sw_avail_phenol%num_pts=2
call cultivar%init()
select type(cultivar)
class is (agsys_crop_type_generic)
cultivar%p_sowing_depth = 50._r8 ! [mm], this is information about management and can be put
! into a separate structure later [TODO (2019-11-12, pb)]
cultivar%p_shoot_lag = 15._r8 ! [degree-days]
cultivar%p_shoot_rate = 0.6_r8 ! [degree-days per mm depth]
cultivar%p_pesw_germ = 0._r8 ! soil moisture threshold for seed germination

cultivar%rc_tair_tt%x=[0._r8, 18._r8, 26._r8, 34._r8, 44._r8]
cultivar%rc_tair_tt%y=[0._r8, 10._r8, 18._r8, 26._r8, 0._r8]
cultivar%rc_tair_tt%num_pts=5

cultivar%rc_sw_avail_phenol%x=[0._r8, 0.16_r8]
cultivar%rc_sw_avail_phenol%y=[0._r8, 1._r8]
cultivar%rc_sw_avail_phenol%num_pts=2

cultivar%rc_sw_emerg_rate%x=[0._r8, 1._r8]
cultivar%rc_sw_emerg_rate%y=[1._r8, 1._r8] !for maize, this is deactivated
cultivar%rc_sw_emerg_rate%num_pts=2

class is (agsys_crop_type_photosensitive)
cultivar%rc_photoperiod_target_tt%x=[0._r8, 12.5_r8, 20._r8]
cultivar%rc_photoperiod_target_tt%y=[0._r8, 0._r8, 0._r8]
cultivar%rc_photoperiod_target_tt%num_pts=3
class is (agsys_crop_type_maize)
cultivar%tt_emerg_to_endjuv = 275._r8
cultivar%tt_flag_to_flower = 1._r8
cultivar%tt_flower_to_maturity = 812._r8
cultivar%tt_flower_to_start_grain = 170._r8
cultivar%tt_maturity_to_ripe = 1._r8
cultivar%potential_kernel_weight = 300._r8
cultivar%leaf_no_dead_const = -0.025_r8
cultivar%leaf_no_dead_slope = 0.00035_r8
end select
end associate

end subroutine ReadParams

!-----------------------------------------------------------------------
subroutine ReadPhases(crop_phases)
!
! !DESCRIPTION:
! Read phase descriptions for each crop
!
! !ARGUMENTS:
type(agsys_phases_type), intent(inout) :: crop_phases(:)
!
! !LOCAL VARIABLES:

character(len=*), parameter :: subname = 'ReadPhases'
!-----------------------------------------------------------------------

SHR_ASSERT_FL((size(crop_phases) == crop_type_maxval), sourcefile, __LINE__)

crop_phases(crop_type_maize)%num_phases=11
crop_phases(crop_type_maize)%stage_name=[character(len=max_str_len_for_phase_def) :: &
'sowing', 'germination', 'emergence', 'end_of_juvenile', &
'floral_initiation', 'flag_leaf', 'flowering', &
'start_grain_fill', 'end_grain_fill', 'maturity', 'harvest_ripe', 'end_crop']
crop_phases(crop_type_maize)%phase_name=[character(len=max_str_len_for_phase_def) :: &
'germinating', 'emerging', 'juvenile', &
'photosen_sitive', 'leaf_apperance', 'flag_leaf_to_flowering', &
'flowering_to_grain_filling', 'grain_filling', 'maturing', 'maturity_to_harvest_ripe', 'ready_for_harvesting']
crop_phases(crop_type_maize)%phase_type=[phase_type_germinating, phase_type_emerging, phase_type_generic, &
phase_type_generic, phase_type_generic, phase_type_generic, &
phase_type_generic, phase_type_generic, phase_type_generic, phase_type_generic, phase_type_generic]

end subroutine ReadPhases

end module AgSysParamReader
147 changes: 147 additions & 0 deletions src/agsys/science/AgSysCropTypeGeneric.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
module AgSysCropTypeGeneric
use AgSysKinds, only : r8
use AgSysEnvInputs, only : agsys_env_inputs_type
use AgSysUtils, only : response_curve_type
use AgSysPhases, only : agsys_phase_type
use AgSysExcepUtils, only : iulog, endrun

implicit none

!!a container type to store the crop type instances
type, public :: agsys_crop_container_type
private
class(agsys_crop_type_generic), allocatable, public :: crop
end type agsys_crop_container_type

!!a container type to store all the cultivars of a given crop type
type, public :: agsys_cultivars_of_crop_type
private
class(agsys_crop_type_generic), allocatable, public :: cultivar(:)
end type agsys_cultivars_of_crop_type

!-----------------------------------------------------------------
!!a generic crop type holding parameters that shared by all crops
type, public :: agsys_crop_type_generic
private
!public data members
integer, public :: croptype

!phase definition
type(agsys_phase_type), public :: phases

!parameters related with phenology
integer, allocatable, public :: max_days_from_sowing_to_end_of_phase(:)
real(r8), public :: p_sowing_depth
real(r8), public :: p_shoot_lag
real(r8), public :: p_shoot_rate
real(r8), public :: p_pesw_germ
type(response_curve_type), public :: rc_tair_tt
type(response_curve_type), public :: rc_sw_avail_phenol
type(response_curve_type), public :: rc_sw_emerg_rate
contains
procedure :: init

procedure :: vernalization
procedure :: vern_days
procedure :: vern_effect
procedure :: photop_eff
procedure :: get_stress_phenol
procedure :: get_stress_phenol_emerging_phase
procedure :: get_stress_phenol_inductive_phase
procedure :: get_target_tt_photosensitive_phase
procedure :: get_target_tt_inductive_phase
end type agsys_crop_type_generic

contains
subroutine init(this)
type(agsys_crop_type_generic), intent(inout) :: this
this%p_sowing_depth = 0._r8
this%p_shoot_lag = 0._r8
this%p_shoot_rate = 0._r8
this%p_pesw_germ = 0._r8
this%rc_tair_tt%num_pts = 0
this%rc_sw_avail_phenol%num_pts = 0
this%rc_sw_emerg_rate%num_pts = 0
end subroutine init

subroutine vernalization(this, env, cumvd)
class(agsys_crop_type_generic), intent(in) :: this
type(agsys_env_inputs_type), intent(in) :: env
real(r8), intent(inout) :: cumvd
!do nothing here
end subroutine vernalization

function vern_days(this, env) result(dlt_cumvd)
class(agsys_crop_type_generic), intent(in) :: this
type(agsys_env_inputs_type), intent(in) :: env
real(r8) :: dlt_cumvd
!do nothng here
end function vern_days

function vern_effect(this, cumvd) result(vern_eff)
class(agsys_crop_type_generic), intent(in) :: this
real(r8), intent(in) :: cumvd
real(r8) :: vern_eff
!do nothing here
end function vern_effect

function photop_effect(this, photoperiod) result(photop_eff)
class(agsys_crop_type_generic), intent(in) :: this
real(r8), intent(in) :: photoperiod
real(r8) :: photop_eff
!do nothing here
end function photop_effect

function get_stress_phenol(this, swdef_phenol) result(stress_phenol)
class(agsys_crop_type_generic), intent(in) :: this
real(r8), intend(in) :: swdef_phenol
real(r8) stress_phenol
!default stress to crop phenology is water stress
stress_phenol=swdef_phenol
end function get_stress_phenol

function get_stress_phenol_inductive_phase(this, env, cumvd, swdef_phenol, nfact_phenol, pfact_phenol) result(stress_phenol)
class(agsys_crop_type_wheat), intent(in) :: this
type(agsys_env_inputs_type), intent(in) :: env
real(r8), intent(in) :: cumvd
real(r8), intent(in) :: swdef_phenol
real(r8), intent(in) :: nfact_phenol
real(r8), intent(in) :: pfact_phenol
real(r8) :: stress_phenol
!do nothing here
character(len=*), parameter :: subname = 'get_stress_phenol_inductive_phase'
write(iulog, *) "This call to ", subname, " is illegal"
call endrun(msg="Illegal call!")
end function get_stress_phenol_inductive_phase

function get_stress_phenol_emerging_phase(this, env, sw_avail_ratio, cumvd)
class(agsys_crop_type_wheat), intent(in) :: this
type(agsys_env_inputs_type), intent(in) :: env
real(r8), intent(in) :: sw_avail_ratio
real(r8), intent(in) :: cumvd
real(r8) :: stress_phenol

stress_phenol=interpolation(sw_avail_ratio, this%rc_sw_emerg_rate)
end function get_stress_phenol_emerging_phase

function get_target_tt_photosensitive_phase(this, env) result(target_tt)
class (agsys_crop_type_photosensitive), intent(in) :: this
type (agsys_env_inputs_type), intent(in) :: env
real(r8) :: target_tt
!do nothing here
character(len=*), parameter :: subname = 'get_target_tt_photosensitive_phase'
write(iulog, *) "This call to ", subname, " is illegal"
call endrun(msg="Illegal call!")
end function get_target_tt_photosensitive_phase

function get_target_tt_inductive_phase(this, cumvd) result(target_tt)
class(agsys_crop_type_vernalization), intent(in) :: this
real(r8), intent(in) :: cumvd
real(r8) :: target_tt
!do nothing here
character(len=*), parameter :: subname = 'get_target_tt_inductive_phase'
write(iulog, *) "This call to ", subname, " is illegal"
call endrun(msg="Illegal call!")
end function get_target_tt_inductive_phase

end module AgSysCropTypeGeneric
63 changes: 63 additions & 0 deletions src/agsys/science/AgSysCropTypeMaize.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module AgSysCropTypeMaize
use AgSysKinds, only : r8
use AgSysConstants, only : crop_type_maize
use AgSysPhases, only : max_str_len_for_phase_def, &
phase_type_generic, &
phase_type_germinating, phase_type_emerging, phase_type_photo_sensitive
use AgSysEnvInputs, only : agsys_env_inputs_type
use AgSysUtils, only : response_curve_type, interpolation
use AgSysCropTypePhotoSensitive, only : agsys_crop_type_photosensitive
implicit none

type, extends(agsys_crop_type_photosensitive), public :: agsys_crop_type_maize
private
!public data members
real(r8), public :: tt_emerg_to_endjuv
real(r8), public :: tt_emerg_to_fi
real(r8), public :: tt_flag_to_flower
real(r8), public :: tt_flower_to_start_grain
real(r8), public :: tt_flower_to_maturity
real(r8), public :: tt_maturity_to_ripe

real(r8), public :: potential_kernel_weight
real(r8), public :: leaf_no_dead_const
real(r8), public :: leaf_no_dead_slope
contains
procedure :: init

end type agsys_crop_type_maize
contains
subroutine init(this)
type(agsys_crop_type_maize), intent(inout) :: this

this%croptype = crop_type_maize

!!!initialize the parameters
!!!TODO(pb, 2019-11-14) now we intialize the variables to 0,
!!!but later can initialize them into nan
this%tt_emerg_to_endjuv = 0._r8
this%tt_emerg_to_fi = 0._r8
this%tt_flag_to_flower = 0._r8
this%tt_flower_to_start_grain = 0._r8
this%tt_flower_to_maturity = 0._r8
this%tt_maturity_to_ripe = 0._r8
this%tt_potential_kernal_weight = 0._r8
this%tt_leaf_no_dead_const = 0._r8
this%tt_leaf_no_dead_slope = 0._r8

!!!initialize the phases
this%phases%num_phases=11
this%phases%stage_name=[character(len=max_str_len_for_phase_def) :: &
'sowing', 'germination', 'emergence', 'end_of_juvenile', &
'floral_initiation', 'flag_leaf', 'flowering', &
'start_grain_fill', 'end_grain_fill', 'maturity', 'harvest_ripe', 'end_crop']
this%phases%phase_name=[character(len=max_str_len_for_phase_def) :: &
'germinating', 'emerging', 'juvenile', &
'photo_sensitive', 'leaf_apperance', 'flag_leaf_to_flowering', &
'flowering_to_grain_filling', 'grain_filling', 'maturing', 'maturity_to_harvest_ripe', 'ready_for_harvesting']
this%phases%phase_type=[phase_type_germinating, phase_type_emerging, phase_type_generic, &
phase_type_photo_sensitive, phase_type_generic, phase_type_generic, &
phase_type_generic, phase_type_generic, phase_type_generic, phase_type_generic, phase_type_generic]

end subroutine init
end module AgSysCropTypeMaize
Loading

0 comments on commit c127f40

Please sign in to comment.