Fortran不定大小的数组被subroutine调用是否可以?
生活随笔
收集整理的這篇文章主要介紹了
Fortran不定大小的数组被subroutine调用是否可以?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
寫一段代碼,從實驗數據文件中,選取elab在limit1和limit2之間的實驗數據存到type為struct_expt_data的數組中,然后再找出不同的elab值,存到elist數組中。
實驗數據格式如下,其中第二列為elab:
由于事先不知道處于limit1和limit2之間的實驗數據個數,所以先聲明不定大小的數組,然后用subroutine找出數組元素個數,然后allocate數組,然后再call一次subroutine寫入元素,這樣上面的每個步驟需要call兩次,allocate一次,代碼如下:
module aa integer,parameter :: NER = kind(0.0d0)type :: struct_Expt_Datacharacter(len=6) :: Refcharacter(len=4) :: obsNamereal(NER) :: acm, elab, val, errorinteger :: ii ! ii is the the sequence number of elab list.end type struct_Expt_Data type :: data_chaincharacter(len=6) :: Refcharacter(len=4) :: obsNamereal(NER) :: acm, elab, val, errortype(data_chain),pointer :: nextend type data_chain end module aa module getdata use aa implicit none contains subroutine get_numdata(numdata,limit1,limit2)character(len=4) :: obsnamereal(NER) :: elab,acm,val,errorcharacter(len=6) :: ref integer :: numdata real(NER) :: limit1,limit2integer :: ii integer :: istatnumdata=0open(unit=330,file="all_data.dat",iostat=istat)do read(330,*,iostat=istat) obsname,elab write(*,*) obsname , elabif (istat /= 0) exitif (elab >= limit1 .and. elab <= limit2) numdata = numdata + 1end do close(330) end subroutine get_numdatasubroutine get_data(expt_data,numdata,limit1,limit2)character(len=4) :: obsnamereal(NER) :: elab,acm,val,errorcharacter(len=6) :: ref type(struct_Expt_Data) :: expt_data(:)integer :: numdata real(NER) :: limit1,limit2integer :: ii integer :: istatopen(unit=330,file="all_data.dat")ii=0do read(330,*,iostat=istat) obsname,elab,acm,val,error,ref if (istat /= 0 ) exit if(elab >= limit1 .and. elab <= limit2) thenii = ii + 1expt_data(ii)%obsname = obsname expt_data(ii)%elab = elab expt_data(ii)%acm = acm expt_data(ii)%val = val expt_data(ii)%error = error expt_data(ii)%ref = ref end if end do close(330)if (ii==numdata) write(*,*) "right numdata"end subroutine get_data subroutine get_numk(numk,expt_data,numdata)type(data_chain),pointer :: head,tail,ptr,ptr1,ptr2real(NER) :: elab character(len=4) :: obsnameinteger :: numk type(struct_Expt_Data) :: expt_data(:)integer :: numdatainteger :: ii,istatnullify(head,tail,ptr,ptr1,ptr2)numk = 0do ii=1,numdataelab = expt_data(ii)%elab if (.not. associated(head)) thenallocate(ptr,stat=istat)numk=numk+1ptr%elab = elab head => ptr tail => headnullify(ptr%next)else if (elab < head%elab-0.0001) thenallocate(ptr,stat=istat)numk=numk+1ptr%elab = elab ptr%next => head head => ptr else if (elab > tail%elab+0.0001) then allocate(ptr,stat=istat)numk=numk+1ptr%elab = elab tail%next => ptrtail => ptr nullify(ptr%next)else ptr1 => head if ( .not. (elab-ptr1%elab)<=0.0001) then ptr2 => ptr1%nextdo if (abs(elab-ptr2%elab)<=0.0001) exit if ( (elab > ptr1%elab +0.0001) .and. (elab < ptr2%elab - 0.0001)) thenallocate(ptr,stat=istat)numk=numk+1ptr%elab = elab ptr%next => ptr2 ptr1%next => ptr exitend if ptr1 => ptr2ptr2 => ptr1%nextend do end if end if end do end subroutine get_numksubroutine get_elist(elist,numk,expt_data,numdata)integer :: numkreal(NER) :: elist(:)real(NER) :: elab type(data_chain),pointer :: head,tail,ptr,ptr1,ptr2integer :: ii , istattype(struct_Expt_Data) :: expt_data(:)integer :: numdatanullify(head,tail,ptr,ptr1,ptr2)do ii=1,numdataelab = expt_data(ii)%elab if (.not. associated(head)) thenallocate(ptr,stat=istat)ptr%elab = elab head => ptr tail => headnullify(ptr%next)else if (elab < head%elab-0.0001) thenallocate(ptr,stat=istat)ptr%elab = elab ptr%next => head head => ptr else if (elab > tail%elab+0.0001) then allocate(ptr,stat=istat)ptr%elab = elab tail%next => ptrtail => ptr nullify(ptr%next)else ptr1 => head if ( .not. (elab-ptr1%elab)<=0.0001) then ptr2 => ptr1%nextdo if (abs(elab-ptr2%elab)<=0.0001) exit if ( (elab > ptr1%elab +0.0001) .and. (elab < ptr2%elab - 0.0001)) thenallocate(ptr,stat=istat)ptr%elab = elab ptr%next => ptr2 ptr1%next => ptr exitend if ptr1 => ptr2ptr2 => ptr1%nextend do end if end ifend do ptr => headdo ii=1,numk elist(ii) = head%elab head => head%next end do end subroutine get_elist end module program main use getdataimplicit none type(struct_Expt_Data),allocatable :: expt_data(:)real(NER),allocatable :: elist(:)integer :: numdata , numk real(NER) :: limit1,limit2integer :: ii limit1=3.limit2=5.call get_numdata(numdata,limit1,limit2)write(*,*) "numdata= ",numdataallocate(expt_data(numdata))call get_data(expt_data,numdata,limit1,limit2)call get_numk(numk,expt_data,numdata)allocate(elist(numk))call get_elist(elist,numk,expt_data,numdata)write(*,*) elistend是否有簡單的方法一步做到?
總結
以上是生活随笔為你收集整理的Fortran不定大小的数组被subroutine调用是否可以?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚无主义还是怀疑论?
- 下一篇: 整理的开学需要准备的物品清单,删了怪可惜