forked from marbl-ecosys/MARBL
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update documentation to include output_for_GCM
A new page explains what additional output is available from the GCM, and a second page shows how to add a new output. The new available_output test is also documented on the regression tests page.
- Loading branch information
1 parent
ef58f3b
commit 1c59f37
Showing
7 changed files
with
278 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
.. _add-ofg: | ||
|
||
============================ | ||
Adding an Output for the GCM | ||
============================ | ||
|
||
In addition to surface fluxes and interior tendencies, MARBL can provide :ref:`additional output <additional_output>` as well. | ||
These might be fluxes that feed back to the atmosphere, or tracer sums used for other physical properties. | ||
Adding a new output is a straightforward process. | ||
|
||
------------------------------------------------- | ||
Step 1. Add to MARBL output for GCM indexing type | ||
------------------------------------------------- | ||
|
||
MARBL tracks the internal index of each output for the GCM in the ``output_for_GCM_type`` components of the interface | ||
(``surface_flux_output`` and ``interior_tendency_output``). | ||
There is a module variable in ``marbl_interface_public_types.F90`` of type ``marbl_output_for_GCM_indexing_type``: | ||
|
||
.. code block from marbl_interface_public_types | ||
.. code-block:: fortran | ||
type, public :: marbl_output_for_GCM_indexing_type | ||
integer(int_kind) :: flux_o2_id = 0 | ||
integer(int_kind) :: flux_co2_id = 0 | ||
integer(int_kind) :: flux_nhx_id = 0 | ||
integer(int_kind) :: total_surfChl_id = 0 | ||
integer(int_kind) :: total_Chl_id = 0 | ||
end type marbl_output_for_GCM_indexing_type | ||
type(marbl_output_for_GCM_indexing_type), target, public :: ofg_ind | ||
``ofg_ind`` is a target because there is a registry of all defined outputs for the GCM that use pointers to | ||
make sure the correct index is updated. | ||
Any new outputs for the GCM must have an index added to this indexing type. | ||
|
||
--------------------------------------------------- | ||
Step 2. Add to MARBL output for GCM output registry | ||
--------------------------------------------------- | ||
|
||
MARBL tracks what outputs are available via the ``marbl_output_for_GCM_registry_type``. | ||
When a GCM calls ``marbl_instance%add_output_for_GCM()``, | ||
MARBL checks the registry to see if it can provide the output. | ||
|
||
.. code block from marbl_interface_public_types | ||
.. code-block:: fortran | ||
type, public :: marbl_output_for_GCM_linked_list_type | ||
character(len=char_len) :: short_name | ||
character(len=char_len) :: long_name | ||
character(len=char_len) :: units | ||
character(len=char_len) :: field_source | ||
character(len=char_len) :: err_message | ||
integer(int_kind), pointer :: id | ||
type(marbl_output_for_GCM_linked_list_type), pointer :: next => NULL() | ||
end type marbl_output_for_GCM_linked_list_type | ||
!***************************************************************************** | ||
type, public :: marbl_output_for_GCM_registry_type | ||
type(marbl_output_for_GCM_linked_list_type), pointer :: registered_outputs | ||
contains | ||
procedure, public :: create_registry | ||
procedure, private :: add_registry_entry | ||
end type marbl_output_for_GCM_registry_type | ||
``create_registry()`` is called during MARBL initialization, | ||
and it makes repeated use of the ``add_registry_entry()`` subroutine. | ||
To add a new output to the registry, copy an existing block and modify appropriately: | ||
|
||
.. code block from marbl_interface_public_types | ||
.. code-block:: fortran | ||
! Surface Chlorophyll | ||
err_message = "" | ||
if (.not. base_bio_on) & | ||
err_message = "requires base biotic tracers" | ||
call this%add_registry_entry(short_name = "total_surfChl", & | ||
long_name = "Total Surface Chlorophyll Concentration", & | ||
units = "mg/m^3", & | ||
field_source = "surface_flux", & | ||
id = ofg_ind%total_surfChl_id, & | ||
err_message = err_message) | ||
! Full Depth Chlorophyll | ||
err_message = "" | ||
if (.not. base_bio_on) & | ||
err_message = "requires base biotic tracers" | ||
call this%add_registry_entry(short_name = "total_Chl", & | ||
long_name = "Total Chlorophyll Concentration", & | ||
units = "mg/m^3", & | ||
field_source = "interior_tendency", & | ||
id = ofg_ind%total_Chl_id, & | ||
err_message = err_message) | ||
* ``field_source`` will tell the GCM whether to look for updated values of this output | ||
after calls to ``surface_flux_compute()`` or ``interior_tendency_compute()``. | ||
* If ``err_message`` is an empty string, then this output is available for the GCM. | ||
If MARBL is configured in a way such that this output will not be computed, | ||
``err_message`` should give a concise explanation of why it is unavailable. | ||
MARBL will return the error ``{short_name} {err_message}`` -- for example, | ||
if ``base_bio_on = .false.`` and a GCM requests ``total_Chl`` then MARBL will abort with the message | ||
``total_Chl requires base biotic tracers``. | ||
|
||
------------------------------------------------ | ||
Step 3. Copy Output into ``output_for_GCM_type`` | ||
------------------------------------------------ | ||
|
||
If ``field_source = "surface_flux"`` you need something like this inside ``surface_flux_compute()``: | ||
|
||
.. code block from marbl_surface_flux_mod | ||
.. code-block:: fortran | ||
!----------------------------------------------------------------------- | ||
! Compute surface chlorophyll (if requested by GCM) | ||
!----------------------------------------------------------------------- | ||
if (ofg_ind%total_surfChl_id.ne.0) then | ||
totalChl_loc = c0 | ||
do auto_ind = 1,autotroph_cnt | ||
totalChl_loc = totalChl_loc + & | ||
max(c0, tracers_at_surface(:,marbl_tracer_indices%auto_inds(auto_ind)%Chl_ind)) | ||
end do | ||
surface_flux_output%outputs_for_GCM(ofg_ind%total_surfChl_id)%forcing_field_0d(:) = totalChl_loc | ||
end if | ||
Otherwise, ``field_source = "interior_tendency"`` and you need something like this inside ``interior_tendency_compute()``: | ||
|
||
.. code block from marbl_interior_tendency_mod | ||
.. code-block:: fortran | ||
!----------------------------------------------------------------------- | ||
! Compute Chlorophyll (if requested by GCM) | ||
!----------------------------------------------------------------------- | ||
if (ofg_ind%total_Chl_id.ne.0) then | ||
interior_tendency_output%outputs_for_GCM(ofg_ind%total_Chl_id)%forcing_field_1d(1,:) = c0 | ||
do auto_ind = 1,autotroph_cnt | ||
interior_tendency_output%outputs_for_GCM(ofg_ind%total_Chl_id)%forcing_field_1d(1,:) = & | ||
interior_tendency_output%outputs_for_GCM(ofg_ind%total_Chl_id)%forcing_field_1d(1,:) & | ||
+ tracer_local(marbl_tracer_indices%auto_inds(auto_ind)%Chl_ind,:) | ||
end do | ||
end if | ||
Note that, in both examples, the output is only computed and stored if the index is positive. | ||
If the GCM did not request this output, | ||
memory will not be allocated to store it and MARBL won't spend time computing it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,5 @@ Examples of common development tasks. | |
add-diagnostic.rst | ||
add-settings-parameter.rst | ||
add-tracer.rst | ||
add-ofg.rst | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
.. _additional_output: | ||
|
||
================= | ||
Additional Output | ||
================= | ||
|
||
MARBL can provide more output than just surface fluxes and interior tendencies. | ||
For example, MARBL can return the total chlorophyll concentration to the GCM, | ||
which can then be used to compute shortwave absorption. | ||
(MARBL can provide both surface chlorophyll and the full depth chlorophyll field, | ||
since difference shortwave absorption algorithms have different inputs.) | ||
MARBL can also provide the O2, CO2, and NHx fluxes at the surface if the GCM wants those to feedback to the atmosphere. | ||
|
||
---------------- | ||
Available Fields | ||
---------------- | ||
|
||
The full list of outputs is available from the ``available_output`` regression test. | ||
In the default configuration, the complete list is | ||
|
||
.. block comes from available_output test | ||
.. code-block:: none | ||
------------------------ | ||
Available output for GCM | ||
------------------------ | ||
1. Total Chlorophyll Concentration | ||
short name: total_Chl | ||
units: mg/m^3 | ||
field_source: interior_tendency | ||
2. Total Surface Chlorophyll Concentration | ||
short name: total_surfChl | ||
units: mg/m^3 | ||
field_source: surface_flux | ||
3. NHx Surface Emissions | ||
short name: flux_nhx | ||
units: nmol/cm^2/s | ||
field_source: surface_flux | ||
4. Carbon Dioxide Flux | ||
short name: flux_co2 | ||
units: nmol/cm^2/s | ||
field_source: surface_flux | ||
5. Oxygen Flux | ||
short name: flux_o2 | ||
units: nmol/cm^2/s | ||
field_source: surface_flux | ||
----------------- | ||
Requesting Output | ||
----------------- | ||
|
||
By default, MARBL will not return any of the additional output. | ||
To request one or more of these fields, | ||
use the ``add_output_for_GCM()`` function on the MARBL interface: | ||
|
||
.. block comes from marbl_interface | ||
.. code-block:: fortran | ||
subroutine add_output_for_GCM(this, num_elements, field_name, output_id, field_source, num_levels) | ||
! Check the registry to see if field_name is provided from surface_flux_compute() or interior_tendency_compute() | ||
! add it to the proper output_for_GCM type, or log a useful error message | ||
use marbl_interface_public_types, only : marbl_output_for_GCM_linked_list_type | ||
class (marbl_interface_class), intent(inout) :: this | ||
character(len=*), intent(in) :: field_name | ||
integer(int_kind), intent(in) :: num_elements | ||
integer(int_kind), intent(out) :: output_id | ||
character(len=*), intent(out) :: field_source | ||
integer(int_kind), optional, intent(in) :: num_levels | ||
The output field ``field_source`` will be ``interior_tendency_output`` or ``surface_flux_output`` | ||
component of the MARBL interface type. | ||
The following block of code from the stand-alone driver shows how to request both surface and total chlorophyll. | ||
Note that the driver tracks how many outputs are coming from ``field_source = "surface_flux"`` | ||
and how many come from ``field_source = "interior_tendency"``. | ||
|
||
.. block comes from marbl_call_compute_subroutines_drv.F90 | ||
.. code-block:: fortran | ||
if (base_bio_on) then | ||
do n=1, size(marbl_instances) | ||
call marbl_instances(n)%add_output_for_GCM(num_elements=col_cnt(n), & | ||
field_name="total_surfChl", & | ||
output_id=total_surfChl_id, & | ||
field_source=field_source) | ||
if (marbl_instances(n)%StatusLog%labort_marbl) then | ||
call marbl_instances(n)%StatusLog%log_error_trace('marbl%add_output_for_GCM(total_surfChl)', subname) | ||
return | ||
end if | ||
end do | ||
if (trim(field_source) == "surface_flux") then | ||
sfo_cnt = sfo_cnt+1 | ||
else if (trim(field_source) == "interior_tendency") then | ||
ito_cnt = ito_cnt+1 | ||
else | ||
write(log_message, "(3A)") "'", trim(field_source), "' is not a recognized field source (total_surfChl)" | ||
call driver_status_log%log_error(log_message, subname) | ||
return | ||
end if | ||
end if | ||
if (base_bio_on) then | ||
do n=1, size(marbl_instances) | ||
call marbl_instances(n)%add_output_for_GCM(num_elements=col_cnt(n), & | ||
field_name="total_Chl", & | ||
output_id=total_Chl_id, & | ||
num_levels=num_levels, & | ||
field_source=field_source) | ||
if (marbl_instances(n)%StatusLog%labort_marbl) then | ||
call marbl_instances(n)%StatusLog%log_error_trace('marbl%add_output_for_GCM(total_Chl)', subname) | ||
return | ||
end if | ||
end do | ||
if (trim(field_source) == "surface_flux") then | ||
sfo_cnt = sfo_cnt+1 | ||
else if (trim(field_source) == "interior_tendency") then | ||
ito_cnt = ito_cnt+1 | ||
else | ||
write(log_message, "(3A)") "'", trim(field_source), "' is not a recognized field source (total_Chl)" | ||
call driver_status_log%log_error(log_message, subname) | ||
return | ||
end if | ||
end if |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters