! GetPattern.f90 ! written by Tim Mitchell on 02.10.01 ! last modified on 20.11.01 ! program to construct response pattern(s) from grim files and dump them to grip file(s) ! designed using the linked list concept: to understand, inspect type sim ! f90 -lnagfl90 -I/sw7/nag90/nagfl90 -o ./../grim/getpattern filenames.f90 time.f90 grimfiles.f90 annfiles.f90 ! glofiles.f90 regress.f90 ./../grim/getpattern.f90 ! note that for .wet .pre .frs the program auto calcs sums, not means, for seasons and years ! the method has been changed to smooth at PerLen rather than use overlapping slices program GetPattern use nag_lin_reg, ONLY : nag_mult_lin_reg use FileNames use Time use GrimFiles use AnnFiles use GloFiles use Regress implicit none character (len=80), parameter :: SpecFile = "/cru/mikeh1/f709762/f90/grim/_ref/ops/getpattern.57.ops.X" type Exec character (len=20) :: Name ! execution name type (Exec), pointer :: Prev ! prev execution defined: recursion type (Exec), pointer :: Next ! next execution defined: recursion character (len=80), pointer, dimension (:) :: SimName, SimFile ! sim name and path: SimN character (len=80), pointer, dimension (:) :: SimGloT ! sim GloT path: SimN character (len=80), pointer, dimension (:) :: SimEquT ! sim equilib T path: SimN character (len=80) :: KayFile, KayInfo ! save file and info character (len=80) :: BaseFile ! base file from which to anomalise end type Exec type Sim character (len=20) :: Name ! simulation name type (Sim), pointer :: Prev ! prev simulation defined: recursion type (Sim), pointer :: Next ! next simulation defined: recursion integer :: YearN ! no. of years in array real, pointer, dimension (:,:,:) :: Data ! grim file: YearN,SeasonN,BoxN real, pointer, dimension (:) :: GloT ! .ann file: YearN real, pointer, dimension (:) :: EquT ! .ann file: YearN end type Sim type (Exec), pointer :: OneExec, CurrentExec, StackExec type (Sim), pointer :: OneSim, CurrentSim, StackSim integer, parameter :: MLRtype = KIND(1.0D0) real (MLRtype), allocatable, dimension (:) :: Response, Coefficients, Weight real (MLRtype), allocatable, dimension (:,:) :: Predictor real, pointer, dimension (:,:,:) :: FileData real, pointer, dimension (:,:) :: FileGloT, FileEquT, BaseData real, pointer, dimension (:,:) :: Kay1, Kay2, CurrentKay ! the arrays of k: SeasonN, BoxN real, pointer, dimension (:) :: GloVector, Array1D, TSLowVec, TSHighVec integer, pointer, dimension (:,:) :: Grid, FileGrid integer, pointer, dimension (:) :: YearAD, FileYearAD, GloTYearAD, EquTYearAD character (len=80), pointer, dimension (:,:) :: BinFile, BinGloT, BinEquT character (len=20), pointer, dimension (:,:) :: BinName character (len=09), pointer, dimension (:) :: AnnNames real, dimension (4) :: Bounds, FileBounds integer, dimension (12), parameter :: SeasonMonths = [3,4,5,6,7,8,9,10,11,12,1,2] character (len=3), dimension (17), parameter :: SeasonNames = ['jan','feb','mar','apr','may','jun','jul',& 'aug','sep','oct','nov','dec','MAM','JJA','SON','DJF','ann'] real, parameter :: MissVal = -999.0 integer, parameter :: SeasonN=17, MonthN=12, BoundN=4 character (len=80), parameter :: Blank = "" real :: MissAccept real :: OpTot, OpMiss, OpEn integer :: AllocStat, ReadStatus integer :: YearN,ExecN,XSim,AllYearN, BoxN, ExeN, WyeN, FileYearN integer :: XYear,XExec,SimN,XAllYear, XBox, XExe, XWye, XBound, XFileYear, XSeason, XMonth, XKay integer :: PredictorN, CheckBoxN integer :: QMethod, QDumpGlo, QHalt, QSimLoaded, QRestrictPer, QMeanSum integer :: PerLen, GapLen, YearLimit, YearAD0,YearAD1 integer :: Year0,Year1, FileYear0,FileYear1, ThisMonth,ThisYear integer :: CheckGrid, MissThresh, SuffixStart character (len=80) :: FileInfo, GloRefFile, GloFile, GloInfo, GripFile, GripInfo character (len=20) :: FindName character (len= 4) :: Suffix, FileSuffix, SaveSuffix, KaySuffix, Variable !******************************************************************************* call Intro ! initialises, loads command file, allocates Exec call ResetCurrentExec ! points CurrentExec back to the first exec do if (associated(CurrentExec%Prev)) CurrentExec => CurrentExec%Next ! not 1st exec, so next exec print*, " > Execution: ", CurrentExec%Name Variable = trim(CurrentExec%Name) if (Variable.EQ.".wet".OR.Variable.EQ.".pre".OR.Variable.EQ.".frs") then QMeanSum = 2 else QMeanSum = 1 end if call LoadSims call CalcPatterns if (.not.associated(CurrentExec%Next)) exit ! last exec, so exit loop end do call Finish contains !******************************************************************************* subroutine Intro open (99,file="/cru/mikeh1/f709762/scratch/log/log-getpattern.dat",status="replace",action="write") print* print*, " > ***** GetPattern: constructs response patterns *****" print* print*, " > Spec file: ", trim(SpecFile) print* open (1,file=SpecFile,status="old",access="sequential",form="unformatted",action="read") read (1), ExecN, SimN, BoxN, ExeN, WyeN read (1), PerLen, GapLen, MissAccept, QMethod, QDumpGlo, YearAD0, YearAD1 read (1), (Bounds(XBound),XBound=1,4) read (1), GloRefFile if (YearAD0.NE.MissVal.AND.YearAD1.NE.MissVal) then YearN = YearAD1 - YearAD0 + 1 allocate (YearAD (YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: YearAD #####" do XYear = 1, YearN YearAD (XYear) = YearAD0 + XYear - 1 end do QRestrictPer = 1 else YearN = MissVal QRestrictPer = 0 end if allocate (Grid (ExeN,WyeN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: Grid #####" do XExe = 1, ExeN read (1), (Grid(XExe,XWye), XWye=1,WyeN) end do allocate (BinName (ExecN,SimN), & BinFile (ExecN,SimN), & BinGloT (ExecN,SimN), & BinEquT (ExecN,SimN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: Bin* #####" do XExec = 1, ExecN allocate (OneExec, & OneExec%SimName (SimN), & OneExec%SimFile (SimN), & OneExec%SimGloT (SimN), & OneExec%SimEquT (SimN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Allocation failure: OneExec #####" read (1), OneExec%Name, OneExec%KayFile, OneExec%KayInfo, OneExec%BaseFile do XSim = 1, SimN read (1), BinName (XExec,XSim) read (1), BinFile (XExec,XSim) read (1), BinGloT (XExec,XSim) read (1), BinEquT (XExec,XSim) OneExec%SimName (XSim) = BinName (XExec,XSim) OneExec%SimFile (XSim) = BinFile (XExec,XSim) OneExec%SimGloT (XSim) = BinGloT (XExec,XSim) OneExec%SimEquT (XSim) = BinEquT (XExec,XSim) end do if (XExec.EQ.1) then nullify(OneExec%Prev) nullify(OneExec%Next) else OneExec%Prev => CurrentExec CurrentExec%Next => OneExec nullify(OneExec%Next) end if CurrentExec => OneExec end do close (1) deallocate (BinName,BinFile,BinGloT,BinEquT, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Intro: Deallocation failure: Bin* #####" end subroutine Intro !******************************************************************************* subroutine LoadSims call GetBaseData do XSim = 1, SimN call LoadSimGrim call LoadSimGloTS write (99,*), "anomalising and smoothing...." ! ########################### call AnomSmoothSim if (XSim.EQ.1) then nullify(OneSim%Prev) nullify(OneSim%Next) else OneSim%Prev => CurrentSim CurrentSim%Next => OneSim nullify(OneSim%Next) end if CurrentSim => OneSim print*, " > Have loaded sim: ", trim(CurrentExec%SimName(XSim)) end do deallocate (BaseData,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSims: Deallocation failure: BaseData #####" end subroutine LoadSims !******************************************************************************* ! option ( 1): assumed relationship: Vy = k1*Ty ! Vy=box-season-anom, Ty=globalT-anom ! option (11): assumed relationship: Vy = k1*Ty + (Te-Ty)*k2 ! Vy=box-season-anom, Ty=globalTanom, Te=equilTanom subroutine CalcPatterns write (99,*), "calc allyearn..." ! ######################## call CalcAllYearN if (QMethod.EQ. 1) PredictorN = 1 if (QMethod.EQ.11) PredictorN = 2 allocate (Predictor (AllYearN,PredictorN), & Response (AllYearN), & Weight (AllYearN), & Coefficients (PredictorN+1), & Kay1 (SeasonN,BoxN), & Kay2 (SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcPatterns: Allocation failure: 01 #####" write (99,*), "filling predictor..." ! ######################## call ResetCurrentSim XAllYear = 0 do ! fill predictor if (XAllYear.GT.0.AND.associated(CurrentSim%Next)) CurrentSim => CurrentSim%Next XFileYear = 0 do XFileYear = XFileYear + 1 ; XAllYear = XAllYear + 1 Predictor (XAllYear,1) = CurrentSim%GloT(XFileYear) ! fill global T ! fill equilT - globalT if (QMethod.GT.10) Predictor(XAllYear,2) = CurrentSim%EquT(XFileYear) - CurrentSim%GloT(XFileYear) if (XFileYear.EQ.CurrentSim%YearN) exit end do if (.not.associated(CurrentSim%Next)) exit end do write (99,*), "filling response..." ! ######################## do XSeason = 1, SeasonN ! iterate by season and box do XBox = 1, BoxN call ResetCurrentSim ; XAllYear = 0 ; XFileYear = 0 do if (XAllYear.GT.0.AND.associated(CurrentSim%Next)) CurrentSim => CurrentSim%Next XFileYear = 0 do XFileYear = XFileYear + 1 ; XAllYear = XAllYear + 1 Response (XAllYear) = CurrentSim%Data(XFileYear,XSeason,XBox) ! fill response if (XFileYear.EQ.CurrentSim%YearN) exit end do if (.not.associated(CurrentSim%Next)) exit end do if (PredictorN.EQ.1) then ! calc weights do XAllYear = 1, AllYearN if (Response(XAllYear).EQ.MissVal.OR.Predictor(XAllYear,1).EQ.MissVal) then Weight(XAllYear) = 0.0 else Weight(XAllYear) = 1.0 end if end do else do XAllYear = 1, AllYearN if (Response(XAllYear).EQ.MissVal.OR.Predictor(XAllYear,1).EQ.MissVal.OR. & Predictor(XAllYear,2).EQ.MissVal) then Weight(XAllYear) = 0.0 else Weight(XAllYear) = 1.0 end if end do end if call nag_mult_lin_reg (Predictor,Response,Coefficients,wt=Weight,add_alpha=.FALSE.) Kay1(XSeason,XBox) = Coefficients (1) Kay2(XSeason,XBox) = Coefficients (2) end do end do write (99,*), "removing sims..." ! ######################## call RemoveSims write (99,*), "iterating by constant..." ! ######################## do XKay = 1, PredictorN write (99,*), "constant: ", XKay ! ######################## if (XKay.EQ.1) then CurrentKay => Kay1 ; KaySuffix = ".k1 " else CurrentKay => Kay2 ; KaySuffix = ".k2 " end if SuffixStart = index (CurrentExec%KayFile,Suffix) GripFile = trim(CurrentExec%KayFile(1:(SuffixStart-1))) // trim(KaySuffix) // trim(Suffix) GripInfo = trim(CurrentExec%KayInfo) // adjustr(KaySuffix) call SaveGrip (CurrentKay,Grid,Bounds,GripInfo,GripFile,Suffix,SaveSuffix) if (QDumpGlo.GT.0) then if (QDumpGlo.EQ.1.OR.QDumpGlo.EQ.2) then XSeason = 17 GloVector => CurrentKay(XSeason,1:BoxN:1) ; call SaveSeasonGlo end if if (QDumpGlo.EQ.1.OR.QDumpGlo.EQ.3) then do XSeason = 13, 16 GloVector => CurrentKay(XSeason,1:BoxN:1) ; call SaveSeasonGlo end do end if if (QDumpGlo.EQ.1.OR.QDumpGlo.EQ.4) then do XSeason = 1, 12 GloVector => CurrentKay(XSeason,1:BoxN:1) ; call SaveSeasonGlo end do end if end if end do nullify (CurrentKay) deallocate (Predictor,Response,Weight,Coefficients,Kay1,Kay2, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: CalcLinear: Deallocation failure: ABK #####" write (99,*), "finished calcpatterns" ! ######################## end subroutine CalcPatterns !******************************************************************************* ! load the main grim file for a particular simulation subroutine LoadSimGrim if (QRestrictPer.EQ.1) then call LoadGrim (FileData,FileGrid,FileYearAD,FileBounds,FileInfo,CurrentExec%SimFile(XSim),Suffix,& FileSuffix,MasterYearAD=YearAD) FileYearN = YearN call CommonVecPer (YearAD,FileYearAD,Year0,Year1,FileYear0,FileYear1) deallocate (FileYearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSims: Deallocation failure: LoadGrim #####" else call LoadGrim (FileData,FileGrid,YearAD,FileBounds,FileInfo,CurrentExec%SimFile(XSim),Suffix,& FileSuffix) FileYearN = size (YearAD,1) Year0 = 1 ; Year1 = FileYearN ; FileYear0 = 1; FileYear1 = FileYearN end if call CheckGridAB (Grid,FileGrid,CheckBoxN) if (CheckBoxN.NE.BoxN) print*, " > ##### ERROR: LoadSimGrim: grids do not match #####" allocate (OneSim, & OneSim%Data (FileYearN,SeasonN,BoxN), & OneSim%GloT (FileYearN), & OneSim%EquT (FileYearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSims: Allocation failure: OneSim #####" OneSim%Name = CurrentExec%SimName(XSim) OneSim%YearN = FileYearN OneSim%Data = MissVal ; OneSim%GloT = MissVal ; OneSim%EquT = MissVal do XYear = Year0, Year1 ! store data XFileYear = FileYear0 + XYear - 1 do XMonth = 1, MonthN do XBox = 1, BoxN OneSim%Data (XYear,XMonth,XBox) = FileData (XFileYear,XMonth,XBox) end do end do end do deallocate (FileData,FileGrid,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSimGrim: Deallocation failure: File* #####" do XYear = Year0, Year1 ! seasonalise data do XBox = 1, BoxN do XSeason = 1, 4 OneSim%Data(XYear,XSeason+12,XBox) = 0.0 do XMonth = (((XSeason-1)*3)+3), (((XSeason-1)*3)+5) if (OneSim%Data(XYear,XSeason+12,XBox).NE.MissVal) then if (XMonth.LE.12) then ThisYear = XYear ; ThisMonth = XMonth else ThisYear = XYear + 1 ; ThisMonth = XMonth - 12 end if if (ThisYear.LE.Year1) then if (OneSim%Data(ThisYear,ThisMonth,XBox).NE.MissVal) then OneSim%Data(XYear,XSeason+12,XBox) = OneSim%Data(XYear,XSeason+12,XBox) + & OneSim%Data(ThisYear,ThisMonth,XBox) else OneSim%Data(XYear,XSeason+12,XBox) = MissVal end if else OneSim%Data(XYear,XSeason+12,XBox) = MissVal end if end if end do if (OneSim%Data(XYear,XSeason+12,XBox).NE.MissVal) then if (QMeanSum.EQ.1) OneSim%Data(XYear,XSeason+12,XBox) = OneSim%Data(XYear,XSeason+12,XBox) / 3.0 end if end do end do end do do XYear = Year0, Year1 ! annualise data do XBox = 1, BoxN OneSim%Data(XYear,17,XBox) = 0.0 do XMonth = 1, 12 if (OneSim%Data(XYear,17,XBox).NE.MissVal) then if (OneSim%Data(XYear,XMonth,XBox).NE.MissVal) then OneSim%Data(XYear,17,XBox) = OneSim%Data(XYear,17,XBox) + OneSim%Data(XYear,XMonth,XBox) else OneSim%Data(XYear,17,XBox) = MissVal end if end if end do if (OneSim%Data(XYear,17,XBox).NE.MissVal) then if (QMeanSum.EQ.1) OneSim%Data(XYear,17,XBox) = OneSim%Data(XYear,17,XBox) / 12.0 end if end do end do end subroutine LoadSimGrim !******************************************************************************* ! anomalise and smooth the simulation subroutine AnomSmoothSim write (99,*), "anomalising...." ! ########################### do XBox = 1, BoxN ! anomalise do XSeason = 1, SeasonN if (BaseData(XSeason,XBox).NE.MissVal) then do XYear = 1, OneSim%YearN if (OneSim%Data(XYear,XSeason,XBox).NE.MissVal) then OneSim%Data(XYear,XSeason,XBox) = OneSim%Data(XYear,XSeason,XBox) - BaseData(XSeason,XBox) else OneSim%Data(XYear,XSeason,XBox) = MissVal end if end do else do XYear = 1, OneSim%YearN OneSim%Data(XYear,XSeason,XBox) = MissVal end do end if end do end do write (99,*), "smoothing...." ! ########################### allocate (Array1D (OneSim%YearN), & TSLowVec (OneSim%YearN), & TSHighVec(OneSim%YearN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: AnomSmoothSim: Allocation failure #####" do XBox = 1, BoxN ! smooth do XSeason = 1, SeasonN TSLowVec = MissVal ; TSHighVec = MissVal do XYear = 1, OneSim%YearN Array1D(XYear) = OneSim%Data(XYear,XSeason,XBox) end do call GaussSmooth (OneSim%YearN,PerLen,1,Array1D,TSLowVec,TSHighVec) do XYear = 1, OneSim%YearN OneSim%Data(XYear,XSeason,XBox) = TSLowVec(XYear) end do end do end do deallocate (Array1D,TSLowVec,TSHighVec, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: AnomSmoothSim: Deallocation failure #####" write (99,*), "finished anomalising and smoothing" ! ########################### end subroutine AnomSmoothSim !******************************************************************************* ! load the global time series for a particular sim ! these should already be anomalised and smoothed subroutine LoadSimGloTS call LoadANN (CurrentExec%SimGloT(XSim), GloTYearAD, AnnNames, FileGloT) ! get global T data if (size(FileGloT,2).NE.1) then print "(a,i2,a)", " > ##### ERROR: LoadSimGloTS: GloT file has multiple columns #####" else call CommonVecPer (YearAD,GloTYearAD,Year0,Year1,FileYear0,FileYear1) do XYear = Year0, Year1 XFileYear = FileYear0 + XYear - 1 OneSim%GloT (XYear) = FileGloT(XFileYear,1) end do end if deallocate (GloTYearAD,AnnNames,FileGloT,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSimGloTS: Deallocation failure: GloT info #####" if (QMethod.GE.10) then call LoadANN (CurrentExec%SimEquT(XSim), EquTYearAD, AnnNames, FileEquT) ! get rad forcing data if (size(FileEquT,2).NE.1) then print "(a,i2,a)", " > ##### ERROR: LoadSimGloTS: EquT file has multiple columns #####" QHalt = 1 else call CommonVecPer (YearAD,EquTYearAD,Year0,Year1,FileYear0,FileYear1) do XYear = Year0, Year1 XFileYear = FileYear0 + XYear - 1 OneSim%EquT (XYear) = FileEquT(XFileYear,1) end do end if deallocate (EquTYearAD,AnnNames,FileEquT,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSimGloTS: Deallocation failure: EquT info #####" end if if (QRestrictPer.EQ.2) then deallocate (YearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: LoadSimGloTS: Deallocation failure: YearAD #####" end if end subroutine LoadSimGloTS !******************************************************************************* subroutine GetBaseData call LoadGrim (FileData,FileGrid,FileYearAD,FileBounds,FileInfo,CurrentExec%BaseFile,& CurrentExec%Name,Suffix) call CheckGridAB (Grid,FileGrid,CheckBoxN) if (CheckBoxN.NE.BoxN) print*, " > ##### ERROR: LoadSims: grids do not match #####" if (size(FileData,1).NE.1) print*, " > ##### ERROR: GetBaseData: base length not 1 year #####" allocate (BaseData(SeasonN,BoxN), stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetBaseData: Allocation failure: BaseData #####" BaseData = 0.0 do XMonth = 1, MonthN do XBox = 1, BoxN BaseData (XMonth,XBox) = FileData (1,XMonth,XBox) end do end do deallocate (FileData,FileGrid,FileYearAD,stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: GetBaseData: Deallocation failure: File* #####" do XSeason = 1, 4 do XBox = 1, BoxN do XMonth = 1, 3 if (BaseData(XSeason+12,XBox).NE.MissVal) then ThisMonth = SeasonMonths (((XSeason-1)*3)+XMonth) if (BaseData(ThisMonth,XBox).NE.MissVal) then BaseData(XSeason+12,XBox) = BaseData(XSeason+12,XBox) + BaseData(ThisMonth,XBox) else BaseData(XSeason+12,XBox) = MissVal end if end if end do if (BaseData(XSeason+12,XBox).NE.MissVal) then if (QMeanSum.EQ.1) BaseData(XSeason+12,XBox) = BaseData(XSeason+12,XBox) / 3.0 end if end do end do do XBox = 1, BoxN do XMonth = 1, 12 if (BaseData(17,XBox).NE.MissVal) then if (BaseData(XMonth,XBox).NE.MissVal) then BaseData(17,XBox) = BaseData(17,XBox) + BaseData(XMonth,XBox) else BaseData(17,XBox) = MissVal end if end if end do if (BaseData(17,XBox).NE.MissVal) then if (QMeanSum.EQ.1) BaseData(17,XBox) = BaseData(17,XBox) / 12.0 end if end do end subroutine GetBaseData !******************************************************************************* subroutine CalcAllYearN call ResetCurrentSim ; AllYearN = 0 do ! calcs total Years from all sims if (AllYearN.GT.0.AND.associated(CurrentSim%Next)) CurrentSim => CurrentSim%Next AllYearN = AllYearN + CurrentSim%YearN if (.not.associated(CurrentSim%Next)) exit end do end subroutine CalcAllYearN !******************************************************************************* subroutine SaveSeasonGlo GloFile = trim(GripFile) // '.' // SeasonNames(XSeason) // ".glo" GloInfo = trim(GripInfo) // ' ' // SeasonNames(XSeason) call SaveGlo (ExeN,WyeN,BoxN,GloRefFile,GloFile,GloInfo,GloVector,Grid) nullify (GloVector) end subroutine SaveSeasonGlo !******************************************************************************* subroutine ResetCurrentSim do ! resets CurrentSim so that it points at first Sim if (associated(CurrentSim%Prev)) CurrentSim => CurrentSim%Prev if (.not.associated(CurrentSim%Prev)) exit end do end subroutine ResetCurrentSim !******************************************************************************* subroutine ResetCurrentExec do ! resets CurrentExec so that it points at first Exec if (associated(CurrentExec%Prev)) CurrentExec => CurrentExec%Prev if (.not.associated(CurrentExec%Prev)) exit end do end subroutine ResetCurrentExec !******************************************************************************* ! destroys all sims subroutine RemoveSims call ResetCurrentSim do if (associated(CurrentSim%Next)) then ! set stack to next sim... StackSim => CurrentSim%Next else ! ...or if no next sim, nullify nullify (StackSim) end if deallocate (CurrentSim, stat=AllocStat) ! deallocate current sim if (AllocStat.NE.0) print*, " > ##### ERROR: RemoveSims: Deallocation failure: CurrentSim #####" if ( associated(StackSim)) CurrentSim => StackSim ! set current to next sim... if (.not.associated(StackSim)) exit ! ....or exit end do end subroutine RemoveSims !******************************************************************************* subroutine RemoveExecs call ResetCurrentExec do if (associated(CurrentExec%Next)) then ! set stack to next Exec... StackExec => CurrentExec%Next else ! ...or if no next Exec, nullify nullify (StackExec) end if deallocate (CurrentExec, stat=AllocStat) ! deallocate current Exec if (AllocStat.NE.0) print*, " > ##### ERROR: RemoveExecs: Deallocation failure: CurrentExec #####" if ( associated(StackExec)) CurrentExec => StackExec ! set current to next Exec... if (.not.associated(StackExec)) exit ! ....or exit end do end subroutine RemoveExecs !******************************************************************************* subroutine Finish print* close (99) deallocate (Grid, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finish: Deallocation failure: Grid #####" if (QRestrictPer.EQ.1) then deallocate (YearAD, stat=AllocStat) if (AllocStat.NE.0) print*, " > ##### ERROR: Finish: Deallocation failure: YearAD #####" end if call RemoveExecs end subroutine Finish !******************************************************************************* end program GetPattern