marbl-ecosys / MARBL

Marine Biogeochemistry Library
https://marbl-ecosys.github.io
Other
14 stars 25 forks source link

Share more code between test suite and library #456

Open mnlevy1981 opened 8 months ago

mnlevy1981 commented 8 months ago

While discussing the available_output test introduced in #453 with @klindsay28, I noted that output_for_gcm_registry was a private component of the MARBL interface class but is needed in the driver. We both agree that it is undesirable to have something public solely for the purpose of calling it from the test suite, and brainstormed possible fixes.

One idea that we both like is to have a report_output_for_GCM() function that contains all the logic of the stand-alone available_output test and is also called from init() -- it would be useful for the GCM to log what is (and is not) available, and this reduces duplicate code. Taking this a step further, the output from all the requested_* tests could be generated from function calls and shared between the test suite and initialization. For example, this block of code from marbl_init_mod.F90

      !--------------------------------------------------------------------
      ! Report what forcings are required from the driver
      !--------------------------------------------------------------------

      call marbl_status_log%log_header('MARBL-Required Forcing Fields', subname)
      call marbl_status_log%log_noerror('Surface:', subname)
      do i=1,size(surface_flux_forcings)
        write(log_message, "(2A)") '* ', trim(surface_flux_forcings(i)%metadata%varname)
        call marbl_status_log%log_noerror(log_message, subname)
      end do

      call marbl_status_log%log_noerror('', subname)
      call marbl_status_log%log_noerror('Interior:', subname)
      do i=1,size(interior_tendency_forcings)
        write(log_message, "(2A)") '* ', trim(interior_tendency_forcings(i)%metadata%varname)
        call marbl_status_log%log_noerror(log_message, subname)
      end do

looks an awful lot like the code in the request_forcings case in the stand-alone driver

        ! Log requested surface forcing fields
        call driver_status_log%log_header('Requested surface forcing fields', subname)
        do n=1,size(marbl_instances(1)%surface_flux_forcings)
          write(log_message, "(I0, 5A)") n, '. ', &
                trim(marbl_instances(1)%surface_flux_forcings(n)%metadata%varname), &
                ' (units: ', trim(marbl_instances(1)%surface_flux_forcings(n)%metadata%field_units),')'
          call driver_status_log%log_noerror(log_message, subname)
        end do

        ! Log requested interior forcing fields
        call driver_status_log%log_header('Requested interior forcing fields', subname)
        ! Provide message if no itnerior tendency forcings are requested
        if (size(marbl_instances(1)%interior_tendency_forcings) == 0) &
          call driver_status_log%log_noerror('No forcing fields requested for interior_tendency_compute()!', subname)
        do n=1,size(marbl_instances(1)%interior_tendency_forcings)
          write(log_message, "(I0, 5A)") n, '. ', &
               trim(marbl_instances(1)%interior_tendency_forcings(n)%metadata%varname), &
               ' (units: ', trim(marbl_instances(1)%interior_tendency_forcings(n)%metadata%field_units),')'
          call driver_status_log%log_noerror(log_message, subname)
        end do

although I updated the stand-alone test to include the forcing units and that is not reflected in the log output from initialization. Similarly, the output of requested_tracers includes units while the initialization log just lists the tracer short names.