write_gmbe_pie_json_impl Subroutine

private subroutine write_gmbe_pie_json_impl(data)

Write GMBE PIE calculation results to output JSON file

Arguments

Type IntentOptional Attributes Name
type(json_output_data_t), intent(in) :: data

Calls

proc~~write_gmbe_pie_json_impl~~CallsGraph proc~write_gmbe_pie_json_impl write_gmbe_pie_json_impl add add proc~write_gmbe_pie_json_impl->add create_array create_array proc~write_gmbe_pie_json_impl->create_array create_object create_object proc~write_gmbe_pie_json_impl->create_object destroy destroy proc~write_gmbe_pie_json_impl->destroy error error proc~write_gmbe_pie_json_impl->error info info proc~write_gmbe_pie_json_impl->info initialize initialize proc~write_gmbe_pie_json_impl->initialize proc~get_basename get_basename proc~write_gmbe_pie_json_impl->proc~get_basename proc~get_output_json_filename get_output_json_filename proc~write_gmbe_pie_json_impl->proc~get_output_json_filename

Called by

proc~~write_gmbe_pie_json_impl~~CalledByGraph proc~write_gmbe_pie_json_impl write_gmbe_pie_json_impl proc~write_json_output write_json_output proc~write_json_output->proc~write_gmbe_pie_json_impl proc~run_calculation run_calculation proc~run_calculation->proc~write_json_output proc~compute_energy_and_forces compute_energy_and_forces proc~compute_energy_and_forces->proc~run_calculation proc~run_multi_molecule_calculations run_multi_molecule_calculations proc~run_multi_molecule_calculations->proc~run_calculation program~main main program~main->proc~run_calculation program~main->proc~run_multi_molecule_calculations

Variables

Type Visibility Attributes Name Initial
integer, private, allocatable :: atom_indices(:)
character(len=256), private :: basename
integer(kind=int64), private :: i
integer, private :: io_stat
integer, private :: iunit
integer, private :: j
type(json_core), private :: json
type(json_value), private, pointer :: main_obj
integer, private :: max_atoms
integer, private :: n_atoms
integer(kind=int64), private :: n_nonzero_terms
character(len=256), private :: output_file
type(json_value), private, pointer :: pie_obj
type(json_value), private, pointer :: root
type(json_value), private, pointer :: term_obj
type(json_value), private, pointer :: terms_arr

Source Code

   subroutine write_gmbe_pie_json_impl(data)
      !! Write GMBE PIE calculation results to output JSON file
      type(json_output_data_t), intent(in) :: data

      type(json_core) :: json
      type(json_value), pointer :: root, main_obj, pie_obj, terms_arr, term_obj
      integer :: j, max_atoms, n_atoms, iunit, io_stat
      integer(int64) :: i, n_nonzero_terms
      integer, allocatable :: atom_indices(:)
      character(len=256) :: output_file, basename

      output_file = get_output_json_filename()
      basename = get_basename()

      call json%initialize(real_format=JSON_REAL_FORMAT)
      call json%create_object(root, '')
      call json%create_object(main_obj, trim(basename))
      call json%add(root, main_obj)

      call json%add(main_obj, 'total_energy', data%total_energy)

      if (data%has_gradient .and. allocated(data%gradient)) then
         call json%add(main_obj, 'gradient_norm', sqrt(sum(data%gradient**2)))
      end if
      if (data%has_hessian .and. allocated(data%hessian)) then
         call json%add(main_obj, 'hessian_frobenius_norm', sqrt(sum(data%hessian**2)))
      end if

      ! Count non-zero coefficient terms
      if (allocated(data%pie_coefficients)) then
         n_nonzero_terms = count(data%pie_coefficients(1:data%n_pie_terms) /= 0)
      else
         n_nonzero_terms = 0
      end if

      ! PIE terms section
      call json%create_object(pie_obj, 'pie_terms')
      call json%add(main_obj, pie_obj)
      call json%add(pie_obj, 'count', int(n_nonzero_terms))

      call json%create_array(terms_arr, 'terms')
      call json%add(pie_obj, terms_arr)

      if (allocated(data%pie_atom_sets) .and. allocated(data%pie_coefficients) .and. &
          allocated(data%pie_energies)) then
         max_atoms = size(data%pie_atom_sets, 1)

         do i = 1_int64, data%n_pie_terms
            if (data%pie_coefficients(i) == 0) cycle

            call json%create_object(term_obj, '')
            call json%add(terms_arr, term_obj)

            ! Extract atom list size (atoms until negative sentinel)
            n_atoms = 0
            do while (n_atoms < max_atoms .and. data%pie_atom_sets(n_atoms + 1, i) >= 0)
               n_atoms = n_atoms + 1
            end do

            allocate (atom_indices(n_atoms))
            atom_indices = data%pie_atom_sets(1:n_atoms, i)
            call json%add(term_obj, 'atom_indices', atom_indices)
            deallocate (atom_indices)

            call json%add(term_obj, 'coefficient', data%pie_coefficients(i))
            call json%add(term_obj, 'energy', data%pie_energies(i))
            call json%add(term_obj, 'weighted_energy', real(data%pie_coefficients(i), dp)*data%pie_energies(i))
         end do
      end if

      ! Write to file
      call logger%info("Writing GMBE PIE JSON output to "//trim(output_file))
      open (newunit=iunit, file=trim(output_file), status='replace', action='write', iostat=io_stat)
      if (io_stat /= 0) then
         call logger%error("Failed to open "//trim(output_file)//" for writing")
         call json%destroy(root)
         return
      end if

      call json%print(root, iunit)
      close (iunit)
      call json%destroy(root)
      call logger%info("GMBE PIE JSON output written successfully to "//trim(output_file))

   end subroutine write_gmbe_pie_json_impl