11 integer::write_debug
= 0,call_femwind
= 0
14 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire domain bounds
15 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! fire memory bounds
16 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
17 ifts
, ifte
, kfts
, kfte
, jfts
, jfte
! fire tile bounds
19 ! declarations of A, msize included from module femwind
21 ! variables read from wrfout
22 real, pointer:: u0_fmw(:,:,:), v0_fmw(:,:,:), w0_fmw(:,:,:), zsf(:,:), ht_fmw(:)
24 ! variables allocated and computed here
25 real, pointer:: u0(:,:,:), v0(:,:,:), w0(:,:,:)
26 real, pointer:: u(:,:,:), v(:,:,:), w(:,:,:), uf(:,:), vf(:,:)
28 integer:: i
, j
, k
, n(3), nx
, ny
, nz
29 integer::ncid
,frame
,sr(2),frame0_fmw
,mframe
=100,dims(3)
30 real:: rate
,A(3,3),dx
,dy
,zx
,zy
31 character(len
=256)::filename
, msg
35 filename
= "wrf.nc" ! file to read from and write to
36 frame
= 1 ! frame in the file
38 !************************************
40 !************************************
42 call ncopen(filename
,nf90_nowrite
,ncid
)
44 ! horizontal height at cell centers
45 call netcdf_read_array_wrf(ncid
,"ZSF",frame
=frame
,a2d
=zsf
)
47 ! height of the vertical layers above the terrain
48 call netcdf_read_array_wrf(ncid
,"HT_FMW",frame
=frame
,a1d
=ht_fmw
)
50 ! fire subgrid refinement ratio, 3d grid dimensions cell centered
51 call get_wrf_dims(ncid
,sr
,dims
)
52 ! horizontal mesh spacing
53 dx
= netcdf_read_att(ncid
,"DX")/sr(1)
54 dy
= netcdf_read_att(ncid
,"DY")/sr(2)
58 !************************************
60 !************************************
64 params
%A
= reshape((/1.0,0.0,0.0, &
70 mg(1)%nx
= dims(1) + 1 ! dimensions are vertex centered
71 mg(1)%ny
= dims(2) + 1 ! dimensions are vertex centered
72 mg(1)%nz
= dims(3) + 1 ! dimensions are vertex centered
74 call get_mg_dims(mg(1), & ! set bounds compatible with WRF
75 ifds
, ifde
, kfds
,kfde
, jfds
, jfde
, & ! fire grid dimensions
76 ifms
, ifme
, kfms
,kfme
, jfms
, jfme
, &
77 ifps
, ifpe
, kfps
,kfpe
, jfps
, jfpe
, & ! fire patch bounds
78 ifts
, ifte
, kfts
,kfte
, jfts
, jfte
)
80 ! allocations persistent over the whole run
82 allocate(mg(1)%X(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
83 allocate(mg(1)%Y(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
84 allocate(mg(1)%Z(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
85 allocate(u0(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
)) ! vector components called u v W
86 allocate(v0(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
87 allocate(w0(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
88 allocate(u(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
)) ! vector components called u v W
89 allocate(v(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
90 allocate(w(ifms
:ifme
,kfms
:kfme
,jfms
:jfme
))
91 allocate(uf(ifts
:ifte
,jfts
:jfte
))
92 allocate(vf(ifts
:ifte
,jfts
:jfte
))
93 write(msg
,*)"shape(uf)=",shape(uf
)
95 write(msg
,*)"shape(vf)=",shape(vf
)
99 ! X Y Z are corner based, upper bound larger by one
100 ! first interpolate/extrapolate zsf to corners
104 zx
= zsf(i
,j
) - 0.5*(zsf(i
+1,j
)-zsf(i
,j
)) ! extrapolate down
105 elseif(i
.eq
.ifte
+1)then
106 zx
= zsf(i
,j
) - 0.5*(zsf(i
-1,j
)-zsf(i
,j
)) ! extrapolate up
108 zx
= 0.5*(zsf(i
,j
) + zsf(i
+1,j
)) ! interpolate
111 zy
= zsf(i
,j
) - 0.5*(zsf(i
,j
+1)-zsf(i
,j
)) ! extrapolate down
112 elseif(j
.eq
.jfte
+1)then
113 zy
= zsf(i
,j
) - 0.5*(zsf(i
,j
-1)-zsf(i
,j
)) ! extrapolate up
115 zy
= 0.5*(zsf(i
,j
) + zsf(i
,j
+1)) ! interpolate
117 mg(1)%Z(i
,kfts
,j
) = 0.5*(zx
+ zy
)
121 ! (X,Y) is the same uniform grid on all levels
125 mg(1)%X(i
,k
,j
) = (i
-1)*dx
126 mg(1)%Y(i
,k
,j
) = (j
-1)*dy
131 ! add top of levels above terrain to Z(:,kfts,:)
132 print *,'debug ht_fmw=',ht_fmw
136 mg(1)%Z(i
,k
,j
) = mg(1)%Z(i
,kfts
,j
) + ht_fmw(k
- kfts
)
144 allocate(mg(1)%dz(mg(1)%nz
-1))
146 mg(1)%dz(k
)=mg(1)%Z(1,k
+1,1)-mg(1)%Z(1,k
,1)
149 deallocate(ht_fmw
,zsf
) ! no longer needed
151 if(call_femwind
.gt
.0)then
152 call message('calling femwind_setup')
153 call femwind_setup(mg
)
154 call message('femwind_setup done')
157 if(write_debug
.gt
.0)then
158 ! write coordinates for debug/display, even if the caller knows
159 call write_average_to_center(mg(1)%X
,'X_c')
160 call write_average_to_center(mg(1)%Y
,'Y_c')
161 call write_average_to_center(mg(1)%Z
,'Z_c')
164 !************************************
165 ! loop over time steps
166 !************************************
168 do frame0_fmw
=1,mframe
170 ! read initial velocity field, loop until delivered
171 call read_initial_wind(filename
,u0_fmw
,v0_fmw
,w0_fmw
,frame0_fmw
,frame
=1)
173 ! copy the input data to tile sized bounds
174 ! initial wind is at cell centers, indexing was already switched to ikj in reading
175 u0(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
) = u0_fmw
176 v0(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
) = v0_fmw
177 w0(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
) = w0_fmw
179 ! save memory while solver is running
180 deallocate(u0_fmw
,v0_fmw
,w0_fmw
)
182 ! compute/update mass consistent flow
184 if(call_femwind
.gt
.0)then
185 write(*,'(a)')'calling femwind_solve'
186 call femwind_solve( mg
,&
187 ifds
, ifde
, kfds
, kfde
, jfds
, jfde
, & ! fire domain bounds
188 ifms
, ifme
, kfms
, kfme
, jfms
, jfme
, & ! fire memory bounds
189 ifps
, ifpe
, kfps
, kfpe
, jfps
, jfpe
, & ! fire patch bounds
190 ifts
, ifte
, kfts
, kfte
, jfts
,jfte
, & ! fire tile bounds
191 u0
, v0
, w0
, & ! input arrays
192 u
, v
, w
, & ! output arrays
194 write(*,'(a)')'femwind_solve returned OK'
196 ! interpolate to fire height
197 call message('TESTING ONLY: copying lowest level of input to uf vf')
198 write(msg
,*)"shape(uf)=",shape(uf
)
200 write(msg
,*)"shape(vf)=",shape(vf
)
202 uf
= u0(ifts
:ifte
,1,jfts
:jfte
)
203 vf
= v0(ifts
:ifte
,1,jfts
:jfte
)
204 call write_fire_wind(filename
,uf
,vf
,frame0_fmw
,frame
=1)
207 if(write_debug
.gt
.0)then
208 ! write output as is in 3D but with tight dimensions
209 call write_array(u(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
),'u')
210 call write_array(v(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
),'v')
211 call write_array(w(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
),'w')
212 call write_scalar(rate
,'rate')
219 subroutine write_average_to_center(F
,name
)
220 ! average and return with tight bounds
223 real, intent(in
)::F(ifms
:ifme
, kfms
:kfme
, jfms
:jfme
)
224 character(len
=*)::name
226 real, allocatable
::Fm(:,:,:)
230 allocate(Fm(ifts
:ifte
,kfts
:kfte
,jfts
:jfte
))
238 s
= s
+ F(i
+ii
,k
+kk
,j
+jj
)
246 call write_array(Fm
,name
)
247 end subroutine write_average_to_center
249 end program femwind_wrfout