From f31648e33fbae230ed4ba377fdcda68aefbad726 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 13:03:25 -0600 Subject: [PATCH 01/15] Update "adding a tracer" documentation and update the tutorial in the appendix. --- doc/source/appendices/tutorial.rst | 203 ++++++------------ .../developer_guide/dg_adding_tracers.rst | 107 ++++++--- 2 files changed, 137 insertions(+), 173 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index fbd0aa567..08bc03e22 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -10,7 +10,7 @@ Icepack Tutorial Learning Goals ---------------- -In this activity you will clone the Icepack model code from the Consortium GitHub repository to run standalone Icepack simulations. You will also make namelist changes and code modifications for experiments and make some basic plots. If you run into issues, contact dbailey@ucar.edu. +In this activity you will clone the Icepack model code from the Consortium GitHub repository, create a branch, add a new tracer to Icepack, and run standalone Icepack simulations. You will also make namelist changes and code modifications for experiments and make some basic plots. Notes: @@ -23,196 +23,117 @@ Notes: * CICE and Icepack Resources, https://github.com/CICE-Consortium/About-Us/wiki/Resource-Index -Github One-time Configuration ----------------------------------- +Create An Icepack Branch, Port, and Run Initial Case +------------------------------------------------------ -You need to have your own GitHub account before you can start the following activities, and you should have already forked the Icepack repository. -For information about how to set up a GitHub account for the Icepack repository, see the Consortium documentation here, https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide. The Consortium recommends that you keep your fork’s main branch in sync with the Consortium version and that you always work on branches. This is all documented in the Git-Workflow-Guide linked above. +You should fork the Icepack repository and create a new branch in your fork for development. This is documented in https://github.com/CICE-Consortium/About-Us/wiki/Git-Workflow-Guide. But basically, -Note: +* Create a github account for yourself +* Fork the Consortium Icepack repository using the "Fork" feature at https://github.com/CICE-Consortium/Icepack +* Clone your repository onto your machine +* Create a branch +* Checkout the branch +* Port the model, verify you can run the model, run a test suite -* The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. Icepack can be set up and run as an independent model following the same workflow. +You may be able to leverage the conda port to build and run the model, you may be working on a supported machine, or you may have to port the model to your machine. Porting, setting up cases, building, running, and running test suites are all documented in the Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html. There are many ways to setup and run the model. +* **Note:** The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. Icepack can be set up and run as an independent model following the same workflow. -Clone Icepack -------------------- +To summarize the steps in greater details **assuming use of conda in a Mac or Linux environment**. -Clone your Icepack repository fork (use the URL from your fork) to a local sandbox:: +* Fork the Consortium Icepack repository + +* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: mkdir ~/icepack-dirs cd ~/icepack-dirs git clone https://github.com//Icepack - -If you have completed this correctly there should be an “Icepack” directory in the icepack-dirs directory. This is the “sandbox” we will be working in locally on your machine. - -Move to the Icepack directory and check which branch you are using. This should be main:: - cd Icepack - git status - -Take a minute to orient yourself to the big picture structure of the directories and files in Icepack. The documentation has information about the Icepack :ref:`dirstructure`. - -Make sure your main is up to date and create a branch. You can also update your fork directly in github by clicking the Sync fork button. If your code is already up to date, you can skip this step:: - - git remote --v (Check the origin and NO upstream) + git status (Branch should be main) + git remote --v (Check the origin and NO upstream) git remote add upstream https://github.com/CICE-Consortium/Icepack - git remote --v (Check upstream has been added) + git remote --v (Check upstream has been added) git pull upstream main git push origin main git branch git checkout + git status (Branch should be ) - -Conda and Laptop One-time Configuration ------------------------------------------- - -To build and run Icepack on your laptop, you need to install software via conda. Instructions on how to do that can be found in the Icepack user guide, :ref:`laptops`. If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. Make sure to follow the instructions for installing miniconda. If your laptop has a conda environment already installed, you will still need to activate the icepack environment, and you may need to do so using the recommended miniconda distribution. Return here after completing section :ref:`laptops` in the documentation. After installing miniconda, the main steps are:: - - cd ~/icepack-dirs/Icepack - conda env create -f configuration/scripts/machines/environment.yml - conda activate icepack - -Before you can run Icepack, you have to set up a directory structure and download the input and forcing datasets:: +* Setup local env and download input datasets:: mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline cd ~/icepack-dirs/input curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz tar -xzf Icepack_data-20200326.tar.gz -You can also run Icepack on an external machine that is supported by the Consortium or to which you have ported the code. In this case, you do not need to port to your laptop. +* Setup the conda environment, see :ref:`laptops`:: + curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/Downloads/miniconda.sh + bash ~/Downloads/miniconda.sh + source $HOME/miniconda3/bin/activate + conda init bash + conda config --set auto_activate_base false + source $HOME/miniconda3/bin/activate + cd ~/icepack-dirs/Icepack + conda env create -f configuration/scripts/machines/environment.yml + conda activate icepack -Set Up an Icepack Simulation ------------------------------ - -Use the online Icepack documentation and in particular the :ref:`quickstart` and :ref:`running_icepack` sections as guidance and for details on the command line settings:: - - cd ~/icepack-dirs - mkdir cases - cd ~/Icepack - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test0 --mach --env - -Notes: - -* If you are doing this in the conda environment, the machine is “conda”. -* Similarly, the variable is set to the compiler on your machine. For the conda environment, this is “macos” or “linux”. +* **NOTE:** If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. -The setup script creates a case consistent with the machine and other defined settings under ~/icepack-dirs/cases/ with the name you selected (icepack_test0). The case directory will contain build and run scripts, a namelist file, and other necessary files. Once the case is set up any of these files can be manually edited to refine the desired configuration. +Again, there are many options for setting up the model on hardware, see the Icepack User Guide for more details. -Move to the new case directory and examine the settings:: +* Set Up an Icepack Simulation. See :ref:`quickstart` and :ref:`running_icepack`:: + cd ~/Icepack + ./icepack.setup --case icepack_test0 --mach conda --env macos -s diag1 cd ~/icepack-dirs/cases/icepack_test0 - -Open the **icepack.settings** file and look at it briefly. Note the ICE_CASEDIR (it should match this directory) and the ICE_RUNDIR (where the model will be run and output created). Now look at the default namelist settings in **icepack_in**. - -Build the code:: - ./icepack.build - -The build script basically runs gmake under the covers, but there are a number of other tasks that are handled by the script to make the build more robust. If the build is successful you will see the message “COMPILE SUCCESSFUL” at the bottom of the screen. You can also check the README.case file to check the status. - -Submit the job. The submit script just submits the run scripts. Look at both **icepack.run** and **icepack.submit** files to see more details. The out-of-the-box run has default settings for the physics and other options. You can have a look at **icepack_in** and **icepack.settings** to review those settings. Then:: - ./icepack.submit -If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! - -Look at the output! Go to the ICE_RUNDIR where output was created. A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.2016-01-01-00000”. The Icepack documentation has more information about :ref:`history`. - -Follow the documentation to create some plots of the output using the tools provided with Icepack (:ref:`testplotting`). The conda icepack environment must be activated, if it isn’t already:: - - cd ~/icepack-dirs/Icepack/configuration/scripts/tests/ - conda activate icepack - ./timeseries.csh ~/icepack-dirs/runs/icepack_test0/ice_diag.full_ITD - -Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. Open the files:: - - cd ~/icepack-dirs/runs/icepack_test0/ - open .png - -Or use your file browser to navigate to the directory and double click on the images. - -Questions to think about while looking at the output. - -* What time period does an out-of-the-box run cover? -* What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? -* What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? -* How does your output compare to the sample output provided for this release? (hint: see the wiki!) - -Take a step back and think about all the directories and files you have created. The Icepack “sandbox” was cloned from GitHub and has the actual Icepack code. - -* There is a particular case directory for building and launching the code, and some output (e.g. job log) are copied. -* There is a particular run directory for each case. This is where the model is run and big files are found. - - -Set Up a Longer Run ---------------------- +Several env variables are defined in **icepack.settings** and the Icepack namelist file is **icepack_in**. Output files are copied from the run directory to a logs directory under the case. If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! -Once you have had success with the previous step, you can run another, longer experiment to practice some basic changes for Icepack. Go back to your Icepack directory:: +Look at the output! Go to the ICE_RUNDIR (defined in **icepack.settings**). A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.2016-01-01-00000”. The Icepack documentation has more information about :ref:`history`. - cd ~/icepack-dirs/Icepack/ +* Plot some output, see :ref:`testplotting`. The conda icepack environment must be activated, if it isn’t already:: -You need to set up a new out-of-the-box case (icepack_test1):: - - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test1 --mach --env - -Go into the cases/icepack_test1 directory, and build the case. -Change the following namelist settings in **icepack_in**, - - npt = 8760 - -How long is this setting the model to run? Change this to run for 10 years (hint: The timestep is one hour, and there are 24 steps per day, and 365 days per year). - -Details about namelist options are in the documentation (:ref:`case_settings`). - -Submit the job. Check the output and think about the following: - -* Over what dates did the model run this time? -* What date would the model restart from? - - -Modify a physics option ---------------------------- - -Set up another case:: - - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test2 --mach --env - -Build the code. - -Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. Think about what would happen if you changed **icepack_in** in the source code before creating the case instead (hint: this experiment should work the same, but what about future experiments?). + cd $ICE_RUNDIR + conda activate icepack + ${ICE_SANDBOX}/configurations/scripts/tests/timeseries.csh ice_diag.full_ITD -Submit the job. Have a look at the output. +Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. View the png files. -* What is different compared to your first run? -* What happens if sw_redist = .false. with ktherm = 1? Why? +* Questions to think about while looking at the output. + * What time period does an out-of-the-box run cover? + * What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? + * What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? + * How does your output compare to the sample output provided for this release? (hint: see the wiki!) -Change a Parameter in the Fortran Code ------------------------------------------ -Set up another case:: +Add a New Tracer and Run Some Tests +-------------------------------------- - ./icepack.setup --case ~/icepack-dirs/cases/icepack_test3 --mach --env +Follow the documentation at :ref:`addtrcr`. In this exercise, add a new tracer associated with fluffballs. +Call the tracer fluff and make it depend on ice area. -Change to the source code directory:: +Add fluffballs output to the diagnostics and update the timeseries scripts to plot the fluffballs values over time. Plots +the fluffballs after each run. - cd columnphysics +* First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run -Edit icepack_mechred.F90 to change the line +* Add constant some atmospheric forcing and review results - fsnowrdg = p5 , & ! snow fraction that survives in ridging +* Change the dependency to ice volume, how do the results change? -to +* Modify the physics to create some physics processes, see isotopes or aerosols for some ideas - fsnowrdg = c1 , & ! snow fraction that survives in ridging +* Set Up a Longer Run. Modify npt in icepack_in. These are the number of timesteps run. Details about namelist options are in the documentation (:ref:`case_settings`). -Build the code and submit the job. +* Modify a physics option. Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? -* What is different about this run? -* What do you think the fsnowrdg parameter is doing here? +* Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set ``fsnowrdg = c1 , & ! snow fraction that survives in ridging``. Rebuild the code before running. What is different about this run? What do you think the fsnowrdg parameter is doing here? -Revert your code changes:: +* Revert your code changes:: cd ~/Icepack git status diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 4f16ec0f3..64313fa30 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -16,10 +16,9 @@ Tracers added to Icepack will also require extensive modifications to the host sea ice model, including initialization on the horizontal grid, namelist flags and restart capabilities. Modifications to the Icepack driver should reflect the modifications needed in the host model but are not expected to match completely. -We recommend that the logical namelist variable -``tr_[tracer]`` be used for all calls involving the new tracer outside of -**ice\_[tracer].F90**, in case other users do not want to use that -tracer. +We recommend that a logical namelist variable +``tr_[tracer]`` be added and used for all calls involving the new tracer to provide +clean backwards compatibility. A number of optional tracers are available in the code, including ice age, first-year ice area, melt pond area and volume, brine height, @@ -45,54 +44,98 @@ the tracer dependencies (weights), which are tracked using the arrays ``trcr_depend`` (indicates dependency on area, ice volume or snow volume), ``trcr_base`` (a dependency mask), ``n_trcr_strata`` (the number of underlying tracer layers), and ``nt_strata`` (indices of underlying layers). -See subroutine *icepack_compute_tracers* in **icepack\_tracers.F90**. +See subroutine *icepack_compute_tracers* in **icepack_tracers.F90**. To add a tracer, follow these steps using one of the existing tracers as -a pattern (e.g. age). +a pattern (e.g. age or isotopes). Lets call the new tracer xyz. Note that many +of the changes are defined in the Icepack driver or scripts. For CICE or other models +using Icepack, adding a new tracer may be done differently. However, changes to the +Icepack columnphyics should be similar. -#. **icedrv\_domain\_size.F90**: increase ``max_ntrcr`` (can also add option - to **icepack.settings** and **icepack.build**) +#. Define a new tracer. First, setup the tracer cpp in **configuration/scripts/icepack.settings** + and **configuration/scripts/icepack.build** -#. **icepack\_tracers.F90**: + - In **icepack.settings**, add ``setenv NXYZ 1 # number of xyz tracers`` - - declare ``nt_[tracer]`` and ``tr_[tracer]`` + - In **icepack.build**, add ``-DNXYZ=${NXYZ}`` to the setenv ICE_CPPDEFS line - - add flags and indices to the init, query and write subroutines, and - call these routines as needed throughout the code +#. Define the new tracer dimension in **icedrv_domain_size.F90**. -#. **icepack\_[tracer].F90**: create physics routines + - Add a new dimension, ``n_xyz = NXYZ, & ! number of xyz tracers`` -#. **icedrv\_init.F90**: (some of this may be done in **icepack\_[tracer].F90** - instead) + - Update the size of ``max_ntrcr`` by adding ``+ n_xyz & ! number of xyz tracers`` - - declare ``tr_[tracer]`` and ``nt_[tracer]`` as needed +#. Add the new tracer to **icepack_tracers.F90**: - - add logical namelist variable ``tr_[tracer]`` + - Define new variables ``tr_xyz=.false.``, ``n_xyz=0``, and ``nt_xyz=0``. By default, these + should be off (false and 0). - - initialize namelist variable + - Add the new variables to the tracer init, query, and write subroutine arguments + (tracer_flags, tracer_sizes, and tracer_indices). The driver of Icepack will turn + this tracer on as needed. - - print namelist variable to diagnostic output file +#. Add the tracer to the default namelist **configuration/scripts/icepack_in** - - increment number of tracers in use based on namelist input (``ntrcr``) + - Add the namelist flag ``tr_xyz`` to *tracer_nml*. + Best practice is to set the default namelist values so that the + new capability is turned off. You can create an option file with your preferred + configuration in **configuration/scripts/options**. - - define tracer dependencies +#. Update the driver code to initialize the tracer flag and size. You will also + define dependency here (ie. whether the variable is dependent on ice area (aice), ice + volume (vice), snow volume (vsno), or something else). Edit **icedrv_init.F90**. -#. **icedrv\_step\_mod.F90** (and elsewhere as needed): + - Define ``tr_xyz`` and ``nt_xyz`` variables - - call physics routines in **icepack\_[tracer].F90** + - Add a logical namelist variable ``tr_xyz`` -#. **icedrv\_restart.F90**: + - Add a line to initialize ``tr_xyz`` - - define restart variables + - Add some code to print the namelist variable value to the output file + + - Add code to increment the number of tracers in use, ``ntrcr``, based on namelist input + + - Define the tracer dependency. Area tracers can be thought of in terms of averages across + the ice area (the tracer value itself) or averages over the grid cell area (tracer * aice). + Volume tracers can be considered in a similar way, but it can also be helpful to think of + the tracer as the “density” of the variable, which when multiplied by the ice or snow volume + gives the total content of the variable in that volume of the ice or snow. The “total content” + is often a conserved quantity that can be checked during the calculation. + +#. If your tracer depends on ocean or atmosphere forcing (ie. see isotopes) + + - Initialize the sources and sinks in **icedrv_flux.F90** + + - Add a subroutine to generate these sources or sinks in **icedrv_forcing.F90** + or **icedrv_forcing_bgc.F90**. + + - Add the new tracer forcing calls in **icedrv_InitMod.F90** and **icedrv_RunMod.F90** - - call routines to read, write tracer restart data + - Always use the flag ``tr_xyz`` to determine whether to call these routines. -#. **icepack\_in**: add namelist variables to *tracer\_nml* and - *icefields\_nml*. Best practice is to set the namelist values so that the - new capability is turned off, and create an option file with your preferred - configuration in **configuration/scripts/options**. +#. Create a new physics file/module for your tracer, **icepack_xyz.F90**. + This subroutine handles a number of the processes within the + sea ice and snow which affect the distribution of the tracer. These processes could include + congelation growth, snow melt, sea ice melt, evaporation / sublimation, or snow-ice formation. + Note there is a more sophisticated vertical distribution of tracer under the zbgc package. + If your tracer is impacted by frazil ice growth or lateral melt, this is discussed later. + It’s often helpful to copy and modify existing modules such as icepack_age.F90 or icepack_isotope.F90. -#. If strict conservation is necessary, add diagnostics as noted for - topo ponds in Section :ref:`ponds` +#. Add the physics calls to Icepack or the driver. Depending on the physics implementation, the + new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, or + elsewhere. See use of subroutines ``update_aerosol``, ``update_isotope``, or ``increment_age``. + Always use the flag ``tr_xyz`` to determine whether to call these routines. + +#. Add the new tracer to the restart files. Edit **icedrv_restart.F90**, + + - define restart variables + + - call routines to read and write tracer restart data + +#. If strict conservation is necessary, add conservation diagnostics using the + topographical ponds as an example, see :ref:`ponds` #. Update documentation, including **icepack_index.rst** and **ug_case_settings.rst** + +#. Test and validate. Very backwards compatibility. + From eb0f251b1cd37323c522e0b863da53020b65e70a Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 13:17:32 -0600 Subject: [PATCH 02/15] update documentation --- doc/source/appendices/tutorial.rst | 4 +++- doc/source/developer_guide/dg_adding_tracers.rst | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 08bc03e22..c999546f9 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -43,7 +43,9 @@ To summarize the steps in greater details **assuming use of conda in a Mac or Li * Fork the Consortium Icepack repository -* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: +* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main + +.. code-block:: mkdir ~/icepack-dirs cd ~/icepack-dirs diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 64313fa30..6f878b35c 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -137,5 +137,5 @@ Icepack columnphyics should be similar. #. Update documentation, including **icepack_index.rst** and **ug_case_settings.rst** -#. Test and validate. Very backwards compatibility. +#. Test and validate. Verify backwards compatibility. From e4e2d5175756cfefbcdceba37ed8c63acdd30abd Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 13:24:16 -0600 Subject: [PATCH 03/15] update documentation --- doc/source/appendices/tutorial.rst | 82 +++++++++++++++--------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index c999546f9..c575ffd24 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -43,42 +43,40 @@ To summarize the steps in greater details **assuming use of conda in a Mac or Li * Fork the Consortium Icepack repository -* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main - -.. code-block:: - - mkdir ~/icepack-dirs - cd ~/icepack-dirs - git clone https://github.com//Icepack - cd Icepack - git status (Branch should be main) - git remote --v (Check the origin and NO upstream) - git remote add upstream https://github.com/CICE-Consortium/Icepack - git remote --v (Check upstream has been added) - git pull upstream main - git push origin main - git branch - git checkout - git status (Branch should be ) +* Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: + + mkdir ~/icepack-dirs + cd ~/icepack-dirs + git clone https://github.com//Icepack + cd Icepack + git status (Branch should be main) + git remote --v (Check the origin and NO upstream) + git remote add upstream https://github.com/CICE-Consortium/Icepack + git remote --v (Check upstream has been added) + git pull upstream main + git push origin main + git branch + git checkout + git status (Branch should be ) * Setup local env and download input datasets:: - mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline - cd ~/icepack-dirs/input - curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz - tar -xzf Icepack_data-20200326.tar.gz + mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline + cd ~/icepack-dirs/input + curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz + tar -xzf Icepack_data-20200326.tar.gz * Setup the conda environment, see :ref:`laptops`:: - curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/Downloads/miniconda.sh - bash ~/Downloads/miniconda.sh - source $HOME/miniconda3/bin/activate - conda init bash - conda config --set auto_activate_base false - source $HOME/miniconda3/bin/activate - cd ~/icepack-dirs/Icepack - conda env create -f configuration/scripts/machines/environment.yml - conda activate icepack + curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/Downloads/miniconda.sh + bash ~/Downloads/miniconda.sh + source $HOME/miniconda3/bin/activate + conda init bash + conda config --set auto_activate_base false + source $HOME/miniconda3/bin/activate + cd ~/icepack-dirs/Icepack + conda env create -f configuration/scripts/machines/environment.yml + conda activate icepack * **NOTE:** If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. @@ -86,11 +84,11 @@ Again, there are many options for setting up the model on hardware, see the Icep * Set Up an Icepack Simulation. See :ref:`quickstart` and :ref:`running_icepack`:: - cd ~/Icepack - ./icepack.setup --case icepack_test0 --mach conda --env macos -s diag1 - cd ~/icepack-dirs/cases/icepack_test0 - ./icepack.build - ./icepack.submit + cd ~/Icepack + ./icepack.setup --case icepack_test0 --mach conda --env macos -s diag1 + cd ~/icepack-dirs/cases/icepack_test0 + ./icepack.build + ./icepack.submit Several env variables are defined in **icepack.settings** and the Icepack namelist file is **icepack_in**. Output files are copied from the run directory to a logs directory under the case. If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! @@ -98,9 +96,9 @@ Look at the output! Go to the ICE_RUNDIR (defined in **icepack.settings**). A s * Plot some output, see :ref:`testplotting`. The conda icepack environment must be activated, if it isn’t already:: - cd $ICE_RUNDIR - conda activate icepack - ${ICE_SANDBOX}/configurations/scripts/tests/timeseries.csh ice_diag.full_ITD + cd $ICE_RUNDIR + conda activate icepack + ${ICE_SANDBOX}/configurations/scripts/tests/timeseries.csh ice_diag.full_ITD Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. View the png files. @@ -137,8 +135,8 @@ the fluffballs after each run. * Revert your code changes:: - cd ~/Icepack - git status - git checkout columnphysics/icepack_mechred.F90 - git status + cd ~/Icepack + git status + git checkout columnphysics/icepack_mechred.F90 + git status From 6243558b2a80681b68eb823c2828ebeaf5228c31 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 13:49:10 -0600 Subject: [PATCH 04/15] update documentation --- doc/source/appendices/tutorial.rst | 10 +++-- .../developer_guide/dg_adding_tracers.rst | 40 ++++++++++++++----- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index c575ffd24..e7d971bd9 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -121,7 +121,7 @@ the fluffballs after each run. * First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run -* Add constant some atmospheric forcing and review results +* Add some constant atmospheric forcing and review results * Change the dependency to ice volume, how do the results change? @@ -131,9 +131,13 @@ the fluffballs after each run. * Modify a physics option. Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? -* Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set ``fsnowrdg = c1 , & ! snow fraction that survives in ridging``. Rebuild the code before running. What is different about this run? What do you think the fsnowrdg parameter is doing here? +* Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set -* Revert your code changes:: + ``fsnowrdg = c1 , & ! snow fraction that survives in ridging``. + + Rebuild the code before running. What is different about this run? What do you think the fsnowrdg parameter is doing here? + +* Revert your latest code changes:: cd ~/Icepack git status diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 6f878b35c..d550730e3 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -55,20 +55,35 @@ Icepack columnphyics should be similar. #. Define a new tracer. First, setup the tracer cpp in **configuration/scripts/icepack.settings** and **configuration/scripts/icepack.build** - - In **icepack.settings**, add ``setenv NXYZ 1 # number of xyz tracers`` + - In **icepack.settings**, add:: - - In **icepack.build**, add ``-DNXYZ=${NXYZ}`` to the setenv ICE_CPPDEFS line + setenv NXYZ 1 # number of xyz tracers + + - In **icepack.build**, add:: + + \-DNXYZ=${NXYZ} + + to the setenv ICE_CPPDEFS line #. Define the new tracer dimension in **icedrv_domain_size.F90**. - - Add a new dimension, ``n_xyz = NXYZ, & ! number of xyz tracers`` + - Add a new dimension:: + + n_xyz = NXYZ, & ! number of xyz tracers + + - Update the size of ``max_ntrcr`` by adding:: - - Update the size of ``max_ntrcr`` by adding ``+ n_xyz & ! number of xyz tracers`` + + n_xyz & ! number of xyz tracers #. Add the new tracer to **icepack_tracers.F90**: - - Define new variables ``tr_xyz=.false.``, ``n_xyz=0``, and ``nt_xyz=0``. By default, these - should be off (false and 0). + - Define new variables:: + + tr_xyz=.false. + n_xyz=0 + nt_xyz=0 + + By default, these are turned off. - Add the new variables to the tracer init, query, and write subroutine arguments (tracer_flags, tracer_sizes, and tracer_indices). The driver of Icepack will turn @@ -121,10 +136,13 @@ Icepack columnphyics should be similar. If your tracer is impacted by frazil ice growth or lateral melt, this is discussed later. It’s often helpful to copy and modify existing modules such as icepack_age.F90 or icepack_isotope.F90. -#. Add the physics calls to Icepack or the driver. Depending on the physics implementation, the - new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, or - elsewhere. See use of subroutines ``update_aerosol``, ``update_isotope``, or ``increment_age``. - Always use the flag ``tr_xyz`` to determine whether to call these routines. +#. Add the physics calls to Icepack or the driver. + + - Depending on the physics implementation, the + new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, or + elsewhere. See use of subroutines ``update_aerosol``, ``update_isotope``, or ``increment_age``. + + - Always use the flag ``tr_xyz`` to determine whether to call these routines. #. Add the new tracer to the restart files. Edit **icedrv_restart.F90**, @@ -133,7 +151,7 @@ Icepack columnphyics should be similar. - call routines to read and write tracer restart data #. If strict conservation is necessary, add conservation diagnostics using the - topographical ponds as an example, see :ref:`ponds` + topographical ponds as an example, :ref:`ponds` #. Update documentation, including **icepack_index.rst** and **ug_case_settings.rst** From a3d7ec5feffe436ce4c4ab78c01d9c1e19c51460 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 17:01:21 -0600 Subject: [PATCH 05/15] update documentation --- doc/source/appendices/tutorial.rst | 31 ++++++++++--------- .../developer_guide/dg_adding_tracers.rst | 20 +++++++----- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index e7d971bd9..d9dcb8bb5 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -33,15 +33,17 @@ You should fork the Icepack repository and create a new branch in your fork for * Clone your repository onto your machine * Create a branch * Checkout the branch -* Port the model, verify you can run the model, run a test suite +* Port the model and verify you can build and run the model You may be able to leverage the conda port to build and run the model, you may be working on a supported machine, or you may have to port the model to your machine. Porting, setting up cases, building, running, and running test suites are all documented in the Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html. There are many ways to setup and run the model. -* **Note:** The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. Icepack can be set up and run as an independent model following the same workflow. +**Note:** The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. To summarize the steps in greater details **assuming use of conda in a Mac or Linux environment**. -* Fork the Consortium Icepack repository +* Create a github account for yourself if you don't have one already + +* Fork the Consortium Icepack repository, go to https://github.com/CICE-Consortium/Icepack and click on the fork button * Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: @@ -78,7 +80,7 @@ To summarize the steps in greater details **assuming use of conda in a Mac or Li conda env create -f configuration/scripts/machines/environment.yml conda activate icepack -* **NOTE:** If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. +**NOTE:** If you have a Windows machine, we recommend using the Ubuntu Linux application, https://ubuntu.com/desktop/wsl. Again, there are many options for setting up the model on hardware, see the Icepack User Guide for more details. @@ -92,32 +94,31 @@ Again, there are many options for setting up the model on hardware, see the Icep Several env variables are defined in **icepack.settings** and the Icepack namelist file is **icepack_in**. Output files are copied from the run directory to a logs directory under the case. If the run is successful, you will see the message “ICEPACK COMPLETED SUCCESSFULLY” in the icepack run log file. Note that this job runs quickly - you are running a column model with four grid cells! -Look at the output! Go to the ICE_RUNDIR (defined in **icepack.settings**). A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.2016-01-01-00000”. The Icepack documentation has more information about :ref:`history`. +Look at the output. Go to the ICE_RUNDIR (defined in **icepack.settings**). A successful model integration will create ice_diag.* files and a file in the “restart” directory called “iced.yyyy-mm-dd-sssss” where yyyy-mm-dd-sssss is a model date/time stamp. The Icepack documentation has more information about :ref:`history`. -* Plot some output, see :ref:`testplotting`. The conda icepack environment must be activated, if it isn’t already:: +* Plot some output using the timeseries script provided, see :ref:`testplotting`. The conda icepack environment must be activated:: cd $ICE_RUNDIR conda activate icepack ${ICE_SANDBOX}/configurations/scripts/tests/timeseries.csh ice_diag.full_ITD -Note that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. View the png files. +**Note:** that you can run the plotting script on any of the four ice_diag.* files. The .png files are created in the ICE_RUNDIR directory. View the png files. * Questions to think about while looking at the output. * What time period does an out-of-the-box run cover? * What are the differences between the full_ITD plots and the icefree plots (or any other combination of the ice_diag.* output files)? Which fields are the same? Which are different? Why would this be? * What happens to ice area and ice thickness around October 1, 2015? Why do you see this signal? - * How does your output compare to the sample output provided for this release? (hint: see the wiki!) + * How does your output compare to the sample output provided for this release? Add a New Tracer and Run Some Tests -------------------------------------- -Follow the documentation at :ref:`addtrcr`. In this exercise, add a new tracer associated with fluffballs. -Call the tracer fluff and make it depend on ice area. - -Add fluffballs output to the diagnostics and update the timeseries scripts to plot the fluffballs values over time. Plots -the fluffballs after each run. +In this exercise, add a new tracer associated with fluffballs. +Call the tracer fluff and make it depend on ice area. Follow the step-by-step instructions in the :ref:`addtrcr` documentation. +Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics. The update +the timeseries plotting script to plot the fluffballs values over time. * First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run @@ -127,9 +128,9 @@ the fluffballs after each run. * Modify the physics to create some physics processes, see isotopes or aerosols for some ideas -* Set Up a Longer Run. Modify npt in icepack_in. These are the number of timesteps run. Details about namelist options are in the documentation (:ref:`case_settings`). +* Set Up a Longer Run. Modify npt in icepack_in. npt defines the number of timesteps to run. Details about namelist options are in the documentation (:ref:`case_settings`). -* Modify a physics option. Change the thermodynamics option from ktherm = 2 to ktherm = 1 in **icepack_in**, and set sw_redist = .true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? +* Modify a physics option. Change the thermodynamics option from ktherm=2 to ktherm=1 in **icepack_in**, and set sw_redist=.true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? * Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index d550730e3..258c64349 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -8,7 +8,7 @@ Adding tracers We require that any changes made to the code be implemented in such a way that they can be "turned off" through namelist flags. In most cases, code run with such changes should be bit-for-bit identical with the unmodified code. Occasionally, non-bit-for-bit changes -are necessary, e.g. associated with an unavoidable change in the order of operations. In +are necessary or unavoidable due to a change in the order of operations. In these cases, changes should be made in stages to isolate the non-bit-for-bit changes, so that those that should be bit-for-bit can be tested separately. @@ -46,11 +46,15 @@ the tracer dependencies (weights), which are tracked using the arrays underlying tracer layers), and ``nt_strata`` (indices of underlying layers). See subroutine *icepack_compute_tracers* in **icepack_tracers.F90**. -To add a tracer, follow these steps using one of the existing tracers as -a pattern (e.g. age or isotopes). Lets call the new tracer xyz. Note that many +To add a tracer, follow these steps using one of the existing tracers, for example +age or isotopes, as an example. Lets call the new tracer xyz. Note that many of the changes are defined in the Icepack driver or scripts. For CICE or other models using Icepack, adding a new tracer may be done differently. However, changes to the -Icepack columnphyics should be similar. +Icepack columnphyics should be similar. As you make changes, we recommend that you +build and run with the tracer off to ensure the code modifications are working properly. +Changes to setup, namelist, and build files either need to be tested by generating +a new case or by modifying the same files in an existing case before running. +Code changes can be tested by rebuilding and rerunning an existing case. #. Define a new tracer. First, setup the tracer cpp in **configuration/scripts/icepack.settings** and **configuration/scripts/icepack.build** @@ -61,7 +65,7 @@ Icepack columnphyics should be similar. - In **icepack.build**, add:: - \-DNXYZ=${NXYZ} + -DNXYZ=${NXYZ} to the setenv ICE_CPPDEFS line @@ -97,8 +101,8 @@ Icepack columnphyics should be similar. configuration in **configuration/scripts/options**. #. Update the driver code to initialize the tracer flag and size. You will also - define dependency here (ie. whether the variable is dependent on ice area (aice), ice - volume (vice), snow volume (vsno), or something else). Edit **icedrv_init.F90**. + define dependency, whether the variable is dependent on ice area (aice), ice + volume (vice), snow volume (vsno), or something else. Edit **icedrv_init.F90**. - Define ``tr_xyz`` and ``nt_xyz`` variables @@ -117,7 +121,7 @@ Icepack columnphyics should be similar. gives the total content of the variable in that volume of the ice or snow. The “total content” is often a conserved quantity that can be checked during the calculation. -#. If your tracer depends on ocean or atmosphere forcing (ie. see isotopes) +#. If your tracer depends on ocean or atmosphere forcing, use isotopes as an example - Initialize the sources and sinks in **icedrv_flux.F90** From 8bb8e310d1294ea1b4dd92719655437a9fb1f449 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 18:47:48 -0600 Subject: [PATCH 06/15] update documentation --- doc/source/appendices/tutorial.rst | 4 +- .../developer_guide/dg_adding_tracers.rst | 38 ++++++++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index d9dcb8bb5..394b01167 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -117,8 +117,8 @@ Add a New Tracer and Run Some Tests In this exercise, add a new tracer associated with fluffballs. Call the tracer fluff and make it depend on ice area. Follow the step-by-step instructions in the :ref:`addtrcr` documentation. -Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics. The update -the timeseries plotting script to plot the fluffballs values over time. +Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics and turn on the +fluff tracer. Then update the timeseries plotting script to plot the fluffballs values over time. * First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 258c64349..3684d6b2d 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -93,34 +93,42 @@ Code changes can be tested by rebuilding and rerunning an existing case. (tracer_flags, tracer_sizes, and tracer_indices). The driver of Icepack will turn this tracer on as needed. -#. Add the tracer to the default namelist **configuration/scripts/icepack_in** - - - Add the namelist flag ``tr_xyz`` to *tracer_nml*. - Best practice is to set the default namelist values so that the - new capability is turned off. You can create an option file with your preferred - configuration in **configuration/scripts/options**. - -#. Update the driver code to initialize the tracer flag and size. You will also +#. Update the driver code to initialize the tracer flag and size and allocate space + for the tracer. You will also define dependency, whether the variable is dependent on ice area (aice), ice volume (vice), snow volume (vsno), or something else. Edit **icedrv_init.F90**. - - Define ``tr_xyz`` and ``nt_xyz`` variables + - Add ``n_xyz`` to use icedrv_domain_size in subroutine input_data - - Add a logical namelist variable ``tr_xyz`` + - Define ``tr_xyz`` and ``nt_xyz`` variables in subroutine input_data - - Add a line to initialize ``tr_xyz`` + - Add a logical namelist variable ``tr_xyz` to tracer_nml - - Add some code to print the namelist variable value to the output file + - Add a line to initialize ``tr_xyz=.false.`` + + - Add a check that ``tr_xyz`` and ``n_xyz`` are consistent - Add code to increment the number of tracers in use, ``ntrcr``, based on namelist input - - Define the tracer dependency. Area tracers can be thought of in terms of averages across + - Add some code to print xyz tracer info to the output file + + - Add calls to subroutines icepack_init_tracer_sizes, icepack_init_tracer_flags, and + icepack_init_tracer_indices to initialize the xyz tracer information in Icepack. + + - Define the tracer dependency in subroutine init_state. Area tracers can be thought of in terms of averages across the ice area (the tracer value itself) or averages over the grid cell area (tracer * aice). Volume tracers can be considered in a similar way, but it can also be helpful to think of the tracer as the “density” of the variable, which when multiplied by the ice or snow volume gives the total content of the variable in that volume of the ice or snow. The “total content” is often a conserved quantity that can be checked during the calculation. +#. Add the tracer to the default namelist **configuration/scripts/icepack_in** + + - Add the namelist flag ``tr_xyz`` to *tracer_nml*. + Best practice is to set the default namelist values so that the + new capability is turned off. You can create an option file with your preferred + configuration in **configuration/scripts/options**. + #. If your tracer depends on ocean or atmosphere forcing, use isotopes as an example - Initialize the sources and sinks in **icedrv_flux.F90** @@ -143,8 +151,10 @@ Code changes can be tested by rebuilding and rerunning an existing case. #. Add the physics calls to Icepack or the driver. - Depending on the physics implementation, the - new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, or + new tracer physics calls might be done in **icepack_therm_vertical**, **icedrv_step.F90**, and/or elsewhere. See use of subroutines ``update_aerosol``, ``update_isotope``, or ``increment_age``. + + - Pass tracer array into Icepack via public interfaces as needed - Always use the flag ``tr_xyz`` to determine whether to call these routines. From e7dada79d2c8568e5507d4e69b765cd993deb41f Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 19:42:11 -0600 Subject: [PATCH 07/15] update documentation --- doc/source/appendices/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 394b01167..b2e31fefd 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -87,7 +87,7 @@ Again, there are many options for setting up the model on hardware, see the Icep * Set Up an Icepack Simulation. See :ref:`quickstart` and :ref:`running_icepack`:: cd ~/Icepack - ./icepack.setup --case icepack_test0 --mach conda --env macos -s diag1 + ./icepack.setup --case icepack_test0 --mach conda --env macos cd ~/icepack-dirs/cases/icepack_test0 ./icepack.build ./icepack.submit From c6b2097f11e65fe8c08824beac42087c8d3c90b6 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 20:05:39 -0600 Subject: [PATCH 08/15] update documentation --- doc/source/appendices/fluff.diff | 858 +++++++++++++++++++++++++++++ doc/source/appendices/tutorial.rst | 1 + 2 files changed, 859 insertions(+) create mode 100644 doc/source/appendices/fluff.diff diff --git a/doc/source/appendices/fluff.diff b/doc/source/appendices/fluff.diff new file mode 100644 index 000000000..b5a6aee03 --- /dev/null +++ b/doc/source/appendices/fluff.diff @@ -0,0 +1,858 @@ +diff --git a/columnphysics/icepack_fluff.F90 b/columnphysics/icepack_fluff.F90 +new file mode 100644 +index 0000000..f938ea8 +--- /dev/null ++++ b/columnphysics/icepack_fluff.F90 +@@ -0,0 +1,52 @@ ++!======================================================================= ++ ++ module icepack_fluff ++ ++ use icepack_kinds ++ use icepack_parameters, only: puny ++ use icepack_warnings, only: warnstr, icepack_warnings_add ++ use icepack_warnings, only: icepack_warnings_setabort, icepack_warnings_aborted ++ ++ implicit none ++ ++ private ++ public :: update_fluff ++ ++!======================================================================= ++ ++ contains ++ ++!======================================================================= ++ ++! Increase ice fluffball tracer ++ ++ subroutine update_fluff (dt, rfluff, fatm, focn, aicen) ++ ++ real (kind=dbl_kind), intent(in) :: & ++ dt ! time step (s) ++ ++ real (kind=dbl_kind), intent(in) :: & ++ aicen, & ! ice area (m2) ++ fatm, & ! atm forcing (kg/m2/s) ++ focn ! ocn forcing (kg/m2/s) ++ ++ real (kind=dbl_kind), intent(inout) :: & ++ rfluff ! fluff tracer (kg) ++ ++ character(len=*),parameter :: subname='(update_fluff)' ++ ++ if (aicen > puny) then ++ rfluff = rfluff + fatm*aicen*dt ! atm forcing ++ rfluff = rfluff + focn*aicen*dt ! ocn forcing ++ endif ++! rfluff = rfluff + dt/86400._dbl_kind ! by timestep ++! other physics ... ++! rfluff = ... ++ ++ end subroutine update_fluff ++ ++!======================================================================= ++ ++ end module icepack_fluff ++ ++!======================================================================= +diff --git a/columnphysics/icepack_therm_vertical.F90 b/columnphysics/icepack_therm_vertical.F90 +index 7cd9f25..e231e8f 100644 +--- a/columnphysics/icepack_therm_vertical.F90 ++++ b/columnphysics/icepack_therm_vertical.F90 +@@ -31,7 +31,7 @@ module icepack_therm_vertical + use icepack_parameters, only: icepack_chkoptargflag + + use icepack_tracers, only: tr_iage, tr_FY, tr_aero, tr_pond, tr_fsd, tr_iso +- use icepack_tracers, only: tr_pond_lvl, tr_pond_topo ++ use icepack_tracers, only: tr_pond_lvl, tr_pond_topo, tr_fluff + use icepack_tracers, only: n_aero, n_iso + + use icepack_therm_shared, only: ferrmax, l_brine +@@ -51,6 +51,7 @@ module icepack_therm_vertical + use icepack_isotope, only: update_isotope + use icepack_atmo, only: neutral_drag_coeffs, icepack_atm_boundary + use icepack_age, only: increment_age ++ use icepack_fluff, only: update_fluff + use icepack_firstyear, only: update_FYarea + use icepack_flux, only: set_sfcflux, merge_fluxes + use icepack_meltpond_lvl, only: compute_ponds_lvl +@@ -2081,7 +2082,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + zqin , zSin , & + alvl , vlvl , & + apnd , hpnd , & +- ipnd , & ++ ipnd , fluff , & + iage , FY , & + aerosno , aeroice , & + isosno , isoice , & +@@ -2142,6 +2143,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + faero_atm , faero_ocn , & + fiso_atm , fiso_ocn , & + fiso_evap , & ++ ffluff_atm , ffluff_ocn , & + HDO_ocn , H2_16O_ocn , & + H2_18O_ocn , & + dhsn , ffracn , & +@@ -2266,6 +2268,7 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + meltsliq ! mass of snow melt (kg/m^2) + + real (kind=dbl_kind), dimension(:), intent(inout), optional :: & ++ fluff , & ! fluffballs + Qa_iso , & ! isotope specific humidity (kg/kg) + Qref_iso , & ! isotope 2m atm ref spec humidity (kg/kg) + fiso_atm , & ! isotope deposition rate (kg/m^2 s) +@@ -2281,6 +2284,8 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + smliqn ! tracer for mass of liq in snow (kg/m^3) + + real (kind=dbl_kind), intent(in), optional :: & ++ ffluff_atm , & ! fluff atm forcing (kg/m^2 s) ++ ffluff_ocn , & ! fluff ocn forcing (kg/m^2/s) + HDO_ocn , & ! ocean concentration of HDO (kg/kg) + H2_16O_ocn , & ! ocean concentration of H2_16O (kg/kg) + H2_18O_ocn , & ! ocean concentration of H2_18O (kg/kg) +@@ -2451,6 +2456,14 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + return + endif + endif ++ if (tr_fluff) then ++ if (.not.(present(fluff) .and. present(ffluff_atm) .and. & ++ present(ffluff_ocn))) then ++ call icepack_warnings_add(subname//' error in fluff arguments, tr_fluff=T') ++ call icepack_warnings_setabort(.true.,__FILE__,__LINE__) ++ return ++ endif ++ endif + endif + + !----------------------------------------------------------------- +@@ -2615,6 +2628,17 @@ subroutine icepack_step_therm1(dt, ncat, nilyr, nslyr, & + yday, FY(n)) + if (icepack_warnings_aborted(subname)) return + ++ !----------------------------------------------------------------- ++ ! Update ice fluffballs ++ !----------------------------------------------------------------- ++ ++ if (tr_fluff) call update_fluff (dt = dt, & ++ rfluff = fluff(n), & ++ fatm = ffluff_atm, & ++ focn = ffluff_ocn, & ++ aicen = aicen(n)) ++ if (icepack_warnings_aborted(subname)) return ++ + !----------------------------------------------------------------- + ! Vertical thermodynamics: Heat conduction, growth and melting. + !----------------------------------------------------------------- +diff --git a/columnphysics/icepack_tracers.F90 b/columnphysics/icepack_tracers.F90 +index 8414e0c..84e4981 100644 +--- a/columnphysics/icepack_tracers.F90 ++++ b/columnphysics/icepack_tracers.F90 +@@ -58,6 +58,7 @@ module icepack_tracers + nblyr = 0, & ! number of bio/brine layers per category + nfsd = 0, & ! number of fsd layers + n_iso = 0, & ! number of isotopes in use ++ n_fluff = 0, & ! number of fluffballs in use + n_aero = 0, & ! number of aerosols in use + n_zaero = 0, & ! number of z aerosols in use + n_algae = 0, & ! number of algae in use +@@ -87,6 +88,7 @@ module icepack_tracers + nt_rsnw = 0, & ! snow grain radius + nt_isosno = 0, & ! starting index for isotopes in snow + nt_isoice = 0, & ! starting index for isotopes in ice ++ nt_fluff = 0, & ! starting index for fluffballs + nt_aero = 0, & ! starting index for aerosols in ice + nt_bgc_Nit = 0, & ! nutrients + nt_bgc_Am = 0, & ! +@@ -110,6 +112,7 @@ module icepack_tracers + tr_iso = .false., & ! if .true., use isotope tracers + tr_aero = .false., & ! if .true., use aerosol tracers + tr_brine = .false., & ! if .true., brine height differs from ice thickness ++ tr_fluff = .false., & ! if .true., use fluffballs + tr_fsd = .false. ! if .true., use floe size distribution + + !----------------------------------------------------------------- +@@ -207,7 +210,7 @@ module icepack_tracers + + subroutine icepack_init_tracer_flags(& + tr_iage_in, tr_FY_in, tr_lvl_in, tr_snow_in, & +- tr_pond_in, tr_pond_lvl_in, tr_pond_topo_in, & ++ tr_pond_in, tr_pond_lvl_in, tr_pond_topo_in, tr_fluff_in, & + tr_fsd_in, tr_aero_in, tr_iso_in, tr_brine_in, tr_zaero_in, & + tr_bgc_Nit_in, tr_bgc_N_in, tr_bgc_DON_in, tr_bgc_C_in, tr_bgc_chl_in, & + tr_bgc_Am_in, tr_bgc_Sil_in, tr_bgc_DMS_in, tr_bgc_Fe_in, tr_bgc_hum_in, & +@@ -223,6 +226,7 @@ subroutine icepack_init_tracer_flags(& + tr_snow_in , & ! if .true., use snow redistribution or metamorphosis tracers + tr_fsd_in , & ! if .true., use floe size distribution tracers + tr_iso_in , & ! if .true., use isotope tracers ++ tr_fluff_in , & ! if .true., use fluffball tracers + tr_aero_in , & ! if .true., use aerosol tracers + tr_brine_in , & ! if .true., brine height differs from ice thickness + tr_zaero_in , & ! if .true., black carbon is tracers (n_zaero) +@@ -251,6 +255,7 @@ subroutine icepack_init_tracer_flags(& + if (present(tr_snow_in) ) tr_snow = tr_snow_in + if (present(tr_fsd_in) ) tr_fsd = tr_fsd_in + if (present(tr_iso_in) ) tr_iso = tr_iso_in ++ if (present(tr_fluff_in) ) tr_fluff = tr_fluff_in + if (present(tr_aero_in) ) tr_aero = tr_aero_in + if (present(tr_brine_in) ) tr_brine = tr_brine_in + if (present(tr_zaero_in) ) tr_zaero = tr_zaero_in +@@ -274,7 +279,7 @@ end subroutine icepack_init_tracer_flags + + subroutine icepack_query_tracer_flags(& + tr_iage_out, tr_FY_out, tr_lvl_out, tr_snow_out, & +- tr_pond_out, tr_pond_lvl_out, tr_pond_topo_out, & ++ tr_pond_out, tr_pond_lvl_out, tr_pond_topo_out, tr_fluff_out, & + tr_fsd_out, tr_aero_out, tr_iso_out, tr_brine_out, tr_zaero_out, & + tr_bgc_Nit_out, tr_bgc_N_out, tr_bgc_DON_out, tr_bgc_C_out, tr_bgc_chl_out, & + tr_bgc_Am_out, tr_bgc_Sil_out, tr_bgc_DMS_out, tr_bgc_Fe_out, tr_bgc_hum_out, & +@@ -290,6 +295,7 @@ subroutine icepack_query_tracer_flags(& + tr_snow_out , & ! if .true., use snow redistribution or metamorphosis tracers + tr_fsd_out , & ! if .true., use floe size distribution + tr_iso_out , & ! if .true., use isotope tracers ++ tr_fluff_out , & ! if .true., use fluffball tracers + tr_aero_out , & ! if .true., use aerosol tracers + tr_brine_out , & ! if .true., brine height differs from ice thickness + tr_zaero_out , & ! if .true., black carbon is tracers (n_zaero) +@@ -318,6 +324,7 @@ subroutine icepack_query_tracer_flags(& + if (present(tr_snow_out) ) tr_snow_out = tr_snow + if (present(tr_fsd_out) ) tr_fsd_out = tr_fsd + if (present(tr_iso_out) ) tr_iso_out = tr_iso ++ if (present(tr_fluff_out) ) tr_fluff_out = tr_fluff + if (present(tr_aero_out) ) tr_aero_out = tr_aero + if (present(tr_brine_out) ) tr_brine_out = tr_brine + if (present(tr_zaero_out) ) tr_zaero_out = tr_zaero +@@ -357,6 +364,7 @@ subroutine icepack_write_tracer_flags(iounit) + write(iounit,*) " tr_snow = ",tr_snow + write(iounit,*) " tr_fsd = ",tr_fsd + write(iounit,*) " tr_iso = ",tr_iso ++ write(iounit,*) " tr_fluff = ",tr_fluff + write(iounit,*) " tr_aero = ",tr_aero + write(iounit,*) " tr_brine = ",tr_brine + write(iounit,*) " tr_zaero = ",tr_zaero +@@ -383,7 +391,7 @@ subroutine icepack_init_tracer_indices(& + nt_fbri_in, nt_iage_in, nt_FY_in, & + nt_alvl_in, nt_vlvl_in, nt_apnd_in, nt_hpnd_in, nt_ipnd_in, & + nt_smice_in, nt_smliq_in, nt_rhos_in, nt_rsnw_in, & +- nt_fsd_in, nt_isosno_in, nt_isoice_in, & ++ nt_fsd_in, nt_isosno_in, nt_isoice_in, nt_fluff_in, & + nt_aero_in, nt_zaero_in, nt_bgc_C_in, & + nt_bgc_N_in, nt_bgc_chl_in, nt_bgc_DOC_in, nt_bgc_DON_in, & + nt_bgc_DIC_in, nt_bgc_Fed_in, nt_bgc_Fep_in, nt_bgc_Nit_in, nt_bgc_Am_in, & +@@ -416,6 +424,7 @@ subroutine icepack_init_tracer_indices(& + nt_fsd_in, & ! floe size distribution + nt_isosno_in, & ! starting index for isotopes in snow + nt_isoice_in, & ! starting index for isotopes in ice ++ nt_fluff_in, & ! starting index for fluffballs + nt_aero_in, & ! starting index for aerosols in ice + nt_bgc_Nit_in, & ! nutrients + nt_bgc_Am_in, & ! +@@ -497,6 +506,7 @@ subroutine icepack_init_tracer_indices(& + if (present(nt_rsnw_in) ) nt_rsnw = nt_rsnw_in + if (present(nt_isosno_in) ) nt_isosno = nt_isosno_in + if (present(nt_isoice_in) ) nt_isoice = nt_isoice_in ++ if (present(nt_fluff_in) ) nt_fluff = nt_fluff_in + if (present(nt_aero_in) ) nt_aero = nt_aero_in + if (present(nt_bgc_Nit_in) ) nt_bgc_Nit = nt_bgc_Nit_in + if (present(nt_bgc_Am_in) ) nt_bgc_Am = nt_bgc_Am_in +@@ -745,7 +755,7 @@ subroutine icepack_query_tracer_indices(& + nt_fbri_out, nt_iage_out, nt_FY_out, & + nt_alvl_out, nt_vlvl_out, nt_apnd_out, nt_hpnd_out, nt_ipnd_out, & + nt_smice_out, nt_smliq_out, nt_rhos_out, nt_rsnw_out, & +- nt_fsd_out, nt_isosno_out, nt_isoice_out, & ++ nt_fsd_out, nt_isosno_out, nt_isoice_out, nt_fluff_out, & + nt_aero_out, nt_zaero_out, nt_bgc_C_out, & + nt_bgc_N_out, nt_bgc_chl_out, nt_bgc_DOC_out, nt_bgc_DON_out, & + nt_bgc_DIC_out, nt_bgc_Fed_out, nt_bgc_Fep_out, nt_bgc_Nit_out, nt_bgc_Am_out, & +@@ -778,6 +788,7 @@ subroutine icepack_query_tracer_indices(& + nt_fsd_out, & ! floe size distribution + nt_isosno_out, & ! starting index for isotopes in snow + nt_isoice_out, & ! starting index for isotopes in ice ++ nt_fluff_out, & ! starting index for fluffballs + nt_aero_out, & ! starting index for aerosols in ice + nt_bgc_Nit_out, & ! nutrients + nt_bgc_Am_out, & ! +@@ -857,6 +868,7 @@ subroutine icepack_query_tracer_indices(& + if (present(nt_rsnw_out) ) nt_rsnw_out = nt_rsnw + if (present(nt_isosno_out) ) nt_isosno_out = nt_isosno + if (present(nt_isoice_out) ) nt_isoice_out = nt_isoice ++ if (present(nt_fluff_out) ) nt_fluff_out = nt_fluff + if (present(nt_aero_out) ) nt_aero_out = nt_aero + if (present(nt_bgc_Nit_out) ) nt_bgc_Nit_out = nt_bgc_Nit + if (present(nt_bgc_Am_out) ) nt_bgc_Am_out = nt_bgc_Am +@@ -936,6 +948,7 @@ subroutine icepack_write_tracer_indices(iounit) + write(iounit,*) " nt_rsnw = ",nt_rsnw + write(iounit,*) " nt_isosno = ",nt_isosno + write(iounit,*) " nt_isoice = ",nt_isoice ++ write(iounit,*) " nt_fluff = ",nt_fluff + write(iounit,*) " nt_aero = ",nt_aero + write(iounit,*) " nt_bgc_Nit = ",nt_bgc_Nit + write(iounit,*) " nt_bgc_Am = ",nt_bgc_Am +@@ -1014,7 +1027,7 @@ end subroutine icepack_write_tracer_indices + + subroutine icepack_init_tracer_sizes(& + ncat_in, nilyr_in, nslyr_in, nblyr_in, nfsd_in , & +- n_algae_in, n_DOC_in, n_aero_in, n_iso_in, & ++ n_algae_in, n_DOC_in, n_aero_in, n_iso_in, n_fluff_in, & + n_DON_in, n_DIC_in, n_fed_in, n_fep_in, n_zaero_in, & + ntrcr_in, ntrcr_o_in, nbtrcr_in, nbtrcr_sw_in) + +@@ -1032,6 +1045,7 @@ subroutine icepack_init_tracer_sizes(& + n_fep_in , & ! + n_zaero_in, & ! + n_iso_in , & ! ++ n_fluff_in, & ! + n_aero_in , & ! + ntrcr_in , & ! number of tracers in use + ntrcr_o_in, & ! number of non-bio tracers in use +@@ -1056,6 +1070,7 @@ subroutine icepack_init_tracer_sizes(& + if (present(n_fep_in) ) n_fep = n_fep_in + if (present(n_zaero_in) ) n_zaero = n_zaero_in + if (present(n_iso_in) ) n_iso = n_iso_in ++ if (present(n_fluff_in) ) n_fluff = n_fluff_in + if (present(n_aero_in) ) n_aero = n_aero_in + + if (present(ntrcr_in) ) ntrcr = ntrcr_in +@@ -1074,7 +1089,7 @@ subroutine icepack_query_tracer_sizes(& + max_don_out , max_fe_out , nmodal1_out , & + nmodal2_out , max_aero_out , max_nbtrcr_out , & + ncat_out, nilyr_out, nslyr_out, nblyr_out, nfsd_out, & +- n_algae_out, n_DOC_out, n_aero_out, n_iso_out, & ++ n_algae_out, n_DOC_out, n_aero_out, n_iso_out, n_fluff_out, & + n_DON_out, n_DIC_out, n_fed_out, n_fep_out, n_zaero_out, & + ntrcr_out, ntrcr_o_out, nbtrcr_out, nbtrcr_sw_out) + +@@ -1103,6 +1118,7 @@ subroutine icepack_query_tracer_sizes(& + n_fep_out , & ! + n_zaero_out, & ! + n_iso_out , & ! ++ n_fluff_out, & ! + n_aero_out , & ! + ntrcr_out , & ! number of tracers in use + ntrcr_o_out, & ! number of non-bio tracers in use +@@ -1138,6 +1154,7 @@ subroutine icepack_query_tracer_sizes(& + if (present(n_zaero_out) ) n_zaero_out = n_zaero + if (present(n_aero_out) ) n_aero_out = n_aero + if (present(n_iso_out) ) n_iso_out = n_iso ++ if (present(n_fluff_out) ) n_fluff_out = n_fluff + + if (present(ntrcr_out) ) ntrcr_out = ntrcr + if (present(ntrcr_o_out) ) ntrcr_o_out = ntrcr_o +@@ -1186,6 +1203,7 @@ subroutine icepack_write_tracer_sizes(iounit) + write(iounit,*) " n_zaero = ",n_zaero + write(iounit,*) " n_aero = ",n_aero + write(iounit,*) " n_iso = ",n_iso ++ write(iounit,*) " n_fluff = ",n_fluff + write(iounit,*) " ntrcr = ",ntrcr + write(iounit,*) " ntrcr_o = ",ntrcr_o + write(iounit,*) " nbtrcr = ",nbtrcr +diff --git a/configuration/driver/icedrv_InitMod.F90 b/configuration/driver/icedrv_InitMod.F90 +index 107ffdc..8a34f61 100644 +--- a/configuration/driver/icedrv_InitMod.F90 ++++ b/configuration/driver/icedrv_InitMod.F90 +@@ -44,7 +44,8 @@ subroutine icedrv_initialize + use icedrv_flux, only: init_coupler_flux, init_history_therm, & + init_flux_atm_ocn + use icedrv_forcing, only: init_forcing, get_forcing, get_wave_spec +- use icedrv_forcing_bgc, only: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc ++ use icedrv_forcing_bgc, only: get_forcing_bgc, faero_default, fiso_default, & ++ init_forcing_bgc, ffluff_default + use icedrv_restart_shared, only: restart + use icedrv_init, only: input_data, init_state, init_grid2, init_fsd + use icedrv_init_column, only: init_thermo_vertical, init_shortwave, init_zbgc +@@ -56,6 +57,7 @@ subroutine icedrv_initialize + tr_snow, & ! from icepack + tr_aero, & ! from icepack + tr_iso, & ! from icepack ++ tr_fluff, & ! from icepack + tr_zaero, & ! from icepack + tr_fsd, wave_spec + +@@ -135,7 +137,7 @@ subroutine icedrv_initialize + call icepack_query_parameters(wave_spec_out=wave_spec) + call icepack_query_tracer_flags(tr_snow_out=tr_snow) + call icepack_query_tracer_flags(tr_aero_out=tr_aero) +- call icepack_query_tracer_flags(tr_iso_out=tr_iso) ++ call icepack_query_tracer_flags(tr_iso_out=tr_iso, tr_fluff_out=tr_fluff) + call icepack_query_tracer_flags(tr_zaero_out=tr_zaero) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & +@@ -155,6 +157,7 @@ subroutine icedrv_initialize + endif + + if (tr_iso) call fiso_default ! default values ++ if (tr_fluff) call ffluff_default ! fluffball forcing + ! aerosols + ! if (tr_aero) call faero_data ! data file + ! if (tr_zaero) call fzaero_data ! data file (gx1) +diff --git a/configuration/driver/icedrv_RunMod.F90 b/configuration/driver/icedrv_RunMod.F90 +index e20ebf8..81fd86a 100644 +--- a/configuration/driver/icedrv_RunMod.F90 ++++ b/configuration/driver/icedrv_RunMod.F90 +@@ -33,12 +33,13 @@ subroutine icedrv_run + + use icedrv_calendar, only: istep, istep1, time, dt, stop_now, calendar + use icedrv_forcing, only: get_forcing, get_wave_spec +- use icedrv_forcing_bgc, only: faero_default, fiso_default, get_forcing_bgc ++ use icedrv_forcing_bgc, only: faero_default, fiso_default, get_forcing_bgc, & ++ ffluff_default + use icedrv_flux, only: init_flux_atm_ocn + use icedrv_history, only: history_format, history_close + + logical (kind=log_kind) :: skl_bgc, z_tracers, tr_aero, tr_zaero, & +- wave_spec, tr_fsd, tr_iso ++ wave_spec, tr_fsd, tr_iso, tr_fluff + + character(len=*), parameter :: subname='(icedrv_run)' + +@@ -47,7 +48,8 @@ subroutine icedrv_run + !-------------------------------------------------------------------- + + call icepack_query_tracer_flags(tr_aero_out=tr_aero, tr_zaero_out=tr_zaero, & +- tr_fsd_out=tr_fsd, tr_iso_out=tr_iso) ++ tr_fsd_out=tr_fsd, tr_iso_out=tr_iso, & ++ tr_fluff_out=tr_fluff) + call icepack_warnings_flush(nu_diag) + if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & + file=__FILE__,line= __LINE__) +@@ -78,6 +80,7 @@ subroutine icedrv_run + + ! biogeochemistry forcing + if (tr_iso) call fiso_default ! default values ++ if (tr_fluff) call ffluff_default ! fluffball forcing + if (tr_aero .or. tr_zaero) call faero_default ! default values + if (skl_bgc .or. z_tracers) call get_forcing_bgc ! biogeochemistry + +diff --git a/configuration/driver/icedrv_diagnostics.F90 b/configuration/driver/icedrv_diagnostics.F90 +index eaa44d5..cd59cde 100644 +--- a/configuration/driver/icedrv_diagnostics.F90 ++++ b/configuration/driver/icedrv_diagnostics.F90 +@@ -87,7 +87,8 @@ subroutine runtime_diags (dt) + pTair, pfsnow, pfrain, & + paice, hiavg, hsavg, hbravg, psalt, pTsfc, & + pevap, pfhocn, fsdavg, & +- rsnwavg, rhosavg, smicetot, smliqtot, smtot ++ rsnwavg, rhosavg, smicetot, smliqtot, smtot, & ++ fluffavg + + real (kind=dbl_kind), dimension (nx) :: & + work1, work2, work3 +@@ -95,9 +96,9 @@ subroutine runtime_diags (dt) + real (kind=dbl_kind) :: & + Tffresh, rhos, rhow, rhoi + +- logical (kind=log_kind) :: tr_brine, tr_fsd, tr_iso, tr_snow ++ logical (kind=log_kind) :: tr_brine, tr_fsd, tr_iso, tr_snow, tr_fluff + integer (kind=int_kind) :: nt_fbri, nt_Tsfc, nt_fsd, nt_isosno, nt_isoice +- integer (kind=int_kind) :: nt_rsnw, nt_rhos, nt_smice, nt_smliq ++ integer (kind=int_kind) :: nt_rsnw, nt_rhos, nt_smice, nt_smliq, nt_fluff + + character(len=*), parameter :: subname='(runtime_diags)' + +@@ -107,11 +108,11 @@ subroutine runtime_diags (dt) + + call icepack_query_parameters(calc_Tsfc_out=calc_Tsfc, & + snwredist_out=snwredist, snwgrain_out=snwgrain) +- call icepack_query_tracer_flags(tr_brine_out=tr_brine, & ++ call icepack_query_tracer_flags(tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_fsd_out=tr_fsd,tr_iso_out=tr_iso,tr_snow_out=tr_snow) + call icepack_query_tracer_indices(nt_fbri_out=nt_fbri, nt_Tsfc_out=nt_Tsfc,& + nt_fsd_out=nt_fsd, nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice, & +- nt_rsnw_out=nt_rsnw, nt_rhos_out=nt_rhos, & ++ nt_rsnw_out=nt_rsnw, nt_rhos_out=nt_rhos, nt_fluff_out=nt_fluff, & + nt_smice_out=nt_smice, nt_smliq_out=nt_smliq) + call icepack_query_parameters(Tffresh_out=Tffresh, rhos_out=rhos, & + rhow_out=rhow, rhoi_out=rhoi) +@@ -138,6 +139,7 @@ subroutine runtime_diags (dt) + hbravg = c0 ! avg brine thickness + rsnwavg = c0 ! avg snow grain radius + rhosavg = c0 ! avg snow density ++ fluffavg = c0 ! fluffball avg + smicetot = c0 ! total mass of ice in snow (kg/m2) + smliqtot = c0 ! total mass of liquid in snow (kg/m2) + smtot = c0 ! total mass of snow volume (kg/m2) +@@ -172,6 +174,11 @@ subroutine runtime_diags (dt) + smicetot = smicetot / real(nslyr,kind=dbl_kind) ! mass of ice in snow + smliqtot = smliqtot / real(nslyr,kind=dbl_kind) ! mass of liquid in snow + end if ++ if (tr_fluff) then ! fluffballs ++ do nc = 1, ncat ++ fluffavg = fluffavg + trcrn(n,nt_fluff,nc)*aicen(n,nc)/paice ! fluffballs ++ end do ++ end if + + endif + if (vice(n) /= c0) psalt = work2(n)/vice(n) +@@ -252,6 +259,10 @@ subroutine runtime_diags (dt) + endif + endif + ++ if (tr_fluff) then ++ write(nu_diag_out+n-1,900) 'fluffballs (kg) = ',fluffavg ++ endif ++ + write(nu_diag_out+n-1,*) '----------ocn----------' + write(nu_diag_out+n-1,900) 'sst (C) = ',sst(n) ! sea surface temperature + write(nu_diag_out+n-1,900) 'sss (ppt) = ',sss(n) ! sea surface salinity +@@ -267,6 +278,7 @@ subroutine runtime_diags (dt) + write(nu_diag_out+n-1,901) 'isotopic conc chg = ',pdiso(n,k),k + enddo + endif ++ + end do + 899 format (43x,a24) + 900 format (a25,2x,f24.17) +diff --git a/configuration/driver/icedrv_domain_size.F90 b/configuration/driver/icedrv_domain_size.F90 +index 75bb4d2..57b9c08 100644 +--- a/configuration/driver/icedrv_domain_size.F90 ++++ b/configuration/driver/icedrv_domain_size.F90 +@@ -28,6 +28,7 @@ module icedrv_domain_size + n_don = TRDON , & ! number of DON pools in use + n_fed = TRFED , & ! number of Fe pools in use dissolved Fe + n_fep = TRFEP , & ! number of Fe pools in use particulate Fe ++ n_fluff = NFLUFF , & ! number of fluffballs + nfreq = 25 , & ! number of wave frequencies ! HARDWIRED FOR NOW + nblyr = NBGCLYR , & ! number of bio/brine layers per category + ! maximum number of biology tracers + aerosols +@@ -43,6 +44,7 @@ module icedrv_domain_size + + nslyr & ! snow enthalpy + !!!!! optional tracers: + + nfsd & ! number of floe size categories ++ + n_fluff & ! number of fluffball tracers + + TRAGE & ! age + + TRFY & ! first-year area + + TRLVL*2 & ! level/deformed ice +diff --git a/configuration/driver/icedrv_flux.F90 b/configuration/driver/icedrv_flux.F90 +index 39c0908..8e32ec0 100644 +--- a/configuration/driver/icedrv_flux.F90 ++++ b/configuration/driver/icedrv_flux.F90 +@@ -299,6 +299,10 @@ module icedrv_flux + fiso_atm , & ! isotope deposition rate (kg/m^2 s) + fiso_evap ! isotope evaporation rate (kg/m^2 s) + ++ real (kind=dbl_kind), dimension(nx), public :: & ! coupling variable for tr_fluff ++ ffluff_atm, & ! fluffball source from atm (kg/m^2 s) ++ ffluff_ocn ! fluffball source from ocn (kg/m^2 s) ++ + real (kind=dbl_kind), & + dimension (nx,icepack_max_nbtrcr), public :: & + flux_bio_atm ! all bio fluxes to ice from atmosphere +@@ -476,6 +480,8 @@ subroutine init_coupler_flux + + fiso_atm (:,:) = c0 ! isotope deposition rate (kg/m2/s) + fiso_evap (:,:) = c0 ! isotope evaporation rate (kg/m2/s) ++ ffluff_atm (:) = c0 ! fluffball forcing from atm (kg/m2/s) ++ ffluff_ocn (:) = c0 ! fluffball forcing from ocean (kg/m2/s) + faero_atm (:,:) = c0 ! aerosol deposition rate (kg/m2/s) + flux_bio_atm (:,:) = c0 ! zaero and bio deposition rate (kg/m2/s) + +diff --git a/configuration/driver/icedrv_forcing_bgc.F90 b/configuration/driver/icedrv_forcing_bgc.F90 +index f471022..70eacbe 100644 +--- a/configuration/driver/icedrv_forcing_bgc.F90 ++++ b/configuration/driver/icedrv_forcing_bgc.F90 +@@ -10,7 +10,7 @@ module icedrv_forcing_bgc + use icedrv_kinds + use icedrv_domain_size, only: nx + use icedrv_calendar, only: secday +- use icedrv_constants, only: nu_forcing, nu_diag ++ use icedrv_constants, only: nu_forcing, nu_diag, c0 + use icepack_intfc, only: icepack_max_algae, icepack_max_doc + use icepack_intfc, only: icepack_max_dic + use icepack_intfc, only: icepack_query_tracer_flags +@@ -19,7 +19,8 @@ module icedrv_forcing_bgc + + implicit none + private +- public :: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc ++ public :: get_forcing_bgc, faero_default, fiso_default, init_forcing_bgc, & ++ ffluff_default + + real (kind=dbl_kind), dimension(365) :: & ! hardwired for now + sil_data, nit_data +@@ -182,6 +183,21 @@ subroutine fiso_default + + end subroutine fiso_default + ++!======================================================================= ++ ++! constant values for atmospheric and ocean fluffballs ++ ++ subroutine ffluff_default ++ ++ use icedrv_flux, only: ffluff_atm, ffluff_ocn ++ character(len=*), parameter :: subname='(ffluff_default)' ++ ++! ffluff_atm(:) = c0 ! kg/m^2 s ++ ffluff_atm(:) = 1.e-8_dbl_kind ! kg/m^2 s ++ ffluff_ocn(:) = c0 ! kg/m^2 s ++ ++ end subroutine ffluff_default ++ + !======================================================================= + + end module icedrv_forcing_bgc +diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 +index c1e738c..c21cfad 100644 +--- a/configuration/driver/icedrv_init.F90 ++++ b/configuration/driver/icedrv_init.F90 +@@ -58,7 +58,7 @@ subroutine input_data + + use icedrv_diagnostics, only: diag_file, nx_names + use icedrv_domain_size, only: nilyr, nslyr, nblyr, max_ntrcr, ncat +- use icedrv_domain_size, only: n_iso, n_aero, nfsd ++ use icedrv_domain_size, only: n_iso, n_aero, nfsd, n_fluff + use icedrv_calendar, only: year_init, istep0 + use icedrv_calendar, only: dumpfreq, diagfreq, dump_last + use icedrv_calendar, only: npt, dt, ndtd, days_per_year, use_leap_years +@@ -116,12 +116,12 @@ subroutine input_data + + integer (kind=int_kind) :: ntrcr + logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_pond, tr_snow +- logical (kind=log_kind) :: tr_iso, tr_aero, tr_fsd ++ logical (kind=log_kind) :: tr_iso, tr_aero, tr_fsd, tr_fluff + logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, wave_spec + integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_FY + integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, & + nt_smice, nt_smliq, nt_rhos, nt_rsnw, & +- nt_aero, nt_fsd, nt_isosno, nt_isoice ++ nt_aero, nt_fsd, nt_isosno, nt_isoice, nt_fluff + + real (kind=real_kind) :: rplvl, rptopo + real (kind=dbl_kind) :: Cf, puny +@@ -194,6 +194,7 @@ subroutine input_data + tr_snow, & + tr_aero, & + tr_fsd, & ++ tr_fluff, & + tr_iso + + !----------------------------------------------------------------- +@@ -300,6 +301,7 @@ subroutine input_data + tr_aero = .false. ! aerosols + tr_fsd = .false. ! floe size distribution + tr_iso = .false. ! isotopes ++ tr_fluff = .false. ! fluffballs + + !----------------------------------------------------------------- + ! read from input file +@@ -549,6 +551,13 @@ subroutine input_data + call icedrv_system_abort(file=__FILE__,line=__LINE__) + endif + ++ if (tr_fluff .and. n_fluff==0) then ++ write (nu_diag,*) 'WARNING: fluffballs activated but' ++ write (nu_diag,*) 'WARNING: not allocated in tracer array.' ++ write (nu_diag,*) 'WARNING: Activate in compilation script.' ++ call icedrv_system_abort(file=__FILE__,line=__LINE__) ++ endif ++ + if (tr_aero .and. n_aero==0) then + write (nu_diag,*) 'WARNING: aerosols activated but' + write (nu_diag,*) 'WARNING: not allocated in tracer array.' +@@ -892,6 +901,12 @@ subroutine input_data + ntrcr = ntrcr + n_iso ! n_iso species in ice + end if + ++ nt_fluff = max_ntrcr ++ if (tr_fluff) then ! fluffballs ++ nt_fluff = ntrcr + 1 ++ ntrcr = ntrcr + n_fluff ++ end if ++ + nt_aero = max_ntrcr - 4*n_aero + if (tr_aero) then + nt_aero = ntrcr + 1 +@@ -918,6 +933,7 @@ subroutine input_data + write(nu_diag,1020) 'nblyr = ', nblyr + write(nu_diag,1020) 'nfsd = ', nfsd + write(nu_diag,1020) 'n_iso = ', n_iso ++ write(nu_diag,1020) 'n_fluff = ', n_fluff + write(nu_diag,1020) 'n_aero = ', n_aero + write(nu_diag,*)' ' + write(nu_diag,1020) 'nx = ', nx +@@ -991,10 +1007,10 @@ subroutine input_data + windmin_in=windmin, drhosdwind_in=drhosdwind, snwlvlfac_in=snwlvlfac) + call icepack_init_tracer_sizes(ntrcr_in=ntrcr, & + ncat_in=ncat, nilyr_in=nilyr, nslyr_in=nslyr, nblyr_in=nblyr, & +- nfsd_in=nfsd, n_iso_in=n_iso, n_aero_in=n_aero) ++ nfsd_in=nfsd, n_iso_in=n_iso, n_aero_in=n_aero, n_fluff_in=n_fluff) + call icepack_init_tracer_flags(tr_iage_in=tr_iage, & + tr_FY_in=tr_FY, tr_lvl_in=tr_lvl, tr_aero_in=tr_aero, & +- tr_iso_in=tr_iso, tr_snow_in=tr_snow, & ++ tr_iso_in=tr_iso, tr_snow_in=tr_snow, tr_fluff_in=tr_fluff, & + tr_pond_in=tr_pond, & + tr_pond_lvl_in=tr_pond_lvl, & + tr_pond_topo_in=tr_pond_topo, tr_fsd_in=tr_fsd) +@@ -1005,7 +1021,7 @@ subroutine input_data + nt_apnd_in=nt_apnd, nt_hpnd_in=nt_hpnd, nt_ipnd_in=nt_ipnd, & + nt_smice_in=nt_smice, nt_smliq_in=nt_smliq, & + nt_rhos_in=nt_rhos, nt_rsnw_in=nt_rsnw, & +- nt_aero_in=nt_aero, nt_fsd_in=nt_fsd, & ++ nt_aero_in=nt_aero, nt_fsd_in=nt_fsd, nt_fluff_in=nt_fluff, & + nt_isosno_in=nt_isosno, nt_isoice_in=nt_isoice) + + call icepack_warnings_flush(nu_diag) +@@ -1073,7 +1089,7 @@ subroutine init_state + + use icepack_intfc, only: icepack_aggregate + use icedrv_domain_size, only: ncat, nilyr, nslyr, nblyr, max_ntrcr +- use icedrv_domain_size, only: n_iso, n_aero, nfsd ++ use icedrv_domain_size, only: n_iso, n_aero, nfsd, n_fluff + use icedrv_flux, only: sst, Tf, Tair, salinz, Tmltz + use icedrv_state, only: trcr_depend, aicen, trcrn, vicen, vsnon + use icedrv_state, only: aice0, aice, vice, vsno, trcr, aice_init +@@ -1086,10 +1102,10 @@ subroutine init_state + + integer (kind=int_kind) :: ntrcr + logical (kind=log_kind) :: tr_iage, tr_FY, tr_lvl, tr_aero, tr_fsd, tr_iso +- logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_snow ++ logical (kind=log_kind) :: tr_pond_lvl, tr_pond_topo, tr_snow, tr_fluff + integer (kind=int_kind) :: nt_Tsfc, nt_sice, nt_qice, nt_qsno, nt_iage, nt_fy + integer (kind=int_kind) :: nt_alvl, nt_vlvl, nt_apnd, nt_hpnd, nt_ipnd, & +- nt_smice, nt_smliq, nt_rhos, nt_rsnw, & ++ nt_smice, nt_smliq, nt_rhos, nt_rsnw, nt_fluff, & + nt_aero, nt_fsd, nt_isosno, nt_isoice + + character(len=*), parameter :: subname='(init_state)' +@@ -1102,7 +1118,7 @@ subroutine init_state + call icepack_query_tracer_flags(tr_iage_out=tr_iage, & + tr_FY_out=tr_FY, tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, & + tr_iso_out=tr_iso, tr_snow_out=tr_snow, & +- tr_pond_lvl_out=tr_pond_lvl, & ++ tr_pond_lvl_out=tr_pond_lvl, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, tr_fsd_out=tr_fsd) + call icepack_query_tracer_indices(nt_Tsfc_out=nt_Tsfc, & + nt_sice_out=nt_sice, nt_qice_out=nt_qice, & +@@ -1111,7 +1127,7 @@ subroutine init_state + nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, & + nt_ipnd_out=nt_ipnd, & + nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & +- nt_rhos_out=nt_rhos, nt_rsnw_out=nt_rsnw, & ++ nt_rhos_out=nt_rhos, nt_rsnw_out=nt_rsnw, nt_fluff_out=nt_fluff, & + nt_isosno_out=nt_isosno, nt_isoice_out=nt_isoice, & + nt_aero_out=nt_aero, nt_fsd_out=nt_fsd) + call icepack_warnings_flush(nu_diag) +@@ -1178,6 +1194,12 @@ subroutine init_state + trcr_depend(nt_isoice) = 1 ! ice + enddo + endif ++ if (tr_fluff) then ! isotopes ++ do it = 1, n_fluff ++ trcr_depend(nt_fluff + it -1) = 0 ! area ++! trcr_depend(nt_fluff + it -1) = 1 ! ice volume ++ enddo ++ endif + if (tr_aero) then ! volume-weighted aerosols + do it = 1, n_aero + trcr_depend(nt_aero+(it-1)*4 ) = 2 ! snow +diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 +index 0f25b56..1dc844d 100644 +--- a/configuration/driver/icedrv_step.F90 ++++ b/configuration/driver/icedrv_step.F90 +@@ -127,7 +127,7 @@ subroutine step_therm1 (dt) + use icedrv_flux, only: fswthru, fswthru_vdr, fswthru_vdf, fswthru_idr, fswthru_idf + use icedrv_flux, only: flatn_f, fsensn_f, fsurfn_f, fcondtopn_f + use icedrv_flux, only: dsnow, dsnown, faero_atm, faero_ocn +- use icedrv_flux, only: fiso_atm, fiso_ocn, fiso_evap ++ use icedrv_flux, only: fiso_atm, fiso_ocn, fiso_evap, ffluff_atm, ffluff_ocn + use icedrv_flux, only: HDO_ocn, H2_16O_ocn, H2_18O_ocn + use icedrv_init, only: lmask_n, lmask_s + use icedrv_state, only: aice, aicen, aice_init, aicen_init, vicen_init +@@ -151,7 +151,7 @@ subroutine step_therm1 (dt) + + integer (kind=int_kind) :: & + ntrcr, nt_apnd, nt_hpnd, nt_ipnd, nt_alvl, nt_vlvl, nt_Tsfc, & +- nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, & ++ nt_iage, nt_FY, nt_qice, nt_sice, nt_qsno, nt_fluff, & + nt_aero, nt_isosno, nt_isoice, nt_rsnw, nt_smice, nt_smliq + + logical (kind=log_kind) :: & +@@ -198,7 +198,7 @@ subroutine step_therm1 (dt) + call icepack_query_tracer_indices( & + nt_apnd_out=nt_apnd, nt_hpnd_out=nt_hpnd, nt_ipnd_out=nt_ipnd, & + nt_alvl_out=nt_alvl, nt_vlvl_out=nt_vlvl, nt_Tsfc_out=nt_Tsfc, & +- nt_iage_out=nt_iage, nt_FY_out=nt_FY, & ++ nt_iage_out=nt_iage, nt_FY_out=nt_FY, nt_fluff_out=nt_fluff, & + nt_qice_out=nt_qice, nt_sice_out=nt_sice, & + nt_aero_out=nt_aero, nt_qsno_out=nt_qsno, & + nt_rsnw_out=nt_rsnw, nt_smice_out=nt_smice, nt_smliq_out=nt_smliq, & +@@ -289,6 +289,7 @@ subroutine step_therm1 (dt) + hpnd = trcrn(i,nt_hpnd,:), & + ipnd = trcrn(i,nt_ipnd,:), & + iage = trcrn(i,nt_iage,:), & ++ fluff= trcrn(i,nt_fluff,:), & + FY = trcrn(i,nt_FY,:), & + rsnwn = rsnwn (:,:), & + smicen = smicen(:,:), & +@@ -356,6 +357,8 @@ subroutine step_therm1 (dt) + faero_ocn = faero_ocn(i,1:n_aero), & + fiso_atm = fiso_atm (i,:), & + fiso_ocn = fiso_ocn (i,:), & ++ ffluff_atm = ffluff_atm (i), & ++ ffluff_ocn = ffluff_ocn (i), & + fiso_evap = fiso_evap (i,:), & + HDO_ocn = HDO_ocn (i), & + H2_16O_ocn = H2_16O_ocn (i), & +diff --git a/configuration/scripts/icepack.build b/configuration/scripts/icepack.build +index f897de4..10e9d23 100755 +--- a/configuration/scripts/icepack.build ++++ b/configuration/scripts/icepack.build +@@ -63,7 +63,7 @@ endif + if !(-d ${ICE_OBJDIR}) mkdir -p ${ICE_OBJDIR} + cd ${ICE_OBJDIR} + +-setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNXGLOB=${ICE_NXGLOB} -DNICELYR=${NICELYR} -DNSNWLYR=${NSNWLYR} -DNICECAT=${NICECAT} -DNFSDCAT=${NFSDCAT} -DTRAGE=${TRAGE} -DTRFY=${TRFY} -DTRLVL=${TRLVL} -DTRPND=${TRPND} -DTRSNOW=${TRSNOW} -DTRBRI=${TRBRI} -DNTRISO=${NTRISO} -DNTRAERO=${NTRAERO} -DNBGCLYR=${NBGCLYR} -DTRALG=${TRALG} -DTRBGCZ=${TRBGCZ} -DTRDOC=${TRDOC} -DTRDOC=${TRDOC} -DTRDIC=${TRDIC} -DTRDON=${TRDON} -DTRFED=${TRFED} -DTRFEP=${TRFEP} -DTRZAERO=${TRZAERO} -DTRBGCS=${TRBGCS} " ++setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DNXGLOB=${ICE_NXGLOB} -DNICELYR=${NICELYR} -DNSNWLYR=${NSNWLYR} -DNICECAT=${NICECAT} -DNFSDCAT=${NFSDCAT} -DTRAGE=${TRAGE} -DTRFY=${TRFY} -DTRLVL=${TRLVL} -DTRPND=${TRPND} -DTRSNOW=${TRSNOW} -DTRBRI=${TRBRI} -DNTRISO=${NTRISO} -DNTRAERO=${NTRAERO} -DNBGCLYR=${NBGCLYR} -DTRALG=${TRALG} -DTRBGCZ=${TRBGCZ} -DTRDOC=${TRDOC} -DTRDOC=${TRDOC} -DTRDIC=${TRDIC} -DTRDON=${TRDON} -DTRFED=${TRFED} -DTRFEP=${TRFEP} -DTRZAERO=${TRZAERO} -DTRBGCS=${TRBGCS} -DNFLUFF=${NFLUFF}" + + if (${ICE_IOTYPE} == 'netcdf') then + setenv ICE_CPPDEFS "${ICE_CPPDEFS} -DUSE_NETCDF" +diff --git a/configuration/scripts/icepack.settings b/configuration/scripts/icepack.settings +index 5c536f8..e5ec95f 100755 +--- a/configuration/scripts/icepack.settings ++++ b/configuration/scripts/icepack.settings +@@ -74,6 +74,7 @@ setenv TRFEP 0 # number of particulate iron tracers + # (up to max_fe = 2) + setenv TRFED 0 # number of dissolved iron tracers + # (up to max_fe = 2) ++setenv NFLUFF 0 # number of fluffball tracers + + ### Specialty code + setenv ICE_SNICARHC false # include hardcoded (HC) snicar tables +diff --git a/configuration/scripts/icepack_in b/configuration/scripts/icepack_in +index bbf7a59..88f76b0 100644 +--- a/configuration/scripts/icepack_in ++++ b/configuration/scripts/icepack_in +@@ -33,6 +33,7 @@ + tr_aero = .false. + tr_fsd = .false. + tr_iso = .false. ++ tr_fluff = .false. + / + + &thermo_nml +diff --git a/configuration/scripts/options/set_env.fluff b/configuration/scripts/options/set_env.fluff +new file mode 100644 +index 0000000..49ac114 +--- /dev/null ++++ b/configuration/scripts/options/set_env.fluff +@@ -0,0 +1 @@ ++setenv NFLUFF 1 # number of fluff tracers +diff --git a/configuration/scripts/options/set_nml.fluff b/configuration/scripts/options/set_nml.fluff +new file mode 100644 +index 0000000..cb0a4ea +--- /dev/null ++++ b/configuration/scripts/options/set_nml.fluff +@@ -0,0 +1 @@ ++tr_fluff = .true. +diff --git a/configuration/scripts/tests/timeseries.csh b/configuration/scripts/tests/timeseries.csh +index 459c905..7b2d5fe 100755 +--- a/configuration/scripts/tests/timeseries.csh ++++ b/configuration/scripts/tests/timeseries.csh +@@ -29,6 +29,7 @@ set fieldlist=("area fraction " \ + "new ice (m)" \ + "congelation (m)" \ + # "snow-ice (m)" \ ++ "fluffballs (kg)" \ + "intnl enrgy chng(W/m^2)") + + # Get the filename for the latest log diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index b2e31fefd..4d400c8a4 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -145,3 +145,4 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs git checkout columnphysics/icepack_mechred.F90 git status +**NOTE:** The file, :doc:fluff.diff, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. From 216e0ac2ab211ff5bfcaa0c284afa13239690a23 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 20:10:53 -0600 Subject: [PATCH 09/15] update documentation --- doc/source/appendices/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 4d400c8a4..38d5002c7 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -145,4 +145,4 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs git checkout columnphysics/icepack_mechred.F90 git status -**NOTE:** The file, :doc:fluff.diff, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. +**NOTE:** The file, :doc:`fluff.diff`, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. From 4223e7b574bf3b8ceb52382c21a9c74096faa115 Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 20:18:44 -0600 Subject: [PATCH 10/15] update documentation --- doc/source/appendices/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 38d5002c7..3a51f3e59 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -145,4 +145,4 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs git checkout columnphysics/icepack_mechred.F90 git status -**NOTE:** The file, :doc:`fluff.diff`, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. +**NOTE:** The file, :download:`fluff.diff`, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. From 9dde101bcc4285ed7a3ed6a8b37b433307c3db4f Mon Sep 17 00:00:00 2001 From: apcraig Date: Tue, 23 Jul 2024 20:21:53 -0600 Subject: [PATCH 11/15] update documentation --- doc/source/appendices/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 3a51f3e59..639552257 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -145,4 +145,4 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs git checkout columnphysics/icepack_mechred.F90 git status -**NOTE:** The file, :download:`fluff.diff`, contains code differences for this example using a version of Icepack from July, 2024. They may not be relevant for the latest code, but provides a sample of the typical code differences required to add the tracer, fluff. +**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, contains code differences for this example for a version of Icepack from July, 2024. They may not be relevant for other code versions, but these diffs provide an example of the typical code differences required to add the tracer, fluff. From 5a2d1f21cf4e43dafaf81a5de1099729b7a72c5e Mon Sep 17 00:00:00 2001 From: apcraig Date: Wed, 24 Jul 2024 12:36:58 -0600 Subject: [PATCH 12/15] update documentation after review --- doc/source/appendices/tutorial.rst | 49 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 639552257..cdfc717f3 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -35,15 +35,15 @@ You should fork the Icepack repository and create a new branch in your fork for * Checkout the branch * Port the model and verify you can build and run the model -You may be able to leverage the conda port to build and run the model, you may be working on a supported machine, or you may have to port the model to your machine. Porting, setting up cases, building, running, and running test suites are all documented in the Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html. There are many ways to setup and run the model. +Many of these steps are done once per user or machine. You may be able to leverage the conda port to build and run the model, you may be working on a supported machine, or you may have to port the model to your machine. Porting, setting up cases, building, running, and running test suites are all documented in the Icepack User Guide, https://cice-consortium-icepack.readthedocs.io/en/latest/index.html. There are many ways to setup and run the model. **Note:** The workflow guide is oriented toward setting up CICE rather than Icepack, but the same workflow applies to Icepack standalone. -To summarize the steps in greater details **assuming use of conda in a Mac or Linux environment**. +To summarize the steps in greater detail **assuming use of conda in a Mac or Linux environment**. -* Create a github account for yourself if you don't have one already +* Create a github account for yourself if you don't have one already (done once per user) -* Fork the Consortium Icepack repository, go to https://github.com/CICE-Consortium/Icepack and click on the fork button +* Fork the Consortium Icepack repository, go to https://github.com/CICE-Consortium/Icepack and click on the fork button (done once per user) * Clone Icepack, sync the main branch, and create a new branch from the main branch. This will create a branch based on the lastest version of main:: @@ -61,14 +61,14 @@ To summarize the steps in greater details **assuming use of conda in a Mac or Li git checkout git status (Branch should be ) -* Setup local env and download input datasets:: +* Setup local env and download input datasets (done once per machine):: mkdir -p ~/icepack-dirs/runs ~/icepack-dirs/input ~/icepack-dirs/baseline cd ~/icepack-dirs/input curl -O https://zenodo.org/records/3728287/files/Icepack_data-20200326.tar.gz tar -xzf Icepack_data-20200326.tar.gz -* Setup the conda environment, see :ref:`laptops`:: +* Setup the conda environment (done once per machine), see :ref:`laptops`:: curl -L https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o ~/Downloads/miniconda.sh bash ~/Downloads/miniconda.sh @@ -112,26 +112,15 @@ Look at the output. Go to the ICE_RUNDIR (defined in **icepack.settings**). A s * How does your output compare to the sample output provided for this release? -Add a New Tracer and Run Some Tests --------------------------------------- - -In this exercise, add a new tracer associated with fluffballs. -Call the tracer fluff and make it depend on ice area. Follow the step-by-step instructions in the :ref:`addtrcr` documentation. -Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics and turn on the -fluff tracer. Then update the timeseries plotting script to plot the fluffballs values over time. - -* First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run - -* Add some constant atmospheric forcing and review results - -* Change the dependency to ice volume, how do the results change? - -* Modify the physics to create some physics processes, see isotopes or aerosols for some ideas +Modify the Configuration or Code +------------------------------------ * Set Up a Longer Run. Modify npt in icepack_in. npt defines the number of timesteps to run. Details about namelist options are in the documentation (:ref:`case_settings`). * Modify a physics option. Change the thermodynamics option from ktherm=2 to ktherm=1 in **icepack_in**, and set sw_redist=.true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? +* Undo your latest **icepack_in** changes + * Change a Parameter in the Fortran Code. Edit **icepack_mechred.F90** and set ``fsnowrdg = c1 , & ! snow fraction that survives in ridging``. @@ -145,4 +134,20 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs git checkout columnphysics/icepack_mechred.F90 git status -**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, contains code differences for this example for a version of Icepack from July, 2024. They may not be relevant for other code versions, but these diffs provide an example of the typical code differences required to add the tracer, fluff. +Add a New Tracer +-------------------------------------- + +In this exercise, add a new tracer associated with fluffballs. +Call the tracer fluff and make it depend on ice area. Follow the step-by-step instructions in the :ref:`addtrcr` documentation. +Once you have implemented the model changes, be sure to add fluffballs output to the standard output diagnostics and turn on the +fluff tracer. Then update the timeseries plotting script to plot the fluffballs values over time. + +* First, set the initial value, physics, sources, and sinks of fluff to zero and make sure fluff values remain zero throughout the run + +* Add some constant atmospheric forcing and review results + +* Change the dependency to ice volume, how do the results change? + +* Modify the physics to create some physics processes, see isotopes or aerosols for some ideas + +**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, demonstrates code differences for this fluffball activity as implemented in a version of Icepack from July, 2024. These code difference may not be directly applicable to other code versions, but these diffs provide an example of the typical code differences required to add the tracer, fluff. From ccf08f86211212cdbe1e901c3339d9be839dacdc Mon Sep 17 00:00:00 2001 From: apcraig Date: Wed, 24 Jul 2024 15:57:22 -0600 Subject: [PATCH 13/15] update documentation --- doc/source/appendices/tutorial.rst | 4 +++- doc/source/developer_guide/dg_adding_tracers.rst | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index cdfc717f3..2829717b0 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -115,7 +115,7 @@ Look at the output. Go to the ICE_RUNDIR (defined in **icepack.settings**). A s Modify the Configuration or Code ------------------------------------ -* Set Up a Longer Run. Modify npt in icepack_in. npt defines the number of timesteps to run. Details about namelist options are in the documentation (:ref:`case_settings`). +* Set up a longer Run. Modify ``npt`` in icepack_in. ``npt`` defines the number of timesteps to run. Details about namelist options are in the documentation (:ref:`case_settings`). * Modify a physics option. Change the thermodynamics option from ktherm=2 to ktherm=1 in **icepack_in**, and set sw_redist=.true. The intent here is to change the namelist option for the current experiment in the case directory. What is different compared to your first run? What happens if sw_redist = .false. with ktherm = 1? Why? @@ -134,6 +134,8 @@ Modify the Configuration or Code git checkout columnphysics/icepack_mechred.F90 git status +.. _tutorialfluff: + Add a New Tracer -------------------------------------- diff --git a/doc/source/developer_guide/dg_adding_tracers.rst b/doc/source/developer_guide/dg_adding_tracers.rst index 3684d6b2d..3a1646af1 100755 --- a/doc/source/developer_guide/dg_adding_tracers.rst +++ b/doc/source/developer_guide/dg_adding_tracers.rst @@ -56,6 +56,10 @@ Changes to setup, namelist, and build files either need to be tested by generati a new case or by modifying the same files in an existing case before running. Code changes can be tested by rebuilding and rerunning an existing case. +The appendix has a tutorial activity, :ref:`tutorialfluff`, where a tracer is added to +Icepack. A set of code differences are provided there as an example of how this could +be done in practice. + #. Define a new tracer. First, setup the tracer cpp in **configuration/scripts/icepack.settings** and **configuration/scripts/icepack.build** @@ -129,7 +133,7 @@ Code changes can be tested by rebuilding and rerunning an existing case. new capability is turned off. You can create an option file with your preferred configuration in **configuration/scripts/options**. -#. If your tracer depends on ocean or atmosphere forcing, use isotopes as an example +#. If your tracer depends on ocean or atmosphere forcing - Initialize the sources and sinks in **icedrv_flux.F90** From fea3112597fb655687da5c2f9970f283c76c6fe3 Mon Sep 17 00:00:00 2001 From: apcraig Date: Wed, 24 Jul 2024 16:00:18 -0600 Subject: [PATCH 14/15] update fluff.diff --- doc/source/appendices/fluff.diff | 123 ++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 3 deletions(-) diff --git a/doc/source/appendices/fluff.diff b/doc/source/appendices/fluff.diff index b5a6aee03..03f745b74 100644 --- a/doc/source/appendices/fluff.diff +++ b/doc/source/appendices/fluff.diff @@ -592,7 +592,7 @@ index f471022..70eacbe 100644 end module icedrv_forcing_bgc diff --git a/configuration/driver/icedrv_init.F90 b/configuration/driver/icedrv_init.F90 -index c1e738c..c21cfad 100644 +index c1e738c..ed69c07 100644 --- a/configuration/driver/icedrv_init.F90 +++ b/configuration/driver/icedrv_init.F90 @@ -58,7 +58,7 @@ subroutine input_data @@ -738,13 +738,130 @@ index c1e738c..c21cfad 100644 endif + if (tr_fluff) then ! isotopes + do it = 1, n_fluff -+ trcr_depend(nt_fluff + it -1) = 0 ! area -+! trcr_depend(nt_fluff + it -1) = 1 ! ice volume ++! trcr_depend(nt_fluff + it -1) = 0 ! area ++ trcr_depend(nt_fluff + it -1) = 1 ! ice volume + enddo + endif if (tr_aero) then ! volume-weighted aerosols do it = 1, n_aero trcr_depend(nt_aero+(it-1)*4 ) = 2 ! snow +diff --git a/configuration/driver/icedrv_restart.F90 b/configuration/driver/icedrv_restart.F90 +index 762d1b3..5a687e8 100644 +--- a/configuration/driver/icedrv_restart.F90 ++++ b/configuration/driver/icedrv_restart.F90 +@@ -29,6 +29,7 @@ module icedrv_restart + write_restart_snow, read_restart_snow, & + write_restart_fsd, read_restart_fsd, & + write_restart_iso, read_restart_iso, & ++ write_restart_fluff, read_restart_fluff, & + write_restart_aero, read_restart_aero + + character (len=3), private :: nchar ! +@@ -89,7 +90,7 @@ subroutine dumpfile + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, tr_brine, & +- tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd ++ tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd, tr_fluff + ! skl_bgc, z_tracers + + integer (kind=int_kind) :: dims(2) +@@ -115,7 +116,7 @@ subroutine dumpfile + + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_iso_out=tr_iso, & +- tr_brine_out=tr_brine, & ++ tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, & + tr_pond_lvl_out=tr_pond_lvl,tr_snow_out=tr_snow,tr_fsd_out=tr_fsd) + ! call icepack_query_parameters(skl_bgc_out=skl_bgc, z_tracers_out=z_tracers) +@@ -224,6 +225,7 @@ subroutine dumpfile + if (tr_aero) call write_restart_aero(dims) ! ice aerosols + if (tr_brine) call write_restart_hbrine(dims) ! brine height + if (tr_fsd) call write_restart_fsd(dims) ! floe size distribution ++ if (tr_fluff) call write_restart_fluff(dims) ! fluffballs + ! called in icedrv_RunMod.F90 to prevent circular dependencies + ! if (skl_bgc .or. z_tracers) & + ! call write_restart_bgc ! biogeochemistry +@@ -275,7 +277,7 @@ subroutine restartfile (ice_ic) + + logical (kind=log_kind) :: & + tr_iage, tr_FY, tr_lvl, tr_iso, tr_aero, tr_brine, & +- tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd ++ tr_pond_topo, tr_pond_lvl, tr_snow, tr_fsd, tr_fluff + + character(len=char_len_long) :: filename + character(len=*), parameter :: subname='(restartfile)' +@@ -290,7 +292,7 @@ subroutine restartfile (ice_ic) + + call icepack_query_tracer_flags(tr_iage_out=tr_iage, tr_FY_out=tr_FY, & + tr_lvl_out=tr_lvl, tr_aero_out=tr_aero, tr_iso_out=tr_iso, & +- tr_brine_out=tr_brine, & ++ tr_brine_out=tr_brine, tr_fluff_out=tr_fluff, & + tr_pond_topo_out=tr_pond_topo, & + tr_pond_lvl_out=tr_pond_lvl,tr_snow_out=tr_snow,tr_fsd_out=tr_fsd) + call icepack_warnings_flush(nu_diag) +@@ -399,6 +401,7 @@ subroutine restartfile (ice_ic) + if (tr_aero) call read_restart_aero() ! ice aerosols + if (tr_brine) call read_restart_hbrine ! brine height + if (tr_fsd) call read_restart_fsd() ! floe size distribution ++ if (tr_fluff) call read_restart_fluff() ! fluffballs + + !----------------------------------------------------------------- + ! Ensure ice is binned in correct categories +@@ -768,6 +771,52 @@ end subroutine read_restart_age + + !======================================================================= + ++! Dumps all values needed for restarting ++ ++ subroutine write_restart_fluff(dims) ++ ++ use icedrv_state, only: trcrn ++ use icedrv_domain_size, only: ncat ++ ++ integer (kind=int_kind), intent(in), optional :: & ++ dims(:) ! netcdf dimension IDs ++ ++ integer (kind=int_kind) :: nt_fluff ++ character(len=*), parameter :: subname='(write_restart_fluff)' ++ ++ call icepack_query_tracer_indices(nt_fluff_out=nt_fluff) ++ call icepack_warnings_flush(nu_diag) ++ if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & ++ file=__FILE__,line= __LINE__) ++ ++ call write_restart_field(nu_dump,trcrn(:,nt_fluff,:),ncat,'fluff',dims) ++ ++ end subroutine write_restart_fluff ++ ++!======================================================================= ++ ++! Reads all values needed for an ice fluff restart ++ ++ subroutine read_restart_fluff() ++ ++ use icedrv_state, only: trcrn ++ use icedrv_domain_size, only: ncat ++ integer (kind=int_kind) :: nt_fluff ++ character(len=*), parameter :: subname='(read_restart_fluff)' ++ ++ write(nu_diag,*) 'min/max fluff (s)' ++ ++ call icepack_query_tracer_indices(nt_fluff_out=nt_fluff) ++ call icepack_warnings_flush(nu_diag) ++ if (icepack_warnings_aborted()) call icedrv_system_abort(string=subname, & ++ file=__FILE__,line= __LINE__) ++ ++ call read_restart_field(nu_restart,trcrn(:,nt_fluff,:),ncat,'fluff') ++ ++ end subroutine read_restart_fluff ++ ++!======================================================================= ++ + ! Dumps all values needed for restarting + ! author Elizabeth C. Hunke, LANL + diff --git a/configuration/driver/icedrv_step.F90 b/configuration/driver/icedrv_step.F90 index 0f25b56..1dc844d 100644 --- a/configuration/driver/icedrv_step.F90 From e8fb0d2876aea6606c7f1c90fbdefcbd8b405066 Mon Sep 17 00:00:00 2001 From: apcraig Date: Thu, 25 Jul 2024 10:20:37 -0600 Subject: [PATCH 15/15] update documentation --- doc/source/appendices/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/appendices/tutorial.rst b/doc/source/appendices/tutorial.rst index 2829717b0..a938eba53 100644 --- a/doc/source/appendices/tutorial.rst +++ b/doc/source/appendices/tutorial.rst @@ -152,4 +152,4 @@ fluff tracer. Then update the timeseries plotting script to plot the fluffballs * Modify the physics to create some physics processes, see isotopes or aerosols for some ideas -**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, demonstrates code differences for this fluffball activity as implemented in a version of Icepack from July, 2024. These code difference may not be directly applicable to other code versions, but these diffs provide an example of the typical code differences required to add the tracer, fluff. +**NOTE:** The file, **doc/source/tutorial/fluff.diff** in the Icepack repository, demonstrates code differences for this fluffball activity as implemented in a version of Icepack from July, 2024. These code differences may not be directly applicable to other code versions, but they provide an example of the typical code modifications required to add the tracer, fluff.