RiceClass_old.f90 Source File


Source Code

module RiceClass
   use, intrinsic :: iso_fortran_env
   use MathClass
   use SeedClass
   use LeafClass
   use RootClass
   use SoilClass
   use LightClass
   use PlantNodeClass
   implicit none

   type :: Rice_
      ! growth_habit = determinate, indeterminate, semi-indeterminate, or vine
      character*20 :: growth_habit
      character*2  :: growth_stage
      integer(int32) :: Num_Of_Node
      integer(int32) :: Num_Of_Root

      integer(int32) :: MaxLeafNum = 300
      integer(int32) :: MaxRootNum = 300
      integer(int32) :: MaxStemNum = 300

      integer(int32)  :: ms_node, br_node(300), br_from(300)
      real(real64)    :: ms_length, br_length(300)
      real(real64)    :: ms_width, br_width(300)
      real(real64)    :: ms_angle_ave, br_angle_ave(300)
      real(real64)    :: ms_angle_sig, br_angle_sig(300)

      integer(int32)  :: mr_node, brr_node(300), brr_from(300)
      real(real64)    :: mr_length, brr_length(300)
      real(real64)    :: mr_width, brr_width(300)
      real(real64)    :: mr_angle_ave, brr_angle_ave(300)
      real(real64)    :: mr_angle_sig, brr_angle_sig(300)

      real(real64)    :: peti_size_ave(300)
      real(real64)    :: peti_size_sig(300)
      real(real64)    :: peti_width_ave(300)
      real(real64)    :: peti_width_sig(300)
      real(real64)    :: peti_angle_ave(300)
      real(real64)    :: peti_angle_sig(300)

      real(real64)    :: leaf_angle_ave(300*3)
      real(real64)    :: leaf_angle_sig(300*3)
      real(real64)    :: leaf_length_ave(300*3)
      real(real64)    :: leaf_length_sig(300*3)
      real(real64)    :: leaf_width_ave(300*3)
      real(real64)    :: leaf_width_sig(300*3)
      real(real64)    :: leaf_thickness_ave(300*3)
      real(real64)    :: leaf_thickness_sig(300*3)

      character(3) :: Stage ! VE, CV, V1,V2, ..., R1, R2, ..., R8
      character(200) :: name
      integer(int32)::stage_id = 0
      real(real64) :: dt
      type(Seed_) :: Seed
      type(PlantNode_), allocatable :: NodeSystem(:)
      type(PlantRoot_), allocatable :: RootSystem(:)

      type(Stem_), allocatable :: Stem(:)
      type(Leaf_), allocatable :: Leaf(:)
      type(Root_), allocatable :: Root(:)
      type(Soil_), allocatable :: Soil

      ! 節-節点データ構造
      type(Mesh_) :: struct
      integer(int32), allocatable :: leaf2stem(:, :)
      integer(int32), allocatable :: stem2stem(:, :)
      integer(int32), allocatable :: root2stem(:, :)
      integer(int32), allocatable :: root2root(:, :)

      ! 器官オブジェクト配列
      type(FEMDomain_), allocatable :: leaf_list(:)
      type(FEMDomain_), allocatable :: stem_list(:)
      type(FEMDomain_), allocatable :: root_list(:)
      real(real64) :: time
      real(real64) :: seed_length
      real(real64) :: seed_width
      real(real64) :: seed_height
      real(real64), allocatable :: stem_angle(:, :)
      real(real64), allocatable :: root_angle(:, :)
      real(real64), allocatable :: leaf_angle(:, :)

      character(200) :: stemconfig = " "
      character(200) :: rootconfig = " "
      character(200) :: leafconfig = " "
   contains
      procedure, public :: addStem => addStemRice
      !procedure,public :: addRoot => addRootRice
      !procedure,public :: addLeaf => addLeafRice

      procedure, public :: Init => initRice
      procedure, public :: new => initRice
      procedure, public :: sowing => initRice
      procedure, public :: export => exportRice

      procedure, public :: grow => growRice

      procedure, public :: show => showRice
      procedure, public :: gmsh => gmshRice
      procedure, public :: msh => mshRice
      procedure, public :: stl => stlRice
      procedure, public :: json => jsonRice

      procedure, public :: WaterAbsorption => WaterAbsorptionRice
      procedure, public :: move => moveRice

      procedure, public :: numleaf => numleafRice
      procedure, public :: numstem => numstemRice
      procedure, public :: numroot => numrootRice

      procedure, public :: laytracing => laytracingRice
      procedure, public :: SinkSourceFlow => SinkSourceFlowRice

      !procedure,public :: AddNode => AddNodeRice
   end type

   type :: RiceCanopy_
      real(real64) :: inter_row, intra_row
      type(Rice_), allocatable :: Canopy(:, :)
   end type

contains

