146 MODULE diag_manager_mod
210 &
OPERATOR(<),
OPERATOR(==),
OPERATOR(/=),
OPERATOR(/),
OPERATOR(+),
ASSIGNMENT(=),
get_date, &
214 USE mpp_mod,
ONLY: input_nml_file,
mpp_error
227 & end_of_run, diag_seconds, diag_minutes, diag_hours, diag_days, diag_months, diag_years,
num_files,&
231 & output_fields, time_zero, append_pelist_name, mix_snapshot_average_fields,&
232 & first_send_data_call, do_diag_field_log, write_bytes_in_file, debug_diag_manager,&
243 use fms_diag_object_mod,
only:fms_diag_object
245 USE constants_mod,
ONLY: seconds_per_day
250 USE netcdf,
ONLY: nf90_int, nf90_float, nf90_char
263 &
need_data, diag_all, diag_ocean, diag_other, get_date_dif, diag_seconds,&
267 PUBLIC :: center, north, east
273 PUBLIC :: diag_field_not_found
277 #include<file_version.h>
279 type(time_type) :: Time_end
385 & long_name, units, missing_value, range, standard_name, do_not_log, err_msg,&
386 & area, volume, realm, multiple_send_data)
387 CHARACTER(len=*),
INTENT(in) :: module_name
388 CHARACTER(len=*),
INTENT(in) :: field_name
389 TYPE(
time_type),
OPTIONAL,
INTENT(in) :: init_time
390 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name
391 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: units
392 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: standard_name
393 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
394 CLASS(*),
OPTIONAL,
INTENT(in) :: range(:)
395 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
396 CHARACTER(len=*),
OPTIONAL,
INTENT(out):: err_msg
397 INTEGER,
OPTIONAL,
INTENT(in) :: area
398 INTEGER,
OPTIONAL,
INTENT(in) :: volume
399 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
400 LOGICAL,
OPTIONAL,
INTENT(in) :: multiple_send_data
404 IF (
PRESENT(range) )
THEN
405 IF (
SIZE(range) .NE. 2 )
THEN
407 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'extent of range should be 2', fatal)
410 if (use_modern_diag)
then
411 if( do_diag_field_log)
then
412 if (
PRESENT(do_not_log) )
THEN
413 if(.not. do_not_log)
call log_diag_field_info(module_name, field_name, (/null_axis_id/), long_name,&
414 & units, missing_value, range, dynamic=.true.)
417 & missing_value, range, dynamic=.true.)
421 & module_name, field_name, init_time, long_name=long_name, units=units, &
422 & missing_value=missing_value, var_range=range, standard_name=standard_name, &
423 & do_not_log=do_not_log, err_msg=err_msg, area=area, volume=volume, realm=realm, &
424 multiple_send_data=multiple_send_data)
427 & long_name=long_name, units=units, missing_value=missing_value, range=range, standard_name=standard_name, &
428 & do_not_log=do_not_log, err_msg=err_msg, area=area, volume=volume, realm=realm)
435 & long_name, units, missing_value, range, mask_variant, standard_name, verbose,&
436 & do_not_log, err_msg, interp_method, tile_count, area, volume, realm, multiple_send_data)
437 CHARACTER(len=*),
INTENT(in) :: module_name
438 CHARACTER(len=*),
INTENT(in) :: field_name
439 INTEGER,
INTENT(in) :: axes(:)
440 TYPE(
time_type),
OPTIONAL,
INTENT(in) :: init_time
441 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name
442 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: units
443 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
444 CLASS(*),
OPTIONAL,
INTENT(in) :: range(:)
445 LOGICAL,
OPTIONAL,
INTENT(in) :: mask_variant
446 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: standard_name
447 LOGICAL,
OPTIONAL,
INTENT(in) :: verbose
448 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
449 CHARACTER(len=*),
OPTIONAL,
INTENT(out):: err_msg
450 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: interp_method
454 INTEGER,
OPTIONAL,
INTENT(in) :: tile_count
455 INTEGER,
OPTIONAL,
INTENT(in) :: area
456 INTEGER,
OPTIONAL,
INTENT(in) :: volume
457 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
458 LOGICAL,
OPTIONAL,
INTENT(in) :: multiple_send_data
461 if (use_modern_diag)
then
462 if( do_diag_field_log)
then
463 if (
PRESENT(do_not_log) )
THEN
465 & units, missing_value, range, dynamic=.true.)
468 & missing_value, range, dynamic=.true.)
472 & module_name, field_name, axes, init_time, long_name=long_name, &
473 & units=units, missing_value=missing_value, var_range=range, mask_variant=mask_variant, &
474 & standard_name=standard_name, verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
475 & interp_method=interp_method, tile_count=tile_count, area=area, volume=volume, realm=realm, &
476 multiple_send_data=multiple_send_data)
479 & long_name=long_name, units=units, missing_value=missing_value, range=range, mask_variant=mask_variant, &
480 & standard_name=standard_name, verbose=verbose, do_not_log=do_not_log, err_msg=err_msg, &
481 & interp_method=interp_method, tile_count=tile_count, area=area, volume=volume, realm=realm)
488 & missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method,&
489 & tile_count, area, volume, realm)
490 CHARACTER(len=*),
INTENT(in) :: module_name
491 CHARACTER(len=*),
INTENT(in) :: field_name
492 INTEGER,
DIMENSION(:),
INTENT(in) :: axes
493 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name
494 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: units
495 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: standard_name
496 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
497 CLASS(*),
DIMENSION(:),
OPTIONAL,
INTENT(in) :: range
498 LOGICAL,
OPTIONAL,
INTENT(in) :: mask_variant
499 LOGICAL,
OPTIONAL,
INTENT(in) :: dynamic
500 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
501 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: interp_method
505 INTEGER,
OPTIONAL,
INTENT(in) :: tile_count
506 INTEGER,
OPTIONAL,
INTENT(in) :: area
508 INTEGER,
OPTIONAL,
INTENT(in) :: volume
510 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
514 IF ( .NOT.module_is_initialized )
THEN
516 CALL error_mesg (
'diag_manager_mod::register_static_field',
'diag_manager has NOT been initialized', fatal)
519 if (use_modern_diag)
then
520 if( do_diag_field_log)
then
521 if (
PRESENT(do_not_log) )
THEN
523 & units, missing_value, range, dynamic=.false.)
526 & missing_value, range, dynamic=.false.)
530 & long_name=long_name, units=units, missing_value=missing_value, range=range, mask_variant=mask_variant, &
531 & standard_name=standard_name, dynamic=dynamic, do_not_log=do_not_log, interp_method=interp_method,&
532 & tile_count=tile_count, area=area, volume=volume, realm=realm)
535 & long_name=long_name, units=units, missing_value=missing_value, range=range, mask_variant=mask_variant, &
536 & standard_name=standard_name, dynamic=dynamic, do_not_log=do_not_log, interp_method=interp_method,&
537 & tile_count=tile_count, area=area, volume=volume, realm=realm)
544 & long_name, units, missing_value, range, standard_name, do_not_log, err_msg,&
545 & area, volume, realm)
546 CHARACTER(len=*),
INTENT(in) :: module_name
547 CHARACTER(len=*),
INTENT(in) :: field_name
548 TYPE(
time_type),
OPTIONAL,
INTENT(in) :: init_time
549 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name
550 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: units
551 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: standard_name
552 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
553 CLASS(*),
OPTIONAL,
INTENT(in) :: range(:)
554 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
555 CHARACTER(len=*),
OPTIONAL,
INTENT(out):: err_msg
556 INTEGER,
OPTIONAL,
INTENT(in) :: area
557 INTEGER,
OPTIONAL,
INTENT(in) :: volume
558 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
560 IF (
PRESENT(err_msg) ) err_msg =
''
562 IF (
PRESENT(init_time) )
THEN
564 & (/null_axis_id/), init_time,long_name, units, missing_value, range, &
565 & standard_name=standard_name, do_not_log=do_not_log, err_msg=err_msg,&
566 & area=area, volume=volume, realm=realm)
569 & (/null_axis_id/),long_name, units, missing_value, range,&
570 & standard_name=standard_name, do_not_log=do_not_log, realm=realm)
577 & long_name, units, missing_value, range, mask_variant, standard_name, verbose,&
578 & do_not_log, err_msg, interp_method, tile_count, area, volume, realm)
579 CHARACTER(len=*),
INTENT(in) :: module_name, field_name
580 INTEGER,
INTENT(in) :: axes(:)
582 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name, units, standard_name
583 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
584 CLASS(*),
DIMENSION(:),
OPTIONAL,
INTENT(in) :: range
585 LOGICAL,
OPTIONAL,
INTENT(in) :: mask_variant,verbose
586 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
587 CHARACTER(len=*),
OPTIONAL,
INTENT(out):: err_msg
588 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: interp_method
592 INTEGER,
OPTIONAL,
INTENT(in) :: tile_count
593 INTEGER,
OPTIONAL,
INTENT(in) :: area
594 INTEGER,
OPTIONAL,
INTENT(in) :: volume
595 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
597 INTEGER :: field, j, ind, file_num, freq
598 INTEGER :: output_units
599 INTEGER :: stdout_unit
600 LOGICAL :: mask_variant1, verbose1
601 CHARACTER(len=128) :: msg
607 IF (
PRESENT(mask_variant) )
THEN
608 mask_variant1 = mask_variant
610 mask_variant1 = .false.
613 IF (
PRESENT(verbose) )
THEN
619 IF (
PRESENT(err_msg) ) err_msg =
''
622 IF (
PRESENT(range) )
THEN
623 IF (
SIZE(range) .NE. 2 )
THEN
625 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'extent of range should be 2', fatal)
631 & long_name, units, missing_value, range, mask_variant1, standard_name=standard_name,&
632 & dynamic=.true., do_not_log=do_not_log, interp_method=interp_method, tile_count=tile_count, realm=realm)
634 IF ( .NOT.first_send_data_call )
THEN
639 IF (
mpp_pe() == mpp_root_pe() ) &
640 &
CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '&
641 &//trim(module_name)//
'/'// trim(field_name)//&
642 &
' registered AFTER first send_data call, TOO LATE', warning)
649 IF ( debug_diag_manager .OR. verbose1 )
THEN
650 IF (
mpp_pe() == mpp_root_pe() ) &
651 &
CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '&
652 &//trim(module_name)//
'/'// trim(field_name)//
' NOT found in diag_table',&
661 IF (
PRESENT(volume).AND.
PRESENT(area) )
THEN
662 IF ( area.EQ.volume )
THEN
663 IF (
PRESENT(err_msg))
THEN
664 err_msg =
'diag_manager_mod::register_diag_field: module/output_field '&
665 &//trim(module_name)//
'/'// trim(field_name)//
' AREA and VOLUME CANNOT be the same variable.&
666 & Contact the developers.'
670 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '&
671 &//trim(module_name)//
'/'// trim(field_name)//
' AREA and VOLUME CANNOT be the same variable.&
672 & Contact the developers.',&
679 IF (
PRESENT(area) )
THEN
681 IF (
PRESENT(err_msg))
THEN
682 err_msg =
'diag_manager_mod::register_diag_field: module/output_field '&
683 &//trim(module_name)//
'/'// trim(field_name)//
' AREA measures field NOT found in diag_table.&
684 & Contact the model liaison.'
688 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '&
689 &//trim(module_name)//
'/'// trim(field_name)//
' AREA measures field NOT found in diag_table.&
690 & Contact the model liaison.',&
695 IF (
PRESENT(volume) )
THEN
696 IF ( volume < 0 )
THEN
697 IF (
PRESENT(err_msg))
THEN
698 err_msg =
'diag_manager_mod::register_diag_field: module/output_field '&
699 &//trim(module_name)//
'/'// trim(field_name)//
' VOLUME measures field NOT found in diag_table.&
700 & Contact the model liaison.'
704 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '&
705 &//trim(module_name)//
'/'// trim(field_name)//
' VOLUME measures field NOT found in diag_table.&
706 & Contact the model liaison.',&
712 IF (
PRESENT(standard_name) ) input_fields(field)%standard_name = standard_name
714 DO j = 1, input_fields(field)%num_output_fields
715 ind = input_fields(field)%output_fields(j)
716 output_fields(ind)%static = .false.
719 file_num = output_fields(ind)%output_file
720 IF ( file_num == max_files ) cycle
721 IF ( output_fields(ind)%local_output )
THEN
722 IF ( output_fields(ind)%need_compute)
THEN
723 files(file_num)%local = .true.
731 IF ( msg /=
'' )
THEN
732 IF (
fms_error_handler(
'diag_manager_mod::register_diag_field', trim(msg), err_msg) )
RETURN
735 freq = files(file_num)%output_freq
737 output_units = files(file_num)%output_units
738 output_fields(ind)%last_output = diag_file_init_time
739 output_fields(ind)%next_output = diag_time_inc(diag_file_init_time, freq, output_units, err_msg=msg)
740 IF ( msg /=
'' )
THEN
742 &
' file='//trim(files(file_num)%name)//
': '//trim(msg),err_msg))
RETURN
744 output_fields(ind)%next_next_output = &
745 & diag_time_inc(output_fields(ind)%next_output, freq, output_units, err_msg=msg)
746 IF ( msg /=
'' )
THEN
748 &
' file='//trim(files(file_num)%name)//
': '//trim(msg),err_msg) )
RETURN
750 IF ( debug_diag_manager .AND.
mpp_pe() == mpp_root_pe() .AND. output_fields(ind)%local_output )
THEN
751 WRITE (msg,
'(" lon(",F5.1,", ",F5.1,"), lat(",F5.1,", ",F5.1,"), dep(",F5.1,", ",F5.1,")")') &
752 & output_fields(ind)%output_grid%start(1),output_fields(ind)%output_grid%end(1),&
753 & output_fields(ind)%output_grid%start(2),output_fields(ind)%output_grid%end(2),&
754 & output_fields(ind)%output_grid%start(3),output_fields(ind)%output_grid%end(3)
755 WRITE(stdout_unit,* )
'module/output_field '//trim(module_name)//
'/'//trim(field_name)// &
756 &
' will be output in region:'//trim(msg)
761 IF ( len_trim(err_msg).GT.0 )
THEN
762 CALL error_mesg (
'diag_manager_mod::register_diag_field',&
763 & trim(err_msg)//
' for module/field '//trim(module_name)//
'/'//trim(field_name),&
774 & missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method,&
775 & tile_count, area, volume, realm)
776 CHARACTER(len=*),
INTENT(in) :: module_name, field_name
777 INTEGER,
DIMENSION(:),
INTENT(in) :: axes
778 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: long_name, units, standard_name
779 CLASS(*),
OPTIONAL,
INTENT(in) :: missing_value
780 CLASS(*),
DIMENSION(:),
OPTIONAL,
INTENT(in) :: range
781 LOGICAL,
OPTIONAL,
INTENT(in) :: mask_variant
782 LOGICAL,
OPTIONAL,
INTENT(in) :: dynamic
783 LOGICAL,
OPTIONAL,
INTENT(in) :: do_not_log
784 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: interp_method
788 INTEGER,
OPTIONAL,
INTENT(in) :: tile_count
789 INTEGER,
OPTIONAL,
INTENT(in) :: area
790 INTEGER,
OPTIONAL,
INTENT(in) :: volume
791 CHARACTER(len=*),
OPTIONAL,
INTENT(in) :: realm
793 REAL :: missing_value_use
794 REAL,
DIMENSION(2) :: range_use
795 INTEGER :: field, num_axes, j, out_num, k
796 INTEGER,
DIMENSION(3) :: siz, local_siz, local_start, local_end
797 INTEGER :: tile, file_num
798 LOGICAL :: mask_variant1, dynamic1, allow_log
799 CHARACTER(len=128) :: msg
800 INTEGER :: domain_type, i
801 character(len=256) :: axis_name
804 IF ( .NOT.module_is_initialized )
THEN
806 CALL error_mesg (
'diag_manager_mod::register_static_field_old',
'diag_manager has NOT been initialized', fatal)
810 IF (
PRESENT(missing_value) )
THEN
812 missing_value_use = cmor_missing_value
814 SELECT TYPE (missing_value)
815 TYPE IS (real(kind=r4_kind))
816 missing_value_use = missing_value
817 TYPE IS (real(kind=r8_kind))
818 missing_value_use = real(missing_value)
820 CALL error_mesg (
'diag_manager_mod::register_static_field',&
821 &
'The missing_value is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
826 IF (
PRESENT(mask_variant) )
THEN
827 mask_variant1 = mask_variant
829 mask_variant1 = .false.
832 IF (
PRESENT(dynamic) )
THEN
838 IF (
PRESENT(tile_count) )
THEN
844 IF (
PRESENT(do_not_log) )
THEN
845 allow_log = .NOT.do_not_log
851 IF (
PRESENT(range) )
THEN
852 IF (
SIZE(range) .NE. 2 )
THEN
854 CALL error_mesg (
'diag_manager_mod::register_static_field',
'extent of range should be 2', fatal)
860 IF ( do_diag_field_log.AND.allow_log )
THEN
862 & long_name, units, missing_value=missing_value, range=range, &
872 domain_type = axis_compatible_check(axes,field_name)
875 IF ( .NOT.input_fields(field)%register )
THEN
880 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '//trim(module_name)//
'/'//&
881 & trim(field_name)//
' is not registered for tile_count = 1, should not register for tile_count > 1',&
887 DO j = 1, input_fields(field)%num_output_fields
888 out_num = input_fields(field)%output_fields(j)
889 file_num = output_fields(out_num)%output_file
890 IF(input_fields(field)%local)
THEN
891 CALL init_output_field(module_name, field_name,output_fields(out_num)%output_name,&
892 & files(file_num)%name,output_fields(out_num)%time_method, output_fields(out_num)%pack,&
893 & tile, input_fields(field)%local_coord)
895 CALL init_output_field(module_name, field_name,output_fields(out_num)%output_name,&
896 & files(file_num)%name,output_fields(out_num)%time_method, output_fields(out_num)%pack, tile)
906 input_fields(field)%static = .true.
908 IF ( input_fields(field)%register .AND.
mpp_pe() == mpp_root_pe() )
THEN
913 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '//trim(module_name)//
'/'//&
914 & trim(field_name)//
' ALREADY registered, should not register twice', fatal)
918 IF (
PRESENT(volume).AND.
PRESENT(area) )
THEN
919 IF ( area.EQ.volume )
THEN
920 CALL error_mesg (
'diag_manager_mod::register_static_field_old',
'module/output_field '&
921 &//trim(module_name)//
'/'// trim(field_name)//
' AREA and VOLUME CANNOT be the same variable.&
922 & Contact the developers.',&
928 IF (
PRESENT(area) )
THEN
930 CALL error_mesg (
'diag_manager_mod::register_static_field_old',
'module/output_field '&
931 &//trim(module_name)//
'/'// trim(field_name)//
' AREA measures field NOT found in diag_table.&
932 & Contact the model liaison.n',&
936 IF (
PRESENT(volume) )
THEN
937 IF ( volume < 0 )
THEN
938 CALL error_mesg (
'diag_manager_mod::register_static_field_old',
'module/output_field '&
939 &//trim(module_name)//
'/'// trim(field_name)//
' VOLUME measures field NOT found in diag_table&
940 & Contact the model liaison.',&
946 input_fields(field)%register = .true.
948 input_fields(field)%mask_variant = mask_variant1
950 input_fields(field)%issued_mask_ignore_warning = .false.
953 IF (
PRESENT(long_name) )
THEN
954 input_fields(field)%long_name = trim(long_name)
956 input_fields(field)%long_name = input_fields(field)%field_name
959 IF (
PRESENT(standard_name) ) input_fields(field)%standard_name = standard_name
961 IF (
PRESENT(units) )
THEN
962 input_fields(field)%units = trim(units)
964 input_fields(field)%units =
'none'
967 IF (
PRESENT(missing_value) )
THEN
968 input_fields(field)%missing_value = missing_value_use
969 input_fields(field)%missing_value_present = .true.
971 input_fields(field)%missing_value_present = .false.
974 IF (
PRESENT(range) )
THEN
976 TYPE IS (real(kind=r4_kind))
978 TYPE IS (real(kind=r8_kind))
979 range_use = real(range)
981 CALL error_mesg (
'diag_manager_mod::register_static_field',&
982 &
'The range is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
984 input_fields(field)%range = range_use
986 input_fields(field)%range_present = range_use(2) .gt. range_use(1)
988 input_fields(field)%range = (/ 1., 0. /)
989 input_fields(field)%range_present = .false.
992 IF (
PRESENT(interp_method) )
THEN
993 IF ( trim(interp_method) .NE.
'conserve_order1' .AND.&
994 & trim(interp_method) .NE.
'conserve_order2' .AND.&
995 & trim(interp_method) .NE.
'none' )
THEN
1001 CALL error_mesg (
'diag_manager_mod::register_diag_field',&
1002 &
'when registering module/output_field '//trim(module_name)//
'/'//&
1003 & trim(field_name)//
', the optional argument interp_method = '//trim(interp_method)//&
1004 &
', but it should be "conserve_order1", "conserve_order2", or "none"', fatal)
1006 input_fields(field)%interp_method = trim(interp_method)
1008 input_fields(field)%interp_method =
''
1012 num_axes =
SIZE(axes(:))
1013 input_fields(field)%axes(1:num_axes) = axes
1014 input_fields(field)%num_axes = num_axes
1018 IF ( axes(j) .LE. 0 )
THEN
1022 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'module/output_field '//trim(module_name)//
'/'//&
1023 & trim(field_name)//
' has non-positive axis_id', fatal)
1025 siz(j) = get_axis_length(axes(j))
1030 input_fields(field)%size(j) = siz(j)
1037 DO j = 1, input_fields(field)%num_output_fields
1038 out_num = input_fields(field)%output_fields(j)
1040 IF ( output_fields(out_num)%pack>=4 .AND. .NOT.input_fields(field)%range_present )
THEN
1041 IF(
mpp_pe() .EQ. mpp_root_pe())
THEN
1045 CALL error_mesg (
'diag_manager_mod::register_diag_field ',
'output_field '//trim(field_name)// &
1046 ' has pack >=4, range is REQUIRED in register_diag_field', fatal)
1051 IF ( .NOT.dynamic1 ) output_fields(out_num)%n_diurnal_samples = 1
1055 file_num = output_fields(out_num)%output_file
1056 if (domain_type .eq. diag_axis_2ddomain)
then
1057 if (files(file_num)%use_domainUG)
then
1058 call error_mesg(
"diag_manager_mod::register_static_field_old", &
1059 "Diagnostics living on a structured grid" &
1060 //
" and an unstructured grid cannot exist" &
1061 //
" in the same file (" &
1062 //trim(files(file_num)%name)//
")", &
1064 elseif (.not. files(file_num)%use_domain2D)
then
1065 files(file_num)%use_domain2D = .true.
1068 if (files(file_num)%use_domain2D)
then
1069 call error_mesg(
"diag_manager_mod::register_static_field_old", &
1070 "Diagnostics living on a structured grid" &
1071 //
" and an unstructured grid cannot exist" &
1072 //
" in the same file (" &
1073 //trim(files(file_num)%name)//
")", &
1075 elseif (.not. files(file_num)%use_domainUG)
then
1076 files(file_num)%use_domainUG = .true.
1082 IF ( output_fields(out_num)%reduced_k_range )
THEN
1091 local_start(2) = output_fields(out_num)%output_grid%l_start_indx(2)
1092 local_end(2) = output_fields(out_num)%output_grid%l_end_indx(2)
1093 local_siz(2) = local_end(2) - local_start(2) + 1
1094 allocate(output_fields(out_num)%buffer(siz(1),local_siz(2),siz(3), &
1095 output_fields(out_num)%n_diurnal_samples))
1096 output_fields(out_num)%region_elements = siz(1)*local_siz(2)*siz(3)
1097 output_fields(out_num)%reduced_k_unstruct = .true.
1099 local_start(3) = output_fields(out_num)%output_grid%l_start_indx(3)
1100 local_end(3) = output_fields(out_num)%output_grid%l_end_indx(3)
1101 local_siz(3) = local_end(3) - local_start(3) + 1
1102 allocate(output_fields(out_num)%buffer(siz(1),siz(2),local_siz(3), &
1103 output_fields(out_num)%n_diurnal_samples))
1104 output_fields(out_num)%region_elements = siz(1)*siz(2)*local_siz(3)
1105 output_fields(out_num)%reduced_k_unstruct = .false.
1107 output_fields(out_num)%total_elements = siz(1)*siz(2)*siz(3)
1110 IF ( output_fields(out_num)%time_max )
THEN
1111 output_fields(out_num)%buffer = max_value
1112 ELSE IF ( output_fields(out_num)%time_min )
THEN
1113 output_fields(out_num)%buffer = min_value
1115 output_fields(out_num)%buffer = empty
1117 ELSE IF ( output_fields(out_num)%local_output )
THEN
1118 IF (
SIZE(axes(:)) .LE. 1 )
THEN
1120 CALL error_mesg (
'diag_manager_mod::register_diag_field',
'axes of '//trim(field_name)//&
1121 &
' must >= 2 for local output', fatal)
1124 IF ( output_fields(out_num)%need_compute )
THEN
1126 local_start(k) = output_fields(out_num)%output_grid%l_start_indx(k)
1127 local_end(k) = output_fields(out_num)%output_grid%l_end_indx(k)
1128 local_siz(k) = local_end(k) - local_start(k) +1
1130 ALLOCATE(output_fields(out_num)%buffer(local_siz(1), local_siz(2), local_siz(3),&
1131 & output_fields(out_num)%n_diurnal_samples))
1132 IF(output_fields(out_num)%time_max)
THEN
1133 output_fields(out_num)%buffer = max_value
1134 ELSE IF(output_fields(out_num)%time_min)
THEN
1135 output_fields(out_num)%buffer = min_value
1137 output_fields(out_num)%buffer = empty
1139 output_fields(out_num)%region_elements = local_siz(1)*local_siz(2)*local_siz(3)
1140 output_fields(out_num)%total_elements = siz(1)*siz(2)*siz(3)
1141 files(output_fields(out_num)%output_file)%local = .true.
1145 ALLOCATE(output_fields(out_num)%buffer(siz(1), siz(2), siz(3),&
1146 & output_fields(out_num)%n_diurnal_samples))
1147 IF(output_fields(out_num)%time_max)
THEN
1148 output_fields(out_num)%buffer = max_value
1149 ELSE IF(output_fields(out_num)%time_min)
THEN
1150 output_fields(out_num)%buffer = min_value
1152 output_fields(out_num)%buffer = empty
1154 output_fields(out_num)%total_elements = siz(1)*siz(2)*siz(3)
1158 output_fields(out_num)%static = .true.
1160 IF ( .NOT.dynamic1 .AND. output_fields(out_num)%time_ops )
THEN
1161 WRITE (msg,
'(a,"/",a)') trim(module_name), trim(field_name)
1162 IF (
mpp_pe() .EQ. mpp_root_pe() )
THEN
1169 CALL error_mesg (
'diag_manager_mod::register_static_field_old',&
1170 &
'module/field '//trim(msg)//
' is STATIC. Cannot perform time operations&
1171 & average, maximum, or minimum on static fields. Setting the time operation&
1172 & to "NONE" for this field.', warning)
1174 output_fields(out_num)%time_ops = .false.
1175 output_fields(out_num)%time_average = .false.
1176 output_fields(out_num)%time_method =
'point'
1181 output_fields(out_num)%num_axes = input_fields(field)%num_axes
1183 IF ( .NOT.output_fields(out_num)%local_output )
THEN
1184 output_fields(out_num)%axes(1:input_fields(field)%num_axes) =&
1185 & input_fields(field)%axes(1:input_fields(field)%num_axes)
1187 output_fields(out_num)%axes(1:input_fields(field)%num_axes) =&
1188 & output_fields(out_num)%output_grid%subaxes(1:input_fields(field)%num_axes)
1193 IF ( output_fields(out_num)%n_diurnal_samples > 1 )
THEN
1194 output_fields(out_num)%axes(output_fields(out_num)%num_axes+1) =&
1196 output_fields(out_num)%num_axes = output_fields(out_num)%num_axes+1
1199 IF ( output_fields(out_num)%reduced_k_range )
THEN
1203 output_fields(out_num)%axes(2) = output_fields(out_num)%output_grid%subaxes(2)
1205 output_fields(out_num)%axes(3) = output_fields(out_num)%output_grid%subaxes(3)
1211 output_fields(out_num)%Time_of_prev_field_data = time_zero
1215 IF ( len_trim(msg).GT.0 )
THEN
1216 CALL error_mesg (
'diag_manager_mod::register_static_field_old',&
1217 & trim(msg)//
' for module/field '//trim(module_name)//
'/'//trim(field_name),&
1222 IF (
PRESENT(realm) )
THEN
1223 CALL prepend_attribute(output_fields(out_num),
'modeling_realm', lowercase(trim(realm)))
1227 IF ( input_fields(field)%mask_variant )
THEN
1228 DO j = 1, input_fields(field)%num_output_fields
1229 out_num = input_fields(field)%output_fields(j)
1230 IF(output_fields(out_num)%time_average)
THEN
1236 if (output_fields(out_num)%reduced_k_range .and. &
1238 allocate(output_fields(out_num)%counter(siz(1),local_siz(2),siz(3), &
1239 output_fields(out_num)%n_diurnal_samples))
1241 allocate(output_fields(out_num)%counter(siz(1),siz(2),siz(3), &
1242 output_fields(out_num)%n_diurnal_samples))
1245 output_fields(out_num)%counter = 0.0
1256 CHARACTER(len=*),
INTENT(in) :: module_name
1257 CHARACTER(len=*),
INTENT(in) :: field_name
1262 if (use_modern_diag)
then
1263 get_diag_field_id = fms_diag_object%fms_get_diag_field_id_from_name(module_name, field_name)
1274 INTEGER,
INTENT(in) :: field
1276 INTEGER,
INTENT(out) :: out_field_id
1277 INTEGER,
INTENT(out) :: out_file_id
1279 INTEGER :: i, cm_ind, cm_file_num
1283 rel_file = rel_field%output_file
1291 DO i = 1, input_fields(field)%num_output_fields
1292 cm_ind = input_fields(field)%output_fields(i)
1293 cm_file_num = output_fields(cm_ind)%output_file
1295 IF ( cm_file_num.EQ.rel_file.AND.&
1296 & (( (output_fields(cm_ind)%time_ops.EQV.rel_field%time_ops) .AND.&
1297 & (output_fields(cm_ind)%next_output.EQ.rel_field%next_output) .AND.&
1298 & (output_fields(cm_ind)%last_output.EQ.rel_field%last_output) ).OR.&
1299 & (output_fields(cm_ind)%static.OR.rel_field%static) ) )
THEN
1301 out_field_id = cm_ind
1302 out_file_id = cm_file_num
1309 DO i = 1, input_fields(field)%num_output_fields
1310 cm_ind = input_fields(field)%output_fields(i)
1311 cm_file_num = output_fields(cm_ind)%output_file
1322 IF ( output_fields(cm_ind)%static.OR.rel_field%static )
THEN
1324 out_field_id = cm_ind
1325 out_file_id = cm_file_num
1335 INTEGER,
INTENT(in),
OPTIONAL :: area
1336 INTEGER,
INTENT(in),
OPTIONAL :: volume
1337 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1339 INTEGER :: cm_ind, cm_file_num, file_num
1341 IF (
PRESENT(err_msg) )
THEN
1346 IF (
PRESENT(area) )
THEN
1347 IF ( area.LE.0 )
THEN
1349 &
'AREA field not in diag_table for field '//trim(input_fields(output_field%input_field)%module_name)//&
1350 &
'/'//trim(input_fields(output_field%input_field)%field_name), err_msg) )
RETURN
1354 IF (
PRESENT(volume) )
THEN
1355 IF ( volume.LE.0 )
THEN
1357 &
'VOLUME field not in diag_table for field '//trim(input_fields(output_field%input_field)%module_name)//&
1358 &
'/'//trim(input_fields(output_field%input_field)%field_name), err_msg) )
RETURN
1363 file_num = output_field%output_file
1366 IF (
PRESENT(area) )
THEN
1369 &
'area: '//trim(output_fields(cm_ind)%output_name))
1370 IF ( cm_file_num.NE.file_num )
THEN
1376 &
'AREA measures field "'//trim(input_fields(area)%module_name)//
'/'//&
1377 & trim(input_fields(area)%field_name)//&
1378 &
'" NOT in diag_table with correct output frequency for field '//&
1379 & trim(input_fields(output_field%input_field)%module_name)//&
1380 &
'/'//trim(input_fields(output_field%input_field)%field_name), err_msg) )
RETURN
1385 IF (
PRESENT(volume) )
THEN
1388 &
'volume: '//trim(output_fields(cm_ind)%output_name))
1389 IF ( cm_file_num.NE.file_num )
THEN
1395 &
'VOLUME measures field "'//trim(input_fields(volume)%module_name)//
'/'//&
1396 & trim(input_fields(volume)%field_name)//&
1397 &
'" NOT in diag_table with correct output frequency for field '//&
1398 & trim(input_fields(output_field%input_field)%module_name)//&
1399 &
'/'//trim(input_fields(output_field%input_field)%field_name), err_msg) )
RETURN
1410 INTEGER,
intent(in) :: file_num
1411 INTEGER,
intent(in) :: cm_file_num
1412 INTEGER,
intent(in) :: cm_ind
1414 INTEGER :: year, month, day, hour, minute, second
1416 CHARACTER(len=25) :: date_prefix
1417 CHARACTER(len=256) :: asso_file_name
1420 IF ( prepend_date )
THEN
1421 CALL get_date(diag_init_time, year, month, day, hour, minute, second)
1422 WRITE (date_prefix,
'(1I20.4, 2I2.2,".")') year, month, day
1423 date_prefix=adjustl(date_prefix)
1431 IF ( len_trim(files(cm_file_num)%name)+17 > len(asso_file_name) )
THEN
1432 CALL error_mesg (
'diag_manager_mod::add_associated_files',&
1433 &
'Length of asso_file_name is not long enough to hold the associated file name. '&
1434 & //
'Contact the developer', fatal)
1436 asso_file_name = trim(files(cm_file_num)%name)
1447 n = max(len_trim(asso_file_name),3)
1448 if (asso_file_name(n-2:n).NE.
'.nc') asso_file_name = trim(asso_file_name)//
'.nc'
1452 & trim(output_fields(cm_ind)%output_name)//
': '//&
1453 & trim(date_prefix)//trim(asso_file_name))
1458 INTEGER,
INTENT(in) :: diag_field_id
1459 CLASS(*),
INTENT(in) :: field
1460 TYPE(
time_type),
INTENT(in),
OPTIONAL :: time
1461 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1463 CLASS(*),
allocatable :: field_out(:, :, :)
1466 IF ( diag_field_id <= 0 )
THEN
1473 TYPE IS (real(kind=r4_kind))
1474 allocate(real(r4_kind) :: field_out(1,1,1))
1475 select type(field_out)
1476 type is (real(r4_kind))
1477 field_out(1, 1, 1) = field
1479 call error_mesg(
'diag_manager_mod::send_data_0d', &
1480 &
'Error allocating field out as real(r4_kind)', fatal)
1482 TYPE IS (real(kind=r8_kind))
1483 allocate(real(r8_kind) :: field_out(1,1,1))
1484 select type(field_out)
1485 type is (real(r8_kind))
1486 field_out(1, 1, 1) = field
1488 call error_mesg(
'diag_manager_mod::send_data_0d', &
1489 &
'Error allocating field out as real(r8_kind)', fatal)
1492 CALL error_mesg (
'diag_manager_mod::send_data_0d',&
1493 &
'The field is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1500 LOGICAL FUNCTION send_data_1d(diag_field_id, field, time, is_in, mask, rmask, ie_in, weight, err_msg)
1501 INTEGER,
INTENT(in) :: diag_field_id
1502 CLASS(*),
DIMENSION(:),
INTENT(in) :: field
1503 CLASS(*),
INTENT(in),
OPTIONAL :: weight
1504 CLASS(*),
INTENT(in),
DIMENSION(:),
OPTIONAL :: rmask
1505 TYPE (
time_type),
INTENT(in),
OPTIONAL :: time
1506 INTEGER,
INTENT(in),
OPTIONAL :: is_in, ie_in
1507 LOGICAL,
INTENT(in),
DIMENSION(:),
OPTIONAL :: mask
1508 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1510 CLASS(*),
ALLOCATABLE :: field_out(:,:,:)
1511 LOGICAL,
DIMENSION(SIZE(field(:)), 1, 1) :: mask_out
1514 IF ( diag_field_id <= 0 )
THEN
1522 TYPE IS (real(kind=r4_kind))
1523 allocate(real(r4_kind) :: field_out(
SIZE(field),1,1))
1524 select type(field_out)
1525 type is (real(r4_kind))
1526 field_out(:, 1, 1) = field
1528 call error_mesg(
'diag_manager_mod::send_data_1d', &
1529 &
'Error allocating field out as real(r4_kind)', fatal)
1531 TYPE IS (real(kind=r8_kind))
1532 allocate(real(r8_kind) :: field_out(
SIZE(field),1,1))
1533 select type(field_out)
1534 type is (real(r8_kind))
1535 field_out(:, 1, 1) = field
1537 call error_mesg(
'diag_manager_mod::send_data_1d', &
1538 &
'Error allocating field out as real(r8_kind)', fatal)
1541 CALL error_mesg (
'diag_manager_mod::send_data_1d',&
1542 &
'The field is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1546 IF (
PRESENT(mask) )
THEN
1547 mask_out(:, 1, 1) = mask
1552 IF (
PRESENT(rmask) )
THEN
1554 TYPE IS (real(kind=r4_kind))
1555 WHERE (rmask < 0.5_r4_kind) mask_out(:, 1, 1) = .false.
1556 TYPE IS (real(kind=r8_kind))
1557 WHERE (rmask < 0.5_r8_kind) mask_out(:, 1, 1) = .false.
1559 CALL error_mesg (
'diag_manager_mod::send_data_1d',&
1560 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1564 IF (
PRESENT(mask) .OR.
PRESENT(rmask) )
THEN
1565 IF (
PRESENT(is_in) .OR.
PRESENT(ie_in) )
THEN
1567 & mask=mask_out, ie_in=ie_in, je_in=1, ke_in=1, weight=weight, err_msg=err_msg)
1570 & weight=weight, err_msg=err_msg)
1573 IF (
PRESENT(is_in) .OR.
PRESENT(ie_in) )
THEN
1575 & ie_in=ie_in, je_in=1, ke_in=1, weight=weight, err_msg=err_msg)
1584 & mask, rmask, ie_in, je_in, weight, err_msg)
1585 INTEGER,
INTENT(in) :: diag_field_id
1586 CLASS(*),
INTENT(in),
DIMENSION(:,:) :: field
1587 CLASS(*),
INTENT(in),
OPTIONAL :: weight
1588 TYPE (
time_type),
INTENT(in),
OPTIONAL :: time
1589 INTEGER,
INTENT(in),
OPTIONAL :: is_in, js_in, ie_in, je_in
1590 LOGICAL,
INTENT(in),
DIMENSION(:,:),
OPTIONAL :: mask
1591 CLASS(*),
INTENT(in),
DIMENSION(:,:),
OPTIONAL :: rmask
1592 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1594 CLASS(*),
ALLOCATABLE :: field_out(:,:,:)
1595 LOGICAL,
DIMENSION(SIZE(field,1),SIZE(field,2),1) :: mask_out
1598 IF ( diag_field_id <= 0 )
THEN
1605 TYPE IS (real(kind=r4_kind))
1606 allocate(real(r4_kind) :: field_out(
SIZE(field,1),
SIZE(field,2),1))
1607 select type(field_out)
1608 type is (real(r4_kind))
1609 field_out(:, :, 1) = field
1611 call error_mesg(
'diag_manager_mod::send_data_2d', &
1612 &
'Error allocating field out as real(r4_kind)', fatal)
1614 TYPE IS (real(kind=r8_kind))
1615 allocate(real(r8_kind) :: field_out(
SIZE(field,1),
SIZE(field,2),1))
1616 select type(field_out)
1617 type is (real(r8_kind))
1618 field_out(:, :, 1) = field
1620 call error_mesg(
'diag_manager_mod::send_data_2d', &
1621 &
'Error allocating field out as real(r8_kind)', fatal)
1624 CALL error_mesg (
'diag_manager_mod::send_data_2d',&
1625 &
'The field is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1629 IF (
PRESENT(mask) )
THEN
1630 mask_out(:, :, 1) = mask
1635 IF (
PRESENT(rmask) )
THEN
1637 TYPE IS (real(kind=r4_kind))
1638 WHERE ( rmask < 0.5_r4_kind ) mask_out(:, :, 1) = .false.
1639 TYPE IS (real(kind=r8_kind))
1640 WHERE ( rmask < 0.5_r8_kind ) mask_out(:, :, 1) = .false.
1642 CALL error_mesg (
'diag_manager_mod::send_data_2d',&
1643 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1647 IF (
PRESENT(mask) .OR.
PRESENT(rmask) )
THEN
1649 & mask=mask_out, ie_in=ie_in, je_in=je_in, ke_in=1, weight=weight, err_msg=err_msg)
1652 & ie_in=ie_in, je_in=je_in, ke_in=1, weight=weight, err_msg=err_msg)
1657 LOGICAL FUNCTION send_data_3d(diag_field_id, field, time, is_in, js_in, ks_in, &
1658 & mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
1659 INTEGER,
INTENT(in) :: diag_field_id
1660 CLASS(*),
DIMENSION(:,:,:),
INTENT(in) :: field
1661 CLASS(*),
INTENT(in),
OPTIONAL :: weight
1662 TYPE (
time_type),
INTENT(in),
OPTIONAL :: time
1663 INTEGER,
INTENT(in),
OPTIONAL :: is_in, js_in, ks_in,ie_in,je_in, ke_in
1664 LOGICAL,
DIMENSION(:,:,:),
INTENT(in),
OPTIONAL :: mask
1665 CLASS(*),
DIMENSION(:,:,:),
INTENT(in),
OPTIONAL :: rmask
1666 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1668 if (
present(mask) .and.
present(rmask))
then
1670 mask=mask, rmask=rmask, ie_in=ie_in, je_in=je_in, ke_in=ke_in, weight=weight, &
1672 elseif (
present(rmask))
then
1674 rmask=rmask, ie_in=ie_in, je_in=je_in, ke_in=ke_in, weight=weight, err_msg=err_msg)
1675 elseif (
present(mask))
then
1677 mask=mask, ie_in=ie_in, je_in=je_in, ke_in=ke_in, weight=weight, err_msg=err_msg)
1680 ie_in=ie_in, je_in=je_in, ke_in=ke_in, weight=weight, err_msg=err_msg)
1687 & mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
1688 INTEGER,
INTENT(in) :: diag_field_id
1689 CLASS(*),
DIMENSION(:,:,:),
INTENT(in),
TARGET,
CONTIGUOUS :: field
1690 CLASS(*),
INTENT(in),
OPTIONAL :: weight
1691 TYPE (
time_type),
INTENT(in),
OPTIONAL :: time
1692 INTEGER,
INTENT(in),
OPTIONAL :: is_in, js_in, ks_in,ie_in,je_in, ke_in
1693 LOGICAL,
DIMENSION(:,:,:),
INTENT(in),
OPTIONAL,
contiguous,
target :: mask
1694 CLASS(*),
DIMENSION(:,:,:),
INTENT(in),
OPTIONAL,
contiguous,
target :: rmask
1695 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
1699 INTEGER :: pow_value
1701 INTEGER :: i, out_num, file_num, n1, n2, n3, number_of_outputs, ii,f1,f2,f3,f4
1702 INTEGER :: freq, units, is, js, ks, ie, je, ke, i1, j1,k1, j, k
1703 INTEGER,
DIMENSION(3) :: l_start
1704 INTEGER,
DIMENSION(3) :: l_end
1714 INTEGER :: numthreads
1715 INTEGER :: active_omp_level
1716 #if defined(_OPENMP)
1717 INTEGER :: omp_get_num_threads
1718 INTEGER :: omp_get_level
1720 LOGICAL :: average, phys_window, need_compute
1721 LOGICAL :: reduced_k_range, local_output
1722 LOGICAL :: time_max, time_min, time_rms, time_sum
1723 LOGICAL :: missvalue_present
1724 LOGICAL,
ALLOCATABLE,
DIMENSION(:,:,:) :: oor_mask
1725 CHARACTER(len=256) :: err_msg_local
1726 CHARACTER(len=128) :: error_string, error_string1
1728 REAL,
ALLOCATABLE,
DIMENSION(:,:,:) :: field_out
1729 class(*),
allocatable,
dimension(:,:,:,:) :: field_remap
1730 logical,
allocatable,
dimension(:,:,:,:) :: mask_remap
1731 class(*),
allocatable,
dimension(:,:,:,:) :: rmask_remap
1732 REAL(kind=r4_kind),
POINTER,
DIMENSION(:,:,:) :: rmask_ptr_r4
1733 REAL(kind=r8_kind),
POINTER,
DIMENSION(:,:,:) :: rmask_ptr_r8
1737 LOGICAL :: mf_result
1739 REAL :: rmask_threshold
1741 character(len=:),
allocatable :: field_name
1744 IF ( diag_field_id <= 0 )
THEN
1751 IF (
PRESENT(err_msg) ) err_msg =
''
1752 IF ( .NOT.module_is_initialized )
THEN
1753 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'diag_manager NOT initialized', err_msg) )
RETURN
1766 ALLOCATE(field_out(
SIZE(field,1),
SIZE(field,2),
SIZE(field,3)), stat=status)
1767 IF ( status .NE. 0 )
THEN
1768 WRITE (err_msg_local, fmt=
'("Unable to allocate field_out(",I5,",",I5,",",I5,"). (STAT: ",I5,")")')&
1769 &
SIZE(field,1),
SIZE(field,2),
SIZE(field,3), status
1770 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
RETURN
1773 TYPE IS (real(kind=r4_kind))
1775 TYPE IS (real(kind=r8_kind))
1776 field_out = real(field)
1778 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
1779 &
'The field is not one of the supported types (real(kind=4) or real(kind=8)). '//&
1780 &
'If using an integer, please set use_modern_diag=.t. in the diag_manager_nml.', fatal)
1783 modern_if:
iF (use_modern_diag)
then
1784 field_name = fms_diag_object%fms_get_field_name_from_id(diag_field_id)
1785 call copy_3d_to_4d(field, field_remap, trim(field_name)//
"'s data")
1786 if (
present(rmask))
call copy_3d_to_4d(rmask, rmask_remap, trim(field_name)//
"'s mask")
1787 if (
present(mask))
then
1788 allocate(mask_remap(1:
size(mask,1), 1:
size(mask,2), 1:
size(mask,3), 1))
1789 mask_remap(:,:,:,1) = mask
1791 diag_send_data = fms_diag_object%fms_diag_accept_data(diag_field_id, field_remap, mask_remap, rmask_remap, &
1792 time, is_in, js_in, ks_in, ie_in, je_in, ke_in, weight, &
1794 deallocate (field_remap)
1795 if (
allocated(mask_remap))
deallocate(mask_remap)
1796 if (
allocated(rmask_remap))
deallocate(rmask_remap)
1799 ALLOCATE(oor_mask(
SIZE(field,1),
SIZE(field,2),
SIZE(field,3)), stat=status)
1800 IF ( status .NE. 0 )
THEN
1801 WRITE (err_msg_local, fmt=
'("Unable to allocate oor_mask(",I5,",",I5,",",I5,"). (STAT: ",I5,")")')&
1802 &
SIZE(field,1),
SIZE(field,2),
SIZE(field,3), status
1803 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
RETURN
1806 IF (
PRESENT(mask) )
THEN
1812 rmask_ptr_r4 => null()
1813 rmask_ptr_r8 => null()
1814 IF (
PRESENT(rmask) )
THEN
1816 TYPE IS (real(kind=r4_kind))
1817 WHERE ( rmask < 0.5_r4_kind ) oor_mask = .false.
1818 rmask_threshold = 0.5_r4_kind
1819 rmask_ptr_r4 => rmask
1820 TYPE IS (real(kind=r8_kind))
1821 WHERE ( rmask < 0.5_r8_kind ) oor_mask = .false.
1822 rmask_threshold = 0.5_r8_kind
1823 rmask_ptr_r8 => rmask
1825 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
1826 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1841 IF (
PRESENT(ie_in) )
THEN
1842 IF ( .NOT.
PRESENT(is_in) )
THEN
1843 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'ie_in present without is_in', err_msg) )
THEN
1844 DEALLOCATE(field_out)
1845 DEALLOCATE(oor_mask)
1849 IF (
PRESENT(js_in) .AND. .NOT.
PRESENT(je_in) )
THEN
1851 &
'is_in and ie_in present, but js_in present without je_in', err_msg) )
THEN
1852 DEALLOCATE(field_out)
1853 DEALLOCATE(oor_mask)
1858 IF (
PRESENT(je_in) )
THEN
1859 IF ( .NOT.
PRESENT(js_in) )
THEN
1860 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'je_in present without js_in', err_msg) )
THEN
1861 DEALLOCATE(field_out)
1862 DEALLOCATE(oor_mask)
1866 IF (
PRESENT(is_in) .AND. .NOT.
PRESENT(ie_in) )
THEN
1868 &
'js_in and je_in present, but is_in present without ie_in', err_msg))
THEN
1869 DEALLOCATE(field_out)
1870 DEALLOCATE(oor_mask)
1880 IF (
PRESENT(is_in) ) is = is_in
1881 IF (
PRESENT(js_in) ) js = js_in
1882 IF (
PRESENT(ks_in) ) ks = ks_in
1889 IF (
PRESENT(ie_in) ) ie = ie_in
1890 IF (
PRESENT(je_in) ) je = je_in
1891 IF (
PRESENT(ke_in) ) ke = ke_in
1892 twohi = n1-(ie-is+1)
1893 IF ( mod(twohi,2) /= 0 )
THEN
1894 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'non-symmetric halos in first dimension', &
1896 DEALLOCATE(field_out)
1897 DEALLOCATE(oor_mask)
1901 twohj = n2-(je-js+1)
1902 IF ( mod(twohj,2) /= 0 )
THEN
1903 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'non-symmetric halos in second dimension', &
1905 DEALLOCATE(field_out)
1906 DEALLOCATE(oor_mask)
1915 IF (
PRESENT(ie_in) .AND.
PRESENT(je_in) )
THEN
1929 IF (
PRESENT(weight) )
THEN
1930 SELECT TYPE (weight)
1931 TYPE IS (real(kind=r4_kind))
1933 TYPE IS (real(kind=r8_kind))
1934 weight1 = real(weight)
1936 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
1937 &
'The weight is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
1944 missvalue_present = input_fields(diag_field_id)%missing_value_present
1945 IF ( missvalue_present ) missvalue = input_fields(diag_field_id)%missing_value
1947 number_of_outputs = input_fields(diag_field_id)%num_output_fields
1949 input_fields(diag_field_id)%numthreads = 1
1951 #if defined(_OPENMP)
1952 input_fields(diag_field_id)%numthreads = omp_get_num_threads()
1953 input_fields(diag_field_id)%active_omp_level = omp_get_level()
1955 numthreads = input_fields(diag_field_id)%numthreads
1956 active_omp_level = input_fields(diag_field_id)%active_omp_level
1959 if(
present(time)) input_fields(diag_field_id)%time = time
1962 IF ( input_fields(diag_field_id)%range_present )
THEN
1963 IF ( issue_oor_warnings .OR. oor_warnings_fatal )
THEN
1964 WRITE (error_string,
'("[",ES14.5E3,",",ES14.5E3,"]")')&
1965 & input_fields(diag_field_id)%range(1:2)
1966 WRITE (error_string1,
'("(Min: ",ES14.5E3,", Max: ",ES14.5E3, ")")')&
1967 & minval(field_out(f1:f2,f3:f4,ks:ke),mask=oor_mask(f1:f2,f3:f4,ks:ke)),&
1968 & maxval(field_out(f1:f2,f3:f4,ks:ke),mask=oor_mask(f1:f2,f3:f4,ks:ke))
1969 IF ( missvalue_present )
THEN
1970 IF ( any(oor_mask(f1:f2,f3:f4,ks:ke) .AND.&
1971 & ((field_out(f1:f2,f3:f4,ks:ke) < input_fields(diag_field_id)%range(1) .OR.&
1972 & field_out(f1:f2,f3:f4,ks:ke) > input_fields(diag_field_id)%range(2)).AND.&
1973 & field_out(f1:f2,f3:f4,ks:ke) .NE. missvalue)) )
THEN
1979 CALL error_mesg(
'diag_manager_mod::send_data_3d',&
1981 &trim(input_fields(diag_field_id)%module_name)//
' in field '//&
1982 &trim(input_fields(diag_field_id)%field_name)//
' '&
1983 &//trim(error_string1)//&
1984 &
' is outside the range '//trim(error_string)//
',&
1985 & and not equal to the missing value.',&
1989 IF ( any(oor_mask(f1:f2,f3:f4,ks:ke) .AND.&
1990 & (field_out(f1:f2,f3:f4,ks:ke) < input_fields(diag_field_id)%range(1) .OR.&
1991 & field_out(f1:f2,f3:f4,ks:ke) > input_fields(diag_field_id)%range(2))) )
THEN
1996 CALL error_mesg(
'diag_manager_mod::send_data_3d',&
1998 &trim(input_fields(diag_field_id)%module_name)//
' in field '//&
1999 &trim(input_fields(diag_field_id)%field_name)//
' '&
2000 &//trim(error_string1)//&
2001 &
' is outside the range '//trim(error_string)//
'.',&
2009 num_out_fields:
DO ii = 1, number_of_outputs
2011 out_num = input_fields(diag_field_id)%output_fields(ii)
2014 local_output = output_fields(out_num)%local_output
2016 need_compute = output_fields(out_num)%need_compute
2018 reduced_k_range = output_fields(out_num)%reduced_k_range
2021 IF ( local_output .AND. (.NOT.need_compute) ) cycle
2024 file_num = output_fields(out_num)%output_file
2025 IF(file_num == max_files) cycle
2027 freq = files(file_num)%output_freq
2028 units = files(file_num)%output_units
2030 average = output_fields(out_num)%time_average
2033 time_rms = output_fields(out_num)%time_rms
2035 pow_value = output_fields(out_num)%pow_value
2037 time_max = output_fields(out_num)%time_max
2038 time_min = output_fields(out_num)%time_min
2040 time_sum = output_fields(out_num)%time_sum
2041 IF ( output_fields(out_num)%total_elements >
SIZE(field_out(f1:f2,f3:f4,ks:ke)) )
THEN
2042 output_fields(out_num)%phys_window = .true.
2044 output_fields(out_num)%phys_window = .false.
2046 phys_window = output_fields(out_num)%phys_window
2047 IF ( need_compute )
THEN
2048 l_start = output_fields(out_num)%output_grid%l_start_indx
2049 l_end = output_fields(out_num)%output_grid%l_end_indx
2054 IF (
PRESENT(time) )
THEN
2055 CALL get_time(time,second,day,tick)
2057 & * output_fields(out_num)%n_diurnal_samples/seconds_per_day) + 1
2061 IF ( reduced_k_range )
THEN
2064 if (output_fields(out_num)%reduced_k_unstruct)
then
2065 js = output_fields(out_num)%output_grid%l_start_indx(2)
2066 je = output_fields(out_num)%output_grid%l_end_indx(2)
2068 l_start(3) = output_fields(out_num)%output_grid%l_start_indx(3)
2069 l_end(3) = output_fields(out_num)%output_grid%l_end_indx(3)
2076 IF ( freq == every_time .AND. .NOT.output_fields(out_num)%static )
THEN
2077 IF (output_fields(out_num)%next_output == output_fields(out_num)%last_output)
THEN
2078 IF(
PRESENT(time))
THEN
2079 output_fields(out_num)%next_output = time
2081 WRITE (error_string,
'(a,"/",a)')&
2082 & trim(input_fields(diag_field_id)%module_name),&
2083 & trim(output_fields(out_num)%output_name)
2084 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)//&
2085 &
', time must be present when output frequency = EVERY_TIME', err_msg))
THEN
2086 DEALLOCATE(field_out)
2087 DEALLOCATE(oor_mask)
2093 IF ( .NOT.output_fields(out_num)%static .AND. .NOT.
PRESENT(time) )
THEN
2094 WRITE (error_string,
'(a,"/",a)')&
2095 & trim(input_fields(diag_field_id)%module_name), &
2096 & trim(output_fields(out_num)%output_name)
2097 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)//&
2098 &
', time must be present for nonstatic field', err_msg))
THEN
2099 DEALLOCATE(field_out)
2100 DEALLOCATE(oor_mask)
2108 IF ( (numthreads == 1) .AND. (active_omp_level.LE.1) )
then
2109 IF ( .NOT.output_fields(out_num)%static .AND. freq /= end_of_run )
THEN
2110 IF ( time > output_fields(out_num)%next_output )
THEN
2112 IF ( time > output_fields(out_num)%next_next_output .AND. freq > 0 )
THEN
2113 IF (
mpp_pe() .EQ. mpp_root_pe() )
THEN
2114 WRITE (error_string,
'(a,"/",a)')&
2115 & trim(input_fields(diag_field_id)%module_name), &
2116 & trim(output_fields(out_num)%output_name)
2117 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//&
2118 & trim(error_string)//
' is skipped one time level in output data', err_msg))
THEN
2119 DEALLOCATE(field_out)
2120 DEALLOCATE(oor_mask)
2126 status =
writing_field(out_num, .false., error_string, time)
2127 IF(status == -1)
THEN
2128 IF (
mpp_pe() .EQ. mpp_root_pe() )
THEN
2129 IF(
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)&
2130 & //
', write EMPTY buffer', err_msg))
THEN
2131 DEALLOCATE(field_out)
2132 DEALLOCATE(oor_mask)
2142 if (
present(time))
then
2144 if (output_fields(out_num)%last_output > time) cycle
2147 IF ( .NOT.output_fields(out_num)%static .AND. .NOT.need_compute .AND. debug_diag_manager )
THEN
2149 IF ( err_msg_local /=
'' )
THEN
2150 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
2151 DEALLOCATE(field_out)
2152 DEALLOCATE(oor_mask)
2158 IF (use_refactored_send)
THEN
2159 ALLOCATE( ofield_index_cfg )
2160 CALL ofield_index_cfg%initialize( is, js, ks, ie, je, ke, &
2161 & hi, hj, f1, f2, f3, f4)
2163 ALLOCATE( ofield_cfg )
2164 CALL ofield_cfg%initialize( input_fields(diag_field_id), output_fields(out_num),
PRESENT(mask), freq)
2168 mf_result =
fieldbuff_update(ofield_cfg, ofield_index_cfg, field_out, sample, &
2169 & output_fields(out_num)%buffer, output_fields(out_num)%counter ,output_fields(out_num)%buff_bounds,&
2170 & output_fields(out_num)%count_0d(sample), output_fields(out_num)%num_elements(sample), &
2171 & mask, weight1 ,missvalue, &
2172 & input_fields(diag_field_id)%numthreads, input_fields(diag_field_id)%active_omp_level,&
2173 & input_fields(diag_field_id)%issued_mask_ignore_warning, &
2174 & l_start, l_end, err_msg, err_msg_local )
2175 IF (mf_result .eqv. .false.)
THEN
2176 DEALLOCATE(ofield_index_cfg)
2177 DEALLOCATE(ofield_cfg)
2178 DEALLOCATE(field_out)
2179 DEALLOCATE(oor_mask)
2184 & output_fields(out_num)%buffer, output_fields(out_num)%buff_bounds , &
2185 & output_fields(out_num)%count_0d(sample), &
2186 & mask, missvalue, l_start, l_end, err_msg, err_msg_local)
2187 IF (mf_result .eqv. .false.)
THEN
2188 DEALLOCATE(ofield_index_cfg)
2189 DEALLOCATE(ofield_cfg)
2190 DEALLOCATE(field_out)
2191 DEALLOCATE(oor_mask)
2196 IF ( output_fields(out_num)%static .AND. .NOT.need_compute .AND. debug_diag_manager )
THEN
2198 IF ( err_msg_local /=
'' )
THEN
2199 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg))
THEN
2200 DEALLOCATE(field_out)
2201 DEALLOCATE(oor_mask)
2228 IF(
ALLOCATED(ofield_index_cfg))
THEN
2229 DEALLOCATE(ofield_index_cfg)
2231 IF(
ALLOCATED(ofield_cfg))
THEN
2232 DEALLOCATE(ofield_cfg)
2239 IF ( input_fields(diag_field_id)%mask_variant )
THEN
2240 IF ( need_compute )
THEN
2241 WRITE (error_string,
'(a,"/",a)') &
2242 & trim(input_fields(diag_field_id)%module_name), &
2243 & trim(output_fields(out_num)%output_name)
2244 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)//&
2245 &
', regional output NOT supported with mask_variant', err_msg))
THEN
2246 DEALLOCATE(field_out)
2247 DEALLOCATE(oor_mask)
2254 IF (
PRESENT(mask) )
THEN
2255 IF ( missvalue_present )
THEN
2256 IF ( debug_diag_manager )
THEN
2257 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
2259 IF ( err_msg_local /=
'' )
THEN
2260 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
2261 DEALLOCATE(field_out)
2262 DEALLOCATE(oor_mask)
2267 IF( numthreads>1 .AND. phys_window )
then
2268 IF ( reduced_k_range )
THEN
2273 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2274 IF ( pow_value /= 1 )
THEN
2275 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2276 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2277 & (field_out(i-is+1+hi, j-js+1+hj, k) * weight1)**(pow_value)
2279 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2280 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2281 & field_out(i-is+1+hi, j-js+1+hj, k) * weight1
2283 output_fields(out_num)%counter(i-hi,j-hj,k1,sample) =&
2284 & output_fields(out_num)%counter(i-hi,j-hj,k1,sample) + weight1
2293 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2294 IF ( pow_value /= 1 )
THEN
2295 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2296 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2297 & (field_out(i-is+1+hi,j-js+1+hj,k)*weight1)**(pow_value)
2299 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2300 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2301 & field_out(i-is+1+hi,j-js+1+hj,k)*weight1
2303 output_fields(out_num)%counter(i-hi,j-hj,k,sample) =&
2304 &output_fields(out_num)%counter(i-hi,j-hj,k,sample) + weight1
2312 IF ( reduced_k_range )
THEN
2317 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2318 IF ( pow_value /= 1 )
THEN
2319 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2320 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2321 & (field_out(i-is+1+hi, j-js+1+hj, k) * weight1)**(pow_value)
2323 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2324 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2325 & field_out(i-is+1+hi, j-js+1+hj, k) * weight1
2327 output_fields(out_num)%counter(i-hi,j-hj,k1,sample) =&
2328 & output_fields(out_num)%counter(i-hi,j-hj,k1,sample) + weight1
2337 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2338 IF ( pow_value /= 1 )
THEN
2339 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2340 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2341 & (field_out(i-is+1+hi,j-js+1+hj,k)*weight1)**(pow_value)
2343 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2344 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2345 & field_out(i-is+1+hi,j-js+1+hj,k)*weight1
2347 output_fields(out_num)%counter(i-hi,j-hj,k,sample) =&
2348 &output_fields(out_num)%counter(i-hi,j-hj,k,sample) + weight1
2357 WRITE (error_string,
'(a,"/",a)')&
2358 & trim(input_fields(diag_field_id)%module_name), &
2359 & trim(output_fields(out_num)%output_name)
2360 IF(
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)//&
2361 &
', variable mask but no missing value defined', err_msg))
THEN
2362 DEALLOCATE(field_out)
2363 DEALLOCATE(oor_mask)
2368 WRITE (error_string,
'(a,"/",a)')&
2369 & trim(input_fields(diag_field_id)%module_name), &
2370 & trim(output_fields(out_num)%output_name)
2371 IF(
fms_error_handler(
'diag_manager_mod::send_data_3d',
'module/output_field '//trim(error_string)//&
2372 &
', variable mask but no mask given', err_msg))
THEN
2373 DEALLOCATE(field_out)
2374 DEALLOCATE(oor_mask)
2379 IF (
PRESENT(mask) )
THEN
2380 IF ( missvalue_present )
THEN
2381 IF ( need_compute )
THEN
2382 IF (numthreads>1 .AND. phys_window)
then
2383 DO k = l_start(3), l_end(3)
2387 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2388 & j <= l_end(2)+hj )
THEN
2389 i1 = i-l_start(1)-hi+1
2390 j1= j-l_start(2)-hj+1
2391 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2392 IF ( pow_value /= 1 )
THEN
2393 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2394 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2395 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2397 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2398 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2399 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2402 output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
2410 DO k = l_start(3), l_end(3)
2414 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2415 & j <= l_end(2)+hj )
THEN
2416 i1 = i-l_start(1)-hi+1
2417 j1= j-l_start(2)-hj+1
2418 IF ( mask(i-is+1+hi, j-js+1+hj, k) )
THEN
2419 IF ( pow_value /= 1 )
THEN
2420 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2421 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2422 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2424 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2425 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2426 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2429 output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
2440 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2441 & j <= l_end(2)+hj )
THEN
2442 output_fields(out_num)%num_elements(sample) = &
2443 output_fields(out_num)%num_elements(sample) + l_end(3) - l_start(3) + 1
2448 ELSE IF ( reduced_k_range )
THEN
2449 IF (numthreads>1 .AND. phys_window)
then
2454 IF ( mask(i-is+1+hi,j-js+1+hj,k) )
THEN
2455 IF ( pow_value /= 1 )
THEN
2456 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2457 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2458 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2460 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2461 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2462 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2465 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample)= missvalue
2476 IF ( mask(i-is+1+hi,j-js+1+hj,k) )
THEN
2477 IF ( pow_value /= 1 )
THEN
2478 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2479 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2480 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2482 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2483 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2484 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2487 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample)= missvalue
2495 IF ( debug_diag_manager )
THEN
2496 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
2498 IF ( err_msg_local /=
'' )
THEN
2499 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
2500 DEALLOCATE(field_out)
2501 DEALLOCATE(oor_mask)
2506 IF (numthreads>1 .AND. phys_window)
then
2510 IF ( mask(i-is+1+hi,j-js+1+hj,k) )
THEN
2511 IF ( pow_value /= 1 )
THEN
2512 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2513 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2514 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2516 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2517 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2518 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2521 output_fields(out_num)%buffer(i-hi,j-hj,k,sample)= missvalue
2531 IF ( mask(i-is+1+hi,j-js+1+hj,k) )
THEN
2532 IF ( pow_value /= 1 )
THEN
2533 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2534 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2535 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2537 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2538 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2539 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2542 output_fields(out_num)%buffer(i-hi,j-hj,k,sample)= missvalue
2551 IF ( need_compute .AND. .NOT.phys_window )
THEN
2552 IF ( any(mask(l_start(1)+hi:l_end(1)+hi,l_start(2)+hj:l_end(2)+hj,l_start(3):l_end(3))) ) &
2553 & output_fields(out_num)%count_0d(sample) =&
2554 & output_fields(out_num)%count_0d(sample) + weight1
2556 IF ( any(mask(f1:f2,f3:f4,ks:ke)) ) output_fields(out_num)%count_0d(sample) =&
2557 & output_fields(out_num)%count_0d(sample)+weight1
2562 IF ( (.NOT.all(mask(f1:f2,f3:f4,ks:ke)) .AND.
mpp_pe() .EQ. mpp_root_pe()).AND.&
2563 & .NOT.input_fields(diag_field_id)%issued_mask_ignore_warning )
THEN
2568 CALL error_mesg(
'diag_manager_mod::send_data_3d',&
2569 &
'Mask will be ignored since missing values were not specified for field '//&
2570 & trim(input_fields(diag_field_id)%field_name)//
' in module '//&
2571 & trim(input_fields(diag_field_id)%module_name), warning)
2572 input_fields(diag_field_id)%issued_mask_ignore_warning = .true.
2574 IF ( need_compute )
THEN
2575 IF (numthreads>1 .AND. phys_window)
then
2578 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2579 & j <= l_end(2)+hj )
THEN
2580 i1 = i-l_start(1)-hi+1
2581 j1 = j-l_start(2)-hj+1
2582 IF ( pow_value /= 1 )
THEN
2583 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2584 & output_fields(out_num)%buffer(i1,j1,:,sample)+ &
2585 & (field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1)**(pow_value)
2587 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2588 & output_fields(out_num)%buffer(i1,j1,:,sample)+ &
2589 & field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1
2598 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2599 & j <= l_end(2)+hj )
THEN
2600 i1 = i-l_start(1)-hi+1
2601 j1 = j-l_start(2)-hj+1
2602 IF ( pow_value /= 1 )
THEN
2603 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2604 & output_fields(out_num)%buffer(i1,j1,:,sample)+ &
2605 & (field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1)**(pow_value)
2607 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2608 & output_fields(out_num)%buffer(i1,j1,:,sample)+ &
2609 & field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1
2619 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2620 & j <= l_end(2)+hj )
THEN
2621 output_fields(out_num)%num_elements(sample)=&
2622 & output_fields(out_num)%num_elements(sample)+l_end(3)-l_start(3)+1
2628 ELSE IF ( reduced_k_range )
THEN
2629 IF (numthreads>1 .AND. phys_window)
then
2632 IF ( pow_value /= 1 )
THEN
2633 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2634 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) +&
2635 & (field_out(f1:f2,f3:f4,ksr:ker)*weight1)**(pow_value)
2637 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2638 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) +&
2639 & field_out(f1:f2,f3:f4,ksr:ker)*weight1
2645 IF ( pow_value /= 1 )
THEN
2646 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2647 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) +&
2648 & (field_out(f1:f2,f3:f4,ksr:ker)*weight1)**(pow_value)
2650 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2651 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) +&
2652 & field_out(f1:f2,f3:f4,ksr:ker)*weight1
2657 IF ( debug_diag_manager )
THEN
2658 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
2660 IF ( err_msg_local /=
'')
THEN
2661 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
2662 DEALLOCATE(field_out)
2663 DEALLOCATE(oor_mask)
2668 IF (numthreads>1 .AND. phys_window)
then
2669 IF ( pow_value /= 1 )
THEN
2670 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
2671 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
2672 & (field_out(f1:f2,f3:f4,ks:ke)*weight1)**(pow_value)
2674 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
2675 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
2676 & field_out(f1:f2,f3:f4,ks:ke)*weight1
2680 IF ( pow_value /= 1 )
THEN
2681 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
2682 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
2683 & (field_out(f1:f2,f3:f4,ks:ke)*weight1)**(pow_value)
2685 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
2686 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
2687 & field_out(f1:f2,f3:f4,ks:ke)*weight1
2693 IF ( .NOT.phys_window ) output_fields(out_num)%count_0d(sample) =&
2694 & output_fields(out_num)%count_0d(sample) + weight1
2698 IF ( missvalue_present )
THEN
2699 IF ( need_compute )
THEN
2700 if( numthreads>1 .AND. phys_window )
then
2701 DO k = l_start(3), l_end(3)
2702 k1 = k - l_start(3) + 1
2705 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2706 & j <= l_end(2)+hj)
THEN
2707 i1 = i-l_start(1)-hi+1
2708 j1= j-l_start(2)-hj+1
2709 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2710 IF ( pow_value /= 1 )
THEN
2711 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2712 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2713 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2715 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2716 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2717 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2720 output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
2728 DO k = l_start(3), l_end(3)
2729 k1 = k - l_start(3) + 1
2732 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2733 & j <= l_end(2)+hj)
THEN
2734 i1 = i-l_start(1)-hi+1
2735 j1= j-l_start(2)-hj+1
2736 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2737 IF ( pow_value /= 1 )
THEN
2738 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2739 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2740 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2742 output_fields(out_num)%buffer(i1,j1,k1,sample) =&
2743 & output_fields(out_num)%buffer(i1,j1,k1,sample) +&
2744 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2747 output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
2758 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2759 & j <= l_end(2)+hj)
THEN
2760 output_fields(out_num)%num_elements(sample) =&
2761 & output_fields(out_num)%num_elements(sample) + l_end(3) - l_start(3) + 1
2765 IF ( .NOT.phys_window )
THEN
2766 outer0:
DO k = l_start(3), l_end(3)
2767 DO j=l_start(2)+hj, l_end(2)+hj
2768 DO i=l_start(1)+hi, l_end(1)+hi
2769 IF ( field_out(i,j,k) /= missvalue )
THEN
2770 output_fields(out_num)%count_0d(sample) = output_fields(out_num)%count_0d(sample)&
2779 ELSE IF ( reduced_k_range )
THEN
2780 if( numthreads>1 .AND. phys_window )
then
2787 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2788 IF ( pow_value /= 1 )
THEN
2789 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2790 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2791 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2793 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2794 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2795 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2798 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) = missvalue
2811 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2812 IF ( pow_value /= 1 )
THEN
2813 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2814 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2815 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2817 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) =&
2818 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) +&
2819 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2822 output_fields(out_num)%buffer(i-hi,j-hj,k1,sample) = missvalue
2830 outer3:
DO k = ksr, ker
2834 IF ( field_out(i,j,k) /= missvalue )
THEN
2835 output_fields(out_num)%count_0d(sample) = output_fields(out_num)%count_0d(sample) &
2844 IF ( debug_diag_manager )
THEN
2845 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
2847 IF ( err_msg_local /=
'' )
THEN
2848 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
2849 DEALLOCATE(field_out)
2850 DEALLOCATE(oor_mask)
2855 IF( numthreads > 1 .AND. phys_window )
then
2859 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2860 IF ( pow_value /= 1 )
THEN
2861 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2862 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2863 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2865 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2866 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2867 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2870 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) = missvalue
2880 IF ( field_out(i-is+1+hi,j-js+1+hj,k) /= missvalue )
THEN
2881 IF ( pow_value /= 1 )
THEN
2882 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2883 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2884 & (field_out(i-is+1+hi,j-js+1+hj,k) * weight1)**(pow_value)
2886 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) =&
2887 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample) +&
2888 & field_out(i-is+1+hi,j-js+1+hj,k) * weight1
2891 output_fields(out_num)%buffer(i-hi,j-hj,k,sample) = missvalue
2902 IF ( field_out(i,j,k) /= missvalue )
THEN
2903 output_fields(out_num)%count_0d(sample) = output_fields(out_num)%count_0d(sample) &
2913 IF ( need_compute )
THEN
2914 IF( numthreads > 1 .AND. phys_window )
then
2917 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2918 & j <= l_end(2)+hj )
THEN
2919 i1 = i-l_start(1)-hi+1
2920 j1= j-l_start(2)-hj+1
2921 IF ( pow_value /= 1 )
THEN
2922 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2923 & output_fields(out_num)%buffer(i1,j1,:,sample) +&
2924 & (field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1)**(pow_value)
2926 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2927 & output_fields(out_num)%buffer(i1,j1,:,sample) +&
2928 & field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1
2937 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2938 & j <= l_end(2)+hj )
THEN
2939 i1 = i-l_start(1)-hi+1
2940 j1= j-l_start(2)-hj+1
2941 IF ( pow_value /= 1 )
THEN
2942 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2943 & output_fields(out_num)%buffer(i1,j1,:,sample) +&
2944 & (field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1)**(pow_value)
2946 output_fields(out_num)%buffer(i1,j1,:,sample)= &
2947 & output_fields(out_num)%buffer(i1,j1,:,sample) +&
2948 & field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))*weight1
2959 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
2960 & j <= l_end(2)+hj )
THEN
2961 output_fields(out_num)%num_elements(sample) =&
2962 & output_fields(out_num)%num_elements(sample)+l_end(3)-l_start(3)+1
2968 ELSE IF ( reduced_k_range )
THEN
2971 IF( numthreads > 1 .AND. phys_window )
then
2972 IF ( pow_value /= 1 )
THEN
2973 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2974 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
2975 & (field_out(f1:f2,f3:f4,ksr:ker)*weight1)**(pow_value)
2977 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2978 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
2979 & field_out(f1:f2,f3:f4,ksr:ker)*weight1
2983 IF ( pow_value /= 1 )
THEN
2984 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2985 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
2986 & (field_out(f1:f2,f3:f4,ksr:ker)*weight1)**(pow_value)
2988 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) =&
2989 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
2990 & field_out(f1:f2,f3:f4,ksr:ker)*weight1
2995 IF ( debug_diag_manager )
THEN
2996 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
2998 IF ( err_msg_local /=
'' )
THEN
2999 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3000 DEALLOCATE(field_out)
3001 DEALLOCATE(oor_mask)
3006 IF( numthreads > 1 .AND. phys_window )
then
3007 IF ( pow_value /= 1 )
THEN
3008 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
3009 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
3010 & (field_out(f1:f2,f3:f4,ks:ke)*weight1)**(pow_value)
3012 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
3013 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
3014 & field_out(f1:f2,f3:f4,ks:ke)*weight1
3018 IF ( pow_value /= 1 )
THEN
3019 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
3020 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
3021 & (field_out(f1:f2,f3:f4,ks:ke)*weight1)**(pow_value)
3023 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) =&
3024 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) +&
3025 & field_out(f1:f2,f3:f4,ks:ke)*weight1
3031 IF ( .NOT.phys_window ) output_fields(out_num)%count_0d(sample) =&
3032 & output_fields(out_num)%count_0d(sample) + weight1
3038 IF ( .NOT.need_compute .AND. .NOT.reduced_k_range )&
3039 & output_fields(out_num)%num_elements(sample) =&
3040 & output_fields(out_num)%num_elements(sample) + (ie-is+1)*(je-js+1)*(ke-ks+1)
3041 IF ( reduced_k_range ) &
3042 & output_fields(out_num)%num_elements(sample) = output_fields(out_num)%num_elements(sample) +&
3043 & (ie-is+1)*(je-js+1)*(ker-ksr+1)
3046 ELSE IF ( time_max )
THEN
3047 IF (
PRESENT(mask) )
THEN
3048 IF ( need_compute )
THEN
3049 DO k = l_start(3), l_end(3)
3050 k1 = k - l_start(3) + 1
3053 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
3054 & j <= l_end(2)+hj )
THEN
3055 i1 = i-l_start(1)-hi+1
3056 j1= j-l_start(2)-hj+1
3057 IF ( mask(i-is+1+hi,j-js+1+hj,k) .AND. field_out(i-is+1+hi,j-js+1+hj,k)>&
3058 & output_fields(out_num)%buffer(i1,j1,k1,sample) )
THEN
3059 output_fields(out_num)%buffer(i1,j1,k1,sample) = field_out(i-is+1+hi,j-js+1+hj,k)
3066 ELSE IF ( reduced_k_range )
THEN
3069 WHERE ( mask(f1:f2,f3:f4,ksr:ker) .AND. field_out(f1:f2,f3:f4,ksr:ker) >&
3070 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) )&
3071 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = field_out(f1:f2,f3:f4,ksr:ker)
3073 IF ( debug_diag_manager )
THEN
3074 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3076 IF ( err_msg_local /=
'' )
THEN
3077 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3078 DEALLOCATE(field_out)
3079 DEALLOCATE(oor_mask)
3084 WHERE ( mask(f1:f2,f3:f4,ks:ke) .AND. field_out(f1:f2,f3:f4,ks:ke)>&
3085 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) )&
3086 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = field_out(f1:f2,f3:f4,ks:ke)
3089 IF ( need_compute )
THEN
3090 DO k = l_start(3), l_end(3)
3091 k1 = k - l_start(3) + 1
3094 IF(l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
3095 & j <= l_end(2)+hj )
THEN
3096 i1 = i-l_start(1)-hi+1
3097 j1 = j-l_start(2)-hj+1
3098 IF ( field_out(i-is+1+hi,j-js+1+hj,k)>output_fields(out_num)%buffer(i1,j1,k1,sample) )
THEN
3099 output_fields(out_num)%buffer(i1,j1,k1,sample) = field_out(i-is+1+hi,j-js+1+hj,k)
3106 ELSE IF ( reduced_k_range )
THEN
3109 WHERE ( field_out(f1:f2,f3:f4,ksr:ker) >&
3110 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) ) &
3111 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = field_out(f1:f2,f3:f4,ksr:ker)
3113 IF ( debug_diag_manager )
THEN
3114 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3116 IF ( err_msg_local /=
'' )
THEN
3117 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3118 DEALLOCATE(field_out)
3119 DEALLOCATE(oor_mask)
3124 WHERE ( field_out(f1:f2,f3:f4,ks:ke) >&
3125 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) ) &
3126 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = field_out(f1:f2,f3:f4,ks:ke)
3129 output_fields(out_num)%count_0d(sample) = 1
3130 ELSE IF ( time_min )
THEN
3131 IF (
PRESENT(mask) )
THEN
3132 IF ( need_compute )
THEN
3133 DO k = l_start(3), l_end(3)
3134 k1 = k - l_start(3) + 1
3137 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
3138 & j <= l_end(2)+hj )
THEN
3139 i1 = i-l_start(1)-hi+1
3140 j1 = j-l_start(2)-hj+1
3141 IF ( mask(i-is+1+hi,j-js+1+hj,k) .AND. field_out(i-is+1+hi,j-js+1+hj,k) <&
3142 & output_fields(out_num)%buffer(i1,j1,k1,sample) )
THEN
3143 output_fields(out_num)%buffer(i1,j1,k1,sample) = field_out(i-is+1+hi,j-js+1+hj,k)
3150 ELSE IF ( reduced_k_range )
THEN
3153 WHERE ( mask(f1:f2,f3:f4,ksr:ker) .AND. field_out(f1:f2,f3:f4,ksr:ker) <&
3154 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) ) &
3155 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = field_out(f1:f2,f3:f4,ksr:ker)
3157 IF ( debug_diag_manager )
THEN
3158 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3160 IF ( err_msg_local /=
'' )
THEN
3161 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3162 DEALLOCATE(field_out)
3163 DEALLOCATE(oor_mask)
3168 WHERE ( mask(f1:f2,f3:f4,ks:ke) .AND. field_out(f1:f2,f3:f4,ks:ke) <&
3169 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) ) &
3170 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = field_out(f1:f2,f3:f4,ks:ke)
3173 IF ( need_compute )
THEN
3174 DO k = l_start(3), l_end(3)
3175 k1 = k - l_start(3) + 1
3178 IF ( l_start(1)+hi <=i.AND.i<=l_end(1)+hi.AND.l_start(2)+hj<=j.AND.j<=l_end(2)+hj)
THEN
3179 i1 = i-l_start(1)-hi+1
3180 j1= j-l_start(2)-hj+1
3181 IF ( field_out(i-is+1+hi,j-js+1+hj,k) <&
3182 & output_fields(out_num)%buffer(i1,j1,k1,sample) )
THEN
3183 output_fields(out_num)%buffer(i1,j1,k1,sample) = field_out(i-is+1+hi,j-js+1+hj,k)
3190 ELSE IF ( reduced_k_range )
THEN
3193 WHERE ( field_out(f1:f2,f3:f4,ksr:ker) <&
3194 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) ) &
3195 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = field_out(f1:f2,f3:f4,ksr:ker)
3197 IF ( debug_diag_manager )
THEN
3198 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3200 IF ( err_msg_local /=
'' )
THEN
3201 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3202 DEALLOCATE(field_out)
3203 DEALLOCATE(oor_mask)
3208 WHERE ( field_out(f1:f2,f3:f4,ks:ke) <&
3209 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) )&
3210 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = field_out(f1:f2,f3:f4,ks:ke)
3213 output_fields(out_num)%count_0d(sample) = 1
3214 ELSE IF ( time_sum )
THEN
3215 IF (
PRESENT(mask) )
THEN
3216 IF ( need_compute )
THEN
3217 DO k = l_start(3), l_end(3)
3218 k1 = k - l_start(3) + 1
3221 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
3222 & j <= l_end(2)+hj )
THEN
3223 i1 = i-l_start(1)-hi+1
3224 j1 = j-l_start(2)-hj+1
3225 IF ( mask(i-is+1+hi,j-js+1+hj,k) )
THEN
3226 output_fields(out_num)%buffer(i1,j1,k1,sample) = &
3227 output_fields(out_num)%buffer(i1,j1,k1,sample) + &
3228 field_out(i-is+1+hi,j-js+1+hj,k)
3235 ELSE IF ( reduced_k_range )
THEN
3238 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = &
3239 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
3240 & field_out(f1:f2,f3:f4,ksr:ker)
3242 IF ( debug_diag_manager )
THEN
3243 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3245 IF ( err_msg_local /=
'' )
THEN
3246 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3247 DEALLOCATE(field_out)
3248 DEALLOCATE(oor_mask)
3253 WHERE ( mask(f1:f2,f3:f4,ks:ke) ) &
3254 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = &
3255 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) + &
3256 & field_out(f1:f2,f3:f4,ks:ke)
3259 IF ( need_compute )
THEN
3260 DO k = l_start(3), l_end(3)
3261 k1 = k - l_start(3) + 1
3264 IF ( l_start(1)+hi <=i.AND.i<=l_end(1)+hi.AND.l_start(2)+hj<=j.AND.j<=l_end(2)+hj)
THEN
3265 i1 = i-l_start(1)-hi+1
3266 j1= j-l_start(2)-hj+1
3267 output_fields(out_num)%buffer(i1,j1,k1,sample) = &
3268 & output_fields(out_num)%buffer(i1,j1,k1,sample) + &
3269 & field_out(i-is+1+hi,j-js+1+hj,k)
3274 ELSE IF ( reduced_k_range )
THEN
3277 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = &
3278 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) + &
3279 & field_out(f1:f2,f3:f4,ksr:ker)
3281 IF ( debug_diag_manager )
THEN
3282 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3284 IF ( err_msg_local /=
'' )
THEN
3285 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3286 DEALLOCATE(field_out)
3287 DEALLOCATE(oor_mask)
3292 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = &
3293 & output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) + &
3294 & field_out(f1:f2,f3:f4,ks:ke)
3297 output_fields(out_num)%count_0d(sample) = 1
3299 output_fields(out_num)%count_0d(sample) = 1
3300 IF ( need_compute )
THEN
3303 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. j <= l_end(2)+hj)
THEN
3304 i1 = i-l_start(1)-hi+1
3305 j1 = j-l_start(2)-hj+1
3306 output_fields(out_num)%buffer(i1,j1,:,sample) =&
3307 & field_out(i-is+1+hi,j-js+1+hj,l_start(3):l_end(3))
3312 ELSE IF ( reduced_k_range )
THEN
3315 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,:,sample) = field_out(f1:f2,f3:f4,ksr:ker)
3317 IF ( debug_diag_manager )
THEN
3318 CALL update_bounds(out_num, is-hi, ie-hi, js-hj, je-hj, ks, ke)
3320 IF ( err_msg_local /=
'' )
THEN
3321 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg) )
THEN
3322 DEALLOCATE(field_out)
3323 DEALLOCATE(oor_mask)
3328 output_fields(out_num)%buffer(is-hi:ie-hi,js-hj:je-hj,ks:ke,sample) = field_out(f1:f2,f3:f4,ks:ke)
3331 IF (
PRESENT(mask) .AND. missvalue_present )
THEN
3332 IF ( need_compute )
THEN
3333 DO k = l_start(3), l_end(3)
3334 k1 = k - l_start(3) + 1
3337 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND. &
3338 & j <= l_end(2)+hj )
THEN
3339 i1 = i-l_start(1)-hi+1
3340 j1 = j-l_start(2)-hj+1
3341 IF ( .NOT.mask(i-is+1+hi,j-js+1+hj,k) )&
3342 & output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
3347 ELSE IF ( reduced_k_range )
THEN
3354 IF ( .NOT.mask(i-is+1+hi,j-js+1+hj,k) ) &
3355 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample)= missvalue
3363 IF ( .NOT.mask(i-is+1+hi,j-js+1+hj,k) )&
3364 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample)= missvalue
3372 IF ( output_fields(out_num)%static .AND. .NOT.need_compute .AND. debug_diag_manager )
THEN
3374 IF ( err_msg_local /=
'' )
THEN
3375 IF (
fms_error_handler(
'diag_manager_mod::send_data_3d', err_msg_local, err_msg))
THEN
3376 DEALLOCATE(field_out)
3377 DEALLOCATE(oor_mask)
3386 IF (
PRESENT(rmask) .AND. missvalue_present )
THEN
3387 IF ( need_compute )
THEN
3389 TYPE IS (real(kind=r4_kind))
3390 DO k = l_start(3), l_end(3)
3391 k1 = k - l_start(3) + 1
3394 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND.&
3395 & j <= l_end(2)+hj )
THEN
3396 i1 = i-l_start(1)-hi+1
3397 j1 = j-l_start(2)-hj+1
3398 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r4_kind ) &
3399 & output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
3404 TYPE IS (real(kind=r8_kind))
3405 DO k = l_start(3), l_end(3)
3406 k1 = k - l_start(3) + 1
3409 IF ( l_start(1)+hi <= i .AND. i <= l_end(1)+hi .AND. l_start(2)+hj <= j .AND.&
3410 & j <= l_end(2)+hj )
THEN
3411 i1 = i-l_start(1)-hi+1
3412 j1 = j-l_start(2)-hj+1
3413 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r8_kind ) &
3414 & output_fields(out_num)%buffer(i1,j1,k1,sample) = missvalue
3420 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
3421 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
3423 ELSE IF ( reduced_k_range )
THEN
3427 TYPE IS (real(kind=r4_kind))
3432 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r4_kind ) &
3433 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample)= missvalue
3437 TYPE IS (real(kind=r8_kind))
3442 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r8_kind ) &
3443 & output_fields(out_num)%buffer(i-hi,j-hj,k1,sample)= missvalue
3448 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
3449 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
3453 TYPE IS (real(kind=r4_kind))
3457 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r4_kind ) &
3458 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample)= missvalue
3462 TYPE IS (real(kind=r8_kind))
3466 IF ( rmask(i-is+1+hi,j-js+1+hj,k) < 0.5_r8_kind ) &
3467 & output_fields(out_num)%buffer(i-hi,j-hj,k,sample)= missvalue
3472 CALL error_mesg (
'diag_manager_mod::send_data_3d',&
3473 &
'The rmask is not one of the supported types of real(kind=4) or real(kind=8)', fatal)
3478 END DO num_out_fields
3480 DEALLOCATE(field_out)
3481 DEALLOCATE(oor_mask)
3487 LOGICAL FUNCTION send_data_4d(diag_field_id, field, time, is_in, js_in, ks_in, &
3488 & mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
3489 INTEGER,
INTENT(in) :: diag_field_id
3490 CLASS(*),
INTENT(in) :: field(:,:,:,:)
3491 CLASS(*),
INTENT(in),
OPTIONAL :: weight
3492 TYPE (
time_type),
INTENT(in),
OPTIONAL :: time
3493 INTEGER,
INTENT(in),
OPTIONAL :: is_in
3494 INTEGER,
INTENT(in),
OPTIONAL :: js_in
3495 INTEGER,
INTENT(in),
OPTIONAL :: ks_in
3496 INTEGER,
INTENT(in),
OPTIONAL :: ie_in
3497 INTEGER,
INTENT(in),
OPTIONAL :: je_in
3498 INTEGER,
INTENT(in),
OPTIONAL :: ke_in
3499 LOGICAL,
INTENT(in),
OPTIONAL :: mask(:,:,:,:)
3500 CLASS(*),
INTENT(in),
OPTIONAL :: rmask(:,:,:,:)
3501 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
3504 class(*),
allocatable :: rmask_local(:,:,:,:)
3505 logical,
allocatable :: mask_local(:,:,:,:)
3508 IF ( diag_field_id <= 0 )
THEN
3513 if (.not. use_modern_diag) &
3514 call mpp_error(fatal,
"Send_data_4d is only supported when diag_manager_nml::use_modern_diag=.true.")
3517 if (
present(mask)) mask_local = mask
3518 if (
present(rmask)) rmask_local = rmask
3520 send_data_4d = fms_diag_object%fms_diag_accept_data(diag_field_id, field, mask_local, rmask_local, &
3521 time, is_in, js_in, ks_in, ie_in, je_in, ke_in, weight, &
3524 if (
present(err_msg))
then
3525 if (err_msg .ne.
"")
then
3532 if (
allocated(rmask_local))
deallocate(rmask_local)
3533 if (
allocated(mask_local))
deallocate(mask_local)
3538 INTEGER,
INTENT(in) :: id
3539 REAL,
INTENT(in) :: field(:,:)
3540 REAL,
INTENT(in) :: area (:,:)
3542 LOGICAL,
INTENT(in),
OPTIONAL :: mask (:,:)
3544 REAL,
DIMENSION(SIZE(field,1)) :: out(size(field,1))
3558 INTEGER,
INTENT(in) :: diag_field_id
3559 REAL,
DIMENSION(:,:),
INTENT(in) :: x
3560 REAL,
DIMENSION(:,:),
INTENT(in) :: area
3561 LOGICAL,
DIMENSION(:,:),
INTENT(in) :: mask
3562 REAL,
DIMENSION(:),
INTENT(out) :: out
3565 REAL,
DIMENSION(SIZE(x,1)) :: s
3566 REAL :: local_missing_value
3570 IF ( diag_field_id <= 0 )
THEN
3574 CALL error_mesg(
'diag_manager_mod::average_tiles1d',&
3575 &
"diag_field_id less than 0. Contact developers.", fatal)
3579 IF ( input_fields(diag_field_id)%missing_value_present )
THEN
3580 local_missing_value = input_fields(diag_field_id)%missing_value
3582 local_missing_value = 0.0
3589 DO it = 1,
SIZE(area,dim=2)
3590 WHERE ( mask(:,it) )
3591 out(:) = out(:) + x(:,it)*area(:,it)
3592 s(:) = s(:) + area(:,it)
3597 out(:) = out(:)/s(:)
3599 out(:) = local_missing_value
3605 INTEGER,
INTENT(in) :: id
3606 REAL,
INTENT(in) :: field(:,:,:)
3607 REAL,
INTENT(in) :: area (:,:,:)
3609 LOGICAL,
INTENT(in),
OPTIONAL :: mask (:,:,:)
3611 REAL,
DIMENSION(SIZE(field,1),SIZE(field,2)) :: out(size(field,1), size(field,2))
3625 INTEGER,
INTENT(in) :: id
3626 REAL,
DIMENSION(:,:,:,:),
INTENT(in) :: field
3627 REAL,
DIMENSION(:,:,:),
INTENT(in) :: area (:,:,:)
3630 LOGICAL,
DIMENSION(:,:,:),
INTENT(in),
OPTIONAL :: mask
3632 REAL,
DIMENSION(SIZE(field,1),SIZE(field,2),SIZE(field,4)) :: out
3633 LOGICAL,
DIMENSION(SIZE(field,1),SIZE(field,2),SIZE(field,4)) :: mask3
3642 DO it=1,
SIZE(field,4)
3643 CALL average_tiles(id, field(:,:,:,it), area, mask, out(:,:,it) )
3646 mask3(:,:,1) = any(mask,dim=3)
3647 DO it = 2,
SIZE(field,4)
3648 mask3(:,:,it) = mask3(:,:,1)
3656 INTEGER,
INTENT(in) :: diag_field_id
3657 REAL,
DIMENSION(:,:,:),
INTENT(in) :: x
3658 REAL,
DIMENSION(:,:,:),
INTENT(in) :: area
3659 LOGICAL,
DIMENSION(:,:,:),
INTENT(in) :: mask
3660 REAL,
DIMENSION(:,:),
INTENT(out) :: out
3663 REAL,
DIMENSION(SIZE(x,1),SIZE(x,2)) :: s
3664 REAL :: local_missing_value
3668 IF ( diag_field_id <= 0 )
THEN
3672 CALL error_mesg(
'diag_manager_mod::average_tiles',&
3673 &
"diag_field_id less than 0. Contact developers.", fatal)
3677 IF ( input_fields(diag_field_id)%missing_value_present )
THEN
3678 local_missing_value = input_fields(diag_field_id)%missing_value
3680 local_missing_value = 0.0
3687 DO it = 1,
SIZE(area,3)
3688 WHERE ( mask(:,:,it) )
3689 out(:,:) = out(:,:) + x(:,:,it)*area(:,:,it)
3690 s(:,:) = s(:,:) + area(:,:,it)
3694 WHERE ( s(:,:) > 0 )
3695 out(:,:) = out(:,:)/s(:,:)
3697 out(:,:) = local_missing_value
3703 INTEGER,
INTENT(in) :: out_num
3704 LOGICAL,
INTENT(in) :: at_diag_end
3705 CHARACTER(len=*),
INTENT(out) :: error_string
3710 LOGICAL :: time_max, time_min, reduced_k_range, missvalue_present
3711 LOGICAL :: average, time_rms, need_compute, phys_window
3712 INTEGER :: in_num, file_num, freq, units
3713 INTEGER :: b1,b2,b3,b4
3714 INTEGER :: i, j, k, m
3715 REAL :: missvalue, num
3718 need_compute = output_fields(out_num)%need_compute
3720 in_num = output_fields(out_num)%input_field
3721 IF ( input_fields(in_num)%static )
RETURN
3723 missvalue = input_fields(in_num)%missing_value
3724 missvalue_present = input_fields(in_num)%missing_value_present
3725 reduced_k_range = output_fields(out_num)%reduced_k_range
3726 phys_window = output_fields(out_num)%phys_window
3728 average = output_fields(out_num)%time_average
3731 time_rms = output_fields(out_num)%time_rms
3733 time_max = output_fields(out_num)%time_max
3734 time_min = output_fields(out_num)%time_min
3735 file_num = output_fields(out_num)%output_file
3736 freq = files(file_num)%output_freq
3737 units = files(file_num)%output_units
3741 b1=
SIZE(output_fields(out_num)%buffer,1)
3742 b2=
SIZE(output_fields(out_num)%buffer,2)
3743 b3=
SIZE(output_fields(out_num)%buffer,3)
3744 b4=
SIZE(output_fields(out_num)%buffer,4)
3745 IF ( input_fields(in_num)%mask_variant )
THEN
3750 IF ( output_fields(out_num)%counter(i,j,k,m) > 0. )
THEN
3751 output_fields(out_num)%buffer(i,j,k,m) = &
3752 & output_fields(out_num)%buffer(i,j,k,m)/output_fields(out_num)%counter(i,j,k,m)
3753 IF ( time_rms ) output_fields(out_num)%buffer(i,j,k,m) = &
3754 sqrt(output_fields(out_num)%buffer(i,j,k,m))
3756 output_fields(out_num)%buffer(i,j,k,m) = missvalue
3764 IF ( phys_window )
THEN
3765 IF ( need_compute .OR. reduced_k_range )
THEN
3766 num = real(output_fields(out_num)%num_elements(m)/output_fields(out_num)%region_elements)
3768 num = real(output_fields(out_num)%num_elements(m)/output_fields(out_num)%total_elements)
3771 num = output_fields(out_num)%count_0d(m)
3773 IF ( num > 0. )
THEN
3774 IF ( missvalue_present )
THEN
3778 IF ( output_fields(out_num)%buffer(i,j,k,m) /= missvalue )
THEN
3779 output_fields(out_num)%buffer(i,j,k,m) = output_fields(out_num)%buffer(i,j,k,m)/num
3780 IF ( time_rms ) output_fields(out_num)%buffer(i,j,k,m) =&
3781 & sqrt(output_fields(out_num)%buffer(i,j,k,m))
3787 output_fields(out_num)%buffer(:,:,:,m) = output_fields(out_num)%buffer(:,:,:,m)/num
3788 IF ( time_rms ) output_fields(out_num)%buffer(:,:,:,m) =&
3789 & sqrt(output_fields(out_num)%buffer(:,:,:,m))
3791 ELSE IF ( .NOT. at_diag_end )
THEN
3792 IF ( missvalue_present )
THEN
3793 IF(any(output_fields(out_num)%buffer /= missvalue))
THEN
3794 WRITE (error_string,
'(a,"/",a)')&
3795 & trim(input_fields(in_num)%module_name), &
3796 & trim(output_fields(out_num)%output_name)
3804 ELSE IF ( time_min .OR. time_max )
THEN
3805 IF ( missvalue_present )
THEN
3806 WHERE ( abs(output_fields(out_num)%buffer) == min_value )
3807 output_fields(out_num)%buffer = missvalue
3813 IF ( at_diag_end .AND. freq == end_of_run ) output_fields(out_num)%next_output = time
3815 IF ( (output_fields(out_num)%time_ops) .AND. (.NOT. mix_snapshot_average_fields) )
THEN
3816 middle_time = (output_fields(out_num)%last_output+output_fields(out_num)%next_output)/2
3817 if (trim(files(file_num)%filename_time_bounds) ==
"begin")
then
3818 filename_time = output_fields(out_num)%last_output
3819 elseif (trim(files(file_num)%filename_time_bounds) ==
"middle")
then
3820 filename_time = middle_time
3821 elseif (trim(files(file_num)%filename_time_bounds) ==
"end")
then
3822 filename_time = output_fields(out_num)%next_output
3825 CALL diag_data_out(file_num, out_num, output_fields(out_num)%buffer, middle_time, &
3826 & filename_time=filename_time)
3829 & output_fields(out_num)%buffer, output_fields(out_num)%next_output)
3833 IF ( at_diag_end )
RETURN
3836 output_fields(out_num)%last_output = output_fields(out_num)%next_output
3837 IF ( freq == end_of_run )
THEN
3838 output_fields(out_num)%next_output = time
3840 IF ( freq == every_time )
THEN
3841 output_fields(out_num)%next_output = time
3843 output_fields(out_num)%next_output = output_fields(out_num)%next_next_output
3844 output_fields(out_num)%next_next_output = &
3845 & diag_time_inc(output_fields(out_num)%next_next_output, freq, units)
3847 output_fields(out_num)%count_0d(:) = 0.0
3848 output_fields(out_num)%num_elements(:) = 0
3849 IF ( time_max )
THEN
3850 output_fields(out_num)%buffer = max_value
3851 ELSE IF ( time_min )
THEN
3852 output_fields(out_num)%buffer = min_value
3854 output_fields(out_num)%buffer = empty
3856 IF ( input_fields(in_num)%mask_variant .AND. average ) output_fields(out_num)%counter = 0.0
3860 SUBROUTINE diag_manager_set_time_end(Time_end_in)
3861 TYPE (
time_type),
INTENT(in) :: time_end_in
3863 time_end = time_end_in
3865 END SUBROUTINE diag_manager_set_time_end
3880 integer :: file, j, freq, in_num, file_num, out_num
3882 DO file = 1, num_files
3883 freq = files(file)%output_freq
3885 DO j = 1, files(file)%num_fields
3886 out_num = files(file)%fields(j)
3887 in_num = output_fields(out_num)%input_field
3888 IF ( (input_fields(in_num)%numthreads == 1) .AND.&
3889 & (input_fields(in_num)%active_omp_level.LE.1) ) cycle
3890 file_num = output_fields(out_num)%output_file
3892 & output_fields(out_num)%buffer, time)
3901 TYPE (
time_type),
INTENT(in) :: time_step
3902 character(len=*),
INTENT(out),
optional :: err_msg
3905 integer :: file, j, out_num, in_num, freq, status
3906 logical :: local_output, need_compute
3907 CHARACTER(len=128) :: error_string
3909 IF ( time_end == time_zero )
THEN
3913 CALL error_mesg(
'diag_manager_mod::diag_send_complete',&
3914 &
"diag_manager_set_time_end must be called before diag_send_complete", fatal)
3917 if (use_modern_diag)
then
3918 call fms_diag_object%fms_diag_send_complete(time_step)
3922 DO file = 1, num_files
3923 freq = files(file)%output_freq
3924 DO j = 1, files(file)%num_fields
3925 out_num = files(file)%fields(j)
3926 in_num = output_fields(out_num)%input_field
3928 IF ( (input_fields(in_num)%numthreads == 1) .AND. (input_fields(in_num)%active_omp_level.LE.1) ) cycle
3929 IF ( output_fields(out_num)%static .OR. freq == end_of_run ) cycle
3930 time = input_fields(in_num)%time
3931 IF ( time >= time_end ) cycle
3934 local_output = output_fields(out_num)%local_output
3936 need_compute = output_fields(out_num)%need_compute
3938 IF ( local_output .AND. (.NOT.need_compute) ) cycle
3939 next_time = time + time_step
3941 IF ( next_time > output_fields(out_num)%next_output )
THEN
3943 IF ( next_time > output_fields(out_num)%next_next_output .AND. freq > 0 )
THEN
3944 IF (
mpp_pe() .EQ. mpp_root_pe() )
THEN
3945 WRITE (error_string,
'(a,"/",a)')&
3946 & trim(input_fields(in_num)%module_name), &
3947 & trim(output_fields(out_num)%output_name)
3949 &
'module/output_field '//trim(error_string)//&
3950 &
' is skipped one time level in output data', err_msg))
RETURN
3954 status =
writing_field(out_num, .false., error_string, next_time)
3955 IF ( status == -1 )
THEN
3956 IF (
mpp_pe() .EQ. mpp_root_pe() )
THEN
3957 IF(
fms_error_handler(
'diag_manager_mod::diag_send_complete',
'module/output_field '//&
3958 & trim(error_string)//
', write EMPTY buffer', err_msg))
RETURN
3974 IF ( do_diag_field_log )
THEN
3975 close (diag_log_unit)
3977 DO file = 1, num_files
3980 if (
allocated(fileobju))
deallocate(fileobju)
3981 if (
allocated(fileobj))
deallocate(fileobj)
3982 if (
allocated(fileobjnd))
deallocate(fileobjnd)
3985 if (use_modern_diag)
then
3986 call fms_diag_object%diag_end(time)
3992 INTEGER,
INTENT(in) :: file
3995 INTEGER :: j, i, input_num, freq, status
3996 INTEGER :: stdout_unit
3997 LOGICAL :: reduced_k_range, need_compute, local_output
3998 CHARACTER(len=128) :: message
4003 DO j = 1, files(file)%num_fields
4004 i = files(file)%fields(j)
4007 local_output = output_fields(i)%local_output
4009 need_compute = output_fields(i)%need_compute
4011 reduced_k_range = output_fields(i)%reduced_k_range
4014 IF ( local_output .AND. (.NOT. need_compute) ) cycle
4016 input_num = output_fields(i)%input_field
4017 IF ( input_fields(input_num)%static ) cycle
4018 IF ( .NOT.input_fields(input_num)%register ) cycle
4019 freq = files(file)%output_freq
4020 IF ( freq /= end_of_run .AND. files(file)%file_unit < 0 &
4021 & .AND. all(output_fields(i)%num_elements(:) == 0)&
4022 & .AND. all(output_fields(i)%count_0d(:) == 0) ) cycle
4025 IF ( time >= output_fields(i)%next_output .OR. freq == end_of_run )
THEN
4026 IF ( time >= output_fields(i)%next_next_output .AND. freq > 0 )
THEN
4027 WRITE (message,
'(a,"/",a)') trim(input_fields(input_num)%module_name), &
4028 & trim(output_fields(i)%output_name)
4033 IF (
mpp_pe() .EQ. mpp_root_pe() ) &
4034 &
CALL error_mesg(
'diag_manager_mod::closing_file',
'module/output_field ' //&
4035 & trim(message)//
', skip one time level, maybe send_data never called', warning)
4040 ELSEIF ( .NOT.output_fields(i)%written_once )
THEN
4045 CALL error_mesg(
'Potential error in diag_manager_end ',&
4046 & trim(output_fields(i)%output_name)//
' NOT available,'//&
4047 &
' check if output interval > runlength. Netcdf fill_values are written', note)
4048 output_fields(i)%buffer = fill_value
4049 CALL diag_data_out(file, i, output_fields(i)%buffer, time, .true.)
4056 IF ( write_bytes_in_file )
THEN
4057 CALL mpp_sum (files(file)%bytes_written)
4058 IF (
mpp_pe() == mpp_root_pe() )&
4059 &
WRITE (stdout_unit,
'(a,i12,a,a)')
'Diag_Manager: ',files(file)%bytes_written, &
4060 &
' bytes of data written to file ',trim(files(file)%name)
4067 INTEGER,
OPTIONAL,
INTENT(IN) :: diag_model_subset
4068 INTEGER,
DIMENSION(6),
OPTIONAL,
INTENT(IN) :: time_init
4069 CHARACTER(len=*),
INTENT(out),
OPTIONAL :: err_msg
4071 CHARACTER(len=*),
PARAMETER :: sep =
'|'
4073 INTEGER,
PARAMETER :: fltkind = r4_kind
4074 INTEGER,
PARAMETER :: dblkind = r8_kind
4075 INTEGER :: diag_subset_output
4077 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pelist
4078 INTEGER :: stdlog_unit, stdout_unit
4080 CHARACTER(len=256) :: err_msg_local
4082 namelist /diag_manager_nml/ append_pelist_name, mix_snapshot_average_fields, max_output_fields, &
4083 & max_input_fields, max_axes, do_diag_field_log, write_bytes_in_file, debug_diag_manager,&
4084 & max_num_axis_sets, max_files, use_cmor, issue_oor_warnings,&
4085 & oor_warnings_fatal, max_out_per_in_field, flush_nc_files, region_out_use_alt_value, max_field_attributes,&
4086 & max_file_attributes, max_axis_attributes, prepend_date, use_modern_diag, use_clock_average, &
4090 IF ( module_is_initialized )
RETURN
4093 IF (
PRESENT(err_msg) ) err_msg =
''
4098 call diag_data_init()
4101 pack_size =
SIZE(transfer(0.0_dblkind, (/0.0, 0.0, 0.0, 0.0/)))
4102 IF (pack_size .EQ. 1)
then
4103 pack_size_str =
"double"
4104 else if (pack_size .EQ. 2)
then
4105 pack_size_str =
"float"
4107 IF (
fms_error_handler(
'diag_manager_mod::diag_manager_init',
'unknown pack_size. Must be 1, or 2.', &
4112 min_value = huge(0.0_fltkind)
4113 max_value = -min_value
4124 time_end = time_zero
4125 diag_subset_output = diag_all
4126 IF (
PRESENT(diag_model_subset) )
THEN
4127 IF ( diag_model_subset >= diag_other .AND. diag_model_subset <= diag_all )
THEN
4128 diag_subset_output = diag_model_subset
4130 IF (
fms_error_handler(
'diag_manager_mod::diag_manager_init',
'invalid value of diag_model_subset', &
4135 READ (input_nml_file, nml=diag_manager_nml, iostat=mystat)
4138 IF (
check_nml_error(iostat=mystat, nml_name=
'DIAG_MANAGER_NML') < 0 )
THEN
4139 IF (
mpp_pe() == mpp_root_pe() )
THEN
4140 CALL error_mesg(
'diag_manager_mod::diag_manager_init', &
4141 &
'DIAG_MANAGER_NML not found in input nml file. Using defaults.', warning)
4145 IF (.not. use_modern_diag .and. use_clock_average) &
4146 call mpp_error(fatal,
"diag_manager_mod: You cannot set use_modern_diag=.false. and &
4147 & use_clock_average=.true. in diag_manager_nml")
4149 IF (
mpp_pe() == mpp_root_pe() )
THEN
4150 WRITE (stdlog_unit, diag_manager_nml)
4154 IF ( use_cmor )
THEN
4156 WRITE (err_msg_local,
'(ES8.1E2)') cmor_missing_value
4157 CALL error_mesg(
'diag_manager_mod::diag_manager_init',
'Using CMOR missing value ('//trim(err_msg_local)// &
4162 IF ( oor_warnings_fatal )
THEN
4164 CALL error_mesg(
'diag_manager_mod::diag_manager_init',
'Out &
4165 &of Range warnings are fatal.', note)
4166 ELSEIF ( .NOT.issue_oor_warnings )
THEN
4167 CALL error_mesg(
'diag_manager_mod::diag_manager_init',
'Out &
4168 &of Range warnings will be ignored.', note)
4171 IF ( mix_snapshot_average_fields )
THEN
4172 IF (
mpp_pe() == mpp_root_pe() )
THEN
4173 CALL error_mesg(
'diag_manager_mod::diag_manager_init',
'Setting diag_manager_nml variable '//&
4174 &
'mix_snapshot_average_fields = .TRUE. will cause ERRORS in the time coordinates '//&
4175 &
'of all time averaged fields. Strongly recommend setting mix_snapshot_average_fields '//&
4176 &
'= .FALSE.', warning)
4179 ALLOCATE(output_fields(max_output_fields))
4180 ALLOCATE(input_fields(max_input_fields))
4181 DO j = 1, max_input_fields
4182 ALLOCATE(input_fields(j)%output_fields(max_out_per_in_field))
4185 ALLOCATE(files(max_files))
4186 ALLOCATE(fileobju(max_files))
4187 ALLOCATE(fileobj(max_files))
4188 ALLOCATE(fileobjnd(max_files))
4193 CALL mpp_get_current_pelist(pelist, pelist_name)
4196 IF (
PRESENT(time_init) )
THEN
4197 diag_init_time =
set_date(time_init(1), time_init(2), time_init(3), time_init(4),&
4198 & time_init(5), time_init(6))
4200 diag_init_time = get_base_time()
4201 IF ( prepend_date .EQV. .true. )
THEN
4202 CALL error_mesg(
'diag_manager_mod::diag_manager_init',&
4203 &
'prepend_date only supported when diag_manager_init is called with time_init present.', note)
4204 prepend_date = .false.
4208 if (use_modern_diag)
then
4209 CALL fms_diag_object%init(diag_subset_output)
4211 if (.not. use_modern_diag)
then
4212 CALL parse_diag_table(diag_subset=diag_subset_output, istat=mystat, err_msg=err_msg_local)
4213 IF ( mystat /= 0 )
THEN
4215 &
'Error parsing diag_table. '//trim(err_msg_local), err_msg) )
RETURN
4219 files(:)%bytes_written = 0
4222 IF ( do_diag_field_log.AND.
mpp_pe().EQ.mpp_root_pe() )
THEN
4223 open(newunit=diag_log_unit, file=
'diag_field_log.out', action=
'WRITE')
4224 WRITE (diag_log_unit,
'(777a)') &
4232 module_is_initialized = .true.
4234 if(.not. use_modern_diag) null_axis_id = diag_axis_init(
'scalar_axis', (/0./),
'none',
'N',
'none')
4241 INTEGER,
INTENT(out) :: year, month, day, hour, minute, second
4244 IF (.NOT.module_is_initialized)
CALL error_mesg (
'diag_manager_mod::get_base_date', &
4245 &
'module has not been initialized', fatal)
4246 year = get_base_year()
4247 month = get_base_month()
4248 day = get_base_day()
4249 hour = get_base_hour()
4250 minute = get_base_minute()
4251 second = get_base_second()
4261 TYPE(
time_type),
INTENT(in) :: next_model_time
4262 INTEGER,
INTENT(in) :: diag_field_id
4264 INTEGER :: i, out_num
4267 IF ( diag_field_id < 0 )
RETURN
4268 DO i = 1, input_fields(diag_field_id)%num_output_fields
4270 out_num = input_fields(diag_field_id)%output_fields(i)
4271 IF ( .NOT.output_fields(out_num)%static )
THEN
4272 IF ( next_model_time > output_fields(out_num)%next_output )
need_data=.true.
4276 IF ( output_fields(out_num)%time_average)
need_data = .true.
4288 INTEGER,
INTENT(in) :: n_samples
4290 REAL :: center_data (n_samples)
4291 REAL :: edges (n_samples+1)
4300 CHARACTER(32) :: name
4301 CHARACTER(128) :: units
4304 WRITE (units,11)
'hours', year, month, day, hour, minute, second
4305 11
FORMAT(a,
' since ',i4.4,
'-',i2.2,
'-',i2.2,
' ',i2.2,
':',i2.2,
':',i2.2)
4309 center_data(i) = 24.0*(real(i)-0.5)/n_samples
4310 edges(i+1) = 24.0* real(i)/n_samples
4315 WRITE (name,
'(a,i2.2)')
'time_of_day_edges_', n_samples
4316 edges_id = get_axis_num(name,
'diurnal')
4317 IF ( edges_id <= 0 )
THEN
4318 edges_id = diag_axis_init(name,edges,units,
'N',
'time of day edges', set_name=
'diurnal')
4323 WRITE (name,
'(a,i2.2)')
'time_of_day_', n_samples
4326 init_diurnal_axis = diag_axis_init(name, center_data, units,
'N',
'time of day', &
4327 set_name=
'diurnal', edges=edges_id)
4332 INTEGER,
INTENT(in) :: diag_field_id
4333 CHARACTER(len=*),
INTENT(in) :: name
4334 INTEGER,
INTENT(in) ::
type
4335 CHARACTER(len=*),
INTENT(in),
OPTIONAL :: cval
4336 INTEGER,
DIMENSION(:),
INTENT(in),
OPTIONAL :: ival
4337 REAL,
DIMENSION(:),
INTENT(in),
OPTIONAL :: rval
4339 INTEGER :: istat, length, i, j, this_attribute, out_field
4341 IF ( .NOT.first_send_data_call )
THEN
4347 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',
'Attempting to add attribute "'&
4348 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4349 &//trim(input_fields(diag_field_id)%field_name)//
'" after first send_data call. Too late.', fatal)
4353 IF ( diag_field_id .LE. 0 )
THEN
4356 DO j=1,input_fields(diag_field_id)%num_output_fields
4357 out_field = input_fields(diag_field_id)%output_fields(j)
4364 DO i=1, output_fields(out_field)%num_attributes
4365 IF ( trim(output_fields(out_field)%attributes(i)%name) .EQ. trim(name) )
THEN
4371 IF ( this_attribute.NE.0 .AND. (type.EQ.nf90_int .OR. type.EQ.nf90_float) )
THEN
4376 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4377 &
'Attribute "'//trim(name)//
'" already defined for module/input_field "'&
4378 &//trim(input_fields(diag_field_id)%module_name)//
'/'&
4379 &//trim(input_fields(diag_field_id)%field_name)//
'". Contact the developers.', fatal)
4380 ELSE IF ( this_attribute.NE.0 .AND. type.EQ.nf90_char .AND. debug_diag_manager )
THEN
4385 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4386 &
'Attribute "'//trim(name)//
'" already defined for module/input_field "'&
4387 &//trim(input_fields(diag_field_id)%module_name)//
'/'&
4388 &//trim(input_fields(diag_field_id)%field_name)//
'". Prepending.', note)
4389 ELSE IF ( this_attribute.EQ.0 )
THEN
4392 this_attribute = output_fields(out_field)%num_attributes + 1
4394 IF ( this_attribute .GT. max_field_attributes )
THEN
4400 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4401 &
'Number of attributes exceeds max_field_attributes for attribute "'&
4402 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4403 &//trim(input_fields(diag_field_id)%field_name)&
4404 &//
'". Increase diag_manager_nml:max_field_attributes.', fatal)
4406 output_fields(out_field)%num_attributes = this_attribute
4408 output_fields(out_field)%attributes(this_attribute)%name = name
4409 output_fields(out_field)%attributes(this_attribute)%type =
type
4411 output_fields(out_field)%attributes(this_attribute)%catt =
''
4417 IF ( .NOT.
PRESENT(ival) )
THEN
4423 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4424 &
'Attribute type claims INTEGER, but ival not present for attribute "'&
4425 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4426 &//trim(input_fields(diag_field_id)%field_name)//
'". Contact then developers.', fatal)
4430 ALLOCATE(output_fields(out_field)%attributes(this_attribute)%iatt(length), stat=istat)
4431 IF ( istat.NE.0 )
THEN
4435 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',
'Unable to allocate iatt for attribute "'&
4436 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4437 &//trim(input_fields(diag_field_id)%field_name)//
'"', fatal)
4440 output_fields(out_field)%attributes(this_attribute)%len = length
4441 output_fields(out_field)%attributes(this_attribute)%iatt = ival
4443 IF ( .NOT.
PRESENT(rval) )
THEN
4449 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4450 &
'Attribute type claims REAL, but rval not present for attribute "'&
4451 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4452 &//trim(input_fields(diag_field_id)%field_name)//
'". Contact the developers.', fatal)
4456 ALLOCATE(output_fields(out_field)%attributes(this_attribute)%fatt(length), stat=istat)
4457 IF ( istat.NE.0 )
THEN
4461 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',
'Unable to allocate fatt for attribute "'&
4462 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4463 &//trim(input_fields(diag_field_id)%field_name)//
'"', fatal)
4466 output_fields(out_field)%attributes(this_attribute)%len = length
4467 output_fields(out_field)%attributes(this_attribute)%fatt = rval
4469 IF ( .NOT.
PRESENT(cval) )
THEN
4475 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',&
4476 &
'Attribute type claims CHARACTER, but cval not present for attribute "'&
4477 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4478 &//trim(input_fields(diag_field_id)%field_name)//
'". Contact the developers.', fatal)
4486 CALL error_mesg(
'diag_manager_mod::diag_field_add_attribute',
'Unknown attribute type for attribute "'&
4487 &//trim(name)//
'" to module/input_field "'//trim(input_fields(diag_field_id)%module_name)//
'/'&
4488 &//trim(input_fields(diag_field_id)%field_name)//
'". Contact the developers.', fatal)
4496 INTEGER,
INTENT(in) :: diag_field_id
4497 CHARACTER(len=*),
INTENT(in) :: att_name
4498 REAL,
INTENT(in) :: att_value
4500 if (use_modern_diag)
then
4501 call fms_diag_object%fms_diag_field_add_attribute(diag_field_id, att_name, (/att_value /))
4509 INTEGER,
INTENT(in) :: diag_field_id
4510 CHARACTER(len=*),
INTENT(in) :: att_name
4511 INTEGER,
INTENT(in) :: att_value
4513 if (use_modern_diag)
then
4514 call fms_diag_object%fms_diag_field_add_attribute(diag_field_id, att_name, (/att_value /))
4522 INTEGER,
INTENT(in) :: diag_field_id
4523 CHARACTER(len=*),
INTENT(in) :: att_name
4524 CHARACTER(len=*),
INTENT(in) :: att_value
4526 if (use_modern_diag)
then
4527 call fms_diag_object%fms_diag_field_add_attribute(diag_field_id, att_name, (/att_value /))
4535 INTEGER,
INTENT(in) :: diag_field_id
4536 CHARACTER(len=*),
INTENT(in) :: att_name
4537 REAL,
DIMENSION(:),
INTENT(in) :: att_value
4539 if (use_modern_diag)
then
4540 call fms_diag_object%fms_diag_field_add_attribute(diag_field_id, att_name, att_value)
4548 INTEGER,
INTENT(in) :: diag_field_id
4549 CHARACTER(len=*),
INTENT(in) :: att_name
4550 INTEGER,
DIMENSION(:),
INTENT(in) :: att_value
4552 if (use_modern_diag)
then
4553 call fms_diag_object%fms_diag_field_add_attribute(diag_field_id, att_name, att_value)
4565 INTEGER,
INTENT(in) :: diag_field_id
4566 INTEGER,
INTENT(in),
OPTIONAL :: area
4567 INTEGER,
INTENT(in),
OPTIONAL :: volume
4571 IF ( diag_field_id.GT.0 )
THEN
4572 IF ( .NOT.
PRESENT(area) .AND. .NOT.
present(volume) )
THEN
4573 CALL error_mesg(
'diag_manager_mod::diag_field_add_cell_measures', &
4574 &
'either area or volume arguments must be present', fatal )
4577 if (use_modern_diag)
then
4578 call fms_diag_object%fms_diag_field_add_cell_measures(diag_field_id, area, volume)
4582 DO j=1, input_fields(diag_field_id)%num_output_fields
4583 ind = input_fields(diag_field_id)%output_fields(j)
4591 class(*),
intent(in) :: data_in(:,:,:)
4592 character(len=*),
intent(in) :: field_name
4593 class(*),
allocatable,
intent(out) :: data_out(:,:,:,:)
4596 select type(data_in)
4597 type is (real(kind=r8_kind))
4598 allocate(real(kind=r8_kind) :: data_out(1:
size(data_in,1), 1:
size(data_in,2), 1:
size(data_in,3), 1))
4599 select type (data_out)
4600 type is (real(kind=r8_kind))
4601 data_out(:,:,:,1) = data_in
4603 call mpp_error(fatal,
"The copy of "//trim(field_name)//&
4604 " was not allocated to the correct type (r8_kind). This shouldn't have happened")
4606 type is (real(kind=r4_kind))
4607 allocate(real(kind=r4_kind) :: data_out(1:
size(data_in,1), 1:
size(data_in,2), 1:
size(data_in,3), 1))
4608 select type (data_out)
4609 type is (real(kind=r4_kind))
4610 data_out(:,:,:,1) = data_in
4612 call mpp_error(fatal,
"The copy of "//trim(field_name)//&
4613 " was not allocated to the correct type (r4_kind). This shouldn't have happened")
4616 call mpp_error(fatal,
"The data for "//trim(field_name)//&
4617 &
" is not a valid type. Currently only r4 and r8 are supported")
4621 END MODULE diag_manager_mod
integer(i4_kind) function, public axis_compatible_check(id, varname)
Checks if the axes are compatible.
integer function, public get_axis_length(id)
Return the length of the axis.
integer function, public get_axis_num(axis_name, set_name)
Returns index into axis table corresponding to a given axis name.
type(domain2d) function, public get_domain2d(ids)
Return the 2D domain for the axis IDs given.
integer function, public get_tile_count(ids)
Return the tile count for the axis.
subroutine, public get_diag_axis_name(id, axis_name)
Return the short name of the axis.
integer(i4_kind), parameter, public diag_axis_2ddomain
For unstructured grid support.
integer function, public diag_axis_init(name, array_data, units, cart_name, long_name, direction, set_name, edges, Domain, Domain2, DomainU, aux, req, tile_count, domain_position)
Initialize the axis, and return the axis ID.
integer(i4_kind), parameter, public diag_axis_ugdomain
For unstructured grid support.
Add an arbitrary attribute and value to the diagnostic axis.
integer max_output_fields
Maximum number of output fields. Increase via diag_manager_nml.
real fill_value
Fill value used. Value will be NF90_FILL_REAL if using the netCDF module, otherwise will be 9....
integer pack_size
1 for double and 2 for float
integer function get_base_minute()
gets the module variable base_minute
integer function get_base_year()
gets the module variable base_year
integer function get_base_hour()
gets the module variable base_hour
logical use_cmor
Indicates if we should overwrite the MISSING_VALUE to use the CMOR missing value.
logical flush_nc_files
Control if diag_manager will force a flush of the netCDF file on each write. Note: changing this to ....
integer max_axis_attributes
Maximum number of user definable attributes per axis.
character(len=6) pack_size_str
Pack size as a string to be used in fms2_io register call set to "double" or "float".
logical use_modern_diag
Namelist flag to use the modernized diag_manager code.
type(time_type) function get_base_time()
gets the module variable base_time
integer max_axes
Maximum number of independent axes.
logical use_mpp_io
false is fms2_io (default); true is mpp_io
integer, parameter diag_field_not_found
Return value for a diag_field that isn't found in the diag_table.
integer max_out_per_in_field
Maximum number of output_fields per input_field. Increase via diag_manager_nml.
integer max_input_fields
Maximum number of input fields. Increase via diag_manager_nml.
logical use_clock_average
.TRUE. if the averaging of variable is done based on the clock For example, if doing daily averages a...
logical issue_oor_warnings
Issue warnings if the output field has values outside the given range for a variable.
logical region_out_use_alt_value
Will determine which value to use when checking a regional output if the region is the full axis or a...
integer num_output_fields
Number of output fields in use.
integer function get_base_day()
gets the module variable base_day
type(time_type) diag_init_time
Time diag_manager_init called. If init_time not included in diag_manager_init call,...
integer max_files
Maximum number of output files allowed. Increase via diag_manager_nml.
integer num_files
Number of output files currenly in use by the diag_manager.
integer max_file_attributes
Maximum number of user definable global attributes per file.
real(r8_kind), parameter cmor_missing_value
CMOR standard missing value.
logical prepend_date
Should the history file have the start date prepended to the file name. .TRUE. is only supported if t...
character(len=2), dimension(:), allocatable fnum_for_domain
If this file number in the array is for the "unstructured" or "2d" domain.
subroutine diag_data_init()
Initialize and write the version number of this file to the log file.
integer function get_base_month()
gets the module variable base_month
logical module_is_initialized
Indicate if diag_manager has been initialized.
logical oor_warnings_fatal
Cause a fatal error if the output field has a value outside the given range for a variable.
integer function get_base_second()
gets the module variable base_second
logical use_refactored_send
Namelist flag to use refactored send_data math funcitons.
integer max_field_attributes
Maximum number of user definable attributes per field. Liptak: Changed from 2 to 4 20170718.
Define the region for field output.
Type to hold the output field description.
subroutine, public diag_grid_init(domain, glo_lat, glo_lon, aglo_lat, aglo_lon)
Send the global grid to the diag_manager_mod for regional output.
subroutine, public diag_grid_end()
Unallocate the diag_global_grid variable.
logical function, public need_data(diag_field_id, next_model_time)
Determine whether data is needed for the current model time step.
logical function get_related_field(field, rel_field, out_field_id, out_file_id)
Finds the corresponding related output field and file for a given input field.
logical function send_data_2d(diag_field_id, field, time, is_in, js_in, mask, rmask, ie_in, je_in, weight, err_msg)
integer function register_diag_field_scalar(module_name, field_name, init_time, long_name, units, missing_value, range, standard_name, do_not_log, err_msg, area, volume, realm, multiple_send_data)
Registers a scalar field.
subroutine diag_field_add_attribute_r1d(diag_field_id, att_name, att_value)
Add a real 1D array attribute to the diag field corresponding to a given id.
integer function, public register_static_field(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method, tile_count, area, volume, realm)
Return field index for subsequent call to send_data.
subroutine copy_3d_to_4d(data_in, data_out, field_name)
Copies a 3d buffer to a 4d buffer.
logical function send_data_4d(diag_field_id, field, time, is_in, js_in, ks_in, mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
Updates the output buffer for a field based on the data for current time step.
subroutine diag_field_attribute_init(diag_field_id, name, type, cval, ival, rval)
logical function send_tile_averaged_data3d(id, field, area, time, mask)
integer function register_diag_field_array(module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, area, volume, realm, multiple_send_data)
Registers an array field.
integer function register_diag_field_scalar_old(module_name, field_name, init_time, long_name, units, missing_value, range, standard_name, do_not_log, err_msg, area, volume, realm)
Registers a scalar field.
subroutine diag_field_add_attribute_i1d(diag_field_id, att_name, att_value)
Add an integer 1D array attribute to the diag field corresponding to a given id.
integer function register_static_field_old(module_name, field_name, axes, long_name, units, missing_value, range, mask_variant, standard_name, DYNAMIC, do_not_log, interp_method, tile_count, area, volume, realm)
Return field index for subsequent call to send_data.
subroutine closing_file(file, time)
Replaces diag_manager_end; close just one file: files(file)
subroutine, public diag_field_add_cell_measures(diag_field_id, area, volume)
Add the cell_measures attribute to a diag out field.
subroutine init_field_cell_measures(output_field, area, volume, err_msg)
If needed, add cell_measures and associated_file attribute to out field/file.
integer function register_diag_field_array_old(module_name, field_name, axes, init_time, long_name, units, missing_value, range, mask_variant, standard_name, verbose, do_not_log, err_msg, interp_method, tile_count, area, volume, realm)
Registers an array field.
subroutine, public diag_send_complete_instant(time)
The subroutine 'diag_send_complete_instant' allows the user to save diagnostic data on variable inter...
subroutine diag_field_add_attribute_scalar_i(diag_field_id, att_name, att_value)
Add a scalar integer attribute to the diag field corresponding to a given id.
subroutine average_tiles(diag_field_id, x, area, mask, out)
Calculates tile average of a field.
logical function send_data_0d(diag_field_id, field, time, err_msg)
subroutine add_associated_files(file_num, cm_file_num, cm_ind)
Add to the associated files attribute.
integer function writing_field(out_num, at_diag_end, error_string, time)
subroutine, public diag_manager_init(diag_model_subset, time_init, err_msg)
Initialize Diagnostics Manager.
integer function, public get_diag_field_id(module_name, field_name)
Return the diagnostic field ID of a given variable.
subroutine, public get_base_date(year, month, day, hour, minute, second)
Return base date for diagnostics.
subroutine diag_field_add_attribute_scalar_r(diag_field_id, att_name, att_value)
Add a scalar real attribute to the diag field corresponding to a given id.
logical function send_data_3d(diag_field_id, field, time, is_in, js_in, ks_in, mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
subroutine average_tiles1d(diag_field_id, x, area, mask, out)
Calculates average for a field with the given area and land mask.
logical function diag_send_data(diag_field_id, field, time, is_in, js_in, ks_in, mask, rmask, ie_in, je_in, ke_in, weight, err_msg)
logical function send_tile_averaged_data1d(id, field, area, time, mask)
logical function send_data_1d(diag_field_id, field, time, is_in, mask, rmask, ie_in, weight, err_msg)
subroutine, public diag_manager_end(time)
Flushes diagnostic buffers where necessary. Close diagnostics files. A warning will be issued here if...
logical function send_tile_averaged_data2d(id, field, area, time, mask)
integer function init_diurnal_axis(n_samples)
Finds or initializes a diurnal time axis and returns its' ID.
subroutine diag_field_add_attribute_scalar_c(diag_field_id, att_name, att_value)
Add a scalar character attribute to the diag field corresponding to a given id.
subroutine, public diag_send_complete(time_step, err_msg)
Saves diagnostic data for the given time value.
Add a attribute to the output field.
Register a diagnostic field for a given module.
Send data over to output fields.
Send tile-averaged data over to output fields.
subroutine, public get_diag_global_att(gAtt)
Return the global attribute type.
subroutine, public set_diag_global_att(component, gridType, tileName)
Set the global attribute type.
subroutine, public parse_diag_table(diag_subset, istat, err_msg)
Parse the diag_table in preparation for diagnostic output.
subroutine, public get_subfield_size(axes, outnum)
Get the size, start, and end indices for output fields.
subroutine, public init_input_field(module_name, field_name, tile_count)
Initialize the input field.
subroutine, public check_bounds_are_exact_static(out_num, diag_field_id, err_msg)
Check if the array indices for output_fields(out_num) are equal to the output_fields(out_num)buffer u...
integer function, public find_input_field(module_name, field_name, tile_count)
Return the field number for the given module name, field name, and tile number.
subroutine, public write_static(file)
Output all static fields in this file.
subroutine, public diag_data_out(file, field, dat, time, final_call_in, static_write_in, filename_time)
Write data out to file, and if necessary flush the buffers.
subroutine, public init_output_field(module_name, field_name, output_name, output_file, time_method, pack, tile_count, local_coord)
Initialize the output field.
type(time_type) function, public get_file_start_time(file_num)
Get the a diag_file's start_time as it is defined in the diag_table.
subroutine, public sync_file_times(file_id, init_time, err_msg)
Synchronize the file's start and close times with the model start and end times.
character(len=1), public field_log_separator
separator used for csv-style log of registered fields set by nml in diag_manager init
subroutine, public check_out_of_bounds(out_num, diag_field_id, err_msg)
Checks if the array indices for output_fields(out_num) are outside the output_fields(out_num)buffer u...
subroutine, public get_subfield_vert_size(axes, outnum)
Get size, start and end indices for output fields.
subroutine, public log_diag_field_info(module_name, field_name, axes, long_name, units, missing_value, range, dynamic)
Writes brief diagnostic field info to the log file.
subroutine, public update_bounds(out_num, lower_i, upper_i, lower_j, upper_j, lower_k, upper_k)
Update the output_fields x, y, and z min and max boundaries (array indices) with the six specified bo...
subroutine, public diag_util_init()
Write the version number of this file to the log file.
subroutine, public check_bounds_are_exact_dynamic(out_num, diag_field_id, Time, err_msg)
This is an adaptor to the check_bounds_are_exact_dynamic_modern function to maintain an interface ser...
Allocates the atttype in out_file.
Prepend a value to a string attribute in the output field or output file.
Interface fieldbuff_copy_fieldvals updates elements of the field output buffer with copies of corresp...
Interface fieldbuff_copy_missvals updates elements of the field output buffer with the missvalue inpu...
Interface fieldbuff_update updates elements of field output buffer based on input field data and math...
Class fmsDiagOutfield_type (along with class ms_diag_outfield_index_type ) contain information used i...
Class fms_diag_outfield_index_type which (along with class fmsDiagOutfield_type) encapsulate related ...
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
logical function, public fms_error_handler(routine, message, err_msg)
Facilitates the control of fatal error conditions.
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
integer function stdout()
This function returns the current standard fortran unit numbers for output.
integer function stdlog()
This function returns the current standard fortran unit numbers for log messages. Log messages,...
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.
integer function, public get_ticks_per_second()
Returns the number of ticks per second.
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
Returns days and seconds ( < 86400 ) corresponding to a time. err_msg should be checked for any error...
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
Gets the date for different calendar types. Given a time_interval, returns the corresponding date und...
Given an input date in year, month, days, etc., creates a time_type that represents this time interva...
Given some number of seconds and days, returns the corresponding time_type.
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.