This section should help you understand key aspects of the NUOPC Layer design that are critical for writing the code to make your model NUOPC Layer compliant. The NUOPC Layer includes four kinds of generic components, each with a different purpose in a coupled application. One kind of generic component is the NUOPC Model, a component that wraps a model code (such as an atmosphere, ocean, or ice model) such that it exposes the set of interfaces defined by the NUOPC specification. You will work primarily with the NUOPC Model generic component in order to make your model NUOPC Layer compliant.
This documentation focuses primarily on the NUOPC Model Component. However, you should be aware that there are four kinds of generic components implemented in the NUOPC Layer:
A key design idea behind NUOPC is that a lot of code (and therefore behavior) is provided for you. This code is provided via the four generic components included with the NUOPC library, plus some additional utility routines. The NUOPC Model generic component implements most of the initialization and run behavior for you, but you have to supply some key parts of the implementation that are specific to your model. The process of supplying your custom code that completes the generic NUOPC Model component is called specialization. In other words, you are specializing the generic component to work for your particular model. Any parts of the code that you do not specialize are inherited from the generic component.
Those familiar with object-oriented programming will recognize the ideas of specialization and inheritance. Since the NUOPC Layer is written in Fortran 90, which has limited support for object-oriented programming, your specialization code is provided in Fortran subroutines which are registered with NUOPC using function pointers. NUOPC makes callbacks into your code when required to execute the specialization code.
However, as detailed in the section 3.2, if your model is currently embedded as a subsystem in a larger application and cannot be built independently, you must first take steps to modularize the code and remove dependencies to other models before beginning the NUOPC implementation.
The creation of a NUOPC cap does not mean that your model must always be run as a NUOPC component. Existing models can retain their native modes of operation, and running your model in NUOPC mode becomes a configuration option.
The NUOPC cap becomes a new locus of control for your model when your model is run in NUOPC mode. In other words, it will make calls into your model code to initialize your model and step it forward in time. One result of this is that the very top level main program of your model may not be used at all when your model is run in NUOPC mode. This is because all models participating in a coupled NUOPC application will be controlled by a separate generic component: the NUOPC Driver.
Putting control into a separate driver enables synchronization of all models participating in a coupled application, allows NUOPC to control when each model component runs (and for how long), and allows NUOPC to intercept and inject variables produced and required by your model at key parts during execution. Once you have a working NUOPC cap (you only need to implement it once), you have an interoperable component that can be used in systems with other NUOPC components.
We also provide tools to help you check whether your cap is NUOPC-compliant. NUOPC Compliance can be evaluated using a combination of two tools, the Component Explorer and the Compliance Checker, included in the ESMF/NUOPC software distribution. More information is provided in sections 3.8 and 3.10.