! ########################################
   subroutine initRice(obj, config, &
                       regacy, mass, water_content, radius, location, x, y, z, &
                       PlantRoot_diameter_per_seed_radius, max_PlantNode_num, Variety, FileName, &
                       max_leaf_num, max_stem_num, max_root_num)
      class(Rice_), intent(inout) :: obj

      real(real64), optional, intent(in) :: mass, water_content, radius, location(3), x, y, z
      real(real64), optional, intent(in) :: PlantRoot_diameter_per_seed_radius
      character(*), optional, intent(in) :: Variety, FileName, config
      logical, optional, intent(in) :: regacy
      character(200) :: fn, conf, line
      integer(int32), optional, intent(in) :: max_PlantNode_num, max_leaf_num, max_stem_num, max_root_num
      real(real64) :: MaxThickness, Maxwidth, loc(3), vec(3), rot(3), zaxis(3), meshloc(3), meshvec(3)
      integer(int32) :: i, j, k, blcount, id, rmc, n, node_id, node_id2, elemid, branch_id, num_stem_node
      integer(int32) :: num_leaf
      real(real64)::readvalreal
      integer(int32) :: readvalint
      type(IO_) :: soyconf
      type(Random_) :: random

      ! set default parameters
      ! stem
      obj%br_node(:) = 0
      obj%br_from(:) = 0
      obj%br_length(:) = 0.0d0

      obj%br_angle_ave(:) = 0.0d0
      obj%br_angle_sig(:) = 10.0d0
      obj%br_angle_ave(1) = 30.0d0
      obj%br_angle_sig(1) = 2.0d0

      obj%ms_angle_ave = 0.0d0
      obj%ms_angle_sig = 2.0d0

      ! for roots
      obj%brr_node(:) = 0
      obj%brr_from(:) = 0
      obj%brr_length(:) = 0.0d0

      obj%brr_angle_ave(:) = 0.0d0
      obj%brr_angle_sig(:) = 10.0d0
      obj%brr_angle_ave(1) = 30.0d0
      obj%brr_angle_sig(1) = 2.0d0

      obj%mr_angle_ave = 0.0d0
      obj%mr_angle_sig = 2.0d0
      ! peti
      ! is also stem

      obj%peti_size_ave(:) = 0.20d0
      obj%peti_size_sig(:) = 0.010d0

      obj%peti_width_ave(:) = 0.0050d0
      obj%peti_width_sig(:) = 0.00010d0

      obj%peti_angle_ave(:) = 30.0d0
      obj%peti_angle_sig(:) = 1.00d0

      ! leaf
      obj%leaf_length_ave(:) = 0.20d0
      obj%leaf_length_sig(:) = 0.01d0

      obj%leaf_width_ave(:) = 0.050d0
      obj%leaf_width_sig(:) = 0.010d0

      obj%leaf_thickness_ave(:) = 0.00100d0
      obj%leaf_thickness_sig(:) = 0.00050d0

      obj%leaf_angle_ave(:) = 40.0d0
      obj%leaf_angle_sig(:) = 10.0d0

      ! 子葉節、初生葉節、根の第1節まで種子の状態で存在

      ! 節を生成するためのスクリプトを開く
      if (.not. present(config) .or. index(config, ".json") == 0) then
         ! デフォルトの設定を生成
         print *, "New Rice-configuration >> soyconfig.json"
         call soyconf%open("soyconfig.json")
         write (soyconf%fh, *) '{'
         write (soyconf%fh, *) '   "type": "Rice",'
         write (soyconf%fh, *) '   "stemconfig": "stemconfig.json",'
         write (soyconf%fh, *) '   "rootconfig": "rootconfig.json",'
         write (soyconf%fh, *) '   "leafconfig": "leafconfig.json",'
         write (soyconf%fh, *) '   "stage": 0,'
         write (soyconf%fh, *) '   "length": 0.0090,'
         write (soyconf%fh, *) '   "width" : 0.0081,'
         write (soyconf%fh, *) '   "height": 0.0072,'
         write (soyconf%fh, *) '   "MaxLeafNum": 50,'
         write (soyconf%fh, *) '   "MaxRootNum":200,'
         write (soyconf%fh, *) '   "MaxStemNum": 50,'

         ! stem
         write (soyconf%fh, *) '   "br_node" : 0,'
         write (soyconf%fh, *) '   "br_from" : 0,'
         write (soyconf%fh, *) '   "br_length" : 0.00,'
         write (soyconf%fh, *) '   "br_angle_ave" : 0.00,'
         write (soyconf%fh, *) '   "br_angle_sig" : 10.00,'
         write (soyconf%fh, *) '   "br_angle_ave(1)": 360.00,'
         write (soyconf%fh, *) '   "br_angle_sig(1)": 2.00,'
         write (soyconf%fh, *) '   "ms_angle_ave": 0.00,'
         write (soyconf%fh, *) '   "ms_angle_sig": 2.00,'

         ! root
         write (soyconf%fh, *) '   "brr_node" : 0,'
         write (soyconf%fh, *) '   "brr_from" : 0,'
         write (soyconf%fh, *) '   "brr_length" : 0.00,'
         write (soyconf%fh, *) '   "brr_angle_ave" : 0.00,'
         write (soyconf%fh, *) '   "brr_angle_sig" : 10.00,'
         write (soyconf%fh, *) '   "brr_angle_ave(1)": 360.00,'
         write (soyconf%fh, *) '   "brr_angle_sig(1)": 2.00,'
         write (soyconf%fh, *) '   "mr_angle_ave": 0.00,'
         write (soyconf%fh, *) '   "mr_angle_sig": 2.00,'
         ! peti
         ! is also stem
         write (soyconf%fh, *) '   "peti_size_ave"  :  0.200,'
         write (soyconf%fh, *) '   "peti_size_sig"  :  0.0100,'
         write (soyconf%fh, *) '   "peti_width_ave"  :  0.00500,'
         write (soyconf%fh, *) '   "peti_width_sig"  :  0.000100,'
         write (soyconf%fh, *) '   "peti_angle_ave"  :  30.00,'
         write (soyconf%fh, *) '   "peti_angle_sig"  :  1.000,'
         ! leaf
         write (soyconf%fh, *) '   "leaf_length_ave"  :  0.200,'
         write (soyconf%fh, *) '   "leaf_length_sig"  :  0.010,'
         write (soyconf%fh, *) '   "leaf_width_ave"  :  0.0500,'
         write (soyconf%fh, *) '   "leaf_width_sig"  :  0.0100,'
         write (soyconf%fh, *) '   "leaf_thickness_ave"  :  0.001000,'
         write (soyconf%fh, *) '   "leaf_thickness_sig"  :  0.000500,'
         write (soyconf%fh, *) '   "leaf_angle_ave"  :  40.00,'
         write (soyconf%fh, *) '   "leaf_angle_sig"  :  10.00'
         write (soyconf%fh, *) '}'
         conf = "soyconfig.json"
         call soyconf%close()
      else
         conf = config
      end if

      call soyconf%open(conf)
      blcount = 0
      do
         read (soyconf%fh, '(a)') line
         print *, line
         if (adjustl(line) == "{") then
            blcount = 1
            cycle
         end if
         if (adjustl(line) == "}") then
            exit
         end if

         if (blcount == 1) then

            if (index(line, "Name") /= 0) then
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%name
            end if

            if (index(line, "Mainstem") /= 0) then
               do
                  read (soyconf%fh, '(a)') line
                  print *, line
                  if (index(line, "}") /= 0) then
                     exit
                  end if

                  if (index(line, "Length") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%ms_length
                  end if

                  if (index(line, "Width") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%ms_width
                  end if

                  if (index(line, "Node") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%ms_node
                  end if

               end do
            end if

            if (index(line, "Branch#") /= 0) then
               rmc = index(line, "{")
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, '"')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, '"')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, ':')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, "#")
               print *, line
               read (line(id + 1:), *) branch_id

               do
                  read (soyconf%fh, '(a)') line
                  print *, line
                  if (index(line, "}") /= 0) then
                     exit
                  end if

                  if (index(line, "Length") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%br_length(branch_id)
                  end if

                  if (index(line, "Width") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%br_Width(branch_id)
                  end if

                  if (index(line, "Node") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%br_node(branch_id)
                  end if

                  if (index(line, "From") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%br_from(branch_id)
                  end if

               end do
            end if

            ! for roots

            if (index(line, "Mainroot") /= 0) then
               do
                  read (soyconf%fh, '(a)') line
                  print *, line
                  if (index(line, "}") /= 0) then
                     exit
                  end if

                  if (index(line, "Length") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%mr_length
                  end if

                  if (index(line, "Width") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%mr_width
                  end if

                  if (index(line, "Node") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%mr_node
                  end if

               end do
            end if

            if (index(line, "Branchroot#") /= 0) then
               rmc = index(line, "{")
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, '"')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, '"')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               rmc = index(line, ':')
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, "#")
               print *, line
               read (line(id + 1:), *) branch_id

               do
                  read (soyconf%fh, '(a)') line
                  print *, line
                  if (index(line, "}") /= 0) then
                     exit
                  end if

                  if (index(line, "Length") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%brr_length(branch_id)
                  end if

                  if (index(line, "Width") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%brr_Width(branch_id)
                  end if

                  if (index(line, "Node") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%brr_node(branch_id)
                  end if

                  if (index(line, "From") /= 0) then
                     rmc = index(line, ",")
                     if (rmc /= 0) then
                        line(rmc:rmc) = " "
                     end if
                     id = index(line, ":")
                     read (line(id + 1:), *) obj%brr_from(branch_id)
                  end if

               end do
            end if

            if (index(line, "type") /= 0 .and. index(line, "Rice") == 0) then
               print *, "ERROR: This config-file is not for Rice"
               return
            end if

            if (index(line, "rootconfig") /= 0) then
               ! 茎の設定ファイル
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%rootconfig
            end if

            if (index(line, "stemconfig") /= 0) then
               ! 茎の設定ファイル
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%stemconfig
            end if

            if (index(line, "leafconfig") /= 0) then
               ! 茎の設定ファイル
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%leafconfig
            end if

            if (index(line, "stage") /= 0) then
               ! 生育ステージ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%stage_id
            end if

            if (index(line, "MaxLeafNum") /= 0) then
               ! 生育ステージ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%MaxLeafNum
            end if

            if (index(line, "MaxStemNum") /= 0) then
               ! 生育ステージ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%MaxStemNum
            end if

            if (index(line, "MaxRootNum") /= 0) then
               ! 生育ステージ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%MaxRootNum
            end if

            if (index(line, "length") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%seed_length
            end if

            if (index(line, "width") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%seed_width
            end if

            if (index(line, "height") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) obj%seed_height
            end if

            ! for version 2020.11.24

            ! stem
            if (index(line, "br_angle_ave") /= 0 .and. index(line, "br_angle_ave(") == 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%br_angle_ave(:) = readvalreal
            end if

            if (index(line, "br_angle_sig") /= 0 .and. index(line, "br_angle_sig(") == 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%br_angle_sig(:) = readvalreal
            end if

            if (index(line, "br_angle_ave(1)") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%br_angle_ave(1) = readvalreal
            end if
            if (index(line, "br_angle_sig(1)") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%br_angle_sig(1) = readvalreal
            end if

            if (index(line, "ms_angle_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%ms_angle_ave = readvalreal
            end if

            if (index(line, "ms_angle_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%ms_angle_sig = readvalreal
            end if
            ! peti
            ! is also stem

            if (index(line, "peti_size_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_size_ave(:) = readvalreal
            end if

            if (index(line, "peti_size_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_size_sig(:) = readvalreal
            end if

            if (index(line, "peti_width_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_width_ave(:) = readvalreal
            end if

            if (index(line, "peti_width_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_width_sig(:) = readvalreal
            end if

            if (index(line, "peti_angle_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_angle_ave(:) = readvalreal
            end if

            if (index(line, "peti_angle_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%peti_angle_sig(:) = readvalreal
            end if
            ! leaf

            if (index(line, "leaf_length_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_length_ave(:) = readvalreal
            end if

            if (index(line, "leaf_length_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_length_sig(:) = readvalreal
            end if

            if (index(line, "leaf_width_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_width_ave(:) = readvalreal
            end if

            if (index(line, "leaf_width_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_width_sig(:) = readvalreal
            end if

            if (index(line, "leaf_thickness_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_thickness_ave(:) = readvalreal
            end if

            if (index(line, "leaf_thickness_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_thickness_sig(:) = readvalreal
            end if

            if (index(line, "leaf_angle_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_angle_ave(:) = readvalreal
            end if

            if (index(line, "leaf_angle_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%leaf_angle_sig(:) = readvalreal
            end if

            ! added in 2020/12/15
            ! for roots

            if (index(line, "brr_angle_ave") /= 0 .and. index(line, "brr_angle_ave(") == 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%brr_angle_ave(:) = readvalreal
            end if

            if (index(line, "brr_angle_sig") /= 0 .and. index(line, "brr_angle_sig(") == 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%brr_angle_sig(:) = readvalreal
            end if

            if (index(line, "brr_angle_ave(1)") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%brr_angle_ave(1) = readvalreal
            end if
            if (index(line, "brr_angle_sig(1)") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%brr_angle_sig(1) = readvalreal
            end if

            if (index(line, "mr_angle_ave") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%mr_angle_ave = readvalreal
            end if

            if (index(line, "mr_angle_sig") /= 0) then
               ! 種子の長さ
               rmc = index(line, ",")
               ! カンマがあれば除く
               if (rmc /= 0) then
                  line(rmc:rmc) = " "
               end if
               id = index(line, ":")
               read (line(id + 1:), *) readvalreal
               obj%mr_angle_sig = readvalreal
            end if

            cycle

         end if

      end do
      call soyconf%close()

      if (index(config, ".json") == 0) then
         obj%stemconfig = " "
         obj%rootconfig = " "
         obj%leafconfig = " "
      end if

      if (obj%ms_node /= 0) then
         ! loaded from Mainstem-Branches relation file format
         ! ex.
!       {
!           "Name":"Rice",
!           "Mainstem":{
!               "Length":1.2,
!               "Node":13
!           },
!           "Branch#1":{
!               "From":1,
!               "Length":0.6,
!               "Node":7
!           },
!           "Branch#2":{
!               "From":3,
!               "Length":0.2,
!               "Node":2
!           },
!           "Branch#3":{
!               "From":4,
!               "Length":0.2,
!               "Node":2
!           }
!       }
         ! count number of nodes
         !num_node = countif(obj%ms_node,notEquai=.true.,0)
         !num_node = num_node + countif(obj%br_node,notEquai=.true.,0)

         allocate (obj%leaf(obj%MaxLeafNum))
         allocate (obj%root(obj%MaxrootNum))
         allocate (obj%stem(obj%MaxstemNum))
         allocate (obj%stem2stem(obj%MaxstemNum, obj%MaxstemNum))
         allocate (obj%leaf2stem(obj%MaxstemNum, obj%MaxLeafNum))
         allocate (obj%root2stem(obj%MaxrootNum, obj%MaxstemNum))
         allocate (obj%root2root(obj%MaxrootNum, obj%MaxrootNum))
         obj%stem2stem(:, :) = 0
         obj%leaf2stem(:, :) = 0
         obj%root2stem(:, :) = 0
         obj%root2root(:, :) = 0

         ! set mainstem
         do i = 1, obj%ms_node

            call obj%stem(i)%init()
            call obj%stem(i)%resize( &
               x=obj%ms_width, &
               y=obj%ms_width, &
               z=obj%ms_length/dble(obj%ms_node) &
               )
            call obj%stem(i)%rotate( &
               x=radian(random%gauss(mu=obj%ms_angle_ave, sigma=obj%ms_angle_sig)), &
               y=radian(random%gauss(mu=obj%ms_angle_ave, sigma=obj%ms_angle_sig)), &
               z=radian(random%gauss(mu=obj%ms_angle_ave, sigma=obj%ms_angle_sig)) &
               )
         end do

         do i = 1, obj%ms_node - 1
            call obj%stem(i + 1)%connect("=>", obj%stem(i))
            obj%stem2stem(i + 1, i) = 1
         end do

         ! set branches
         k = obj%ms_node
         do i = 1, size(obj%br_node)
            do j = 1, obj%br_node(i)
               k = k + 1
               call obj%stem(k)%init()
               call obj%stem(k)%resize( &
                  x=obj%ms_width, &
                  y=obj%ms_width, &
                  z=obj%ms_length/dble(obj%ms_node) &
                  )

               call obj%stem(k)%rotate( &
                  x=radian(random%gauss(mu=obj%br_angle_ave(j), sigma=obj%br_angle_sig(j))), &
                  y=0.0d0, &
                  z=radian(360.0d0*random%random()) &
                  )

               if (j == 1) then
                  call obj%stem(k)%connect("=>", obj%stem(obj%br_from(i)))
                  obj%stem2stem(k, obj%br_from(i)) = 1
               else
                  call obj%stem(k)%connect("=>", obj%stem(k - 1))
                  obj%stem2stem(k, k - 1) = 1
               end if

            end do
         end do

         ! peti and leaf
         num_stem_node = k
         num_leaf = 0
         do i = 1, num_stem_node
            ! 3複葉
            ! add peti
            num_stem_node = num_stem_node + 1
            call obj%stem(num_stem_node)%init()

            call obj%stem(num_stem_node)%resize( &
               x=random%gauss(mu=obj%peti_width_ave(i), sigma=obj%peti_width_sig(i)), &
               y=random%gauss(mu=obj%peti_width_ave(i), sigma=obj%peti_width_sig(i)), &
               z=random%gauss(mu=obj%peti_size_ave(i), sigma=obj%peti_size_sig(i)) &
               )

            call obj%stem(num_stem_node)%rotate( &
               x=radian(random%gauss(mu=obj%peti_angle_ave(i), sigma=obj%peti_angle_sig(i))), &
               y=0.0d0, &
               z=radian(360.0d0*random%random()) &
               )
            call obj%stem(num_stem_node)%connect("=>", obj%stem(i))
            obj%leaf2stem(num_stem_node, i) = 1

            ! add leaves
            do j = 1, 3
               num_leaf = num_leaf + 1
               call obj%leaf(num_leaf)%init()
               call obj%leaf(num_leaf)%resize( &
                  y=random%gauss(mu=obj%leaf_thickness_ave(i), sigma=obj%leaf_thickness_sig(i)), &
                  z=random%gauss(mu=obj%leaf_length_ave(i), sigma=obj%leaf_length_sig(i)), &
                  x=random%gauss(mu=obj%leaf_width_ave(i), sigma=obj%leaf_width_sig(i)) &
                  )
               call obj%leaf(num_leaf)%rotate( &
                  x=radian(random%gauss(mu=obj%leaf_angle_ave(i), sigma=obj%leaf_angle_sig(i))), &
                  y=0.0d0, &
                  z=radian(random%random()*360.0d0) &
                  )
               call obj%leaf(num_leaf)%connect("=>", obj%stem(num_stem_node))
               obj%leaf2stem(num_leaf, num_stem_node) = 1
            end do

         end do

         ! set mainroot
         do i = 1, obj%mr_node

            call obj%root(i)%init()
            call obj%root(i)%resize( &
               x=obj%mr_width, &
               y=obj%mr_width, &
               z=obj%mr_length/dble(obj%mr_node) &
               )
            call obj%root(i)%rotate( &
               x=radian(random%gauss(mu=obj%mr_angle_ave, sigma=obj%mr_angle_sig)), &
               y=radian(random%gauss(mu=obj%mr_angle_ave, sigma=obj%mr_angle_sig)), &
               z=radian(random%gauss(mu=obj%mr_angle_ave, sigma=obj%mr_angle_sig)) &
               )
         end do

         do i = 1, obj%mr_node - 1
            if (i == 1) then
               call obj%root(1)%connect("=>", obj%stem(1))
               obj%root2stem(1, 1) = 1
            end if
            call obj%root(i + 1)%connect("=>", obj%root(i))
            obj%root2root(i + 1, i) = 1
         end do

         ! set branches
         k = obj%mr_node
         do i = 1, size(obj%brr_node)
            do j = 1, obj%brr_node(i)
               k = k + 1
               call obj%root(k)%init()
               call obj%root(k)%resize( &
                  x=obj%mr_width, &
                  y=obj%mr_width, &
                  z=obj%mr_length/dble(obj%mr_node) &
                  )

               call obj%root(k)%rotate( &
                  x=radian(random%gauss(mu=obj%brr_angle_ave(j), sigma=obj%brr_angle_sig(j))), &
                  y=0.0d0, &
                  z=radian(360.0d0*random%random()) &
                  )

               if (j == 1) then
                  call obj%root(k)%connect("=>", obj%root(obj%brr_from(i)))
                  obj%root2root(k, obj%brr_from(i)) = 1
               else
                  call obj%root(k)%connect("=>", obj%root(k - 1))
                  obj%root2root(k, k - 1) = 1
               end if

            end do
         end do

         obj%stage = "V"//str(obj%ms_node)
         return
      else
         ! create leaf, root, stem
         allocate (obj%leaf(obj%MaxLeafNum))
         allocate (obj%root(obj%MaxrootNum))
         allocate (obj%stem(obj%MaxstemNum))
         allocate (obj%stem2stem(obj%MaxstemNum, obj%MaxstemNum))
         allocate (obj%leaf2stem(obj%MaxstemNum, obj%MaxLeafNum))
         allocate (obj%root2stem(obj%MaxrootNum, obj%MaxstemNum))
         allocate (obj%root2root(obj%MaxrootNum, obj%MaxrootNum))

         !allocate(obj%struct%NodCoord(4,3) )
         !allocate(obj%struct%ElemNod(3,2) )
         !allocate(obj%struct%ElemMat(3) )
         ! 子葉結節部=(0,0,0)
         !obj%struct%NodCoord(1,1:3) = 0.0d0
         call obj%leaf(1)%init(obj%leafconfig)
         call obj%leaf(1)%rotate(x=radian(90.0d0), y=radian(90.0d0), z=radian(10.0d0))
         call obj%leaf(2)%init(obj%leafconfig)
         call obj%leaf(2)%rotate(x=radian(90.0d0), y=radian(90.0d0), z=radian(-10.0d0))

         call obj%stem(1)%init(obj%stemconfig)
         call obj%stem(1)%rotate(x=radian(40.0d0))

         call obj%stem(2)%init(obj%stemconfig)
         call obj%stem(2)%rotate(x=radian(80.0d0))

         call obj%root(1)%init(obj%rootconfig)
         call obj%root(1)%fix(x=0.0d0, y=0.0d0, z=0.0d0)
         call obj%root(1)%rotate(x=radian(-60.0d0))

         call obj%leaf(1)%connect("=>", obj%stem(1))
         obj%leaf2stem(1, 1) = 1

         call obj%leaf(2)%connect("=>", obj%stem(1))
         obj%leaf2stem(2, 1) = 1

         call obj%stem(2)%connect("=>", obj%stem(1))
         obj%stem2stem(2, 1) = 1

         call obj%root(1)%connect("=>", obj%stem(1))
         obj%root2stem(1, 1) = 1

         obj%stage = "VE"
         ! 初生葉結節部
         !obj%struct%NodCoord(2,1) = 0.0d0
         !obj%struct%NodCoord(2,2) = 0.0d0
         !obj%struct%NodCoord(2,3) = 1.0d0/20.0d0*obj%seed_height
         ! 地際部
         !obj%struct%NodCoord(3,1) = 1.0d0/4.0d0*obj%seed_length
         !obj%struct%NodCoord(3,2) = 0.0d0
         !obj%struct%NodCoord(3,3) = -1.0d0/3.0d0*obj%seed_height
         ! 根冠
         !obj%struct%NodCoord(4,1) = 1.0d0/2.0d0*obj%seed_length
         !obj%struct%NodCoord(4,2) = 0.0d0
         !obj%struct%NodCoord(4,3) = -1.0d0/2.0d0*obj%seed_height

         ! 子葉-初生葉節
         !obj%struct%ElemNod(1,1) = 1
         !obj%struct%ElemNod(1,2) = 2
         ! 地際-子葉節
         !obj%struct%ElemNod(2,1) = 3
         !obj%struct%ElemNod(2,2) = 1
         ! 地際-根冠節
         !obj%struct%ElemNod(3,1) = 3
         !obj%struct%ElemNod(3,2) = 4

         ! 子葉-初生葉節 stem: 1
         !obj%struct%ElemMat(1) = 1
         ! 地際-子葉節 stem: 1
         !obj%struct%ElemMat(2) = 1
         ! 地際-根冠節 primary root: -1
         !obj%struct%ElemMat(3) = -1

         ! FEメッシュを生成
         ! 領域を確保
         !    n = input(default=80,option=max_leaf_num)
         !    allocate(obj%leaf_list(n) )
         !    n = input(default=80,option=max_stem_num)
         !    allocate(obj%stem_list(n) )
         !    n = input(default=80,option=max_root_num)
         !    allocate(obj%root_list(n) )
         !
         !    ! 子葉のメッシュを生成
         !    call obj%leaf_list(1)%create(meshtype="Sphere3D",x_num=10,y_num=10,z_num=10,&
         !        x_len=obj%seed_length,y_len=obj%seed_width,z_len=obj%seed_height)
         !    call obj%leaf_list(1)%move(x=0.0d0,y=-0.50d0*obj%seed_width,z=-0.50d0*obj%seed_height)
         !
         !    call obj%leaf_list(2)%create(meshtype="Sphere3D",x_num=10,y_num=10,z_num=10,&
         !        x_len=obj%seed_length,y_len=obj%seed_width,z_len=obj%seed_height)
         !    call obj%leaf_list(2)%rotate(x=radian(180.0d0) )
         !    call obj%leaf_list(2)%move(x=0.0d0,y=-0.50d0*obj%seed_width,z=-0.50d0*obj%seed_height)
         !
         !
         !
         !    ! 子葉-初生葉節のメッシュを生成
         !    rot(:) = 0.0d0
         !    call obj%stem_list(1)%create(meshtype="rectangular3D",x_num=5,y_num=5,z_num=10,&
         !        x_len=obj%seed_width/6.0d0,y_len=obj%seed_width/6.0d0,z_len=obj%seed_length/4.0d0)
         !    ! 節基部の節点ID
         !    node_id = obj%struct%ElemNod(1,1)
         !    ! 節先端部の節点ID
         !    node_id2= obj%struct%ElemNod(1,2)
         !    ! 節基部の位置ベクトル
         !    loc(:) = obj%struct%NodCoord( node_id  ,:)
         !    ! 節先端部までの方向ベクトル
         !    vec(:) =  obj%struct%NodCoord( node_id2 ,:) - obj%struct%NodCoord( node_id  ,:)
         !
         !    ! structの構造データにメッシュデータを合わせる。
         !    print *, obj%stem_list(1)%Mesh%BottomElemID
         !    print *, obj%stem_list(1)%Mesh%TopElemID
         !
         !    elemid = obj%stem_list(1)%Mesh%BottomElemID
         !    node_id = obj%stem_list(1)%Mesh%ElemNod(elemID,1)
         !    meshloc(:) = obj%stem_list(1)%Mesh%NodCoord(node_id,:)
         !
         !    elemid = obj%stem_list(1)%Mesh%TopElemID
         !    node_id = obj%stem_list(1)%Mesh%ElemNod(elemID,1)
         !    meshvec(:) = obj%stem_list(1)%Mesh%NodCoord(node_id,:)-meshloc(:)

         !print *, "loc",loc
         !print *, "meshloc",meshloc
         !print *, "vec",vec
         !print *, "meshvec",meshvec

         !    ! 節中央を原点へ
         !    call obj%stem_list(1)%move(x=-obj%seed_width/12.0d0,y=-obj%seed_width/12.0d0)
         !
         !    print *, "loc",loc
         !    print *, "vec",vec
         !    print *, "rot",rot
         !    zaxis(:)=0.0d0
         !    zaxis(3)=obj%seed_length/5.0d0
         !    rot(:) = angles(zaxis,vec)
         !    call obj%stem_list(1)%move(x=loc(1),y=loc(2),z=loc(3) )
         !    call obj%stem_list(1)%rotate(x=0.0d0,y=0.0d0,z=0.0d0 )
    !!
         !
    !!
         !
         !
         !    ! 地際-子葉節のメッシュを生成
         !    rot(:) = 0.0d0
         !    call obj%stem_list(2)%create(meshtype="rectangular3D",x_num=5,y_num=5,z_num=10,&
         !        x_len=obj%seed_width/6.0d0,y_len=obj%seed_width/6.0d0,z_len=obj%seed_length/4.0d0)
         !    ! 節基部の節点ID
         !    node_id = obj%struct%ElemNod(2,1)
         !    ! 節先端部の節点ID
         !    node_id2= obj%struct%ElemNod(2,2)
         !    ! 節基部の位置ベクトル
         !    loc(:) = obj%struct%NodCoord( node_id  ,:)
         !    ! 節先端部までの方向ベクトル
         !    vec(:) =  obj%struct%NodCoord( node_id2 ,:) - obj%struct%NodCoord( node_id  ,:)
         !    ! 節中央を原点へ
         !    call obj%stem_list(2)%move(x=-obj%seed_width/12.0d0,y=-obj%seed_width/12.0d0,&
         !        z=-obj%seed_length/8.0d0)
         !    zaxis(:)=0.0d0
         !    zaxis(3)=obj%seed_length/5.0d0
         !    rot(:) = angles(zaxis,vec)
         !    print *, "loc",loc
         !    print *, "vec",vec
         !    print *, "rot",rot
         !    !call obj%stem_list(2)%rotate(x=rot(1),y=rot(2),z=rot(3) )
         !    call obj%stem_list(2)%move(x=loc(1),y=loc(2),z=loc(3) )
         !
         !
         !
         !    ! 地際-根冠節のメッシュ生成
         !    rot(:) = 0.0d0
         !    call obj%root_list(1)%create(meshtype="rectangular3D",x_num=5,y_num=5,z_num=10,&
         !        x_len=obj%seed_width/6.0d0,y_len=obj%seed_width/6.0d0,z_len=obj%seed_length/4.0d0)
         !    ! 節基部の節点ID
         !    node_id = obj%struct%ElemNod(3,1)
         !    ! 節先端部の節点ID
         !    node_id2= obj%struct%ElemNod(3,2)
         !    ! 節基部の位置ベクトル
         !    loc(:) = obj%struct%NodCoord( node_id  ,:)
         !    ! 節先端部までの方向ベクトル
         !    vec(:) =  obj%struct%NodCoord( node_id2 ,:) - obj%struct%NodCoord( node_id  ,:)
         !    ! 節基部へ移動
         !    call obj%root_list(1)%move(x=-obj%seed_width/12.0d0,y=-obj%seed_width/12.0d0,&
         !        z=-obj%seed_length/8.0d0)
         !    call obj%root_list(1)%move(x=loc(1),y=loc(2),z=loc(3) )
         !    zaxis(:)=0.0d0
         !    zaxis(3)=obj%seed_length/5.0d0
         !    rot(:) = angles(zaxis,vec)
         !    !call obj%root_list(1)%rotate(x=rot(1),y=rot(2),z=rot(3) )
         !    print *, "loc",loc
         !    print *, "vec",vec
         !    print *, "rot",rot
      end if

      ! ここからレガシーモード
      if (present(regacy)) then
         if (regacy .eqv. .true.) then
            obj%Stage = "VE"
            if (present(FileName)) then
               fn = FileName
            else
               fn = "untitled"
            end if

            loc(:) = 0.0d0

            if (present(x)) then
               loc(1) = x
            end if

            if (present(y)) then
               loc(2) = y
            end if

            if (present(z)) then
               loc(3) = z
            end if

            if (present(location)) then
               loc(:) = location(:)
            end if

            ! initialize RootSystem and NodeSystem
            if (.not. allocated(obj%RootSystem)) then
               allocate (obj%RootSystem(input(default=1000, option=max_PlantNode_num)))
               obj%num_of_root = 1
            end if
            if (.not. allocated(obj%NodeSystem)) then
               allocate (obj%NodeSystem(input(default=1000, option=max_PlantNode_num)))
               obj%num_of_node = 1
            end if

            ! setup seed
            if (Variety == "Tachinagaha" .or. Variety == "tachinagaha") then
               call obj%Seed%init(mass=mass, width1=9.70d0, width2=8.20d0, &
                                  width3=7.70d0, &
                                  water_content=water_content, radius=radius, location=loc)
               call obj%Seed%createMesh(FileName=fn//".stl", &
                                        ElemType="Tetrahedra")

               call obj%Seed%convertMeshType(Option="TetraToHexa")

            else
               print *, "Variety name :: is not implemented."
               stop
            end if

            ! setup primary node (plumule)
            call obj%NodeSystem(1)%init(Stage=obj%Stage, &
                                        Plantname="Rice", location=loc)

            ! setup primary node (radicle))
            MaxThickness = input(default=0.20d0, &
                                 option=PlantRoot_diameter_per_seed_radius)*obj%Seed%radius
            Maxwidth = input(default=0.20d0, &
                             option=PlantRoot_diameter_per_seed_radius)*obj%Seed%radius
            call obj%RootSystem(1)%init(Plantname="Rice", &
                                        Stage=obj%Stage, MaxThickness=MaxThickness, Maxwidth=Maxwidth, location=loc)

            obj%time = 0.0d0
            return
         end if
      end if

   end subroutine
! ########################################

! ########################################
   subroutine growRice(obj, dt, light, air, temp)
      class(Rice_), intent(inout) :: obj
      type(Light_), optional, intent(inout) :: light
      type(air_), optional, intent(in) :: air
      real(real64), optional, intent(in) :: temp
      real(real64), intent(in) :: dt! time-interval
      real(real64) :: ac_temp ! time-interval
      integer(int32) :: i

      obj%dt = dt

      ! 光量子量を計算
      call obj%laytracing(light=light)

      ! 光合成量を計算
      do i = 1, size(obj%Leaf)
         if (obj%Leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%leaf(i)%photosynthesis(dt=dt, air=air)
         end if
      end do

      ! シンクソース輸送を計算
      call obj%SinkSourceFlow()

      ! ソースの消耗、拡散を計算
      !call obj%source2sink()

      ! 伸長を計算
      !call obj%extention()

      ! 分化を計算、構造の更新
      !call obj%development()

   end subroutine
! ########################################

   subroutine SinkSourceFlowRice(obj)
      class(Rice_), intent(inout) :: obj
      type(DiffusionEq_) :: DiffusionEq

      !DiffusionEq%femdomain => obj%femdomain

   end subroutine

! ########################################
   subroutine WaterAbsorptionRice(obj, temp, dt)
      class(Rice_), intent(inout) :: obj
      real(real64), intent(in) :: temp, dt
      real(real64) :: a, b, c, d, AA, BB, w1max, w2max, w3max, time
      real(real64) :: x_rate, y_rate, z_rate, wx, wy, wz

      obj%time = obj%time + dt

      ! tested by tachinagaha, 2019
      a = 0.00910d0
      b = -1.76450d0
      c = 3.32E-04
      d = -0.0905180d0
      AA = a*temp + b
      !BB=c*exp(d*temp)
      BB = c*temp + d
      ! width1 becomes 1.7 times, width2 becomes 1.2, width3 becomes 1.1
      w1max = 1.70d0
      w2max = 1.20d0
      w3max = 1.10d0
      obj%seed%width1 = obj%seed%width1_origin*(w1max - AA*exp(-BB*obj%time))
      obj%seed%width2 = obj%seed%width2_origin*(w2max - AA*exp(-BB*obj%time))
      obj%seed%width3 = obj%seed%width3_origin*(w3max - AA*exp(-BB*obj%time))

      ! linear model; it should be changed in near future.
      if (obj%time > 60.0d0*6.0d0) then
         obj%seed%width2 = obj%seed%width2_origin*(w2max)
         obj%seed%width3 = obj%seed%width3_origin*(w3max)
      else
         obj%seed%width2 = obj%seed%width2_origin + obj%seed%width2_origin*(w2max - 1.0d0)*(obj%time)/(60.0d0*6.0d0)
         obj%seed%width3 = obj%seed%width3_origin + obj%seed%width3_origin*(w3max - 1.0d0)*(obj%time)/(60.0d0*6.0d0)
      end if

      wx = maxval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 1)) - minval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 1))
      wy = maxval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 2)) - minval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 2))
      wz = maxval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 3)) - minval(obj%Seed%FEMDomain%Mesh%NodCoord(:, 3))
      print *, wx, wy, wz
      x_rate = 1.0d0/wx
      y_rate = 1.0d0/wy
      z_rate = 1.0d0/wz
      call obj%Seed%FEMDomain%resize(x_rate=x_rate, y_rate=y_rate, z_rate=z_rate)
      x_rate = obj%seed%width1
      y_rate = obj%seed%width2
      z_rate = obj%seed%width3
      call obj%Seed%FEMDomain%resize(x_rate=x_rate, y_rate=y_rate, z_rate=z_rate)

   end subroutine
! ########################################

! ########################################
   subroutine exportRice(obj, FilePath, FileName, SeedID, withSTL, withMesh)
      class(Rice_), intent(inout) :: obj
      character(*), optional, intent(in) :: FilePath
      character(*), intent(in) :: FileName
      integer(int32), optional, intent(inout) :: SeedID
      logical, optional, intent(in) :: withSTL, withMesh
      integer(int32) :: i, itr

      itr = SeedID
      ! if seed exists => output
      if (obj%Seed%num_of_seed >= 0) then
         if (present(withSTL)) then
            if (withSTL .eqv. .true.) then
               call obj%Seed%export(FileName=FileName, SeedID=itr, extention=".stl")
            end if
         end if
         if (present(withMesh)) then
            if (withMesh .eqv. .true.) then
               call obj%Seed%export(FileName=FileName, SeedID=itr, extention=".pos")
            end if
         end if

         if (present(FilePath)) then
            call obj%Seed%export(FileName=FilePath//"/seed.geo", SeedID=itr)
         else
            call obj%Seed%export(FileName=FileName, SeedID=itr)
         end if
      end if

      itr = itr + 1
      ! export NodeSystem
      do i = 1, size(obj%NodeSystem)

         if (present(FilePath)) then
            call obj%NodeSystem(i)%export(FileName=FilePath//"/Node.geo", objID=itr)
         else
            call obj%NodeSystem(i)%export(FileName=FileName//"_Node.geo", objID=itr)
         end if
         if (i == obj%num_of_node) then
            exit
         end if
      end do

      ! export RootSystem
      do i = 1, size(obj%RootSystem)

         if (present(FilePath)) then
            call obj%RootSystem(i)%export(FileName=FilePath//"/Root.geo", RootID=itr)
         else
            call obj%RootSystem(i)%export(FileName=FileName//"_Root.geo", RootID=itr)
         end if
         if (i == obj%num_of_root) then
            exit
         end if
      end do
      SeedID = itr

   end subroutine
! ########################################

! ########################################

! ########################################
!subroutine initRice(obj,growth_habit,Max_Num_of_Node)
!    class(Rice_) :: obj
!    character(*),optional,intent(in) :: growth_habit
!    integer(int32),optional,intent(in)::Max_Num_of_Node
!    integer(int32) ::n
!
!    if(present(growth_habit) )then
!        obj%growth_habit=growth_habit
!    else
!        obj%growth_habit="determinate"
!    endif
!
!    obj%growth_stage="VE"
!
!    n=input(default=100,option=Max_Num_of_Node)
!
!    allocate(obj%NodeSystem(n))
!    obj%NumOfNode=0
!    obj%NumOfRoot=0
!
!    ! set an initial node and root
!    ! two leaves, one root.
!
!    call obj%AddNode()
!
!end subroutine
!! ########################################
!
!
!
!
!
!
!! ########################################
!subroutine AddNodeRice(obj,SizeRatio)
!    class(Rice_),intent(inout)::obj
!    real(real64),optional,intent(in)::SizeRatio
!    real(real64) :: magnif
!
!    magnif=input(default=1.0d0,option=SizeRatio)
!    obj%NumOfNode=obj%NumOfNode+1
!
!    ! add leaves
!    if(obj%NumOfNode==1 .or. obj%NumOfNode==2)then
!        allocate(obj%NodeSystem(obj%NumOfNode)%leaf(2) )
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=3.0d0*magnif,width=2.0d0*magnif)
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=3.0d0*magnif,width=2.0d0*magnif)
!    else
!        allocate(obj%NodeSystem(obj%NumOfNode)%leaf(3) )
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=4.0d0*magnif,width=2.0d0*magnif)
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=4.0d0*magnif,width=2.0d0*magnif)
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=4.0d0*magnif,width=2.0d0*magnif)
!    endif
!
!    ! add stem
!    if(obj%NumOfNode==1 .or. obj%NumOfNode==2)then
!        allocate(obj%NodeSystem(obj%NumOfNode)%Stem(1) )
!        call obj%NodeSystem(obj%NumOfNode)%leaf(1)%init(thickness=0.10d0*magnif,length=3.0d0*magnif,width=2.0d0*magnif)
!    endif
!
!    ! add Peti
!    if(obj%NumOfNode==1 .or. obj%NumOfNode==2)then
!        allocate(obj%NodeSystem(obj%NumOfNode)%Peti(1) )
!        call obj%NodeSystem(obj%NumOfNode)%Peti(1)%init(thickness=0.10d0*magnif,length=3.0d0*magnif,width=2.0d0*magnif)
!    endif
!
!end subroutine
!! ########################################
!

! ########################################
   subroutine showRice(obj, name)
      class(Rice_), intent(inout) :: obj
      character(*), intent(in)::name

      if (obj%struct%empty() .eqv. .true.) then
         print *, "Error :: showRice>> no structure is imported."
         return
      end if

      call obj%struct%export(name=name)

   end subroutine
! ########################################

! ########################################
   function numleafRice(obj) result(ret)
      class(Rice_), intent(in) :: obj
      integer(int32) :: ret, i

      ret = 0
      do i = 1, size(obj%leaf_list)
         if (obj%leaf_list(i)%Mesh%empty() .eqv. .false.) then
            ret = ret + 1
         end if
      end do

   end function
! ########################################

! ########################################
   function numstemRice(obj) result(ret)
      class(Rice_), intent(in) :: obj
      integer(int32) :: ret, i

      ret = 0
      do i = 1, size(obj%stem_list)
         if (obj%stem_list(i)%Mesh%empty() .eqv. .false.) then
            ret = ret + 1
         end if
      end do

   end function
! ########################################

! ########################################
   function numrootRice(obj) result(ret)
      class(Rice_), intent(in) :: obj
      integer(int32) :: ret, i

      ret = 0
      do i = 1, size(obj%root_list)
         if (obj%root_list(i)%Mesh%empty() .eqv. .false.) then
            ret = ret + 1
         end if
      end do

   end function
! ########################################

! ########################################
   subroutine gmshRice(obj, name)
      class(Rice_), intent(inout) :: obj
      character(*), intent(in) :: name
      integer(int32) :: i

      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%stem(i)%gmsh(name=name//"_stem"//str(i))
         end if
      end do

      do i = 1, size(obj%root)
         if (obj%root(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%root(i)%gmsh(name=name//"_root"//str(i))
         end if
      end do

      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%leaf(i)%gmsh(name=name//"_leaf"//str(i))
         end if
      end do

   end subroutine
! ########################################

! ########################################
   subroutine mshRice(obj, name)
      class(Rice_), intent(inout) :: obj
      character(*), intent(in) :: name
      integer(int32) :: i

      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%stem(i)%msh(name=name//"_stem"//str(i))
         end if
      end do

      do i = 1, size(obj%root)
         if (obj%root(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%root(i)%msh(name=name//"_root"//str(i))
         end if
      end do

      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%leaf(i)%msh(name=name//"_leaf"//str(i))
         end if
      end do

   end subroutine
! ########################################

! ########################################
   subroutine jsonRice(obj, name)
      class(Rice_), intent(inout) :: obj
      character(*), intent(in) :: name
      integer(int32) :: i, countnum
      type(IO_) :: f

      call f%open(name//".json")
      call f%write("{")
      countnum = 0
      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            countnum = countnum + 1
            call f%write('"'//"stem"//str(i)//'":')
            call obj%stem(i)%femdomain%json(name=name//"_stem"//str(i), fh=f%fh, endl=.false.)
         end if
      end do
      call f%write('"num_stem":'//str(countnum)//',')

      countnum = 0
      do i = 1, size(obj%root)
         if (obj%root(i)%femdomain%mesh%empty() .eqv. .false.) then
            countnum = countnum + 1
            call f%write('"'//"root"//str(i)//'":')
            call obj%root(i)%femdomain%json(name=name//"_root"//str(i), fh=f%fh, endl=.false.)
         end if
      end do
      call f%write('"num_root":'//str(countnum)//',')

      countnum = 0
      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            countnum = countnum + 1
            call f%write('"'//"leaf"//str(i)//'":')
            call obj%leaf(i)%femdomain%json(name=name//"_leaf"//str(i), fh=f%fh, endl=.false.)
         end if
      end do
      call f%write('"num_leaf":'//str(countnum)//',')
      call f%write('"return_Rice":0')
      call f%write("}")
      call f%close()
   end subroutine
! ########################################

! ########################################
   subroutine stlRice(obj, name)
      class(Rice_), intent(inout) :: obj
      character(*), intent(in) :: name
      integer(int32) :: i

      !call execute_command_line("echo ' ' > "//name//".stl")
      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%stem(i)%stl(name=name//"_stem"//str(i))
            !call execute_command_line("cat "//name//"_stem"//str(i)//"_000001.stl >> "//name//".stl")
         end if
      end do

      do i = 1, size(obj%root)
         if (obj%root(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%root(i)%stl(name=name//"_root"//str(i))
            !call execute_command_line("cat "//name//"_root"//str(i)//"_000001.stl >> "//name//".stl")
         end if
      end do

      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%leaf(i)%stl(name=name//"_leaf"//str(i))
            !call execute_command_line("cat "//name//"_leaf"//str(i)//"_000001.stl >> "//name//".stl")
         end if
      end do

   end subroutine
! ########################################

! ########################################
   subroutine moveRice(obj, x, y, z)
      class(Rice_), intent(inout) :: obj
      real(real64), optional, intent(in) :: x, y, z
      integer(int32) :: i

      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%stem(i)%move(x=x, y=y, z=z)
         end if
      end do

      do i = 1, size(obj%root)
         if (obj%root(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%root(i)%move(x=x, y=y, z=z)
         end if
      end do

      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            call obj%leaf(i)%move(x=x, y=y, z=z)
         end if
      end do

   end subroutine
! ########################################

! ########################################
   subroutine laytracingRice(obj, light)
      class(Rice_), intent(inout) :: obj
      type(Light_), intent(in) :: light
      real(real64), allocatable :: stemcenter(:, :), stemradius(:)
      real(real64), allocatable :: leafcenter(:, :), leafradius(:)
      real(real64), allocatable :: elemnodcoord(:, :), x(:), x2(:)
      real(real64) :: max_PPFD, r, rc, r0
      real(real64), parameter :: extinction_ratio = 100.0d0 ! ratio/m
      !real(real64),parameter :: radius_ratio = 0.01d0 ! radius_of_gauss_point/element_length
      type(IO_) :: f
      integer(int32) :: i, j, n, num_particle, k, l, nodeid, m, totcount

      max_PPFD = light%maxPPFD
      ! 総当りで、総遮蔽長を割り出す
      ! 茎は光を通さない、葉は透過率あり、空間は透過率ゼロ
      ! 要素中心から頂点への平均長さを半径に持ち、要素中心を中心とする球
      ! を考え、Layとの公差判定を行う。
      num_particle = 0
      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            num_particle = num_particle + size(obj%leaf(i)%femdomain%mesh%ElemNod, 1)
         end if
      end do
      allocate (leafcenter(num_particle, 3), leafradius(num_particle))
      leafcenter(:, :) = 0.0d0
      leafradius(:) = 0.0d0

      num_particle = 0
      do i = 1, size(obj%leaf)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            num_particle = num_particle + size(obj%stem(i)%femdomain%mesh%ElemNod, 1)
         end if
      end do
      allocate (stemcenter(num_particle, 3), stemradius(num_particle))
      stemcenter(:, :) = 0.0d0
      stemradius(:) = 0.0d0

      num_particle = 0

      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            n = size(obj%leaf(i)%femdomain%mesh%Elemnod, 2)
            m = size(obj%leaf(i)%femdomain%mesh%Nodcoord, 2)
            allocate (elemnodcoord(n, m))
            allocate (x(m))
            do j = 1, size(obj%leaf(i)%femdomain%mesh%elemnod, 1)
               do k = 1, size(obj%leaf(i)%femdomain%mesh%elemnod, 2)
                  nodeid = obj%leaf(i)%femdomain%mesh%elemnod(j, k)
                  elemnodcoord(k, :) = obj%leaf(i)%femdomain%mesh%Nodcoord(nodeid, :)
               end do
               num_particle = num_particle + 1
               do k = 1, size(elemnodcoord, 1)
                  do l = 1, size(elemnodcoord, 2)
                     leafcenter(num_particle, l) = &
                        +leafcenter(num_particle, l) &
                        + 1.0d0/dble(size(elemnodcoord, 1))*elemnodcoord(k, l)
                  end do
               end do
               do k = 1, size(elemnodcoord, 1)
                  x(:) = elemnodcoord(k, :)
                  x(:) = x(:) - leafcenter(num_particle, :)
                  if (k >= 2 .and. leafradius(num_particle) > sqrt(dot_product(x, x))) then
                     leafradius(num_particle) = sqrt(dot_product(x, x))
                  elseif (k == 1) then
                     leafradius(num_particle) = sqrt(dot_product(x, x))
                  else
                     cycle
                  end if
               end do
            end do
            deallocate (elemnodcoord)
            deallocate (x)
         end if
      end do

      num_particle = 0
      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .false.) then
            n = size(obj%stem(i)%femdomain%mesh%Elemnod, 2)
            m = size(obj%stem(i)%femdomain%mesh%Nodcoord, 2)
            allocate (elemnodcoord(n, m))
            allocate (x(m))
            do j = 1, size(obj%stem(i)%femdomain%mesh%elemnod, 1)
               do k = 1, size(obj%stem(i)%femdomain%mesh%elemnod, 2)
                  nodeid = obj%stem(i)%femdomain%mesh%elemnod(j, k)
                  elemnodcoord(k, :) = obj%stem(i)%femdomain%mesh%Nodcoord(nodeid, :)
               end do
               num_particle = num_particle + 1
               do k = 1, size(elemnodcoord, 1)
                  do l = 1, size(elemnodcoord, 2)
                     stemcenter(num_particle, l) = &
                        +stemcenter(num_particle, l) &
                        + 1.0d0/dble(size(elemnodcoord, 1))*elemnodcoord(k, l)
                  end do
               end do
               do k = 1, size(elemnodcoord, 1)
                  x(:) = elemnodcoord(k, :)
                  x(:) = x(:) - stemcenter(num_particle, :)
                  !最小半径で考える
                  if (k >= 2 .and. stemradius(num_particle) > sqrt(dot_product(x, x))) then
                     stemradius(num_particle) = sqrt(dot_product(x, x))
                  elseif (k == 1) then
                     stemradius(num_particle) = sqrt(dot_product(x, x))
                  else
                     cycle
                  end if
               end do
            end do
            deallocate (elemnodcoord)
            deallocate (x)
         end if
      end do

      ! DEBUG
      call f%open("leaf.txt")
      do i = 1, size(leafcenter, 1)
         write (f%fh, *) leafcenter(i, :)
      end do
      call f%close()

      call f%open("stem.txt")
      do i = 1, size(stemcenter, 1)
         write (f%fh, *) stemcenter(i, :)
      end do
      call f%close()

      allocate (x(3), x2(3))

      num_particle = 0
      totcount = 0
      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            ! 葉あり
            obj%leaf(i)%PPFD(:) = max_PPFD
            do j = 1, size(obj%leaf(i)%PPFD)
               totcount = totcount + 1
               num_particle = num_particle + 1
               ! それぞれの要素について、遮蔽particleを探索
               ! 茎:全減衰
               ! 葉:半減衰
               ! 簡単のため上からのみ
               ! x-yのみについて見て、上方かつx-y平面距離が半径以内で覆陰判定
               x(:) = leafcenter(num_particle, :)
               r0 = leafradius(num_particle)
               ! 枝による覆陰判定

               do k = 1, size(stemcenter, 1)
                  x2(:) = stemcenter(k, :)
                  r = stemradius(k)
                  rc = (x(1) - x2(1))**(2.0d0) + (x(2) - x2(2))**(2.0d0)
                  rc = sqrt(rc)
                  if (rc <= r0 + r .and. x(3) < x2(3)) then
                     ! 茎により覆陰されてる
                     obj%leaf(i)%PPFD(j) = 0.0d0
                     exit
                  end if
               end do
               if (obj%leaf(i)%PPFD(j) == 0.0d0) then
                  cycle
               end if

               do k = 1, size(leafcenter, 1)
                  ! もし自信だったら除外
                  if (totcount == k) then
                     cycle
                  end if

                  x2(:) = leafcenter(k, :)
                  r = leafradius(k)
                  rc = (x(1) - x2(1))**(2.0d0) + (x(2) - x2(2))**(2.0d0)
                  rc = sqrt(rc)
                  if (rc <= (r0 + r)/2.0d0 .and. x(3) < x2(3)) then
                     ! 茎により覆陰されてる
                     obj%leaf(i)%PPFD(j) = &
                        obj%leaf(i)%PPFD(j)*(1.0d0 - extinction_ratio*2.0d0*r)
                     if (obj%leaf(i)%PPFD(j) <= 0.0d0) then
                        obj%leaf(i)%PPFD(j) = 0.0d0
                     end if
                  end if
               end do

            end do
         end if
      end do

      call f%open("PPFD.txt")
      do i = 1, size(obj%leaf)
         if (obj%leaf(i)%femdomain%mesh%empty() .eqv. .false.) then
            ! 葉あり
            do j = 1, size(obj%leaf(i)%PPFD, 1)
               write (f%fh, *) obj%leaf(i)%PPFD(j), "leaf_id: ", str(i), "elem_id: ", str(j)
            end do
         end if
      end do
      call f%close()

   end subroutine
! ########################################

   subroutine addStemRice(obj, stemid, rotx, roty, rotz, json)
      class(Rice_), intent(inout) :: obj
      integer(int32), intent(in) :: stemid
      character(*), optional, intent(in) :: json
      real(real64), optional, intent(in) :: rotx, roty, rotz
      integer(int32) :: i

      ! add a stem after stem(stemid)
      do i = 1, size(obj%stem)
         if (obj%stem(i)%femdomain%mesh%empty() .eqv. .true.) then
            if (present(json)) then
               call obj%stem(i)%init(json)
               call obj%stem(i)%rotate(x=rotx, y=roty, z=rotz)
               call obj%stem(i)%connect("=>", obj%stem(stemid))
               return
            else
               call obj%stem(i)%init()
               call obj%stem(i)%rotate(x=rotx, y=roty, z=rotz)
               call obj%stem(i)%connect("=>", obj%stem(stemid))
               return
            end if
         else
            cycle
         end if
      end do

   end subroutine

end module