10 use fckit_configuration_module
14 use oops_variables_mod
36 integer :: isc, iec, jsc, jec, npx, npy, npz, nf
37 integer :: calendar_type, date_init(6)
38 type(fckit_mpi_comm) :: f_comm
77 subroutine create(self, geom, vars, increment)
81 type(oops_variables),
intent(in) :: vars
82 logical,
optional,
intent(in) :: increment
86 logical :: is_increment, field_fail
90 self%nf = vars%nvars()
91 allocate(self%fields(self%nf))
95 if (.not.
present(increment))
then
96 is_increment = .false.
98 is_increment = increment
104 do var = 1, vars%nvars()
106 fmd = geom%fields%get_field(trim(vars%variable(var)))
111 self%fields(fc)%isc = geom%isc
112 self%fields(fc)%iec = geom%iec
113 self%fields(fc)%jsc = geom%jsc
114 self%fields(fc)%jec = geom%jec
115 self%fields(fc)%npz = fmd%levels
117 field_fail = len(trim(fmd%field_name)) >
field_clen
118 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: " //trim(fmd%field_name)//
" too long")
120 if(.not.self%fields(fc)%lalloc)
then
122 if (trim(fmd%stagger_loc) ==
'center')
then
123 allocate(self%fields(fc)%array(geom%isc:geom%iec,geom%jsc:geom%jec,1:fmd%levels))
124 elseif (trim(fmd%stagger_loc) ==
'northsouth')
then
125 allocate(self%fields(fc)%array(geom%isc:geom%iec,geom%jsc:geom%jec+1,1:fmd%levels))
126 elseif (trim(fmd%stagger_loc) ==
'eastwest')
then
127 allocate(self%fields(fc)%array(geom%isc:geom%iec+1,geom%jsc:geom%jec,1:fmd%levels))
132 self%fields(fc)%lalloc = .true.
134 self%fields(fc)%short_name = trim(fmd%field_io_name)
135 if (is_increment)
then
136 self%fields(fc)%long_name =
"increment_of_"//trim(fmd%long_name)
138 self%fields(fc)%long_name = trim(fmd%long_name)
140 self%fields(fc)%fv3jedi_name = trim(fmd%field_name)
141 self%fields(fc)%units = trim(fmd%units)
142 self%fields(fc)%io_file = trim(fmd%io_file)
143 self%fields(fc)%space = trim(fmd%space)
144 self%fields(fc)%staggerloc = trim(fmd%stagger_loc)
145 self%fields(fc)%tracer = fmd%tracer
146 self%fields(fc)%integerfield = trim(fmd%array_kind)==
'integer'
151 if (fc .ne. self%nf)
call abor1_ftn(
"fv3jedi_fields_mod create: fc does not equal self%nf")
166 self%f_comm = geom%f_comm
169 field_fail = self%has_field(
'ua') .and. .not.self%has_field(
'va')
170 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: found A-Grid u but not v")
171 field_fail = .not.self%has_field(
'ua') .and. self%has_field(
'va')
172 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: found A-Grid v but not u")
173 field_fail = self%has_field(
'ud') .and. .not.self%has_field(
'vd')
174 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: found D-Grid u but not v")
175 field_fail = .not.self%has_field(
'ud') .and. self%has_field(
'vd')
176 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: found D-Grid v but not u")
179 field_fail = self%has_field(
'o3mr') .and. self%has_field(
'o3ppmv')
180 if (field_fail)
call abor1_ftn(
"fv3jedi_fields.create: o3mr and o3ppmv created")
193 if(self%fields(var)%lalloc)
deallocate(self%fields(var)%array)
194 self%fields(var)%lalloc = .false.
196 deallocate(self%fields)
209 call checksame(self%fields, other%fields,
"fv3jedi_fields_mod.copy")
212 self%fields(var)%array = other%fields(var)%array
215 self%calendar_type = other%calendar_type
216 self%date_init = other%date_init
229 self%fields(var)%array = 0.0_kind_real
239 real(kind=
kind_real),
intent(out) :: normout
241 integer :: i, j, k, ii, iisum, var
249 do k = 1, self%fields(var)%npz
250 do j = self%fields(var)%jsc, self%fields(var)%jec
251 do i = self%fields(var)%isc, self%fields(var)%iec
252 zz = zz + self%fields(var)%array(i,j,k)**2
261 call self%f_comm%allreduce(zz,normout,fckit_mpi_sum())
262 call self%f_comm%allreduce(ii,iisum,fckit_mpi_sum())
263 normout = sqrt(normout/real(iisum,
kind_real))
280 logical :: integer_interp = .false.
282 call checksame(self%fields, other%fields,
"fv3jedi_fields_mod.change_resol")
284 if ((other%iec-other%isc+1)-(self%iec-self%isc+1) == 0)
then
286 call self%copy(other)
292 if (other%fields(var)%integerfield) integer_interp = .true.
295 call interp%create(geom%interp_method, integer_interp, geom_other, geom)
296 call interp%apply(self%nf, geom_other, other%fields, geom, self%fields)
299 self%calendar_type = other%calendar_type
300 self%date_init = other%date_init
308 subroutine minmaxrms(self, field_num, field_name, minmaxrmsout)
311 integer,
intent(in) :: field_num
312 character(len=*),
intent(inout) :: field_name
313 real(kind=
kind_real),
intent(out) :: minmaxrmsout(3)
315 integer :: isc, iec, jsc, jec, npz
316 real(kind=
kind_real) :: tmp(3), gs3, gs3g
318 isc = self%fields(field_num)%isc
319 iec = self%fields(field_num)%iec
320 jsc = self%fields(field_num)%jsc
321 jec = self%fields(field_num)%jec
322 npz = self%fields(field_num)%npz
324 field_name = self%fields(field_num)%short_name
327 gs3 = real((iec-isc+1)*(jec-jsc+1)*npz,
kind_real)
328 call self%f_comm%allreduce(gs3,gs3g,fckit_mpi_sum())
331 tmp(1) = minval(self%fields(field_num)%array(isc:iec,jsc:jec,1:npz))
332 tmp(2) = maxval(self%fields(field_num)%array(isc:iec,jsc:jec,1:npz))
333 tmp(3) = sum(self%fields(field_num)%array(isc:iec,jsc:jec,1:npz)**2)
336 call self%f_comm%allreduce(tmp(1), minmaxrmsout(1), fckit_mpi_min())
337 call self%f_comm%allreduce(tmp(2), minmaxrmsout(2), fckit_mpi_max())
338 call self%f_comm%allreduce(tmp(3), minmaxrmsout(3), fckit_mpi_sum())
341 minmaxrmsout(3) = sqrt(minmaxrmsout(3)/gs3g)
347 subroutine read(self, geom, conf, vdate)
351 type(fckit_configuration),
intent(in) :: conf
352 type(datetime),
intent(inout) :: vdate
357 character(len=10) :: filetype
358 character(len=:),
allocatable :: str
362 call conf%get_or_die(
"filetype",str)
367 if (trim(filetype) ==
'gfs')
then
369 call gfs%setup_conf(conf)
370 call gfs%read_meta(geom, vdate, self%calendar_type, self%date_init)
371 call gfs%read_fields(geom, self%fields)
373 elseif (trim(filetype) ==
'geos')
then
375 call geos%setup_conf(geom, conf)
376 call geos%read_meta(geom, vdate, self%calendar_type, self%date_init, self%fields)
377 call geos%read_fields(geom, self%fields)
382 call abor1_ftn(
"fv3jedi_fields_mod.read: restart type not supported")
390 subroutine write(self, geom, conf, vdate)
394 type(fckit_configuration),
intent(in) :: conf
395 type(datetime),
intent(inout) :: vdate
401 character(len=10) :: filetype
402 character(len=:),
allocatable :: str
405 call conf%get_or_die(
"filetype",str)
409 if (trim(filetype) ==
'gfs')
then
411 call gfs%setup_conf(conf)
412 call gfs%setup_date(vdate)
413 call gfs%write(geom, self%fields, vdate, self%calendar_type, self%date_init)
415 elseif (trim(filetype) ==
'geos')
then
417 call geos%setup_conf(geom, conf)
418 call geos%setup_date(vdate)
419 call geos%write(geom, self%fields, vdate)
422 elseif (trim(filetype) ==
'latlon')
then
424 call latlon%setup_conf(geom)
425 call latlon%setup_date(vdate)
426 call latlon%write(geom, self%fields, conf, vdate)
430 call abor1_ftn(
"fv3jedi_fields.write: restart type not supported")
447 call checksame(self%fields,rhs%fields,
"fv3jedi_fields.accumul")
450 self%fields(var)%array = self%fields(var)%array + zz * rhs%fields(var)%array
463 integer,
intent(in) :: vsize
464 real(kind_real),
intent(out) :: vect_inc(vsize)
467 integer :: ind, var, i, j, k
474 do k = 1,self%fields(var)%npz
475 do j = self%fields(var)%jsc,self%fields(var)%jec
476 do i = self%fields(var)%isc,self%fields(var)%iec
478 vect_inc(ind) = self%fields(var)%array(i, j, k)
494 integer,
intent(in) :: vsize
495 real(kind_real),
intent(in) :: vect_inc(vsize)
496 integer,
intent(inout) :: index
499 integer :: ind, var, i, j, k
503 do k = 1,self%fields(var)%npz
504 do j = self%fields(var)%jsc,self%fields(var)%jec
505 do i = self%fields(var)%isc,self%fields(var)%iec
506 self%fields(var)%array(i, j, k) = vect_inc(index + 1)
520 character(len=*),
intent(in) :: field_name
521 integer,
optional,
intent(out) :: field_index
532 character(len=*),
intent(in) :: field_name
535 call get_field(self%fields, field_name, field)
544 character(len=*),
intent(in) :: field_name
545 real(kind=
kind_real),
pointer,
intent(inout) :: field(:,:,:)
547 call get_field(self%fields, field_name, field)
556 character(len=*),
intent(in) :: field_name
557 real(kind=
kind_real),
allocatable,
intent(inout) :: field(:,:,:)
559 call get_field(self%fields, field_name, field)
568 character(len=*),
intent(in) :: field_name
569 real(kind=
kind_real),
allocatable,
intent(in) :: field(:,:,:)
571 call put_field(self%fields, field_name, field)