Steps to perform the coupling ============================== To couple OpenWQ to an hydro-model, you need to call OpenWQ's coupler functions that contain a series of `API calls `_. The coupler functions provided are generic and were designed to require minimal editing, but each hydro-model is different so some adjustments are always needed. We refer to there adjustments as ``COUPLER CODE``. This editable ``COUPLER CODE`` is to ensure that the data types used in the hydro-model are properly converted to OpenWQ's own data types, so that the `API calls `_ can perform adequately. We suggest to place all the coupler calls inside the same file and name it ``OpenWQ_hydrolink.cpp``. It may be convenient to have an header file with the same name (``OpenWQ_hydrolink.h``). An example of these ``OpenWQ_hydrolink`` files can be seen `here `_. Inside these ``hydrolink`` files, we also suggest that the couplers are placed inside a class with the name ``OpenWQ``. However, all the steps described below, as well as the class names, consider these suggestions. For now, don't worry with editing the ``COUPLER CODE``; it's the last step in the coupling process. Bellow are all the steps you need to perform the coupling: STEP 1: Hydro-model structure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Identify the following components of your hydro-model. It is important that you understand the source code of your model. .. image:: coupling_steps_1.png :width: 500 :alt: Host-model structure STEP 2: Get OpenWQ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To download OpenWQ in your machine, follow the steps indicated in section `Get OpenWQ `_. STEP 3: Create class objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Before you can call OpenWQ's coupler functions, you need to create OpenWQ class objects inside your hydro-model. This can be accomplished by introducing the code below inside your hydro-model. This code should be placed in a ``main`` function of your hydro-model from where the created objects objects can be passed to OpenWQ's coupler functions. This is a critical step since these objects are input arguments of the different `OpenWQ's APIs `_ (passed by reference). .. code-block:: guess // Include OpenWQ header files #include "/OpenWQ_couplercalls.h" #include "/OpenWQ_global.h" #include "/OpenWQ_readjson.h" #include "/OpenWQ_initiate.h" #include "/OpenWQ_CH_model.h" #include "/OpenWQ_watertransp.h" #include "/OpenWQ_sinksource.h" #include "/OpenWQ_units.h" #include "/OpenWQ_compute.h" #include "/OpenWQ_output.h" // Create OpenWQ Class Objects OpenWQ_couplercalls OpenWQ_couplercalls; // Class that contains coupler functions OpenWQ_hostModelconfig OpenWQ_hostModelconfig; // Class that stores hydro-model info OpenWQ_json OpenWQ_json; // Class that stores JSON input data OpenWQ_wqconfig OpenWQ_wqconfig(''); // Class that contains configuration functions OpenWQ_units OpenWQ_units; // Class that contains unit conversion functions OpenWQ_readjson OpenWQ_readjson; // Class that contains functions to read and process JSON files int num_HydroComp = ; // Set number of compartments/domains of the hydro-model OpenWQ_vars OpenWQ_vars(num_HydroComp); // Class that stores global variables OpenWQ_initiate OpenWQ_initiate; // Class tht contains pre-processing and initiation functions OpenWQ_watertransp OpenWQ_watertransp; // Class that contains water transport functions OpenWQ_CH_model OpenWQ_CH_model; // Cass that contains biogeochemical functions OpenWQ_sinksource OpenWQ_sinksource; // Cass that contains functions related to sinks and sources OpenWQ_compute OpenWQ_compute; // Class containing solvers OpenWQ_output OpenWQ_output; // Class containing printing functions // Include hydrolink header file #include "/OpenWQ_hydrolink.h" STEP 4: Locate coupler functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Referring to the diagram in STEP 1, now you need to identify the main functions or code blocks of your hydro-model that are responsible for the tasks listed below. * [``CONFIGURATION``] * [``SIMULATION`` > ``TIME LOOP`` > ``Before space loop``] * [``SPACE LOOP``] * [``SIMULATION`` > ``TIME LOOP`` > ``After space loop``] STEP 5: Call coupler functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From each of those hydro-model functions or code blocks, call the following `OpenWQ coupler functions `_: * [``CONFIGURATION``]: call Coupler Function 1 (``OpenWQ::decl``) * [``SIMULATION`` > ``TIME LOOP`` > ``Before space loop``]: call Coupler Function 2 (``OpenWQ::run_time_start``) * [``SPACE LOOP``]: call Coupler Function 3 (``OpenWQ::run_space``) * [``SIMULATION`` > ``TIME LOOP`` > ``After space loop``]: Coupler Function 4 (``OpenWQ::run_time_end``) The diagram below shows these coupler calls: .. image:: coupling_steps_2.png :width: 600 :alt: API calls STEP 6: Adjust coupler to hydro-model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OpenWQ's coupler functions are generic and have been designed to require minimal editing. However, as previously said, each hydro-model is different and small adjustments are needed to ensure the hydro-model passes the correct arguments to `OpenWQ's APIs `_. The diagrams below list code editing needed, identified as ``COUPLE CODE``. * Coupler Function 1 (``OpenWQ::decl``) This coupler function contains a series of API calls that deal with the initial configuration of the model, initialization of variables, and pre-processing of the input data. .. image:: coupling_steps_3.png :width: 700 :alt: API calls * Coupler Function 2 (``OpenWQ::run_time_start``) This coupler function contains a series of API calls that handle tasks required at the start of each time step. .. image:: coupling_steps_4.png :width: 700 :alt: API calls * Coupler Function 3 (``OpenWQ::run_space``) This coupler function contains a series of API calls that handles tasks related to the spatial domain of the model. .. image:: coupling_steps_5.png :width: 700 :alt: API calls * Coupler Function 4 (``CLASSWQ_openwq::OpenWQ::run_time_end``) This coupler call function contains a series of API calls that handle tasks required at the end of each time step. .. image:: coupling_steps_6.png :width: 700 :alt: API calls STEP 7: Compile your coupled code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now you need to adapt your ``MakeFile`` or '`CMakeLists` files to properly link and compile OpenWQ together with your hydro-model. * Include flags for external libraries: * Armdadillo (fag: ``--larmadillo``) * OpenMP (flag: ``-fopenmp``) * Link OpenWQ objects in your compilation instruction: .. code-block:: guess /OpenWQ_couplercalls.o \ /OpenWQ_hydrolink.o \ /OpenWQ_readjson.o \ /OpenWQ_initiate.o \ /OpenWQ_CH_model.o \ /OpenWQ_watertransp.o \ /OpenWQ_sinksource.o \ /OpenWQ_units.o \ /OpenWQ_compute.o \ /OpenWQ_output.o \