-invalid file format
-"""
- with open(file_path, 'w') as fhandle:
- fhandle.write(contents)
- with self.assertRaises(RuntimeError):
- read_externals_description_file(root_dir, filename)
- os.remove(file_path)
-
-
-class TestCreateExternalsDescription(unittest.TestCase):
- """Test the application logic of creat_externals_description
- """
-
- def setUp(self):
- """Create config object used as basis for all tests
- """
- self._config = config_parser()
- self._gmconfig = config_parser()
- self.setup_config()
-
- def setup_config(self):
- """Boiler plate construction of xml string for componet 1
- """
- # Create a standard externals config with a single external
- name = 'test'
- self._config.add_section(name)
- self._config.set(name, ExternalsDescription.PATH, 'externals')
- self._config.set(name, ExternalsDescription.PROTOCOL, 'git')
- self._config.set(name, ExternalsDescription.REPO_URL, '/path/to/repo')
- self._config.set(name, ExternalsDescription.TAG, 'test_tag')
- self._config.set(name, ExternalsDescription.REQUIRED, 'True')
-
- self._config.add_section(DESCRIPTION_SECTION)
- self._config.set(DESCRIPTION_SECTION, VERSION_ITEM, '1.0.0')
-
- # Create a .gitmodules test
- name = 'submodule "gitmodules_test"'
- self._gmconfig.add_section(name)
- self._gmconfig.set(name, "path", 'externals/test')
- self._gmconfig.set(name, "url", '/path/to/repo')
- # NOTE(goldy, 2019-03) Should test other possible keywords such as
- # fetchRecurseSubmodules, ignore, and shallow
-
- @staticmethod
- def setup_dict_config():
- """Create the full container dictionary with simple and mixed use
- externals
-
- """
- rdatat = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL: 'simple-ext.git',
- ExternalsDescription.TAG: 'tag1'}
- rdatab = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL: 'simple-ext.git',
- ExternalsDescription.BRANCH: 'feature2'}
- rdatam = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL: 'mixed-cont-ext.git',
- ExternalsDescription.BRANCH: 'master'}
- desc = {'simp_tag': {ExternalsDescription.REQUIRED: True,
- ExternalsDescription.PATH: 'simp_tag',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdatat},
- 'simp_branch' : {ExternalsDescription.REQUIRED: True,
- ExternalsDescription.PATH: 'simp_branch',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdatab},
- 'simp_opt': {ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'simp_opt',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdatat},
- 'mixed_req': {ExternalsDescription.REQUIRED: True,
- ExternalsDescription.PATH: 'mixed_req',
- ExternalsDescription.EXTERNALS: 'sub-ext.cfg',
- ExternalsDescription.REPO: rdatam}}
-
- return desc
-
- def test_cfg_v1_ok(self):
- """Test that a correct cfg v1 object is created by create_externals_description
-
- """
- self._config.set(DESCRIPTION_SECTION, VERSION_ITEM, '1.0.3')
- ext = create_externals_description(self._config, model_format='cfg')
- self.assertIsInstance(ext, ExternalsDescriptionConfigV1)
-
- def test_cfg_v1_unknown_version(self):
- """Test that a config file with unknown schema version is rejected by
- create_externals_description.
-
- """
- self._config.set(DESCRIPTION_SECTION, VERSION_ITEM, '100.0.3')
- with self.assertRaises(RuntimeError):
- create_externals_description(self._config, model_format='cfg')
-
- def test_dict(self):
- """Test that a correct cfg v1 object is created by create_externals_description
-
- """
- rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL: '/path/to/repo',
- ExternalsDescription.TAG: 'tagv1',
- }
-
- desc = {
- 'test': {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: '../fake',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata, },
- }
-
- ext = create_externals_description(desc, model_format='dict')
- self.assertIsInstance(ext, ExternalsDescriptionDict)
-
- def test_cfg_component_dict(self):
- """Verify that create_externals_description works with a dictionary
- """
- # create the top level externals file
- desc = self.setup_dict_config()
- # Check external with all repos
- external = create_externals_description(desc, model_format='dict')
- self.assertIsInstance(external, ExternalsDescriptionDict)
- self.assertTrue('simp_tag' in external)
- self.assertTrue('simp_branch' in external)
- self.assertTrue('simp_opt' in external)
- self.assertTrue('mixed_req' in external)
-
- def test_cfg_exclude_component_dict(self):
- """Verify that exclude component checkout works with a dictionary
- """
- # create the top level externals file
- desc = self.setup_dict_config()
- # Test an excluded repo
- external = create_externals_description(desc, model_format='dict',
- exclude=['simp_tag',
- 'simp_opt'])
- self.assertIsInstance(external, ExternalsDescriptionDict)
- self.assertFalse('simp_tag' in external)
- self.assertTrue('simp_branch' in external)
- self.assertFalse('simp_opt' in external)
- self.assertTrue('mixed_req' in external)
-
- def test_cfg_opt_component_dict(self):
- """Verify that exclude component checkout works with a dictionary
- """
- # create the top level externals file
- desc = self.setup_dict_config()
- # Test an excluded repo
- external = create_externals_description(desc, model_format='dict',
- components=['simp_tag',
- 'simp_opt'])
- self.assertIsInstance(external, ExternalsDescriptionDict)
- self.assertTrue('simp_tag' in external)
- self.assertFalse('simp_branch' in external)
- self.assertTrue('simp_opt' in external)
- self.assertFalse('mixed_req' in external)
-
- def test_cfg_unknown_version(self):
- """Test that a runtime error is raised when an unknown file version is
- received
-
- """
- self._config.set(DESCRIPTION_SECTION, VERSION_ITEM, '123.456.789')
- with self.assertRaises(RuntimeError):
- create_externals_description(self._config, model_format='cfg')
-
- def test_cfg_unknown_format(self):
- """Test that a runtime error is raised when an unknown format string is
- received
-
- """
- with self.assertRaises(RuntimeError):
- create_externals_description(self._config, model_format='unknown')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/manage_externals/test/test_unit_externals_status.py b/manage_externals/test/test_unit_externals_status.py
deleted file mode 100644
index f019514e9e..0000000000
--- a/manage_externals/test/test_unit_externals_status.py
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/env python3
-
-"""Unit test driver for the manic external status reporting module.
-
-Note: this script assumes the path to the manic package is already in
-the python path.
-
-"""
-
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import unittest
-
-from manic.externals_status import ExternalStatus
-
-
-class TestStatusObject(unittest.TestCase):
- """Verify that the Status object behaives as expected.
- """
-
- def test_exists_empty_all(self):
- """If the repository sync-state is empty (doesn't exist), and there is no
- clean state, then it is considered not to exist.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.EMPTY
- stat.clean_state = ExternalStatus.DEFAULT
- exists = stat.exists()
- self.assertFalse(exists)
-
- stat.clean_state = ExternalStatus.EMPTY
- exists = stat.exists()
- self.assertFalse(exists)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- exists = stat.exists()
- self.assertFalse(exists)
-
- # this state represtens an internal logic error in how the
- # repo status was determined.
- stat.clean_state = ExternalStatus.STATUS_OK
- exists = stat.exists()
- self.assertTrue(exists)
-
- # this state represtens an internal logic error in how the
- # repo status was determined.
- stat.clean_state = ExternalStatus.DIRTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- def test_exists_default_all(self):
- """If the repository sync-state is default, then it is considered to exist
- regardless of clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.DEFAULT
- stat.clean_state = ExternalStatus.DEFAULT
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.EMPTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.DIRTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- def test_exists_unknown_all(self):
- """If the repository sync-state is unknown, then it is considered to exist
- regardless of clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.UNKNOWN
- stat.clean_state = ExternalStatus.DEFAULT
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.EMPTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.DIRTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- def test_exists_modified_all(self):
- """If the repository sync-state is modified, then it is considered to exist
- regardless of clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.MODEL_MODIFIED
- stat.clean_state = ExternalStatus.DEFAULT
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.EMPTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.DIRTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- def test_exists_ok_all(self):
- """If the repository sync-state is ok, then it is considered to exist
- regardless of clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.STATUS_OK
- stat.clean_state = ExternalStatus.DEFAULT
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.EMPTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- exists = stat.exists()
- self.assertTrue(exists)
-
- stat.clean_state = ExternalStatus.DIRTY
- exists = stat.exists()
- self.assertTrue(exists)
-
- def test_update_ok_all(self):
- """If the repository in-sync is ok, then it is safe to
- update only if clean state is ok
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.STATUS_OK
- stat.clean_state = ExternalStatus.DEFAULT
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.EMPTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- safe_to_update = stat.safe_to_update()
- self.assertTrue(safe_to_update)
-
- stat.clean_state = ExternalStatus.DIRTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- def test_update_modified_all(self):
- """If the repository in-sync is modified, then it is safe to
- update only if clean state is ok
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.MODEL_MODIFIED
- stat.clean_state = ExternalStatus.DEFAULT
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.EMPTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- safe_to_update = stat.safe_to_update()
- self.assertTrue(safe_to_update)
-
- stat.clean_state = ExternalStatus.DIRTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- def test_update_unknown_all(self):
- """If the repository in-sync is unknown, then it is not safe to
- update, regardless of the clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.UNKNOWN
- stat.clean_state = ExternalStatus.DEFAULT
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.EMPTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.DIRTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- def test_update_default_all(self):
- """If the repository in-sync is default, then it is not safe to
- update, regardless of the clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.UNKNOWN
- stat.clean_state = ExternalStatus.DEFAULT
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.EMPTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.DIRTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- def test_update_empty_all(self):
- """If the repository in-sync is empty, then it is not safe to
- update, regardless of the clean state.
-
- """
- stat = ExternalStatus()
- stat.sync_state = ExternalStatus.UNKNOWN
- stat.clean_state = ExternalStatus.DEFAULT
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.EMPTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.UNKNOWN
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.STATUS_OK
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
- stat.clean_state = ExternalStatus.DIRTY
- safe_to_update = stat.safe_to_update()
- self.assertFalse(safe_to_update)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/manage_externals/test/test_unit_repository.py b/manage_externals/test/test_unit_repository.py
deleted file mode 100644
index 1b93861834..0000000000
--- a/manage_externals/test/test_unit_repository.py
+++ /dev/null
@@ -1,208 +0,0 @@
-#!/usr/bin/env python3
-
-"""Unit test driver for checkout_externals
-
-Note: this script assume the path to the checkout_externals.py module is
-already in the python path.
-
-"""
-
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import unittest
-
-from manic.repository_factory import create_repository
-from manic.repository_git import GitRepository
-from manic.repository_svn import SvnRepository
-from manic.repository import Repository
-from manic.externals_description import ExternalsDescription
-from manic.global_constants import EMPTY_STR
-
-
-class TestCreateRepositoryDict(unittest.TestCase):
- """Test the create_repository functionality to ensure it returns the
- propper type of repository and errors for unknown repository
- types.
-
- """
-
- def setUp(self):
- """Common data needed for all tests in this class
- """
- self._name = 'test_name'
- self._repo = {ExternalsDescription.PROTOCOL: None,
- ExternalsDescription.REPO_URL: 'junk_root',
- ExternalsDescription.TAG: 'junk_tag',
- ExternalsDescription.BRANCH: EMPTY_STR,
- ExternalsDescription.HASH: EMPTY_STR,
- ExternalsDescription.SPARSE: EMPTY_STR, }
-
- def test_create_repo_git(self):
- """Verify that several possible names for the 'git' protocol
- create git repository objects.
-
- """
- protocols = ['git', 'GIT', 'Git', ]
- for protocol in protocols:
- self._repo[ExternalsDescription.PROTOCOL] = protocol
- repo = create_repository(self._name, self._repo)
- self.assertIsInstance(repo, GitRepository)
-
- def test_create_repo_svn(self):
- """Verify that several possible names for the 'svn' protocol
- create svn repository objects.
- """
- protocols = ['svn', 'SVN', 'Svn', ]
- for protocol in protocols:
- self._repo[ExternalsDescription.PROTOCOL] = protocol
- repo = create_repository(self._name, self._repo)
- self.assertIsInstance(repo, SvnRepository)
-
- def test_create_repo_externals_only(self):
- """Verify that an externals only repo returns None.
- """
- protocols = ['externals_only', ]
- for protocol in protocols:
- self._repo[ExternalsDescription.PROTOCOL] = protocol
- repo = create_repository(self._name, self._repo)
- self.assertEqual(None, repo)
-
- def test_create_repo_unsupported(self):
- """Verify that an unsupported protocol generates a runtime error.
- """
- protocols = ['not_a_supported_protocol', ]
- for protocol in protocols:
- self._repo[ExternalsDescription.PROTOCOL] = protocol
- with self.assertRaises(RuntimeError):
- create_repository(self._name, self._repo)
-
-
-class TestRepository(unittest.TestCase):
- """Test the externals description processing used to create the Repository
- base class shared by protocol specific repository classes.
-
- """
-
- def test_tag(self):
- """Test creation of a repository object with a tag
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- tag = 'test_tag'
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.TAG: tag,
- ExternalsDescription.BRANCH: EMPTY_STR,
- ExternalsDescription.HASH: EMPTY_STR,
- ExternalsDescription.SPARSE: EMPTY_STR, }
- repo = Repository(name, repo_info)
- print(repo.__dict__)
- self.assertEqual(repo.tag(), tag)
- self.assertEqual(repo.url(), url)
-
- def test_branch(self):
- """Test creation of a repository object with a branch
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- branch = 'test_branch'
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.BRANCH: branch,
- ExternalsDescription.TAG: EMPTY_STR,
- ExternalsDescription.HASH: EMPTY_STR,
- ExternalsDescription.SPARSE: EMPTY_STR, }
- repo = Repository(name, repo_info)
- print(repo.__dict__)
- self.assertEqual(repo.branch(), branch)
- self.assertEqual(repo.url(), url)
-
- def test_hash(self):
- """Test creation of a repository object with a hash
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- ref = 'deadc0de'
- sparse = EMPTY_STR
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.BRANCH: EMPTY_STR,
- ExternalsDescription.TAG: EMPTY_STR,
- ExternalsDescription.HASH: ref,
- ExternalsDescription.SPARSE: sparse, }
- repo = Repository(name, repo_info)
- print(repo.__dict__)
- self.assertEqual(repo.hash(), ref)
- self.assertEqual(repo.url(), url)
-
- def test_tag_branch(self):
- """Test creation of a repository object with a tag and branch raises a
- runtimer error.
-
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- branch = 'test_branch'
- tag = 'test_tag'
- ref = EMPTY_STR
- sparse = EMPTY_STR
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.BRANCH: branch,
- ExternalsDescription.TAG: tag,
- ExternalsDescription.HASH: ref,
- ExternalsDescription.SPARSE: sparse, }
- with self.assertRaises(RuntimeError):
- Repository(name, repo_info)
-
- def test_tag_branch_hash(self):
- """Test creation of a repository object with a tag, branch and hash raises a
- runtimer error.
-
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- branch = 'test_branch'
- tag = 'test_tag'
- ref = 'deadc0de'
- sparse = EMPTY_STR
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.BRANCH: branch,
- ExternalsDescription.TAG: tag,
- ExternalsDescription.HASH: ref,
- ExternalsDescription.SPARSE: sparse, }
- with self.assertRaises(RuntimeError):
- Repository(name, repo_info)
-
- def test_no_tag_no_branch(self):
- """Test creation of a repository object without a tag or branch raises a
- runtimer error.
-
- """
- name = 'test_repo'
- protocol = 'test_protocol'
- url = 'test_url'
- branch = EMPTY_STR
- tag = EMPTY_STR
- ref = EMPTY_STR
- sparse = EMPTY_STR
- repo_info = {ExternalsDescription.PROTOCOL: protocol,
- ExternalsDescription.REPO_URL: url,
- ExternalsDescription.BRANCH: branch,
- ExternalsDescription.TAG: tag,
- ExternalsDescription.HASH: ref,
- ExternalsDescription.SPARSE: sparse, }
- with self.assertRaises(RuntimeError):
- Repository(name, repo_info)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/manage_externals/test/test_unit_repository_git.py b/manage_externals/test/test_unit_repository_git.py
deleted file mode 100644
index 1c01098acf..0000000000
--- a/manage_externals/test/test_unit_repository_git.py
+++ /dev/null
@@ -1,811 +0,0 @@
-#!/usr/bin/env python3
-
-"""Unit test driver for checkout_externals
-
-Note: this script assume the path to the checkout_externals.py module is
-already in the python path.
-
-"""
-# pylint: disable=too-many-lines,protected-access
-
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import os
-import shutil
-import unittest
-
-from manic.repository_git import GitRepository
-from manic.externals_status import ExternalStatus
-from manic.externals_description import ExternalsDescription
-from manic.externals_description import ExternalsDescriptionDict
-from manic.global_constants import EMPTY_STR
-
-# NOTE(bja, 2017-11) order is important here. origin should be a
-# subset of other to trap errors on processing remotes!
-GIT_REMOTE_OUTPUT_ORIGIN_UPSTREAM = '''
-upstream /path/to/other/repo (fetch)
-upstream /path/to/other/repo (push)
-other /path/to/local/repo2 (fetch)
-other /path/to/local/repo2 (push)
-origin /path/to/local/repo (fetch)
-origin /path/to/local/repo (push)
-'''
-
-
-class TestGitRepositoryCurrentRef(unittest.TestCase):
- """test the current_ref command on a git repository
- """
-
- def setUp(self):
- self._name = 'component'
- rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL:
- '/path/to/local/repo',
- ExternalsDescription.TAG:
- 'tag1',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'junk',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = GitRepository('test', repo)
-
- #
- # mock methods replacing git system calls
- #
- @staticmethod
- def _git_current_branch(branch_found, branch_name):
- """Return a function that takes the place of
- repo._git_current_branch, which returns the given output."""
- def my_git_current_branch(dirname):
- """mock function that can take the place of repo._git_current_branch"""
- return branch_found, branch_name
- return my_git_current_branch
-
- @staticmethod
- def _git_current_tag(tag_found, tag_name):
- """Return a function that takes the place of
- repo._git_current_tag, which returns the given output."""
- def my_git_current_tag(dirname):
- """mock function that can take the place of repo._git_current_tag"""
- return tag_found, tag_name
- return my_git_current_tag
-
- @staticmethod
- def _git_current_hash(hash_found, hash_name):
- """Return a function that takes the place of
- repo._git_current_hash, which returns the given output."""
- def my_git_current_hash(dirname):
- """mock function that can take the place of repo._git_current_hash"""
- return hash_found, hash_name
- return my_git_current_hash
-
- # ------------------------------------------------------------------------
- # Begin tests
- # ------------------------------------------------------------------------
-
- def test_ref_branch(self):
- """Test that we correctly identify we are on a branch
- """
- self._repo._git_current_branch = self._git_current_branch(
- True, 'feature3')
- self._repo._git_current_tag = self._git_current_tag(True, 'foo_tag')
- self._repo._git_current_hash = self._git_current_hash(True, 'abc123')
- expected = 'foo_tag (branch feature3)'
- result = self._repo._current_ref(os.getcwd())
- self.assertEqual(result, expected)
-
- def test_ref_detached_tag(self):
- """Test that we correctly identify that the ref is detached at a tag
- """
- self._repo._git_current_branch = self._git_current_branch(False, '')
- self._repo._git_current_tag = self._git_current_tag(True, 'foo_tag')
- self._repo._git_current_hash = self._git_current_hash(True, 'abc123')
- expected = 'foo_tag'
- result = self._repo._current_ref(os.getcwd())
- self.assertEqual(result, expected)
-
- def test_ref_detached_hash(self):
- """Test that we can identify ref is detached at a hash
-
- """
- self._repo._git_current_branch = self._git_current_branch(False, '')
- self._repo._git_current_tag = self._git_current_tag(False, '')
- self._repo._git_current_hash = self._git_current_hash(True, 'abc123')
- expected = 'abc123'
- result = self._repo._current_ref(os.getcwd())
- self.assertEqual(result, expected)
-
- def test_ref_none(self):
- """Test that we correctly identify that we're not in a git repo.
- """
- self._repo._git_current_branch = self._git_current_branch(False, '')
- self._repo._git_current_tag = self._git_current_tag(False, '')
- self._repo._git_current_hash = self._git_current_hash(False, '')
- result = self._repo._current_ref(os.getcwd())
- self.assertEqual(result, EMPTY_STR)
-
-
-class TestGitRepositoryCheckSync(unittest.TestCase):
- """Test whether the GitRepository _check_sync_logic functionality is
- correct.
-
- Note: there are a lot of combinations of state:
-
- - external description - tag, branch
-
- - working copy
- - doesn't exist (not checked out)
- - exists, no git info - incorrect protocol, e.g. svn, or tarball?
- - exists, git info
- - as expected:
- - different from expected:
- - detached tag,
- - detached hash,
- - detached branch (compare remote and branch),
- - tracking branch (compare remote and branch),
- - same remote
- - different remote
- - untracked branch
-
- Test list:
- - doesn't exist
- - exists no git info
-
- - num_external * (working copy expected + num_working copy different)
- - total tests = 16
-
- """
-
- # NOTE(bja, 2017-11) pylint complains about long method names, but
- # it is hard to differentiate tests without making them more
- # cryptic. Also complains about too many public methods, but it
- # doesn't really make sense to break this up.
- # pylint: disable=invalid-name,too-many-public-methods
-
- TMP_FAKE_DIR = 'fake'
- TMP_FAKE_GIT_DIR = os.path.join(TMP_FAKE_DIR, '.git')
-
- def setUp(self):
- """Setup reusable git repository object
- """
- self._name = 'component'
- rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL:
- '/path/to/local/repo',
- ExternalsDescription.TAG: 'tag1',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: self.TMP_FAKE_DIR,
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = GitRepository('test', repo)
- # The unit tests here don't care about the result of
- # _current_ref, but we replace it here so that we don't need to
- # worry about calling a possibly slow and possibly
- # error-producing command (since _current_ref calls various git
- # functions):
- self._repo._current_ref = self._current_ref_empty
- self._create_tmp_git_dir()
-
- # We have to override this class method rather than the self._repo
- # instance method because it is called via
- # GitRepository._remote_name_for_url, which is itself a @classmethod
- # calls cls._git_remote_verbose().
- self._orignal_git_remote_verbose = GitRepository._git_remote_verbose
- GitRepository._git_remote_verbose = self._git_remote_origin_upstream
- def tearDown(self):
- """Cleanup tmp stuff on the file system
- """
- self._remove_tmp_git_dir()
-
- GitRepository._git_remote_verbose = self._orignal_git_remote_verbose
-
- def _create_tmp_git_dir(self):
- """Create a temporary fake git directory for testing purposes.
- """
- if not os.path.exists(self.TMP_FAKE_GIT_DIR):
- os.makedirs(self.TMP_FAKE_GIT_DIR)
-
- def _remove_tmp_git_dir(self):
- """Remove the temporary fake git directory
- """
- if os.path.exists(self.TMP_FAKE_DIR):
- shutil.rmtree(self.TMP_FAKE_DIR)
-
- #
- # mock methods replacing git system calls
- #
- @staticmethod
- def _current_ref_empty(dirname):
- """Return an empty string.
-
- Drop-in for GitRepository._current_ref
- """
- return EMPTY_STR
-
- @staticmethod
- def _git_remote_origin_upstream(dirname):
- """Return an info string that is a checkout hash.
-
- Drop-in for GitRepository._git_remote_verbose.
- """
- return GIT_REMOTE_OUTPUT_ORIGIN_UPSTREAM
-
- @staticmethod
- def _git_current_hash(myhash):
- """Return a function that takes the place of repo._git_current_hash,
- which returns the given hash
- """
- def my_git_current_hash(dirname):
- """mock function that can take the place of repo._git_current_hash"""
- return 0, myhash
- return my_git_current_hash
-
- def _git_revparse_commit(self, expected_ref, mystatus, myhash):
- """Return a function that takes the place of
- repo._git_revparse_commit, which returns a tuple:
- (mystatus, myhash).
-
- Expects the passed-in ref to equal expected_ref
-
- status = 0 implies success, non-zero implies failure
- """
- def my_git_revparse_commit(ref, dirname):
- """mock function that can take the place of repo._git_revparse_commit"""
- self.assertEqual(expected_ref, ref)
- return mystatus, myhash
- return my_git_revparse_commit
-
- # ----------------------------------------------------------------
- #
- # Tests where working copy doesn't exist or is invalid
- #
- # ----------------------------------------------------------------
- def test_sync_dir_not_exist(self):
- """Test that a directory that doesn't exist returns an error status
-
- Note: the Repository classes should be prevented from ever
- working on an empty directory by the _Source object.
-
- """
- stat = ExternalStatus()
- self._repo._check_sync(stat, 'invalid_directory_name')
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_ERROR)
- # check_dir should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_dir_exist_no_git_info(self):
- """Test that a non-existent git repo returns an unknown status
- """
- stat = ExternalStatus()
- self._repo._tag = 'tag1'
- self._repo._git_current_hash = self._git_current_hash('')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'tag1', 1, '')
- self._repo._check_sync(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.UNKNOWN)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- # ------------------------------------------------------------------------
- #
- # Tests where version in configuration file is not a valid reference
- #
- # ------------------------------------------------------------------------
-
- def test_sync_invalid_reference(self):
- """Test that an invalid reference returns out-of-sync
- """
- stat = ExternalStatus()
- self._repo._tag = 'tag1'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'tag1', 1, '')
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- # ----------------------------------------------------------------
- #
- # Tests where external description specifies a tag
- #
- # ----------------------------------------------------------------
- def test_sync_tag_on_same_hash(self):
- """Test expect tag on same hash --> status ok
-
- """
- stat = ExternalStatus()
- self._repo._tag = 'tag1'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'tag1', 0, 'abc123')
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_OK)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_tag_on_different_hash(self):
- """Test expect tag on a different hash --> status modified
-
- """
- stat = ExternalStatus()
- self._repo._tag = 'tag1'
- self._repo._git_current_hash = self._git_current_hash('def456')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'tag1', 0, 'abc123')
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- # ----------------------------------------------------------------
- #
- # Tests where external description specifies a hash
- #
- # ----------------------------------------------------------------
- def test_sync_hash_on_same_hash(self):
- """Test expect hash on same hash --> status ok
-
- """
- stat = ExternalStatus()
- self._repo._tag = ''
- self._repo._hash = 'abc'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'abc', 0, 'abc123')
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_OK)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_hash_on_different_hash(self):
- """Test expect hash on a different hash --> status modified
-
- """
- stat = ExternalStatus()
- self._repo._tag = ''
- self._repo._hash = 'abc'
- self._repo._git_current_hash = self._git_current_hash('def456')
- self._repo._git_revparse_commit = self._git_revparse_commit(
- 'abc', 0, 'abc123')
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- # ----------------------------------------------------------------
- #
- # Tests where external description specifies a branch
- #
- # ----------------------------------------------------------------
- def test_sync_branch_on_same_hash(self):
- """Test expect branch on same hash --> status ok
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature-2'
- self._repo._tag = ''
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('origin/feature-2', 0, 'abc123'))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_OK)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_branch_on_diff_hash(self):
- """Test expect branch on diff hash --> status modified
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature-2'
- self._repo._tag = ''
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('origin/feature-2', 0, 'def456'))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_branch_diff_remote(self):
- """Test _remote_name_for_url with a different remote
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature-2'
- self._repo._tag = ''
- self._repo._url = '/path/to/other/repo'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('upstream/feature-2', 0, 'def456'))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- # The test passes if _git_revparse_commit is called with the
- # expected argument
-
- def test_sync_branch_diff_remote2(self):
- """Test _remote_name_for_url with a different remote
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature-2'
- self._repo._tag = ''
- self._repo._url = '/path/to/local/repo2'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('other/feature-2', 0, 'def789'))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- # The test passes if _git_revparse_commit is called with the
- # expected argument
-
- def test_sync_branch_on_unknown_remote(self):
- """Test expect branch, but remote is unknown --> status modified
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature-2'
- self._repo._tag = ''
- self._repo._url = '/path/to/unknown/repo'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('unknown_remote/feature-2', 1, ''))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_sync_branch_on_untracked_local(self):
- """Test expect branch, on untracked branch in local repo --> status ok
-
- Setting the externals description to '.' indicates that the
- user only wants to consider the current local repo state
- without fetching from remotes. This is required to preserve
- the current branch of a repository during an update.
-
- """
- stat = ExternalStatus()
- self._repo._branch = 'feature3'
- self._repo._tag = ''
- self._repo._url = '.'
- self._repo._git_current_hash = self._git_current_hash('abc123')
- self._repo._git_revparse_commit = (
- self._git_revparse_commit('feature3', 0, 'abc123'))
- self._repo._check_sync_logic(stat, self.TMP_FAKE_DIR)
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_OK)
- # check_sync should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
-
-class TestGitStatusPorcelain(unittest.TestCase):
- """Test parsing of output from git status --porcelain=v1 -z
- """
- # pylint: disable=C0103
- GIT_STATUS_PORCELAIN_V1_ALL = (
- r' D INSTALL\0MM Makefile\0M README.md\0R cmakelists.txt\0'
- r'CMakeLists.txt\0D commit-message-template.txt\0A stuff.txt\0'
- r'?? junk.txt')
-
- GIT_STATUS_PORCELAIN_CLEAN = r''
-
- def test_porcelain_status_dirty(self):
- """Verify that git status output is considered dirty when there are
- listed files.
-
- """
- git_output = self.GIT_STATUS_PORCELAIN_V1_ALL
- is_dirty = GitRepository._status_v1z_is_dirty(git_output)
- self.assertTrue(is_dirty)
-
- def test_porcelain_status_clean(self):
- """Verify that git status output is considered clean when there are no
- listed files.
-
- """
- git_output = self.GIT_STATUS_PORCELAIN_CLEAN
- is_dirty = GitRepository._status_v1z_is_dirty(git_output)
- self.assertFalse(is_dirty)
-
-
-class TestGitCreateRemoteName(unittest.TestCase):
- """Test the create_remote_name method on the GitRepository class
- """
-
- def setUp(self):
- """Common infrastructure for testing _create_remote_name
- """
- self._rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL:
- 'empty',
- ExternalsDescription.TAG:
- 'very_useful_tag',
- ExternalsDescription.BRANCH: EMPTY_STR,
- ExternalsDescription.HASH: EMPTY_STR,
- ExternalsDescription.SPARSE: EMPTY_STR, }
- self._repo = GitRepository('test', self._rdata)
-
- def test_remote_git_proto(self):
- """Test remote with git protocol
- """
- self._repo._url = 'git@git.github.com:very_nice_org/useful_repo'
- remote_name = self._repo._create_remote_name()
- self.assertEqual(remote_name, 'very_nice_org_useful_repo')
-
- def test_remote_https_proto(self):
- """Test remote with git protocol
- """
- self._repo._url = 'https://www.github.com/very_nice_org/useful_repo'
- remote_name = self._repo._create_remote_name()
- self.assertEqual(remote_name, 'very_nice_org_useful_repo')
-
- def test_remote_local_abs(self):
- """Test remote with git protocol
- """
- self._repo._url = '/path/to/local/repositories/useful_repo'
- remote_name = self._repo._create_remote_name()
- self.assertEqual(remote_name, 'repositories_useful_repo')
-
- def test_remote_local_rel(self):
- """Test remote with git protocol
- """
- os.environ['TEST_VAR'] = '/my/path/to/repos'
- self._repo._url = '${TEST_VAR}/../../useful_repo'
- remote_name = self._repo._create_remote_name()
- self.assertEqual(remote_name, 'path_useful_repo')
- del os.environ['TEST_VAR']
-
-
-class TestVerifyTag(unittest.TestCase):
- """Test logic verifying that a tag exists and is unique
-
- """
-
- def setUp(self):
- """Setup reusable git repository object
- """
- self._name = 'component'
- rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL:
- '/path/to/local/repo',
- ExternalsDescription.TAG: 'tag1',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'tmp',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = GitRepository('test', repo)
-
- @staticmethod
- def _shell_true(*args, **kwargs):
- return 0
-
- @staticmethod
- def _shell_false(*args, **kwargs):
- return 1
-
- @staticmethod
- def _mock_revparse_commit(ref, dirname):
- _ = ref
- return (TestValidRef._shell_true, '97ebc0e0deadc0de')
-
- @staticmethod
- def _mock_revparse_commit_false(ref, dirname):
- _ = ref
- return (TestValidRef._shell_false, '97ebc0e0deadc0de')
-
- def test_tag_not_tag_branch_commit(self):
- """Verify a non-tag returns false
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit_false
- self._repo._tag = 'something'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertFalse(received)
-
- def test_tag_not_tag(self):
- """Verify a non-tag, untracked remote returns false
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_true
- self._repo._git_lsremote_branch = self._shell_true
- self._repo._git_revparse_commit = self._mock_revparse_commit_false
- self._repo._tag = 'tag1'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertFalse(received)
-
- def test_tag_indeterminant(self):
- """Verify an indeterminant tag/branch returns false
- """
- self._repo._git_showref_tag = self._shell_true
- self._repo._git_showref_branch = self._shell_true
- self._repo._git_lsremote_branch = self._shell_true
- self._repo._git_revparse_commit = self._mock_revparse_commit
- self._repo._tag = 'something'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertFalse(received)
-
- def test_tag_is_unique(self):
- """Verify a unique tag match returns true
- """
- self._repo._git_showref_tag = self._shell_true
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit
- self._repo._tag = 'tag1'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertTrue(received)
-
- def test_tag_is_not_hash(self):
- """Verify a commit hash is not classified as a tag
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit
- self._repo._tag = '97ebc0e0'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertFalse(received)
-
- def test_hash_is_commit(self):
- """Verify a commit hash is not classified as a tag
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit
- self._repo._tag = '97ebc0e0'
- remote_name = 'origin'
- received, _ = self._repo._is_unique_tag(self._repo._tag, remote_name,
- os.getcwd())
- self.assertFalse(received)
-
-
-class TestValidRef(unittest.TestCase):
- """Test logic verifying that a reference is a valid tag, branch or sha1
-
- """
-
- def setUp(self):
- """Setup reusable git repository object
- """
- self._name = 'component'
- rdata = {ExternalsDescription.PROTOCOL: 'git',
- ExternalsDescription.REPO_URL:
- '/path/to/local/repo',
- ExternalsDescription.TAG: 'tag1',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'tmp',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = GitRepository('test', repo)
-
- @staticmethod
- def _shell_true(url, remote=None):
- _ = url
- _ = remote
- return 0
-
- @staticmethod
- def _shell_false(url, remote=None):
- _ = url
- _ = remote
- return 1
-
- @staticmethod
- def _mock_revparse_commit_false(ref, dirname):
- _ = ref
- return (TestValidRef._shell_false, '')
-
- @staticmethod
- def _mock_revparse_commit_true(ref, dirname):
- _ = ref
- _ = dirname
- return (TestValidRef._shell_true, '')
-
- def test_valid_ref_is_invalid(self):
- """Verify an invalid reference raises an exception
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit_false
- self._repo._tag = 'invalid_ref'
- with self.assertRaises(RuntimeError):
- self._repo._check_for_valid_ref(self._repo._tag,
- remote_name=None,
- dirname=os.getcwd())
-
- def test_valid_tag(self):
- """Verify a valid tag return true
- """
- self._repo._git_showref_tag = self._shell_true
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit_true
- self._repo._tag = 'tag1'
- received = self._repo._check_for_valid_ref(self._repo._tag,
- remote_name=None,
- dirname=os.getcwd())
- self.assertTrue(received)
-
- def test_valid_branch(self):
- """Verify a valid tag return true
- """
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_true
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = self._mock_revparse_commit_true
- self._repo._tag = 'tag1'
- received = self._repo._check_for_valid_ref(self._repo._tag,
- remote_name=None,
- dirname=os.getcwd())
- self.assertTrue(received)
-
- def test_valid_hash(self):
- """Verify a valid hash return true
- """
- def _mock_revparse_commit_true(ref, dirname):
- _ = ref
- return (0, '56cc0b539426eb26810af9e')
-
- self._repo._git_showref_tag = self._shell_false
- self._repo._git_showref_branch = self._shell_false
- self._repo._git_lsremote_branch = self._shell_false
- self._repo._git_revparse_commit = _mock_revparse_commit_true
- self._repo._hash = '56cc0b5394'
- received = self._repo._check_for_valid_ref(self._repo._hash,
- remote_name=None,
- dirname=os.getcwd())
- self.assertTrue(received)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/manage_externals/test/test_unit_repository_svn.py b/manage_externals/test/test_unit_repository_svn.py
deleted file mode 100755
index d9309df7f6..0000000000
--- a/manage_externals/test/test_unit_repository_svn.py
+++ /dev/null
@@ -1,501 +0,0 @@
-#!/usr/bin/env python3
-
-"""Unit test driver for checkout_externals
-
-Note: this script assume the path to the checkout_externals.py module is
-already in the python path.
-
-"""
-
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import unittest
-
-from manic.repository_svn import SvnRepository
-from manic.externals_status import ExternalStatus
-from manic.externals_description import ExternalsDescription
-from manic.externals_description import ExternalsDescriptionDict
-from manic.global_constants import EMPTY_STR
-
-# pylint: disable=W0212
-
-SVN_INFO_MOSART = """Path: components/mosart
-Working Copy Root Path: /Users/andreb/projects/ncar/git-conversion/clm-dev-experimental/components/mosart
-URL: https://svn-ccsm-models.cgd.ucar.edu/mosart/trunk_tags/mosart1_0_26
-Relative URL: ^/mosart/trunk_tags/mosart1_0_26
-Repository Root: https://svn-ccsm-models.cgd.ucar.edu
-Repository UUID: fe37f545-8307-0410-aea5-b40df96820b5
-Revision: 86711
-Node Kind: directory
-Schedule: normal
-Last Changed Author: erik
-Last Changed Rev: 86031
-Last Changed Date: 2017-07-07 12:28:10 -0600 (Fri, 07 Jul 2017)
-"""
-SVN_INFO_CISM = """
-Path: components/cism
-Working Copy Root Path: /Users/andreb/projects/ncar/git-conversion/clm-dev-experimental/components/cism
-URL: https://svn-ccsm-models.cgd.ucar.edu/glc/trunk_tags/cism2_1_37
-Relative URL: ^/glc/trunk_tags/cism2_1_37
-Repository Root: https://svn-ccsm-models.cgd.ucar.edu
-Repository UUID: fe37f545-8307-0410-aea5-b40df96820b5
-Revision: 86711
-Node Kind: directory
-Schedule: normal
-Last Changed Author: sacks
-Last Changed Rev: 85704
-Last Changed Date: 2017-06-15 05:59:28 -0600 (Thu, 15 Jun 2017)
-"""
-
-
-class TestSvnRepositoryCheckURL(unittest.TestCase):
- """Verify that the svn_check_url function is working as expected.
- """
-
- def setUp(self):
- """Setup reusable svn repository object
- """
- self._name = 'component'
- rdata = {ExternalsDescription.PROTOCOL: 'svn',
- ExternalsDescription.REPO_URL:
- 'https://svn-ccsm-models.cgd.ucar.edu',
- ExternalsDescription.TAG:
- 'mosart/trunk_tags/mosart1_0_26',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'junk',
- ExternalsDescription.EXTERNALS: '',
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = SvnRepository('test', repo)
-
- def test_check_url_same(self):
- """Test that we correctly identify that the correct URL.
- """
- svn_output = SVN_INFO_MOSART
- expected_url = self._repo.url()
- result, current_version = \
- self._repo._check_url(svn_output, expected_url)
- self.assertEqual(result, ExternalStatus.STATUS_OK)
- self.assertEqual(current_version, 'mosart/trunk_tags/mosart1_0_26')
-
- def test_check_url_different(self):
- """Test that we correctly reject an incorrect URL.
- """
- svn_output = SVN_INFO_CISM
- expected_url = self._repo.url()
- result, current_version = \
- self._repo._check_url(svn_output, expected_url)
- self.assertEqual(result, ExternalStatus.MODEL_MODIFIED)
- self.assertEqual(current_version, 'glc/trunk_tags/cism2_1_37')
-
- def test_check_url_none(self):
- """Test that we can handle an empty string for output, e.g. not an svn
- repo.
-
- """
- svn_output = EMPTY_STR
- expected_url = self._repo.url()
- result, current_version = \
- self._repo._check_url(svn_output, expected_url)
- self.assertEqual(result, ExternalStatus.UNKNOWN)
- self.assertEqual(current_version, '')
-
-
-class TestSvnRepositoryCheckSync(unittest.TestCase):
- """Test whether the SvnRepository svn_check_sync functionality is
- correct.
-
- """
-
- def setUp(self):
- """Setup reusable svn repository object
- """
- self._name = "component"
- rdata = {ExternalsDescription.PROTOCOL: 'svn',
- ExternalsDescription.REPO_URL:
- 'https://svn-ccsm-models.cgd.ucar.edu/',
- ExternalsDescription.TAG:
- 'mosart/trunk_tags/mosart1_0_26',
- }
-
- data = {self._name:
- {
- ExternalsDescription.REQUIRED: False,
- ExternalsDescription.PATH: 'junk',
- ExternalsDescription.EXTERNALS: EMPTY_STR,
- ExternalsDescription.REPO: rdata,
- },
- }
-
- model = ExternalsDescriptionDict(data)
- repo = model[self._name][ExternalsDescription.REPO]
- self._repo = SvnRepository('test', repo)
-
- @staticmethod
- def _svn_info_empty(*_):
- """Return an empty info string. Simulates svn info failing.
- """
- return ''
-
- @staticmethod
- def _svn_info_synced(*_):
- """Return an info sting that is synced with the setUp data
- """
- return SVN_INFO_MOSART
-
- @staticmethod
- def _svn_info_modified(*_):
- """Return and info string that is modified from the setUp data
- """
- return SVN_INFO_CISM
-
- def test_repo_dir_not_exist(self):
- """Test that a directory that doesn't exist returns an error status
-
- Note: the Repository classes should be prevented from ever
- working on an empty directory by the _Source object.
-
- """
- stat = ExternalStatus()
- self._repo._check_sync(stat, 'junk')
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_ERROR)
- # check_dir should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_repo_dir_exist_no_svn_info(self):
- """Test that an empty info string returns an unknown status
- """
- stat = ExternalStatus()
- # Now we over-ride the _svn_info method on the repo to return
- # a known value without requiring access to svn.
- self._repo._svn_info = self._svn_info_empty
- self._repo._check_sync(stat, '.')
- self.assertEqual(stat.sync_state, ExternalStatus.UNKNOWN)
- # check_dir should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_repo_dir_synced(self):
- """Test that a valid info string that is synced to the repo in the
- externals description returns an ok status.
-
- """
- stat = ExternalStatus()
- # Now we over-ride the _svn_info method on the repo to return
- # a known value without requiring access to svn.
- self._repo._svn_info = self._svn_info_synced
- self._repo._check_sync(stat, '.')
- self.assertEqual(stat.sync_state, ExternalStatus.STATUS_OK)
- # check_dir should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
- def test_repo_dir_modified(self):
- """Test that a valid svn info string that is out of sync with the
- externals description returns a modified status.
-
- """
- stat = ExternalStatus()
- # Now we over-ride the _svn_info method on the repo to return
- # a known value without requiring access to svn.
- self._repo._svn_info = self._svn_info_modified
- self._repo._check_sync(stat, '.')
- self.assertEqual(stat.sync_state, ExternalStatus.MODEL_MODIFIED)
- # check_dir should only modify the sync_state, not clean_state
- self.assertEqual(stat.clean_state, ExternalStatus.DEFAULT)
-
-
-class TestSVNStatusXML(unittest.TestCase):
- """Test parsing of svn status xml output
- """
- SVN_STATUS_XML_DIRTY_ALL = '''
-
-
-
-
-
-sacks
-2017-06-15T11:59:00.355419Z
-
-
-
-
-
-
-sacks
-2013-02-07T16:17:56.412878Z
-
-
-
-
-
-
-sacks
-2017-05-01T16:48:27.893741Z
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_DIRTY_MISSING = '''
-
-
-
-
-
-sacks
-2017-06-15T11:59:00.355419Z
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_DIRTY_MODIFIED = '''
-
-
-
-
-
-sacks
-2013-02-07T16:17:56.412878Z
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_DIRTY_DELETED = '''
-
-
-
-
-
-sacks
-2017-05-01T16:48:27.893741Z
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_DIRTY_UNVERSION = '''
-
-
-
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_DIRTY_ADDED = '''
-
-
-
-
-
-
-
-
-
-
-
-'''
-
- SVN_STATUS_XML_CLEAN = '''
-
-
-
-
-
-
-
-
-
-
-
-'''
-
- def test_xml_status_dirty_missing(self):
- """Verify that svn status output is consindered dirty when there is a
- missing file.
-
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_MISSING
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertTrue(is_dirty)
-
- def test_xml_status_dirty_modified(self):
- """Verify that svn status output is consindered dirty when there is a
- modified file.
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_MODIFIED
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertTrue(is_dirty)
-
- def test_xml_status_dirty_deleted(self):
- """Verify that svn status output is consindered dirty when there is a
- deleted file.
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_DELETED
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertTrue(is_dirty)
-
- def test_xml_status_dirty_unversion(self):
- """Verify that svn status output ignores unversioned files when making
- the clean/dirty decision.
-
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_UNVERSION
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertFalse(is_dirty)
-
- def test_xml_status_dirty_added(self):
- """Verify that svn status output is consindered dirty when there is a
- added file.
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_ADDED
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertTrue(is_dirty)
-
- def test_xml_status_dirty_all(self):
- """Verify that svn status output is consindered dirty when there are
- multiple dirty files..
-
- """
- svn_output = self.SVN_STATUS_XML_DIRTY_ALL
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertTrue(is_dirty)
-
- def test_xml_status_dirty_clean(self):
- """Verify that svn status output is consindered clean when there are
- no 'dirty' files. This means accepting untracked and externals.
-
- """
- svn_output = self.SVN_STATUS_XML_CLEAN
- is_dirty = SvnRepository.xml_status_is_dirty(
- svn_output)
- self.assertFalse(is_dirty)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/manage_externals/test/test_unit_utils.py b/manage_externals/test/test_unit_utils.py
deleted file mode 100644
index 80e1636649..0000000000
--- a/manage_externals/test/test_unit_utils.py
+++ /dev/null
@@ -1,350 +0,0 @@
-#!/usr/bin/env python3
-
-"""Unit test driver for checkout_externals
-
-Note: this script assume the path to the checkout_externals.py module is
-already in the python path.
-
-"""
-
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import os
-import unittest
-
-from manic.utils import last_n_lines, indent_string
-from manic.utils import str_to_bool, execute_subprocess
-from manic.utils import is_remote_url, split_remote_url, expand_local_url
-
-
-class TestExecuteSubprocess(unittest.TestCase):
- """Test the application logic of execute_subprocess wrapper
- """
-
- def test_exesub_return_stat_err(self):
- """Test that execute_subprocess returns a status code when caller
- requests and the executed subprocess fails.
-
- """
- cmd = ['false']
- status = execute_subprocess(cmd, status_to_caller=True)
- self.assertEqual(status, 1)
-
- def test_exesub_return_stat_ok(self):
- """Test that execute_subprocess returns a status code when caller
- requests and the executed subprocess succeeds.
-
- """
- cmd = ['true']
- status = execute_subprocess(cmd, status_to_caller=True)
- self.assertEqual(status, 0)
-
- def test_exesub_except_stat_err(self):
- """Test that execute_subprocess raises an exception on error when
- caller doesn't request return code
-
- """
- cmd = ['false']
- with self.assertRaises(RuntimeError):
- execute_subprocess(cmd, status_to_caller=False)
-
-
-class TestLastNLines(unittest.TestCase):
- """Test the last_n_lines function.
-
- """
-
- def test_last_n_lines_short(self):
- """With a message with <= n lines, result of last_n_lines should
- just be the original message.
-
- """
- mystr = """three
-line
-string
-"""
-
- mystr_truncated = last_n_lines(
- mystr, 3, truncation_message='[truncated]')
- self.assertEqual(mystr, mystr_truncated)
-
- def test_last_n_lines_long(self):
- """With a message with > n lines, result of last_n_lines should
- be a truncated string.
-
- """
- mystr = """a
-big
-five
-line
-string
-"""
- expected = """[truncated]
-five
-line
-string
-"""
-
- mystr_truncated = last_n_lines(
- mystr, 3, truncation_message='[truncated]')
- self.assertEqual(expected, mystr_truncated)
-
-
-class TestIndentStr(unittest.TestCase):
- """Test the indent_string function.
-
- """
-
- def test_indent_string_singleline(self):
- """Test the indent_string function with a single-line string
-
- """
- mystr = 'foo'
- result = indent_string(mystr, 4)
- expected = ' foo'
- self.assertEqual(expected, result)
-
- def test_indent_string_multiline(self):
- """Test the indent_string function with a multi-line string
-
- """
- mystr = """hello
-hi
-goodbye
-"""
- result = indent_string(mystr, 2)
- expected = """ hello
- hi
- goodbye
-"""
- self.assertEqual(expected, result)
-
-
-class TestStrToBool(unittest.TestCase):
- """Test the string to boolean conversion routine.
-
- """
-
- def test_case_insensitive_true(self):
- """Verify that case insensitive variants of 'true' returns the True
- boolean.
-
- """
- values = ['true', 'TRUE', 'True', 'tRuE', 't', 'T', ]
- for value in values:
- received = str_to_bool(value)
- self.assertTrue(received)
-
- def test_case_insensitive_false(self):
- """Verify that case insensitive variants of 'false' returns the False
- boolean.
-
- """
- values = ['false', 'FALSE', 'False', 'fAlSe', 'f', 'F', ]
- for value in values:
- received = str_to_bool(value)
- self.assertFalse(received)
-
- def test_invalid_str_error(self):
- """Verify that a non-true/false string generates a runtime error.
- """
- values = ['not_true_or_false', 'A', '1', '0',
- 'false_is_not_true', 'true_is_not_false']
- for value in values:
- with self.assertRaises(RuntimeError):
- str_to_bool(value)
-
-
-class TestIsRemoteURL(unittest.TestCase):
- """Crude url checking to determine if a url is local or remote.
-
- """
-
- def test_url_remote_git(self):
- """verify that a remote git url is identified.
- """
- url = 'git@somewhere'
- is_remote = is_remote_url(url)
- self.assertTrue(is_remote)
-
- def test_url_remote_ssh(self):
- """verify that a remote ssh url is identified.
- """
- url = 'ssh://user@somewhere'
- is_remote = is_remote_url(url)
- self.assertTrue(is_remote)
-
- def test_url_remote_http(self):
- """verify that a remote http url is identified.
- """
- url = 'http://somewhere'
- is_remote = is_remote_url(url)
- self.assertTrue(is_remote)
-
- def test_url_remote_https(self):
- """verify that a remote https url is identified.
- """
- url = 'https://somewhere'
- is_remote = is_remote_url(url)
- self.assertTrue(is_remote)
-
- def test_url_local_user(self):
- """verify that a local path with '~/path/to/repo' gets rejected
-
- """
- url = '~/path/to/repo'
- is_remote = is_remote_url(url)
- self.assertFalse(is_remote)
-
- def test_url_local_var_curly(self):
- """verify that a local path with env var '${HOME}' gets rejected
- """
- url = '${HOME}/path/to/repo'
- is_remote = is_remote_url(url)
- self.assertFalse(is_remote)
-
- def test_url_local_var(self):
- """verify that a local path with an env var '$HOME' gets rejected
- """
- url = '$HOME/path/to/repo'
- is_remote = is_remote_url(url)
- self.assertFalse(is_remote)
-
- def test_url_local_abs(self):
- """verify that a local abs path gets rejected
- """
- url = '/path/to/repo'
- is_remote = is_remote_url(url)
- self.assertFalse(is_remote)
-
- def test_url_local_rel(self):
- """verify that a local relative path gets rejected
- """
- url = '../../path/to/repo'
- is_remote = is_remote_url(url)
- self.assertFalse(is_remote)
-
-
-class TestSplitRemoteURL(unittest.TestCase):
- """Crude url checking to determine if a url is local or remote.
-
- """
-
- def test_url_remote_git(self):
- """verify that a remote git url is identified.
- """
- url = 'git@somewhere.com:org/repo'
- received = split_remote_url(url)
- self.assertEqual(received, "org/repo")
-
- def test_url_remote_ssh(self):
- """verify that a remote ssh url is identified.
- """
- url = 'ssh://user@somewhere.com/path/to/repo'
- received = split_remote_url(url)
- self.assertEqual(received, 'somewhere.com/path/to/repo')
-
- def test_url_remote_http(self):
- """verify that a remote http url is identified.
- """
- url = 'http://somewhere.org/path/to/repo'
- received = split_remote_url(url)
- self.assertEqual(received, 'somewhere.org/path/to/repo')
-
- def test_url_remote_https(self):
- """verify that a remote http url is identified.
- """
- url = 'http://somewhere.gov/path/to/repo'
- received = split_remote_url(url)
- self.assertEqual(received, 'somewhere.gov/path/to/repo')
-
- def test_url_local_url_unchanged(self):
- """verify that a local path is unchanged
-
- """
- url = '/path/to/repo'
- received = split_remote_url(url)
- self.assertEqual(received, url)
-
-
-class TestExpandLocalURL(unittest.TestCase):
- """Crude url checking to determine if a url is local or remote.
-
- Remote should be unmodified.
-
- Local, should perform user and variable expansion.
-
- """
-
- def test_url_local_user1(self):
- """verify that a local path with '~/path/to/repo' gets expanded to an
- absolute path.
-
- NOTE(bja, 2017-11) we can't test for something like:
- '~user/path/to/repo' because the user has to be in the local
- machine password directory and we don't know a user name that
- is valid on every system....?
-
- """
- field = 'test'
- url = '~/path/to/repo'
- received = expand_local_url(url, field)
- print(received)
- self.assertTrue(os.path.isabs(received))
-
- def test_url_local_expand_curly(self):
- """verify that a local path with '${HOME}' gets expanded to an absolute path.
- """
- field = 'test'
- url = '${HOME}/path/to/repo'
- received = expand_local_url(url, field)
- self.assertTrue(os.path.isabs(received))
-
- def test_url_local_expand_var(self):
- """verify that a local path with '$HOME' gets expanded to an absolute path.
- """
- field = 'test'
- url = '$HOME/path/to/repo'
- received = expand_local_url(url, field)
- self.assertTrue(os.path.isabs(received))
-
- def test_url_local_env_missing(self):
- """verify that a local path with env var that is missing gets left as-is
-
- """
- field = 'test'
- url = '$TMP_VAR/path/to/repo'
- received = expand_local_url(url, field)
- print(received)
- self.assertEqual(received, url)
-
- def test_url_local_expand_env(self):
- """verify that a local path with another env var gets expanded to an
- absolute path.
-
- """
- field = 'test'
- os.environ['TMP_VAR'] = '/some/absolute'
- url = '$TMP_VAR/path/to/repo'
- received = expand_local_url(url, field)
- del os.environ['TMP_VAR']
- print(received)
- self.assertTrue(os.path.isabs(received))
- self.assertEqual(received, '/some/absolute/path/to/repo')
-
- def test_url_local_normalize_rel(self):
- """verify that a local path with another env var gets expanded to an
- absolute path.
-
- """
- field = 'test'
- url = '/this/is/a/long/../path/to/a/repo'
- received = expand_local_url(url, field)
- print(received)
- self.assertEqual(received, '/this/is/a/path/to/a/repo')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/py_env_create b/py_env_create
index 9a9b8d940c..ac705edb3c 100755
--- a/py_env_create
+++ b/py_env_create
@@ -122,7 +122,7 @@ if [ "$verbose" == "Yes" ]; then
verbosity="--verbose"
loglevel="INFO"
fi
-cmd="conda install --yes $verbosity --channel conda-forge --name $ctsm_python $condadir/$condafile $option"
+cmd="conda install --yes $verbosity --channel conda-forge --name $ctsm_python --file $condadir/$condafile $option"
echo "$cmd"
$cmd
if [ $? != 0 ]; then
diff --git a/python/ctsm/crop_calendars/check_rx_obeyed.py b/python/ctsm/crop_calendars/check_rx_obeyed.py
index 383ebbf1e0..4d8ccd1788 100644
--- a/python/ctsm/crop_calendars/check_rx_obeyed.py
+++ b/python/ctsm/crop_calendars/check_rx_obeyed.py
@@ -114,8 +114,6 @@ def summarize_results(which_ds, output_var, verbose, all_ok, gdd_tolerance, diff
print(f"✅ {which_ds}: Prescribed {output_var} always obeyed")
elif all_ok == 1:
bad = False
- # print(f"🟨 {which_ds}: Prescribed {output_var} *not* always obeyed, but acceptable:")
- # for x in diff_str_list: print(x)
print(
f"🟨 {which_ds}: Prescribed {output_var} *not* always obeyed, but acceptable (diffs <= "
+ f"{gdd_tolerance})"
diff --git a/python/ctsm/modify_input_files/fsurdat_modifier.py b/python/ctsm/modify_input_files/fsurdat_modifier.py
index bd060cb9dc..1a45590872 100644
--- a/python/ctsm/modify_input_files/fsurdat_modifier.py
+++ b/python/ctsm/modify_input_files/fsurdat_modifier.py
@@ -254,8 +254,8 @@ def modify_optional(
"""Modify the dataset according to the optional settings"""
# Set fsurdat variables in a rectangle that could be global (default).
- # Note that the land/ocean mask gets specified in the domain file for
- # MCT or the ocean mesh files for NUOPC. Here the user may specify
+ # Note that the land/ocean mask gets specified in
+ # the ocean mesh files. Here the user may specify
# fsurdat variables inside a box but cannot change which points will
# run as land and which as ocean.
if idealized:
diff --git a/python/ctsm/run_sys_tests.py b/python/ctsm/run_sys_tests.py
index b3a3b78379..6afc43cd19 100644
--- a/python/ctsm/run_sys_tests.py
+++ b/python/ctsm/run_sys_tests.py
@@ -124,7 +124,7 @@ def run_sys_tests(
cime_path (str): path to root of cime
skip_testroot_creation (bool): if True, assume the testroot directory has already been
created, so don't try to recreate it or re-make the link to it
- skip_git_status (bool): if True, skip printing git and manage_externals status
+ skip_git_status (bool): if True, skip printing git and git-fleximod status
dry_run (bool): if True, print commands to be run but don't run them
suite_name (str): name of test suite/category to run
testfile (str): path to file containing list of tests to run
@@ -476,11 +476,11 @@ def _commandline_args():
parser.add_argument(
"--skip-git-status",
action="store_true",
- help="Skip printing git and manage_externals status,\n"
+ help="Skip printing git and git-fleximod status,\n"
"both to screen and to the SRCROOT_GIT_STATUS file in TESTROOT.\n"
"This printing can often be helpful, but this option can be used to\n"
"avoid extraneous output, to reduce the time needed to run this script,\n"
- "or if git or manage_externals are currently broken in your sandbox.\n",
+ "or if git or git-fleximod are currently broken in your sandbox.\n",
)
parser.add_argument(
@@ -576,12 +576,12 @@ def _record_git_status(testroot, retry, dry_run):
if git_status.count("\n") == 1:
# Only line in git status is the branch info
output += "(clean sandbox)\n"
- manic = os.path.join("manage_externals", "checkout_externals")
- manage_externals_status = subprocess.check_output(
- [manic, "--status", "--verbose"], cwd=ctsm_root, universal_newlines=True
+ fleximod = os.path.join("bin", "git-fleximod")
+ fleximod_status = subprocess.check_output(
+ [fleximod, "status"], cwd=ctsm_root, universal_newlines=True
)
- output += 72 * "-" + "\n" + "manage_externals status:" + "\n"
- output += manage_externals_status
+ output += 72 * "-" + "\n" + "git-fleximod status:" + "\n"
+ output += fleximod_status
output += 72 * "-" + "\n"
print(output)
diff --git a/python/ctsm/site_and_regional/run_neon.py b/python/ctsm/site_and_regional/run_neon.py
index 4b0df2722d..3acbf435b1 100755
--- a/python/ctsm/site_and_regional/run_neon.py
+++ b/python/ctsm/site_and_regional/run_neon.py
@@ -41,7 +41,7 @@
# - [ ] Case dependency and the ability to check case status
# - [ ] If Case dependency works we don't need finidat given explicilty for post-ad and transient.
-# - [ ] checkout_externals instead of using env varaiable
+# - [ ] "./bin/git-fleximod update" instead of using env variable
# - [ ] wget the fields available and run for those available
# - [ ] Matrix spin-up if (SASU) Eric merged it in
diff --git a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py
index 5038c6b3e1..8b8e2df32a 100755
--- a/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py
+++ b/python/ctsm/test/test_unit_gen_mksurfdata_jobscript_single.py
@@ -136,7 +136,7 @@ def test_simple_derecho_args(self):
def test_derecho_mpirun(self):
"""
test derecho mpirun. This would've helped caught a problem we ran into
- It will also be helpful when externals are updated to guide to solutions
+ It will also be helpful when sumodules are updated to guide to solutions
to problems
"""
machine = "derecho"
diff --git a/share b/share
new file mode 160000
index 0000000000..4b9dc4871a
--- /dev/null
+++ b/share
@@ -0,0 +1 @@
+Subproject commit 4b9dc4871a259f00f35bb47708d876cb7dcdf75c
diff --git a/src/biogeochem/CMakeLists.txt b/src/biogeochem/CMakeLists.txt
index e31bbc80f8..0763be096d 100644
--- a/src/biogeochem/CMakeLists.txt
+++ b/src/biogeochem/CMakeLists.txt
@@ -6,11 +6,15 @@ list(APPEND clm_sources
CNPhenologyMod.F90
CNSpeciesMod.F90
CNDVType.F90
+ DustEmisBase.F90
+ DustEmisZender2003.F90
+ DustEmisFactory.F90
CropReprPoolsMod.F90
CropType.F90
CNVegStateType.F90
CNVegCarbonStateType.F90
CNVegCarbonFluxType.F90
+ CNVegMatrixMod.F90
CNVegNitrogenStateType.F90
CNVegNitrogenFluxType.F90
CNCIsoAtmTimeSeriesReadMod.F90
diff --git a/src/biogeochem/CNAllocationMod.F90 b/src/biogeochem/CNAllocationMod.F90
index 8d38ca4b87..6376279a61 100644
--- a/src/biogeochem/CNAllocationMod.F90
+++ b/src/biogeochem/CNAllocationMod.F90
@@ -86,6 +86,7 @@ subroutine calc_gpp_mr_availc(bounds, num_soilp, filter_soilp, &
!
! !USES:
use CNSharedParamsMod , only : use_matrixcn
+ !
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
integer , intent(in) :: num_soilp ! number of soil patches in filter
diff --git a/src/biogeochem/CNBalanceCheckMod.F90 b/src/biogeochem/CNBalanceCheckMod.F90
index 8801efdf72..7b88422843 100644
--- a/src/biogeochem/CNBalanceCheckMod.F90
+++ b/src/biogeochem/CNBalanceCheckMod.F90
@@ -64,7 +64,6 @@ module CNBalanceCheckMod
!-----------------------------------------------------------------------
subroutine Init(this, bounds)
- use CNSharedParamsMod, only : use_matrixcn
class(cn_balance_type) :: this
type(bounds_type) , intent(in) :: bounds
@@ -346,7 +345,7 @@ subroutine CBalanceCheck(this, bounds, num_soilc, filter_soilc, &
(col_endcb(c) - col_begcb(c))
! check for significant errors
- if (abs(col_errcb(c)) > this%cerror) then
+ if (abs(col_errcb(c)) > this%cerror) then
err_found = .true.
err_index = c
end if
@@ -644,8 +643,8 @@ subroutine NBalanceCheck(this, bounds, num_soilc, filter_soilc, &
! calculate the total column-level nitrogen balance error for this time step
col_errnb(c) = (col_ninputs(c) - col_noutputs(c))*dt - &
(col_endnb(c) - col_begnb(c))
-
- if (abs(col_errnb(c)) > this%nerror) then
+
+ if (abs(col_errnb(c)) > this%nerror) then
err_found = .true.
err_index = c
end if
diff --git a/src/biogeochem/CNC14DecayMod.F90 b/src/biogeochem/CNC14DecayMod.F90
index 26e938f72e..1679c602e4 100644
--- a/src/biogeochem/CNC14DecayMod.F90
+++ b/src/biogeochem/CNC14DecayMod.F90
@@ -89,7 +89,26 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
livestemc => c14_cnveg_carbonstate_inst%livestemc_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C
livestemc_storage => c14_cnveg_carbonstate_inst%livestemc_storage_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C storage
livestemc_xfer => c14_cnveg_carbonstate_inst%livestemc_xfer_patch , & ! Output: [real(r8) (:) ] (gC/m2) live stem C transfer
- pft_ctrunc => c14_cnveg_carbonstate_inst%ctrunc_patch & ! Output: [real(r8) (:) ] (gC/m2) patch-level sink for C truncation
+ pft_ctrunc => c14_cnveg_carbonstate_inst%ctrunc_patch , & ! Output: [real(r8) (:) ] (gC/m2) patch-level sink for C truncation
+
+ ileaf_to_iout_fic => c14_cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => c14_cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => c14_cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => c14_cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => c14_cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => c14_cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => c14_cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
)
! set time steps
@@ -116,12 +135,15 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
spinup_term = 1._r8
endif
- ! Without matrix solution
if(.not. use_soil_matrixcn)then
decomp_cpools_vr(c,j,l) = decomp_cpools_vr(c,j,l) * (1._r8 - decay_const * spinup_term * dt)
else
- ! Matrix solution equivalent to above
- ! This will be added when the full matrix solution is brought in
+ associate( &
+ matrix_decomp_fire_k => c14_soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - spinup_term * decay_const * dt
+ end associate
end if
end do
end do
@@ -133,8 +155,6 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
cpool(p) = cpool(p) * (1._r8 - decay_const * dt)
xsmrpool(p) = xsmrpool(p) * (1._r8 - decay_const * dt)
-
- ! Without Matrix solution
if(.not. use_matrixcn)then
! NOTE: Any changes here need to be applied below
deadcrootc(p) = deadcrootc(p) * (1._r8 - decay_const * dt)
@@ -156,11 +176,31 @@ subroutine C14Decay( bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
livestemc_storage(p) = livestemc_storage(p) * (1._r8 - decay_const * dt)
livestemc_xfer(p) = livestemc_xfer(p) * (1._r8 - decay_const * dt)
else
+ associate( &
+ matrix_fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch & ! Output: [real(r8) (:,:) ] (gC/m2/s) C transfer rate from fire processes
+ )
! Each of these MUST correspond to the code above. Any changes in
! code above need to apply here as well
+ matrix_fitransfer(p,ideadcroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadcrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadcrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstem_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstemst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ideadstemxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ifrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileaf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileafst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ileafxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecroot_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecrootst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivecrootxf_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestem_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestemst_to_iout_fic) = decay_const
+ matrix_fitransfer(p,ilivestemxf_to_iout_fic) = decay_const
+ end associate
end if
- ! Some fields like cpool, and xsmrpool above, and the gresp and
- ! pft_ctrunc fields are handled the same for both matrix on and off
gresp_storage(p) = gresp_storage(p) * (1._r8 - decay_const * dt)
gresp_xfer(p) = gresp_xfer(p) * (1._r8 - decay_const * dt)
pft_ctrunc(p) = pft_ctrunc(p) * (1._r8 - decay_const * dt)
diff --git a/src/biogeochem/CNCStateUpdate1Mod.F90 b/src/biogeochem/CNCStateUpdate1Mod.F90
index 5e38de2676..093e83172a 100644
--- a/src/biogeochem/CNCStateUpdate1Mod.F90
+++ b/src/biogeochem/CNCStateUpdate1Mod.F90
@@ -2,9 +2,6 @@ module CNCStateUpdate1Mod
!-----------------------------------------------------------------------
! Module for carbon state variable update, non-mortality fluxes.
- ! When the matrix solution is being used (use_matrixcn and use_soil_matrixcn)
- ! only some state updates are done here, the other state updates happen
- ! after the matrix is solved in VegMatrix and SoilMatrix.
!
! !USES:
use shr_kind_mod , only : r8 => shr_kind_r8
@@ -147,6 +144,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! variables (except for gap-phase mortality and fire fluxes)
!
use clm_varctl , only : carbon_resp_opt
+ use CNVegMatrixMod, only : matrix_update_phc
! !ARGUMENTS:
integer , intent(in) :: num_soilc ! number of soil columns filter
integer , intent(in) :: filter_soilc(:) ! filter for soil columns
@@ -188,7 +186,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
dt = get_step_size_real()
! Below is the input into the soil biogeochemistry model
-
+
fc_loop: do fc = 1,num_soilc
c = filter_soilc(fc)
@@ -202,9 +200,7 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
call clm_fates%UpdateCLitterfluxes(cf_soil,clump_index,c)
else
-
do j = 1,nlevdecomp
-
!
! State update without the matrix solution
!
@@ -219,66 +215,52 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! terms have been moved to CStateUpdateDynPatch. I think this is zeroed every
! time step, but to be safe, I'm explicitly setting it to zero here.
cf_soil%decomp_cpools_sourcesink_col(c,j,i_cwd) = 0._r8
+
+ else
!
! For the matrix solution the actual state update comes after the matrix
! multiply in SoilMatrix, but the matrix needs to be setup with
! the equivalent of above. Those changes can be here or in the
! native subroutines dealing with that field
!
- else
! phenology and dynamic land cover fluxes
+ do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%phenology_c_to_litr_c_col(c,j,i) *dt
+ end do
end if
end do
end if fates_if
-
- end do fc_loop
-
- ! litter and SOM HR fluxes
- do k = 1, ndecomp_cascade_transitions
do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- !
- ! State update without the matrix solution
- !
- if (.not. use_soil_matrixcn) then
+ !
+ ! State update without the matrix solution
+ !
+ if (.not. use_soil_matrixcn) then
+ ! litter and SOM HR fluxes
+ do k = 1, ndecomp_cascade_transitions
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_donor_pool(k)) &
- - ( cf_soil%decomp_cascade_hr_vr_col(c,j,k) + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)) *dt
- end if !not use_soil_matrixcn
- end do
- end do
- end do
- do k = 1, ndecomp_cascade_transitions
- if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
- do j = 1,nlevdecomp
- do fc = 1,num_soilc
- c = filter_soilc(fc)
- !
- ! State update without the matrix solution
- !
- if (.not. use_soil_matrixcn) then
+ - ( cf_soil%decomp_cascade_hr_vr_col(c,j,k) + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)) * dt
+ if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
cf_soil%decomp_cpools_sourcesink_col(c,j,cascade_receiver_pool(k)) &
- + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k)*dt
- end if !not use_soil_matrixcn
+ + cf_soil%decomp_cascade_ctransfer_vr_col(c,j,k) * dt
+ end if
end do
- end do
- end if
- end do
+ end if
+ end do
+
+ end do fc_loop
soilpatch_loop: do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
! phenology: transfer growth fluxes
-
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn)then
+ ! TODO slevis: improve indentation
+ if(.not. use_matrixcn)then
! NOTE: Any changes that go here MUST be applied to the matrix
! version as well
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) + cf_veg%leafc_xfer_to_leafc_patch(p)*dt
@@ -307,11 +289,11 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
end do
end if
- ! phenology: litterfall fluxes
+ ! phenology: litterfall fluxes
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) - cf_veg%leafc_to_litter_patch(p)*dt
cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) - cf_veg%frootc_to_litter_patch(p)*dt
- ! livewood turnover fluxes
+ ! livewood turnover fluxes
if (woody(ivt(p)) == 1._r8) then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) - cf_veg%livestemc_to_deadstemc_patch(p)*dt
cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) + cf_veg%livestemc_to_deadstemc_patch(p)*dt
@@ -337,55 +319,57 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
- (cf_veg%repr_structurec_to_cropprod_patch(p,k) + cf_veg%repr_structurec_to_litter_patch(p,k))*dt
end do
end if
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
- else
- ! NOTE: Changes for above that apply for matrix code are in CNPhenology EBK (11/26/2019)
-
- ! This part below MUST match exactly the code for the non-matrix part
- ! above!
- end if !not use_matrixcn
+ else
+ ! NOTE: Changes for above that apply for matrix code are in CNPhenology EBK (11/26/2019)
+
+ ! This part below MUST match exactly the code for the non-matrix part
+ ! above!
+ if (ivt(p) >= npcropmin) then
+ cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) &
+ - cf_veg%crop_seedc_to_leaf_patch(p) * dt
+ do k = repr_grain_min, repr_grain_max
+ cs_veg%cropseedc_deficit_patch(p) = cs_veg%cropseedc_deficit_patch(p) &
+ + cf_veg%repr_grainc_to_seed_patch(p,k) * dt
+ end do
+ end if
+ end if !not use_matrixcn
- check_cpool = cs_veg%cpool_patch(p)- cf_veg%psnsun_to_cpool_patch(p)*dt-cf_veg%psnshade_to_cpool_patch(p)*dt
- cpool_delta = cs_veg%cpool_patch(p)
+ check_cpool = cs_veg%cpool_patch(p)- cf_veg%psnsun_to_cpool_patch(p)*dt-cf_veg%psnshade_to_cpool_patch(p)*dt
+ cpool_delta = cs_veg%cpool_patch(p)
- ! maintenance respiration fluxes from cpool
+ ! maintenance respiration fluxes from cpool
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_xsmrpool_patch(p)*dt
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%leaf_curmr_patch(p)*dt
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%froot_curmr_patch(p)*dt
- If (woody(ivt(p)) == 1._r8) then
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_xsmrpool_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%leaf_curmr_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%froot_curmr_patch(p)*dt
+ If (woody(ivt(p)) == 1._r8) then
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livestem_curmr_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livecroot_curmr_patch(p)*dt
- end if
- if (ivt(p) >= npcropmin) then ! skip 2 generic crops
+ end if
+ if (ivt(p) >= npcropmin) then ! skip 2 generic crops
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%livestem_curmr_patch(p)*dt
do k = 1, nrepr
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%reproductive_curmr_patch(p,k)*dt
end do
- end if
+ end if
- cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_resp_patch(p)*dt
+ cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_resp_patch(p)*dt
- !RF Add in the carbon spent on uptake respiration.
- cs_veg%cpool_patch(p)= cs_veg%cpool_patch(p) - cf_veg%soilc_change_patch(p)*dt
+ !RF Add in the carbon spent on uptake respiration.
+ cs_veg%cpool_patch(p)= cs_veg%cpool_patch(p) - cf_veg%soilc_change_patch(p)*dt
- ! maintenance respiration fluxes from xsmrpool
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) + cf_veg%cpool_to_xsmrpool_patch(p)*dt
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%leaf_xsmr_patch(p)*dt
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%froot_xsmr_patch(p)*dt
- if (woody(ivt(p)) == 1._r8) then
+ ! maintenance respiration fluxes from xsmrpool
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) + cf_veg%cpool_to_xsmrpool_patch(p)*dt
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%leaf_xsmr_patch(p)*dt
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%froot_xsmr_patch(p)*dt
+ if (woody(ivt(p)) == 1._r8) then
cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%livestem_xsmr_patch(p)*dt
cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) - cf_veg%livecroot_xsmr_patch(p)*dt
- end if
+ end if
- ! allocation fluxes
- if (carbon_resp_opt == 1) then
+ ! allocation fluxes
+ if (carbon_resp_opt == 1) then
cf_veg%cpool_to_leafc_patch(p) = cf_veg%cpool_to_leafc_patch(p) - cf_veg%cpool_to_leafc_resp_patch(p)
cf_veg%cpool_to_leafc_storage_patch(p) = cf_veg%cpool_to_leafc_storage_patch(p) - &
cf_veg%cpool_to_leafc_storage_resp_patch(p)
@@ -397,20 +381,11 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_leafc_storage_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_frootc_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_frootc_storage_patch(p)*dt
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn) then
+ if(.not. use_matrixcn) then
cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) + cf_veg%cpool_to_leafc_patch(p)*dt
cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) + cf_veg%cpool_to_leafc_storage_patch(p)*dt
cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) + cf_veg%cpool_to_frootc_patch(p)*dt
cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) + cf_veg%cpool_to_frootc_storage_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -431,9 +406,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_livecrootc_storage_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_deadcrootc_patch(p)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_deadcrootc_storage_patch(p)*dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) + cf_veg%cpool_to_livestemc_patch(p)*dt
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) + cf_veg%cpool_to_livestemc_storage_patch(p)*dt
@@ -443,12 +415,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) + cf_veg%cpool_to_livecrootc_storage_patch(p)*dt
cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) + cf_veg%cpool_to_deadcrootc_patch(p)*dt
cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) + cf_veg%cpool_to_deadcrootc_storage_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -465,9 +431,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_reproductivec_patch(p,k)*dt
cs_veg%cpool_patch(p) = cs_veg%cpool_patch(p) - cf_veg%cpool_to_reproductivec_storage_patch(p,k)*dt
end do
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) + cf_veg%cpool_to_livestemc_patch(p)*dt
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) + cf_veg%cpool_to_livestemc_storage_patch(p)*dt
@@ -477,12 +440,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%reproductivec_storage_patch(p,k) = cs_veg%reproductivec_storage_patch(p,k) &
+ cf_veg%cpool_to_reproductivec_storage_patch(p,k)*dt
end do
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -545,30 +502,17 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) + cf_veg%cpool_to_gresp_storage_patch(p)*dt
! move storage pools into transfer pools
-
- !
- ! State update without the matrix solution
- !
- if(.not. use_matrixcn)then
- cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) - cf_veg%leafc_storage_to_xfer_patch(p)*dt
- cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) + cf_veg%leafc_storage_to_xfer_patch(p)*dt
- cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) - cf_veg%frootc_storage_to_xfer_patch(p)*dt
- cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) + cf_veg%frootc_storage_to_xfer_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
+ if(.not. use_matrixcn)then
+ cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) - cf_veg%leafc_storage_to_xfer_patch(p)*dt
+ cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) + cf_veg%leafc_storage_to_xfer_patch(p)*dt
+ cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) - cf_veg%frootc_storage_to_xfer_patch(p)*dt
+ cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) + cf_veg%frootc_storage_to_xfer_patch(p)*dt
else
- ! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
+ ! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
if (woody(ivt(p)) == 1._r8) then
cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) - cf_veg%gresp_storage_to_xfer_patch(p)*dt
cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) + cf_veg%gresp_storage_to_xfer_patch(p)*dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) - cf_veg%livestemc_storage_to_xfer_patch(p)*dt
cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) + cf_veg%livestemc_storage_to_xfer_patch(p)*dt
@@ -578,21 +522,12 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) + cf_veg%livecrootc_storage_to_xfer_patch(p)*dt
cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p)- cf_veg%deadcrootc_storage_to_xfer_patch(p)*dt
cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) + cf_veg%deadcrootc_storage_to_xfer_patch(p)*dt
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
! lines here for consistency; the transfer terms are zero
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
! lines here for consistency; the transfer terms are zero
cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) - cf_veg%livestemc_storage_to_xfer_patch(p)*dt
@@ -603,12 +538,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%reproductivec_xfer_patch(p,k) = cs_veg%reproductivec_xfer_patch(p,k) &
+ cf_veg%reproductivec_storage_to_xfer_patch(p,k)*dt
end do
- !
- ! For the matrix solution the actual state update comes after the matrix
- ! multiply in VegMatrix, but the matrix needs to be setup with
- ! the equivalent of above. Those changes can be here or in the
- ! native subroutines dealing with that field
- !
else
! NOTE: The equivalent changes for matrix code are in CNPhenology EBK (11/26/2019)
end if !not use_matrixcn
@@ -631,15 +560,14 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
! bounds. Zeroing out these small pools and putting them into the flux to the
! atmosphere solved many of the crop isotope problems
- ! Instantly release XSMRPOOL to atmosphere
if ( .not. dribble_crophrv_xsmrpool_2atm ) then
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%xsmrpool_patch(p)/dt
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%cpool_patch(p)/dt
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) + cs_veg%frootc_patch(p)/dt
+ else
+ cf_veg%xsmrpool_to_atm_patch(p) = cf_veg%xsmrpool_to_atm_patch(p) &
+ + cs_veg%frootc_patch(p) * matrix_update_phc(p,cf_veg%ifroot_to_iout_ph,1._r8/dt,dt,cnveg_carbonflux_inst,.true.,.true.)
end if
! Save xsmrpool, cpool, frootc to loss state variable for
! dribbling
@@ -650,16 +578,13 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) + &
cs_veg%xsmrpool_patch(p) + &
cs_veg%cpool_patch(p)
- !
- ! State update without the matrix solution
- !
if(.not. use_matrixcn)then
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) + cs_veg%frootc_patch(p)
+ else
+ cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) &
+ + cs_veg%frootc_patch(p) * matrix_update_phc(p,cf_veg%ifroot_to_iout_ph,1._r8/dt,dt,cnveg_carbonflux_inst,.true.,.true.)
end if
end if
- !
- ! State update without the matrix solution
- !
if (.not. use_matrixcn) then
cs_veg%frootc_patch(p) = 0._r8
end if
@@ -675,7 +600,6 @@ subroutine CStateUpdate1( num_soilc, filter_soilc, num_soilp, filter_soilp, &
cs_veg%xsmrpool_loss_patch(p) = cs_veg%xsmrpool_loss_patch(p) - cf_veg%xsmrpool_to_atm_patch(p) * dt
end if
end if
-
end do soilpatch_loop ! end of patch loop
end associate
diff --git a/src/biogeochem/CNCStateUpdate2Mod.F90 b/src/biogeochem/CNCStateUpdate2Mod.F90
index 6ecc4893e3..5fb7a283e9 100644
--- a/src/biogeochem/CNCStateUpdate2Mod.F90
+++ b/src/biogeochem/CNCStateUpdate2Mod.F90
@@ -97,9 +97,13 @@ subroutine CStateUpdate2(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for soil-matrix
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%gap_mortality_c_to_litr_c_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%gap_mortality_c_to_cwdc_col(c,j) * dt
end if !soil_matrix
end do
end do
@@ -237,9 +241,13 @@ subroutine CStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for matrix method
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%harvest_c_to_litr_c_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%harvest_c_to_cwdc_col(c,j) * dt
end if
! wood to product pools - states updated in CNProducts
@@ -327,7 +335,8 @@ end subroutine CStateUpdate2h
!-----------------------------------------------------------------------
subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst)
+ cnveg_carbonflux_inst, cnveg_carbonstate_inst, &
+ soilbiogeochem_carbonstate_inst, soilbiogeochem_carbonflux_inst)
!
! !DESCRIPTION:
! Update all the prognostic carbon state
@@ -340,6 +349,7 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
integer , intent(in) :: filter_soilp(:) ! filter for soil patches
type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst
type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst
type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst
!
! !LOCAL VARIABLES:
@@ -351,6 +361,7 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
associate( &
cf_veg => cnveg_carbonflux_inst , &
cs_veg => cnveg_carbonstate_inst , &
+ cf_soil => soilbiogeochem_carbonflux_inst, &
cs_soil => soilbiogeochem_carbonstate_inst &
)
@@ -362,15 +373,27 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fc = 1,num_soilc
c = filter_soilc(fc)
- ! column gross unrepresented landcover change fluxes
- do i = i_litr_min, i_litr_max
- cs_soil%decomp_cpools_vr_col(c,j,i) = &
- cs_soil%decomp_cpools_vr_col(c,j,i) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
- end do
- cs_soil%decomp_cpools_vr_col(c,j,i_cwd) = &
- cs_soil%decomp_cpools_vr_col(c,j,i_cwd) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
+ if (.not. use_soil_matrixcn)then
+ ! column gross unrepresented landcover change fluxes
+ do i = i_litr_min, i_litr_max
+ cs_soil%decomp_cpools_vr_col(c,j,i) = &
+ cs_soil%decomp_cpools_vr_col(c,j,i) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
+ end do
+ cs_soil%decomp_cpools_vr_col(c,j,i_cwd) = &
+ cs_soil%decomp_cpools_vr_col(c,j,i_cwd) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
- ! wood to product pools - states updated in CNProducts
+ ! wood to product pools - states updated in CNProducts
+ else
+ ! Match above for soil-matrix
+ do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + cf_veg%gru_c_to_litr_c_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + cf_veg%gru_c_to_cwdc_col(c,j) * dt
+ end if !soil_matrix
end do
end do
@@ -378,59 +401,69 @@ subroutine CStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fp = 1,num_soilp
p = filter_soilp(fp)
- ! patch-level carbon fluxes from gross unrepresented landcover change mortality
- ! displayed pools
- cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) &
- - cf_veg%gru_leafc_to_litter_patch(p) * dt
- cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) &
- - cf_veg%gru_frootc_to_litter_patch(p) * dt
- cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) &
- - cf_veg%gru_livestemc_to_atm_patch(p) * dt
- cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
- - cf_veg%gru_deadstemc_to_atm_patch(p) * dt
- cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
- - cf_veg%gru_wood_productc_gain_patch(p) * dt
- cs_veg%livecrootc_patch(p) = cs_veg%livecrootc_patch(p) &
- - cf_veg%gru_livecrootc_to_litter_patch(p) * dt
- cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) &
- - cf_veg%gru_deadcrootc_to_litter_patch(p) * dt
-
! xsmrpool
- cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) &
+ cs_veg%xsmrpool_patch(p) = cs_veg%xsmrpool_patch(p) &
- cf_veg%gru_xsmrpool_to_atm_patch(p) * dt
-
- ! storage pools
- cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) &
- - cf_veg%gru_leafc_storage_to_atm_patch(p) * dt
- cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) &
- - cf_veg%gru_frootc_storage_to_atm_patch(p) * dt
- cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) &
- - cf_veg%gru_livestemc_storage_to_atm_patch(p) * dt
- cs_veg%deadstemc_storage_patch(p) = cs_veg%deadstemc_storage_patch(p) &
- - cf_veg%gru_deadstemc_storage_to_atm_patch(p) * dt
- cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) &
- - cf_veg%gru_livecrootc_storage_to_atm_patch(p) * dt
- cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) &
- - cf_veg%gru_deadcrootc_storage_to_atm_patch(p) * dt
- cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) &
+ ! gresp storage pool
+ cs_veg%gresp_storage_patch(p) = cs_veg%gresp_storage_patch(p) &
- cf_veg%gru_gresp_storage_to_atm_patch(p) * dt
-
- ! transfer pools
- cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) &
- - cf_veg%gru_leafc_xfer_to_atm_patch(p) * dt
- cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) &
- - cf_veg%gru_frootc_xfer_to_atm_patch(p) * dt
- cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) &
- - cf_veg%gru_livestemc_xfer_to_atm_patch(p) * dt
- cs_veg%deadstemc_xfer_patch(p) = cs_veg%deadstemc_xfer_patch(p) &
- - cf_veg%gru_deadstemc_xfer_to_atm_patch(p) * dt
- cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) &
- - cf_veg%gru_livecrootc_xfer_to_atm_patch(p) * dt
- cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) &
- - cf_veg%gru_deadcrootc_xfer_to_atm_patch(p) * dt
- cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) &
+ ! gresp transfer pool
+ cs_veg%gresp_xfer_patch(p) = cs_veg%gresp_xfer_patch(p) &
- cf_veg%gru_gresp_xfer_to_atm_patch(p) * dt
+ ! patch-level carbon fluxes from gross unrepresented landcover change mortality
+ !
+ ! State update without the matrix solution
+ !
+ if(.not. use_matrixcn)then
+ ! displayed pools
+ cs_veg%leafc_patch(p) = cs_veg%leafc_patch(p) &
+ - cf_veg%gru_leafc_to_litter_patch(p) * dt
+ cs_veg%frootc_patch(p) = cs_veg%frootc_patch(p) &
+ - cf_veg%gru_frootc_to_litter_patch(p) * dt
+ cs_veg%livestemc_patch(p) = cs_veg%livestemc_patch(p) &
+ - cf_veg%gru_livestemc_to_atm_patch(p) * dt
+ cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
+ - cf_veg%gru_deadstemc_to_atm_patch(p) * dt
+ cs_veg%deadstemc_patch(p) = cs_veg%deadstemc_patch(p) &
+ - cf_veg%gru_wood_productc_gain_patch(p) * dt
+ cs_veg%livecrootc_patch(p) = cs_veg%livecrootc_patch(p) &
+ - cf_veg%gru_livecrootc_to_litter_patch(p) * dt
+ cs_veg%deadcrootc_patch(p) = cs_veg%deadcrootc_patch(p) &
+ - cf_veg%gru_deadcrootc_to_litter_patch(p) * dt
+
+ ! storage pools
+ cs_veg%leafc_storage_patch(p) = cs_veg%leafc_storage_patch(p) &
+ - cf_veg%gru_leafc_storage_to_atm_patch(p) * dt
+ cs_veg%frootc_storage_patch(p) = cs_veg%frootc_storage_patch(p) &
+ - cf_veg%gru_frootc_storage_to_atm_patch(p) * dt
+ cs_veg%livestemc_storage_patch(p) = cs_veg%livestemc_storage_patch(p) &
+ - cf_veg%gru_livestemc_storage_to_atm_patch(p) * dt
+ cs_veg%deadstemc_storage_patch(p) = cs_veg%deadstemc_storage_patch(p) &
+ - cf_veg%gru_deadstemc_storage_to_atm_patch(p) * dt
+ cs_veg%livecrootc_storage_patch(p) = cs_veg%livecrootc_storage_patch(p) &
+ - cf_veg%gru_livecrootc_storage_to_atm_patch(p) * dt
+ cs_veg%deadcrootc_storage_patch(p) = cs_veg%deadcrootc_storage_patch(p) &
+ - cf_veg%gru_deadcrootc_storage_to_atm_patch(p) * dt
+
+ ! transfer pools
+ cs_veg%leafc_xfer_patch(p) = cs_veg%leafc_xfer_patch(p) &
+ - cf_veg%gru_leafc_xfer_to_atm_patch(p) * dt
+ cs_veg%frootc_xfer_patch(p) = cs_veg%frootc_xfer_patch(p) &
+ - cf_veg%gru_frootc_xfer_to_atm_patch(p) * dt
+ cs_veg%livestemc_xfer_patch(p) = cs_veg%livestemc_xfer_patch(p) &
+ - cf_veg%gru_livestemc_xfer_to_atm_patch(p) * dt
+ cs_veg%deadstemc_xfer_patch(p) = cs_veg%deadstemc_xfer_patch(p) &
+ - cf_veg%gru_deadstemc_xfer_to_atm_patch(p) * dt
+ cs_veg%livecrootc_xfer_patch(p) = cs_veg%livecrootc_xfer_patch(p) &
+ - cf_veg%gru_livecrootc_xfer_to_atm_patch(p) * dt
+ cs_veg%deadcrootc_xfer_patch(p) = cs_veg%deadcrootc_xfer_patch(p) &
+ - cf_veg%gru_deadcrootc_xfer_to_atm_patch(p) * dt
+
+ else
+ ! NB (slevis) The matrix equivalent of the above is in
+ ! dynGrossUnrepMod::CNGrossUnrep*
+ end if
end do ! end of patch loop
end associate
diff --git a/src/biogeochem/CNCStateUpdate3Mod.F90 b/src/biogeochem/CNCStateUpdate3Mod.F90
index 55d647866f..4b4d41fbe3 100644
--- a/src/biogeochem/CNCStateUpdate3Mod.F90
+++ b/src/biogeochem/CNCStateUpdate3Mod.F90
@@ -92,9 +92,12 @@ subroutine CStateUpdate3( num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Match above for matrix terms
! patch-level wood to column-level CWD (uncombusted wood)
-
+ cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) = cf_soil%matrix_Cinput%V(c,j+(i_cwd-1)*nlevdecomp) + &
+ cf_veg%fire_mortality_c_to_cwdc_col(c,j) * dt
! patch-level wood to column-level litter (uncombusted wood)
do i = i_litr_min, i_litr_max
+ cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) = cf_soil%matrix_Cinput%V(c,j+(i-1)*nlevdecomp) + &
+ cf_veg%m_c_to_litr_fire_col(c,j,i)* dt
end do
end if
end do
diff --git a/src/biogeochem/CNDriverMod.F90 b/src/biogeochem/CNDriverMod.F90
index b23019eb23..c5deb1e86a 100644
--- a/src/biogeochem/CNDriverMod.F90
+++ b/src/biogeochem/CNDriverMod.F90
@@ -6,12 +6,12 @@ module CNDriverMod
!
! !USES:
use shr_kind_mod , only : r8 => shr_kind_r8
- use clm_varctl , only : use_c13, use_c14, use_fates, use_fates_bgc, use_dynroot
+ use clm_varctl , only : use_c13, use_c14, use_fates, use_fates_bgc
use dynSubgridControlMod , only : get_do_harvest, get_do_grossunrep
use decompMod , only : bounds_type
use perf_mod , only : t_startf, t_stopf
use clm_varctl , only : use_nitrif_denitrif, use_nguardrail
- use clm_varctl , only : iulog, use_crop, use_crop_agsys, use_cn
+ use clm_varctl , only : use_crop, use_crop_agsys, use_cn
use SoilBiogeochemDecompCascadeConType, only : mimics_decomp, century_decomp, decomp_method
use CNSharedParamsMod , only : use_fun
use CNVegStateType , only : cnveg_state_type
@@ -85,7 +85,7 @@ end subroutine CNDriverInit
!-----------------------------------------------------------------------
subroutine CNDriverNoLeaching(bounds, &
- num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
+ num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
num_pcropp, filter_pcropp, num_soilnopcropp, filter_soilnopcropp, &
num_actfirec, filter_actfirec, num_actfirep, filter_actfirep, &
num_exposedvegp, filter_exposedvegp, num_noexposedvegp, filter_noexposedvegp, &
@@ -103,8 +103,8 @@ subroutine CNDriverNoLeaching(bounds,
active_layer_inst, clm_fates, &
atm2lnd_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst, &
wateratm2lndbulk_inst, canopystate_inst, soilstate_inst, temperature_inst, &
- soil_water_retention_curve, crop_inst, ch4_inst, &
- dgvs_inst, photosyns_inst, saturated_excess_runoff_inst, energyflux_inst, &
+ soil_water_retention_curve, crop_inst, ch4_inst, &
+ dgvs_inst, photosyns_inst, saturated_excess_runoff_inst, energyflux_inst, &
nutrient_competition_method, cnfire_method, dribble_crophrv_xsmrpool_2atm)
!
! !DESCRIPTION:
@@ -147,7 +147,6 @@ subroutine CNDriverNoLeaching(bounds,
use SoilBiogeochemNitrifDenitrifMod , only: SoilBiogeochemNitrifDenitrif
use SoilBiogeochemNStateUpdate1Mod , only: SoilBiogeochemNStateUpdate1
use NutrientCompetitionMethodMod , only: nutrient_competition_method_type
- use CNRootDynMod , only: CNRootDyn
use CNPrecisionControlMod , only: CNPrecisionControl
!
! !ARGUMENTS:
@@ -564,20 +563,6 @@ subroutine CNDriverNoLeaching(bounds,
call t_stopf('CNGResp')
- !--------------------------------------------
- ! Dynamic Roots
- !--------------------------------------------
-
- if( use_dynroot ) then
- call t_startf('CNRootDyn')
-
- call CNRootDyn(bounds, num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, &
- cnveg_state_inst, crop_inst, soilstate_inst, soilbiogeochem_nitrogenstate_inst)
-
- call t_stopf('CNRootDyn')
- end if
-
!--------------------------------------------------------------------------
! CNUpdate0
! The state updates are still called for the matrix solution (use_matrixn
@@ -609,12 +594,9 @@ subroutine CNDriverNoLeaching(bounds,
c14_cnveg_carbonstate_inst, cnveg_nitrogenstate_inst)
call t_stopf('CNPrecisionControl')
end if
- !--------------------------------------------------------------------------
+ !--------------------------------------------
! Update1
- ! The state updates are still called for the matrix solution (use_matrixn
- ! and use_soil_matrixcn) but most of the state updates are done after
- ! the matrix multiply in VegMatrix and SoilMatrix.
- !--------------------------------------------------------------------------
+ !--------------------------------------------
call t_startf('CNUpdate1')
@@ -830,18 +812,22 @@ subroutine CNDriverNoLeaching(bounds,
end if
call CStateUpdate2g( num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_carbonflux_inst, cnveg_carbonstate_inst, soilbiogeochem_carbonstate_inst)
+ cnveg_carbonflux_inst, cnveg_carbonstate_inst, &
+ soilbiogeochem_carbonstate_inst, soilbiogeochem_carbonflux_inst)
if ( use_c13 ) then
call CStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, c13_soilbiogeochem_carbonstate_inst)
+ c13_cnveg_carbonflux_inst, c13_cnveg_carbonstate_inst, &
+ c13_soilbiogeochem_carbonstate_inst, c13_soilbiogeochem_carbonflux_inst)
end if
if ( use_c14 ) then
call CStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, c14_soilbiogeochem_carbonstate_inst)
+ c14_cnveg_carbonflux_inst, c14_cnveg_carbonstate_inst, &
+ c14_soilbiogeochem_carbonstate_inst, c14_soilbiogeochem_carbonflux_inst)
end if
call NStateUpdate2g(num_bgc_soilc, filter_bgc_soilc, num_bgc_vegp, filter_bgc_vegp, &
- cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst)
+ cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ soilbiogeochem_nitrogenstate_inst, soilbiogeochem_nitrogenflux_inst)
call t_stopf('CNUpdate2')
@@ -1040,9 +1026,11 @@ subroutine CNDriverLeaching(bounds, &
use SoilBiogeochemNLeachingMod, only: SoilBiogeochemNLeaching
use CNNStateUpdate3Mod , only: NStateUpdate3
use CNNStateUpdate3Mod , only: NStateUpdateLeaching
+ use CNVegMatrixMod , only: CNVegMatrix
+ use CNSoilMatrixMod , only: CNSoilMatrix
use clm_time_manager , only: is_first_step_of_this_run_segment,is_beg_curr_year,is_end_curr_year,get_curr_date
use CNSharedParamsMod , only: use_matrixcn
- use SoilBiogeochemDecompCascadeConType , only : use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType, only: use_soil_matrixcn
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -1088,10 +1076,6 @@ subroutine CNDriverLeaching(bounds, &
soilbiogeochem_nitrogenflux_inst, soilbiogeochem_nitrogenstate_inst)
call t_stopf('SoilBiogeochemNLeaching')
-
-
-
-
! Nitrogen state variable update, mortality fluxes.
if(num_bgc_vegp>0)then
call t_startf('NUpdate3')
@@ -1108,14 +1092,23 @@ subroutine CNDriverLeaching(bounds, &
if ( use_matrixcn ) then
call t_startf('CNVMatrix')
- ! Matrix cn code will go here:
- call t_stopf( 'CNVMatrix')
+ call CNVegMatrix(bounds, num_bgc_vegp, filter_bgc_vegp(1:num_bgc_vegp), &
+ num_actfirep, filter_actfirep, cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, &
+ cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_state_inst,soilbiogeochem_nitrogenflux_inst, &
+ c13_cnveg_carbonstate_inst, c14_cnveg_carbonstate_inst, c13_cnveg_carbonflux_inst, c14_cnveg_carbonflux_inst)
+ call t_stopf('CNVMatrix')
end if
- if ( use_soil_matrixcn ) then
+ if(use_soil_matrixcn)then
call t_startf('CNSoilMatrix')
- ! Soil Matrix cn code will go here:
- call t_stopf( 'CNSoilMatrix')
+ call CNSoilMatrix(bounds,num_bgc_soilc, filter_bgc_soilc(1:num_bgc_soilc), num_actfirec, filter_actfirec, &
+ cnveg_carbonflux_inst,soilbiogeochem_carbonstate_inst, &
+ soilbiogeochem_carbonflux_inst,soilbiogeochem_state_inst, &
+ cnveg_nitrogenflux_inst, soilbiogeochem_nitrogenflux_inst, &
+ soilbiogeochem_nitrogenstate_inst,c13_soilbiogeochem_carbonstate_inst,&
+ c13_soilbiogeochem_carbonflux_inst,c14_soilbiogeochem_carbonstate_inst,&
+ c14_soilbiogeochem_carbonflux_inst)
+ call t_stopf('CNSoilMatrix')
end if
end subroutine CNDriverLeaching
diff --git a/src/biogeochem/CNFUNMod.F90 b/src/biogeochem/CNFUNMod.F90
index bb750af2fd..dde666c1f7 100644
--- a/src/biogeochem/CNFUNMod.F90
+++ b/src/biogeochem/CNFUNMod.F90
@@ -26,7 +26,7 @@ module CNFUNMod
use pftconMod , only : pftcon, npcropmin
use decompMod , only : bounds_type
use clm_varctl , only : use_nitrif_denitrif,use_flexiblecn
- use CNSharedParamsMod , only : use_matrixcn
+ use CNSharedParamsMod , only : use_matrixcn
use abortutils , only : endrun
use CNVegstateType , only : cnveg_state_type
use CNVegCarbonStateType , only : cnveg_carbonstate_type
@@ -218,6 +218,7 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
use PatchType , only : patch
use subgridAveMod , only : p2c
use pftconMod , only : npcropmin
+ use CNVegMatrixMod , only : matrix_update_phn
!
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds
@@ -621,6 +622,7 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
leafc_change => cnveg_carbonflux_inst%leafc_change_patch , & ! Output: [real(r8)
! (:) ] Used C from the leaf (gC/m2/s)
leafn_storage_to_xfer => cnveg_nitrogenflux_inst%leafn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Input: [integer]
plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Iutput: [real(r8) (:)
! ] N flux required to support initial GPP (gN/m2/s)
plant_ndemand_retrans => cnveg_nitrogenflux_inst%plant_ndemand_retrans_patch , & ! Output: [real(r8) (:)
@@ -1451,11 +1453,14 @@ subroutine CNFUN(bounds,num_soilc, filter_soilc,num_soilp&
Npassive(p) = n_passive_acc(p)/dt
Nfix(p) = n_fix_acc_total(p)/dt
retransn_to_npool(p) = n_retrans_acc_total(p)/dt
- ! Without matrix solution
if(.not. use_matrixcn)then
free_retransn_to_npool(p) = free_nretrans(p)/dt
- ! With matrix solution (when it comes in)
else
+ if(retransn(p) .gt. 0)then
+ free_retransn_to_npool(p) = retransn(p) * matrix_update_phn(p,iretransn_to_iout,free_nretrans(p)/dt/retransn(p),dt,cnveg_nitrogenflux_inst,.true.,.true.)
+ else
+ free_retransn_to_npool(p) = 0._r8
+ end if
end if
! this is the N that comes off leaves.
Nretrans(p) = retransn_to_npool(p) + free_retransn_to_npool(p)
diff --git a/src/biogeochem/CNFireBaseMod.F90 b/src/biogeochem/CNFireBaseMod.F90
index f1d488eb22..7cc7750809 100644
--- a/src/biogeochem/CNFireBaseMod.F90
+++ b/src/biogeochem/CNFireBaseMod.F90
@@ -451,6 +451,13 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
use pftconMod , only: nc3crop
use dynSubgridControlMod , only: run_has_transient_landcover
use clm_varpar , only: nlevdecomp_full, ndecomp_pools, nlevdecomp, i_litr_max, i_met_lit
+ use clm_varpar , only: ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,iretransn,ioutc,ioutn
+ use CNVegMatrixMod , only: matrix_update_fic, matrix_update_fin
+ !
! !ARGUMENTS:
class(cnfire_base_type) :: this
type(bounds_type) , intent(in) :: bounds
@@ -683,7 +690,48 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_xfer_to_litter_fire => cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_retransn_to_litter_fire => cnveg_nitrogenflux_inst%m_retransn_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_decomp_npools_to_fire_vr => cnveg_nitrogenflux_inst%m_decomp_npools_to_fire_vr_col , & ! Output: [real(r8) (:,:,:) ] VR decomp. N fire loss (gN/m3/s)
- m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col & ! Output: [real(r8) (:,:,:) ]
+ m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col , & ! Output: [real(r8) (:,:) ]
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi & ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
)
transient_landcover = run_has_transient_landcover()
@@ -696,7 +744,7 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
!
! patch loop
!
- num_actfirep = 0 ! Initialize active fire patch filter to zero
+ num_actfirep = 0
do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
@@ -722,7 +770,6 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! carbon fluxes
m = spinup_factor_deadwood
- ! For patches with active fire add to active fire filter
if(f /= 0)then
num_actfirep = num_actfirep + 1
filter_actfirep(num_actfirep) = p
@@ -773,6 +820,45 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * f * cc_other(patch%itype(p))
m_retransn_to_fire(p) = retransn(p) * f * cc_other(patch%itype(p))
+ else
+ m_leafc_to_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_retransn_to_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
! mortality due to fire
! carbon pools
@@ -920,6 +1006,88 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
(1._r8 - cc_other(patch%itype(p))) * &
fm_other(patch%itype(p))
+ else
+ m_leafc_to_litter_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_litter_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_litter_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_litter_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_litter_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_litter_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_deadstemc_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_ideadstem_fic,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_litter_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_litter_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_litter_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_litter_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic, &
+ f * fm_root(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_litter_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_litter_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_litter_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_litter_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_litter_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_deadcrootc_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_ideadcroot_fic,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_litter_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_litter_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_litter_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_litter_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_litter_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_litter_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_litter_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_litter_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_litter_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_deadstemn_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_ideadstem_fin,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_litter_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_litter_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_litter_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_litter_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin, &
+ f * fm_root(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_litter_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_litter_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_litter_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_litter_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_litter_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_deadcrootn_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_ideadcroot_fin,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_litter_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_litter_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_litter_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
if (use_cndv) then
@@ -1022,13 +1190,12 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! vertically-resolved decomposing C/N fire loss
! column loop
!
- num_actfirec = 0 ! Initialize active fire column filter to zero
+ num_actfirec = 0
do fc = 1,num_soilc
c = filter_soilc(fc)
f = farea_burned(c)
- ! If fire is active add to active fire filter
if(f /= 0 .or. f /= baf_crop(c))then
num_actfirec = num_actfirec + 1
filter_actfirec(num_actfirec) = c
@@ -1040,14 +1207,24 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * f * &
cmb_cmplt_fact_litter
if(use_soil_matrixcn)then! matrix is the same for C and N in the fire.
- ! Apply above for matrix solution
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - f * cmb_cmplt_fact_litter * dt
+ end associate
end if
end if
if ( is_cwd(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * &
(f-baf_crop(c)) * cmb_cmplt_fact_cwd
if(use_soil_matrixcn)then
- ! Apply above for matrix solution
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ] (gC/m3/step) VR deomp. C fire loss in matrix representation
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) &
+ - (f-baf_crop(c)) * cmb_cmplt_fact_cwd * dt
+ end associate
end if
end if
end do
diff --git a/src/biogeochem/CNFireLi2014Mod.F90 b/src/biogeochem/CNFireLi2014Mod.F90
index 6ea21a530b..6bfa17a143 100644
--- a/src/biogeochem/CNFireLi2014Mod.F90
+++ b/src/biogeochem/CNFireLi2014Mod.F90
@@ -46,6 +46,7 @@ module CNFireLi2014Mod
use PatchType , only : patch
use FireMethodType , only : fire_method_type
use CNFireBaseMod , only : cnfire_base_type, cnfire_const, cnfire_params
+ use CNVegMatrixMod , only : matrix_update_fic, matrix_update_fin
!
implicit none
private
@@ -654,6 +655,11 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
use clm_varpar , only: i_met_lit, i_litr_max
use pftconMod , only: nc3crop
use dynSubgridControlMod , only: run_has_transient_landcover
+ use clm_varpar , only: ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,iretransn,ioutc,ioutn
!
! !ARGUMENTS:
class(cnfire_li2014_type) :: this
@@ -884,7 +890,48 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_xfer_to_litter_fire => cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_retransn_to_litter_fire => cnveg_nitrogenflux_inst%m_retransn_to_litter_fire_patch , & ! Output: [real(r8) (:) ]
m_decomp_npools_to_fire_vr => cnveg_nitrogenflux_inst%m_decomp_npools_to_fire_vr_col , & ! Output: [real(r8) (:,:,:) ] VR decomp. N fire loss (gN/m3/s)
- m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col & ! Output: [real(r8) (:,:,:) ]
+ m_n_to_litr_fire => cnveg_nitrogenflux_inst%m_n_to_litr_fire_col , & ! Output: [real(r8) (:,:) ]
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pool
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , & ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , & ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , & ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi & ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
)
transient_landcover = run_has_transient_landcover()
@@ -897,7 +944,7 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
!
! patch loop
!
- num_actfirep = 0 ! Initialize active fire patch filter to zero
+ num_actfirep = 0
do fp = 1,num_soilp
p = filter_soilp(fp)
c = patch%column(p)
@@ -923,7 +970,6 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! carbon fluxes
m = spinup_factor_deadwood
- ! For patches with active fire add to active fire filter
if(f /= 0)then
num_actfirep = num_actfirep + 1
filter_actfirep(num_actfirep) = p
@@ -975,6 +1021,45 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * f * cc_other(patch%itype(p))
m_retransn_to_fire(p) = retransn(p) * f * cc_other(patch%itype(p))
+ else
+ m_leafc_to_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic ,f * 0._r8 ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic ,f * cc_other(patch%itype(p)) ,dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin ,f * cc_leaf(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin ,f * cc_lstem(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin ,f * cc_dstem(patch%itype(p))*m,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin ,f * cc_other(patch%itype(p)) ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_retransn_to_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin ,f * 0._r8 ,dt,cnveg_nitrogenflux_inst,.True.,.True.)
end if
! mortality due to fire
! carbon pools
@@ -1122,6 +1207,94 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
(1._r8 - cc_other(patch%itype(p))) * &
fm_other(patch%itype(p))
+ else
+ m_leafc_to_litter_fire(p) = leafc(p) * matrix_update_fic(p,ileaf_to_iout_fic, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_storage_to_litter_fire(p) = leafc_storage(p) * matrix_update_fic(p,ileafst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_leafc_xfer_to_litter_fire(p) = leafc_xfer(p) * matrix_update_fic(p,ileafxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_litter_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_iout_fic, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_storage_to_litter_fire(p) = livestemc_storage(p) * matrix_update_fic(p,ilivestemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_xfer_to_litter_fire(p) = livestemc_xfer(p) * matrix_update_fic(p,ilivestemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livestemc_to_deadstemc_fire(p) = livestemc(p) * matrix_update_fic(p,ilivestem_to_ideadstem_fic,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_to_litter_fire(p) = deadstemc(p) * matrix_update_fic(p,ideadstem_to_iout_fic, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_storage_to_litter_fire(p) = deadstemc_storage(p) * matrix_update_fic(p,ideadstemst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadstemc_xfer_to_litter_fire(p) = deadstemc_xfer(p) * matrix_update_fic(p,ideadstemxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_to_litter_fire(p) = frootc(p) * matrix_update_fic(p,ifroot_to_iout_fic, &
+ f * fm_root(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_storage_to_litter_fire(p) = frootc_storage(p) * matrix_update_fic(p,ifrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_frootc_xfer_to_litter_fire(p) = frootc_xfer(p) * matrix_update_fic(p,ifrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_litter_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_iout_fic, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_storage_to_litter_fire(p) = livecrootc_storage(p) * matrix_update_fic(p,ilivecrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_xfer_to_litter_fire(p) = livecrootc_xfer(p) * matrix_update_fic(p,ilivecrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_livecrootc_to_deadcrootc_fire(p) = livecrootc(p) * matrix_update_fic(p,ilivecroot_to_ideadcroot_fic,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_to_litter_fire(p) = deadcrootc(p) * matrix_update_fic(p,ideadcroot_to_iout_fic, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_storage_to_litter_fire(p) = deadcrootc_storage(p) * matrix_update_fic(p,ideadcrootst_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+ m_deadcrootc_xfer_to_litter_fire(p) = deadcrootc_xfer(p) * matrix_update_fic(p,ideadcrootxf_to_iout_fic, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_carbonflux_inst,.True.,.True.)
+
+ m_leafn_to_litter_fire(p) = leafn(p) * matrix_update_fin(p,ileaf_to_iout_fin, &
+ f * (1._r8 - cc_leaf(patch%itype(p))) * fm_leaf(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_storage_to_litter_fire(p) = leafn_storage(p) * matrix_update_fin(p,ileafst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_leafn_xfer_to_litter_fire(p) = leafn_xfer(p) * matrix_update_fin(p,ileafxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_litter_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_iout_fin, &
+ f * (1._r8 - cc_lstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_storage_to_litter_fire(p) = livestemn_storage(p) * matrix_update_fin(p,ilivestemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_xfer_to_litter_fire(p) = livestemn_xfer(p) * matrix_update_fin(p,ilivestemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livestemn_to_deadstemn_fire(p) = livestemn(p) * matrix_update_fin(p,ilivestem_to_ideadstem_fin,&
+ f * (1._r8 - cc_lstem(patch%itype(p))) * (fm_lstem(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_to_litter_fire(p) = deadstemn(p) * matrix_update_fin(p,ideadstem_to_iout_fin, &
+ f * (1._r8 - cc_dstem(patch%itype(p))) * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_storage_to_litter_fire(p) = deadstemn_storage(p) * matrix_update_fin(p,ideadstemst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadstemn_xfer_to_litter_fire(p) = deadstemn_xfer(p) * matrix_update_fin(p,ideadstemxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_to_litter_fire(p) = frootn(p) * matrix_update_fin(p,ifroot_to_iout_fin, &
+ f * fm_root(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_storage_to_litter_fire(p) = frootn_storage(p) * matrix_update_fin(p,ifrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_frootn_xfer_to_litter_fire(p) = frootn_xfer(p) * matrix_update_fin(p,ifrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_litter_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_iout_fin, &
+ f * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_storage_to_litter_fire(p) = livecrootn_storage(p) * matrix_update_fin(p,ilivecrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_xfer_to_litter_fire(p) = livecrootn_xfer(p) * matrix_update_fin(p,ilivecrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_livecrootn_to_deadcrootn_fire(p) = livecrootn(p) * matrix_update_fin(p,ilivecroot_to_ideadcroot_fin,&
+ f * (fm_lroot(patch%itype(p))-fm_droot(patch%itype(p))),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_to_litter_fire(p) = deadcrootn(p) * matrix_update_fin(p,ideadcroot_to_iout_fin, &
+ f * m * fm_droot(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_storage_to_litter_fire(p) = deadcrootn_storage(p) * matrix_update_fin(p,ideadcrootst_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+ m_deadcrootn_xfer_to_litter_fire(p) = deadcrootn_xfer(p) * matrix_update_fin(p,ideadcrootxf_to_iout_fin, &
+ f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+!KO
+ ! This term is not currently in the matrix code version of CNFireBaseMod, but there are non-matrix terms for this
+ ! in CNFireLi2014Mod and in CNFireBaseMod in ctsm5.1.dev012. I'm not adding it here because tests are passing without it.
+!KO m_retransn_to_litter_fire(p) = retransn(p) * matrix_update_fin(p,iretransn_to_iout_fin, &
+!KO f * (1._r8 - cc_other(patch%itype(p))) * fm_other(patch%itype(p)),dt,cnveg_nitrogenflux_inst,.True.,.True.)
+!KO
end if
if (use_cndv) then
@@ -1218,13 +1391,12 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
! vertically-resolved decomposing C/N fire loss
! column loop
!
- num_actfirec = 0 ! Initialize active fire column filter to zero
+ num_actfirec = 0
do fc = 1,num_soilc
c = filter_soilc(fc)
f = farea_burned(c)
- ! If fire is active add to active fire filter
if(f .ne. 0 .or. f .ne. baf_crop(c))then
num_actfirec = num_actfirec + 1
filter_actfirec(num_actfirec) = c
@@ -1237,15 +1409,23 @@ subroutine CNFireFluxes (this, bounds, num_soilc, filter_soilc, num_soilp, filte
do l = 1, ndecomp_pools
if ( is_litter(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * f * 0.5_r8
- ! Apply the above for the matrix solution
if(use_soil_matrixcn)then
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ]
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) - f * 0.5_r8 * dt
+ end associate
end if
end if
if ( is_cwd(l) ) then
m_decomp_cpools_to_fire_vr(c,j,l) = decomp_cpools_vr(c,j,l) * &
(f-baf_crop(c)) * 0.25_r8
- ! Apply the above for the matrix solution
if(use_soil_matrixcn)then
+ associate( &
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col & ! Output: [real(r8) (:,:) ]
+ )
+ matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) = matrix_decomp_fire_k(c,j+nlevdecomp*(l-1)) - (f-baf_crop(c)) * 0.25_r8 * dt
+ end associate
end if
end if
end do
diff --git a/src/biogeochem/CNGapMortalityMod.F90 b/src/biogeochem/CNGapMortalityMod.F90
index aa53317fb3..8979b1eebd 100644
--- a/src/biogeochem/CNGapMortalityMod.F90
+++ b/src/biogeochem/CNGapMortalityMod.F90
@@ -24,7 +24,8 @@ module CNGapMortalityMod
use PatchType , only : patch
use GridcellType , only : grc
use CNSharedParamsMod , only : use_matrixcn
-
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
+ !
implicit none
private
!
@@ -141,7 +142,44 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
livewdcn => pftcon%livewdcn , & ! Input: [real(r8) (:)] live wood (phloem and ray parenchyma) C:N (gC/gN)
laisun => canopystate_inst%laisun_patch , & ! Input: [real(r8) (:) ] sunlit projected leaf area index
laisha => canopystate_inst%laisha_patch , & ! Input: [real(r8) (:) ] shaded projected leaf area index
- nind => dgvs_inst%nind_patch & ! Output:[real(r8)(:)] number of individuals (#/m2) added by F. Li and S. Levis
+ nind => dgvs_inst%nind_patch , & ! Output:[real(r8)(:)] number of individuals (#/m2) added by F. Li and S. Levis
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm, & ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm & ! Input: [integer (:)] Index of gap mortality related N transfer from retranslocation pool to outside of vegetation pools
)
dt = real( get_step_size(), r8 )
@@ -195,9 +233,23 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_carbonflux_inst%m_frootc_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_patch(p) * m
cnveg_carbonflux_inst%m_livestemc_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_patch(p) * m
cnveg_carbonflux_inst%m_livecrootc_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_patch(p) * m
- cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * m * spinup_factor_deadwood
- cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * m * spinup_factor_deadwood
+ else
+ cnveg_carbonflux_inst%m_leafc_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_patch(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_patch(p) * matrix_update_gmc(p,ifroot_to_iout_gmc,m,dt,cnveg_carbonflux_inst,.true.,.True.)
+ cnveg_carbonflux_inst%m_livestemc_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_patch(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_patch(p) * matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ end if
+ if(.not. use_matrixcn)then
+ cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * m * spinup_factor_deadwood
+ cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * m * spinup_factor_deadwood
+ else
+ cnveg_carbonflux_inst%m_deadstemc_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_patch(p) * matrix_update_gmc(p,ideadstem_to_iout_gmc, &
+ m*spinup_factor_deadwood,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_patch(p) * matrix_update_gmc(p,ideadcroot_to_iout_gmc, &
+ m*spinup_factor_deadwood,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ end if !use_matrixcn
+ if(.not. use_matrixcn)then
! storage pools
cnveg_carbonflux_inst%m_leafc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_storage_patch(p) * m
cnveg_carbonflux_inst%m_frootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_storage_patch(p) * m
@@ -216,11 +268,23 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_carbonflux_inst%m_deadcrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_xfer_patch(p) * m
cnveg_carbonflux_inst%m_gresp_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%gresp_xfer_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmc when use_matrixcn is true
- ! displayed pools
- ! storage pools
- ! transfer pools
+ ! NOTE: The non-matrix version of this is in CNCStateUpdate2Mod CStateUpdate2 (EBK 11/25/2019)
+
+ ! storage pools
+ cnveg_carbonflux_inst%m_leafc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_storage_patch(p) * matrix_update_gmc(p,ileafst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_storage_patch(p) * matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livestemc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_storage_patch(p) * matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadstemc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_storage_patch(p) * matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_storage_patch(p) * matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_storage_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_storage_patch(p) * matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+
+ ! transfer pools
+ cnveg_carbonflux_inst%m_leafc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%leafc_xfer_patch(p) * matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_frootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%frootc_xfer_patch(p) * matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livestemc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%livestemc_xfer_patch(p) * matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadstemc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadstemc_xfer_patch(p) * matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_livecrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%livecrootc_xfer_patch(p) * matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
+ cnveg_carbonflux_inst%m_deadcrootc_xfer_to_litter_patch(p) = cnveg_carbonstate_inst%deadcrootc_xfer_patch(p) * matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dt,cnveg_carbonflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
!------------------------------------------------------
@@ -234,8 +298,10 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_livestemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_patch(p) * m
cnveg_nitrogenflux_inst%m_livecrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_leafn_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_patch(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_patch(p) * matrix_update_gmn(p,ifroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,.true.,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_patch(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_patch(p) * matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if
if (spinup_state == 2 .and. .not. use_cndv) then !accelerate mortality of dead woody pools
@@ -243,16 +309,18 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * m * spinup_factor_deadwood
cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * m * spinup_factor_deadwood
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * matrix_update_gmn(p,ideadstem_to_iout_gmn , &
+ m*spinup_factor_deadwood,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * matrix_update_gmn(p,ideadcroot_to_iout_gmn, &
+ m*spinup_factor_deadwood,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !.not. use_matrixcn
else
if (.not. use_matrixcn) then
cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * m
cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_deadstemn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_patch(p) * matrix_update_gmn(p,ideadstem_to_iout_gmn ,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_patch(p) * matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
end if
@@ -260,8 +328,7 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
if(.not. use_matrixcn)then
cnveg_nitrogenflux_inst%m_retransn_to_litter_patch(p) = cnveg_nitrogenstate_inst%retransn_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
+ cnveg_nitrogenflux_inst%m_retransn_to_litter_patch(p) = cnveg_nitrogenstate_inst%retransn_patch(p) * matrix_update_gmn(p,iretransn_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if
end if
@@ -282,10 +349,21 @@ subroutine CNGapMortality (bounds, num_soilp, filter_soilp, &
cnveg_nitrogenflux_inst%m_livecrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_xfer_patch(p) * m
cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_xfer_patch(p) * m
else
- ! For the matrix solution the same mortality gets applied, but it may be limited by the matrix solution
- ! This could be unified, by not limiting matrix_update_gmn when use_matrixcn is true
- ! storage pools
- ! transfer pools
+ ! storage pools
+ cnveg_nitrogenflux_inst%m_leafn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_storage_patch(p) * matrix_update_gmn(p,ileafst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_storage_patch(p) * matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_storage_patch(p) * matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadstemn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_storage_patch(p) * matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_storage_patch(p) * matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_storage_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_storage_patch(p) * matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+
+ ! transfer pools
+ cnveg_nitrogenflux_inst%m_leafn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%leafn_xfer_patch(p) * matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_frootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%frootn_xfer_patch(p) * matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livestemn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livestemn_xfer_patch(p) * matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadstemn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadstemn_xfer_patch(p) * matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_livecrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%livecrootn_xfer_patch(p) * matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
+ cnveg_nitrogenflux_inst%m_deadcrootn_xfer_to_litter_patch(p) = cnveg_nitrogenstate_inst%deadcrootn_xfer_patch(p) * matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dt,cnveg_nitrogenflux_inst,matrixcheck_gm,.True.)
end if !use_matrixcn
! added by F. Li and S. Levis
diff --git a/src/biogeochem/CNNStateUpdate1Mod.F90 b/src/biogeochem/CNNStateUpdate1Mod.F90
index 833a65cbc3..21b5d335b7 100644
--- a/src/biogeochem/CNNStateUpdate1Mod.F90
+++ b/src/biogeochem/CNNStateUpdate1Mod.F90
@@ -182,6 +182,8 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do the above to the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%phenology_n_to_litr_n_col(c,j,i) *dt
end do
end if
end do
@@ -286,6 +288,14 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
(nf_veg%leafn_to_biofueln_patch(p) + nf_veg%leafn_to_removedresiduen_patch(p))*dt
ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) - nf_veg%livestemn_to_retransn_patch(p)*dt
ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) + nf_veg%livestemn_to_retransn_patch(p)*dt
+ do k = repr_grain_min, repr_grain_max
+ ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
+ - (nf_veg%repr_grainn_to_food_patch(p,k) + nf_veg%repr_grainn_to_seed_patch(p,k))*dt
+ end do
+ do k = repr_structure_min, repr_structure_max
+ ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
+ - (nf_veg%repr_structuren_to_cropprod_patch(p,k) + nf_veg%repr_structuren_to_litter_patch(p,k))*dt
+ end do
!
! For the matrix solution the actual state update comes after the matrix
! multiply in VegMatrix, but the matrix needs to be setup with
@@ -298,15 +308,9 @@ subroutine NStateUpdate1(num_soilc, filter_soilc, num_soilp, filter_soilp, &
ns_veg%cropseedn_deficit_patch(p) = ns_veg%cropseedn_deficit_patch(p) &
- nf_veg%crop_seedn_to_leaf_patch(p) * dt
do k = repr_grain_min, repr_grain_max
- ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
- - (nf_veg%repr_grainn_to_food_patch(p,k) + nf_veg%repr_grainn_to_seed_patch(p,k))*dt
ns_veg%cropseedn_deficit_patch(p) = ns_veg%cropseedn_deficit_patch(p) &
+ nf_veg%repr_grainn_to_seed_patch(p,k) * dt
end do
- do k = repr_structure_min, repr_structure_max
- ns_veg%reproductiven_patch(p,k) = ns_veg%reproductiven_patch(p,k) &
- - (nf_veg%repr_structuren_to_cropprod_patch(p,k) + nf_veg%repr_structuren_to_litter_patch(p,k))*dt
- end do
end if
! uptake from soil mineral N pool
diff --git a/src/biogeochem/CNNStateUpdate2Mod.F90 b/src/biogeochem/CNNStateUpdate2Mod.F90
index 678bdf05d3..4b6174195e 100644
--- a/src/biogeochem/CNNStateUpdate2Mod.F90
+++ b/src/biogeochem/CNNStateUpdate2Mod.F90
@@ -96,9 +96,13 @@ subroutine NStateUpdate2(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do above for the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%gap_mortality_n_to_litr_n_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%gap_mortality_n_to_cwdn_col(c,j) * dt
end if !not use_soil_matrix
end do
end do
@@ -235,9 +239,13 @@ subroutine NStateUpdate2h(num_soilc, filter_soilc, num_soilp, filter_soilp, &
else
! Do above for the matrix solution
do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%harvest_n_to_litr_n_col(c,j,i) * dt
end do
! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%harvest_n_to_cwdn_col(c,j) * dt
end if !not use_soil_matrixcn
end do
end do
@@ -313,7 +321,8 @@ end subroutine NStateUpdate2h
!-----------------------------------------------------------------------
subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, soilbiogeochem_nitrogenstate_inst)
+ cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ soilbiogeochem_nitrogenstate_inst, soilbiogeochem_nitrogenflux_inst)
!
! !DESCRIPTION:
! Update all the prognostic nitrogen state
@@ -329,6 +338,7 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
type(cnveg_nitrogenflux_type) , intent(in) :: cnveg_nitrogenflux_inst
type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
!
! !LOCAL VARIABLES:
integer :: c,p,j,l,i ! indices
@@ -339,6 +349,7 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
associate( &
nf_veg => cnveg_nitrogenflux_inst , &
ns_veg => cnveg_nitrogenstate_inst , &
+ nf_soil => soilbiogeochem_nitrogenflux_inst, &
ns_soil => soilbiogeochem_nitrogenstate_inst &
)
@@ -350,14 +361,29 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do j = 1,nlevdecomp
do fc = 1,num_soilc
c = filter_soilc(fc)
- do i = i_litr_min, i_litr_max
- ns_soil%decomp_npools_vr_col(c,j,i) = &
- ns_soil%decomp_npools_vr_col(c,j,i) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
- end do
- ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
- ! i_cwd = 0 if fates, so not including in the i-loop
- ns_soil%decomp_npools_vr_col(c,j,i_cwd) = &
- ns_soil%decomp_npools_vr_col(c,j,i_cwd) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ !
+ ! State update without the matrix solution
+ !
+ if (.not. use_soil_matrixcn)then
+ do i = i_litr_min, i_litr_max
+ ns_soil%decomp_npools_vr_col(c,j,i) = &
+ ns_soil%decomp_npools_vr_col(c,j,i) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ ns_soil%decomp_npools_vr_col(c,j,i_cwd) = &
+ ns_soil%decomp_npools_vr_col(c,j,i_cwd) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ else
+ ! Do above for the matrix solution
+ do i = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i-1)*nlevdecomp) + nf_veg%gru_n_to_litr_n_col(c,j,i) * dt
+ end do
+ ! Currently i_cwd .ne. i_litr_max + 1 if .not. fates and
+ ! i_cwd = 0 if fates, so not including in the i-loop
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = &
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + nf_veg%gru_n_to_cwdn_col(c,j) * dt
+ end if !not use_soil_matrixcn
end do
end do
@@ -366,51 +392,59 @@ subroutine NStateUpdate2g(num_soilc, filter_soilc, num_soilp, filter_soilp, &
do fp = 1,num_soilp
p = filter_soilp(fp)
- ! displayed pools
- ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) &
- - nf_veg%gru_leafn_to_litter_patch(p) * dt
- ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) &
- - nf_veg%gru_frootn_to_litter_patch(p) * dt
- ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) &
- - nf_veg%gru_livestemn_to_atm_patch(p) * dt
- ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
- - nf_veg%gru_deadstemn_to_atm_patch(p) * dt
- ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
- - nf_veg%gru_wood_productn_gain_patch(p) * dt
- ns_veg%livecrootn_patch(p) = ns_veg%livecrootn_patch(p) &
- - nf_veg%gru_livecrootn_to_litter_patch(p) * dt
- ns_veg%deadcrootn_patch(p) = ns_veg%deadcrootn_patch(p) &
- - nf_veg%gru_deadcrootn_to_litter_patch(p) * dt
- ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) &
- - nf_veg%gru_retransn_to_litter_patch(p) * dt
-
- ! storage pools
- ns_veg%leafn_storage_patch(p) = ns_veg%leafn_storage_patch(p) &
- - nf_veg%gru_leafn_storage_to_atm_patch(p) * dt
- ns_veg%frootn_storage_patch(p) = ns_veg%frootn_storage_patch(p) &
- - nf_veg%gru_frootn_storage_to_atm_patch(p) * dt
- ns_veg%livestemn_storage_patch(p) = ns_veg%livestemn_storage_patch(p) &
- - nf_veg%gru_livestemn_storage_to_atm_patch(p) * dt
- ns_veg%deadstemn_storage_patch(p) = ns_veg%deadstemn_storage_patch(p) &
- - nf_veg%gru_deadstemn_storage_to_atm_patch(p) * dt
- ns_veg%livecrootn_storage_patch(p) = ns_veg%livecrootn_storage_patch(p) &
- - nf_veg%gru_livecrootn_storage_to_atm_patch(p) * dt
- ns_veg%deadcrootn_storage_patch(p) = ns_veg%deadcrootn_storage_patch(p) &
- - nf_veg%gru_deadcrootn_storage_to_atm_patch(p) * dt
-
- ! transfer pools
- ns_veg%leafn_xfer_patch(p) = ns_veg%leafn_xfer_patch(p) &
- - nf_veg%gru_leafn_xfer_to_atm_patch(p) *dt
- ns_veg%frootn_xfer_patch(p) = ns_veg%frootn_xfer_patch(p) &
- - nf_veg%gru_frootn_xfer_to_atm_patch(p) *dt
- ns_veg%livestemn_xfer_patch(p) = ns_veg%livestemn_xfer_patch(p) &
- - nf_veg%gru_livestemn_xfer_to_atm_patch(p) *dt
- ns_veg%deadstemn_xfer_patch(p) = ns_veg%deadstemn_xfer_patch(p) &
- - nf_veg%gru_deadstemn_xfer_to_atm_patch(p) *dt
- ns_veg%livecrootn_xfer_patch(p) = ns_veg%livecrootn_xfer_patch(p) &
- - nf_veg%gru_livecrootn_xfer_to_atm_patch(p) *dt
- ns_veg%deadcrootn_xfer_patch(p) = ns_veg%deadcrootn_xfer_patch(p) &
- - nf_veg%gru_deadcrootn_xfer_to_atm_patch(p) *dt
+ !
+ ! State update without the matrix solution
+ !
+ if(.not. use_matrixcn)then
+ ! displayed pools
+ ns_veg%leafn_patch(p) = ns_veg%leafn_patch(p) &
+ - nf_veg%gru_leafn_to_litter_patch(p) * dt
+ ns_veg%frootn_patch(p) = ns_veg%frootn_patch(p) &
+ - nf_veg%gru_frootn_to_litter_patch(p) * dt
+ ns_veg%livestemn_patch(p) = ns_veg%livestemn_patch(p) &
+ - nf_veg%gru_livestemn_to_atm_patch(p) * dt
+ ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
+ - nf_veg%gru_deadstemn_to_atm_patch(p) * dt
+ ns_veg%deadstemn_patch(p) = ns_veg%deadstemn_patch(p) &
+ - nf_veg%gru_wood_productn_gain_patch(p) * dt
+ ns_veg%livecrootn_patch(p) = ns_veg%livecrootn_patch(p) &
+ - nf_veg%gru_livecrootn_to_litter_patch(p) * dt
+ ns_veg%deadcrootn_patch(p) = ns_veg%deadcrootn_patch(p) &
+ - nf_veg%gru_deadcrootn_to_litter_patch(p) * dt
+ ns_veg%retransn_patch(p) = ns_veg%retransn_patch(p) &
+ - nf_veg%gru_retransn_to_litter_patch(p) * dt
+
+ ! storage pools
+ ns_veg%leafn_storage_patch(p) = ns_veg%leafn_storage_patch(p) &
+ - nf_veg%gru_leafn_storage_to_atm_patch(p) * dt
+ ns_veg%frootn_storage_patch(p) = ns_veg%frootn_storage_patch(p) &
+ - nf_veg%gru_frootn_storage_to_atm_patch(p) * dt
+ ns_veg%livestemn_storage_patch(p) = ns_veg%livestemn_storage_patch(p) &
+ - nf_veg%gru_livestemn_storage_to_atm_patch(p) * dt
+ ns_veg%deadstemn_storage_patch(p) = ns_veg%deadstemn_storage_patch(p) &
+ - nf_veg%gru_deadstemn_storage_to_atm_patch(p) * dt
+ ns_veg%livecrootn_storage_patch(p) = ns_veg%livecrootn_storage_patch(p) &
+ - nf_veg%gru_livecrootn_storage_to_atm_patch(p) * dt
+ ns_veg%deadcrootn_storage_patch(p) = ns_veg%deadcrootn_storage_patch(p) &
+ - nf_veg%gru_deadcrootn_storage_to_atm_patch(p) * dt
+
+ ! transfer pools
+ ns_veg%leafn_xfer_patch(p) = ns_veg%leafn_xfer_patch(p) &
+ - nf_veg%gru_leafn_xfer_to_atm_patch(p) *dt
+ ns_veg%frootn_xfer_patch(p) = ns_veg%frootn_xfer_patch(p) &
+ - nf_veg%gru_frootn_xfer_to_atm_patch(p) *dt
+ ns_veg%livestemn_xfer_patch(p) = ns_veg%livestemn_xfer_patch(p) &
+ - nf_veg%gru_livestemn_xfer_to_atm_patch(p) *dt
+ ns_veg%deadstemn_xfer_patch(p) = ns_veg%deadstemn_xfer_patch(p) &
+ - nf_veg%gru_deadstemn_xfer_to_atm_patch(p) *dt
+ ns_veg%livecrootn_xfer_patch(p) = ns_veg%livecrootn_xfer_patch(p) &
+ - nf_veg%gru_livecrootn_xfer_to_atm_patch(p) *dt
+ ns_veg%deadcrootn_xfer_patch(p) = ns_veg%deadcrootn_xfer_patch(p) &
+ - nf_veg%gru_deadcrootn_xfer_to_atm_patch(p) *dt
+ else
+ ! NB (slevis) The equivalent changes for matrix code are in
+ ! dynGrossUnrepMod::CNGrossUnrep*
+ end if !not use_matrixcn
end do
diff --git a/src/biogeochem/CNNStateUpdate3Mod.F90 b/src/biogeochem/CNNStateUpdate3Mod.F90
index 26902cef22..fb8f57b38f 100644
--- a/src/biogeochem/CNNStateUpdate3Mod.F90
+++ b/src/biogeochem/CNNStateUpdate3Mod.F90
@@ -146,10 +146,14 @@ subroutine NStateUpdate3(num_soilc, filter_soilc, num_soilp, filter_soilp, &
! native subroutines dealing with that field
!
else
+ nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) = nf_soil%matrix_Ninput%V(c,j+(i_cwd-1)*nlevdecomp) + &
+ nf_veg%fire_mortality_n_to_cwdn_col(c,j) * dt
! Do above for the matrix solution
! patch-level wood to column-level litter (uncombusted wood)
do k = i_litr_min, i_litr_max
+ nf_soil%matrix_Ninput%V(c,j+(k-1)*nlevdecomp) = nf_soil%matrix_Ninput%V(c,j+(k-1)*nlevdecomp) + &
+ nf_veg%m_n_to_litr_fire_col(c,j,k)* dt
end do
end if ! not use_soil_matrix
end do ! end of column loop
diff --git a/src/biogeochem/CNPhenologyMod.F90 b/src/biogeochem/CNPhenologyMod.F90
index 1fb13d32eb..2ce7f029da 100644
--- a/src/biogeochem/CNPhenologyMod.F90
+++ b/src/biogeochem/CNPhenologyMod.F90
@@ -14,6 +14,12 @@ module CNPhenologyMod
use shr_log_mod , only : errMsg => shr_log_errMsg
use shr_sys_mod , only : shr_sys_flush
use decompMod , only : bounds_type
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn
use clm_varpar , only : maxveg, nlevdecomp_full, mxsowings, mxharvests
use clm_varpar , only : i_litr_min, i_litr_max
use clm_varctl , only : iulog, use_cndv
@@ -42,6 +48,8 @@ module CNPhenologyMod
use GridcellType , only : grc
use PatchType , only : patch
use atm2lndType , only : atm2lnd_type
+ use CNVegMatrixMod , only : matrix_update_phc, matrix_update_phn
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
implicit none
private
@@ -132,10 +140,8 @@ module CNPhenologyMod
integer, allocatable :: maxplantjday(:,:) ! maximum planting julian day
integer :: jdayyrstart(inSH) ! julian day of start of year
- ! Two matrix check parameters that will be invoked when the matrix solution
- ! comes in (use_matrixcn)
- logical,parameter :: matrixcheck_ph = .True. ! Matrix solution check
- logical,parameter :: acc_ph = .False. ! Another matrix solution check
+ logical,parameter :: matrixcheck_ph = .True. ! Matrix check
+ logical,parameter :: acc_ph = .False. ! Another matrix check
real(r8), private :: initial_seed_at_planting = 3._r8 ! Initial seed at planting
@@ -677,8 +683,47 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
bglfr => cnveg_state_inst%bglfr_patch , & ! Output: [real(r8) (:) ] background litterfall rate (1/s)
bgtr => cnveg_state_inst%bgtr_patch , & ! Output: [real(r8) (:) ] background transfer growth rate (1/s)
- lgsf => cnveg_state_inst%lgsf_patch & ! Output: [real(r8) (:) ] long growing season factor [0-1]
-
+ lgsf => cnveg_state_inst%lgsf_patch , & ! Output: [real(r8) (:) ] long growing season factor [0-1]
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
avg_dayspyr = get_average_days_per_year()
@@ -700,22 +745,38 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
tranr=0.0002_r8
! set carbon fluxes for shifting storage pools to transfer pools
- if (.not. use_matrixcn) then
- leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt
- frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt
- if (woody(ivt(p)) == 1.0_r8) then
- livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt
- deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt
- livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt
- deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt
- gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt
+ if (use_matrixcn) then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc,tranr/dt ,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc,tranr/dt ,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,tranr/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- end if !not use_matrixcn
+ leafc_storage_to_xfer(p) = tranr * leafc_storage(p)/dt
+ frootc_storage_to_xfer(p) = tranr * frootc_storage(p)/dt
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = tranr * livestemc_storage(p)/dt
+ deadstemc_storage_to_xfer(p) = tranr * deadstemc_storage(p)/dt
+ livecrootc_storage_to_xfer(p) = tranr * livecrootc_storage(p)/dt
+ deadcrootc_storage_to_xfer(p) = tranr * deadcrootc_storage(p)/dt
+ gresp_storage_to_xfer(p) = tranr * gresp_storage(p)/dt
+ end if
+ end if !use_matrixcn
! set nitrogen fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,tranr/dt ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,tranr/dt ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,tranr/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
leafn_storage_to_xfer(p) = tranr * leafn_storage(p)/dt
@@ -731,6 +792,22 @@ subroutine CNEvergreenPhenology (num_soilp, filter_soilp , &
t1 = 1.0_r8 / dt
if (use_matrixcn) then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -883,7 +960,46 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , &
livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! start patch loop
@@ -1005,6 +1121,25 @@ subroutine CNSeasonDecidPhenology (num_soilp, filter_soilp , &
! set carbon fluxes for shifting storage pools to transfer pools
if(use_matrixcn)then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc ,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc ,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ gresp_storage_to_xfer(p) = fstor2tran * gresp_storage(p)/dt
+ end if
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn ,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn ,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -1343,7 +1478,46 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
livestemn_storage_to_xfer => cnveg_nitrogenflux_inst%livestemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
deadstemn_storage_to_xfer => cnveg_nitrogenflux_inst%deadstemn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
livecrootn_storage_to_xfer => cnveg_nitrogenflux_inst%livecrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_storage_to_xfer => cnveg_nitrogenflux_inst%deadcrootn_storage_to_xfer_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
avg_dayspyr = get_average_days_per_year()
@@ -1511,6 +1685,23 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! set carbon fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,fstor2tran/dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ end if
+
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,fstor2tran/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -1634,9 +1825,26 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! between leafc and leafc_store in the flux. RosieF, Nov5 2015.
leafc_storage_to_xfer(p) = max(0.0_r8,(leafc_storage(p)-leafc(p))) * bgtr(p)
frootc_storage_to_xfer(p) = max(0.0_r8,(frootc_storage(p)-frootc(p))) * bgtr(p)
-
if (use_matrixcn) then
- else
+ if(leafc_storage(p) .gt. 0)then
+ leafc_storage_to_xfer(p) = leafc_storage(p) * matrix_update_phc(p,ileafst_to_ileafxf_phc,&
+ leafc_storage_to_xfer(p) / leafc_storage(p), dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_storage_to_xfer(p) = 0
+ end if
+ if(frootc_storage(p) .gt. 0)then
+ frootc_storage_to_xfer(p) = frootc_storage(p) * matrix_update_phc(p,ifrootst_to_ifrootxf_phc,&
+ frootc_storage_to_xfer(p) / frootc_storage(p), dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_storage_to_xfer(p) = 0
+ end if
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemc_storage_to_xfer(p) = livestemc_storage(p) * matrix_update_phc(p,ilivestemst_to_ilivestemxf_phc ,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_storage_to_xfer(p) = deadstemc_storage(p) * matrix_update_phc(p,ideadstemst_to_ideadstemxf_phc ,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_storage_to_xfer(p) = livecrootc_storage(p) * matrix_update_phc(p,ilivecrootst_to_ilivecrootxf_phc,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_storage_to_xfer(p) = deadcrootc_storage(p) * matrix_update_phc(p,ideadcrootst_to_ideadcrootxf_phc,bgtr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ end if
+ else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
if (woody(ivt(p)) == 1.0_r8) then
@@ -1650,9 +1858,17 @@ subroutine CNStressDecidPhenology (num_soilp, filter_soilp , &
! set nitrogen fluxes for shifting storage pools to transfer pools
if (use_matrixcn) then
+ leafn_storage_to_xfer(p) = leafn_storage(p) * matrix_update_phn(p,ileafst_to_ileafxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_storage_to_xfer(p) = frootn_storage(p) * matrix_update_phn(p,ifrootst_to_ifrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+ livestemn_storage_to_xfer(p) = livestemn_storage(p) * matrix_update_phn(p,ilivestemst_to_ilivestemxf_phn,bgtr(p) ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_storage_to_xfer(p) = deadstemn_storage(p) * matrix_update_phn(p,ideadstemst_to_ideadstemxf_phn,bgtr(p) ,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_storage_to_xfer(p) = livecrootn_storage(p) * matrix_update_phn(p,ilivecrootst_to_ilivecrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_storage_to_xfer(p) = deadcrootn_storage(p) * matrix_update_phn(p,ideadcrootst_to_ideadcrootxf_phn,bgtr(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- ! and CNNStateUpdate1::NStateUpdate11
+ ! and CNNStateUpdate1::NStateUpdate1
leafn_storage_to_xfer(p) = leafn_storage(p) * bgtr(p)
frootn_storage_to_xfer(p) = frootn_storage(p) * bgtr(p)
if (woody(ivt(p)) == 1.0_r8) then
@@ -2994,7 +3210,46 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
livestemn_xfer_to_livestemn => cnveg_nitrogenflux_inst%livestemn_xfer_to_livestemn_patch , & ! Output: [real(r8) (:) ]
deadstemn_xfer_to_deadstemn => cnveg_nitrogenflux_inst%deadstemn_xfer_to_deadstemn_patch , & ! Output: [real(r8) (:) ]
livecrootn_xfer_to_livecrootn => cnveg_nitrogenflux_inst%livecrootn_xfer_to_livecrootn_patch , & ! Output: [real(r8) (:) ]
- deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch & ! Output: [real(r8) (:) ]
+ deadcrootn_xfer_to_deadcrootn => cnveg_nitrogenflux_inst%deadcrootn_xfer_to_deadcrootn_patch , & ! Output: [real(r8) (:) ]
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! patch loop
@@ -3013,6 +3268,22 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
t1 = 2.0_r8 / (onset_counter(p))
end if
if (use_matrixcn)then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,t1,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,t1,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3039,7 +3310,26 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
! pools should be moved to displayed growth in each timestep.
if (bgtr(p) > 0._r8) then
- if(.not. use_matrixcn)then
+ if(use_matrixcn)then
+ leafc_xfer_to_leafc(p) = leafc_xfer(p) * matrix_update_phc(p,ileafxf_to_ileaf_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_xfer_to_frootc(p) = frootc_xfer(p) * matrix_update_phc(p,ifrootxf_to_ifroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ leafn_xfer_to_leafn(p) = leafn_xfer(p) * matrix_update_phn(p,ileafxf_to_ileaf_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ frootn_xfer_to_frootn(p) = frootn_xfer(p) * matrix_update_phn(p,ifrootxf_to_ifroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ if (woody(ivt(p)) == 1.0_r8) then
+
+ livestemc_xfer_to_livestemc(p) = livestemc_xfer(p) * matrix_update_phc(p,ilivestemxf_to_ilivestem_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadstemc_xfer_to_deadstemc(p) = deadstemc_xfer(p) * matrix_update_phc(p,ideadstemxf_to_ideadstem_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootc_xfer_to_livecrootc(p) = livecrootc_xfer(p) * matrix_update_phc(p,ilivecrootxf_to_ilivecroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootc_xfer_to_deadcrootc(p) = deadcrootc_xfer(p) * matrix_update_phc(p,ideadcrootxf_to_ideadcroot_phc,1._r8 / dt,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+
+ livestemn_xfer_to_livestemn(p) = livestemn_xfer(p) * matrix_update_phn(p,ilivestemxf_to_ilivestem_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadstemn_xfer_to_deadstemn(p) = deadstemn_xfer(p) * matrix_update_phn(p,ideadstemxf_to_ideadstem_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) * matrix_update_phn(p,ilivecrootxf_to_ilivecroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) * matrix_update_phn(p,ideadcrootxf_to_ideadcroot_phn,1._r8 / dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
+ else
+ ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
+ ! and CNNStateUpdate1::NStateUpdate1
leafc_xfer_to_leafc(p) = leafc_xfer(p) / dt
frootc_xfer_to_frootc(p) = frootc_xfer(p) / dt
leafn_xfer_to_leafn(p) = leafn_xfer(p) / dt
@@ -3054,7 +3344,7 @@ subroutine CNOnsetGrowth (num_soilp, filter_soilp, &
livecrootn_xfer_to_livecrootn(p) = livecrootn_xfer(p) / dt
deadcrootn_xfer_to_deadcrootn(p) = deadcrootn_xfer(p) / dt
end if
- end if !not use_matrixcn
+ end if !use_matrixcn
end if ! end if bgtr
end do ! end patch loop
@@ -3176,8 +3466,51 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch, & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch , & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s)
- leafcn_offset => cnveg_state_inst%leafcn_offset_patch & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
-
+ leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , & ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! The litterfall transfer rate starts at 0.0 and increases linearly
@@ -3192,14 +3525,18 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if (abs(offset_counter(p) - dt) <= dt/2._r8) then
t1 = 1.0_r8 / dt
frootc_to_litter(p) = t1 * frootc(p) + cpool_to_frootc(p)
-
- ! leafc_litter and frootc_to_litter for matrix
+
+ ! frootc_to_litter for matrix
if (use_matrixcn) then
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
end if ! use_matrixcn
-
! this assumes that offset_counter == dt for crops
! if this were ever changed, we'd need to add code to the "else"
if (ivt(p) >= npcropmin) then
@@ -3302,8 +3639,55 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
! as well as leaf C:N ratio (unaffected by biofuel harvest). It thus does not
! need to be updated here.
- ! Matrix for grain, livestem to litter and biofuel
+ ! Matrix for grain
+ ! Matrix for livestem/leaf to litter, biofuel, and removed residue
if(use_matrixcn)then
+ if(reproductivec(p,1) > 0._r8)then
+ grainc_to_out = reproductivec(p,1) * matrix_update_phc(p,igrain_to_iout_phc,(repr_grainc_to_seed(p,1) + repr_grainc_to_food(p,1)) / reproductivec(p,1),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ repr_grainc_to_seed(p,1) = 0._r8
+ repr_grainc_to_food(p,1) = 0._r8
+ end if
+ if(reproductiven(p,1) > 0._r8)then
+ grainn_to_out = reproductiven(p,1) * matrix_update_phn(p,igrain_to_iout_phn,(repr_grainn_to_seed(p,1) + repr_grainn_to_food(p,1)) / reproductiven(p,1),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ repr_grainn_to_seed(p,1) = 0._r8
+ repr_grainn_to_food(p,1) = 0._r8
+ end if
+ if(livestemc(p) > 0._r8)then
+ livestemc_to_litter(p) = livestemc(p) * matrix_update_phc(p,ilivestem_to_iout_phc,livestemc_to_litter(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livestemc_to_removedresiduec(p) = livestemc(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,livestemc_to_removedresiduec(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ livestemc_to_biofuelc(p) = livestemc(p) * matrix_update_gmc(p,ilivestem_to_iout_gmc,livestemc_to_biofuelc(p) / livestemc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ else
+ livestemc_to_litter(p) = 0._r8
+ livestemc_to_removedresiduec(p) = 0._r8
+ livestemc_to_biofuelc(p) = 0._r8
+ end if
+ if(livestemn(p) > 0._r8)then
+ livestemn_to_biofueln(p) = livestemn(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,livestemn_to_biofueln(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ livestemn_to_removedresiduen(p) = livestemn(p) * matrix_update_gmn(p,ilivestem_to_iout_gmn,livestemn_to_removedresiduen(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ livestemn_to_litter(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_iout_phn, (1._r8- biofuel_harvfrac(ivt(p)))/dt, dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_biofueln(p) = 0._r8
+ livestemn_to_removedresiduen(p) = 0._r8
+ livestemn_to_litter(p) = 0._r8
+ end if
+ if(leafn(p) > 0._r8)then
+ leafn_to_biofueln(p) = leafn(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,leafn_to_biofueln(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ leafn_to_removedresiduen(p) = leafn(p) * matrix_update_gmn(p,ileaf_to_iout_gmn,leafn_to_removedresiduen(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ else
+ leafn_to_biofueln(p) = 0._r8
+ leafn_to_removedresiduen(p) = 0._r8
+ end if
+ if (leafc(p) > 0._r8)then
+ leafc_to_biofuelc(p) = leafc(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,leafc_to_biofuelc(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ leafc_to_removedresiduec(p) = leafc(p) * matrix_update_gmc(p,ileaf_to_iout_gmc,leafc_to_removedresiduec(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,.True.)
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_biofuelc(p) = 0._r8
+ leafc_to_removedresiduec(p) = 0._r8
+ leafc_to_litter(p) = 0._r8
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3314,8 +3698,17 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafc_to_litter(p) = prev_leafc_to_litter(p) + t1*(leafc(p) - prev_leafc_to_litter(p)*offset_counter(p))
frootc_to_litter(p) = prev_frootc_to_litter(p) + t1*(frootc(p) - prev_frootc_to_litter(p)*offset_counter(p))
- ! Matrix for leafc and frootc to litter
if (use_matrixcn) then
+ if(leafc(p) .gt. 0)then
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_litter(p) = 0
+ end if
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0 ! TODO slevis here and elsewhere
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3325,18 +3718,24 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if ( use_fun ) then
if(leafc_to_litter(p)*dt.gt.leafc(p))then
leafc_to_litter(p) = leafc(p)/dt + cpool_to_leafc(p)
-
- ! Matrix for leafc to litter
- if (use_matrixcn) then
- else
- ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
- end if !use_matrixcn
+ if (use_matrixcn) then
+ if(leafc(p) .gt. 0)then
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,leafc_to_litter(p) / leafc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafc_to_litter(p) = 0
+ end if
+ else
+ ! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
+ end if !use_matrixcn
endif
if(frootc_to_litter(p)*dt.gt.frootc(p))then
frootc_to_litter(p) = frootc(p)/dt + cpool_to_frootc(p)
-
- ! Matrix update for frootc to litter
if (use_matrixcn) then
+ if(frootc(p) .gt. 0)then
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,frootc_to_litter(p) / frootc(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootc_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3358,9 +3757,14 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
end if
leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p)
leafn_to_litter(p) = max(leafn_to_litter(p),0._r8)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3383,8 +3787,14 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p))
leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p)
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3392,9 +3802,12 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
! calculate fine root N litterfall (no retranslocation of fine root N)
frootn_to_litter(p) = frootc_to_litter(p) / frootcn(ivt(p))
-
- ! Matrix update for frootn to litter
if (use_matrixcn) then
+ if(frootn(p) .gt. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootn_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3408,19 +3821,26 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf
leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
- else
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
end if !use_matrixcn
if (frootc(p) == 0.0_r8) then
frootn_to_litter(p) = 0.0_r8
- else
+ else
frootn_to_litter(p) = frootc_to_litter(p) * (frootn(p) / frootc(p))
- end if
-
- ! Matrix update for frootn to litter
+ end if
if (use_matrixcn) then
+ if(frootn(p) .gt. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ frootn_to_litter(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3428,12 +3848,10 @@ subroutine CNOffsetLitterfall (num_soilp, filter_soilp, &
if ( use_fun ) then
if(frootn_to_litter(p)*dt.gt.frootn(p))then
-
- ! Send all frootn to litter
if (.not. use_matrixcn) then
frootn_to_litter(p) = frootn(p)/dt
else
- ! Matrix update for frootn to litter
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,1._r8/dt,dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
endif
end if
@@ -3503,8 +3921,47 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafc_to_litter_fun => cnveg_carbonflux_inst%leafc_to_litter_fun_patch, & ! Output: [real(r8) (:) ] leaf C litterfall used by FUN (gC/m2/s)
leafcn_offset => cnveg_state_inst%leafcn_offset_patch , & ! Output: [real(r8) (:) ] Leaf C:N used by FUN
free_retransn_to_npool=> cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
- paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
-
+ paid_retransn_to_npool=> cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
! patch loop
@@ -3516,10 +3973,9 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
! units for bglfr are already 1/s
leafc_to_litter(p) = bglfr(p) * leafc(p)
frootc_to_litter(p) = bglfr(p) * frootc(p)
-
- ! Matrix update for leafc and frootc to litter
if (use_matrixcn) then
- else
+ leafc_to_litter(p) = leafc(p) * matrix_update_phc(p,ileaf_to_iout_phc,bglfr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ frootc_to_litter(p) = frootc(p) * matrix_update_phc(p,ifroot_to_iout_phc,bglfr(p),dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
end if
if ( use_fun ) then
leafc_to_litter_fun(p) = leafc_to_litter(p)
@@ -3535,9 +3991,11 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
end if
leafn_to_litter(p) = leafc_to_litter(p)/leafcn_offset(p) - leafn_to_retransn(p)
leafn_to_litter(p) = max(leafn_to_litter(p),0._r8)
-
- ! Matrix update for leafn to litter and retrans
if(use_matrixcn)then
+ if(leafn(p) .ne. 0._r8)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3560,8 +4018,11 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = leafc_to_litter(p) / lflitcn(ivt(p))
leafn_to_retransn(p) = (leafc_to_litter(p) / leafcn(ivt(p))) - leafn_to_litter(p)
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .ne. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3579,9 +4040,14 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
leafn_to_litter(p) = fr_leafn_to_litter * ntovr_leaf
leafn_to_retransn(p) = ntovr_leaf - leafn_to_litter(p)
-
- ! Matrix update for leafn to litter and retrans
if (use_matrixcn) then
+ if(leafn(p) .gt. 0)then
+ leafn_to_litter(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iout_phn,leafn_to_litter(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ leafn_to_litter(p) = 0
+ leafn_to_retransn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3598,8 +4064,10 @@ subroutine CNBackgroundLitterfall (num_soilp, filter_soilp, &
endif
end if
- ! Matrix update for frootn to litter
if (use_matrixcn) then
+ if(frootn(p) .ne. 0)then
+ frootn_to_litter(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iout_phn,frootn_to_litter(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
@@ -3657,7 +4125,47 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch , & ! Output: [real(r8) (:) ]
livecrootn_to_deadcrootn => cnveg_nitrogenflux_inst%livecrootn_to_deadcrootn_patch , & ! Output: [real(r8) (:) ]
livecrootn_to_retransn => cnveg_nitrogenflux_inst%livecrootn_to_retransn_patch , & ! Output: [real(r8) (:) ]
- free_retransn_to_npool => cnveg_nitrogenflux_inst%free_retransn_to_npool_patch & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+ free_retransn_to_npool => cnveg_nitrogenflux_inst%free_retransn_to_npool_patch , & ! Input: [real(r8) (:) ] free leaf N to retranslocated N pool (gN/m2/s)
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to retranslocation pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to retranslocation pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , & ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to retranslocation pool
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Input: [integer ]
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph & ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
)
@@ -3675,9 +4183,13 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
ntovr = ctovr / livewdcn(ivt(p))
livestemc_to_deadstemc(p) = ctovr
livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p))
-
- ! Matrix update for livestemc to deadstem
if( use_matrixcn)then
+ livestemc_to_deadstemc(p) = livestemc(p) * matrix_update_phc(p,ilivestem_to_ideadstem_phc,lwtop,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ if (livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_deadstemn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_ideadstem_phn,livestemn_to_deadstemn(p)/livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_deadstemn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
@@ -3686,13 +4198,18 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
if (livestemc(p) == 0.0_r8) then
ntovr = 0.0_r8
livestemn_to_deadstemn(p) = 0.0_r8
- else
+ else
ntovr = ctovr * (livestemn(p) / livestemc(p))
livestemn_to_deadstemn(p) = ctovr / deadwdcn(ivt(p))
- end if
+ end if
- ! Matrix update for livestemn to deadstem
if (use_matrixcn)then
+ if (livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_deadstemn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_ideadstem_phn,&
+ livestemn_to_deadstemn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
+ else
+ livestemn_to_deadstemn(p) = 0
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if
@@ -3705,14 +4222,14 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
ctovr = livecrootc(p) * lwtop
ntovr = ctovr / livewdcn(ivt(p))
-
if(.not. use_matrixcn)then
! NOTE: The non matrix version of this is in CNCStateUpdate1::CStateUpdate1 EBK (11/26/2019)
! and CNNStateUpdate1::NStateUpdate1
livecrootc_to_deadcrootc(p) = ctovr
livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p))
else
- ! Matrix update for livecroot to deadcroot
+ livecrootc_to_deadcrootc(p) = livecrootc(p) * matrix_update_phc(p,ilivecroot_to_ideadcroot_phc,lwtop,dt,cnveg_carbonflux_inst,matrixcheck_ph,acc_ph)
+ livecrootn_to_deadcrootn(p) = livecrootn(p) * matrix_update_phn(p,ilivecroot_to_ideadcroot_phn,lwtop/deadwdcn(ivt(p)),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if !use_matrixcn
if (CNratio_floating .eqv. .true.) then
@@ -3724,20 +4241,48 @@ subroutine CNLivewoodTurnover (num_soilp, filter_soilp, &
livecrootn_to_deadcrootn(p) = ctovr / deadwdcn(ivt(p))
end if
- ! Matrix update for livecroot to deadcroot
if (use_matrixcn)then
+ if (livecrootn(p) .ne.0.0_r8 )then
+ livecrootn_to_deadcrootn(p) = matrix_update_phn(p,ilivecroot_to_ideadcroot_phn,&
+ livecrootn_to_deadcrootn(p) / livecrootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livecrootn(p)
+ end if
else
! NOTE: The non matrix version of this is in CNNStateUpdate1::NStateUpdate1 EBK (11/26/2019)
end if !use_matrixcn
end if
livecrootn_to_retransn(p) = ntovr - livecrootn_to_deadcrootn(p)
-
- ! Matrix update for livecrootn and livestemn to retrans as well as free retransn to npool with FUN
- if(use_matrixcn)then
- else
- ! The non-matrix version of this is in NStateUpdate1
- end if !use_matrixcn
+ if(use_matrixcn)then
+ if(livecrootn(p) .gt. 0.0_r8) then
+ livecrootn_to_retransn(p) = matrix_update_phn(p,ilivecroot_to_iretransn_phn,&
+ livecrootn_to_retransn(p) / livecrootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livecrootn(p)
+ else
+ livecrootn_to_retransn(p) = 0
+ end if
+ if(livestemn(p) .gt. 0.0_r8) then
+ livestemn_to_retransn(p) = matrix_update_phn(p,ilivestem_to_iretransn_phn,&
+ livestemn_to_retransn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph) * livestemn(p)
+ else
+ livestemn_to_retransn(p) = 0
+ end if
+ ! WW change logic so livestem_retrans goes to npool (via
+ ! free_retrans flux)
+ ! this should likely be done more cleanly if it works, i.e. not
+ ! update fluxes w/ states
+ ! additional considerations for crop?
+ ! The non-matrix version of this is in NStateUpdate1
+ if (use_fun) then
+ if (retransn(p) .gt. 0._r8) then
+ ! The acc matrix check MUST be turned on, or this will
+ ! fail with Nitrogen balance error EBK 03/11/2021
+ free_retransn_to_npool(p) = free_retransn_to_npool(p) + retransn(p) * matrix_update_phn(p,iretransn_to_iout, &
+ (livestemn_to_retransn(p) + livecrootn_to_retransn(p)) / retransn(p),dt, &
+ cnveg_nitrogenflux_inst, matrixcheck_ph, acc=.true.)
+ else
+ free_retransn_to_npool(p) = 0._r8
+ end if
+ end if
+ end if !use_matrixcn
end if
diff --git a/src/biogeochem/CNRootDynMod.F90 b/src/biogeochem/CNRootDynMod.F90
deleted file mode 100644
index 3f43424cfa..0000000000
--- a/src/biogeochem/CNRootDynMod.F90
+++ /dev/null
@@ -1,271 +0,0 @@
-module CNRootDynMod
-
-!-----------------------------------------------------------------------
-! !DESCRIPTION:
-! Module holding routines used for determining fine root distribution for all pfts.
-! Includes dynamic root depth for crops
-!
-! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8
- use clm_time_manager , only : get_step_size_real
- use abortutils , only : endrun
- use clm_varpar , only : nlevsoi, nlevgrnd
- use clm_varctl , only : use_bedrock
- use decompMod , only : bounds_type
- use pftconMod , only : noveg, npcropmin, pftcon
- use ColumnType , only : col
- use PatchType , only : patch
- use CNVegStateType , only : cnveg_state_type
- use CNVegCarbonStateType , only : cnveg_carbonstate_type
- use CNVegCarbonFluxType , only : cnveg_carbonflux_type
- use CNVegnitrogenstateType , only : cnveg_nitrogenstate_type
- use SoilStateType , only : soilstate_type
- use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
- use CropType , only : crop_type
-
-! !PUBLIC TYPES:
- implicit none
- save
- private
- public :: CNRootDyn
-!-----------------------------------------------------------------------
-
-contains
-
-!-----------------------------------------------------------------------
-!
-subroutine CNRootDyn(bounds, num_soilc, filter_soilc, num_soilp, filter_soilp, &
- cnveg_carbonstate_inst, cnveg_nitrogenstate_inst, cnveg_carbonflux_inst, &
- cnveg_state_inst, crop_inst, soilstate_inst, soilbiogeochem_nitrogenstate_inst)
-!
-! !DESCRIPTION:
-! This routine determine the fine root distribution
-! Needs to be called after the photosynthesis calculation
-! May need to update other subroutines that use the fixed root profile for calculations
-! i.e. CNVerticalProfileMod
-!
-! !USES:
-
-
-! !ARGUMENTS:
- type(bounds_type), intent(in) :: bounds ! bounds
- integer, intent(in) :: num_soilc
- integer, intent(in) :: filter_soilc(:)
- integer, intent(in) :: num_soilp ! number of soil pfts in filter
- integer, intent(in) :: filter_soilp(:) ! filter for soil pfts
- type(cnveg_state_type) , intent(in) :: cnveg_state_inst
- type(cnveg_carbonstate_type) , intent(in) :: cnveg_carbonstate_inst
- type(cnveg_carbonflux_type) , intent(in) :: cnveg_carbonflux_inst
- type(cnveg_nitrogenstate_type) , intent(in) :: cnveg_nitrogenstate_inst
- type(crop_type) , intent(in) :: crop_inst
- type(soilbiogeochem_nitrogenstate_type) , intent(in) :: soilbiogeochem_nitrogenstate_inst
- type(soilstate_type) , intent(inout) :: soilstate_inst
-
-!
-! !LOCAL VARIABLES:
-
- integer :: f,c,p,lev,j ! indices
- real(r8):: dt ! radiation time step delta t (seconds)
- real(r8), allocatable :: w_limit(:)
- real(r8), allocatable :: rswa(:,:) ! soil water availability in each soil layer
- real(r8), allocatable :: rsmn(:,:) ! soil nitrogen availability in each soil layer
- real(r8), allocatable :: sumrswa(:) ! scaling soil water availability in each soil layer
- real(r8), allocatable :: sumrsmn(:) ! scaling soil mineral N availability in each soil layer
- real(r8) :: frootc_dz(bounds%begp:bounds%endp, 1:nlevgrnd)
- real(r8), allocatable :: sumfrootc(:) ! fine root carbon total before turnover in each step
- real(r8):: minpsi ! minimum soil moisture potential
- real(r8):: psi
- real(r8):: maxpsi
- real(r8):: new_growth
-
-!-----------------------------------------------------------------------
- ! Assign local pointers to derived type arrays (in)
- associate(&
- ivt => patch%itype , & ! Input: [integer (:)] pft vegetation type
- pcolumn => patch%column , & ! Input: [integer (:)] pft's column index
- roota_par => pftcon%roota_par , & ! Input: [real(r8) (:)] pft's roota index
- rootb_par => pftcon%rootb_par , & ! Input: [real(r8) (:)] pft's rootb index
- root_dmx => pftcon%root_dmx , & ! Input: [real(r8) (:)] crop maximum root depth
- cpool_to_frootc => cnveg_carbonflux_inst%cpool_to_frootc_patch , & ! Input: [real(r8) (:)] allocation to fine root C (gC/m2/s)
- frootc_xfer_to_frootc => cnveg_carbonflux_inst%frootc_xfer_to_frootc_patch , & ! Input: [real(r8) (:)] fine root C growth from storage (gC/m2/s)
- dormant_flag => cnveg_state_inst%dormant_flag_patch , & ! Input: [real(r8) (:)] dormancy flag
- root_depth => soilstate_inst%root_depth_patch , & ! InOut: [real(r8) (:)] current root depth
- dz => col%dz , & ! Input: layer thickness (m) (-nlevsno+1:nlevgrnd)
- zi => col%zi , & ! Input: interface level below a "z" level (m) (-nlevsno+0:nlevgrnd)
- rootfr => soilstate_inst%rootfr_patch , & ! Output: [real(r8) (:,:)] fraction of roots in each soil layer
- sucsat => soilstate_inst%sucsat_col , & ! Input: minimum soil suction (mm)
- soilpsi => soilstate_inst%soilpsi_col , & ! Input: soil water potential in each soil layer (MPa)
- sminn_vr => soilbiogeochem_nitrogenstate_inst%sminn_vr_col , & ! Iniput: [real(r8) (:,:)] (gN/m3) soil mineral N
- frootc => cnveg_carbonstate_inst%frootc_patch , & ! Input: [real(r8) (:)] (gC/m2) fine root C
- hui => crop_inst%hui_patch , & ! Input: [real(r8) (:)] crop patch heat unit index (growing degree-days); set to 0 at sowing and accumulated until harvest
- croplive => crop_inst%croplive_patch , & ! Input: [logical (:)] flag, true if planted, not harvested
- huigrain => cnveg_state_inst%huigrain_patch & ! Input: [real(r8) (:)] same to reach vegetative maturity
- )
-
-! set time steps
- dt = get_step_size_real()
-
-! set minpsi to permanent wilting point
- minpsi = -1.5_r8
-
- allocate(sumrswa(bounds%begp:bounds%endp))
- allocate(sumrsmn(bounds%begp:bounds%endp))
- allocate(sumfrootc(bounds%begp:bounds%endp))
- allocate(rswa(bounds%begp:bounds%endp,nlevgrnd))
- allocate(rsmn(bounds%begp:bounds%endp,nlevgrnd))
- allocate(w_limit(bounds%begp:bounds%endp))
-
-!initialize to 0
- w_limit(bounds%begp:bounds%endp) = 0._r8
- sumrswa(bounds%begp:bounds%endp) = 0._r8
- sumrsmn(bounds%begp:bounds%endp) = 0._r8
- sumfrootc(bounds%begp:bounds%endp) = 0._r8
- rswa(bounds%begp:bounds%endp,:) = 0._r8
- rsmn(bounds%begp:bounds%endp,:) = 0._r8
-
- frootc_dz(bounds%begp:bounds%endp,1:nlevgrnd) = 0._r8
-
-
-!---------------------------------------------------------------
-! Set root depth, dynamic for crops, fixed for other vegetation
-!---------------------------------------------------------------
-
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- if (ivt(p) /= noveg) then
- if((ivt(p)) >= npcropmin)then !skip generic crop types
- if (.not. croplive(p)) then
- root_depth(p) = 0._r8
- else if(huigrain(p) > 0._r8)then
- root_depth(p) = max(zi(c,2), min(hui(p)/huigrain(p)* root_dmx(ivt(p)), root_dmx(ivt(p))))
- end if
- else
- ! this can be changed to any depth (i.e. the maximum soil depth)
- root_depth(p) = zi(c,nlevsoi)
- end if
- if (use_bedrock) then
- root_depth(p) = min(root_depth(p),zi(c,col%nbedrock(c)))
- end if
- else
- root_depth(p) = 0._r8
- end if
- end do
-
-!----------------------------------------------------------------
-! ! calculate a weighting function by soil depth that depends on the
- ! fine root distribution per pft and depth and the pft weight on the column.
- ! This will be used to weight the temperature and water potential scalars
- ! for decomposition control.
-
- ! calculate the rate constant scalar for soil water content.
- ! Uses the log relationship with water potential given in
- ! Andren, O., and K. Paustian, 1987. Barley straw decomposition in the field:
- ! a comparison of models. Ecology, 68(5):1190-1200.
- ! and supported by data in
- ! Orchard, V.A., and F.J. Cook, 1983. Relationship between soil respiration
- ! and soil moisture. Soil Biol. Biochem., 15(4):447-453.
-
- do j = 1,nlevsoi
- do f = 1,num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- maxpsi = sucsat(c,j) * (-9.8e-6_r8)
- psi = min(soilpsi(c,j),maxpsi)
- if (psi > minpsi) then
-! First calculate water in the root zone
- if(root_depth(p) > 0.15_r8 .and. (zi(c,j) <= root_depth(p) .or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p)))) then
- w_limit(p) = w_limit(p) + max(0._r8,log(minpsi/psi)/log(minpsi/maxpsi))*rootfr(p,j)
- end if
-! Calculate the water in each soil layer
- if (root_depth(p) >= zi(c,j) .or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p))) then
- rswa(p,j) = max(0._r8, (log(minpsi/psi)/log(minpsi/maxpsi)))
- end if
- end if
- sumrswa(p) = sumrswa(p) + rswa(p,j)
-
-! Calculate the nitrogen profile in each layer
-! For now, the profile for each PFT is equivilent to the
-! column profile, in the future, this could be changed to a weighted profile
- rsmn(p,j) = sminn_vr(c,j)
- if (root_depth(p) >= zi(c,j).or. &
- (zi(c,j-1) < root_depth(p) .and. zi(c,j) > root_depth(p))) then
- sumrsmn(p) = sumrsmn(p) + rsmn(p,j)
- end if
- end do
- end do
-
-
-!--------------------------------------------------------------------
-! Now calculate the density of roots in each soil layer for each pft
-! based on this timesteps growth
-!--------------------------------------------------------------------
- do lev = 1, nlevgrnd
-
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
-
- new_growth = (cpool_to_frootc(p) + frootc_xfer_to_frootc(p))*dt
- if(zi(c,lev) <= root_depth(p) .or. &
- (zi(c,lev-1) < root_depth(p) .and. zi(c,lev) > root_depth(p))) then
- if(sumrswa(p) <= 0._r8 .or. sumrsmn(p) <= 0._r8) then
-! when sumrswa or sumrsmn are less than or equal to 0 rootfr will not be updated
- else
- frootc_dz(p,lev) = (frootc(p))*rootfr(p,lev) &
- + new_growth * ((1._r8 - w_limit(p)) * rswa(p,lev) / sumrswa(p) &
- + w_limit(p) * rsmn(p,lev) / sumrsmn(p))
- end if
- else
- frootc_dz(p,lev) = 0._r8
- end if
-
- sumfrootc(p) = sumfrootc(p) + frootc_dz(p,lev)
-
- end do
- end do
-!----------------------------------
-!Calculate root fraction
-!----------------------------------
-
- do lev = 1, nlevgrnd
- do f = 1, num_soilp
- p = filter_soilp(f)
- c = pcolumn(p)
- if(sumfrootc(p) > 0._r8)then
- rootfr(p,lev) = frootc_dz(p,lev)/sumfrootc(p)
- end if
- if(ivt(p) >= npcropmin .and. .not. croplive(p))then
-! CROPS are dormant, there are no roots!
-! but, need an initial frootr so crops can start root production
- if (lev < 2)then
- rootfr(p,lev) = .5_r8*( exp(-roota_par(patch%itype(p)) * zi(c,lev-1)) &
- + exp(-rootb_par(patch%itype(p)) * zi(c,lev-1)) &
- - exp(-roota_par(patch%itype(p)) * zi(c,lev )) &
- - exp(-rootb_par(patch%itype(p)) * zi(c,lev )) )
- elseif (lev == 2) then
- rootfr(p,lev) = .5_r8*( exp(-roota_par(patch%itype(p)) * zi(c,lev-1)) &
- + exp(-rootb_par(patch%itype(p)) * zi(c,lev-1)) )
- else
- rootfr(p,lev) = 0.0_r8
- end if
-
- end if
- end do
- end do
-
-!**********************
- deallocate(sumrswa)
- deallocate(sumrsmn)
- deallocate(sumfrootc)
- deallocate(rsmn)
- deallocate(rswa)
- deallocate(w_limit)
-
- end associate
-
- end subroutine CNRootDyn
-
-end module CNRootDynMod
diff --git a/src/biogeochem/CNSharedParamsMod.F90 b/src/biogeochem/CNSharedParamsMod.F90
index f4f5eb3bac..a178a0f7f0 100644
--- a/src/biogeochem/CNSharedParamsMod.F90
+++ b/src/biogeochem/CNSharedParamsMod.F90
@@ -35,7 +35,7 @@ module CNSharedParamsMod
! Public data
- logical, public, parameter :: use_matrixcn = .false. ! true => use cn matrix solution
+ logical, public :: use_matrixcn = .false. ! true => use cn matrix solution
logical, public :: use_fun = .false. ! Use the FUN2.0 model
integer, public :: nlev_soildecomp_standard = 5
integer, public :: upper_soil_layer = -1 ! Upper soil layer to use for 10-day average in CNPhenology
diff --git a/src/biogeochem/CNVegCarbonFluxType.F90 b/src/biogeochem/CNVegCarbonFluxType.F90
index 8210bafc97..b4c581c081 100644
--- a/src/biogeochem/CNVegCarbonFluxType.F90
+++ b/src/biogeochem/CNVegCarbonFluxType.F90
@@ -9,10 +9,17 @@ module CNVegCarbonFluxType
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_log_mod , only : errMsg => shr_log_errMsg
use decompMod , only : bounds_type
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
- use clm_varpar , only : nvegcpool
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools,&
+ nvegcpool,ncphtrans,ncgmtrans,ncfitrans,&
+ ncphouttrans,ncgmouttrans,ncfiouttrans
use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,ioutc
use clm_varpar , only : mxharvests
use clm_varcon , only : spval, dzsoi_decomp
use clm_varctl , only : use_cndv, use_c13, use_c14, use_nitrif_denitrif, use_crop
@@ -402,11 +409,112 @@ module CNVegCarbonFluxType
real(r8), pointer :: npp_growth_patch (:) ! Total C u for growth in FUN (gC/m2/s)
real(r8), pointer :: leafc_change_patch (:) ! Total used C from leaves (gC/m2/s)
real(r8), pointer :: soilc_change_patch (:) ! Total used C from soil (gC/m2/s)
- integer, pointer :: actpatch_fire (:) ! Patch indices with fire in current time step
- integer :: num_actpatch_fire ! Number of patches with fire in current time step
! Matrix solution arrays for C flux index
+ real(r8), pointer :: matrix_Cinput_patch (:) ! I-matrix for carbon input
+ real(r8), pointer :: matrix_C13input_patch (:) ! I-matrix for C13 input
+ real(r8), pointer :: matrix_C14input_patch (:) ! I-matrix for C14 input
+ real(r8), pointer :: matrix_alloc_patch (:,:) ! B-matrix for carbon allocation
+
+ real(r8), pointer :: matrix_phtransfer_patch (:,:) ! A-matrix_phenology
+ real(r8), pointer :: matrix_phturnover_patch (:,:) ! K-matrix_phenology
+ integer, pointer :: matrix_phtransfer_doner_patch (:) ! A-matrix_phenology non-zero indices (column indices)
+ integer, pointer :: matrix_phtransfer_receiver_patch (:) ! A-matrix_phenology non-zero indices (row indices)
+
+ real(r8), pointer :: matrix_gmtransfer_patch (:,:) ! A-matrix_gap mortality
+ real(r8), pointer :: matrix_gmturnover_patch (:,:) ! K-matrix_gap mortality
+ integer, pointer :: matrix_gmtransfer_doner_patch (:) ! A-matrix_gap mortality non-zero indices (column indices)
+ integer, pointer :: matrix_gmtransfer_receiver_patch (:) ! A-matrix_gap mortality non-zero indices (row indices)
+
+ real(r8), pointer :: matrix_fitransfer_patch (:,:) ! A-matrix_fire
+ real(r8), pointer :: matrix_fiturnover_patch (:,:) ! K-matrix_fire
+ integer, pointer :: matrix_fitransfer_doner_patch (:) ! A-matrix_fire non-zero indices (column indices)
+ integer, pointer :: matrix_fitransfer_receiver_patch (:) ! A-matrix_fire non-zero indices (row indices)
+
! Matrix variables
+ integer ileafst_to_ileafxf_ph ! Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ integer ileafxf_to_ileaf_ph ! Index of phenology related C transfer from leaf transfer pool to leaf pool
+ integer ifrootst_to_ifrootxf_ph ! Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ integer ifrootxf_to_ifroot_ph ! Index of phenology related C transfer from fine root transfer pool to fine root pool
+ integer ilivestemst_to_ilivestemxf_ph ! Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ integer ilivestemxf_to_ilivestem_ph ! Index of phenology related C transfer from live stem transfer pool to live stem pool
+ integer ideadstemst_to_ideadstemxf_ph ! Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ integer ideadstemxf_to_ideadstem_ph ! Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ integer ilivecrootst_to_ilivecrootxf_ph ! Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ integer ilivecrootxf_to_ilivecroot_ph ! Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ integer ideadcrootst_to_ideadcrootxf_ph ! Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ integer ideadcrootxf_to_ideadcroot_ph ! Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ integer ilivestem_to_ideadstem_ph ! Index of phenology related C transfer from live stem pool to dead stem pool
+ integer ilivecroot_to_ideadcroot_ph ! Index of phenology related C transfer from live coarse root pool to dead coarse root pool
+ integer ileaf_to_iout_ph ! Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ integer ifroot_to_iout_ph ! Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ integer ilivestem_to_iout_ph ! Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ integer igrain_to_iout_ph ! Index of phenology related C transfer from grain pool to outside of vegetation pools
+ integer ileaf_to_iout_gm ! Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_gm ! Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_gm ! Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_gm ! Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_gm ! Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_gm ! Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_gm ! Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_gm ! Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_gm ! Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_gm ! Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_gm ! Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_gm ! Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_gm ! Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_gm ! Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_gm ! Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_gm ! Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer ileaf_to_iout_fi ! Index of fire related C transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_fi ! Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_fi ! Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_fi ! Index of fire related C transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_fi ! Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_fi ! Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_fi ! Index of fire related C transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_fi ! Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_fi ! Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_fi ! Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_fi ! Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_fi ! Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_fi ! Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_fi ! Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_fi ! Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_fi ! Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_fi ! Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_fi ! Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer ilivestem_to_ideadstem_fi ! Index of fire related C transfer from live stem pool to dead stem pools
+ integer ilivecroot_to_ideadcroot_fi ! Index of fire related C transfer from live coarse root pool to dead coarse root pools
+
+ integer,pointer :: list_phc_phgmc (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphc to AKphc+AKgmc
+ integer,pointer :: list_gmc_phgmc (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmc to AKphc+AKgmc
+ integer,pointer :: list_phc_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphc to AKphc+AKgmc+AKfic
+ integer,pointer :: list_gmc_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmc to AKphc+AKgmc+AKfic
+ integer,pointer :: list_fic_phgmfic (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKfic to AKphc+AKgmc+AKfic
+ integer,pointer :: list_aphc (:) ! Indices of non-diagnoal entries in full sparse matrix Aph for C cycle
+ integer,pointer :: list_agmc (:) ! Indices of non-diagnoal entries in full sparse matrix Agm for C cycle
+ integer,pointer :: list_afic (:) ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+
+ type(sparse_matrix_type) :: AKphvegc ! Aph*Kph for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKgmvegc ! Agm*Kgm for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKfivegc ! Afi*Kfi for C cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKallvegc ! Aph*Kph + Agm*Kgm + Afi*Kfi for C cycle in sparse matrix format
+ integer :: NE_AKallvegc ! Number of entries in AKallvegc
+ integer,pointer,dimension(:) :: RI_AKallvegc ! Row indices in Akallvegc
+ integer,pointer,dimension(:) :: CI_AKallvegc ! Column indices in AKallvegc
+ integer,pointer,dimension(:) :: RI_phc ! Row indices of non-diagonal entires in Aph for C cycle
+ integer,pointer,dimension(:) :: CI_phc ! Column indices of non-diagonal entries in Aph for C cycle
+ integer,pointer,dimension(:) :: RI_gmc ! Row indices of non-diagonal entires in Agm for C cycle
+ integer,pointer,dimension(:) :: CI_gmc ! Column indices of non-diagonal entries in Agm for C cycle
+ integer,pointer,dimension(:) :: RI_fic ! Row indices of non-diagonal entires in Afi for C cycle
+ integer,pointer,dimension(:) :: CI_fic ! Column indices of non-diagonal entries in Afi for C cycle
+ type(diag_matrix_type) :: Kvegc ! Temporary variable of Kph, Kgm or Kfi for C cycle in diagonal matrix format
+ type(vector_type) :: Xvegc ! Vegetation C of each compartment in a vector format
+ type(vector_type) :: Xveg13c ! Vegetation C13 of each compartment in a vector format
+ type(vector_type) :: Xveg14c ! Vegetation C14 of each compartment in a vector format
! Objects that help convert once-per-year dynamic land cover changes into fluxes
! that are dribbled throughout the year
@@ -463,7 +571,233 @@ subroutine InitTransfer (this)
!
! !AGRUMENTS:
class (cnveg_carbonflux_type) :: this
-
+
+ this%ileafst_to_ileafxf_ph = 1
+ this%matrix_phtransfer_doner_patch(this%ileafst_to_ileafxf_ph) = ileaf_st
+ this%matrix_phtransfer_receiver_patch(this%ileafst_to_ileafxf_ph) = ileaf_xf
+
+ this%ileafxf_to_ileaf_ph = 2
+ this%matrix_phtransfer_doner_patch(this%ileafxf_to_ileaf_ph) = ileaf_xf
+ this%matrix_phtransfer_receiver_patch(this%ileafxf_to_ileaf_ph) = ileaf
+
+ this%ifrootst_to_ifrootxf_ph = 3
+ this%matrix_phtransfer_doner_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_st
+ this%matrix_phtransfer_receiver_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_xf
+
+ this%ifrootxf_to_ifroot_ph = 4
+ this%matrix_phtransfer_doner_patch(this%ifrootxf_to_ifroot_ph) = ifroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ifrootxf_to_ifroot_ph) = ifroot
+
+ this%ilivestem_to_ideadstem_ph = 5
+ this%matrix_phtransfer_doner_patch(this%ilivestem_to_ideadstem_ph) = ilivestem
+ this%matrix_phtransfer_receiver_patch(this%ilivestem_to_ideadstem_ph) = ideadstem
+
+ this%ilivestemst_to_ilivestemxf_ph = 6
+ this%matrix_phtransfer_doner_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_st
+ this%matrix_phtransfer_receiver_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_xf
+
+ this%ilivestemxf_to_ilivestem_ph = 7
+ this%matrix_phtransfer_doner_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem_xf
+ this%matrix_phtransfer_receiver_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem
+
+ this%ideadstemst_to_ideadstemxf_ph = 8
+ this%matrix_phtransfer_doner_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_st
+ this%matrix_phtransfer_receiver_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_xf
+
+ this%ideadstemxf_to_ideadstem_ph = 9
+ this%matrix_phtransfer_doner_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem_xf
+ this%matrix_phtransfer_receiver_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_ph = 10
+ this%matrix_phtransfer_doner_patch(this%ilivecroot_to_ideadcroot_ph) = ilivecroot
+ this%matrix_phtransfer_receiver_patch(this%ilivecroot_to_ideadcroot_ph) = ideadcroot
+
+ this%ilivecrootst_to_ilivecrootxf_ph = 11
+ this%matrix_phtransfer_doner_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_st
+ this%matrix_phtransfer_receiver_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_xf
+
+ this%ilivecrootxf_to_ilivecroot_ph = 12
+ this%matrix_phtransfer_doner_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot
+
+ this%ideadcrootst_to_ideadcrootxf_ph = 13
+ this%matrix_phtransfer_doner_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_st
+ this%matrix_phtransfer_receiver_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_xf
+
+ this%ideadcrootxf_to_ideadcroot_ph = 14
+ this%matrix_phtransfer_doner_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot_xf
+ this%matrix_phtransfer_receiver_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot
+
+ this%ileaf_to_iout_ph = 15
+ this%matrix_phtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_phtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutc
+
+ this%ifroot_to_iout_ph = 16
+ this%matrix_phtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_phtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutc
+
+ this%ilivestem_to_iout_ph = 17
+ this%matrix_phtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_phtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutc
+
+ if(use_crop)then
+ this%igrain_to_iout_ph = 18
+ this%matrix_phtransfer_doner_patch(this%igrain_to_iout_ph) = igrain
+ this%matrix_phtransfer_receiver_patch(this%igrain_to_iout_ph) = ioutc
+ end if
+
+ this%ileaf_to_iout_gm = 1
+ this%matrix_gmtransfer_doner_patch(this%ileaf_to_iout_gm) = ileaf
+ this%matrix_gmtransfer_receiver_patch(this%ileaf_to_iout_gm) = ioutc
+
+ this%ileafst_to_iout_gm = 2
+ this%matrix_gmtransfer_doner_patch(this%ileafst_to_iout_gm) = ileaf_st
+ this%matrix_gmtransfer_receiver_patch(this%ileafst_to_iout_gm) = ioutc
+
+ this%ileafxf_to_iout_gm = 3
+ this%matrix_gmtransfer_doner_patch(this%ileafxf_to_iout_gm) = ileaf_xf
+ this%matrix_gmtransfer_receiver_patch(this%ileafxf_to_iout_gm) = ioutc
+
+ this%ifroot_to_iout_gm = 4
+ this%matrix_gmtransfer_doner_patch(this%ifroot_to_iout_gm) = ifroot
+ this%matrix_gmtransfer_receiver_patch(this%ifroot_to_iout_gm) = ioutc
+
+ this%ifrootst_to_iout_gm = 5
+ this%matrix_gmtransfer_doner_patch(this%ifrootst_to_iout_gm) = ifroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ifrootst_to_iout_gm) = ioutc
+
+ this%ifrootxf_to_iout_gm = 6
+ this%matrix_gmtransfer_doner_patch(this%ifrootxf_to_iout_gm) = ifroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ifrootxf_to_iout_gm) = ioutc
+
+ this%ilivestem_to_iout_gm = 7
+ this%matrix_gmtransfer_doner_patch(this%ilivestem_to_iout_gm) = ilivestem
+ this%matrix_gmtransfer_receiver_patch(this%ilivestem_to_iout_gm) = ioutc
+
+ this%ilivestemst_to_iout_gm = 8
+ this%matrix_gmtransfer_doner_patch(this%ilivestemst_to_iout_gm) = ilivestem_st
+ this%matrix_gmtransfer_receiver_patch(this%ilivestemst_to_iout_gm) = ioutc
+
+ this%ilivestemxf_to_iout_gm = 9
+ this%matrix_gmtransfer_doner_patch(this%ilivestemxf_to_iout_gm) = ilivestem_xf
+ this%matrix_gmtransfer_receiver_patch(this%ilivestemxf_to_iout_gm) = ioutc
+
+ this%ideadstem_to_iout_gm = 10
+ this%matrix_gmtransfer_doner_patch(this%ideadstem_to_iout_gm) = ideadstem
+ this%matrix_gmtransfer_receiver_patch(this%ideadstem_to_iout_gm) = ioutc
+
+ this%ideadstemst_to_iout_gm = 11
+ this%matrix_gmtransfer_doner_patch(this%ideadstemst_to_iout_gm) = ideadstem_st
+ this%matrix_gmtransfer_receiver_patch(this%ideadstemst_to_iout_gm) = ioutc
+
+ this%ideadstemxf_to_iout_gm = 12
+ this%matrix_gmtransfer_doner_patch(this%ideadstemxf_to_iout_gm) = ideadstem_xf
+ this%matrix_gmtransfer_receiver_patch(this%ideadstemxf_to_iout_gm) = ioutc
+
+ this%ilivecroot_to_iout_gm = 13
+ this%matrix_gmtransfer_doner_patch(this%ilivecroot_to_iout_gm) = ilivecroot
+ this%matrix_gmtransfer_receiver_patch(this%ilivecroot_to_iout_gm) = ioutc
+
+ this%ilivecrootst_to_iout_gm = 14
+ this%matrix_gmtransfer_doner_patch(this%ilivecrootst_to_iout_gm) = ilivecroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ilivecrootst_to_iout_gm) = ioutc
+
+ this%ilivecrootxf_to_iout_gm = 15
+ this%matrix_gmtransfer_doner_patch(this%ilivecrootxf_to_iout_gm) = ilivecroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ilivecrootxf_to_iout_gm) = ioutc
+
+ this%ideadcroot_to_iout_gm = 16
+ this%matrix_gmtransfer_doner_patch(this%ideadcroot_to_iout_gm) = ideadcroot
+ this%matrix_gmtransfer_receiver_patch(this%ideadcroot_to_iout_gm) = ioutc
+
+ this%ideadcrootst_to_iout_gm = 17
+ this%matrix_gmtransfer_doner_patch(this%ideadcrootst_to_iout_gm) = ideadcroot_st
+ this%matrix_gmtransfer_receiver_patch(this%ideadcrootst_to_iout_gm) = ioutc
+
+ this%ideadcrootxf_to_iout_gm = 18
+ this%matrix_gmtransfer_doner_patch(this%ideadcrootxf_to_iout_gm) = ideadcroot_xf
+ this%matrix_gmtransfer_receiver_patch(this%ideadcrootxf_to_iout_gm) = ioutc
+
+ this%ilivestem_to_ideadstem_fi = 1
+ this%matrix_fitransfer_doner_patch(this%ilivestem_to_ideadstem_fi) = ilivestem
+ this%matrix_fitransfer_receiver_patch(this%ilivestem_to_ideadstem_fi) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_fi = 2
+ this%matrix_fitransfer_doner_patch(this%ilivecroot_to_ideadcroot_fi) = ilivecroot
+ this%matrix_fitransfer_receiver_patch(this%ilivecroot_to_ideadcroot_fi) = ideadcroot
+
+ this%ileaf_to_iout_fi = 3
+ this%matrix_fitransfer_doner_patch(this%ileaf_to_iout_fi) = ileaf
+ this%matrix_fitransfer_receiver_patch(this%ileaf_to_iout_fi) = ioutc
+
+ this%ileafst_to_iout_fi = 4
+ this%matrix_fitransfer_doner_patch(this%ileafst_to_iout_fi) = ileaf_st
+ this%matrix_fitransfer_receiver_patch(this%ileafst_to_iout_fi) = ioutc
+
+ this%ileafxf_to_iout_fi = 5
+ this%matrix_fitransfer_doner_patch(this%ileafxf_to_iout_fi) = ileaf_xf
+ this%matrix_fitransfer_receiver_patch(this%ileafxf_to_iout_fi) = ioutc
+
+ this%ifroot_to_iout_fi = 6
+ this%matrix_fitransfer_doner_patch(this%ifroot_to_iout_fi) = ifroot
+ this%matrix_fitransfer_receiver_patch(this%ifroot_to_iout_fi) = ioutc
+
+ this%ifrootst_to_iout_fi = 7
+ this%matrix_fitransfer_doner_patch(this%ifrootst_to_iout_fi) = ifroot_st
+ this%matrix_fitransfer_receiver_patch(this%ifrootst_to_iout_fi) = ioutc
+
+ this%ifrootxf_to_iout_fi = 8
+ this%matrix_fitransfer_doner_patch(this%ifrootxf_to_iout_fi) = ifroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ifrootxf_to_iout_fi) = ioutc
+
+ this%ilivestem_to_iout_fi = 9
+ this%matrix_fitransfer_doner_patch(this%ilivestem_to_iout_fi) = ilivestem
+ this%matrix_fitransfer_receiver_patch(this%ilivestem_to_iout_fi) = ioutc
+
+ this%ilivestemst_to_iout_fi = 10
+ this%matrix_fitransfer_doner_patch(this%ilivestemst_to_iout_fi) = ilivestem_st
+ this%matrix_fitransfer_receiver_patch(this%ilivestemst_to_iout_fi) = ioutc
+
+ this%ilivestemxf_to_iout_fi = 11
+ this%matrix_fitransfer_doner_patch(this%ilivestemxf_to_iout_fi) = ilivestem_xf
+ this%matrix_fitransfer_receiver_patch(this%ilivestemxf_to_iout_fi) = ioutc
+
+ this%ideadstem_to_iout_fi = 12
+ this%matrix_fitransfer_doner_patch(this%ideadstem_to_iout_fi) = ideadstem
+ this%matrix_fitransfer_receiver_patch(this%ideadstem_to_iout_fi) = ioutc
+
+ this%ideadstemst_to_iout_fi = 13
+ this%matrix_fitransfer_doner_patch(this%ideadstemst_to_iout_fi) = ideadstem_st
+ this%matrix_fitransfer_receiver_patch(this%ideadstemst_to_iout_fi) = ioutc
+
+ this%ideadstemxf_to_iout_fi = 14
+ this%matrix_fitransfer_doner_patch(this%ideadstemxf_to_iout_fi) = ideadstem_xf
+ this%matrix_fitransfer_receiver_patch(this%ideadstemxf_to_iout_fi) = ioutc
+
+ this%ilivecroot_to_iout_fi = 15
+ this%matrix_fitransfer_doner_patch(this%ilivecroot_to_iout_fi) = ilivecroot
+ this%matrix_fitransfer_receiver_patch(this%ilivecroot_to_iout_fi) = ioutc
+
+ this%ilivecrootst_to_iout_fi = 16
+ this%matrix_fitransfer_doner_patch(this%ilivecrootst_to_iout_fi) = ilivecroot_st
+ this%matrix_fitransfer_receiver_patch(this%ilivecrootst_to_iout_fi) = ioutc
+
+ this%ilivecrootxf_to_iout_fi = 17
+ this%matrix_fitransfer_doner_patch(this%ilivecrootxf_to_iout_fi) = ilivecroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ilivecrootxf_to_iout_fi) = ioutc
+
+ this%ideadcroot_to_iout_fi = 18
+ this%matrix_fitransfer_doner_patch(this%ideadcroot_to_iout_fi) = ideadcroot
+ this%matrix_fitransfer_receiver_patch(this%ideadcroot_to_iout_fi) = ioutc
+
+ this%ideadcrootst_to_iout_fi = 19
+ this%matrix_fitransfer_doner_patch(this%ideadcrootst_to_iout_fi) = ideadcroot_st
+ this%matrix_fitransfer_receiver_patch(this%ideadcrootst_to_iout_fi) = ioutc
+
+ this%ideadcrootxf_to_iout_fi = 20
+ this%matrix_fitransfer_doner_patch(this%ideadcrootxf_to_iout_fi) = ideadcroot_xf
+ this%matrix_fitransfer_receiver_patch(this%ideadcrootxf_to_iout_fi) = ioutc
+
end subroutine InitTransfer
!------------------------------------------------------------------------
@@ -839,6 +1173,58 @@ subroutine InitAllocate(this, bounds, carbon_type, alloc_full_veg)
allocate(this%soilc_change_patch (begp:endp)) ; this%soilc_change_patch (:) = nan
! Allocate Matrix data
if(use_matrixcn)then
+ allocate(this%matrix_Cinput_patch (begp:endp)) ; this%matrix_Cinput_patch (:) = nan
+ allocate(this%matrix_C13input_patch (begp:endp)) ; this%matrix_C13input_patch (:) = nan !for isotop
+ allocate(this%matrix_C14input_patch (begp:endp)) ; this%matrix_C14input_patch (:) = nan
+ allocate(this%matrix_alloc_patch (begp:endp,1:nvegcpool)) ; this%matrix_alloc_patch (:,:) = nan
+
+ allocate(this%matrix_phtransfer_patch (begp:endp,1:ncphtrans)) ; this%matrix_phtransfer_patch (:,:) = nan
+ allocate(this%matrix_phturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_phturnover_patch (:,:) = nan
+ allocate(this%matrix_phtransfer_doner_patch (1:ncphtrans)) ; this%matrix_phtransfer_doner_patch(:) = -9999
+ allocate(this%matrix_phtransfer_receiver_patch (1:ncphtrans)) ; this%matrix_phtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_gmtransfer_patch (begp:endp,1:ncgmtrans)) ; this%matrix_gmtransfer_patch (:,:) = nan
+ allocate(this%matrix_gmturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_gmturnover_patch (:,:) = nan
+ allocate(this%matrix_gmtransfer_doner_patch (1:ncgmtrans)) ; this%matrix_gmtransfer_doner_patch(:) = -9999
+ allocate(this%matrix_gmtransfer_receiver_patch (1:ncgmtrans)) ; this%matrix_gmtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_fitransfer_patch (begp:endp,1:ncfitrans)) ; this%matrix_fitransfer_patch (:,:) = nan
+ allocate(this%matrix_fiturnover_patch (begp:endp,1:nvegcpool)) ; this%matrix_fiturnover_patch (:,:) = nan
+ allocate(this%matrix_fitransfer_doner_patch (1:ncfitrans)) ; this%matrix_fitransfer_doner_patch(:) = -9999
+ allocate(this%matrix_fitransfer_receiver_patch (1:ncfitrans)) ; this%matrix_fitransfer_receiver_patch(:) = -9999
+
+ allocate(this%list_phc_phgmc (1:ncphtrans+nvegcpool)) ; this%list_phc_phgmc(:) = -9999
+ allocate(this%list_gmc_phgmc (1:nvegcpool)) ; this%list_gmc_phgmc(:) = -9999
+ allocate(this%list_phc_phgmfic (1:ncphtrans+nvegcpool)); this%list_phc_phgmfic(:) = -9999
+ allocate(this%list_gmc_phgmfic (1:nvegcpool)) ; this%list_gmc_phgmfic(:) = -9999
+ allocate(this%list_fic_phgmfic (1:ncfitrans+nvegcpool)); this%list_fic_phgmfic(:) = -9999
+
+ allocate(this%list_aphc(1:ncphtrans-ncphouttrans)); this%list_aphc = -9999
+ allocate(this%list_agmc(1:ncgmtrans-ncgmouttrans)); this%list_agmc = -9999
+ allocate(this%list_afic(1:ncfitrans-ncfiouttrans)); this%list_afic = -9999
+
+ call this%AKphvegc%InitSM(nvegcpool,begp,endp,ncphtrans-ncphouttrans+nvegcpool)
+ call this%AKgmvegc%InitSM(nvegcpool,begp,endp,ncgmtrans-ncgmouttrans+nvegcpool)
+ call this%AKfivegc%InitSM(nvegcpool,begp,endp,ncfitrans-ncfiouttrans+nvegcpool)
+ call this%AKallvegc%InitSM(nvegcpool,begp,endp,ncphtrans-ncphouttrans+ncfitrans-ncfiouttrans+nvegcpool)
+ this%NE_AKallvegc = (ncphtrans-ncphouttrans+nvegcpool) + (ncgmtrans-ncgmouttrans+nvegcpool) + &
+ ncfitrans-ncfiouttrans+nvegcpool
+ allocate(this%RI_AKallvegc(1:this%NE_AKallvegc));this%RI_AKallvegc(:) = -9999
+ allocate(this%CI_AKallvegc(1:this%NE_AKallvegc));this%CI_AKallvegc(:) = -9999
+ allocate(this%RI_phc(1:ncphtrans-ncphouttrans+nvegcpool));this%RI_phc(:) = -9999
+ allocate(this%CI_phc(1:ncphtrans-ncphouttrans+nvegcpool));this%CI_phc(:) = -9999
+ allocate(this%RI_gmc(1:ncgmtrans-ncgmouttrans+nvegcpool));this%RI_gmc(:) = -9999
+ allocate(this%CI_gmc(1:ncgmtrans-ncgmouttrans+nvegcpool));this%CI_gmc(:) = -9999
+ allocate(this%RI_fic(1:ncfitrans-ncfiouttrans+nvegcpool));this%RI_fic(:) = -9999
+ allocate(this%CI_fic(1:ncfitrans-ncfiouttrans+nvegcpool));this%CI_fic(:) = -9999
+ call this%Kvegc%InitDM(nvegcpool,begp,endp)
+ call this%Xvegc%InitV(nvegcpool,begp,endp)
+ if(use_c13)then
+ call this%Xveg13c%InitV(nvegcpool,begp,endp)
+ end if
+ if(use_c14)then
+ call this%Xveg14c%InitV(nvegcpool,begp,endp)
+ end if
end if
! Construct restart field names consistently to what is done in SpeciesNonIsotope &
@@ -3574,6 +3960,9 @@ subroutine InitCold(this, bounds)
if (lun%ifspecial(l)) then
this%availc_patch(p) = spval
if(use_matrixcn)then
+ this%matrix_Cinput_patch(p) = spval
+ this%matrix_C13input_patch(p) = spval
+ this%matrix_C14input_patch(p) = spval
end if
this%xsmrpool_recover_patch(p) = spval
this%excess_cflux_patch(p) = spval
@@ -3588,6 +3977,9 @@ subroutine InitCold(this, bounds)
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
this%availc_patch(p) = 0._r8
if(use_matrixcn)then
+ this%matrix_Cinput_patch(p) = 0._r8
+ this%matrix_C13input_patch(p) = 0._r8
+ this%matrix_C14input_patch(p) = 0._r8
end if
this%xsmrpool_recover_patch(p) = 0._r8
this%excess_cflux_patch(p) = 0._r8
@@ -4194,6 +4586,9 @@ subroutine SetValues ( this, nvegcpool, &
this%crop_harvestc_to_cropprodc_patch(i) = value_patch
! Matrix
if(use_matrixcn)then
+ this%matrix_Cinput_patch(i) = value_patch
+ this%matrix_C13input_patch(i) = value_patch
+ this%matrix_C14input_patch(i) = value_patch
end if
end do
@@ -4208,6 +4603,36 @@ subroutine SetValues ( this, nvegcpool, &
! Set Matrix elements
if(use_matrixcn)then
+ do j = 1, nvegcpool
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_alloc_patch(i,j) = value_patch
+ this%matrix_phturnover_patch (i,j) = value_patch
+ this%matrix_gmturnover_patch (i,j) = value_patch
+ this%matrix_fiturnover_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncphtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_phtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncgmtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_gmtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, ncfitrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_fitransfer_patch (i,j) = value_patch
+ end do
+ end do
end if
if ( use_crop )then
diff --git a/src/biogeochem/CNVegCarbonStateType.F90 b/src/biogeochem/CNVegCarbonStateType.F90
index c7e21da1d6..aee328a45e 100644
--- a/src/biogeochem/CNVegCarbonStateType.F90
+++ b/src/biogeochem/CNVegCarbonStateType.F90
@@ -9,7 +9,7 @@ module CNVegCarbonStateType
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_const_mod , only : SHR_CONST_PDB
use shr_log_mod , only : errMsg => shr_log_errMsg
- use pftconMod , only : noveg, npcropmin, pftcon, nc3crop, nc3irrig
+ use pftconMod , only : noveg, npcropmin, pftcon, nc3crop, nc3irrig
use clm_varcon , only : spval, c3_r2, c4_r2, c14ratio
use clm_varctl , only : iulog, use_cndv, use_crop
use CNSharedParamsMod, only : use_matrixcn
@@ -36,33 +36,50 @@ module CNVegCarbonStateType
real(r8), pointer :: reproductivec_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C (crop model)
real(r8), pointer :: reproductivec_storage_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C storage (crop model)
real(r8), pointer :: reproductivec_xfer_patch (:,:) ! (gC/m2) reproductive (e.g., grain) C transfer (crop model)
+ real(r8), pointer :: matrix_cap_reproc_patch (:) ! (gC/m2) Capacity of grain C
+ real(r8), pointer :: matrix_cap_reproc_storage_patch (:) ! (gC/m2) Capacity of grain storage C
+ real(r8), pointer :: matrix_cap_reproc_xfer_patch (:) ! (gC/m2) Capacity of grain transfer C
real(r8), pointer :: leafc_patch (:) ! (gC/m2) leaf C
real(r8), pointer :: leafc_storage_patch (:) ! (gC/m2) leaf C storage
real(r8), pointer :: leafc_xfer_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: matrix_cap_leafc_patch (:) ! (gC/m2) Capacity of leaf C
+ real(r8), pointer :: matrix_cap_leafc_storage_patch (:) ! (gC/m2) Capacity of leaf C storage
+ real(r8), pointer :: matrix_cap_leafc_xfer_patch (:) ! (gC/m2) Capacity of leaf C transfer
real(r8), pointer :: leafc_storage_xfer_acc_patch (:) ! (gC/m2) Accmulated leaf C transfer
real(r8), pointer :: storage_cdemand_patch (:) ! (gC/m2) C use from the C storage pool
real(r8), pointer :: frootc_patch (:) ! (gC/m2) fine root C
real(r8), pointer :: frootc_storage_patch (:) ! (gC/m2) fine root C storage
real(r8), pointer :: frootc_xfer_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: matrix_cap_frootc_patch (:) ! (gC/m2) Capacity of fine root C
+ real(r8), pointer :: matrix_cap_frootc_storage_patch (:) ! (gC/m2) Capacity of fine root C storage
+ real(r8), pointer :: matrix_cap_frootc_xfer_patch (:) ! (gC/m2) Capacity of fine root C transfer
real(r8), pointer :: livestemc_patch (:) ! (gC/m2) live stem C
real(r8), pointer :: livestemc_storage_patch (:) ! (gC/m2) live stem C storage
real(r8), pointer :: livestemc_xfer_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: matrix_cap_livestemc_patch (:) ! (gC/m2) Capacity of live stem C
+ real(r8), pointer :: matrix_cap_livestemc_storage_patch (:) ! (gC/m2) Capacity of live stem C storage
+ real(r8), pointer :: matrix_cap_livestemc_xfer_patch (:) ! (gC/m2) Capacity of live stem C transfer
real(r8), pointer :: deadstemc_patch (:) ! (gC/m2) dead stem C
real(r8), pointer :: deadstemc_storage_patch (:) ! (gC/m2) dead stem C storage
real(r8), pointer :: deadstemc_xfer_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: matrix_cap_deadstemc_patch (:) ! (gC/m2) Capacity of dead stem C
+ real(r8), pointer :: matrix_cap_deadstemc_storage_patch (:) ! (gC/m2) Capacity of dead stem C storage
+ real(r8), pointer :: matrix_cap_deadstemc_xfer_patch (:) ! (gC/m2) Capacity of dead stem C transfer
real(r8), pointer :: livecrootc_patch (:) ! (gC/m2) live coarse root C
real(r8), pointer :: livecrootc_storage_patch (:) ! (gC/m2) live coarse root C storage
real(r8), pointer :: livecrootc_xfer_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: matrix_cap_livecrootc_patch (:) ! (gC/m2) Capacity of live coarse root C
+ real(r8), pointer :: matrix_cap_livecrootc_storage_patch (:) ! (gC/m2) Capacity of live coarse root C storage
+ real(r8), pointer :: matrix_cap_livecrootc_xfer_patch (:) ! (gC/m2) Capacity of live coarse root C transfer
real(r8), pointer :: deadcrootc_patch (:) ! (gC/m2) dead coarse root C
real(r8), pointer :: deadcrootc_storage_patch (:) ! (gC/m2) dead coarse root C storage
real(r8), pointer :: deadcrootc_xfer_patch (:) ! (gC/m2) dead coarse root C transfer
+ real(r8), pointer :: matrix_cap_deadcrootc_patch (:) ! (gC/m2) Capacity of dead coarse root C
+ real(r8), pointer :: matrix_cap_deadcrootc_storage_patch (:) ! (gC/m2) Capacity of dead coarse root C storage
+ real(r8), pointer :: matrix_cap_deadcrootc_xfer_patch (:) ! (gC/m2) Capacity of dead coarse root C transfer
real(r8), pointer :: gresp_storage_patch (:) ! (gC/m2) growth respiration storage
real(r8), pointer :: gresp_xfer_patch (:) ! (gC/m2) growth respiration transfer
real(r8), pointer :: cpool_patch (:) ! (gC/m2) temporary photosynthate C pool
- ! Matrix data
- ! Initial pool size for matrix spinup
- ! Assumulation variables for matrix spinup as well as calculation of diagnostic variables
- ! Transfer pools
real(r8), pointer :: xsmrpool_patch (:) ! (gC/m2) abstract C pool to meet excess MR demand
real(r8), pointer :: xsmrpool_loss_patch (:) ! (gC/m2) abstract C pool to meet excess MR demand loss
real(r8), pointer :: ctrunc_patch (:) ! (gC/m2) patch-level sink for C truncation
@@ -74,6 +91,28 @@ module CNVegCarbonStateType
real(r8), pointer :: fuelc_col (:) ! fuel load outside cropland
real(r8), pointer :: fuelc_crop_col (:) ! fuel load for cropland
real(r8), pointer :: cropseedc_deficit_patch (:) ! (gC/m2) pool for seeding new crop growth; this is a NEGATIVE term, indicating the amount of seed usage that needs to be repaid
+! initial pool size of year for matrix
+ real(r8), pointer :: leafc0_patch (:) ! (gC/m2) Initial value of leaf C for SASU
+ real(r8), pointer :: leafc0_storage_patch (:) ! (gC/m2) Initial value of leaf C storage for SASU
+ real(r8), pointer :: leafc0_xfer_patch (:) ! (gC/m2) Initial value of leaf C transfer for SASU
+ real(r8), pointer :: frootc0_patch (:) ! (gC/m2) Initial value of fine root C for SASU
+ real(r8), pointer :: frootc0_storage_patch (:) ! (gC/m2) Initial value of fine root C storage for SASU
+ real(r8), pointer :: frootc0_xfer_patch (:) ! (gC/m2) Initial value of fine root C transfer for SASU
+ real(r8), pointer :: livestemc0_patch (:) ! (gC/m2) Initial value of live stem C for SASU
+ real(r8), pointer :: livestemc0_storage_patch (:) ! (gC/m2) Initial value of live stem C storage for SASU
+ real(r8), pointer :: livestemc0_xfer_patch (:) ! (gC/m2) Initial value of live stem C transfer for SASU
+ real(r8), pointer :: deadstemc0_patch (:) ! (gC/m2) Initial value of dead stem C for SASU
+ real(r8), pointer :: deadstemc0_storage_patch (:) ! (gC/m2) Initial value of dead stem C storage for SASU
+ real(r8), pointer :: deadstemc0_xfer_patch (:) ! (gC/m2) Initial value of dead stem C transfer for SASU
+ real(r8), pointer :: livecrootc0_patch (:) ! (gC/m2) Initial value of live coarse root C for SASU
+ real(r8), pointer :: livecrootc0_storage_patch (:) ! (gC/m2) Initial value of live coarse root C storage for SASU
+ real(r8), pointer :: livecrootc0_xfer_patch (:) ! (gC/m2) Initial value of live coarse root C transfer for SASU
+ real(r8), pointer :: deadcrootc0_patch (:) ! (gC/m2) Initial value of dead coarse root C for SASU
+ real(r8), pointer :: deadcrootc0_storage_patch (:) ! (gC/m2) Initial value of dead coarse root C storage for SASU
+ real(r8), pointer :: deadcrootc0_xfer_patch (:) ! (gC/m2) Initial value of dead coarse root C transfer for SASU
+ real(r8), pointer :: reproc0_patch (:) ! (gC/m2) Initial value of fine grain C for SASU
+ real(r8), pointer :: reproc0_storage_patch (:) ! (gC/m2) Initial value of fine grain C storage for SASU
+ real(r8), pointer :: reproc0_xfer_patch (:) ! (gC/m2) Initial value of fine grain C transfer for SASU
! pools for dynamic landcover
real(r8), pointer :: seedc_grc (:) ! (gC/m2) gridcell-level pool for seeding new PFTs via dynamic landcover
@@ -90,7 +129,83 @@ module CNVegCarbonStateType
real(r8), pointer :: totvegc_patch (:) ! (gC/m2) total vegetation carbon, excluding cpool
real(r8), pointer :: totvegc_col (:) ! (gC/m2) total vegetation carbon, excluding cpool averaged to column (p2c)
real(r8), pointer :: totc_p2c_col (:) ! (gC/m2) totc_patch averaged to col
-
+
+! Accumulation variables are accumulated for a whole year. They are used for matrix spinup and calculation of diagnostic variables
+ real(r8), pointer :: matrix_calloc_leaf_acc_patch (:) ! (gC/m2/year) Input C allocated to leaf during this year
+ real(r8), pointer :: matrix_calloc_leafst_acc_patch (:) ! (gC/m2/year) Input C allocated to leaf storage during this year
+ real(r8), pointer :: matrix_calloc_froot_acc_patch (:) ! (gC/m2/year) Input C allocated to fine root during this year
+ real(r8), pointer :: matrix_calloc_frootst_acc_patch (:) ! (gC/m2/year) Input C allocated to fine root storage during this year
+ real(r8), pointer :: matrix_calloc_livestem_acc_patch (:) ! (gC/m2/year) Input C allocated to live stem during this year
+ real(r8), pointer :: matrix_calloc_livestemst_acc_patch (:) ! (gC/m2/year) Input C allocated to live stem storage during this year
+ real(r8), pointer :: matrix_calloc_deadstem_acc_patch (:) ! (gC/m2/year) Input C allocated to dead stem during this year
+ real(r8), pointer :: matrix_calloc_deadstemst_acc_patch (:) ! (gC/m2/year) Input C allocated to dead stem storage during this year
+ real(r8), pointer :: matrix_calloc_livecroot_acc_patch (:) ! (gC/m2/year) Input C allocated to live coarse root during this year
+ real(r8), pointer :: matrix_calloc_livecrootst_acc_patch (:) ! (gC/m2/year) Input C allocated to live coarse root storage during this year
+ real(r8), pointer :: matrix_calloc_deadcroot_acc_patch (:) ! (gC/m2/year) Input C allocated to dead coarse root during this year
+ real(r8), pointer :: matrix_calloc_deadcrootst_acc_patch (:) ! (gC/m2/year) Input C allocated to dead coarse root storage during this year
+ real(r8), pointer :: matrix_calloc_grain_acc_patch (:) ! (gC/m2/year) Input C allocated to grain during this year
+ real(r8), pointer :: matrix_calloc_grainst_acc_patch (:) ! (gC/m2/year) Input C allocated to grain storage during this year
+
+ real(r8), pointer :: matrix_ctransfer_leafst_to_leafxf_acc_patch (:) ! (gC/m2/year) C transfer from leaf storage to leaf transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_leafxf_to_leaf_acc_patch (:) ! (gC/m2/year) C transfer from leaf transfer to leaf pool during this year
+ real(r8), pointer :: matrix_ctransfer_frootst_to_frootxf_acc_patch (:) ! (gC/m2/year) C transfer from fine root storage to fine root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_frootxf_to_froot_acc_patch (:) ! (gC/m2/year) C transfer from fine root transfer to fine root pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestemst_to_livestemxf_acc_patch (:) ! (gC/m2/year) C transfer from live stem storage to live stem transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestemxf_to_livestem_acc_patch (:) ! (gC/m2/year) C transfer from live stem transfer to live stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (:) ! (gC/m2/year) C transfer from dead stem storage to dead stem transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (:) ! (gC/m2/year) C transfer from dead stem transfer to dead stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root storage to live coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root transfer to live coarse root pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (:) ! (gC/m2/year) C transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (:) ! (gC/m2/year) C transfer from dead coarse root transfer to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ctransfer_grainst_to_grainxf_acc_patch (:) ! (gC/m2/year) C transfer from grain storage to grain transfer pool during this year
+ real(r8), pointer :: matrix_ctransfer_grainxf_to_grain_acc_patch (:) ! (gC/m2/year) C transfer from grain transfer to grain pool during this year
+ real(r8), pointer :: matrix_ctransfer_livestem_to_deadstem_acc_patch (:) ! (gC/m2/year) C transfer from live stem to dead stem pool during this year
+ real(r8), pointer :: matrix_ctransfer_livecroot_to_deadcroot_acc_patch (:) ! (gC/m2/year) C transfer from live coarse root to dead coarse root pool during this year
+
+ real(r8), pointer :: matrix_cturnover_leaf_acc_patch (:) ! (gC/m2/year) C turnover from leaf
+ real(r8), pointer :: matrix_cturnover_leafst_acc_patch (:) ! (gC/m2/year) C turnover from leaf storage
+ real(r8), pointer :: matrix_cturnover_leafxf_acc_patch (:) ! (gC/m2/year) C turnover from leaf transfer
+ real(r8), pointer :: matrix_cturnover_froot_acc_patch (:) ! (gC/m2/year) C turnover from fine root
+ real(r8), pointer :: matrix_cturnover_frootst_acc_patch (:) ! (gC/m2/year) C turnover from fine root storage
+ real(r8), pointer :: matrix_cturnover_frootxf_acc_patch (:) ! (gC/m2/year) C turnover from fine root transfer
+ real(r8), pointer :: matrix_cturnover_livestem_acc_patch (:) ! (gC/m2/year) C turnover from live stem
+ real(r8), pointer :: matrix_cturnover_livestemst_acc_patch (:) ! (gC/m2/year) C turnover from live stem storage
+ real(r8), pointer :: matrix_cturnover_livestemxf_acc_patch (:) ! (gC/m2/year) C turnover from live stem transfer
+ real(r8), pointer :: matrix_cturnover_deadstem_acc_patch (:) ! (gC/m2/year) C turnover from dead stem
+ real(r8), pointer :: matrix_cturnover_deadstemst_acc_patch (:) ! (gC/m2/year) C turnover from dead stem storage
+ real(r8), pointer :: matrix_cturnover_deadstemxf_acc_patch (:) ! (gC/m2/year) C turnover from dead stem transfer
+ real(r8), pointer :: matrix_cturnover_livecroot_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root
+ real(r8), pointer :: matrix_cturnover_livecrootst_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root storage
+ real(r8), pointer :: matrix_cturnover_livecrootxf_acc_patch (:) ! (gC/m2/year) C turnover from live coarse root transfer
+ real(r8), pointer :: matrix_cturnover_deadcroot_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root
+ real(r8), pointer :: matrix_cturnover_deadcrootst_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root storage
+ real(r8), pointer :: matrix_cturnover_deadcrootxf_acc_patch (:) ! (gC/m2/year) C turnover from dead coarse root transfer
+ real(r8), pointer :: matrix_cturnover_grain_acc_patch (:) ! (gC/m2/year) C turnover from grain
+ real(r8), pointer :: matrix_cturnover_grainst_acc_patch (:) ! (gC/m2/year) C turnover from grain storage
+ real(r8), pointer :: matrix_cturnover_grainxf_acc_patch (:) ! (gC/m2/year) C turnover from grain transfer
+
+ real(r8), pointer :: grainc_SASUsave_patch (:) ! (gC/m2) grain C (crop model)
+ real(r8), pointer :: grainc_storage_SASUsave_patch (:) ! (gC/m2) grain C storage (crop model)
+ real(r8), pointer :: leafc_SASUsave_patch (:) ! (gC/m2) leaf C
+ real(r8), pointer :: leafc_storage_SASUsave_patch (:) ! (gC/m2) leaf C storage
+ real(r8), pointer :: leafc_xfer_SASUsave_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: frootc_SASUsave_patch (:) ! (gC/m2) fine root C
+ real(r8), pointer :: frootc_storage_SASUsave_patch (:) ! (gC/m2) fine root C storage
+ real(r8), pointer :: frootc_xfer_SASUsave_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: livestemc_SASUsave_patch (:) ! (gC/m2) live stem C
+ real(r8), pointer :: livestemc_storage_SASUsave_patch (:) ! (gC/m2) live stem C storage
+ real(r8), pointer :: livestemc_xfer_SASUsave_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: deadstemc_SASUsave_patch (:) ! (gC/m2) dead stem C
+ real(r8), pointer :: deadstemc_storage_SASUsave_patch (:) ! (gC/m2) dead stem C storage
+ real(r8), pointer :: deadstemc_xfer_SASUsave_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: livecrootc_SASUsave_patch (:) ! (gC/m2) live coarse root C
+ real(r8), pointer :: livecrootc_storage_SASUsave_patch (:) ! (gC/m2) live coarse root C storage
+ real(r8), pointer :: livecrootc_xfer_SASUsave_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: deadcrootc_SASUsave_patch (:) ! (gC/m2) dead coarse root C
+ real(r8), pointer :: deadcrootc_storage_SASUsave_patch (:) ! (gC/m2) dead coarse root C storage
+ real(r8), pointer :: deadcrootc_xfer_SASUsave_patch (:) ! (gC/m2) dead coarse root C transfer
+
contains
procedure , public :: Init
@@ -242,23 +357,53 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%leafc_patch (begp:endp)) ; this%leafc_patch (:) = nan
allocate(this%leafc_storage_patch (begp:endp)) ; this%leafc_storage_patch (:) = nan
allocate(this%leafc_xfer_patch (begp:endp)) ; this%leafc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_leafc_patch (begp:endp)) ; this%matrix_cap_leafc_patch (:) = nan
+ allocate(this%matrix_cap_leafc_storage_patch (begp:endp)) ; this%matrix_cap_leafc_storage_patch (:) = nan
+ allocate(this%matrix_cap_leafc_xfer_patch (begp:endp)) ; this%matrix_cap_leafc_xfer_patch (:) = nan
+ end if
allocate(this%leafc_storage_xfer_acc_patch (begp:endp)) ; this%leafc_storage_xfer_acc_patch (:) = nan
allocate(this%storage_cdemand_patch (begp:endp)) ; this%storage_cdemand_patch (:) = nan
allocate(this%frootc_patch (begp:endp)) ; this%frootc_patch (:) = nan
allocate(this%frootc_storage_patch (begp:endp)) ; this%frootc_storage_patch (:) = nan
allocate(this%frootc_xfer_patch (begp:endp)) ; this%frootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_frootc_patch (begp:endp)) ; this%matrix_cap_frootc_patch (:) = nan
+ allocate(this%matrix_cap_frootc_storage_patch (begp:endp)) ; this%matrix_cap_frootc_storage_patch (:) = nan
+ allocate(this%matrix_cap_frootc_xfer_patch (begp:endp)) ; this%matrix_cap_frootc_xfer_patch (:) = nan
+ end if
allocate(this%livestemc_patch (begp:endp)) ; this%livestemc_patch (:) = nan
allocate(this%livestemc_storage_patch (begp:endp)) ; this%livestemc_storage_patch (:) = nan
allocate(this%livestemc_xfer_patch (begp:endp)) ; this%livestemc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livestemc_patch (begp:endp)) ; this%matrix_cap_livestemc_patch (:) = nan
+ allocate(this%matrix_cap_livestemc_storage_patch (begp:endp)) ; this%matrix_cap_livestemc_storage_patch (:) = nan
+ allocate(this%matrix_cap_livestemc_xfer_patch (begp:endp)) ; this%matrix_cap_livestemc_xfer_patch (:) = nan
+ end if
allocate(this%deadstemc_patch (begp:endp)) ; this%deadstemc_patch (:) = nan
allocate(this%deadstemc_storage_patch (begp:endp)) ; this%deadstemc_storage_patch (:) = nan
allocate(this%deadstemc_xfer_patch (begp:endp)) ; this%deadstemc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_deadstemc_patch (begp:endp)) ; this%matrix_cap_deadstemc_patch (:) = nan
+ allocate(this%matrix_cap_deadstemc_storage_patch (begp:endp)) ; this%matrix_cap_deadstemc_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadstemc_xfer_patch (begp:endp)) ; this%matrix_cap_deadstemc_xfer_patch (:) = nan
+ end if
allocate(this%livecrootc_patch (begp:endp)) ; this%livecrootc_patch (:) = nan
allocate(this%livecrootc_storage_patch (begp:endp)) ; this%livecrootc_storage_patch (:) = nan
allocate(this%livecrootc_xfer_patch (begp:endp)) ; this%livecrootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livecrootc_patch (begp:endp)) ; this%matrix_cap_livecrootc_patch (:) = nan
+ allocate(this%matrix_cap_livecrootc_storage_patch (begp:endp)) ; this%matrix_cap_livecrootc_storage_patch(:) = nan
+ allocate(this%matrix_cap_livecrootc_xfer_patch (begp:endp)) ; this%matrix_cap_livecrootc_xfer_patch (:) = nan
+ end if
allocate(this%deadcrootc_patch (begp:endp)) ; this%deadcrootc_patch (:) = nan
allocate(this%deadcrootc_storage_patch (begp:endp)) ; this%deadcrootc_storage_patch (:) = nan
allocate(this%deadcrootc_xfer_patch (begp:endp)) ; this%deadcrootc_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_deadcrootc_patch (begp:endp)) ; this%matrix_cap_deadcrootc_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootc_storage_patch (begp:endp)) ; this%matrix_cap_deadcrootc_storage_patch(:) = nan
+ allocate(this%matrix_cap_deadcrootc_xfer_patch (begp:endp)) ; this%matrix_cap_deadcrootc_xfer_patch (:) = nan
+ end if
allocate(this%gresp_storage_patch (begp:endp)) ; this%gresp_storage_patch (:) = nan
allocate(this%gresp_xfer_patch (begp:endp)) ; this%gresp_xfer_patch (:) = nan
allocate(this%cpool_patch (begp:endp)) ; this%cpool_patch (:) = nan
@@ -272,7 +417,127 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%reproductivec_patch (begp:endp, nrepr)) ; this%reproductivec_patch (:,:) = nan
allocate(this%reproductivec_storage_patch (begp:endp, nrepr)) ; this%reproductivec_storage_patch (:,:) = nan
allocate(this%reproductivec_xfer_patch (begp:endp, nrepr)) ; this%reproductivec_xfer_patch (:,:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_reproc_patch (begp:endp)) ; this%matrix_cap_reproc_patch (:) = nan
+ allocate(this%matrix_cap_reproc_storage_patch (begp:endp)) ; this%matrix_cap_reproc_storage_patch (:) = nan
+ allocate(this%matrix_cap_reproc_xfer_patch (begp:endp)) ; this%matrix_cap_reproc_xfer_patch (:) = nan
+ end if
allocate(this%woodc_patch (begp:endp)) ; this%woodc_patch (:) = nan
+!initial pool size of year for matrix
+ if(use_matrixcn)then
+ allocate(this%leafc0_patch (begp:endp)) ; this%leafc0_patch (:) = nan
+ allocate(this%leafc0_storage_patch (begp:endp)) ; this%leafc0_storage_patch (:) = nan
+ allocate(this%leafc0_xfer_patch (begp:endp)) ; this%leafc0_xfer_patch (:) = nan
+ allocate(this%frootc0_patch (begp:endp)) ; this%frootc0_patch (:) = nan
+ allocate(this%frootc0_storage_patch (begp:endp)) ; this%frootc0_storage_patch (:) = nan
+ allocate(this%frootc0_xfer_patch (begp:endp)) ; this%frootc0_xfer_patch (:) = nan
+ allocate(this%livestemc0_patch (begp:endp)) ; this%livestemc0_patch (:) = nan
+ allocate(this%livestemc0_storage_patch (begp:endp)) ; this%livestemc0_storage_patch (:) = nan
+ allocate(this%livestemc0_xfer_patch (begp:endp)) ; this%livestemc0_xfer_patch (:) = nan
+ allocate(this%deadstemc0_patch (begp:endp)) ; this%deadstemc0_patch (:) = nan
+ allocate(this%deadstemc0_storage_patch (begp:endp)) ; this%deadstemc0_storage_patch (:) = nan
+ allocate(this%deadstemc0_xfer_patch (begp:endp)) ; this%deadstemc0_xfer_patch (:) = nan
+ allocate(this%livecrootc0_patch (begp:endp)) ; this%livecrootc0_patch (:) = nan
+ allocate(this%livecrootc0_storage_patch (begp:endp)) ; this%livecrootc0_storage_patch (:) = nan
+ allocate(this%livecrootc0_xfer_patch (begp:endp)) ; this%livecrootc0_xfer_patch (:) = nan
+ allocate(this%deadcrootc0_patch (begp:endp)) ; this%deadcrootc0_patch (:) = nan
+ allocate(this%deadcrootc0_storage_patch (begp:endp)) ; this%deadcrootc0_storage_patch (:) = nan
+ allocate(this%deadcrootc0_xfer_patch (begp:endp)) ; this%deadcrootc0_xfer_patch (:) = nan
+ allocate(this%reproc0_patch (begp:endp)) ; this%reproc0_patch (:) = nan
+ allocate(this%reproc0_storage_patch (begp:endp)) ; this%reproc0_storage_patch (:) = nan
+ allocate(this%reproc0_xfer_patch (begp:endp)) ; this%reproc0_xfer_patch (:) = nan
+
+ allocate(this%leafc_SASUsave_patch (begp:endp)) ; this%leafc_SASUsave_patch (:) = nan
+ allocate(this%leafc_storage_SASUsave_patch (begp:endp)) ; this%leafc_storage_SASUsave_patch (:) = nan
+ allocate(this%leafc_xfer_SASUsave_patch (begp:endp)) ; this%leafc_xfer_SASUsave_patch (:) = nan
+ allocate(this%frootc_SASUsave_patch (begp:endp)) ; this%frootc_SASUsave_patch (:) = nan
+ allocate(this%frootc_storage_SASUsave_patch (begp:endp)) ; this%frootc_storage_SASUsave_patch (:) = nan
+ allocate(this%frootc_xfer_SASUsave_patch (begp:endp)) ; this%frootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%livestemc_SASUsave_patch (begp:endp)) ; this%livestemc_SASUsave_patch (:) = nan
+ allocate(this%livestemc_storage_SASUsave_patch (begp:endp)) ; this%livestemc_storage_SASUsave_patch (:) = nan
+ allocate(this%livestemc_xfer_SASUsave_patch (begp:endp)) ; this%livestemc_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_SASUsave_patch (begp:endp)) ; this%deadstemc_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_storage_SASUsave_patch (begp:endp)) ; this%deadstemc_storage_SASUsave_patch (:) = nan
+ allocate(this%deadstemc_xfer_SASUsave_patch (begp:endp)) ; this%deadstemc_xfer_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_SASUsave_patch (begp:endp)) ; this%livecrootc_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_storage_SASUsave_patch (begp:endp)) ; this%livecrootc_storage_SASUsave_patch (:) = nan
+ allocate(this%livecrootc_xfer_SASUsave_patch (begp:endp)) ; this%livecrootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_SASUsave_patch (begp:endp)) ; this%deadcrootc_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_storage_SASUsave_patch (begp:endp)) ; this%deadcrootc_storage_SASUsave_patch (:) = nan
+ allocate(this%deadcrootc_xfer_SASUsave_patch (begp:endp)) ; this%deadcrootc_xfer_SASUsave_patch (:) = nan
+ allocate(this%grainc_SASUsave_patch (begp:endp)) ; this%grainc_SASUsave_patch (:) = nan
+ allocate(this%grainc_storage_SASUsave_patch (begp:endp)) ; this%grainc_storage_SASUsave_patch (:) = nan
+
+ allocate(this%matrix_calloc_leaf_acc_patch (begp:endp)); this%matrix_calloc_leaf_acc_patch (:) = nan
+ allocate(this%matrix_calloc_leafst_acc_patch (begp:endp)); this%matrix_calloc_leafst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_froot_acc_patch (begp:endp)); this%matrix_calloc_froot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_frootst_acc_patch (begp:endp)); this%matrix_calloc_frootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livestem_acc_patch (begp:endp)); this%matrix_calloc_livestem_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livestemst_acc_patch (begp:endp)); this%matrix_calloc_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadstem_acc_patch (begp:endp)); this%matrix_calloc_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadstemst_acc_patch (begp:endp)); this%matrix_calloc_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livecroot_acc_patch (begp:endp)); this%matrix_calloc_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_livecrootst_acc_patch (begp:endp)); this%matrix_calloc_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadcroot_acc_patch (begp:endp)); this%matrix_calloc_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_calloc_deadcrootst_acc_patch (begp:endp)); this%matrix_calloc_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_calloc_grain_acc_patch (begp:endp)); this%matrix_calloc_grain_acc_patch (:) = nan
+ allocate(this%matrix_calloc_grainst_acc_patch (begp:endp)); this%matrix_calloc_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ctransfer_leafst_to_leafxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_leafxf_to_leaf_acc_patch (begp:endp))
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_frootst_to_frootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_frootxf_to_froot_acc_patch (begp:endp))
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_grainst_to_grainxf_acc_patch (begp:endp))
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_grainxf_to_grain_acc_patch (begp:endp))
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livestem_to_deadstem_acc_patch (begp:endp))
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (begp:endp))
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (:) = nan
+
+ allocate(this%matrix_cturnover_leaf_acc_patch (begp:endp)) ; this%matrix_cturnover_leaf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_leafst_acc_patch (begp:endp)) ; this%matrix_cturnover_leafst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_leafxf_acc_patch (begp:endp)) ; this%matrix_cturnover_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_froot_acc_patch (begp:endp)) ; this%matrix_cturnover_froot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_frootst_acc_patch (begp:endp)) ; this%matrix_cturnover_frootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_frootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestem_acc_patch (begp:endp)) ; this%matrix_cturnover_livestem_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestemst_acc_patch (begp:endp)) ; this%matrix_cturnover_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livestemxf_acc_patch (begp:endp)) ; this%matrix_cturnover_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstem_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstemst_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadstemxf_acc_patch (begp:endp)) ; this%matrix_cturnover_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecroot_acc_patch (begp:endp)) ; this%matrix_cturnover_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecrootst_acc_patch (begp:endp)) ; this%matrix_cturnover_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_livecrootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcroot_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcrootst_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_cturnover_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grain_acc_patch (begp:endp)) ; this%matrix_cturnover_grain_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grainst_acc_patch (begp:endp)) ; this%matrix_cturnover_grainst_acc_patch (:) = nan
+ allocate(this%matrix_cturnover_grainxf_acc_patch (begp:endp)) ; this%matrix_cturnover_grainxf_acc_patch (:) = nan
+ end if
allocate(this%cropseedc_deficit_patch (begp:endp)) ; this%cropseedc_deficit_patch (:) = nan
allocate(this%seedc_grc (begg:endg)) ; this%seedc_grc (:) = nan
@@ -287,11 +552,6 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%totc_p2c_col (begc:endc)) ; this%totc_p2c_col (:) = nan
- ! Matrix solution variables
- if(use_matrixcn)then
- ! Initisl pool size for matrix solution
- end if
-
end subroutine InitAllocate
!------------------------------------------------------------------------
@@ -375,6 +635,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='leaf C transfer', &
ptr_patch=this%leafc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch, default='inactive')
+ end if
+
this%leafc_storage_xfer_acc_patch(begp:endp) = spval
call hist_addfld1d (fname='LEAFC_STORAGE_XFER_ACC', units='gC/m^2', &
avgflag='A', long_name='Accumulated leaf C transfer', &
@@ -400,6 +677,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVESTEMC', units='gC/m^2', &
avgflag='A', long_name='live stem C', &
@@ -415,6 +709,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADSTEMC', units='gC/m^2', &
avgflag='A', long_name='dead stem C', &
@@ -430,6 +741,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVECROOTC', units='gC/m^2', &
avgflag='A', long_name='live coarse root C', &
@@ -445,6 +773,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADCROOTC', units='gC/m^2', &
avgflag='A', long_name='dead coarse root C', &
@@ -460,6 +805,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_STORAGE_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTC_XFER_CAP', units='gC/m^2', &
+ avgflag='I', long_name='dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='GRESP_STORAGE', units='gC/m^2', &
avgflag='A', long_name='growth respiration storage', &
@@ -515,9 +877,6 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='fuel load', &
ptr_col=this%fuelc_col)
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
end if
!-------------------------------
@@ -541,6 +900,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 leaf C transfer', &
ptr_patch=this%leafc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LEAFC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch)!, default='inactive')
+ end if
+
this%leafc_storage_xfer_acc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LEAFC_STORAGE_XFER_ACC', units='gC13/m^2', &
avgflag='A', long_name='Accumulated C13 leaf C transfer', &
@@ -561,6 +937,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_FROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch)!, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LIVESTEMC', units='gC13/m^2', &
avgflag='A', long_name='C13 live stem C', &
@@ -576,6 +969,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVESTEMC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch)!, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_DEADSTEMC', units='gC13/m^2', &
avgflag='A', long_name='C13 dead stem C', &
@@ -591,6 +1001,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADSTEMC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch)!, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_LIVECROOTC', units='gC13/m^2', &
avgflag='A', long_name='C13 live coarse root C', &
@@ -606,6 +1033,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_LIVECROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch)!, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_DEADCROOTC', units='gC13/m^2', &
avgflag='A', long_name='C13 dead coarse root C', &
@@ -621,6 +1065,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C13 dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_STORAGE_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C13_DEADCROOTC_XFER_CAP', units='gC13/m^2', &
+ avgflag='I', long_name='C13 dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch)!, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='C13_GRESP_STORAGE', units='gC13/m^2', &
avgflag='A', long_name='C13 growth respiration storage', &
@@ -695,9 +1156,6 @@ subroutine InitHistory(this, bounds, carbon_type)
ptr_patch=this%xsmrpool_loss_patch, default='inactive')
end if
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
endif
@@ -727,6 +1185,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='Accumulated C14 leaf C transfer', &
ptr_patch=this%leafc_storage_xfer_acc_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C capacity', &
+ ptr_patch=this%matrix_cap_leafc_patch)
+
+ this%matrix_cap_leafc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C storage capacity', &
+ ptr_patch=this%matrix_cap_leafc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_leafc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LEAFC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 leaf C transfer capacity', &
+ ptr_patch=this%matrix_cap_leafc_xfer_patch)!, default='inactive')
+ end if
+
this%frootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_FROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 fine root C', &
@@ -742,6 +1217,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 fine root C transfer', &
ptr_patch=this%frootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C capacity', &
+ ptr_patch=this%matrix_cap_frootc_patch)
+
+ this%matrix_cap_frootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C storage capacity', &
+ ptr_patch=this%matrix_cap_frootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_frootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_FROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 fine root C transfer capacity', &
+ ptr_patch=this%matrix_cap_frootc_xfer_patch)!, default='inactive')
+ end if
+
this%livestemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_LIVESTEMC', units='gC14/m^2', &
avgflag='A', long_name='C14 live stem C', &
@@ -757,6 +1249,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 live stem C transfer', &
ptr_patch=this%livestemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C capacity', &
+ ptr_patch=this%matrix_cap_livestemc_patch)
+
+ this%matrix_cap_livestemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C storage capcity', &
+ ptr_patch=this%matrix_cap_livestemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livestemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVESTEMC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemc_xfer_patch)!, default='inactive')
+ end if
+
this%deadstemc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_DEADSTEMC', units='gC14/m^2', &
avgflag='A', long_name='C14 dead stem C', &
@@ -772,6 +1281,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 dead stem C transfer', &
ptr_patch=this%deadstemc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_patch)
+
+ this%matrix_cap_deadstemc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadstemc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADSTEMC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead stem C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemc_xfer_patch)!, default='inactive')
+ end if
+
this%livecrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_LIVECROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 live coarse root C', &
@@ -787,6 +1313,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 live coarse root C transfer', &
ptr_patch=this%livecrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_patch)
+
+ this%matrix_cap_livecrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_livecrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_LIVECROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 live coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootc_xfer_patch)!, default='inactive')
+ end if
+
this%deadcrootc_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_DEADCROOTC', units='gC14/m^2', &
avgflag='A', long_name='C14 dead coarse root C', &
@@ -802,6 +1345,23 @@ subroutine InitHistory(this, bounds, carbon_type)
avgflag='A', long_name='C14 dead coarse root C transfer', &
ptr_patch=this%deadcrootc_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_patch)
+
+ this%matrix_cap_deadcrootc_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_STORAGE_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_storage_patch)!, default='inactive')
+
+ this%matrix_cap_deadcrootc_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='C14_DEADCROOTC_XFER_CAP', units='gC14/m^2', &
+ avgflag='I', long_name='C14 dead coarse root C transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootc_xfer_patch)!, default='inactive')
+ end if
+
this%gresp_storage_patch(begp:endp) = spval
call hist_addfld1d (fname='C14_GRESP_STORAGE', units='gC14/m^2', &
avgflag='A', long_name='C14 growth respiration storage', &
@@ -875,9 +1435,6 @@ subroutine InitHistory(this, bounds, carbon_type)
ptr_patch=this%xsmrpool_loss_patch, default='inactive')
end if
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
endif
@@ -890,7 +1447,7 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
! Initializes time varying variables used only in coupled carbon-nitrogen mode (CN):
!
! !USES:
- use landunit_varcon , only : istsoil, istcrop
+ use landunit_varcon , only : istsoil, istcrop
use clm_time_manager , only : is_restart, get_nstep
use clm_varctl, only : MM_Nuptake_opt, spinup_state
!
@@ -957,9 +1514,11 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
-
- ! Set matrix solution bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else
if (pftcon%evergreen(patch%itype(p)) == 1._r8) then
@@ -967,73 +1526,100 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = cnvegcstate_const%initial_vegC * ratio
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution evergreen
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else if (patch%itype(p) >= npcropmin) then ! prognostic crop types
this%leafc_patch(p) = 0._r8
this%leafc_storage_patch(p) = 0._r8
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution prognostic crops
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = 0._r8
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
else
this%leafc_patch(p) = 0._r8
this%leafc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
- ! Set matrix solution for everything else
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(p) = 0._r8
+ this%matrix_cap_leafc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = cnvegcstate_const%initial_vegC * ratio
end if
end if
end if
this%leafc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_xfer_patch(p) = 0._r8
+ end if
this%leafc_storage_xfer_acc_patch(p) = 0._r8
this%storage_cdemand_patch(p) = 0._r8
- ! Set matrix solution general
- if ( use_matrixcn )then
- end if
-
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootc_patch(p) = 0._r8
this%frootc_storage_patch(p) = 0._r8
- ! Set matrix solution
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(p) = 0._r8
+ this%matrix_cap_frootc_storage_patch(p) = 0._r8
end if
end if
this%frootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_xfer_patch(p) = 0._r8
+ end if
this%livestemc_patch(p) = 0._r8
this%livestemc_storage_patch(p) = 0._r8
this%livestemc_xfer_patch(p) = 0._r8
-
- ! Set matrix solution
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_livestemc_patch(p) = 0._r8
+ this%matrix_cap_livestemc_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemc_xfer_patch(p) = 0._r8
end if
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemc_patch(p) = 0.1_r8 * ratio
- ! Set matrix solution for woody
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(p) = 0.1_r8 * ratio
end if
else
this%deadstemc_patch(p) = 0._r8
- ! Set matrix solution for non-woody
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(p) = 0._r8
end if
end if
this%deadstemc_storage_patch(p) = 0._r8
this%deadstemc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemc_xfer_patch(p) = 0._r8
+ end if
this%livecrootc_patch(p) = 0._r8
this%livecrootc_storage_patch(p) = 0._r8
this%livecrootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(p) = 0._r8
+ this%matrix_cap_livecrootc_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootc_xfer_patch(p) = 0._r8
+ end if
this%deadcrootc_patch(p) = 0._r8
this%deadcrootc_storage_patch(p) = 0._r8
this%deadcrootc_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootc_patch(p) = 0._r8
+ this%matrix_cap_deadcrootc_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootc_xfer_patch(p) = 0._r8
+ end if
this%gresp_storage_patch(p) = 0._r8
this%gresp_xfer_patch(p) = 0._r8
@@ -1045,10 +1631,103 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%storvegc_patch(p) = 0._r8
this%woodc_patch(p) = 0._r8
this%totc_patch(p) = 0._r8
-
- ! Initial pool size for matrix solution
- if ( use_matrixcn )then
+!!!!initial pool size for matrix
+ if(use_matrixcn)then
+ this%leafc0_patch(p) = 1.e-30_r8
+ this%leafc0_storage_patch(p) = 1.e-30_r8
+ this%leafc0_xfer_patch(p) = 1.e-30_r8
+ this%frootc0_patch(p) = 1.e-30_r8
+ this%frootc0_storage_patch(p) = 1.e-30_r8
+ this%frootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%livestemc0_patch(p) = 1.e-30_r8
+ this%livestemc0_storage_patch(p) = 1.e-30_r8
+ this%livestemc0_xfer_patch(p) = 1.e-30_r8
+ this%deadstemc0_patch(p) = 1.e-30_r8
+ this%deadstemc0_storage_patch(p) = 1.e-30_r8
+ this%deadstemc0_xfer_patch(p) = 1.e-30_r8
+
+ this%livecrootc0_patch(p) = 1.e-30_r8
+ this%livecrootc0_storage_patch(p) = 1.e-30_r8
+ this%livecrootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%deadcrootc0_patch(p) = 1.e-30_r8
+ this%deadcrootc0_storage_patch(p) = 1.e-30_r8
+ this%deadcrootc0_xfer_patch(p) = 1.e-30_r8
+
+ this%reproc0_patch(p) = 1.e-30_r8
+ this%reproc0_storage_patch(p) = 1.e-30_r8
+ this%reproc0_xfer_patch(p) = 1.e-30_r8
+
+ this%leafc_SASUsave_patch(p) = 0._r8
+ this%leafc_storage_SASUsave_patch(p) = 0._r8
+ this%leafc_xfer_SASUsave_patch(p) = 0._r8
+ this%frootc_SASUsave_patch(p) = 0._r8
+ this%frootc_storage_SASUsave_patch(p) = 0._r8
+ this%frootc_xfer_SASUsave_patch(p) = 0._r8
+ this%livestemc_SASUsave_patch(p) = 0._r8
+ this%livestemc_storage_SASUsave_patch(p) = 0._r8
+ this%livestemc_xfer_SASUsave_patch(p) = 0._r8
+ this%deadstemc_SASUsave_patch(p) = 0._r8
+ this%deadstemc_storage_SASUsave_patch(p) = 0._r8
+ this%deadstemc_xfer_SASUsave_patch(p) = 0._r8
+ this%livecrootc_SASUsave_patch(p) = 0._r8
+ this%livecrootc_storage_SASUsave_patch(p) = 0._r8
+ this%livecrootc_xfer_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_storage_SASUsave_patch(p) = 0._r8
+ this%deadcrootc_xfer_SASUsave_patch(p) = 0._r8
+ this%grainc_SASUsave_patch(p) = 0._r8
+ this%grainc_storage_SASUsave_patch(p) = 0._r8
+
+ this%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ this%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ this%matrix_calloc_froot_acc_patch(p) = 0._r8
+ this%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ this%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ this%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ this%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ this%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ this%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
end if
+
if ( use_crop )then
this%reproductivec_patch(p,:) = 0._r8
@@ -1056,8 +1735,18 @@ subroutine InitCold(this, bounds, ratio, carbon_type, c12_cnveg_carbonstate_inst
this%reproductivec_xfer_patch(p,:) = 0._r8
this%cropseedc_deficit_patch(p) = 0._r8
this%xsmrpool_loss_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_reproc_patch(p) = 0._r8
+ this%matrix_cap_reproc_storage_patch(p) = 0._r8
+ this%matrix_cap_reproc_xfer_patch(p) = 0._r8
+ ! I think these need to change as well...
+ this%matrix_calloc_grain_acc_patch(p) = 0._r8
+ this%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ this%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
end if
end if
@@ -1107,7 +1796,7 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
use clm_varctl , only : spinup_state, use_cndv, MM_Nuptake_opt
use clm_varctl , only : spinup_state, use_cndv, MM_Nuptake_opt
use clm_time_manager , only : is_restart
- use landunit_varcon , only : istsoil, istcrop
+ use landunit_varcon , only : istsoil, istcrop
use spmdMod , only : mpicom
use shr_mpi_mod , only : shr_mpi_sum
use restUtilMod
@@ -1186,6 +1875,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_xfer_acc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafc_storage_xfer_acc_patch)
@@ -1206,6 +1950,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -1218,6 +2016,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -1230,6 +2086,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -1242,6 +2152,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_xfer_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -1254,37 +2222,125 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_xfer_patch)
- call restartvar(ncid=ncid, flag=flag, varname='gresp_storage', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
- call restartvar(ncid=ncid, flag=flag, varname='gresp_xfer', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%gresp_xfer_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
- call restartvar(ncid=ncid, flag=flag, varname='cpool', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%cpool_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
- call restartvar(ncid=ncid, flag=flag, varname='xsmrpool', xtype=ncd_double, &
- dim1name='pft', long_name='', units='', &
- interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_patch)
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
- ! Restart variables for matrix solution
- if ( use_matrixcn )then
- end if
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
- if (use_crop) then
- call restartvar(ncid=ncid, flag=flag, varname='xsmrpool_loss', xtype=ncd_double, &
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C storage', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C transfer', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='C accumulated allocation to grain', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='C accumulated allocation to grain storage', units='gC/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
+ call restartvar(ncid=ncid, flag=flag, varname='gresp_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='gresp_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%gresp_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='cpool', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%cpool_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='xsmrpool', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_patch)
+
+ if (use_crop) then
+ call restartvar(ncid=ncid, flag=flag, varname='xsmrpool_loss', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%xsmrpool_loss_patch)
if (flag == 'read' .and. (.not. readvar) ) then
this%xsmrpool_loss_patch(bounds%begp:bounds%endp) = 0._r8
end if
-
- ! Restart variables for matrix solution with prognostic crop
- if ( use_matrixcn )then
- end if
end if
call restartvar(ncid=ncid, flag=flag, varname='pft_ctrunc', xtype=ncd_double, &
@@ -1372,9 +2428,11 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%leafc_storage_patch(i) = 0._r8
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = 0._r8
-
- ! Bare soil matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = 0._r8
+ this%matrix_cap_leafc_storage_patch(i) = 0._r8
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
else
if (pftcon%evergreen(patch%itype(i)) == 1._r8) then
@@ -1382,35 +2440,38 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%leafc_storage_patch(i) = 0._r8
this%frootc_patch(i) = cnvegcstate_const%initial_vegC * ratio
this%frootc_storage_patch(i) = 0._r8
- ! Evergreen matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_leafc_storage_patch(i) = 0._r8
+ this%matrix_cap_frootc_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
else
this%leafc_patch(i) = 0._r8
this%leafc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
-
- ! Otherwise matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = 0._r8
+ this%matrix_cap_leafc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = cnvegcstate_const%initial_vegC * ratio
end if
end if
end if
this%leafc_xfer_patch(i) = 0._r8
- this%leafc_storage_xfer_acc_patch(i) = 0._r8
- this%storage_cdemand_patch(i) = 0._r8
-
- ! General matrix solution
if(use_matrixcn)then
+ this%matrix_cap_leafc_xfer_patch(i) = 0._r8
end if
-
+ this%leafc_storage_xfer_acc_patch(i) = 0._r8
+ this%storage_cdemand_patch(i) = 0._r8
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootc_patch(i) = 0._r8
this%frootc_storage_patch(i) = 0._r8
-
- ! Flex CN for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_frootc_patch(i) = 0._r8
+ this%matrix_cap_frootc_storage_patch(i) = 0._r8
end if
end if
this%frootc_xfer_patch(i) = 0._r8
@@ -1418,20 +2479,30 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%livestemc_patch(i) = 0._r8
this%livestemc_storage_patch(i) = 0._r8
this%livestemc_xfer_patch(i) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_frootc_xfer_patch(i) = 0._r8
+ this%matrix_cap_livestemc_patch(i) = 0._r8
+ this%matrix_cap_livestemc_storage_patch(i) = 0._r8
+ this%matrix_cap_livestemc_xfer_patch(i) = 0._r8
+ end if
if (pftcon%woody(patch%itype(i)) == 1._r8) then
this%deadstemc_patch(i) = 0.1_r8 * ratio
- ! Woody for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(i) = 0.1_r8 * ratio
end if
else
this%deadstemc_patch(i) = 0._r8
- ! Non-Woody for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_deadstemc_patch(i) = 0._r8
end if
end if
this%deadstemc_storage_patch(i) = 0._r8
this%deadstemc_xfer_patch(i) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemc_storage_patch(i) = 0._r8
+ this%matrix_cap_deadstemc_xfer_patch(i) = 0._r8
+ end if
this%livecrootc_patch(i) = 0._r8
this%livecrootc_storage_patch(i) = 0._r8
@@ -1441,8 +2512,14 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%deadcrootc_storage_patch(i) = 0._r8
this%deadcrootc_xfer_patch(i) = 0._r8
- ! Live/Dead course roots for matrix solution
if(use_matrixcn)then
+ this%matrix_cap_livecrootc_patch(i) = 0._r8
+ this%matrix_cap_livecrootc_storage_patch(i) = 0._r8
+ this%matrix_cap_livecrootc_xfer_patch(i) = 0._r8
+
+ this%matrix_cap_deadcrootc_patch(i) = 0._r8
+ this%matrix_cap_deadcrootc_storage_patch(i) = 0._r8
+ this%matrix_cap_deadcrootc_xfer_patch(i) = 0._r8
end if
this%gresp_storage_patch(i) = 0._r8
@@ -1460,12 +2537,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
this%reproductivec_patch(i,:) = 0._r8
this%reproductivec_storage_patch(i,:) = 0._r8
this%reproductivec_xfer_patch(i,:) = 0._r8
- this%cropseedc_deficit_patch(i) = 0._r8
- this%xsmrpool_loss_patch(i) = 0._r8
-
- ! Reproductive pools for matrix solution
if(use_matrixcn)then
+ this%reproc0_patch(i) = 0._r8
+ this%reproc0_storage_patch(i) = 0._r8
+ this%reproc0_xfer_patch(i) = 0._r8
+ this%matrix_cap_reproc_patch(i) = 0._r8
+ this%matrix_cap_reproc_storage_patch(i) = 0._r8
+ this%matrix_cap_reproc_xfer_patch(i) = 0._r8
end if
+ this%cropseedc_deficit_patch(i) = 0._r8
+ this%xsmrpool_loss_patch(i) = 0._r8
end if
! calculate totvegc explicitly so that it is available for the isotope
@@ -1633,6 +2714,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='frootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_patch)
@@ -1675,6 +2811,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -1717,6 +2908,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -1759,6 +3008,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -1801,6 +3104,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -1843,6 +3204,102 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13 storage', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer_13', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C13 transfer', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='C13 accumulated allocation to grain', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='C13 accumulated allocation to grain storage', units='gC13/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc_13', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='gresp_storage_13', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
@@ -1930,14 +3387,6 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
- ! Restart variables for matrix solution and C13
- if(use_matrixcn)then
-
- ! Prgnostic crop C13 variables for matrix solution
- if ( use_crop )then
- end if
- end if
-
end if
!--------------------------------
@@ -1997,6 +3446,61 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_leafst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafst_to_leafxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_leafxf_to_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leaf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_leafst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctrunover_leafxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_leafxf_acc_patch)
+
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='frootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootc_patch)
@@ -2036,6 +3540,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_frootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootst_to_frootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_frootxf_to_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_froot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_frootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_frootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livestemc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livestemc_patch)
@@ -2072,6 +3630,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livestemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemst_to_livestemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestemxf_to_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livestem_to_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livestemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livestemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadstemc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadstemc_patch)
@@ -2108,6 +3724,60 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadstemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemst_to_deadstemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadstemxf_to_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstem_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadstemxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadstemxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='livecrootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%livecrootc_patch)
@@ -2144,6 +3814,64 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_livecrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootst_to_livecrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecrootxf_to_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_livecroot_to_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_livecrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_livecrootxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootc_patch)
@@ -2180,6 +3908,102 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_storage_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc_xfer_cap_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootc_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootc0_xfer_patch)
+!
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_deadcrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_deadcrootxf_to_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcroot_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_deadcrootxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_deadcrootxf_acc_patch)
+ end if
+
+ if(use_matrixcn .and. use_crop)then
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_storage_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14 storage', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='reproc0_xfer_14', xtype=ncd_double, &
+ dim1name='pft', long_name='initial grain C14 transfer', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%reproc0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='C14 accumulated allocation to grain', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_calloc_grainst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='C14 accumulated allocation to grain storage', units='gC14/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_calloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainst_to_grainxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ctransfer_grainxf_to_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ctransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grain_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainst_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_cturnover_grainxf_acc_14', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cturnover_grainxf_acc_patch)
+ end if
+
call restartvar(ncid=ncid, flag=flag, varname='gresp_storage_14', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%gresp_storage_patch)
@@ -2252,13 +4076,6 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, reseed_dead_plants,
end do
end if
- ! Restart variables for matrix solution and C13
- if(use_matrixcn)then
-
- ! Prgnostic crop C13 variables for matrix solution
- if ( use_crop )then
- end if
- end if
end if
!--------------------------------
@@ -2537,6 +4354,95 @@ subroutine SetValues ( this, &
this%deadcrootc_patch(i) = value_patch
this%deadcrootc_storage_patch(i) = value_patch
this%deadcrootc_xfer_patch(i) = value_patch
+ if(use_matrixcn)then
+ this%matrix_cap_leafc_patch(i) = value_patch
+ this%matrix_cap_leafc_storage_patch(i) = value_patch
+ this%matrix_cap_leafc_xfer_patch(i) = value_patch
+ this%matrix_cap_frootc_patch(i) = value_patch
+ this%matrix_cap_frootc_storage_patch(i) = value_patch
+ this%matrix_cap_frootc_xfer_patch(i) = value_patch
+ this%matrix_cap_livestemc_patch(i) = value_patch
+ this%matrix_cap_livestemc_storage_patch(i) = value_patch
+ this%matrix_cap_livestemc_xfer_patch(i) = value_patch
+ this%matrix_cap_deadstemc_patch(i) = value_patch
+ this%matrix_cap_deadstemc_storage_patch(i) = value_patch
+ this%matrix_cap_deadstemc_xfer_patch(i) = value_patch
+ this%matrix_cap_livecrootc_patch(i) = value_patch
+ this%matrix_cap_livecrootc_storage_patch(i) = value_patch
+ this%matrix_cap_livecrootc_xfer_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_storage_patch(i) = value_patch
+ this%matrix_cap_deadcrootc_xfer_patch(i) = value_patch
+
+ this%leafc0_patch(i) = value_patch
+ this%leafc0_storage_patch(i) = value_patch
+ this%leafc0_xfer_patch(i) = value_patch
+ this%frootc0_patch(i) = value_patch
+ this%frootc0_storage_patch(i) = value_patch
+ this%frootc0_xfer_patch(i) = value_patch
+ this%livestemc0_patch(i) = value_patch
+ this%livestemc0_storage_patch(i) = value_patch
+ this%livestemc0_xfer_patch(i) = value_patch
+ this%deadstemc0_patch(i) = value_patch
+ this%deadstemc0_storage_patch(i) = value_patch
+ this%deadstemc0_xfer_patch(i) = value_patch
+ this%livecrootc0_patch(i) = value_patch
+ this%livecrootc0_storage_patch(i) = value_patch
+ this%livecrootc0_xfer_patch(i) = value_patch
+ this%deadcrootc0_patch(i) = value_patch
+ this%deadcrootc0_storage_patch(i) = value_patch
+ this%deadcrootc0_xfer_patch(i) = value_patch
+ this%reproc0_patch(i) = value_patch
+ this%reproc0_storage_patch(i) = value_patch
+ this%reproc0_xfer_patch(i) = value_patch
+!!!!matrix
+ this%matrix_calloc_leaf_acc_patch(i) = value_patch
+ this%matrix_calloc_leafst_acc_patch(i) = value_patch
+ this%matrix_calloc_froot_acc_patch(i) = value_patch
+ this%matrix_calloc_frootst_acc_patch(i) = value_patch
+ this%matrix_calloc_livestem_acc_patch(i) = value_patch
+ this%matrix_calloc_livestemst_acc_patch(i) = value_patch
+ this%matrix_calloc_deadstem_acc_patch(i) = value_patch
+ this%matrix_calloc_deadstemst_acc_patch(i) = value_patch
+ this%matrix_calloc_livecroot_acc_patch(i) = value_patch
+ this%matrix_calloc_livecrootst_acc_patch(i) = value_patch
+ this%matrix_calloc_deadcroot_acc_patch(i) = value_patch
+ this%matrix_calloc_deadcrootst_acc_patch(i) = value_patch
+
+ this%matrix_ctransfer_leafst_to_leafxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_leafxf_to_leaf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_frootst_to_frootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_frootxf_to_froot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestemst_to_livestemxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestemxf_to_livestem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livestem_to_deadstem_acc_patch (i) = value_patch
+ this%matrix_ctransfer_livecroot_to_deadcroot_acc_patch (i) = value_patch
+
+ this%matrix_cturnover_leaf_acc_patch(i) = value_patch
+ this%matrix_cturnover_leafst_acc_patch(i) = value_patch
+ this%matrix_cturnover_leafxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_froot_acc_patch(i) = value_patch
+ this%matrix_cturnover_frootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_frootxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestem_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestemst_acc_patch(i) = value_patch
+ this%matrix_cturnover_livestemxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstem_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstemst_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecroot_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecrootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcroot_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_cturnover_deadcrootxf_acc_patch(i) = value_patch
+ end if
this%gresp_storage_patch(i) = value_patch
this%gresp_xfer_patch(i) = value_patch
this%cpool_patch(i) = value_patch
@@ -2547,18 +4453,18 @@ subroutine SetValues ( this, &
this%woodc_patch(i) = value_patch
this%totvegc_patch(i) = value_patch
this%totc_patch(i) = value_patch
-
- ! Set matrix solution values
- if ( use_matrixcn )then
- end if
-
if ( use_crop ) then
+ if(use_matrixcn)then
+ this%matrix_calloc_grain_acc_patch(i) = value_patch
+ this%matrix_calloc_grainst_acc_patch(i) = value_patch
+ this%matrix_ctransfer_grainst_to_grainxf_acc_patch (i) = value_patch
+ this%matrix_ctransfer_grainxf_to_grain_acc_patch (i) = value_patch
+ this%matrix_cturnover_grain_acc_patch(i) = value_patch
+ this%matrix_cturnover_grainst_acc_patch(i) = value_patch
+ this%matrix_cturnover_grainxf_acc_patch(i) = value_patch
+ end if
this%cropseedc_deficit_patch(i) = value_patch
this%xsmrpool_loss_patch(i) = value_patch
-
- ! Set matrix solution values for prognostic crop
- if ( use_matrixcn )then
- end if
end if
end do
@@ -2569,12 +4475,16 @@ subroutine SetValues ( this, &
this%reproductivec_patch(i,k) = value_patch
this%reproductivec_storage_patch(i,k) = value_patch
this%reproductivec_xfer_patch(i,k) = value_patch
-
- ! Set matrix solution values for prognostic crop reproductive patches
- if ( use_matrixcn )then
- end if
end do
end do
+ if(use_matrixcn)then
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%matrix_cap_reproc_patch(i) = value_patch
+ this%matrix_cap_reproc_storage_patch(i) = value_patch
+ this%matrix_cap_reproc_xfer_patch(i) = value_patch
+ end do
+ end if
end if
do fi = 1,num_column
diff --git a/src/biogeochem/CNVegMatrixMod.F90 b/src/biogeochem/CNVegMatrixMod.F90
new file mode 100644
index 0000000000..5582afeffe
--- /dev/null
+++ b/src/biogeochem/CNVegMatrixMod.F90
@@ -0,0 +1,3851 @@
+module CNVegMatrixMod
+
+ !---------------------------------------------------------------------------------------
+ ! The matrix model of CLM5.0 was developed by Yiqi Luo EcoLab members,
+ ! Drs. Xingjie Lu, Yuanyuan Huang and Zhengguang Du, at Northern Arizona University
+ !---------------------------------------------------------------------------------------
+ !
+ ! DESCRIPTION:
+ ! Matrix solution for vegetation C and N cycles
+ ! The matrix equation
+ ! Xn+1 = Xn + B*I*dt + (Aph*Kph + Agm*Kgm + Afi*Kfi) * Xn*dt
+ ! Xn is the state variable of last time step n, and Xn+1 is the state variable of
+ ! the next time step n+1, I is the input to the vegetation, i.e. NPP in this case.
+ ! B is allocation fraction vector.
+ ! Aph, Agm and Afi represent transfer coefficient matrix A from phenology, gap mortality
+ ! and fire related C and N transfers.
+ ! Kph, Kgm and Kfi represent turnover rate matrix K from phenology, gap mortality
+ ! and fire related C and N transfers.
+ !---------------------------------------------------------------------------------------
+
+ ! !USES:
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use clm_time_manager , only : get_step_size,is_end_curr_year,is_first_step_of_this_run_segment,&
+ is_beg_curr_year,update_DA_nstep
+ use decompMod , only : bounds_type
+ use clm_varcon , only : spval
+ use clm_varpar , only : nlevdecomp, nvegcpool, nvegnpool
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn,&
+ ncphtrans,nnphtrans,ncgmtrans,nngmtrans,ncfitrans,nnfitrans,&
+ ncphouttrans,nnphouttrans,ncgmouttrans,nngmouttrans,ncfiouttrans,nnfiouttrans
+ use perf_mod , only : t_startf, t_stopf
+ use PatchType , only : patch
+ use pftconMod , only : pftcon,npcropmin
+ use CNVegCarbonStateType , only : cnveg_carbonstate_type
+ use CNVegNitrogenStateType , only : cnveg_nitrogenstate_type
+ use CNVegCarbonFluxType , only : cnveg_carbonflux_type !include: callocation,ctransfer, cturnover
+ use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
+ use CNVegStateType , only : cnveg_state_type
+ use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type
+ use clm_varctl , only : spinup_matrixcn, hist_wrt_matrixcn_diag, nyr_forcing, nyr_SASU, iloop_avg
+ use clm_varctl , only : use_c13, use_c14
+ use SparseMatrixMultiplyMod , only : sparse_matrix_type,diag_matrix_type,vector_type
+ use MatrixMod , only : inverse
+ !
+ implicit none
+ private
+ !
+ ! !PUBLIC MEMBER FUNCTIONS:
+ public:: CNVegMatrix
+ public:: matrix_update_phc,matrix_update_gmc,matrix_update_fic
+ public:: matrix_update_phn,matrix_update_gmn,matrix_update_fin
+ public:: CNVegMatrixRest
+
+ ! ! PRIVATE MEMBER DATA:
+ integer,save, private :: iyr=0 ! Cycling year number into forcing sequence
+ integer,save, private :: iloop=0 ! The iloop^th forcing loop
+ !-----------------------------------------------------------------------
+
+contains
+
+ !-----------------------------------------------------------------------
+ subroutine CNVegMatrix(bounds,num_soilp,filter_soilp,num_actfirep,filter_actfirep,cnveg_carbonstate_inst,cnveg_nitrogenstate_inst,&
+ cnveg_carbonflux_inst, cnveg_nitrogenflux_inst,cnveg_state_inst,soilbiogeochem_nitrogenflux_inst, &
+ c13_cnveg_carbonstate_inst,c14_cnveg_carbonstate_inst,c13_cnveg_carbonflux_inst,&
+ c14_cnveg_carbonflux_inst)
+ ! !DESCRIPTION:
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_soilp ! number of soil patches in filter
+ integer , intent(in) :: filter_soilp(:) ! filter for soil patches
+ integer , intent(in) :: num_actfirep ! number of soil patches in filter
+ integer , intent(in) :: filter_actfirep(:) ! filter for soil patches
+ type(cnveg_carbonstate_type) , intent(inout) :: cnveg_carbonstate_inst
+ type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
+ type(cnveg_carbonstate_type) , intent(inout) :: c13_cnveg_carbonstate_inst
+ type(cnveg_carbonstate_type) , intent(inout) :: c14_cnveg_carbonstate_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst
+ type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst
+ type(cnveg_state_type) , intent(in) :: cnveg_state_inst
+
+! LOCAL VARIABLES:
+ integer :: fc,fp,j,i,k ! indices
+ integer :: p,c !
+
+ ! Temporary variables matrix A for different processes
+ real(r8),dimension(:,:) :: Aphconed(bounds%begp:bounds%endp,ncphtrans-ncphouttrans)
+ real(r8),dimension(:,:) :: Aphnoned(bounds%begp:bounds%endp,nnphtrans-nnphouttrans)
+ real(r8),dimension(:,:) :: Agmconed(bounds%begp:bounds%endp,ncgmtrans-ncgmouttrans)
+ real(r8),dimension(:,:) :: Agmnoned(bounds%begp:bounds%endp,nngmtrans-nngmouttrans)
+ real(r8),dimension(:,:) :: Aficoned(bounds%begp:bounds%endp,ncfitrans-ncfiouttrans)
+ real(r8),dimension(:,:) :: Afic14oned(bounds%begp:bounds%endp,ncfitrans-ncfiouttrans)
+ real(r8),dimension(:,:) :: Afinoned(bounds%begp:bounds%endp,nnfitrans-nnfiouttrans)
+
+ ! Temporary variables saving row indices of all transfers in different processes
+ integer,dimension(:) :: AI_phc(ncphtrans-ncphouttrans)
+ integer,dimension(:) :: AI_phn(nnphtrans-nnphouttrans)
+ integer,dimension(:) :: AI_gmc(ncgmtrans-ncgmouttrans)
+ integer,dimension(:) :: AI_gmn(nngmtrans-nngmouttrans)
+ integer,dimension(:) :: AI_fic(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AI_fic14(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AI_fin(nnfitrans-nnfiouttrans)
+
+ ! Temporary variables saving column indices of all transfers in different processes
+ integer,dimension(:) :: AJ_phc(ncphtrans-ncphouttrans)
+ integer,dimension(:) :: AJ_phn(nnphtrans-nnphouttrans)
+ integer,dimension(:) :: AJ_gmc(ncgmtrans-ncgmouttrans)
+ integer,dimension(:) :: AJ_gmn(nngmtrans-nngmouttrans)
+ integer,dimension(:) :: AJ_fic(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AJ_fic14(ncfitrans-ncfiouttrans)
+ integer,dimension(:) :: AJ_fin(nnfitrans-nnfiouttrans)
+
+ ! Temporary variables for matrix operation, which save C and N inputs to different vegetation compartments as a vector type.
+ type(vector_type) :: vegmatrixc_input
+ type(vector_type) :: vegmatrixc13_input
+ type(vector_type) :: vegmatrixc14_input
+ type(vector_type) :: vegmatrixn_input
+
+ ! "init" indicators indicate whether A matrices have been initialized.
+ logical, save :: init_ready_aphc = .false.
+ logical, save :: init_ready_agmc = .false.
+ logical, save :: init_ready_afic = .false.
+ logical, save :: init_ready_afic14 = .false.
+ logical, save :: init_ready_aphn = .false.
+ logical, save :: init_ready_agmn = .false.
+ logical, save :: init_ready_afin = .false.
+
+ ! "list" indicators indicate whether operation of sparse matrix plus SPMP_AB or SPMP_ABC has already been saved.
+ logical, save :: list_ready_phgmfic = .false.
+ logical, save :: list_ready_phgmfic14 = .false.
+ logical, save :: list_ready_phgmc = .false.
+ logical, save :: list_ready_phgmfin = .false.
+ logical, save :: list_ready_phgmn = .false.
+
+ ! Temporary variables are only used at end of the year to calculate C and N storage capacity
+ real(r8),dimension(:) :: matrix_calloc_acc (1:nvegcpool)
+ real(r8),dimension(:) :: matrix_nalloc_acc (1:nvegnpool)
+ real(r8),dimension(:,:) :: matrix_ctransfer_acc (1:nvegcpool,1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_ntransfer_acc (1:nvegnpool,1:nvegnpool)
+ real(r8),dimension(:) :: matrix_c13alloc_acc (1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_c13transfer_acc (1:nvegcpool,1:nvegcpool)
+ real(r8),dimension(:) :: matrix_c14alloc_acc (1:nvegcpool)
+ real(r8),dimension(:,:) :: matrix_c14transfer_acc (1:nvegcpool,1:nvegcpool)
+
+ ! Local variables for capacity calculation and spin up
+ real(r8),dimension(:) :: vegmatrixc_rt(1:nvegcpool) ! C storage capacity
+ real(r8),dimension(:) :: vegmatrixc13_rt(1:nvegcpool) ! C13 storage capacity
+ real(r8),dimension(:) :: vegmatrixc14_rt(1:nvegcpool) ! C14 storage capacity
+ real(r8),dimension(:) :: vegmatrixn_rt(1:nvegnpool) ! N storage capacity
+ real(r8),dimension(:,:) :: AKinvc(1:nvegcpool,1:nvegcpool),AKinvn(1:nvegnpool,1:nvegnpool)
+ real(r8):: epsi
+
+
+ real(r8):: dt ! time step (seconds)
+#ifdef _OPENMP
+ integer, external :: OMP_GET_MAX_THREADS
+ integer :: nthreads ! Number of threads
+#else
+ integer, parameter :: nthreads = 0 ! Number of threads
+#endif
+ integer, parameter :: irepr = 1 ! Reproductive index to use for grain
+
+fr: associate( &
+ ivt => patch%itype , & ! Input: [integer (:) ] patch vegetation type
+ cf13_veg => c13_cnveg_carbonflux_inst , & ! In
+ cf14_veg => c14_cnveg_carbonflux_inst , & ! In
+ cs13_veg => c13_cnveg_carbonstate_inst , & ! In/Output
+ cs14_veg => c14_cnveg_carbonstate_inst , & ! In/Output
+
+ fire_closs => cnveg_carbonflux_inst%fire_closs_patch , &
+
+ ! Original vegetation variables are updated by matrix operation in this module
+ leafc => cnveg_carbonstate_inst%leafc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C
+ leafc_storage => cnveg_carbonstate_inst%leafc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf storage C
+ leafc_xfer => cnveg_carbonstate_inst%leafc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf transfer C
+ frootc => cnveg_carbonstate_inst%frootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root C
+ frootc_storage => cnveg_carbonstate_inst%frootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root storage C
+ frootc_xfer => cnveg_carbonstate_inst%frootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root transfer C
+ livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem C
+ livestemc_storage => cnveg_carbonstate_inst%livestemc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem storage C
+ livestemc_xfer => cnveg_carbonstate_inst%livestemc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem transfer C
+ deadstemc => cnveg_carbonstate_inst%deadstemc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem C
+ deadstemc_storage => cnveg_carbonstate_inst%deadstemc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem storage C
+ deadstemc_xfer => cnveg_carbonstate_inst%deadstemc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem transfer C
+ livecrootc => cnveg_carbonstate_inst%livecrootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root C
+ livecrootc_storage => cnveg_carbonstate_inst%livecrootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root storage C
+ livecrootc_xfer => cnveg_carbonstate_inst%livecrootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root transfer C
+ deadcrootc => cnveg_carbonstate_inst%deadcrootc_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root C
+ deadcrootc_storage => cnveg_carbonstate_inst%deadcrootc_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root storage C
+ deadcrootc_xfer => cnveg_carbonstate_inst%deadcrootc_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root transfer C
+ reproductivec => cnveg_carbonstate_inst%reproductivec_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C
+ reproductivec_storage => cnveg_carbonstate_inst%reproductivec_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C
+ reproductivec_xfer => cnveg_carbonstate_inst%reproductivec_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain transfer C
+
+ leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf N
+ leafn_storage => cnveg_nitrogenstate_inst%leafn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf storage N
+ leafn_xfer => cnveg_nitrogenstate_inst%leafn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf transfer N
+ frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root N
+ frootn_storage => cnveg_nitrogenstate_inst%frootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root storage N
+ frootn_xfer => cnveg_nitrogenstate_inst%frootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root transfer N
+ livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem N
+ livestemn_storage => cnveg_nitrogenstate_inst%livestemn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem storage N
+ livestemn_xfer => cnveg_nitrogenstate_inst%livestemn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem transfer N
+ deadstemn => cnveg_nitrogenstate_inst%deadstemn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem N
+ deadstemn_storage => cnveg_nitrogenstate_inst%deadstemn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem storage N
+ deadstemn_xfer => cnveg_nitrogenstate_inst%deadstemn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem transfer N
+ livecrootn => cnveg_nitrogenstate_inst%livecrootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root N
+ livecrootn_storage => cnveg_nitrogenstate_inst%livecrootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root storage N
+ livecrootn_xfer => cnveg_nitrogenstate_inst%livecrootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root transfer N
+ deadcrootn => cnveg_nitrogenstate_inst%deadcrootn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root N
+ deadcrootn_storage => cnveg_nitrogenstate_inst%deadcrootn_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root storage N
+ deadcrootn_xfer => cnveg_nitrogenstate_inst%deadcrootn_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root transfer N
+ reproductiven => cnveg_nitrogenstate_inst%reproductiven_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain N
+ reproductiven_storage => cnveg_nitrogenstate_inst%reproductiven_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain storage N
+ reproductiven_xfer => cnveg_nitrogenstate_inst%reproductiven_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain transfer N
+ retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) plant retranslocated N
+
+ leafc_SASUsave => cnveg_carbonstate_inst%leafc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ leafc_storage_SASUsave => cnveg_carbonstate_inst%leafc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ leafc_xfer_SASUsave => cnveg_carbonstate_inst%leafc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C for SASU
+ frootc_SASUsave => cnveg_carbonstate_inst%frootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ frootc_storage_SASUsave => cnveg_carbonstate_inst%frootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ frootc_xfer_SASUsave => cnveg_carbonstate_inst%frootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot C for SASU
+ livestemc_SASUsave => cnveg_carbonstate_inst%livestemc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ livestemc_storage_SASUsave => cnveg_carbonstate_inst%livestemc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ livestemc_xfer_SASUsave => cnveg_carbonstate_inst%livestemc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem C for SASU
+ deadstemc_SASUsave => cnveg_carbonstate_inst%deadstemc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ deadstemc_storage_SASUsave => cnveg_carbonstate_inst%deadstemc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ deadstemc_xfer_SASUsave => cnveg_carbonstate_inst%deadstemc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem C for SASU
+ livecrootc_SASUsave => cnveg_carbonstate_inst%livecrootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ livecrootc_storage_SASUsave => cnveg_carbonstate_inst%livecrootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ livecrootc_xfer_SASUsave => cnveg_carbonstate_inst%livecrootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot C for SASU
+ deadcrootc_SASUsave => cnveg_carbonstate_inst%deadcrootc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ deadcrootc_storage_SASUsave => cnveg_carbonstate_inst%deadcrootc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ deadcrootc_xfer_SASUsave => cnveg_carbonstate_inst%deadcrootc_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot C for SASU
+ grainc_SASUsave => cnveg_carbonstate_inst%grainc_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C for SASU
+ grainc_storage_SASUsave => cnveg_carbonstate_inst%grainc_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C for SASU
+
+ leafn_SASUsave => cnveg_nitrogenstate_inst%leafn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ leafn_storage_SASUsave => cnveg_nitrogenstate_inst%leafn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ leafn_xfer_SASUsave => cnveg_nitrogenstate_inst%leafn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf N for SASU
+ frootn_SASUsave => cnveg_nitrogenstate_inst%frootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ frootn_storage_SASUsave => cnveg_nitrogenstate_inst%frootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ frootn_xfer_SASUsave => cnveg_nitrogenstate_inst%frootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) froot N for SASU
+ livestemn_SASUsave => cnveg_nitrogenstate_inst%livestemn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ livestemn_storage_SASUsave => cnveg_nitrogenstate_inst%livestemn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ livestemn_xfer_SASUsave => cnveg_nitrogenstate_inst%livestemn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livestem N for SASU
+ deadstemn_SASUsave => cnveg_nitrogenstate_inst%deadstemn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ deadstemn_storage_SASUsave => cnveg_nitrogenstate_inst%deadstemn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ deadstemn_xfer_SASUsave => cnveg_nitrogenstate_inst%deadstemn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadstem N for SASU
+ livecrootn_SASUsave => cnveg_nitrogenstate_inst%livecrootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ livecrootn_storage_SASUsave => cnveg_nitrogenstate_inst%livecrootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ livecrootn_xfer_SASUsave => cnveg_nitrogenstate_inst%livecrootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) livecroot N for SASU
+ deadcrootn_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ deadcrootn_storage_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ deadcrootn_xfer_SASUsave => cnveg_nitrogenstate_inst%deadcrootn_xfer_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) deadcroot N for SASU
+ grainn_SASUsave => cnveg_nitrogenstate_inst%grainn_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain N for SASU
+ grainn_storage_SASUsave => cnveg_nitrogenstate_inst%grainn_storage_SASUsave_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage N for SASU
+
+ ! Vegetation capacity variables "matrix_cap_*", save the capacity of each vegetation compartment.
+ matrix_cap_leafc => cnveg_carbonstate_inst%matrix_cap_leafc_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf C capacity
+ matrix_cap_leafc_storage => cnveg_carbonstate_inst%matrix_cap_leafc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf storage C capacity
+ matrix_cap_leafc_xfer => cnveg_carbonstate_inst%matrix_cap_leafc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) leaf transfer C capacity
+ matrix_cap_frootc => cnveg_carbonstate_inst%matrix_cap_frootc_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root C capacity
+ matrix_cap_frootc_storage => cnveg_carbonstate_inst%matrix_cap_frootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root storage C capacity
+ matrix_cap_frootc_xfer => cnveg_carbonstate_inst%matrix_cap_frootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) fine root transfer C capacity
+ matrix_cap_livestemc => cnveg_carbonstate_inst%matrix_cap_livestemc_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem C capacity
+ matrix_cap_livestemc_storage => cnveg_carbonstate_inst%matrix_cap_livestemc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem storage C capacity
+ matrix_cap_livestemc_xfer => cnveg_carbonstate_inst%matrix_cap_livestemc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) live stem transfer C capacity
+ matrix_cap_deadstemc => cnveg_carbonstate_inst%matrix_cap_deadstemc_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem C capacity
+ matrix_cap_deadstemc_storage => cnveg_carbonstate_inst%matrix_cap_deadstemc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem storage C capaicty
+ matrix_cap_deadstemc_xfer => cnveg_carbonstate_inst%matrix_cap_deadstemc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) dead stem transfer C capacity
+ matrix_cap_livecrootc => cnveg_carbonstate_inst%matrix_cap_livecrootc_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root C capacity
+ matrix_cap_livecrootc_storage => cnveg_carbonstate_inst%matrix_cap_livecrootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root storage C capacity
+ matrix_cap_livecrootc_xfer => cnveg_carbonstate_inst%matrix_cap_livecrootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) live coarse root transfer C capacity
+ matrix_cap_deadcrootc => cnveg_carbonstate_inst%matrix_cap_deadcrootc_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root C capacity
+ matrix_cap_deadcrootc_storage => cnveg_carbonstate_inst%matrix_cap_deadcrootc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root storage C capacity
+ matrix_cap_deadcrootc_xfer => cnveg_carbonstate_inst%matrix_cap_deadcrootc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) dead coarse root transfer C capacity
+ matrix_cap_reproc => cnveg_carbonstate_inst%matrix_cap_reproc_patch ,&!Output:[real(r8)(:)] (gC/m2) grain C capacity
+ matrix_cap_reproc_storage => cnveg_carbonstate_inst%matrix_cap_reproc_storage_patch ,&!Output:[real(r8)(:)] (gC/m2) grain storage C capacity
+ matrix_cap_reproc_xfer => cnveg_carbonstate_inst%matrix_cap_reproc_xfer_patch ,&!Output:[real(r8)(:)] (gC/m2) grain transfer C
+
+ matrix_cap_leafn => cnveg_nitrogenstate_inst%matrix_cap_leafn_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf N capacity
+ matrix_cap_leafn_storage => cnveg_nitrogenstate_inst%matrix_cap_leafn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf storage N capacity
+ matrix_cap_leafn_xfer => cnveg_nitrogenstate_inst%matrix_cap_leafn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) leaf transfer N capacity
+ matrix_cap_frootn => cnveg_nitrogenstate_inst%matrix_cap_frootn_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root N capacity
+ matrix_cap_frootn_storage => cnveg_nitrogenstate_inst%matrix_cap_frootn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root storage N capacity
+ matrix_cap_frootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_frootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) fine root transfer N capacity
+ matrix_cap_livestemn => cnveg_nitrogenstate_inst%matrix_cap_livestemn_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem N capacity
+ matrix_cap_livestemn_storage => cnveg_nitrogenstate_inst%matrix_cap_livestemn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem storage N capacity
+ matrix_cap_livestemn_xfer => cnveg_nitrogenstate_inst%matrix_cap_livestemn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) live stem transfer N capacity
+ matrix_cap_deadstemn => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem N capacity
+ matrix_cap_deadstemn_storage => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem storage N capacity
+ matrix_cap_deadstemn_xfer => cnveg_nitrogenstate_inst%matrix_cap_deadstemn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) dead stem transfer N capacity
+ matrix_cap_livecrootn => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_patch ,&!Output:[real(r8)(:)] (gN/m2) live coarse root N capacity
+ matrix_cap_livecrootn_storage => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_storage_patch,&!Output:[real(r8)(:)] (gN/m2) live coarse root storage N capacity
+ matrix_cap_livecrootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_livecrootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) live coarse root transfer N capacity
+ matrix_cap_deadcrootn => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_patch ,&!Output:[real(r8)(:)] (gN/m2) dead coarse root N capacity
+ matrix_cap_deadcrootn_storage => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_storage_patch,&!Output:[real(r8)(:)] (gN/m2) dead coarse root storage N capacity
+ matrix_cap_deadcrootn_xfer => cnveg_nitrogenstate_inst%matrix_cap_deadcrootn_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) dead coarse root transfer N capacity
+ matrix_cap_repron => cnveg_nitrogenstate_inst%matrix_cap_repron_patch ,&!Output:[real(r8)(:)] (gN/m2) grain N capacity
+ matrix_cap_repron_storage => cnveg_nitrogenstate_inst%matrix_cap_repron_storage_patch ,&!Output:[real(r8)(:)] (gN/m2) grain storage N capacity
+ matrix_cap_repron_xfer => cnveg_nitrogenstate_inst%matrix_cap_repron_xfer_patch ,&!Output:[real(r8)(:)] (gN/m2) grain transfer N capacity
+
+ ! Variables matrix_calloc_*_acc, matrix_ctransfer_*_acc, and matrix_cturnover_*_acc are used to calculate the C capacity as the C steady state estimates in spin up.
+ ! These variables are all state variables, saving accumulated N transfers during the calendar year.
+ matrix_calloc_leaf_acc => cnveg_carbonstate_inst%matrix_calloc_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to leaf during this year
+ matrix_calloc_leafst_acc => cnveg_carbonstate_inst%matrix_calloc_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to leaf storage during this year
+ matrix_calloc_froot_acc => cnveg_carbonstate_inst%matrix_calloc_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to fine root during this year
+ matrix_calloc_frootst_acc => cnveg_carbonstate_inst%matrix_calloc_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to fine root storage during this year
+ matrix_calloc_livestem_acc => cnveg_carbonstate_inst%matrix_calloc_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live stem during this year
+ matrix_calloc_livestemst_acc => cnveg_carbonstate_inst%matrix_calloc_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live stem storage during this year
+ matrix_calloc_deadstem_acc => cnveg_carbonstate_inst%matrix_calloc_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead stem during this year
+ matrix_calloc_deadstemst_acc => cnveg_carbonstate_inst%matrix_calloc_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead stem storage during this year
+ matrix_calloc_livecroot_acc => cnveg_carbonstate_inst%matrix_calloc_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live corase root during this year
+ matrix_calloc_livecrootst_acc => cnveg_carbonstate_inst%matrix_calloc_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to live corase root storage during this year
+ matrix_calloc_deadcroot_acc => cnveg_carbonstate_inst%matrix_calloc_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead corase root during this year
+ matrix_calloc_deadcrootst_acc => cnveg_carbonstate_inst%matrix_calloc_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to dead corase root storage during this year
+ matrix_calloc_grain_acc => cnveg_carbonstate_inst%matrix_calloc_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to grain during this year
+ matrix_calloc_grainst_acc => cnveg_carbonstate_inst%matrix_calloc_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) Input C allocated to grain storage during this year
+
+ matrix_ctransfer_leafst_to_leafxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_leafst_to_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from leaf storage to leaf transfer pool during this year
+ matrix_ctransfer_leafxf_to_leaf_acc => cnveg_carbonstate_inst%matrix_ctransfer_leafxf_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from leaf transfer to leaf pool during this year
+ matrix_ctransfer_frootst_to_frootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_frootst_to_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from fine root storage to fine root transfer pool during this year
+ matrix_ctransfer_frootxf_to_froot_acc => cnveg_carbonstate_inst%matrix_ctransfer_frootxf_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from fine root transfer to fine root pool during this year
+ matrix_ctransfer_livestemst_to_livestemxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestemst_to_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem storage to live stem transfer pool during this year
+ matrix_ctransfer_livestemxf_to_livestem_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestemxf_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem transfer to live stem pool during this year
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead stem storage to dead stem transfer pool during this year
+ matrix_ctransfer_deadstemxf_to_deadstem_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead stem transfer to dead stem pool during this year
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root storage to live coarse root transfer pool during this year
+ matrix_ctransfer_livecrootxf_to_livecroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root transfer to live coarse root pool during this year
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from dead coarse root transfer to dead coarse root pool during this year
+ matrix_ctransfer_grainst_to_grainxf_acc => cnveg_carbonstate_inst%matrix_ctransfer_grainst_to_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from grain storage to grain transfer pool during this year
+ matrix_ctransfer_grainxf_to_grain_acc => cnveg_carbonstate_inst%matrix_ctransfer_grainxf_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from grain transfer to grain pool during this year
+ matrix_ctransfer_livestem_to_deadstem_acc => cnveg_carbonstate_inst%matrix_ctransfer_livestem_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live stem to dead stem pool during this year
+ matrix_ctransfer_livecroot_to_deadcroot_acc => cnveg_carbonstate_inst%matrix_ctransfer_livecroot_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C transfer from live coarse root to dead coarse root pool during this year
+
+ matrix_cturnover_leaf_acc => cnveg_carbonstate_inst%matrix_cturnover_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf
+ matrix_cturnover_leafst_acc => cnveg_carbonstate_inst%matrix_cturnover_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf storage
+ matrix_cturnover_leafxf_acc => cnveg_carbonstate_inst%matrix_cturnover_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from leaf transfer
+ matrix_cturnover_froot_acc => cnveg_carbonstate_inst%matrix_cturnover_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root
+ matrix_cturnover_frootst_acc => cnveg_carbonstate_inst%matrix_cturnover_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root storage
+ matrix_cturnover_frootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from fine root transfer
+ matrix_cturnover_livestem_acc => cnveg_carbonstate_inst%matrix_cturnover_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem
+ matrix_cturnover_livestemst_acc => cnveg_carbonstate_inst%matrix_cturnover_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem storage
+ matrix_cturnover_livestemxf_acc => cnveg_carbonstate_inst%matrix_cturnover_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live stem transfer
+ matrix_cturnover_deadstem_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem
+ matrix_cturnover_deadstemst_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem storage
+ matrix_cturnover_deadstemxf_acc => cnveg_carbonstate_inst%matrix_cturnover_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead stem transfer
+ matrix_cturnover_livecroot_acc => cnveg_carbonstate_inst%matrix_cturnover_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root
+ matrix_cturnover_livecrootst_acc => cnveg_carbonstate_inst%matrix_cturnover_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root storage
+ matrix_cturnover_livecrootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from live coarse root transfer
+ matrix_cturnover_deadcroot_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root
+ matrix_cturnover_deadcrootst_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root storage
+ matrix_cturnover_deadcrootxf_acc => cnveg_carbonstate_inst%matrix_cturnover_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from dead coarse root transfer
+ matrix_cturnover_grain_acc => cnveg_carbonstate_inst%matrix_cturnover_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain
+ matrix_cturnover_grainst_acc => cnveg_carbonstate_inst%matrix_cturnover_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain storage
+ matrix_cturnover_grainxf_acc => cnveg_carbonstate_inst%matrix_cturnover_grainxf_acc_patch &
+ ! In/Output: [real(r8) (:) ] (gC/m2/year) C turnover from grain transfer
+ )
+od: associate( &
+
+ ! Variables matrix_nalloc_*_acc, matrix_ntransfer_*_acc, and matrix_nturnover_*_acc are used to calculate the N capacity as the N steady state estimates in spin up.
+ ! These variables are all state variables, saving accumulated N transfers during the calendar year.
+ matrix_nalloc_leaf_acc => cnveg_nitrogenstate_inst%matrix_nalloc_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to leaf during this year
+ matrix_nalloc_leafst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to leaf storage during this year
+ matrix_nalloc_froot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to fine root during this year
+ matrix_nalloc_frootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to fine root storage during this year
+ matrix_nalloc_livestem_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live stem during this year
+ matrix_nalloc_livestemst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live stem storage during this year
+ matrix_nalloc_deadstem_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead stem during this year
+ matrix_nalloc_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead stem storage during this year
+ matrix_nalloc_livecroot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live coarse root during this year
+ matrix_nalloc_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to live coarse root storage during this year
+ matrix_nalloc_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead coarse root during this year
+ matrix_nalloc_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to dead coarse root storage during this year
+ matrix_nalloc_grain_acc => cnveg_nitrogenstate_inst%matrix_nalloc_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to grain during this year
+ matrix_nalloc_grainst_acc => cnveg_nitrogenstate_inst%matrix_nalloc_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) Input N allocated to grain storage during this year
+
+ matrix_ntransfer_leafst_to_leafxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leafst_to_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf storage to leaf transfer pool during this year
+ matrix_ntransfer_leafxf_to_leaf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leafxf_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf transfer to leaf pool during this year
+ matrix_ntransfer_frootst_to_frootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_frootst_to_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root storage to fine root transfer pool during this year
+ matrix_ntransfer_frootxf_to_froot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_frootxf_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root transfer to fine root pool during this year
+ matrix_ntransfer_livestemst_to_livestemxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestemst_to_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem storage to live stem transfer pool during this year
+ matrix_ntransfer_livestemxf_to_livestem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestemxf_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem transfer to live stem pool during this year
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead stem storage to dead stem transfer pool during this year
+ matrix_ntransfer_deadstemxf_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead stem transfer to dead stem pool during this year
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarese root storage to live coarese root transfer pool during this year
+ matrix_ntransfer_livecrootxf_to_livecroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarese root transfer to live coarese root pool during this year
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from dead coarse root transfer to dead coarse root pool during this year
+ matrix_ntransfer_grainst_to_grainxf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_grainst_to_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from grain storage to grain transfer pool during this year
+ matrix_ntransfer_grainxf_to_grain_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_grainxf_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from grain transfer to grain pool during this year
+ matrix_ntransfer_livestem_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestem_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem storage to dead stem transfer pool during this year
+ matrix_ntransfer_livecroot_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecroot_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarse root to dead coarse root pool during this year
+
+ matrix_ntransfer_retransn_to_leaf_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to leaf pool during this year
+ matrix_ntransfer_retransn_to_leafst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to leaf storage pool during this year
+ matrix_ntransfer_retransn_to_froot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to fine root pool during this year
+ matrix_ntransfer_retransn_to_frootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to fine root storage pool during this year
+ matrix_ntransfer_retransn_to_livestem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live stem pool during this year
+ matrix_ntransfer_retransn_to_livestemst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to livestem storage pool during this year
+ matrix_ntransfer_retransn_to_deadstem_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead stem pool during this year
+ matrix_ntransfer_retransn_to_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead stem storage pool during this year
+ matrix_ntransfer_retransn_to_livecroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live coarse root pool during this year
+ matrix_ntransfer_retransn_to_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to live coarse root storage pool during this year
+ matrix_ntransfer_retransn_to_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead coarse root pool during this year
+ matrix_ntransfer_retransn_to_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to dead coarse root storage pool during this year
+ matrix_ntransfer_retransn_to_grain_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to grain pool during this year
+ matrix_ntransfer_retransn_to_grainst_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_retransn_to_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from retranslocated N pool to grain storage pool during this year
+
+ matrix_ntransfer_leaf_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_leaf_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from leaf pool to retranslocated N pool during this year
+ matrix_ntransfer_froot_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_froot_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from fine root pool to retranslocated N pool during this year
+ matrix_ntransfer_livestem_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livestem_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live stem pool to retranslocated N pool during this year
+ matrix_ntransfer_livecroot_to_retransn_acc => cnveg_nitrogenstate_inst%matrix_ntransfer_livecroot_to_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N transfer from live coarse root pool to retranslocated N pool during this year
+
+ matrix_nturnover_leaf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leaf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf
+ matrix_nturnover_leafst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leafst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf storage
+ matrix_nturnover_leafxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_leafxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from leaf transfer
+ matrix_nturnover_froot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_froot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root
+ matrix_nturnover_frootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_frootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root storage
+ matrix_nturnover_frootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_frootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from fine root transfer
+ matrix_nturnover_livestem_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem
+ matrix_nturnover_livestemst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem storage
+ matrix_nturnover_livestemxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livestemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live stem transfer
+ matrix_nturnover_deadstem_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstem_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem
+ matrix_nturnover_deadstemst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstemst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem storage
+ matrix_nturnover_deadstemxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadstemxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead stem transfer
+ matrix_nturnover_livecroot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root
+ matrix_nturnover_livecrootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root storage
+ matrix_nturnover_livecrootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_livecrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from live coarse root transfer
+ matrix_nturnover_deadcroot_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcroot_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root
+ matrix_nturnover_deadcrootst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcrootst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root storage
+ matrix_nturnover_deadcrootxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_deadcrootxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from dead coarse root transfer
+ matrix_nturnover_grain_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grain_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain
+ matrix_nturnover_grainst_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grainst_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain storage
+ matrix_nturnover_grainxf_acc => cnveg_nitrogenstate_inst%matrix_nturnover_grainxf_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from grain transfer
+ matrix_nturnover_retransn_acc => cnveg_nitrogenstate_inst%matrix_nturnover_retransn_acc_patch , &
+ ! In/Output: [real(r8) (:) ] (gN/m2/year) N turnover from retranslocated N pool
+
+ ! *c0* variables save vegetation pool size at beginning of each year as a base for capacity calculation. For examples,
+ ! C turnover rate of pool KC_leaf (yr-1) is calculated by C turnover during the calendar year: matrix_cturnover_leaf_acc (gC/m2/yr) / leafc0 (gC/m2)
+ leafc0 => cnveg_carbonstate_inst%leafc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf C at begin of this year
+ leafc0_storage => cnveg_carbonstate_inst%leafc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf storage C at begin of this year
+ leafc0_xfer => cnveg_carbonstate_inst%leafc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) leaf transfer C at begin of this year
+ frootc0 => cnveg_carbonstate_inst%frootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root C at begin of this year
+ frootc0_storage => cnveg_carbonstate_inst%frootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root storage C at begin of this year
+ frootc0_xfer => cnveg_carbonstate_inst%frootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) fine root transfer C at begin of this year
+ livestemc0 => cnveg_carbonstate_inst%livestemc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem C at begin of this year
+ livestemc0_storage => cnveg_carbonstate_inst%livestemc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem storage C at begin of this year
+ livestemc0_xfer => cnveg_carbonstate_inst%livestemc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live stem transfer C at begin of this year
+ deadstemc0 => cnveg_carbonstate_inst%deadstemc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem C at begin of this year
+ deadstemc0_storage => cnveg_carbonstate_inst%deadstemc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem storage C at begin of this year
+ deadstemc0_xfer => cnveg_carbonstate_inst%deadstemc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead stem transfer C at begin of this year
+ livecrootc0 => cnveg_carbonstate_inst%livecrootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root C at begin of this year
+ livecrootc0_storage => cnveg_carbonstate_inst%livecrootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root storage C at begin of this year
+ livecrootc0_xfer => cnveg_carbonstate_inst%livecrootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) live coarse root transfer C at begin of this year
+ deadcrootc0 => cnveg_carbonstate_inst%deadcrootc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root C at begin of this year
+ deadcrootc0_storage => cnveg_carbonstate_inst%deadcrootc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root storage C at begin of this year
+ deadcrootc0_xfer => cnveg_carbonstate_inst%deadcrootc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) dead coarse root transfer C at begin of this year
+ reproc0 => cnveg_carbonstate_inst%reproc0_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain C at begin of this year
+ reproc0_storage => cnveg_carbonstate_inst%reproc0_storage_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain storage C at begin of this year
+ reproc0_xfer => cnveg_carbonstate_inst%reproc0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gC/m2) grain transfer C at begin of this year
+
+ ! *n0* variables save vegetation pool size at beginning of each year as a base for capacity calculation. For examples,
+ ! N turnover rate of pool KN_leaf (yr-1) is calculated by N turnover during the calendar year matrix_nturnover_leaf_acc (gN/m2/yr) / leafn0 (gN/m2)
+ leafn0 => cnveg_nitrogenstate_inst%leafn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf N at begin of this year
+ leafn0_storage => cnveg_nitrogenstate_inst%leafn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf storage N at begin of this year
+ leafn0_xfer => cnveg_nitrogenstate_inst%leafn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) leaf transfer N at begin of this year
+ frootn0 => cnveg_nitrogenstate_inst%frootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root N at begin of this year
+ frootn0_storage => cnveg_nitrogenstate_inst%frootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root storage N at begin of this year
+ frootn0_xfer => cnveg_nitrogenstate_inst%frootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) fine root transfer N at begin of this year
+ livestemn0 => cnveg_nitrogenstate_inst%livestemn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem N at begin of this year
+ livestemn0_storage => cnveg_nitrogenstate_inst%livestemn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem storage N at begin of this year
+ livestemn0_xfer => cnveg_nitrogenstate_inst%livestemn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live stem transfer N at begin of this year
+ deadstemn0 => cnveg_nitrogenstate_inst%deadstemn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem N at begin of this year
+ deadstemn0_storage => cnveg_nitrogenstate_inst%deadstemn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem storage N at begin of this year
+ deadstemn0_xfer => cnveg_nitrogenstate_inst%deadstemn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead stem transfer N at begin of this year
+ livecrootn0 => cnveg_nitrogenstate_inst%livecrootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root N at begin of this year
+ livecrootn0_storage => cnveg_nitrogenstate_inst%livecrootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root storage N at begin of this year
+ livecrootn0_xfer => cnveg_nitrogenstate_inst%livecrootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) live coarse root transfer N at begin of this year
+ deadcrootn0 => cnveg_nitrogenstate_inst%deadcrootn0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root N at begin of this year
+ deadcrootn0_storage => cnveg_nitrogenstate_inst%deadcrootn0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root storage N at begin of this year
+ deadcrootn0_xfer => cnveg_nitrogenstate_inst%deadcrootn0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) dead coarse root transfer N at begin of this year
+ repron0 => cnveg_nitrogenstate_inst%repron0_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain N at begin of this year
+ repron0_storage => cnveg_nitrogenstate_inst%repron0_storage_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain storage N at begin of this year
+ repron0_xfer => cnveg_nitrogenstate_inst%repron0_xfer_patch , & ! In/Output: [real(r8) (:) ] (gN/m2) grain transfer N at begin of this year
+ retransn0 => cnveg_nitrogenstate_inst%retransn0_patch & ! In/Output: [real(r8) (:) ] (gN/m2) plant retranslocated N at begin of this year
+ )
+sd: associate( &
+
+ ! Following variables save the C and N transfer rate of different processes at current time step.
+ ! Eg. ph: phenology, gm: gap mortality (including harvest), fi: fire.
+ matrix_alloc => cnveg_carbonflux_inst%matrix_alloc_patch , & ! Input: [real(r8) (:,:)] (gC/gC) input C allocation matrix, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_nalloc => cnveg_nitrogenflux_inst%matrix_nalloc_patch , & ! Input: [real(r8) (:,:)] (gC/gC) input N allocation matrix, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_phtransfer => cnveg_carbonflux_inst%matrix_phtransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from phenology processes, updated in CNPhenology
+ matrix_gmtransfer => cnveg_carbonflux_inst%matrix_gmtransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from gap mortality processes, updated in CNGapMortality
+ matrix_fitransfer => cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in CNFireBaseMod or CNFireLi2014Mod
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from phenology processes, updated in CNVegMatrixMod and dynHarvestMod
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from gap mortality processe, updated in CNVegMatrixMods
+ matrix_fiturnover => cnveg_carbonflux_inst%matrix_fiturnover_patch , & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+
+ matrix_nphtransfer => cnveg_nitrogenflux_inst%matrix_nphtransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from phenology processes, updated in CNPhenology and (NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod)
+ matrix_ngmtransfer => cnveg_nitrogenflux_inst%matrix_ngmtransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from gap mortality processes, updated in CNGapMortality and dynHarvestMod
+ matrix_nfitransfer => cnveg_nitrogenflux_inst%matrix_nfitransfer_patch , & ! Input: [real(r8) (:,:)] (gN/m2/s) N transfer rate from fire processes, updated in CNFireBaseMod or CNFireLi2014Mod
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from phenology processes, updated in CNVegMatrixMod
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from gap mortality processes, updated in CNVegMatrixMod
+ matrix_nfiturnover => cnveg_nitrogenflux_inst%matrix_nfiturnover_patch , & ! Output: [real(r8) (:,:)] (gN/m2/step) N turnover rate from fire processes, updated in CNVegMatrixMod
+
+ matrix_Cinput => cnveg_carbonflux_inst%matrix_Cinput_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_C13input => cnveg_carbonflux_inst%matrix_C13input_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C13 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch , & ! Input: [real(r8) (:)] (gC/m2/s) C14 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch , & ! Input: [real(r8) (:)] (gN/m2/s) N input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+
+ ! Doners and receivers of all transfers from different processes have been prescribed in following variables:
+ doner_phc => cnveg_carbonflux_inst%matrix_phtransfer_doner_patch , & ! Input: [integer (:)] Doners of phenology related C transfer
+ receiver_phc => cnveg_carbonflux_inst%matrix_phtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of phenology related C transfer
+ doner_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_doner_patch , & ! Input: [integer (:)] Doners of gap mortality related C transfer
+ receiver_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of gap mortality related C transfer
+ doner_fic => cnveg_carbonflux_inst%matrix_fitransfer_doner_patch , & ! Input: [integer (:)] Doners of fire related C transfer
+ receiver_fic => cnveg_carbonflux_inst%matrix_fitransfer_receiver_patch , & ! Input: [integer (:)] Receiver of fire related C transfer
+ doner_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_doner_patch , & ! Input: [integer (:)] Doners of phenology related N transfer
+ receiver_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of phenology related N transfer
+ doner_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_doner_patch , & ! Input: [integer (:)] Doners of gap mortality related N transfer
+ receiver_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_receiver_patch , & ! Input: [integer (:)] Receiver of gap mortality related N transfer
+ doner_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_doner_patch , & ! Input: [integer (:)] Doners of fire related N transfer
+ receiver_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_receiver_patch , & ! Input: [integer (:)] Receiver of fire related N transfer
+
+ ! Index of each processes related C transfers. See subroutine InitTransfer in CNVegCarbonFluxType.F90 for details.
+ ileafst_to_ileafxf_phc => cnveg_carbonflux_inst%ileafst_to_ileafxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phc => cnveg_carbonflux_inst%ileafxf_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phc => cnveg_carbonflux_inst%ifrootst_to_ifrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phc => cnveg_carbonflux_inst%ifrootxf_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phc => cnveg_carbonflux_inst%ilivestemst_to_ilivestemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phc => cnveg_carbonflux_inst%ilivestemxf_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phc => cnveg_carbonflux_inst%ideadstemst_to_ideadstemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phc => cnveg_carbonflux_inst%ideadstemxf_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phc => cnveg_carbonflux_inst%ilivecrootst_to_ilivecrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phc => cnveg_carbonflux_inst%ilivecrootxf_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phc => cnveg_carbonflux_inst%ideadcrootst_to_ideadcrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phc => cnveg_carbonflux_inst%ideadcrootxf_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phc => cnveg_carbonflux_inst%ilivestem_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phc => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_phc => cnveg_carbonflux_inst%ileaf_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phc => cnveg_carbonflux_inst%ifroot_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phc => cnveg_carbonflux_inst%ilivestem_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from live stem pool to outside of vegetation pools
+ igrain_to_iout_phc => cnveg_carbonflux_inst%igrain_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related C transfer from grain pool to outside of vegetation pools
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ileaf_to_iout_fic => cnveg_carbonflux_inst%ileaf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fic => cnveg_carbonflux_inst%ileafst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fic => cnveg_carbonflux_inst%ileafxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fic => cnveg_carbonflux_inst%ifroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fic => cnveg_carbonflux_inst%ifrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fic => cnveg_carbonflux_inst%ifrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fic => cnveg_carbonflux_inst%ilivestem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fic => cnveg_carbonflux_inst%ilivestemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fic => cnveg_carbonflux_inst%ilivestemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fic => cnveg_carbonflux_inst%ideadstem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fic => cnveg_carbonflux_inst%ideadstemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fic => cnveg_carbonflux_inst%ideadstemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fic => cnveg_carbonflux_inst%ilivecroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fic => cnveg_carbonflux_inst%ilivecrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fic => cnveg_carbonflux_inst%ilivecrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fic => cnveg_carbonflux_inst%ideadcroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fic => cnveg_carbonflux_inst%ideadcrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fic => cnveg_carbonflux_inst%ideadcrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fic => cnveg_carbonflux_inst%ilivestem_to_ideadstem_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_fic => cnveg_carbonflux_inst%ilivecroot_to_ideadcroot_fi , &
+ ! Input: [integer (:)] Index of fire related C transfer from live coarse root pool to dead coarse root pool
+ ! Index of each processes related N transfers. See subroutine InitTransfer in CNVegNitrogenFluxType.F90 for details.
+ ileafst_to_ileafxf_phn => cnveg_nitrogenflux_inst%ileafst_to_ileafxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf storage pool to leaf transfer pool
+ ileafxf_to_ileaf_phn => cnveg_nitrogenflux_inst%ileafxf_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf transfer pool to leaf pool
+ ifrootst_to_ifrootxf_phn => cnveg_nitrogenflux_inst%ifrootst_to_ifrootxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root storage pool to fine root transfer pool
+ ifrootxf_to_ifroot_phn => cnveg_nitrogenflux_inst%ifrootxf_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root transfer pool to fine root pool
+ ilivestemst_to_ilivestemxf_phn => cnveg_nitrogenflux_inst%ilivestemst_to_ilivestemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem storage pool to live stem transfer pool
+ ilivestemxf_to_ilivestem_phn => cnveg_nitrogenflux_inst%ilivestemxf_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem transfer pool to live stem pool
+ ideadstemst_to_ideadstemxf_phn => cnveg_nitrogenflux_inst%ideadstemst_to_ideadstemxf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead stem storage pool to dead stem transfer pool
+ ideadstemxf_to_ideadstem_phn => cnveg_nitrogenflux_inst%ideadstemxf_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead stem transfer pool to dead stem pool
+ ilivecrootst_to_ilivecrootxf_phn => cnveg_nitrogenflux_inst%ilivecrootst_to_ilivecrootxf_ph, &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root storage pool to live coarse root transfer pool
+ ilivecrootxf_to_ilivecroot_phn => cnveg_nitrogenflux_inst%ilivecrootxf_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root transfer pool to live coarse root pool
+ ideadcrootst_to_ideadcrootxf_phn => cnveg_nitrogenflux_inst%ideadcrootst_to_ideadcrootxf_ph, &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead coarse root storage pool to dead coarse root transfer pool
+ ideadcrootxf_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ideadcrootxf_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from dead coarse root transfer pool to dead coarse root pool
+ ilivestem_to_ideadstem_phn => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to dead stem pool
+ ilivecroot_to_ideadcroot_phn => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root pool to dead coarse root pool
+ ileaf_to_iout_phn => cnveg_nitrogenflux_inst%ileaf_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf pool to outside of vegetation pools
+ ifroot_to_iout_phn => cnveg_nitrogenflux_inst%ifroot_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root pool to outside of vegetation pools
+ ilivestem_to_iout_phn => cnveg_nitrogenflux_inst%ilivestem_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to outside of vegetation pools
+ iretransn_to_iout_phn => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to outside of vegetation pools
+ igrain_to_iout_phn => cnveg_nitrogenflux_inst%igrain_to_iout_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from grain pool to outside of vegetation pools
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from leaf pool to retranslocated N pool
+ ifroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from fine root pool to retranslocated N pool
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live stem pool to retranslocated N pool
+ ilivecroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivecroot_to_iretransn_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from live coarse root pool to retranslocated N pool
+ iretransn_to_ileaf_phn => cnveg_nitrogenflux_inst%iretransn_to_ileaf_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to leaf pool
+ iretransn_to_ileafst_phn => cnveg_nitrogenflux_inst%iretransn_to_ileafst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to leaf storage pool
+ iretransn_to_ifroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ifroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to fine root pool
+ iretransn_to_ifrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ifrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to fine root storage pool
+ iretransn_to_ilivestem_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivestem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live stem pool
+ iretransn_to_ilivestemst_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivestemst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live stem storage pool
+ iretransn_to_ideadstem_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadstem_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead stem pool
+ iretransn_to_ideadstemst_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadstemst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead stem storage pool
+ iretransn_to_ilivecroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivecroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live coarse root pool
+ iretransn_to_ilivecrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ilivecrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to live coarse root storage pool
+ iretransn_to_ideadcroot_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadcroot_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead coarse root pool
+ iretransn_to_ideadcrootst_phn => cnveg_nitrogenflux_inst%iretransn_to_ideadcrootst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to dead coarse root storage pool
+ iretransn_to_igrain_phn => cnveg_nitrogenflux_inst%iretransn_to_igrain_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to grain pool
+ iretransn_to_igrainst_phn => cnveg_nitrogenflux_inst%iretransn_to_igrainst_ph , &
+ ! Input: [integer (:)] Index of phenology related N transfer from retranslocated N pool to grain storage pool
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm , &
+ ! Input: [integer (:)] Index of gap mortality related N transfer from retranslocated N pool to outside of vegetation pools
+ ileaf_to_iout_fin => cnveg_nitrogenflux_inst%ileaf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf pool to outside of vegetation pools
+ ileafst_to_iout_fin => cnveg_nitrogenflux_inst%ileafst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ ileafxf_to_iout_fin => cnveg_nitrogenflux_inst%ileafxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ ifroot_to_iout_fin => cnveg_nitrogenflux_inst%ifroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine root pool to outside of vegetation pools
+ ifrootst_to_iout_fin => cnveg_nitrogenflux_inst%ifrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ ifrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ifrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from fine transfer pool to outside of vegetation pools
+ ilivestem_to_iout_fin => cnveg_nitrogenflux_inst%ilivestem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem pool to outside of vegetation pools
+ ilivestemst_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ ilivestemxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ ideadstem_to_iout_fin => cnveg_nitrogenflux_inst%ideadstem_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ ideadstemst_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ ideadstemxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ ilivecroot_to_iout_fin => cnveg_nitrogenflux_inst%ilivecroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ ilivecrootst_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ ilivecrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ ideadcroot_to_iout_fin => cnveg_nitrogenflux_inst%ideadcroot_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ ideadcrootst_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ ideadcrootxf_to_iout_fin => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ ilivestem_to_ideadstem_fin => cnveg_nitrogenflux_inst%ilivestem_to_ideadstem_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live stem to dead stem pool
+ ilivecroot_to_ideadcroot_fin => cnveg_nitrogenflux_inst%ilivecroot_to_ideadcroot_fi , &
+ ! Input: [integer (:)] Index of fire related N transfer from live coarse root pool to dead coarse root pool
+ iretransn_to_iout_fin => cnveg_nitrogenflux_inst%iretransn_to_iout_fi &
+ ! Input: [integer (:)] Index of fire related N transfer from retranslocated N pool to outside of vegetation pools
+ )
+td: associate( &
+
+ ! Sparse matrix type of A*K
+ AKphvegc => cnveg_carbonflux_inst%AKphvegc , & ! Aph*Kph for C cycle in sparse matrix format
+ AKgmvegc => cnveg_carbonflux_inst%AKgmvegc , & ! Agm*Kgm for C cycle in sparse matrix format
+ AKfivegc => cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C cycle in sparse matrix format
+ AKallvegc => cnveg_carbonflux_inst%AKallvegc , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C cycle in sparse matrix format
+ NE_AKallvegc => cnveg_carbonflux_inst%NE_AKallvegc , & ! Number of entries in AKallvegc
+ RI_AKallvegc => cnveg_carbonflux_inst%RI_AKallvegc , & ! Row indices in Akallvegc
+ CI_AKallvegc => cnveg_carbonflux_inst%CI_AKallvegc , & ! Column indices in AKallvegc
+ Kvegc => cnveg_carbonflux_inst%Kvegc , & ! Temporary variable of Kph, Kgm or Kfi for C cycle in diagonal matrix format
+ Xvegc => cnveg_carbonflux_inst%Xvegc , & ! Vegetation C of each compartment in a vector format
+ AKphvegn => cnveg_nitrogenflux_inst%AKphvegn , & ! Aph*Kph for N cycle in sparse matrix format
+ AKgmvegn => cnveg_nitrogenflux_inst%AKgmvegn , & ! Agm*Kgm for N cycle in sparse matrix format
+ AKfivegn => cnveg_nitrogenflux_inst%AKfivegn , & ! Afi*Kfi for N cycle in sparse matrix format
+ AKallvegn => cnveg_nitrogenflux_inst%AKallvegn , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for N cycle in sparse matrix format
+ NE_AKallvegn => cnveg_nitrogenflux_inst%NE_AKallvegn , & ! Number of entries in AKallvegn
+ RI_AKallvegn => cnveg_nitrogenflux_inst%RI_AKallvegn , & ! Row indices in Akallvegn
+ CI_AKallvegn => cnveg_nitrogenflux_inst%CI_AKallvegn , & ! Column indices in AKallvegn
+ Kvegn => cnveg_nitrogenflux_inst%Kvegn , & ! Temporary variable of Kph, Kgm or Kfi for N cycle in diagonal matrix format
+ Xvegn => cnveg_nitrogenflux_inst%Xvegn , & ! Vegetation N of each compartment in a vector format
+ Xveg13c => cnveg_carbonflux_inst%Xveg13c , & ! Vegetation C13 of each compartment in a vector format
+ Xveg14c => cnveg_carbonflux_inst%Xveg14c , & ! Vegetation C14 of each compartment in a vector format
+
+ ! Row and column indices of A matrices
+ RI_phc => cnveg_carbonflux_inst%RI_phc , & ! Row indices of non-diagonal entires in Aph for C cycle
+ CI_phc => cnveg_carbonflux_inst%CI_phc , & ! Column indices of non-diagonal entries in Aph for C cycle
+ RI_gmc => cnveg_carbonflux_inst%RI_gmc , & ! Row indices of non-diagonal entires in Agm for C cycle
+ CI_gmc => cnveg_carbonflux_inst%CI_gmc , & ! Column indices of non-diagonal entries in Agm for C cycle
+ RI_fic => cnveg_carbonflux_inst%RI_fic , & ! Row indices of non-diagonal entires in Afi for C cycle
+ CI_fic => cnveg_carbonflux_inst%CI_fic , & ! Column indices of non-diagonal entries in Afi for C cycle
+ RI_phn => cnveg_nitrogenflux_inst%RI_phn , & ! Row indices of non-diagonal entires in Aph for N cycle
+ CI_phn => cnveg_nitrogenflux_inst%CI_phn , & ! Column indices of non-diagonal entries in Aph for N cycle
+ RI_gmn => cnveg_nitrogenflux_inst%RI_gmn , & ! Row indices of non-diagonal entires in Agm for N cycle
+ CI_gmn => cnveg_nitrogenflux_inst%CI_gmn , & ! Column indices of non-diagonal entries in Agm for N cycle
+ RI_fin => cnveg_nitrogenflux_inst%RI_fin , & ! Row indices of non-diagonal entires in Afi for N cycle
+ CI_fin => cnveg_nitrogenflux_inst%CI_fin , & ! Column indices of non-diagonal entries in Afi for N cycle
+
+ ! Following list contains indices of non-diagonal entries in full sparse matrix
+ list_aphc => cnveg_carbonflux_inst%list_aphc , & ! Indices of non-diagnoal entries in full sparse matrix Aph for C cycle
+ list_agmc => cnveg_carbonflux_inst%list_agmc , & ! Indices of non-diagnoal entries in full sparse matrix Agm for C cycle
+ list_afic => cnveg_carbonflux_inst%list_afic , & ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+ list_aphn => cnveg_nitrogenflux_inst%list_aphn , & ! Indices of non-diagnoal entries in full sparse matrix Aph for N cycle
+ list_agmn => cnveg_nitrogenflux_inst%list_agmn , & ! Indices of non-diagnoal entries in full sparse matrix Agm for N cycle
+ list_afin => cnveg_nitrogenflux_inst%list_afin , & ! Indices of non-diagnoal entries in full sparse matrix Afi for N cycle
+
+ ! For sparse matrix A, B and A + B, following list contains locations of entries in A or B or C mapped into matrix (A+B) or (A+B+C)
+ list_phc_phgm => cnveg_carbonflux_inst%list_phc_phgmc , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc)
+ list_gmc_phgm => cnveg_carbonflux_inst%list_gmc_phgmc , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc)
+ list_phc_phgmfi => cnveg_carbonflux_inst%list_phc_phgmfic , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_gmc_phgmfi => cnveg_carbonflux_inst%list_gmc_phgmfic , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_fic_phgmfi => cnveg_carbonflux_inst%list_fic_phgmfic , & ! The locations of entries in AKfivegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_phn_phgm => cnveg_nitrogenflux_inst%list_phn_phgmn , & ! The locations of entries in AKphvegn mapped into (AKphvegn+AKgmvegn)
+ list_gmn_phgm => cnveg_nitrogenflux_inst%list_gmn_phgmn , & ! The locations of entries in AKgmvegn mapped into (AKphvegn+AKgmvegn)
+ list_phn_phgmfi => cnveg_nitrogenflux_inst%list_phn_phgmfin , & ! The locations of entries in AKphvegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ list_gmn_phgmfi => cnveg_nitrogenflux_inst%list_gmn_phgmfin , & ! The locations of entries in AKgmvegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ list_fin_phgmfi => cnveg_nitrogenflux_inst%list_fin_phgmfin & ! The locations of entries in AKfivegn mapped into (AKphvegn+AKgmvegn+AKfivegn)
+ )
+#ifdef _OPENMP
+ nthreads = OMP_GET_MAX_THREADS()
+#endif
+ !-----------------------------------------------------------------------
+ ! set time steps
+ call t_startf('CN veg matrix-init')
+ dt = real( get_step_size(), r8 )
+
+ ! Initialize local variables
+ call vegmatrixc_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ if(use_c13)then
+ call vegmatrixc13_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ end if
+ if(use_c14)then
+ call vegmatrixc14_input%InitV(nvegcpool,bounds%begp,bounds%endp)
+ end if
+ call vegmatrixn_input%InitV(nvegnpool,bounds%begp,bounds%endp)
+
+ matrix_calloc_acc (:) = 0._r8
+ matrix_nalloc_acc (:) = 0._r8
+ matrix_ctransfer_acc (:,:) = 0._r8
+ matrix_ntransfer_acc (:,:) = 0._r8
+ if(use_c13)then
+ matrix_c13alloc_acc (:) = 0._r8
+ matrix_c13transfer_acc (:,:) = 0._r8
+ end if
+ if(use_c14)then
+ matrix_c14alloc_acc (:) = 0._r8
+ matrix_c14transfer_acc (:,:) = 0._r8
+ end if
+
+ AKinvc (:,:) = 0._r8
+ AKinvn (:,:) = 0._r8
+
+ epsi = 1.e-30_r8 ! small number
+
+ call t_stopf('CN veg matrix-init')
+
+ call t_startf('CN veg matrix-assigning matrix')
+
+ ! Calculate A matrices from C transfers and C turnovers
+ if(ncphtrans .gt. ncphouttrans)then
+ do k=1,ncphtrans-ncphouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_phturnover(p,doner_phc(k)) .ne. 0)then
+ Aphconed(p,k) = matrix_phtransfer(p,k) * dt / matrix_phturnover(p,doner_phc(k))
+ else
+ Aphconed(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(ncgmtrans .gt. ncgmouttrans)then
+ do k=1,ncgmtrans-ncgmouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_gmturnover(p,doner_gmc(k)) .ne. 0)then
+ Agmconed(p,k) = matrix_gmtransfer(p,k) * dt / matrix_gmturnover(p,doner_gmc(k))
+ else
+ Agmconed(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(ncfitrans .gt. ncfiouttrans)then
+ do k=1,ncfitrans-ncfiouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_fiturnover(p,doner_fic(k)) .ne. 0)then
+ Aficoned(p,k) = matrix_fitransfer(p,k) * dt / matrix_fiturnover(p,doner_fic(k))
+ else
+ Aficoned(p,k) = 0._r8
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ if(matrix_c14fiturnover(p,doner_fic(k)) .ne. 0)then
+ Afic14oned(p,k) = matrix_c14fitransfer(p,k) * dt / matrix_c14fiturnover(p,doner_fic(k))
+ else
+ Afic14oned(p,k) = 0._r8
+ end if
+ end associate
+ end if
+ end do
+ end do
+ end if
+
+ if(nnphtrans .gt. nnphouttrans)then
+ do k=1,nnphtrans-nnphouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_nphturnover(p,doner_phn(k)) .ne. 0)then
+ Aphnoned(p,k) = matrix_nphtransfer(p,k) * dt / matrix_nphturnover(p,doner_phn(k))
+ else
+ Aphnoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(nngmtrans .gt. nngmouttrans)then
+ do k=1,nngmtrans-nngmouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_ngmturnover(p,doner_phn(k)) .ne. 0)then
+ Agmnoned(p,k) = matrix_ngmtransfer(p,k) * dt / matrix_ngmturnover(p,doner_phn(k))
+ else
+ Agmnoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ if(nnfitrans .gt. nnfiouttrans)then
+ do k=1,nnfitrans-nnfiouttrans
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(matrix_nfiturnover(p,doner_fin(k)) .ne. 0)then
+ Afinoned(p,k) = matrix_nfitransfer(p,k) * dt / matrix_nfiturnover(p,doner_fin(k))
+ else
+ Afinoned(p,k) = 0._r8
+ end if
+ end do
+ end do
+ end if
+
+ call t_stopf('CN veg matrix-assigning matrix')
+
+ ! Assign old state variables to vector Xveg*
+ call t_startf('CN veg matrix-set old value')
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegc%V(p,ileaf) = leafc(p)
+ Xvegc%V(p,ileaf_st) = leafc_storage(p)
+ Xvegc%V(p,ileaf_xf) = leafc_xfer(p)
+ Xvegc%V(p,ifroot) = frootc(p)
+ Xvegc%V(p,ifroot_st) = frootc_storage(p)
+ Xvegc%V(p,ifroot_xf) = frootc_xfer(p)
+ Xvegc%V(p,ilivestem) = livestemc(p)
+ Xvegc%V(p,ilivestem_st) = livestemc_storage(p)
+ Xvegc%V(p,ilivestem_xf) = livestemc_xfer(p)
+ Xvegc%V(p,ideadstem) = deadstemc(p)
+ Xvegc%V(p,ideadstem_st) = deadstemc_storage(p)
+ Xvegc%V(p,ideadstem_xf) = deadstemc_xfer(p)
+ Xvegc%V(p,ilivecroot) = livecrootc(p)
+ Xvegc%V(p,ilivecroot_st) = livecrootc_storage(p)
+ Xvegc%V(p,ilivecroot_xf) = livecrootc_xfer(p)
+ Xvegc%V(p,ideadcroot) = deadcrootc(p)
+ Xvegc%V(p,ideadcroot_st) = deadcrootc_storage(p)
+ Xvegc%V(p,ideadcroot_xf) = deadcrootc_xfer(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xvegc%V(p,igrain) = reproductivec(p,irepr)
+ Xvegc%V(p,igrain_st) = reproductivec_storage(p,irepr)
+ Xvegc%V(p,igrain_xf) = reproductivec_xfer(p,irepr)
+ end if
+ end do
+
+ if ( use_c13 )then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg13c%V(p,ileaf) = cs13_veg%leafc_patch(p)
+ Xveg13c%V(p,ileaf_st) = cs13_veg%leafc_storage_patch(p)
+ Xveg13c%V(p,ileaf_xf) = cs13_veg%leafc_xfer_patch(p)
+ Xveg13c%V(p,ifroot) = cs13_veg%frootc_patch(p)
+ Xveg13c%V(p,ifroot_st) = cs13_veg%frootc_storage_patch(p)
+ Xveg13c%V(p,ifroot_xf) = cs13_veg%frootc_xfer_patch(p)
+ Xveg13c%V(p,ilivestem) = cs13_veg%livestemc_patch(p)
+ Xveg13c%V(p,ilivestem_st) = cs13_veg%livestemc_storage_patch(p)
+ Xveg13c%V(p,ilivestem_xf) = cs13_veg%livestemc_xfer_patch(p)
+ Xveg13c%V(p,ideadstem) = cs13_veg%deadstemc_patch(p)
+ Xveg13c%V(p,ideadstem_st) = cs13_veg%deadstemc_storage_patch(p)
+ Xveg13c%V(p,ideadstem_xf) = cs13_veg%deadstemc_xfer_patch(p)
+ Xveg13c%V(p,ilivecroot) = cs13_veg%livecrootc_patch(p)
+ Xveg13c%V(p,ilivecroot_st) = cs13_veg%livecrootc_storage_patch(p)
+ Xveg13c%V(p,ilivecroot_xf) = cs13_veg%livecrootc_xfer_patch(p)
+ Xveg13c%V(p,ideadcroot) = cs13_veg%deadcrootc_patch(p)
+ Xveg13c%V(p,ideadcroot_st) = cs13_veg%deadcrootc_storage_patch(p)
+ Xveg13c%V(p,ideadcroot_xf) = cs13_veg%deadcrootc_xfer_patch(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xveg13c%V(p,igrain) = cs13_veg%reproductivec_patch(p,irepr)
+ Xveg13c%V(p,igrain_st) = cs13_veg%reproductivec_storage_patch(p,irepr)
+ Xveg13c%V(p,igrain_xf) = cs13_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ end do
+ end if
+
+ if ( use_c14 )then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg14c%V(p,ileaf) = cs14_veg%leafc_patch(p)
+ Xveg14c%V(p,ileaf_st) = cs14_veg%leafc_storage_patch(p)
+ Xveg14c%V(p,ileaf_xf) = cs14_veg%leafc_xfer_patch(p)
+ Xveg14c%V(p,ifroot) = cs14_veg%frootc_patch(p)
+ Xveg14c%V(p,ifroot_st) = cs14_veg%frootc_storage_patch(p)
+ Xveg14c%V(p,ifroot_xf) = cs14_veg%frootc_xfer_patch(p)
+ Xveg14c%V(p,ilivestem) = cs14_veg%livestemc_patch(p)
+ Xveg14c%V(p,ilivestem_st) = cs14_veg%livestemc_storage_patch(p)
+ Xveg14c%V(p,ilivestem_xf) = cs14_veg%livestemc_xfer_patch(p)
+ Xveg14c%V(p,ideadstem) = cs14_veg%deadstemc_patch(p)
+ Xveg14c%V(p,ideadstem_st) = cs14_veg%deadstemc_storage_patch(p)
+ Xveg14c%V(p,ideadstem_xf) = cs14_veg%deadstemc_xfer_patch(p)
+ Xveg14c%V(p,ilivecroot) = cs14_veg%livecrootc_patch(p)
+ Xveg14c%V(p,ilivecroot_st) = cs14_veg%livecrootc_storage_patch(p)
+ Xveg14c%V(p,ilivecroot_xf) = cs14_veg%livecrootc_xfer_patch(p)
+ Xveg14c%V(p,ideadcroot) = cs14_veg%deadcrootc_patch(p)
+ Xveg14c%V(p,ideadcroot_st) = cs14_veg%deadcrootc_storage_patch(p)
+ Xveg14c%V(p,ideadcroot_xf) = cs14_veg%deadcrootc_xfer_patch(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ Xveg14c%V(p,igrain) = cs14_veg%reproductivec_patch(p,irepr)
+ Xveg14c%V(p,igrain_st) = cs14_veg%reproductivec_storage_patch(p,irepr)
+ Xveg14c%V(p,igrain_xf) = cs14_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegn%V(p,ileaf) = leafn(p)
+ Xvegn%V(p,ileaf_st) = leafn_storage(p)
+ Xvegn%V(p,ileaf_xf) = leafn_xfer(p)
+ Xvegn%V(p,ifroot) = frootn(p)
+ Xvegn%V(p,ifroot_st) = frootn_storage(p)
+ Xvegn%V(p,ifroot_xf) = frootn_xfer(p)
+ Xvegn%V(p,ilivestem) = livestemn(p)
+ Xvegn%V(p,ilivestem_st) = livestemn_storage(p)
+ Xvegn%V(p,ilivestem_xf) = livestemn_xfer(p)
+ Xvegn%V(p,ideadstem) = deadstemn(p)
+ Xvegn%V(p,ideadstem_st) = deadstemn_storage(p)
+ Xvegn%V(p,ideadstem_xf) = deadstemn_xfer(p)
+ Xvegn%V(p,ilivecroot) = livecrootn(p)
+ Xvegn%V(p,ilivecroot_st) = livecrootn_storage(p)
+ Xvegn%V(p,ilivecroot_xf) = livecrootn_xfer(p)
+ Xvegn%V(p,ideadcroot) = deadcrootn(p)
+ Xvegn%V(p,ideadcroot_st) = deadcrootn_storage(p)
+ Xvegn%V(p,ideadcroot_xf) = deadcrootn_xfer(p)
+ Xvegn%V(p,iretransn) = retransn(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ Xvegn%V(p,igrain) = sum(reproductiven(p,:))
+ Xvegn%V(p,igrain_st) = sum(reproductiven_storage(p,:))
+ Xvegn%V(p,igrain_xf) = sum(reproductiven_xfer(p,:))
+ end if
+ end do
+
+ ! Save *c0* and *n0* variables at begin of each year.
+ if (is_beg_curr_year())then
+ iyr = iyr + 1
+ if(mod(iyr-1,nyr_forcing) .eq. 0)then
+ iloop = iloop + 1
+ end if
+ if(.not. spinup_matrixcn .or. spinup_matrixcn .and. mod(iyr-1,nyr_SASU) .eq. 0)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafc0(p) = max(leafc(p), epsi)
+ leafc0_storage(p) = max(leafc_storage(p), epsi)
+ leafc0_xfer(p) = max(leafc_xfer(p), epsi)
+ frootc0(p) = max(frootc(p), epsi)
+ frootc0_storage(p) = max(frootc_storage(p), epsi)
+ frootc0_xfer(p) = max(frootc_xfer(p), epsi)
+ livestemc0(p) = max(livestemc(p), epsi)
+ livestemc0_storage(p) = max(livestemc_storage(p), epsi)
+ livestemc0_xfer(p) = max(livestemc_xfer(p), epsi)
+ deadstemc0(p) = max(deadstemc(p), epsi)
+ deadstemc0_storage(p) = max(deadstemc_storage(p), epsi)
+ deadstemc0_xfer(p) = max(deadstemc_xfer(p), epsi)
+ livecrootc0(p) = max(livecrootc(p), epsi)
+ livecrootc0_storage(p) = max(livecrootc_storage(p), epsi)
+ livecrootc0_xfer(p) = max(livecrootc_xfer(p), epsi)
+ deadcrootc0(p) = max(deadcrootc(p), epsi)
+ deadcrootc0_storage(p) = max(deadcrootc_storage(p), epsi)
+ deadcrootc0_xfer(p) = max(deadcrootc_xfer(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ reproc0(p) = max(reproductivec(p,irepr), epsi)
+ reproc0_storage(p) = max(reproductivec_storage(p,irepr), epsi)
+ reproc0_xfer(p) = max(reproductivec_xfer(p,irepr), epsi)
+ end if
+ end do
+
+ if(use_c13)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs13_veg%leafc0_patch(p) = max(cs13_veg%leafc_patch(p), epsi)
+ cs13_veg%leafc0_storage_patch(p) = max(cs13_veg%leafc_storage_patch(p), epsi)
+ cs13_veg%leafc0_xfer_patch(p) = max(cs13_veg%leafc_xfer_patch(p), epsi)
+ cs13_veg%frootc0_patch(p) = max(cs13_veg%frootc_patch(p), epsi)
+ cs13_veg%frootc0_storage_patch(p) = max(cs13_veg%frootc_storage_patch(p), epsi)
+ cs13_veg%frootc0_xfer_patch(p) = max(cs13_veg%frootc_xfer_patch(p), epsi)
+ cs13_veg%livestemc0_patch(p) = max(cs13_veg%livestemc_patch(p), epsi)
+ cs13_veg%livestemc0_storage_patch(p) = max(cs13_veg%livestemc_storage_patch(p), epsi)
+ cs13_veg%livestemc0_xfer_patch(p) = max(cs13_veg%livestemc_xfer_patch(p), epsi)
+ cs13_veg%deadstemc0_patch(p) = max(cs13_veg%deadstemc_patch(p), epsi)
+ cs13_veg%deadstemc0_storage_patch(p) = max(cs13_veg%deadstemc_storage_patch(p), epsi)
+ cs13_veg%deadstemc0_xfer_patch(p) = max(cs13_veg%deadstemc_xfer_patch(p), epsi)
+ cs13_veg%livecrootc0_patch(p) = max(cs13_veg%livecrootc_patch(p), epsi)
+ cs13_veg%livecrootc0_storage_patch(p) = max(cs13_veg%livecrootc_storage_patch(p), epsi)
+ cs13_veg%livecrootc0_xfer_patch(p) = max(cs13_veg%livecrootc_xfer_patch(p), epsi)
+ cs13_veg%deadcrootc0_patch(p) = max(cs13_veg%deadcrootc_patch(p), epsi)
+ cs13_veg%deadcrootc0_storage_patch(p) = max(cs13_veg%deadcrootc_storage_patch(p), epsi)
+ cs13_veg%deadcrootc0_xfer_patch(p) = max(cs13_veg%deadcrootc_xfer_patch(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ cs13_veg%reproc0_patch(p) = max(cs13_veg%reproductivec_patch(p,irepr), epsi)
+ cs13_veg%reproc0_storage_patch(p) = max(cs13_veg%reproductivec_storage_patch(p,irepr), epsi)
+ cs13_veg%reproc0_xfer_patch(p) = max(cs13_veg%reproductivec_xfer_patch(p,irepr), epsi)
+ end if
+ end do
+ end if
+
+ if(use_c14)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs14_veg%leafc0_patch(p) = max(cs14_veg%leafc_patch(p), epsi)
+ cs14_veg%leafc0_storage_patch(p) = max(cs14_veg%leafc_storage_patch(p), epsi)
+ cs14_veg%leafc0_xfer_patch(p) = max(cs14_veg%leafc_xfer_patch(p), epsi)
+ cs14_veg%frootc0_patch(p) = max(cs14_veg%frootc_patch(p), epsi)
+ cs14_veg%frootc0_storage_patch(p) = max(cs14_veg%frootc_storage_patch(p), epsi)
+ cs14_veg%frootc0_xfer_patch(p) = max(cs14_veg%frootc_xfer_patch(p), epsi)
+ cs14_veg%livestemc0_patch(p) = max(cs14_veg%livestemc_patch(p), epsi)
+ cs14_veg%livestemc0_storage_patch(p) = max(cs14_veg%livestemc_storage_patch(p), epsi)
+ cs14_veg%livestemc0_xfer_patch(p) = max(cs14_veg%livestemc_xfer_patch(p), epsi)
+ cs14_veg%deadstemc0_patch(p) = max(cs14_veg%deadstemc_patch(p), epsi)
+ cs14_veg%deadstemc0_storage_patch(p) = max(cs14_veg%deadstemc_storage_patch(p), epsi)
+ cs14_veg%deadstemc0_xfer_patch(p) = max(cs14_veg%deadstemc_xfer_patch(p), epsi)
+ cs14_veg%livecrootc0_patch(p) = max(cs14_veg%livecrootc_patch(p), epsi)
+ cs14_veg%livecrootc0_storage_patch(p) = max(cs14_veg%livecrootc_storage_patch(p), epsi)
+ cs14_veg%livecrootc0_xfer_patch(p) = max(cs14_veg%livecrootc_xfer_patch(p), epsi)
+ cs14_veg%deadcrootc0_patch(p) = max(cs14_veg%deadcrootc_patch(p), epsi)
+ cs14_veg%deadcrootc0_storage_patch(p) = max(cs14_veg%deadcrootc_storage_patch(p), epsi)
+ cs14_veg%deadcrootc0_xfer_patch(p) = max(cs14_veg%deadcrootc_xfer_patch(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ cs14_veg%reproc0_patch(p) = max(cs14_veg%reproductivec_patch(p,irepr), epsi)
+ cs14_veg%reproc0_storage_patch(p) = max(cs14_veg%reproductivec_storage_patch(p,irepr), epsi)
+ cs14_veg%reproc0_xfer_patch(p) = max(cs14_veg%reproductivec_xfer_patch(p,irepr), epsi)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafn0(p) = max(leafn(p), epsi)
+ leafn0_storage(p) = max(leafn_storage(p), epsi)
+ leafn0_xfer(p) = max(leafn_xfer(p), epsi)
+ frootn0(p) = max(frootn(p), epsi)
+ frootn0_storage(p) = max(frootn_storage(p), epsi)
+ frootn0_xfer(p) = max(frootn_xfer(p), epsi)
+ livestemn0(p) = max(livestemn(p), epsi)
+ livestemn0_storage(p) = max(livestemn_storage(p), epsi)
+ livestemn0_xfer(p) = max(livestemn_xfer(p), epsi)
+ deadstemn0(p) = max(deadstemn(p), epsi)
+ deadstemn0_storage(p) = max(deadstemn_storage(p), epsi)
+ deadstemn0_xfer(p) = max(deadstemn_xfer(p), epsi)
+ livecrootn0(p) = max(livecrootn(p), epsi)
+ livecrootn0_storage(p) = max(livecrootn_storage(p), epsi)
+ livecrootn0_xfer(p) = max(livecrootn_xfer(p), epsi)
+ deadcrootn0(p) = max(deadcrootn(p), epsi)
+ deadcrootn0_storage(p) = max(deadcrootn_storage(p), epsi)
+ deadcrootn0_xfer(p) = max(deadcrootn_xfer(p), epsi)
+ retransn0(p) = max(retransn(p), epsi)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! Use one index of the grain reproductive pools to operate on
+ repron0(p) = max(reproductiven(p,irepr), epsi)
+ repron0_storage(p) = max(reproductiven_storage(p,irepr), epsi)
+ repron0_xfer(p) = max(reproductiven_xfer(p,irepr), epsi)
+ end if
+ end do
+ end if
+ end if
+
+ call t_stopf('CN veg matrix-set old value')
+
+ call t_startf('CN veg matrix-matrix multi.')
+
+ ! Start matrix operation
+ ! Calculate B*I
+
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc_input%V(p,i) = matrix_alloc(p,i) * matrix_Cinput(p) * dt
+ end do
+ end do
+
+ ! Set up sparse matrix Aph_c from non-diagonal entires Aphconed, diagonal entries are all set to -1.
+ ! Note that AKphvegc here only represent A matrix instead of A * K
+
+ if(ncphtrans .gt. ncphouttrans)then
+ AI_phc = receiver_phc(1:ncphtrans-ncphouttrans)
+ AJ_phc = doner_phc (1:ncphtrans-ncphouttrans)
+ call AKphvegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aphconed,&
+ AI_phc,AJ_phc,ncphtrans-ncphouttrans,init_ready_aphc,list_aphc,RI_phc,CI_phc)
+ else
+ call AKphvegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kph_c from diagonal entries matrix_phturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_phturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Aph_c*Kph_c using SPMM_AK.
+ call AKphvegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+
+
+ ! Set up sparse matrix Agm_c from non-diagonal entires Agmconed, diagonal entries are all set to -1.
+ ! Note that AKgmvegc here only represent A matrix instead of A * K
+
+ if(ncgmtrans .gt. ncgmouttrans)then
+ AI_gmc = receiver_gmc(1:ncgmtrans-ncgmouttrans)
+ AJ_gmc = doner_gmc (1:ncgmtrans-ncgmouttrans)
+ call AKgmvegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Agmconed,&
+ AI_gmc,AJ_gmc,ncgmtrans-ncgmouttrans,init_ready_agmc,list_agmc,RI_gmc,CI_gmc)
+ else
+ call AKgmvegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kgm_c from diagonal entries matrix_gmturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_gmturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Agm_c*Kgm_c using SPMM_AK.
+ call AKgmvegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+
+
+ ! Set up sparse matrix Afi_c from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKfivegc here only represent A matrix instead of A * K
+
+ if(ncfitrans .gt. ncfiouttrans)then
+ AI_fic = receiver_fic(1:ncfitrans-ncfiouttrans)
+ AJ_fic = doner_fic (1:ncfitrans-ncfiouttrans)
+ call AKfivegc%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aficoned,&
+ AI_fic,AJ_fic,ncfitrans-ncfiouttrans,init_ready_afic,list_afic,RI_fic,CI_fic)
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ RI_fic14 => c14_cnveg_carbonflux_inst%RI_fic , & ! Row indices of non-diagonal entires in Afi for C cycle
+ CI_fic14 => c14_cnveg_carbonflux_inst%CI_fic , & ! Column indices of non-diagonal entries in Afi for C cycle
+ list_afic14 => c14_cnveg_carbonflux_inst%list_afic & ! Indices of non-diagnoal entries in full sparse matrix Afi for C cycle
+ )
+ AI_fic14 = receiver_fic(1:ncfitrans-ncfiouttrans)
+ AJ_fic14 = doner_fic (1:ncfitrans-ncfiouttrans)
+ call AKfivegc14%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Afic14oned,&
+ AI_fic14,AJ_fic14,ncfitrans-ncfiouttrans,init_ready_afic14,list_afic14,RI_fic14,CI_fic14)
+ end associate
+ end if
+ else
+ call AKfivegc%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc & ! Afi*Kfi for C14 cycle in sparse matrix format
+ )
+ call AKfivegc14%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end associate
+ end if
+ end if
+
+ ! Set up diagonal matrix Kfi_c from diagonal entries matrix_fiturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_fiturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Afi_c*Kfi_c using SPMM_AK.
+ call AKfivegc%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ ! Set up diagonal matrix Kfi_c from diagonal entries matrix_fiturnover
+ call Kvegc%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_c14fiturnover(bounds%begp:bounds%endp,1:nvegcpool))
+
+ ! Calculate Afi_c*Kfi_c using SPMM_AK.
+ call AKfivegc14%SPMM_AK(num_soilp,filter_soilp,Kvegc)
+ end associate
+ end if
+
+ ! Caclulate AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c
+ ! When no fire, Afi_c*Kfi_c = 0, AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c
+ ! When fire is on, AKallvegc = Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c
+
+ if(num_actfirep .eq. 0 .and. nthreads < 2)then
+ call AKallvegc%SPMP_AB(num_soilp,filter_soilp,AKphvegc,AKgmvegc,list_ready_phgmc,list_A=list_phc_phgm,list_B=list_gmc_phgm,&
+ NE_AB=NE_AKallvegc,RI_AB=RI_AKallvegc,CI_AB=CI_AKallvegc)
+ else
+ call AKallvegc%SPMP_ABC(num_soilp,filter_soilp,AKphvegc,AKgmvegc,AKfivegc,list_ready_phgmfic,list_A=list_phc_phgmfi,&
+ list_B=list_gmc_phgmfi,list_C=list_fic_phgmfi,NE_ABC=NE_AKallvegc,RI_ABC=RI_AKallvegc,CI_ABC=CI_AKallvegc,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirep,filter_actunit_C=filter_actfirep)
+ end if
+
+ if(use_c14)then
+ associate( &
+ AKfivegc14 => c14_cnveg_carbonflux_inst%AKfivegc , & ! Afi*Kfi for C14 cycle in sparse matrix format
+ AKallvegc14 => c14_cnveg_carbonflux_inst%AKallvegc , & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C14 cycle in sparse matrix format
+ NE_AKallvegc14 => c14_cnveg_carbonflux_inst%NE_AKallvegc , & ! Number of entries in AKallvegc
+ RI_AKallvegc14 => c14_cnveg_carbonflux_inst%RI_AKallvegc , & ! Row indices in Akallvegc
+ CI_AKallvegc14 => c14_cnveg_carbonflux_inst%CI_AKallvegc , & ! Column indices in AKallvegc
+ list_phc14_phgmfi => c14_cnveg_carbonflux_inst%list_phc_phgmfic , & ! The locations of entries in AKphvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_gmc14_phgmfi => c14_cnveg_carbonflux_inst%list_gmc_phgmfic , & ! The locations of entries in AKgmvegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ list_fic14_phgmfi => c14_cnveg_carbonflux_inst%list_fic_phgmfic & ! The locations of entries in AKfivegc mapped into (AKphvegc+AKgmvegc+AKfivegc)
+ )
+ call AKallvegc14%SPMP_ABC(num_soilp,filter_soilp,AKphvegc,AKgmvegc,AKfivegc14,list_ready_phgmfic14,list_A=list_phc14_phgmfi,&
+ list_B=list_gmc14_phgmfi,list_C=list_fic14_phgmfi,NE_ABC=NE_AKallvegc14,RI_ABC=RI_AKallvegc14,CI_ABC=CI_AKallvegc14)
+ end associate
+ end if
+
+
+ ! Xvegc_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xvegc_n + Xvegc_n
+ call Xvegc%SPMM_AX(num_soilp,filter_soilp,AKallvegc)
+
+ ! Xvegc_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xvegc_n + Xvegc_n + B*I
+ do i = 1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegc%V(p,i) = Xvegc%V(p,i) + vegmatrixc_input%V(p,i)
+ end do
+ end do
+
+
+ if ( use_c13 ) then
+ ! Calculate B*I_C13
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc13_input%V(p,i) = matrix_alloc(p,i) * matrix_C13input(p) * dt
+ end do
+ end do
+
+ ! Xveg13c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg13c_n + Xveg13c_n
+ call Xveg13c%SPMM_AX(num_soilp,filter_soilp,AKallvegc)
+
+ ! Xveg13c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg13c_n + Xveg13c_n + B*I_C13
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg13c%V(p,i) = Xveg13c%V(p,i) + vegmatrixc13_input%V(p,i)
+ end do
+ end do
+ end if
+
+
+ if ( use_c14 ) then
+ associate( &
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch, & ! Input: [real(r8) (:)] (gC/m2/s) C14 input to vegetation, updated in NutrientCompetitionFlexibleCNMod or NutrientCompetitionCLM45defaultMod
+ AKallvegc14 => c14_cnveg_carbonflux_inst%AKallvegc & ! Aph*Kph + Agm*Kgm + Afi*Kfi for C14 cycle in sparse matrix format
+ )
+ ! Calculate B*I_C14
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixc14_input%V(p,i) = matrix_alloc(p,i) * matrix_C14input(p) * dt
+ end do
+ end do
+
+ ! Xveg14c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg14c_n + Xveg14c_n
+ call Xveg14c%SPMM_AX(num_soilp,filter_soilp,AKallvegc14)
+
+ ! Xveg14c_n+1 = (Aph_c*Kph_c + Agm_c*Kgm_c + Afi_c*Kfi_c) * Xveg14c_n + Xveg14c_n + B*I_C14
+ do i=1,nvegcpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xveg14c%V(p,i) = Xveg14c%V(p,i) + vegmatrixc14_input%V(p,i)
+ end do
+ end do
+ end associate
+ end if
+
+
+
+ ! Calculate B_N*I_N
+ do i=1,nvegnpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ vegmatrixn_input%V(p,i) = matrix_nalloc(p,i) * matrix_Ninput(p) * dt
+ end do
+ end do
+
+
+ ! Set up sparse matrix Aph_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKphvegn here only represent A matrix instead of A * K
+
+ if(nnphtrans .gt. nnphouttrans)then
+ AI_phn = receiver_phn(1:nnphtrans-nnphouttrans)
+ AJ_phn = doner_phn (1:nnphtrans-nnphouttrans)
+ call AKphvegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Aphnoned,&
+ AI_phn,AJ_phn,nnphtrans-nnphouttrans,init_ready_aphn,list_aphn,RI_phn,CI_phn)
+ else
+ call AKphvegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kph_n from diagonal entries matrix_nphturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_nphturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Aph_n*Kph_n using SPMM_AK.
+ call AKphvegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Set up sparse matrix Agm_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKgmvegn here only represent A matrix instead of A * K
+
+ if(nngmtrans .gt. nngmouttrans)then
+ AI_gmn = receiver_gmn(1:nngmtrans-nngmouttrans)
+ AJ_gmn = doner_gmn (1:nngmtrans-nngmouttrans)
+ call AKgmvegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Agmnoned,&
+ AI_gmn,AJ_gmn,nngmtrans-nngmouttrans,init_ready_agmn,list_agmn,RI_gmn,CI_gmn)
+ else
+ call AKgmvegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kgm_n from diagonal entries matrix_ngmturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_ngmturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Agm_n*Kgm_n using SPMM_AK.
+ call AKgmvegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Set up sparse matrix Afi_n from non-diagonal entires Aficoned, diagonal entries are all set to -1.
+ ! Note that AKfivegn here only represent A matrix instead of A * K
+
+ if(nnfitrans .gt. nnfiouttrans)then
+ AI_fin = receiver_fin(1:nnfitrans-nnfiouttrans)
+ AJ_fin = doner_fin (1:nnfitrans-nnfiouttrans)
+ call AKfivegn%SetValueA(bounds%begp,bounds%endp,num_soilp,filter_soilp,Afinoned,&
+ AI_fin,AJ_fin,nnfitrans-nnfiouttrans,init_ready_afin,list_afin,RI_fin,CI_fin)
+ else
+ call AKfivegn%SetValueA_diag(num_soilp,filter_soilp,-1._r8)
+ end if
+
+ ! Set up diagonal matrix Kfi_n from diagonal entries matrix_nfiturnover
+ call Kvegn%SetValueDM(bounds%begp,bounds%endp,num_soilp,filter_soilp,matrix_nfiturnover(bounds%begp:bounds%endp,1:nvegnpool))
+
+ ! Calculate Afi_n*Kfi_n using SPMM_AK.
+ call AKfivegn%SPMM_AK(num_soilp,filter_soilp,Kvegn)
+
+
+ ! Caclulate AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n
+ ! When no fire, Afi_n*Kfi_n = 0, AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n
+ ! When fire is on, AKallvegn = Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n
+
+ if(num_actfirep .eq. 0 .and. nthreads < 2)then
+ call AKallvegn%SPMP_AB(num_soilp,filter_soilp,AKphvegn,AKgmvegn,list_ready_phgmn,list_A=list_phn_phgm,list_B=list_gmn_phgm,&
+ NE_AB=NE_AKallvegn,RI_AB=RI_AKallvegn,CI_AB=CI_AKallvegn)
+ else
+ call AKallvegn%SPMP_ABC(num_soilp,filter_soilp,AKphvegn,AKgmvegn,AKfivegn,list_ready_phgmfin,list_A=list_phn_phgmfi,&
+ list_B=list_gmn_phgmfi,list_C=list_fin_phgmfi,NE_ABC=NE_AKallvegn,RI_ABC=RI_AKallvegn,CI_ABC=CI_AKallvegn,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirep,filter_actunit_C=filter_actfirep)
+ end if
+
+ ! Xvegn_n+1 = (Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n) * Xvegc_n + Xvegc_n
+ call Xvegn%SPMM_AX(num_soilp,filter_soilp,AKallvegn)
+
+ ! Xvegn_n+1 = (Aph_n*Kph_n + Agm_n*Kgm_n + Afi_n*Kfi_n) * Xvegc_n + Xvegc_n + B_N*I_N
+ do i=1,nvegnpool
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ Xvegn%V(p,i) = Xvegn%V(p,i) + vegmatrixn_input%V(p,i)
+ end do
+ end do
+
+ call t_stopf('CN veg matrix-matrix multi.')
+
+
+ ! Accumulate transfers during the whole calendar year
+
+ call t_startf('CN veg matrix-accum. trans.')
+ if(spinup_matrixcn .or. hist_wrt_matrixcn_diag)then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_calloc_leaf_acc(p) = matrix_calloc_leaf_acc(p) + vegmatrixc_input%V(p,ileaf)
+ matrix_calloc_leafst_acc(p) = matrix_calloc_leafst_acc(p) + vegmatrixc_input%V(p,ileaf_st)
+ matrix_calloc_froot_acc(p) = matrix_calloc_froot_acc(p) + vegmatrixc_input%V(p,ifroot)
+ matrix_calloc_frootst_acc(p) = matrix_calloc_frootst_acc(p) + vegmatrixc_input%V(p,ifroot_st)
+ matrix_calloc_livestem_acc(p) = matrix_calloc_livestem_acc(p) + vegmatrixc_input%V(p,ilivestem)
+ matrix_calloc_livestemst_acc(p) = matrix_calloc_livestemst_acc(p) + vegmatrixc_input%V(p,ilivestem_st)
+ matrix_calloc_deadstem_acc(p) = matrix_calloc_deadstem_acc(p) + vegmatrixc_input%V(p,ideadstem)
+ matrix_calloc_deadstemst_acc(p) = matrix_calloc_deadstemst_acc(p) + vegmatrixc_input%V(p,ideadstem_st)
+ matrix_calloc_livecroot_acc(p) = matrix_calloc_livecroot_acc(p) + vegmatrixc_input%V(p,ilivecroot)
+ matrix_calloc_livecrootst_acc(p) = matrix_calloc_livecrootst_acc(p) + vegmatrixc_input%V(p,ilivecroot_st)
+ matrix_calloc_deadcroot_acc(p) = matrix_calloc_deadcroot_acc(p) + vegmatrixc_input%V(p,ideadcroot)
+ matrix_calloc_deadcrootst_acc(p) = matrix_calloc_deadcrootst_acc(p) + vegmatrixc_input%V(p,ideadcroot_st)
+ if(use_c13)then
+ cs13_veg%matrix_calloc_leaf_acc_patch(p) = cs13_veg%matrix_calloc_leaf_acc_patch(p) + vegmatrixc13_input%V(p,ileaf)
+ cs13_veg%matrix_calloc_leafst_acc_patch(p) = cs13_veg%matrix_calloc_leafst_acc_patch(p) + vegmatrixc13_input%V(p,ileaf_st)
+ cs13_veg%matrix_calloc_froot_acc_patch(p) = cs13_veg%matrix_calloc_froot_acc_patch(p) + vegmatrixc13_input%V(p,ifroot)
+ cs13_veg%matrix_calloc_frootst_acc_patch(p) = cs13_veg%matrix_calloc_frootst_acc_patch(p) + vegmatrixc13_input%V(p,ifroot_st)
+ cs13_veg%matrix_calloc_livestem_acc_patch(p) = cs13_veg%matrix_calloc_livestem_acc_patch(p) + vegmatrixc13_input%V(p,ilivestem)
+ cs13_veg%matrix_calloc_livestemst_acc_patch(p) = cs13_veg%matrix_calloc_livestemst_acc_patch(p) + vegmatrixc13_input%V(p,ilivestem_st)
+ cs13_veg%matrix_calloc_deadstem_acc_patch(p) = cs13_veg%matrix_calloc_deadstem_acc_patch(p) + vegmatrixc13_input%V(p,ideadstem)
+ cs13_veg%matrix_calloc_deadstemst_acc_patch(p) = cs13_veg%matrix_calloc_deadstemst_acc_patch(p) + vegmatrixc13_input%V(p,ideadstem_st)
+ cs13_veg%matrix_calloc_livecroot_acc_patch(p) = cs13_veg%matrix_calloc_livecroot_acc_patch(p) + vegmatrixc13_input%V(p,ilivecroot)
+ cs13_veg%matrix_calloc_livecrootst_acc_patch(p) = cs13_veg%matrix_calloc_livecrootst_acc_patch(p) + vegmatrixc13_input%V(p,ilivecroot_st)
+ cs13_veg%matrix_calloc_deadcroot_acc_patch(p) = cs13_veg%matrix_calloc_deadcroot_acc_patch(p) + vegmatrixc13_input%V(p,ideadcroot)
+ cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) = cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) + vegmatrixc13_input%V(p,ideadcroot_st)
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_calloc_leaf_acc_patch(p) = cs14_veg%matrix_calloc_leaf_acc_patch(p) + vegmatrixc14_input%V(p,ileaf)
+ cs14_veg%matrix_calloc_leafst_acc_patch(p) = cs14_veg%matrix_calloc_leafst_acc_patch(p) + vegmatrixc14_input%V(p,ileaf_st)
+ cs14_veg%matrix_calloc_froot_acc_patch(p) = cs14_veg%matrix_calloc_froot_acc_patch(p) + vegmatrixc14_input%V(p,ifroot)
+ cs14_veg%matrix_calloc_frootst_acc_patch(p) = cs14_veg%matrix_calloc_frootst_acc_patch(p) + vegmatrixc14_input%V(p,ifroot_st)
+ cs14_veg%matrix_calloc_livestem_acc_patch(p) = cs14_veg%matrix_calloc_livestem_acc_patch(p) + vegmatrixc14_input%V(p,ilivestem)
+ cs14_veg%matrix_calloc_livestemst_acc_patch(p) = cs14_veg%matrix_calloc_livestemst_acc_patch(p) + vegmatrixc14_input%V(p,ilivestem_st)
+ cs14_veg%matrix_calloc_deadstem_acc_patch(p) = cs14_veg%matrix_calloc_deadstem_acc_patch(p) + vegmatrixc14_input%V(p,ideadstem)
+ cs14_veg%matrix_calloc_deadstemst_acc_patch(p) = cs14_veg%matrix_calloc_deadstemst_acc_patch(p) + vegmatrixc14_input%V(p,ideadstem_st)
+ cs14_veg%matrix_calloc_livecroot_acc_patch(p) = cs14_veg%matrix_calloc_livecroot_acc_patch(p) + vegmatrixc14_input%V(p,ilivecroot)
+ cs14_veg%matrix_calloc_livecrootst_acc_patch(p) = cs14_veg%matrix_calloc_livecrootst_acc_patch(p) + vegmatrixc14_input%V(p,ilivecroot_st)
+ cs14_veg%matrix_calloc_deadcroot_acc_patch(p) = cs14_veg%matrix_calloc_deadcroot_acc_patch(p) + vegmatrixc14_input%V(p,ideadcroot)
+ cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) = cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) + vegmatrixc14_input%V(p,ideadcroot_st)
+ end if
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_grain_acc(p) = matrix_calloc_grain_acc(p) + vegmatrixc_input%V(p,igrain)
+ matrix_calloc_grainst_acc(p) = matrix_calloc_grainst_acc(p) + vegmatrixc_input%V(p,igrain_st)
+ if(use_c13)then
+ cs13_veg%matrix_calloc_grain_acc_patch(p) = cs13_veg%matrix_calloc_grain_acc_patch(p) + vegmatrixc13_input%V(p,igrain)
+ cs13_veg%matrix_calloc_grainst_acc_patch(p) = cs13_veg%matrix_calloc_grainst_acc_patch(p) + vegmatrixc13_input%V(p,igrain_st)
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_calloc_grain_acc_patch(p) = cs14_veg%matrix_calloc_grain_acc_patch(p) + vegmatrixc14_input%V(p,igrain)
+ cs14_veg%matrix_calloc_grainst_acc_patch(p) = cs14_veg%matrix_calloc_grainst_acc_patch(p) + vegmatrixc14_input%V(p,igrain_st)
+ end if
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_ctransfer_leafst_to_leafxf_acc(p) = matrix_ctransfer_leafst_to_leafxf_acc(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * leafc_storage(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ matrix_ctransfer_leafxf_to_leaf_acc(p) = matrix_ctransfer_leafxf_to_leaf_acc(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * leafc_xfer(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ matrix_ctransfer_frootst_to_frootxf_acc(p) = matrix_ctransfer_frootst_to_frootxf_acc(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * frootc_storage(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ matrix_ctransfer_frootxf_to_froot_acc(p) = matrix_ctransfer_frootxf_to_froot_acc(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * frootc_xfer(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ matrix_ctransfer_livestemst_to_livestemxf_acc(p) = matrix_ctransfer_livestemst_to_livestemxf_acc(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * livestemc_storage(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ matrix_ctransfer_livestemxf_to_livestem_acc(p) = matrix_ctransfer_livestemxf_to_livestem_acc(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * livestemc_xfer(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) = matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * deadstemc_storage(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ matrix_ctransfer_deadstemxf_to_deadstem_acc(p) = matrix_ctransfer_deadstemxf_to_deadstem_acc(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * deadstemc_xfer(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) = matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * livecrootc_storage(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ matrix_ctransfer_livecrootxf_to_livecroot_acc(p) = matrix_ctransfer_livecrootxf_to_livecroot_acc(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * livecrootc_xfer(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) = matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * deadcrootc_storage(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) = matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * deadcrootc_xfer(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ matrix_ctransfer_livestem_to_deadstem_acc(p) = matrix_ctransfer_livestem_to_deadstem_acc(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * livestemc(p)
+ matrix_ctransfer_livecroot_to_deadcroot_acc(p) = matrix_ctransfer_livecroot_to_deadcroot_acc(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * livecrootc(p)
+ matrix_cturnover_leaf_acc(p) = matrix_cturnover_leaf_acc(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_fiturnover(p,ileaf)) &
+ * leafc(p)
+ matrix_cturnover_leafst_acc(p) = matrix_cturnover_leafst_acc(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_fiturnover(p,ileaf_st)) &
+ * leafc_storage(p)
+ matrix_cturnover_leafxf_acc(p) = matrix_cturnover_leafxf_acc(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_fiturnover(p,ileaf_xf)) &
+ * leafc_xfer(p)
+ matrix_cturnover_froot_acc(p) = matrix_cturnover_froot_acc(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_fiturnover(p,ifroot)) &
+ * frootc(p)
+ matrix_cturnover_frootst_acc(p) = matrix_cturnover_frootst_acc(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_fiturnover(p,ifroot_st)) &
+ * frootc_storage(p)
+ matrix_cturnover_frootxf_acc(p) = matrix_cturnover_frootxf_acc(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_fiturnover(p,ifroot_xf)) &
+ * frootc_xfer(p)
+ matrix_cturnover_livestem_acc(p) = matrix_cturnover_livestem_acc(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_fiturnover(p,ilivestem)) &
+ * livestemc(p)
+ matrix_cturnover_livestemst_acc(p) = matrix_cturnover_livestemst_acc(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_fiturnover(p,ilivestem_st)) &
+ * livestemc_storage(p)
+ matrix_cturnover_livestemxf_acc(p) = matrix_cturnover_livestemxf_acc(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_fiturnover(p,ilivestem_xf)) &
+ * livestemc_xfer(p)
+ matrix_cturnover_deadstem_acc(p) = matrix_cturnover_deadstem_acc(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_fiturnover(p,ideadstem)) &
+ * deadstemc(p)
+ matrix_cturnover_deadstemst_acc(p) = matrix_cturnover_deadstemst_acc(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_fiturnover(p,ideadstem_st)) &
+ * deadstemc_storage(p)
+ matrix_cturnover_deadstemxf_acc(p) = matrix_cturnover_deadstemxf_acc(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_fiturnover(p,ideadstem_xf)) &
+ * deadstemc_xfer(p)
+ matrix_cturnover_livecroot_acc(p) = matrix_cturnover_livecroot_acc(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_fiturnover(p,ilivecroot)) &
+ * livecrootc(p)
+ matrix_cturnover_livecrootst_acc(p) = matrix_cturnover_livecrootst_acc(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_fiturnover(p,ilivecroot_st)) &
+ * livecrootc_storage(p)
+ matrix_cturnover_livecrootxf_acc(p) = matrix_cturnover_livecrootxf_acc(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_fiturnover(p,ilivecroot_xf)) &
+ * livecrootc_xfer(p)
+ matrix_cturnover_deadcroot_acc(p) = matrix_cturnover_deadcroot_acc(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_fiturnover(p,ideadcroot)) &
+ * deadcrootc(p)
+ matrix_cturnover_deadcrootst_acc(p) = matrix_cturnover_deadcrootst_acc(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_fiturnover(p,ideadcroot_st)) &
+ * deadcrootc_storage(p)
+ matrix_cturnover_deadcrootxf_acc(p) = matrix_cturnover_deadcrootxf_acc(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_fiturnover(p,ideadcroot_xf)) &
+ * deadcrootc_xfer(p)
+ if(use_c13)then
+ cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * cs13_veg%leafc_storage_patch(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * cs13_veg%leafc_xfer_patch(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * cs13_veg%frootc_storage_patch(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * cs13_veg%frootc_xfer_patch(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * cs13_veg%livestemc_storage_patch(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * cs13_veg%livestemc_xfer_patch(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * cs13_veg%deadstemc_storage_patch(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * cs13_veg%deadstemc_xfer_patch(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * cs13_veg%livecrootc_storage_patch(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * cs13_veg%livecrootc_xfer_patch(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * cs13_veg%deadcrootc_storage_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * cs13_veg%deadcrootc_xfer_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * cs13_veg%livestemc_patch(p)
+ cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * cs13_veg%livecrootc_patch(p)
+ cs13_veg%matrix_cturnover_leaf_acc_patch(p) = cs13_veg%matrix_cturnover_leaf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_fiturnover(p,ileaf)) &
+ * cs13_veg%leafc_patch(p)
+ cs13_veg%matrix_cturnover_leafst_acc_patch(p) = cs13_veg%matrix_cturnover_leafst_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_fiturnover(p,ileaf_st)) &
+ * cs13_veg%leafc_storage_patch(p)
+ cs13_veg%matrix_cturnover_leafxf_acc_patch(p) = cs13_veg%matrix_cturnover_leafxf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_fiturnover(p,ileaf_xf)) &
+ * cs13_veg%leafc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_froot_acc_patch(p) = cs13_veg%matrix_cturnover_froot_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_fiturnover(p,ifroot)) &
+ * cs13_veg%frootc_patch(p)
+ cs13_veg%matrix_cturnover_frootst_acc_patch(p) = cs13_veg%matrix_cturnover_frootst_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_fiturnover(p,ifroot_st)) &
+ * cs13_veg%frootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_frootxf_acc_patch(p) = cs13_veg%matrix_cturnover_frootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_fiturnover(p,ifroot_xf)) &
+ * cs13_veg%frootc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_livestem_acc_patch(p) = cs13_veg%matrix_cturnover_livestem_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_fiturnover(p,ilivestem)) &
+ * cs13_veg%livestemc_patch(p)
+ cs13_veg%matrix_cturnover_livestemst_acc_patch(p) = cs13_veg%matrix_cturnover_livestemst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_fiturnover(p,ilivestem_st)) &
+ * cs13_veg%livestemc_storage_patch(p)
+ cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) = cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_fiturnover(p,ilivestem_xf)) &
+ * cs13_veg%livestemc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_deadstem_acc_patch(p) = cs13_veg%matrix_cturnover_deadstem_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_fiturnover(p,ideadstem)) &
+ * cs13_veg%deadstemc_patch(p)
+ cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) = cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_fiturnover(p,ideadstem_st)) &
+ * cs13_veg%deadstemc_storage_patch(p)
+ cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) = cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_fiturnover(p,ideadstem_xf)) &
+ * cs13_veg%deadstemc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_livecroot_acc_patch(p) = cs13_veg%matrix_cturnover_livecroot_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_fiturnover(p,ilivecroot)) &
+ * cs13_veg%livecrootc_patch(p)
+ cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) = cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_fiturnover(p,ilivecroot_st)) &
+ * cs13_veg%livecrootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) = cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_fiturnover(p,ilivecroot_xf)) &
+ * cs13_veg%livecrootc_xfer_patch(p)
+ cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) = cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_fiturnover(p,ideadcroot)) &
+ * cs13_veg%deadcrootc_patch(p)
+ cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) = cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_fiturnover(p,ideadcroot_st)) &
+ * cs13_veg%deadcrootc_storage_patch(p)
+ cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_fiturnover(p,ideadcroot_xf)) &
+ * cs13_veg%deadcrootc_xfer_patch(p)
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafst_to_ileafxf_phc) &
+ * dt * cs14_veg%leafc_storage_patch(p) !matrix_phturnover(p,ileaf_st)*leafc_storage(p)
+ cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) &
+ + matrix_phtransfer(p,ileafxf_to_ileaf_phc) &
+ * dt * cs14_veg%leafc_xfer_patch(p)!matrix_phturnover(p,ileaf_xf)*leafc_xfer(p)
+ cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootst_to_ifrootxf_phc) &
+ * dt * cs14_veg%frootc_storage_patch(p)!matrix_phturnover(p,ifroot_st)*frootc_storage(p)
+ cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) &
+ + matrix_phtransfer(p,ifrootxf_to_ifroot_phc) &
+ * dt * cs14_veg%frootc_xfer_patch(p)!matrix_phturnover(p,ifroot_xf)*frootc_xfer(p)
+ cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemst_to_ilivestemxf_phc) &
+ * dt * cs14_veg%livestemc_storage_patch(p)!matrix_phturnover(p,ilivestem_st)*livestemc_storage(p)
+ cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) &
+ + matrix_phtransfer(p,ilivestemxf_to_ilivestem_phc) &
+ * dt * cs14_veg%livestemc_xfer_patch(p)!matrix_phturnover(p,ilivestem_xf)*livestemc_xfer(p)
+ cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemst_to_ideadstemxf_phc) &
+ * dt * cs14_veg%deadstemc_storage_patch(p)!matrix_phturnover(p,ideadstem_st)*deadstemc_storage(p)
+ cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) &
+ + matrix_phtransfer(p,ideadstemxf_to_ideadstem_phc) &
+ * dt * cs14_veg%deadstemc_xfer_patch(p)!matrix_phturnover(p,ideadstem_xf)*deadstemc_xfer(p)
+ cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootst_to_ilivecrootxf_phc) &
+ * dt * cs14_veg%livecrootc_storage_patch(p)!matrix_phturnover(p,ilivecroot_st)*livecrootc_storage(p)
+ cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) &
+ + matrix_phtransfer(p,ilivecrootxf_to_ilivecroot_phc) &
+ * dt * cs14_veg%livecrootc_xfer_patch(p)!matrix_phturnover(p,ilivecroot_xf)*livecrootc_xfer(p)
+ cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootst_to_ideadcrootxf_phc) &
+ * dt * cs14_veg%deadcrootc_storage_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_storage(p)
+ cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) &
+ + matrix_phtransfer(p,ideadcrootxf_to_ideadcroot_phc) &
+ * dt * cs14_veg%deadcrootc_xfer_patch(p)!matrix_phturnover(p,ideadcroot_st)*deadcrootc_xfer(p)
+ cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivestem_to_ideadstem_phc)&!matrix_phturnover(p,ilivestem) &
+ + matrix_c14fitransfer(p,ilivestem_to_ideadstem_fic))&!matrix_fiturnover(p,ilivestem))&
+ * dt * cs14_veg%livestemc_patch(p)
+ cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) &
+ +(matrix_phtransfer(p,ilivecroot_to_ideadcroot_phc)&!*matrix_phturnover(p,ilivecroot) &
+ + matrix_c14fitransfer(p,ilivecroot_to_ideadcroot_fic))&!*matrix_fiturnover(p,ilivecroot))&
+ * dt * cs14_veg%livecrootc_patch(p)
+ cs14_veg%matrix_cturnover_leaf_acc_patch(p) = cs14_veg%matrix_cturnover_leaf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf)+matrix_gmturnover(p,ileaf)+matrix_c14fiturnover(p,ileaf)) &
+ * cs14_veg%leafc_patch(p)
+ cs14_veg%matrix_cturnover_leafst_acc_patch(p) = cs14_veg%matrix_cturnover_leafst_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_st)+matrix_gmturnover(p,ileaf_st)+matrix_c14fiturnover(p,ileaf_st)) &
+ * cs14_veg%leafc_storage_patch(p)
+ cs14_veg%matrix_cturnover_leafxf_acc_patch(p) = cs14_veg%matrix_cturnover_leafxf_acc_patch(p) &
+ + (matrix_phturnover(p,ileaf_xf)+matrix_gmturnover(p,ileaf_xf)+matrix_c14fiturnover(p,ileaf_xf)) &
+ * cs14_veg%leafc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_froot_acc_patch(p) = cs14_veg%matrix_cturnover_froot_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot)+matrix_gmturnover(p,ifroot)+matrix_c14fiturnover(p,ifroot)) &
+ * cs14_veg%frootc_patch(p)
+ cs14_veg%matrix_cturnover_frootst_acc_patch(p) = cs14_veg%matrix_cturnover_frootst_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_st)+matrix_gmturnover(p,ifroot_st)+matrix_c14fiturnover(p,ifroot_st)) &
+ * cs14_veg%frootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_frootxf_acc_patch(p) = cs14_veg%matrix_cturnover_frootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ifroot_xf)+matrix_gmturnover(p,ifroot_xf)+matrix_c14fiturnover(p,ifroot_xf)) &
+ * cs14_veg%frootc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_livestem_acc_patch(p) = cs14_veg%matrix_cturnover_livestem_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem)+matrix_gmturnover(p,ilivestem)+matrix_c14fiturnover(p,ilivestem)) &
+ * cs14_veg%livestemc_patch(p)
+ cs14_veg%matrix_cturnover_livestemst_acc_patch(p) = cs14_veg%matrix_cturnover_livestemst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_st)+matrix_gmturnover(p,ilivestem_st)+matrix_c14fiturnover(p,ilivestem_st)) &
+ * cs14_veg%livestemc_storage_patch(p)
+ cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) = cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivestem_xf)+matrix_gmturnover(p,ilivestem_xf)+matrix_c14fiturnover(p,ilivestem_xf)) &
+ * cs14_veg%livestemc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_deadstem_acc_patch(p) = cs14_veg%matrix_cturnover_deadstem_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem)+matrix_gmturnover(p,ideadstem)+matrix_c14fiturnover(p,ideadstem)) &
+ * cs14_veg%deadstemc_patch(p)
+ cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) = cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_st)+matrix_gmturnover(p,ideadstem_st)+matrix_c14fiturnover(p,ideadstem_st)) &
+ * cs14_veg%deadstemc_storage_patch(p)
+ cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) = cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadstem_xf)+matrix_gmturnover(p,ideadstem_xf)+matrix_c14fiturnover(p,ideadstem_xf)) &
+ * cs14_veg%deadstemc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_livecroot_acc_patch(p) = cs14_veg%matrix_cturnover_livecroot_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot)+matrix_gmturnover(p,ilivecroot)+matrix_c14fiturnover(p,ilivecroot)) &
+ * cs14_veg%livecrootc_patch(p)
+ cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) = cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_st)+matrix_gmturnover(p,ilivecroot_st)+matrix_c14fiturnover(p,ilivecroot_st)) &
+ * cs14_veg%livecrootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) = cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ilivecroot_xf)+matrix_gmturnover(p,ilivecroot_xf)+matrix_c14fiturnover(p,ilivecroot_xf)) &
+ * cs14_veg%livecrootc_xfer_patch(p)
+ cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) = cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot)+matrix_gmturnover(p,ideadcroot)+matrix_c14fiturnover(p,ideadcroot)) &
+ * cs14_veg%deadcrootc_patch(p)
+ cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) = cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_st)+matrix_gmturnover(p,ideadcroot_st)+matrix_c14fiturnover(p,ideadcroot_st)) &
+ * cs14_veg%deadcrootc_storage_patch(p)
+ cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) &
+ + (matrix_phturnover(p,ideadcroot_xf)+matrix_gmturnover(p,ideadcroot_xf)+matrix_c14fiturnover(p,ideadcroot_xf)) &
+ * cs14_veg%deadcrootc_xfer_patch(p)
+ end associate
+ end if
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_cturnover_grain_acc(p) = matrix_cturnover_grain_acc(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_fiturnover(p,igrain)) &
+ * reproductivec(p,irepr)
+ matrix_cturnover_grainst_acc(p) = matrix_cturnover_grainst_acc(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_fiturnover(p,igrain_st)) &
+ * reproductivec_storage(p,irepr)
+ matrix_cturnover_grainxf_acc(p) = matrix_cturnover_grainxf_acc(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_fiturnover(p,igrain_xf)) &
+ * reproductivec_xfer(p,irepr)
+ if(use_c13)then
+ cs13_veg%matrix_cturnover_grain_acc_patch(p) = cs13_veg%matrix_cturnover_grain_acc_patch(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_fiturnover(p,igrain)) &
+ * cs13_veg%reproductivec_patch(p,irepr)
+ cs13_veg%matrix_cturnover_grainst_acc_patch(p) = cs13_veg%matrix_cturnover_grainst_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_fiturnover(p,igrain_st)) &
+ * cs13_veg%reproductivec_storage_patch(p,irepr)
+ cs13_veg%matrix_cturnover_grainxf_acc_patch(p) = cs13_veg%matrix_cturnover_grainxf_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_fiturnover(p,igrain_xf)) &
+ * cs13_veg%reproductivec_xfer_patch(p,irepr)
+ end if
+ if(use_c14)then
+ associate( &
+ matrix_c14fitransfer => c14_cnveg_carbonflux_inst%matrix_fitransfer_patch , & ! Input: [real(r8) (:,:)] (gC/m2/s) C transfer rate from fire processes, updated in (CNFireBaseMod or CNFireLi2014Mod) and CNC14decayMod
+ matrix_c14fiturnover => c14_cnveg_carbonflux_inst%matrix_fiturnover_patch & ! Output: [real(r8) (:,:)] (gC/m2/step) C turnover rate from fire processe, updated in CNVegMatrixMods
+ )
+ cs14_veg%matrix_cturnover_grain_acc_patch(p) = cs14_veg%matrix_cturnover_grain_acc_patch(p) &
+ + (matrix_phturnover(p,igrain)+matrix_gmturnover(p,igrain)+matrix_c14fiturnover(p,igrain)) &
+ * cs14_veg%reproductivec_patch(p,irepr)
+ cs14_veg%matrix_cturnover_grainst_acc_patch(p) = cs14_veg%matrix_cturnover_grainst_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_st)+matrix_gmturnover(p,igrain_st)+matrix_c14fiturnover(p,igrain_st)) &
+ * cs14_veg%reproductivec_storage_patch(p,irepr)
+ cs14_veg%matrix_cturnover_grainxf_acc_patch(p) = cs14_veg%matrix_cturnover_grainxf_acc_patch(p) &
+ + (matrix_phturnover(p,igrain_xf)+matrix_gmturnover(p,igrain_xf)+matrix_c14fiturnover(p,igrain_xf)) &
+ * cs14_veg%reproductivec_xfer_patch(p,irepr)
+ end associate
+ end if
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_nalloc_leaf_acc(p) = matrix_nalloc_leaf_acc(p) + vegmatrixn_input%V(p,ileaf)
+ matrix_nalloc_leafst_acc(p) = matrix_nalloc_leafst_acc(p) + vegmatrixn_input%V(p,ileaf_st)
+ matrix_nalloc_froot_acc(p) = matrix_nalloc_froot_acc(p) + vegmatrixn_input%V(p,ifroot)
+ matrix_nalloc_frootst_acc(p) = matrix_nalloc_frootst_acc(p) + vegmatrixn_input%V(p,ifroot_st)
+ matrix_nalloc_livestem_acc(p) = matrix_nalloc_livestem_acc(p) + vegmatrixn_input%V(p,ilivestem)
+ matrix_nalloc_livestemst_acc(p) = matrix_nalloc_livestemst_acc(p) + vegmatrixn_input%V(p,ilivestem_st)
+ matrix_nalloc_deadstem_acc(p) = matrix_nalloc_deadstem_acc(p) + vegmatrixn_input%V(p,ideadstem)
+ matrix_nalloc_deadstemst_acc(p) = matrix_nalloc_deadstemst_acc(p) + vegmatrixn_input%V(p,ideadstem_st)
+ matrix_nalloc_livecroot_acc(p) = matrix_nalloc_livecroot_acc(p) + vegmatrixn_input%V(p,ilivecroot)
+ matrix_nalloc_livecrootst_acc(p) = matrix_nalloc_livecrootst_acc(p) + vegmatrixn_input%V(p,ilivecroot_st)
+ matrix_nalloc_deadcroot_acc(p) = matrix_nalloc_deadcroot_acc(p) + vegmatrixn_input%V(p,ideadcroot)
+ matrix_nalloc_deadcrootst_acc(p) = matrix_nalloc_deadcrootst_acc(p) + vegmatrixn_input%V(p,ideadcroot_st)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_grain_acc(p) = matrix_nalloc_grain_acc(p) + vegmatrixn_input%V(p,igrain)
+ matrix_nalloc_grainst_acc(p) = matrix_nalloc_grainst_acc(p) + vegmatrixn_input%V(p,igrain_st)
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_ntransfer_leafst_to_leafxf_acc(p) = matrix_ntransfer_leafst_to_leafxf_acc(p) &
+ + matrix_nphtransfer(p,ileafst_to_ileafxf_phn) &
+ * dt * leafn_storage(p)!matrix_nphturnover(p,ileaf_st)*leafn_storage(p)
+ matrix_ntransfer_leafxf_to_leaf_acc(p) = matrix_ntransfer_leafxf_to_leaf_acc(p) &
+ + matrix_nphtransfer(p,ileafxf_to_ileaf_phn) &
+ * dt * leafn_xfer(p)!matrix_nphturnover(p,ileaf_xf)*leafn_xfer(p)
+ matrix_ntransfer_frootst_to_frootxf_acc(p) = matrix_ntransfer_frootst_to_frootxf_acc(p) &
+ + matrix_nphtransfer(p,ifrootst_to_ifrootxf_phn) &
+ * dt * frootn_storage(p)!matrix_nphturnover(p,ifroot_st)*frootn_storage(p)
+ matrix_ntransfer_frootxf_to_froot_acc(p) = matrix_ntransfer_frootxf_to_froot_acc(p) &
+ + matrix_nphtransfer(p,ifrootxf_to_ifroot_phn) &
+ * dt * frootn_xfer(p)!matrix_nphturnover(p,ifroot_xf)*frootn_xfer(p)
+ matrix_ntransfer_livestemst_to_livestemxf_acc(p) = matrix_ntransfer_livestemst_to_livestemxf_acc(p) &
+ + matrix_nphtransfer(p,ilivestemst_to_ilivestemxf_phn) &
+ * dt * livestemn_storage(p)!matrix_nphturnover(p,ilivestem_st)*livestemn_storage(p)
+ matrix_ntransfer_livestemxf_to_livestem_acc(p) = matrix_ntransfer_livestemxf_to_livestem_acc(p) &
+ + matrix_nphtransfer(p,ilivestemxf_to_ilivestem_phn) &
+ * dt * livestemn_xfer(p)!matrix_nphturnover(p,ilivestem_xf)*livestemn_xfer(p)
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) = matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) &
+ + matrix_nphtransfer(p,ideadstemst_to_ideadstemxf_phn) &
+ * dt * deadstemn_storage(p)!matrix_nphturnover(p,ideadstem_st)*deadstemn_storage(p)
+ matrix_ntransfer_deadstemxf_to_deadstem_acc(p) = matrix_ntransfer_deadstemxf_to_deadstem_acc(p) &
+ + matrix_nphtransfer(p,ideadstemxf_to_ideadstem_phn) &
+ * dt * deadstemn_xfer(p)!matrix_nphturnover(p,ideadstem_xf)*deadstemn_storage(p)
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) = matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) &
+ + matrix_nphtransfer(p,ilivecrootst_to_ilivecrootxf_phn) &
+ * dt * livecrootn_storage(p)!matrix_nphturnover(p,ilivecroot_st)*livecrootn_storage(p)
+ matrix_ntransfer_livecrootxf_to_livecroot_acc(p) = matrix_ntransfer_livecrootxf_to_livecroot_acc(p) &
+ + matrix_nphtransfer(p,ilivecrootxf_to_ilivecroot_phn) &
+ * dt * livecrootn_xfer(p)!matrix_nphturnover(p,ilivecroot_xf)*livecrootn_xfer(p)
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) = matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) &
+ + matrix_nphtransfer(p,ideadcrootst_to_ideadcrootxf_phn) &
+ * dt * deadcrootn_storage(p)!matrix_nphturnover(p,ideadcroot_st)*deadcrootn_storage(p)
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) = matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) &
+ + matrix_nphtransfer(p,ideadcrootxf_to_ideadcroot_phn) &
+ * dt * deadcrootn_xfer(p)!matrix_nphturnover(p,ideadcroot_st)*deadcrootn_xfer(p)
+ matrix_ntransfer_livestem_to_deadstem_acc(p) = matrix_ntransfer_livestem_to_deadstem_acc(p) &
+ +(matrix_nphtransfer(p,ilivestem_to_ideadstem_phn) &!*matrix_nphturnover(p,ilivestem) &
+ + matrix_nfitransfer(p,ilivestem_to_ideadstem_fin)) &!*matrix_nfiturnover(p,ilivestem)) &
+ * dt * livestemn(p)
+ matrix_ntransfer_livecroot_to_deadcroot_acc(p) = matrix_ntransfer_livecroot_to_deadcroot_acc(p) &
+ +(matrix_nphtransfer(p,ilivecroot_to_ideadcroot_phn) &!*matrix_nphturnover(p,ilivecroot) &
+ + matrix_nfitransfer(p,ilivecroot_to_ideadcroot_fin)) &!*matrix_nfiturnover(p,ilivecroot)) &
+ * dt * livecrootn(p)
+
+ matrix_ntransfer_retransn_to_leaf_acc(p) = matrix_ntransfer_retransn_to_leaf_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ileaf_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_leafst_acc(p) = matrix_ntransfer_retransn_to_leafst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ileafst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_froot_acc(p) = matrix_ntransfer_retransn_to_froot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ifroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_frootst_acc(p) = matrix_ntransfer_retransn_to_frootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ifrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livestem_acc(p) = matrix_ntransfer_retransn_to_livestem_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivestem_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livestemst_acc(p) = matrix_ntransfer_retransn_to_livestemst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivestemst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadstem_acc(p) = matrix_ntransfer_retransn_to_deadstem_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadstem_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadstemst_acc(p) = matrix_ntransfer_retransn_to_deadstemst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadstemst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livecroot_acc(p) = matrix_ntransfer_retransn_to_livecroot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivecroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_livecrootst_acc(p) = matrix_ntransfer_retransn_to_livecrootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ilivecrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadcroot_acc(p) = matrix_ntransfer_retransn_to_deadcroot_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadcroot_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_deadcrootst_acc(p) = matrix_ntransfer_retransn_to_deadcrootst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_ideadcrootst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_leaf_to_retransn_acc(p) = matrix_ntransfer_leaf_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ileaf_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ileaf)*leafn(p)
+ matrix_ntransfer_froot_to_retransn_acc(p) = matrix_ntransfer_froot_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ifroot_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ifroot)*frootn(p)
+ matrix_ntransfer_livestem_to_retransn_acc(p) = matrix_ntransfer_livestem_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ilivestem_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ilivestem)*livestemn(p)
+ matrix_ntransfer_livecroot_to_retransn_acc(p) = matrix_ntransfer_livecroot_to_retransn_acc(p) &
+ + matrix_nphtransfer(p,ilivecroot_to_iretransn_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,ilivecroot)*livecrootn(p)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_retransn_to_grain_acc(p) = matrix_ntransfer_retransn_to_grain_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_igrain_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ matrix_ntransfer_retransn_to_grainst_acc(p) = matrix_ntransfer_retransn_to_grainst_acc(p) &
+ + matrix_nphtransfer(p,iretransn_to_igrainst_phn) &
+ * dt * retransn(p)!matrix_nphturnover(p,iretransn)*retransn(p)
+ end if
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ matrix_nturnover_leaf_acc(p) = matrix_nturnover_leaf_acc(p) &
+ + (matrix_nphturnover(p,ileaf)+matrix_ngmturnover(p,ileaf)+matrix_nfiturnover(p,ileaf)) &
+ * leafn(p)
+ matrix_nturnover_leafst_acc(p) = matrix_nturnover_leafst_acc(p) &
+ + (matrix_nphturnover(p,ileaf_st)+matrix_ngmturnover(p,ileaf_st)+matrix_nfiturnover(p,ileaf_st)) &
+ * leafn_storage(p)
+ matrix_nturnover_leafxf_acc(p) = matrix_nturnover_leafxf_acc(p) &
+ + (matrix_nphturnover(p,ileaf_xf)+matrix_ngmturnover(p,ileaf_xf)+matrix_nfiturnover(p,ileaf_xf)) &
+ * leafn_xfer(p)
+ matrix_nturnover_froot_acc(p) = matrix_nturnover_froot_acc(p) &
+ + (matrix_nphturnover(p,ifroot)+matrix_ngmturnover(p,ifroot)+matrix_nfiturnover(p,ifroot)) &
+ * frootn(p)
+ matrix_nturnover_frootst_acc(p) = matrix_nturnover_frootst_acc(p) &
+ + (matrix_nphturnover(p,ifroot_st)+matrix_ngmturnover(p,ifroot_st)+matrix_nfiturnover(p,ifroot_st)) &
+ * frootn_storage(p)
+ matrix_nturnover_frootxf_acc(p) = matrix_nturnover_frootxf_acc(p) &
+ + (matrix_nphturnover(p,ifroot_xf)+matrix_ngmturnover(p,ifroot_xf)+matrix_nfiturnover(p,ifroot_xf)) &
+ * frootn_xfer(p)
+ matrix_nturnover_livestem_acc(p) = matrix_nturnover_livestem_acc(p) &
+ + (matrix_nphturnover(p,ilivestem)+matrix_ngmturnover(p,ilivestem)+matrix_nfiturnover(p,ilivestem)) &
+ * livestemn(p)
+ matrix_nturnover_livestemst_acc(p) = matrix_nturnover_livestemst_acc(p) &
+ + (matrix_nphturnover(p,ilivestem_st)+matrix_ngmturnover(p,ilivestem_st)+matrix_nfiturnover(p,ilivestem_st)) &
+ * livestemn_storage(p)
+ matrix_nturnover_livestemxf_acc(p) = matrix_nturnover_livestemxf_acc(p) &
+ + (matrix_nphturnover(p,ilivestem_xf)+matrix_ngmturnover(p,ilivestem_xf)+matrix_nfiturnover(p,ilivestem_xf)) &
+ * livestemn_xfer(p)
+ matrix_nturnover_deadstem_acc(p) = matrix_nturnover_deadstem_acc(p) &
+ + (matrix_nphturnover(p,ideadstem)+matrix_ngmturnover(p,ideadstem)+matrix_nfiturnover(p,ideadstem)) &
+ * deadstemn(p)
+ matrix_nturnover_deadstemst_acc(p) = matrix_nturnover_deadstemst_acc(p) &
+ + (matrix_nphturnover(p,ideadstem_st)+matrix_ngmturnover(p,ideadstem_st)+matrix_nfiturnover(p,ideadstem_st)) &
+ * deadstemn_storage(p)
+ matrix_nturnover_deadstemxf_acc(p) = matrix_nturnover_deadstemxf_acc(p) &
+ + (matrix_nphturnover(p,ideadstem_xf)+matrix_ngmturnover(p,ideadstem_xf)+matrix_nfiturnover(p,ideadstem_xf)) &
+ * deadstemn_xfer(p)
+ matrix_nturnover_livecroot_acc(p) = matrix_nturnover_livecroot_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot)+matrix_ngmturnover(p,ilivecroot)+matrix_nfiturnover(p,ilivecroot)) &
+ * livecrootn(p)
+ matrix_nturnover_livecrootst_acc(p) = matrix_nturnover_livecrootst_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot_st)+matrix_ngmturnover(p,ilivecroot_st)+matrix_nfiturnover(p,ilivecroot_st)) &
+ * livecrootn_storage(p)
+ matrix_nturnover_livecrootxf_acc(p) = matrix_nturnover_livecrootxf_acc(p) &
+ + (matrix_nphturnover(p,ilivecroot_xf)+matrix_ngmturnover(p,ilivecroot_xf)+matrix_nfiturnover(p,ilivecroot_xf)) &
+ * livecrootn_xfer(p)
+ matrix_nturnover_deadcroot_acc(p) = matrix_nturnover_deadcroot_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot)+matrix_ngmturnover(p,ideadcroot)+matrix_nfiturnover(p,ideadcroot)) &
+ * deadcrootn(p)
+ matrix_nturnover_deadcrootst_acc(p) = matrix_nturnover_deadcrootst_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot_st)+matrix_ngmturnover(p,ideadcroot_st)+matrix_nfiturnover(p,ideadcroot_st)) &
+ * deadcrootn_storage(p)
+ matrix_nturnover_deadcrootxf_acc(p) = matrix_nturnover_deadcrootxf_acc(p) &
+ + (matrix_nphturnover(p,ideadcroot_xf)+matrix_ngmturnover(p,ideadcroot_xf)+matrix_nfiturnover(p,ideadcroot_xf)) &
+ * deadcrootn_xfer(p)
+ matrix_nturnover_retransn_acc(p) = matrix_nturnover_retransn_acc(p) &
+ + (matrix_nphturnover(p,iretransn)+matrix_ngmturnover(p,iretransn)+matrix_nfiturnover(p,iretransn)) &
+ * retransn(p)
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ matrix_nturnover_grain_acc(p) = matrix_nturnover_grain_acc(p) &
+ + (matrix_nphturnover(p,igrain)+matrix_ngmturnover(p,igrain)+matrix_nfiturnover(p,igrain)) &
+ * reproductiven(p,irepr)
+ matrix_nturnover_grainst_acc(p) = matrix_nturnover_grainst_acc(p) &
+ + (matrix_nphturnover(p,igrain_st)+matrix_ngmturnover(p,igrain_st)+matrix_nfiturnover(p,igrain_st)) &
+ * reproductiven_storage(p,irepr)
+ matrix_nturnover_grainxf_acc(p) = matrix_nturnover_grainxf_acc(p) &
+ + (matrix_nphturnover(p,igrain_xf)+matrix_ngmturnover(p,igrain_xf)+matrix_nfiturnover(p,igrain_xf)) &
+ * reproductiven_xfer(p,irepr)
+ end if
+ end do
+ end if
+ call t_stopf('CN veg matrix-accum. trans.')
+
+ ! Update state variables
+ call t_startf('CN veg matrix-assign new value')
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafc(p) = Xvegc%V(p,ileaf)
+ leafc_storage(p) = Xvegc%V(p,ileaf_st)
+ leafc_xfer(p) = Xvegc%V(p,ileaf_xf)
+ frootc(p) = Xvegc%V(p,ifroot)
+ frootc_storage(p) = Xvegc%V(p,ifroot_st)
+ frootc_xfer(p) = Xvegc%V(p,ifroot_xf)
+ livestemc(p) = Xvegc%V(p,ilivestem)
+ livestemc_storage(p) = Xvegc%V(p,ilivestem_st)
+ livestemc_xfer(p) = Xvegc%V(p,ilivestem_xf)
+ deadstemc(p) = Xvegc%V(p,ideadstem)
+ deadstemc_storage(p) = Xvegc%V(p,ideadstem_st)
+ deadstemc_xfer(p) = Xvegc%V(p,ideadstem_xf)
+ livecrootc(p) = Xvegc%V(p,ilivecroot)
+ livecrootc_storage(p) = Xvegc%V(p,ilivecroot_st)
+ livecrootc_xfer(p) = Xvegc%V(p,ilivecroot_xf)
+ deadcrootc(p) = Xvegc%V(p,ideadcroot)
+ deadcrootc_storage(p) = Xvegc%V(p,ideadcroot_st)
+ deadcrootc_xfer(p) = Xvegc%V(p,ideadcroot_xf)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ reproductivec(p,:) = Xvegc%V(p,igrain)
+ reproductivec_storage(p,:) = Xvegc%V(p,igrain_st)
+ reproductivec_xfer(p,:) = Xvegc%V(p,igrain_xf)
+ end if
+ end do
+
+ if ( use_c13 ) then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs13_veg%leafc_patch(p) = Xveg13c%V(p,ileaf)
+ cs13_veg%leafc_storage_patch(p) = Xveg13c%V(p,ileaf_st)
+ cs13_veg%leafc_xfer_patch(p) = Xveg13c%V(p,ileaf_xf)
+ cs13_veg%frootc_patch(p) = Xveg13c%V(p,ifroot)
+ cs13_veg%frootc_storage_patch(p) = Xveg13c%V(p,ifroot_st)
+ cs13_veg%frootc_xfer_patch(p) = Xveg13c%V(p,ifroot_xf)
+ cs13_veg%livestemc_patch(p) = Xveg13c%V(p,ilivestem)
+ cs13_veg%livestemc_storage_patch(p) = Xveg13c%V(p,ilivestem_st)
+ cs13_veg%livestemc_xfer_patch(p) = Xveg13c%V(p,ilivestem_xf)
+ cs13_veg%deadstemc_patch(p) = Xveg13c%V(p,ideadstem)
+ cs13_veg%deadstemc_storage_patch(p) = Xveg13c%V(p,ideadstem_st)
+ cs13_veg%deadstemc_xfer_patch(p) = Xveg13c%V(p,ideadstem_xf)
+ cs13_veg%livecrootc_patch(p) = Xveg13c%V(p,ilivecroot)
+ cs13_veg%livecrootc_storage_patch(p) = Xveg13c%V(p,ilivecroot_st)
+ cs13_veg%livecrootc_xfer_patch(p) = Xveg13c%V(p,ilivecroot_xf)
+ cs13_veg%deadcrootc_patch(p) = Xveg13c%V(p,ideadcroot)
+ cs13_veg%deadcrootc_storage_patch(p) = Xveg13c%V(p,ideadcroot_st)
+ cs13_veg%deadcrootc_xfer_patch(p) = Xveg13c%V(p,ideadcroot_xf)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ cs13_veg%reproductivec_patch(p,:) = Xveg13c%V(p,igrain)
+ cs13_veg%reproductivec_storage_patch(p,:) = Xveg13c%V(p,igrain_st)
+ cs13_veg%reproductivec_xfer_patch(p,:) = Xveg13c%V(p,igrain_xf)
+ end if
+ end do
+ end if
+
+ if ( use_c14 ) then
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ cs14_veg%leafc_patch(p) = Xveg14c%V(p,ileaf)
+ cs14_veg%leafc_storage_patch(p) = Xveg14c%V(p,ileaf_st)
+ cs14_veg%leafc_xfer_patch(p) = Xveg14c%V(p,ileaf_xf)
+ cs14_veg%frootc_patch(p) = Xveg14c%V(p,ifroot)
+ cs14_veg%frootc_storage_patch(p) = Xveg14c%V(p,ifroot_st)
+ cs14_veg%frootc_xfer_patch(p) = Xveg14c%V(p,ifroot_xf)
+ cs14_veg%livestemc_patch(p) = Xveg14c%V(p,ilivestem)
+ cs14_veg%livestemc_storage_patch(p) = Xveg14c%V(p,ilivestem_st)
+ cs14_veg%livestemc_xfer_patch(p) = Xveg14c%V(p,ilivestem_xf)
+ cs14_veg%deadstemc_patch(p) = Xveg14c%V(p,ideadstem)
+ cs14_veg%deadstemc_storage_patch(p) = Xveg14c%V(p,ideadstem_st)
+ cs14_veg%deadstemc_xfer_patch(p) = Xveg14c%V(p,ideadstem_xf)
+ cs14_veg%livecrootc_patch(p) = Xveg14c%V(p,ilivecroot)
+ cs14_veg%livecrootc_storage_patch(p) = Xveg14c%V(p,ilivecroot_st)
+ cs14_veg%livecrootc_xfer_patch(p) = Xveg14c%V(p,ilivecroot_xf)
+ cs14_veg%deadcrootc_patch(p) = Xveg14c%V(p,ideadcroot)
+ cs14_veg%deadcrootc_storage_patch(p) = Xveg14c%V(p,ideadcroot_st)
+ cs14_veg%deadcrootc_xfer_patch(p) = Xveg14c%V(p,ideadcroot_xf)
+ end do
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ ! NOTE: This assumes only a single grain pool! (i.e nrepr is
+ ! fixed at 1)!
+ cs14_veg%reproductivec_patch(p,:) = Xveg14c%V(p,igrain)
+ cs14_veg%reproductivec_storage_patch(p,:) = Xveg14c%V(p,igrain_st)
+ cs14_veg%reproductivec_xfer_patch(p,:) = Xveg14c%V(p,igrain_xf)
+ end if
+ end do
+ end if
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ leafn(p) = Xvegn%V(p,ileaf)
+ leafn_storage(p) = Xvegn%V(p,ileaf_st)
+ leafn_xfer(p) = Xvegn%V(p,ileaf_xf)
+ frootn(p) = Xvegn%V(p,ifroot)
+ frootn_storage(p) = Xvegn%V(p,ifroot_st)
+ frootn_xfer(p) = Xvegn%V(p,ifroot_xf)
+ livestemn(p) = Xvegn%V(p,ilivestem)
+ livestemn_storage(p) = Xvegn%V(p,ilivestem_st)
+ livestemn_xfer(p) = Xvegn%V(p,ilivestem_xf)
+ deadstemn(p) = Xvegn%V(p,ideadstem)
+ deadstemn_storage(p) = Xvegn%V(p,ideadstem_st)
+ deadstemn_xfer(p) = Xvegn%V(p,ideadstem_xf)
+ livecrootn(p) = Xvegn%V(p,ilivecroot)
+ livecrootn_storage(p) = Xvegn%V(p,ilivecroot_st)
+ livecrootn_xfer(p) = Xvegn%V(p,ilivecroot_xf)
+ deadcrootn(p) = Xvegn%V(p,ideadcroot)
+ deadcrootn_storage(p) = Xvegn%V(p,ideadcroot_st)
+ deadcrootn_xfer(p) = Xvegn%V(p,ideadcroot_xf)
+ retransn(p) = Xvegn%V(p,iretransn)
+ end do
+
+ do fp = 1,num_soilp
+ p = filter_soilp(fp)
+ if(ivt(p) >= npcropmin)then
+ reproductiven(p,:) = Xvegn%V(p,igrain)
+ reproductiven_storage(p,:) = Xvegn%V(p,igrain_st)
+ reproductiven_xfer(p,:) = Xvegn%V(p,igrain_xf)
+ end if
+ end do
+ call t_stopf('CN veg matrix-assign new value')
+
+ ! Calculate C storage capacity. 2D matrix instead of sparse matrix is still used when calculating the inverse
+ if(spinup_matrixcn .or. hist_wrt_matrixcn_diag)then
+ if((.not. spinup_matrixcn .and. is_end_curr_year()) .or. (spinup_matrixcn .and. is_end_curr_year() .and. mod(iyr,nyr_SASU) .eq. 0))then
+ do fp = 1,num_soilp
+ call t_startf('CN veg matrix-prepare AK^-1')
+ p = filter_soilp(fp)
+ matrix_calloc_acc(ileaf) = matrix_calloc_leaf_acc(p)
+ matrix_calloc_acc(ileaf_st) = matrix_calloc_leafst_acc(p)
+ matrix_calloc_acc(ifroot) = matrix_calloc_froot_acc(p)
+ matrix_calloc_acc(ifroot_st) = matrix_calloc_frootst_acc(p)
+ matrix_calloc_acc(ilivestem) = matrix_calloc_livestem_acc(p)
+ matrix_calloc_acc(ilivestem_st) = matrix_calloc_livestemst_acc(p)
+ matrix_calloc_acc(ideadstem) = matrix_calloc_deadstem_acc(p)
+ matrix_calloc_acc(ideadstem_st) = matrix_calloc_deadstemst_acc(p)
+ matrix_calloc_acc(ilivecroot) = matrix_calloc_livecroot_acc(p)
+ matrix_calloc_acc(ilivecroot_st) = matrix_calloc_livecrootst_acc(p)
+ matrix_calloc_acc(ideadcroot) = matrix_calloc_deadcroot_acc(p)
+ matrix_calloc_acc(ideadcroot_st) = matrix_calloc_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_acc(igrain) = matrix_calloc_grain_acc(p)
+ matrix_calloc_acc(igrain_st) = matrix_calloc_grainst_acc(p)
+ end if
+
+ matrix_ctransfer_acc(ileaf_xf,ileaf_st) = matrix_ctransfer_leafst_to_leafxf_acc(p)
+ matrix_ctransfer_acc(ileaf,ileaf_xf) = matrix_ctransfer_leafxf_to_leaf_acc(p)
+ matrix_ctransfer_acc(ifroot_xf,ifroot_st) = matrix_ctransfer_frootst_to_frootxf_acc(p)
+ matrix_ctransfer_acc(ifroot,ifroot_xf) = matrix_ctransfer_frootxf_to_froot_acc(p)
+ matrix_ctransfer_acc(ilivestem_xf,ilivestem_st) = matrix_ctransfer_livestemst_to_livestemxf_acc(p)
+ matrix_ctransfer_acc(ilivestem,ilivestem_xf) = matrix_ctransfer_livestemxf_to_livestem_acc(p)
+ matrix_ctransfer_acc(ideadstem_xf,ideadstem_st) = matrix_ctransfer_deadstemst_to_deadstemxf_acc(p)
+ matrix_ctransfer_acc(ideadstem,ideadstem_xf) = matrix_ctransfer_deadstemxf_to_deadstem_acc(p)
+ matrix_ctransfer_acc(ilivecroot_xf,ilivecroot_st) = matrix_ctransfer_livecrootst_to_livecrootxf_acc(p)
+ matrix_ctransfer_acc(ilivecroot,ilivecroot_xf) = matrix_ctransfer_livecrootxf_to_livecroot_acc(p)
+ matrix_ctransfer_acc(ideadcroot_xf,ideadcroot_st) = matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ideadcroot_xf) = matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(igrain_xf,igrain_st) = matrix_ctransfer_grainst_to_grainxf_acc(p)
+ matrix_ctransfer_acc(igrain,igrain_xf) = matrix_ctransfer_grainxf_to_grain_acc(p)
+ end if
+ matrix_ctransfer_acc(ideadstem,ilivestem) = matrix_ctransfer_livestem_to_deadstem_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ilivecroot) = matrix_ctransfer_livecroot_to_deadcroot_acc(p)
+
+ matrix_ctransfer_acc(ileaf,ileaf) = -matrix_cturnover_leaf_acc(p)
+ matrix_ctransfer_acc(ileaf_st,ileaf_st) = -matrix_cturnover_leafst_acc(p)
+ matrix_ctransfer_acc(ileaf_xf,ileaf_xf) = -matrix_cturnover_leafxf_acc(p)
+ matrix_ctransfer_acc(ifroot,ifroot) = -matrix_cturnover_froot_acc(p)
+ matrix_ctransfer_acc(ifroot_st,ifroot_st) = -matrix_cturnover_frootst_acc(p)
+ matrix_ctransfer_acc(ifroot_xf,ifroot_xf) = -matrix_cturnover_frootxf_acc(p)
+ matrix_ctransfer_acc(ilivestem,ilivestem) = -matrix_cturnover_livestem_acc(p)
+ matrix_ctransfer_acc(ilivestem_st,ilivestem_st) = -matrix_cturnover_livestemst_acc(p)
+ matrix_ctransfer_acc(ilivestem_xf,ilivestem_xf) = -matrix_cturnover_livestemxf_acc(p)
+ matrix_ctransfer_acc(ideadstem,ideadstem) = -matrix_cturnover_deadstem_acc(p)
+ matrix_ctransfer_acc(ideadstem_st,ideadstem_st) = -matrix_cturnover_deadstemst_acc(p)
+ matrix_ctransfer_acc(ideadstem_xf,ideadstem_xf) = -matrix_cturnover_deadstemxf_acc(p)
+ matrix_ctransfer_acc(ilivecroot,ilivecroot) = -matrix_cturnover_livecroot_acc(p)
+ matrix_ctransfer_acc(ilivecroot_st,ilivecroot_st) = -matrix_cturnover_livecrootst_acc(p)
+ matrix_ctransfer_acc(ilivecroot_xf,ilivecroot_xf) = -matrix_cturnover_livecrootxf_acc(p)
+ matrix_ctransfer_acc(ideadcroot,ideadcroot) = -matrix_cturnover_deadcroot_acc(p)
+ matrix_ctransfer_acc(ideadcroot_st,ideadcroot_st) = -matrix_cturnover_deadcrootst_acc(p)
+ matrix_ctransfer_acc(ideadcroot_xf,ideadcroot_xf) = -matrix_cturnover_deadcrootxf_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(igrain,igrain) = -matrix_cturnover_grain_acc(p)
+ matrix_ctransfer_acc(igrain_st,igrain_st) = -matrix_cturnover_grainst_acc(p)
+ matrix_ctransfer_acc(igrain_xf,igrain_xf) = -matrix_cturnover_grainxf_acc(p)
+ end if
+
+ if(use_c13)then
+ matrix_c13alloc_acc(ileaf) = cs13_veg%matrix_calloc_leaf_acc_patch(p)
+ matrix_c13alloc_acc(ileaf_st) = cs13_veg%matrix_calloc_leafst_acc_patch(p)
+ matrix_c13alloc_acc(ifroot) = cs13_veg%matrix_calloc_froot_acc_patch(p)
+ matrix_c13alloc_acc(ifroot_st) = cs13_veg%matrix_calloc_frootst_acc_patch(p)
+ matrix_c13alloc_acc(ilivestem) = cs13_veg%matrix_calloc_livestem_acc_patch(p)
+ matrix_c13alloc_acc(ilivestem_st) = cs13_veg%matrix_calloc_livestemst_acc_patch(p)
+ matrix_c13alloc_acc(ideadstem) = cs13_veg%matrix_calloc_deadstem_acc_patch(p)
+ matrix_c13alloc_acc(ideadstem_st) = cs13_veg%matrix_calloc_deadstemst_acc_patch(p)
+ matrix_c13alloc_acc(ilivecroot) = cs13_veg%matrix_calloc_livecroot_acc_patch(p)
+ matrix_c13alloc_acc(ilivecroot_st) = cs13_veg%matrix_calloc_livecrootst_acc_patch(p)
+ matrix_c13alloc_acc(ideadcroot) = cs13_veg%matrix_calloc_deadcroot_acc_patch(p)
+ matrix_c13alloc_acc(ideadcroot_st) = cs13_veg%matrix_calloc_deadcrootst_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13alloc_acc(igrain) = cs13_veg%matrix_calloc_grain_acc_patch(p)
+ matrix_c13alloc_acc(igrain_st) = cs13_veg%matrix_calloc_grainst_acc_patch(p)
+ end if
+
+ matrix_c13transfer_acc(ileaf_xf,ileaf_st) = cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p)
+ matrix_c13transfer_acc(ileaf,ileaf_xf) = cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_xf,ifroot_st) = cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot,ifroot_xf) = cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_xf,ilivestem_st) = cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem,ilivestem_xf) = cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_xf,ideadstem_st) = cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem,ideadstem_xf) = cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_xf,ilivecroot_st) = cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot,ilivecroot_xf) = cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_xf,ideadcroot_st) = cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ideadcroot_xf) = cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(igrain_xf,igrain_st) = cs13_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p)
+ matrix_c13transfer_acc(igrain,igrain_xf) = cs13_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p)
+ end if
+ matrix_c13transfer_acc(ideadstem,ilivestem) = cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ilivecroot) = cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p)
+
+ matrix_c13transfer_acc(ileaf,ileaf) = -cs13_veg%matrix_cturnover_leaf_acc_patch(p)
+ matrix_c13transfer_acc(ileaf_st,ileaf_st) = -cs13_veg%matrix_cturnover_leafst_acc_patch(p)
+ matrix_c13transfer_acc(ileaf_xf,ileaf_xf) = -cs13_veg%matrix_cturnover_leafxf_acc_patch(p)
+ matrix_c13transfer_acc(ifroot,ifroot) = -cs13_veg%matrix_cturnover_froot_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_st,ifroot_st) = -cs13_veg%matrix_cturnover_frootst_acc_patch(p)
+ matrix_c13transfer_acc(ifroot_xf,ifroot_xf) = -cs13_veg%matrix_cturnover_frootxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem,ilivestem) = -cs13_veg%matrix_cturnover_livestem_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_st,ilivestem_st) = -cs13_veg%matrix_cturnover_livestemst_acc_patch(p)
+ matrix_c13transfer_acc(ilivestem_xf,ilivestem_xf) = -cs13_veg%matrix_cturnover_livestemxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem,ideadstem) = -cs13_veg%matrix_cturnover_deadstem_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_st,ideadstem_st) = -cs13_veg%matrix_cturnover_deadstemst_acc_patch(p)
+ matrix_c13transfer_acc(ideadstem_xf,ideadstem_xf) = -cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot,ilivecroot) = -cs13_veg%matrix_cturnover_livecroot_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_st,ilivecroot_st) = -cs13_veg%matrix_cturnover_livecrootst_acc_patch(p)
+ matrix_c13transfer_acc(ilivecroot_xf,ilivecroot_xf) = -cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot,ideadcroot) = -cs13_veg%matrix_cturnover_deadcroot_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_st,ideadcroot_st) = -cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p)
+ matrix_c13transfer_acc(ideadcroot_xf,ideadcroot_xf) = -cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(igrain,igrain) = -cs13_veg%matrix_cturnover_grain_acc_patch(p)
+ matrix_c13transfer_acc(igrain_st,igrain_st) = -cs13_veg%matrix_cturnover_grainst_acc_patch(p)
+ matrix_c13transfer_acc(igrain_xf,igrain_xf) = -cs13_veg%matrix_cturnover_grainxf_acc_patch(p)
+ end if
+ end if
+
+ if(use_c14)then
+ matrix_c14alloc_acc(ileaf) = cs14_veg%matrix_calloc_leaf_acc_patch(p)
+ matrix_c14alloc_acc(ileaf_st) = cs14_veg%matrix_calloc_leafst_acc_patch(p)
+ matrix_c14alloc_acc(ifroot) = cs14_veg%matrix_calloc_froot_acc_patch(p)
+ matrix_c14alloc_acc(ifroot_st) = cs14_veg%matrix_calloc_frootst_acc_patch(p)
+ matrix_c14alloc_acc(ilivestem) = cs14_veg%matrix_calloc_livestem_acc_patch(p)
+ matrix_c14alloc_acc(ilivestem_st) = cs14_veg%matrix_calloc_livestemst_acc_patch(p)
+ matrix_c14alloc_acc(ideadstem) = cs14_veg%matrix_calloc_deadstem_acc_patch(p)
+ matrix_c14alloc_acc(ideadstem_st) = cs14_veg%matrix_calloc_deadstemst_acc_patch(p)
+ matrix_c14alloc_acc(ilivecroot) = cs14_veg%matrix_calloc_livecroot_acc_patch(p)
+ matrix_c14alloc_acc(ilivecroot_st) = cs14_veg%matrix_calloc_livecrootst_acc_patch(p)
+ matrix_c14alloc_acc(ideadcroot) = cs14_veg%matrix_calloc_deadcroot_acc_patch(p)
+ matrix_c14alloc_acc(ideadcroot_st) = cs14_veg%matrix_calloc_deadcrootst_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14alloc_acc(igrain) = cs14_veg%matrix_calloc_grain_acc_patch(p)
+ matrix_c14alloc_acc(igrain_st) = cs14_veg%matrix_calloc_grainst_acc_patch(p)
+ end if
+
+ matrix_c14transfer_acc(ileaf_xf,ileaf_st) = cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p)
+ matrix_c14transfer_acc(ileaf,ileaf_xf) = cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_xf,ifroot_st) = cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot,ifroot_xf) = cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_xf,ilivestem_st) = cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem,ilivestem_xf) = cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_xf,ideadstem_st) = cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem,ideadstem_xf) = cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_xf,ilivecroot_st) = cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot,ilivecroot_xf) = cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_xf,ideadcroot_st) = cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ideadcroot_xf) = cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(igrain_xf,igrain_st) = cs14_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p)
+ matrix_c14transfer_acc(igrain,igrain_xf) = cs14_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p)
+ end if
+ matrix_c14transfer_acc(ideadstem,ilivestem) = cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ilivecroot) = cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p)
+
+ matrix_c14transfer_acc(ileaf,ileaf) = -cs14_veg%matrix_cturnover_leaf_acc_patch(p)
+ matrix_c14transfer_acc(ileaf_st,ileaf_st) = -cs14_veg%matrix_cturnover_leafst_acc_patch(p)
+ matrix_c14transfer_acc(ileaf_xf,ileaf_xf) = -cs14_veg%matrix_cturnover_leafxf_acc_patch(p)
+ matrix_c14transfer_acc(ifroot,ifroot) = -cs14_veg%matrix_cturnover_froot_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_st,ifroot_st) = -cs14_veg%matrix_cturnover_frootst_acc_patch(p)
+ matrix_c14transfer_acc(ifroot_xf,ifroot_xf) = -cs14_veg%matrix_cturnover_frootxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem,ilivestem) = -cs14_veg%matrix_cturnover_livestem_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_st,ilivestem_st) = -cs14_veg%matrix_cturnover_livestemst_acc_patch(p)
+ matrix_c14transfer_acc(ilivestem_xf,ilivestem_xf) = -cs14_veg%matrix_cturnover_livestemxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem,ideadstem) = -cs14_veg%matrix_cturnover_deadstem_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_st,ideadstem_st) = -cs14_veg%matrix_cturnover_deadstemst_acc_patch(p)
+ matrix_c14transfer_acc(ideadstem_xf,ideadstem_xf) = -cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot,ilivecroot) = -cs14_veg%matrix_cturnover_livecroot_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_st,ilivecroot_st) = -cs14_veg%matrix_cturnover_livecrootst_acc_patch(p)
+ matrix_c14transfer_acc(ilivecroot_xf,ilivecroot_xf) = -cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot,ideadcroot) = -cs14_veg%matrix_cturnover_deadcroot_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_st,ideadcroot_st) = -cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p)
+ matrix_c14transfer_acc(ideadcroot_xf,ideadcroot_xf) = -cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(igrain,igrain) = -cs14_veg%matrix_cturnover_grain_acc_patch(p)
+ matrix_c14transfer_acc(igrain_st,igrain_st) = -cs14_veg%matrix_cturnover_grainst_acc_patch(p)
+ matrix_c14transfer_acc(igrain_xf,igrain_xf) = -cs14_veg%matrix_cturnover_grainxf_acc_patch(p)
+ end if
+ end if
+
+ matrix_nalloc_acc(ileaf) = matrix_nalloc_leaf_acc(p)
+ matrix_nalloc_acc(ileaf_st) = matrix_nalloc_leafst_acc(p)
+ matrix_nalloc_acc(ifroot) = matrix_nalloc_froot_acc(p)
+ matrix_nalloc_acc(ifroot_st) = matrix_nalloc_frootst_acc(p)
+ matrix_nalloc_acc(ilivestem) = matrix_nalloc_livestem_acc(p)
+ matrix_nalloc_acc(ilivestem_st) = matrix_nalloc_livestemst_acc(p)
+ matrix_nalloc_acc(ideadstem) = matrix_nalloc_deadstem_acc(p)
+ matrix_nalloc_acc(ideadstem_st) = matrix_nalloc_deadstemst_acc(p)
+ matrix_nalloc_acc(ilivecroot) = matrix_nalloc_livecroot_acc(p)
+ matrix_nalloc_acc(ilivecroot_st) = matrix_nalloc_livecrootst_acc(p)
+ matrix_nalloc_acc(ideadcroot) = matrix_nalloc_deadcroot_acc(p)
+ matrix_nalloc_acc(ideadcroot_st) = matrix_nalloc_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_acc(igrain) = matrix_nalloc_grain_acc(p)
+ matrix_nalloc_acc(igrain_st) = matrix_nalloc_grainst_acc(p)
+ end if
+
+ matrix_ntransfer_acc(ileaf_xf,ileaf_st) = matrix_ntransfer_leafst_to_leafxf_acc(p)
+ matrix_ntransfer_acc(ileaf,ileaf_xf) = matrix_ntransfer_leafxf_to_leaf_acc(p)
+ matrix_ntransfer_acc(ifroot_xf,ifroot_st) = matrix_ntransfer_frootst_to_frootxf_acc(p)
+ matrix_ntransfer_acc(ifroot,ifroot_xf) = matrix_ntransfer_frootxf_to_froot_acc(p)
+ matrix_ntransfer_acc(ilivestem_xf,ilivestem_st) = matrix_ntransfer_livestemst_to_livestemxf_acc(p)
+ matrix_ntransfer_acc(ilivestem,ilivestem_xf) = matrix_ntransfer_livestemxf_to_livestem_acc(p)
+ matrix_ntransfer_acc(ideadstem_xf,ideadstem_st) = matrix_ntransfer_deadstemst_to_deadstemxf_acc(p)
+ matrix_ntransfer_acc(ideadstem,ideadstem_xf) = matrix_ntransfer_deadstemxf_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ilivecroot_xf,ilivecroot_st) = matrix_ntransfer_livecrootst_to_livecrootxf_acc(p)
+ matrix_ntransfer_acc(ilivecroot,ilivecroot_xf) = matrix_ntransfer_livecrootxf_to_livecroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_xf,ideadcroot_st) = matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ideadcroot_xf) = matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain_xf,igrain_st) = matrix_ntransfer_grainst_to_grainxf_acc(p)
+ matrix_ntransfer_acc(igrain,igrain_xf) = matrix_ntransfer_grainxf_to_grain_acc(p)
+ end if
+ matrix_ntransfer_acc(ideadstem,ilivestem) = matrix_ntransfer_livestem_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ilivecroot) = matrix_ntransfer_livecroot_to_deadcroot_acc(p)
+
+ matrix_ntransfer_acc(ileaf,iretransn) = matrix_ntransfer_retransn_to_leaf_acc(p)
+ matrix_ntransfer_acc(ileaf_st,iretransn) = matrix_ntransfer_retransn_to_leafst_acc(p)
+ matrix_ntransfer_acc(ifroot,iretransn) = matrix_ntransfer_retransn_to_froot_acc(p)
+ matrix_ntransfer_acc(ifroot_st,iretransn) = matrix_ntransfer_retransn_to_frootst_acc(p)
+ matrix_ntransfer_acc(ilivestem,iretransn) = matrix_ntransfer_retransn_to_livestem_acc(p)
+ matrix_ntransfer_acc(ilivestem_st,iretransn) = matrix_ntransfer_retransn_to_livestemst_acc(p)
+ matrix_ntransfer_acc(ideadstem,iretransn) = matrix_ntransfer_retransn_to_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadstem_st,iretransn) = matrix_ntransfer_retransn_to_deadstemst_acc(p)
+ matrix_ntransfer_acc(ilivecroot,iretransn) = matrix_ntransfer_retransn_to_livecroot_acc(p)
+ matrix_ntransfer_acc(ilivecroot_st,iretransn) = matrix_ntransfer_retransn_to_livecrootst_acc(p)
+ matrix_ntransfer_acc(ideadcroot,iretransn) = matrix_ntransfer_retransn_to_deadcroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_st,iretransn) = matrix_ntransfer_retransn_to_deadcrootst_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain,iretransn) = matrix_ntransfer_retransn_to_grain_acc(p)
+ matrix_ntransfer_acc(igrain_st,iretransn) = matrix_ntransfer_retransn_to_grainst_acc(p)
+ end if
+ matrix_ntransfer_acc(iretransn,ileaf) = matrix_ntransfer_leaf_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ifroot) = matrix_ntransfer_froot_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ilivestem) = matrix_ntransfer_livestem_to_retransn_acc(p)
+ matrix_ntransfer_acc(iretransn,ilivecroot) = matrix_ntransfer_livecroot_to_retransn_acc(p)
+
+ matrix_ntransfer_acc(ileaf,ileaf) = -matrix_nturnover_leaf_acc(p)
+ matrix_ntransfer_acc(ileaf_st,ileaf_st) = -matrix_nturnover_leafst_acc(p)
+ matrix_ntransfer_acc(ileaf_xf,ileaf_xf) = -matrix_nturnover_leafxf_acc(p)
+ matrix_ntransfer_acc(ifroot,ifroot) = -matrix_nturnover_froot_acc(p)
+ matrix_ntransfer_acc(ifroot_st,ifroot_st) = -matrix_nturnover_frootst_acc(p)
+ matrix_ntransfer_acc(ifroot_xf,ifroot_xf) = -matrix_nturnover_frootxf_acc(p)
+ matrix_ntransfer_acc(ilivestem,ilivestem) = -matrix_nturnover_livestem_acc(p)
+ matrix_ntransfer_acc(ilivestem_st,ilivestem_st) = -matrix_nturnover_livestemst_acc(p)
+ matrix_ntransfer_acc(ilivestem_xf,ilivestem_xf) = -matrix_nturnover_livestemxf_acc(p)
+ matrix_ntransfer_acc(ideadstem,ideadstem) = -matrix_nturnover_deadstem_acc(p)
+ matrix_ntransfer_acc(ideadstem_st,ideadstem_st) = -matrix_nturnover_deadstemst_acc(p)
+ matrix_ntransfer_acc(ideadstem_xf,ideadstem_xf) = -matrix_nturnover_deadstemxf_acc(p)
+ matrix_ntransfer_acc(ilivecroot,ilivecroot) = -matrix_nturnover_livecroot_acc(p)
+ matrix_ntransfer_acc(ilivecroot_st,ilivecroot_st) = -matrix_nturnover_livecrootst_acc(p)
+ matrix_ntransfer_acc(ilivecroot_xf,ilivecroot_xf) = -matrix_nturnover_livecrootxf_acc(p)
+ matrix_ntransfer_acc(ideadcroot,ideadcroot) = -matrix_nturnover_deadcroot_acc(p)
+ matrix_ntransfer_acc(ideadcroot_st,ideadcroot_st) = -matrix_nturnover_deadcrootst_acc(p)
+ matrix_ntransfer_acc(ideadcroot_xf,ideadcroot_xf) = -matrix_nturnover_deadcrootxf_acc(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(igrain,igrain) = -matrix_nturnover_grain_acc(p)
+ matrix_ntransfer_acc(igrain_st,igrain_st) = -matrix_nturnover_grainst_acc(p)
+ matrix_ntransfer_acc(igrain_xf,igrain_xf) = -matrix_nturnover_grainxf_acc(p)
+ end if
+ matrix_ntransfer_acc(iretransn,iretransn) = -matrix_nturnover_retransn_acc(p)
+
+ do i=1,nvegcpool
+ if(matrix_ctransfer_acc(i,i) == 0)then
+ matrix_ctransfer_acc(i,i) = spval
+ end if
+ end do
+ if(use_c13)then
+ do i=1,nvegcpool
+ if(matrix_c13transfer_acc(i,i) == 0)then
+ matrix_c13transfer_acc(i,i) = spval
+ end if
+ end do
+ end if
+ if(use_c14)then
+ do i=1,nvegcpool
+ if(matrix_c14transfer_acc(i,i) == 0)then
+ matrix_c14transfer_acc(i,i) = spval
+ end if
+ end do
+ end if
+ do i=1,nvegnpool
+ if(matrix_ntransfer_acc(i,i) == 0)then
+ matrix_ntransfer_acc(i,i) = spval
+ end if
+ end do
+
+ ! Calculate the transfer rate based on the initial value of the calendar year.
+ matrix_ctransfer_acc(1:nvegcpool,ileaf) = matrix_ctransfer_acc(1:nvegcpool,ileaf) / leafc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ileaf_st) = matrix_ctransfer_acc(1:nvegcpool,ileaf_st) / leafc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ileaf_xf) = matrix_ctransfer_acc(1:nvegcpool,ileaf_xf) / leafc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot) = matrix_ctransfer_acc(1:nvegcpool,ifroot) / frootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot_st) = matrix_ctransfer_acc(1:nvegcpool,ifroot_st) / frootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ifroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ifroot_xf) / frootc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem) = matrix_ctransfer_acc(1:nvegcpool,ilivestem) / livestemc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem_st) = matrix_ctransfer_acc(1:nvegcpool,ilivestem_st) / livestemc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivestem_xf) = matrix_ctransfer_acc(1:nvegcpool,ilivestem_xf) / livestemc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem) = matrix_ctransfer_acc(1:nvegcpool,ideadstem) / deadstemc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem_st) = matrix_ctransfer_acc(1:nvegcpool,ideadstem_st) / deadstemc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadstem_xf) = matrix_ctransfer_acc(1:nvegcpool,ideadstem_xf) / deadstemc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot) / livecrootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot_st) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot_st) / livecrootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ilivecroot_xf) / livecrootc0_xfer(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot) / deadcrootc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot_st) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot_st) / deadcrootc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_ctransfer_acc(1:nvegcpool,ideadcroot_xf) / deadcrootc0_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_acc(1:nvegcpool,igrain) = matrix_ctransfer_acc(1:nvegcpool,igrain) / reproc0(p)
+ matrix_ctransfer_acc(1:nvegcpool,igrain_st) = matrix_ctransfer_acc(1:nvegcpool,igrain_st) / reproc0_storage(p)
+ matrix_ctransfer_acc(1:nvegcpool,igrain_xf) = matrix_ctransfer_acc(1:nvegcpool,igrain_xf) / reproc0_xfer(p)
+ end if
+
+ if(use_c13)then
+ matrix_c13transfer_acc(1:nvegcpool,ileaf) = matrix_c13transfer_acc(1:nvegcpool,ileaf) / cs13_veg%leafc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ileaf_st) = matrix_c13transfer_acc(1:nvegcpool,ileaf_st) / cs13_veg%leafc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ileaf_xf) = matrix_c13transfer_acc(1:nvegcpool,ileaf_xf) / cs13_veg%leafc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot) = matrix_c13transfer_acc(1:nvegcpool,ifroot) / cs13_veg%frootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot_st) = matrix_c13transfer_acc(1:nvegcpool,ifroot_st) / cs13_veg%frootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ifroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ifroot_xf) / cs13_veg%frootc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem) = matrix_c13transfer_acc(1:nvegcpool,ilivestem) / cs13_veg%livestemc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem_st) = matrix_c13transfer_acc(1:nvegcpool,ilivestem_st) / cs13_veg%livestemc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivestem_xf) = matrix_c13transfer_acc(1:nvegcpool,ilivestem_xf) / cs13_veg%livestemc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem) = matrix_c13transfer_acc(1:nvegcpool,ideadstem) / cs13_veg%deadstemc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem_st) = matrix_c13transfer_acc(1:nvegcpool,ideadstem_st) / cs13_veg%deadstemc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadstem_xf) = matrix_c13transfer_acc(1:nvegcpool,ideadstem_xf) / cs13_veg%deadstemc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot) / cs13_veg%livecrootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot_st) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot_st) / cs13_veg%livecrootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ilivecroot_xf) / cs13_veg%livecrootc0_xfer_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot) / cs13_veg%deadcrootc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot_st) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot_st) / cs13_veg%deadcrootc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_c13transfer_acc(1:nvegcpool,ideadcroot_xf) / cs13_veg%deadcrootc0_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c13transfer_acc(1:nvegcpool,igrain) = matrix_c13transfer_acc(1:nvegcpool,igrain) / cs13_veg%reproc0_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,igrain_st) = matrix_c13transfer_acc(1:nvegcpool,igrain_st) / cs13_veg%reproc0_storage_patch(p)
+ matrix_c13transfer_acc(1:nvegcpool,igrain_xf) = matrix_c13transfer_acc(1:nvegcpool,igrain_xf) / cs13_veg%reproc0_xfer_patch(p)
+ end if
+ end if
+
+ if(use_c14)then
+ matrix_c14transfer_acc(1:nvegcpool,ileaf) = matrix_c14transfer_acc(1:nvegcpool,ileaf) / cs14_veg%leafc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ileaf_st) = matrix_c14transfer_acc(1:nvegcpool,ileaf_st) / cs14_veg%leafc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ileaf_xf) = matrix_c14transfer_acc(1:nvegcpool,ileaf_xf) / cs14_veg%leafc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot) = matrix_c14transfer_acc(1:nvegcpool,ifroot) / cs14_veg%frootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot_st) = matrix_c14transfer_acc(1:nvegcpool,ifroot_st) / cs14_veg%frootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ifroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ifroot_xf) / cs14_veg%frootc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem) = matrix_c14transfer_acc(1:nvegcpool,ilivestem) / cs14_veg%livestemc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem_st) = matrix_c14transfer_acc(1:nvegcpool,ilivestem_st) / cs14_veg%livestemc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivestem_xf) = matrix_c14transfer_acc(1:nvegcpool,ilivestem_xf) / cs14_veg%livestemc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem) = matrix_c14transfer_acc(1:nvegcpool,ideadstem) / cs14_veg%deadstemc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem_st) = matrix_c14transfer_acc(1:nvegcpool,ideadstem_st) / cs14_veg%deadstemc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadstem_xf) = matrix_c14transfer_acc(1:nvegcpool,ideadstem_xf) / cs14_veg%deadstemc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot) / cs14_veg%livecrootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot_st) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot_st) / cs14_veg%livecrootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ilivecroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ilivecroot_xf) / cs14_veg%livecrootc0_xfer_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot) / cs14_veg%deadcrootc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot_st) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot_st) / cs14_veg%deadcrootc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,ideadcroot_xf) = matrix_c14transfer_acc(1:nvegcpool,ideadcroot_xf) / cs14_veg%deadcrootc0_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_c14transfer_acc(1:nvegcpool,igrain) = matrix_c14transfer_acc(1:nvegcpool,igrain) / cs14_veg%reproc0_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,igrain_st) = matrix_c14transfer_acc(1:nvegcpool,igrain_st) / cs14_veg%reproc0_storage_patch(p)
+ matrix_c14transfer_acc(1:nvegcpool,igrain_xf) = matrix_c14transfer_acc(1:nvegcpool,igrain_xf) / cs14_veg%reproc0_xfer_patch(p)
+ end if
+ end if
+
+ matrix_ntransfer_acc(1:nvegnpool,ileaf) = matrix_ntransfer_acc(1:nvegnpool,ileaf) / leafn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ileaf_st) = matrix_ntransfer_acc(1:nvegnpool,ileaf_st) / leafn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ileaf_xf) = matrix_ntransfer_acc(1:nvegnpool,ileaf_xf) / leafn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot) = matrix_ntransfer_acc(1:nvegnpool,ifroot) / frootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot_st) = matrix_ntransfer_acc(1:nvegnpool,ifroot_st) / frootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ifroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ifroot_xf) / frootn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem) = matrix_ntransfer_acc(1:nvegnpool,ilivestem) / livestemn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem_st) = matrix_ntransfer_acc(1:nvegnpool,ilivestem_st) / livestemn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivestem_xf) = matrix_ntransfer_acc(1:nvegnpool,ilivestem_xf) / livestemn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem) = matrix_ntransfer_acc(1:nvegnpool,ideadstem) / deadstemn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem_st) = matrix_ntransfer_acc(1:nvegnpool,ideadstem_st) / deadstemn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadstem_xf) = matrix_ntransfer_acc(1:nvegnpool,ideadstem_xf) / deadstemn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot) / livecrootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot_st) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot_st) / livecrootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ilivecroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ilivecroot_xf) / livecrootn0_xfer(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot) / deadcrootn0(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot_st) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot_st) / deadcrootn0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,ideadcroot_xf) = matrix_ntransfer_acc(1:nvegnpool,ideadcroot_xf) / deadcrootn0_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_acc(1:nvegnpool,igrain) = matrix_ntransfer_acc(1:nvegnpool,igrain) / repron0(p)
+ matrix_ntransfer_acc(1:nvegnpool,igrain_st) = matrix_ntransfer_acc(1:nvegnpool,igrain_st) / repron0_storage(p)
+ matrix_ntransfer_acc(1:nvegnpool,igrain_xf) = matrix_ntransfer_acc(1:nvegnpool,igrain_xf) / repron0_xfer(p)
+ end if
+ matrix_ntransfer_acc(1:nvegnpool,iretransn) = matrix_ntransfer_acc(1:nvegnpool,iretransn) / retransn0(p)
+
+ call t_stopf('CN veg matrix-prepare AK^-1')
+ call t_startf('CN veg matrix-inv matrix operation')
+
+ ! Calculate the residence time and C storage capacity
+ call inverse(matrix_ctransfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_calloc_acc(1:nvegcpool))
+
+ ! Calculate the residence time and C13 storage capacity
+ if(use_c13)then
+ call inverse(matrix_c13transfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc13_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_c13alloc_acc(1:nvegcpool))
+ end if
+
+ ! Calculate the residence time and C14 storage capacity
+ if(use_c14)then
+ call inverse(matrix_c14transfer_acc(1:nvegcpool,1:nvegcpool),AKinvc(1:nvegcpool,1:nvegcpool),nvegcpool)
+ vegmatrixc14_rt(:) = -matmul(AKinvc(1:nvegcpool,1:nvegcpool),matrix_c14alloc_acc(1:nvegcpool))
+ end if
+
+ ! Calculate the residence time and N storage capacity
+ call inverse(matrix_ntransfer_acc(1:nvegnpool,1:nvegnpool),AKinvn(1:nvegnpool,1:nvegnpool),nvegnpool)
+ vegmatrixn_rt(:) = -matmul(AKinvn(1:nvegnpool,1:nvegnpool),matrix_nalloc_acc(1:nvegnpool))
+
+ do i=1,nvegcpool
+ if(vegmatrixc_rt(i) .lt. 0)vegmatrixc_rt(i) = epsi
+ end do
+ if(use_c13)then
+ do i=1,nvegcpool
+ if(vegmatrixc13_rt(i) .lt. 0)vegmatrixc13_rt(i) = epsi
+ end do
+ end if
+ if(use_c14)then
+ do i=1,nvegcpool
+ if(vegmatrixc14_rt(i) .lt. 0)vegmatrixc14_rt(i) = epsi
+ end do
+ end if
+ do i=1,nvegnpool
+ if(vegmatrixn_rt(i) .lt. 0)vegmatrixn_rt(i) = epsi
+ end do
+
+ call t_stopf('CN veg matrix-inv matrix operation')
+
+ call t_startf('CN veg matrix-finalize spinup')
+
+ if(spinup_matrixcn .and. .not. is_first_step_of_this_run_segment())then
+ deadstemc(p) = vegmatrixc_rt(ideadstem)
+ deadstemc_storage(p) = vegmatrixc_rt(ideadstem_st)
+ deadcrootc(p) = vegmatrixc_rt(ideadcroot)
+ deadcrootc_storage(p) = vegmatrixc_rt(ideadcroot_st)
+ if(use_c13)then
+ cs13_veg%deadstemc_patch(p) = vegmatrixc13_rt(ideadstem)
+ cs13_veg%deadstemc_storage_patch(p) = vegmatrixc13_rt(ideadstem_st)
+ cs13_veg%deadcrootc_patch(p) = vegmatrixc13_rt(ideadcroot)
+ cs13_veg%deadcrootc_storage_patch(p) = vegmatrixc13_rt(ideadcroot_st)
+ end if
+ if(use_c14)then
+ cs14_veg%deadstemc_patch(p) = vegmatrixc14_rt(ideadstem)
+ cs14_veg%deadstemc_storage_patch(p) = vegmatrixc14_rt(ideadstem_st)
+ cs14_veg%deadcrootc_patch(p) = vegmatrixc14_rt(ideadcroot)
+ cs14_veg%deadcrootc_storage_patch(p) = vegmatrixc14_rt(ideadcroot_st)
+ end if
+ deadstemn(p) = vegmatrixn_rt(ideadstem)
+ deadstemn_storage(p) = vegmatrixn_rt(ideadstem_st)
+ deadcrootn(p) = vegmatrixn_rt(ideadcroot)
+ deadcrootn_storage(p) = vegmatrixn_rt(ideadcroot_st)
+
+ if(iloop .eq. iloop_avg)then
+ leafc_SASUsave(p) = leafc_SASUsave(p) + leafc(p)
+ leafc_storage_SASUsave(p) = leafc_storage_SASUsave(p) + leafc_storage(p)
+ leafc_xfer_SASUsave(p) = leafc_xfer_SASUsave(p) + leafc_xfer(p)
+ frootc_SASUsave(p) = frootc_SASUsave(p) + frootc(p)
+ frootc_storage_SASUsave(p) = frootc_storage_SASUsave(p) + frootc_storage(p)
+ frootc_xfer_SASUsave(p) = frootc_xfer_SASUsave(p) + frootc_xfer(p)
+ livestemc_SASUsave(p) = livestemc_SASUsave(p) + livestemc(p)
+ livestemc_storage_SASUsave(p) = livestemc_storage_SASUsave(p) + livestemc_storage(p)
+ livestemc_xfer_SASUsave(p) = livestemc_xfer_SASUsave(p) + livestemc_xfer(p)
+ deadstemc_SASUsave(p) = deadstemc_SASUsave(p) + deadstemc(p)
+ deadstemc_storage_SASUsave(p) = deadstemc_storage_SASUsave(p) + deadstemc_storage(p)
+ deadstemc_xfer_SASUsave(p) = deadstemc_xfer_SASUsave(p) + deadstemc_xfer(p)
+ livecrootc_SASUsave(p) = livecrootc_SASUsave(p) + livecrootc(p)
+ livecrootc_storage_SASUsave(p) = livecrootc_storage_SASUsave(p) + livecrootc_storage(p)
+ livecrootc_xfer_SASUsave(p) = livecrootc_xfer_SASUsave(p) + livecrootc_xfer(p)
+ deadcrootc_SASUsave(p) = deadcrootc_SASUsave(p) + deadcrootc(p)
+ deadcrootc_storage_SASUsave(p) = deadcrootc_storage_SASUsave(p) + deadcrootc_storage(p)
+ deadcrootc_xfer_SASUsave(p) = deadcrootc_xfer_SASUsave(p) + deadcrootc_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ grainc_SASUsave(p) = grainc_SASUsave(p) + sum(reproductivec(p,:))
+ grainc_storage_SASUsave(p) = grainc_storage_SASUsave(p) + sum(reproductivec_storage(p,:))
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_SASUsave_patch(p) = cs13_veg%leafc_SASUsave_patch(p) + cs13_veg%leafc_patch(p)
+ cs13_veg%leafc_storage_SASUsave_patch(p) = cs13_veg%leafc_storage_SASUsave_patch(p) + cs13_veg%leafc_storage_patch(p)
+ cs13_veg%leafc_xfer_SASUsave_patch(p) = cs13_veg%leafc_xfer_SASUsave_patch(p) + cs13_veg%leafc_xfer_patch(p)
+ cs13_veg%frootc_SASUsave_patch(p) = cs13_veg%frootc_SASUsave_patch(p) + cs13_veg%frootc_patch(p)
+ cs13_veg%frootc_storage_SASUsave_patch(p) = cs13_veg%frootc_storage_SASUsave_patch(p) + cs13_veg%frootc_storage_patch(p)
+ cs13_veg%frootc_xfer_SASUsave_patch(p) = cs13_veg%frootc_xfer_SASUsave_patch(p) + cs13_veg%frootc_xfer_patch(p)
+ cs13_veg%livestemc_SASUsave_patch(p) = cs13_veg%livestemc_SASUsave_patch(p) + cs13_veg%livestemc_patch(p)
+ cs13_veg%livestemc_storage_SASUsave_patch(p) = cs13_veg%livestemc_storage_SASUsave_patch(p) + cs13_veg%livestemc_storage_patch(p)
+ cs13_veg%livestemc_xfer_SASUsave_patch(p) = cs13_veg%livestemc_xfer_SASUsave_patch(p) + cs13_veg%livestemc_xfer_patch(p)
+ cs13_veg%deadstemc_SASUsave_patch(p) = cs13_veg%deadstemc_SASUsave_patch(p) + cs13_veg%deadstemc_patch(p)
+ cs13_veg%deadstemc_storage_SASUsave_patch(p) = cs13_veg%deadstemc_storage_SASUsave_patch(p) + cs13_veg%deadstemc_storage_patch(p)
+ cs13_veg%deadstemc_xfer_SASUsave_patch(p) = cs13_veg%deadstemc_xfer_SASUsave_patch(p) + cs13_veg%deadstemc_xfer_patch(p)
+ cs13_veg%livecrootc_SASUsave_patch(p) = cs13_veg%livecrootc_SASUsave_patch(p) + cs13_veg%livecrootc_patch(p)
+ cs13_veg%livecrootc_storage_SASUsave_patch(p) = cs13_veg%livecrootc_storage_SASUsave_patch(p) + cs13_veg%livecrootc_storage_patch(p)
+ cs13_veg%livecrootc_xfer_SASUsave_patch(p) = cs13_veg%livecrootc_xfer_SASUsave_patch(p) + cs13_veg%livecrootc_xfer_patch(p)
+ cs13_veg%deadcrootc_SASUsave_patch(p) = cs13_veg%deadcrootc_SASUsave_patch(p) + cs13_veg%deadcrootc_patch(p)
+ cs13_veg%deadcrootc_storage_SASUsave_patch(p) = cs13_veg%deadcrootc_storage_SASUsave_patch(p) + cs13_veg%deadcrootc_storage_patch(p)
+ cs13_veg%deadcrootc_xfer_SASUsave_patch(p) = cs13_veg%deadcrootc_xfer_SASUsave_patch(p) + cs13_veg%deadcrootc_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%grainc_SASUsave_patch(p) = cs13_veg%grainc_SASUsave_patch(p) + cs13_veg%reproductivec_patch(p,irepr)
+ cs13_veg%grainc_storage_SASUsave_patch(p) = cs13_veg%grainc_storage_SASUsave_patch(p) + cs13_veg%reproductivec_storage_patch(p,irepr)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_SASUsave_patch(p) = cs14_veg%leafc_SASUsave_patch(p) + cs14_veg%leafc_patch(p)
+ cs14_veg%leafc_storage_SASUsave_patch(p) = cs14_veg%leafc_storage_SASUsave_patch(p) + cs14_veg%leafc_storage_patch(p)
+ cs14_veg%leafc_xfer_SASUsave_patch(p) = cs14_veg%leafc_xfer_SASUsave_patch(p) + cs14_veg%leafc_xfer_patch(p)
+ cs14_veg%frootc_SASUsave_patch(p) = cs14_veg%frootc_SASUsave_patch(p) + cs14_veg%frootc_patch(p)
+ cs14_veg%frootc_storage_SASUsave_patch(p) = cs14_veg%frootc_storage_SASUsave_patch(p) + cs14_veg%frootc_storage_patch(p)
+ cs14_veg%frootc_xfer_SASUsave_patch(p) = cs14_veg%frootc_xfer_SASUsave_patch(p) + cs14_veg%frootc_xfer_patch(p)
+ cs14_veg%livestemc_SASUsave_patch(p) = cs14_veg%livestemc_SASUsave_patch(p) + cs14_veg%livestemc_patch(p)
+ cs14_veg%livestemc_storage_SASUsave_patch(p) = cs14_veg%livestemc_storage_SASUsave_patch(p) + cs14_veg%livestemc_storage_patch(p)
+ cs14_veg%livestemc_xfer_SASUsave_patch(p) = cs14_veg%livestemc_xfer_SASUsave_patch(p) + cs14_veg%livestemc_xfer_patch(p)
+ cs14_veg%deadstemc_SASUsave_patch(p) = cs14_veg%deadstemc_SASUsave_patch(p) + cs14_veg%deadstemc_patch(p)
+ cs14_veg%deadstemc_storage_SASUsave_patch(p) = cs14_veg%deadstemc_storage_SASUsave_patch(p) + cs14_veg%deadstemc_storage_patch(p)
+ cs14_veg%deadstemc_xfer_SASUsave_patch(p) = cs14_veg%deadstemc_xfer_SASUsave_patch(p) + cs14_veg%deadstemc_xfer_patch(p)
+ cs14_veg%livecrootc_SASUsave_patch(p) = cs14_veg%livecrootc_SASUsave_patch(p) + cs14_veg%livecrootc_patch(p)
+ cs14_veg%livecrootc_storage_SASUsave_patch(p) = cs14_veg%livecrootc_storage_SASUsave_patch(p) + cs14_veg%livecrootc_storage_patch(p)
+ cs14_veg%livecrootc_xfer_SASUsave_patch(p) = cs14_veg%livecrootc_xfer_SASUsave_patch(p) + cs14_veg%livecrootc_xfer_patch(p)
+ cs14_veg%deadcrootc_SASUsave_patch(p) = cs14_veg%deadcrootc_SASUsave_patch(p) + cs14_veg%deadcrootc_patch(p)
+ cs14_veg%deadcrootc_storage_SASUsave_patch(p) = cs14_veg%deadcrootc_storage_SASUsave_patch(p) + cs14_veg%deadcrootc_storage_patch(p)
+ cs14_veg%deadcrootc_xfer_SASUsave_patch(p) = cs14_veg%deadcrootc_xfer_SASUsave_patch(p) + cs14_veg%deadcrootc_xfer_patch(p)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%grainc_SASUsave_patch(p) = cs14_veg%grainc_SASUsave_patch(p) + cs14_veg%reproductivec_patch(p,irepr)
+ cs14_veg%grainc_storage_SASUsave_patch(p) = cs14_veg%grainc_storage_SASUsave_patch(p) + cs14_veg%reproductivec_storage_patch(p,irepr)
+ end if
+ end if
+ leafn_SASUsave(p) = leafn_SASUsave(p) + leafn(p)
+ leafn_storage_SASUsave(p) = leafn_storage_SASUsave(p) + leafn_storage(p)
+ leafn_xfer_SASUsave(p) = leafn_xfer_SASUsave(p) + leafn_xfer(p)
+ frootn_SASUsave(p) = frootn_SASUsave(p) + frootn(p)
+ frootn_storage_SASUsave(p) = frootn_storage_SASUsave(p) + frootn_storage(p)
+ frootn_xfer_SASUsave(p) = frootn_xfer_SASUsave(p) + frootn_xfer(p)
+ livestemn_SASUsave(p) = livestemn_SASUsave(p) + livestemn(p)
+ livestemn_storage_SASUsave(p) = livestemn_storage_SASUsave(p) + livestemn_storage(p)
+ livestemn_xfer_SASUsave(p) = livestemn_xfer_SASUsave(p) + livestemn_xfer(p)
+ deadstemn_SASUsave(p) = deadstemn_SASUsave(p) + deadstemn(p)
+ deadstemn_storage_SASUsave(p) = deadstemn_storage_SASUsave(p) + deadstemn_storage(p)
+ deadstemn_xfer_SASUsave(p) = deadstemn_xfer_SASUsave(p) + deadstemn_xfer(p)
+ livecrootn_SASUsave(p) = livecrootn_SASUsave(p) + livecrootn(p)
+ livecrootn_storage_SASUsave(p) = livecrootn_storage_SASUsave(p) + livecrootn_storage(p)
+ livecrootn_xfer_SASUsave(p) = livecrootn_xfer_SASUsave(p) + livecrootn_xfer(p)
+ deadcrootn_SASUsave(p) = deadcrootn_SASUsave(p) + deadcrootn(p)
+ deadcrootn_storage_SASUsave(p) = deadcrootn_storage_SASUsave(p) + deadcrootn_storage(p)
+ deadcrootn_xfer_SASUsave(p) = deadcrootn_xfer_SASUsave(p) + deadcrootn_xfer(p)
+ if(ivt(p) >= npcropmin)then
+ grainn_SASUsave(p) = grainn_SASUsave(p) + reproductiven(p,irepr)
+ end if
+ if(iyr .eq. nyr_forcing)then
+ leafc(p) = leafc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafc_storage(p) = leafc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafc_xfer(p) = leafc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc(p) = frootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc_storage(p) = frootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootc_xfer(p) = frootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc(p) = livestemc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc_storage(p) = livestemc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemc_xfer(p) = livestemc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc(p) = deadstemc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc_storage(p) = deadstemc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemc_xfer(p) = deadstemc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc(p) = livecrootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc_storage(p) = livecrootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootc_xfer(p) = livecrootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc(p) = deadcrootc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc_storage(p) = deadcrootc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootc_xfer(p) = deadcrootc_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ reproductivec(p,:) = grainc_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ reproductivec_storage(p,:) = grainc_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_patch(p) = cs13_veg%leafc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%leafc_storage_patch(p) = cs13_veg%leafc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%leafc_xfer_patch(p) = cs13_veg%leafc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_patch(p) = cs13_veg%frootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_storage_patch(p) = cs13_veg%frootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%frootc_xfer_patch(p) = cs13_veg%frootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_patch(p) = cs13_veg%livestemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_storage_patch(p) = cs13_veg%livestemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livestemc_xfer_patch(p) = cs13_veg%livestemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_patch(p) = cs13_veg%deadstemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_storage_patch(p) = cs13_veg%deadstemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadstemc_xfer_patch(p) = cs13_veg%deadstemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_patch(p) = cs13_veg%livecrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_storage_patch(p) = cs13_veg%livecrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%livecrootc_xfer_patch(p) = cs13_veg%livecrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_patch(p) = cs13_veg%deadcrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_storage_patch(p) = cs13_veg%deadcrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%deadcrootc_xfer_patch(p) = cs13_veg%deadcrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%reproductivec_patch(p,:) = cs13_veg%grainc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs13_veg%reproductivec_storage_patch(p,:) = cs13_veg%grainc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_patch(p) = cs14_veg%leafc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%leafc_storage_patch(p) = cs14_veg%leafc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%leafc_xfer_patch(p) = cs14_veg%leafc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_patch(p) = cs14_veg%frootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_storage_patch(p) = cs14_veg%frootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%frootc_xfer_patch(p) = cs14_veg%frootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_patch(p) = cs14_veg%livestemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_storage_patch(p) = cs14_veg%livestemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livestemc_xfer_patch(p) = cs14_veg%livestemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_patch(p) = cs14_veg%deadstemc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_storage_patch(p) = cs14_veg%deadstemc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadstemc_xfer_patch(p) = cs14_veg%deadstemc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_patch(p) = cs14_veg%livecrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_storage_patch(p) = cs14_veg%livecrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%livecrootc_xfer_patch(p) = cs14_veg%livecrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_patch(p) = cs14_veg%deadcrootc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_storage_patch(p) = cs14_veg%deadcrootc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%deadcrootc_xfer_patch(p) = cs14_veg%deadcrootc_xfer_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%reproductivec_patch(p,:) = cs14_veg%grainc_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ cs14_veg%reproductivec_storage_patch(p,:) = cs14_veg%grainc_storage_SASUsave_patch(p) / (nyr_forcing/nyr_SASU)
+ end if
+ end if
+ leafn(p) = leafn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafn_storage(p) = leafn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ leafn_xfer(p) = leafn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn(p) = frootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn_storage(p) = frootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ frootn_xfer(p) = frootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn(p) = livestemn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn_storage(p) = livestemn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livestemn_xfer(p) = livestemn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn(p) = deadstemn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn_storage(p) = deadstemn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadstemn_xfer(p) = deadstemn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn(p) = livecrootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn_storage(p) = livecrootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ livecrootn_xfer(p) = livecrootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn(p) = deadcrootn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn_storage(p) = deadcrootn_storage_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ deadcrootn_xfer(p) = deadcrootn_xfer_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ if(ivt(p) >= npcropmin)then
+ reproductiven(p,:) = grainn_SASUsave(p) / (nyr_forcing/nyr_SASU)
+ end if
+ leafc_SASUsave(p) = 0
+ leafc_storage_SASUsave(p) = 0
+ leafc_xfer_SASUsave(p) = 0
+ frootc_SASUsave(p) = 0
+ frootc_storage_SASUsave(p) = 0
+ frootc_xfer_SASUsave(p) = 0
+ livestemc_SASUsave(p) = 0
+ livestemc_storage_SASUsave(p) = 0
+ livestemc_xfer_SASUsave(p) = 0
+ deadstemc_SASUsave(p) = 0
+ deadstemc_storage_SASUsave(p) = 0
+ deadstemc_xfer_SASUsave(p) = 0
+ livecrootc_SASUsave(p) = 0
+ livecrootc_storage_SASUsave(p) = 0
+ livecrootc_xfer_SASUsave(p) = 0
+ deadcrootc_SASUsave(p) = 0
+ deadcrootc_storage_SASUsave(p) = 0
+ deadcrootc_xfer_SASUsave(p) = 0
+ if(ivt(p) >= npcropmin)then
+ grainc_SASUsave(p) = 0
+ grainc_storage_SASUsave(p) = 0
+ end if
+ if(use_c13)then
+ cs13_veg%leafc_SASUsave_patch(p) = 0
+ cs13_veg%leafc_storage_SASUsave_patch(p) = 0
+ cs13_veg%leafc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%frootc_SASUsave_patch(p) = 0
+ cs13_veg%frootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%frootc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_storage_SASUsave_patch(p) = 0
+ cs13_veg%livestemc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_storage_SASUsave_patch(p) = 0
+ cs13_veg%deadstemc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%livecrootc_xfer_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_storage_SASUsave_patch(p) = 0
+ cs13_veg%deadcrootc_xfer_SASUsave_patch(p) = 0
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%grainc_SASUsave_patch(p) = 0
+ cs13_veg%grainc_storage_SASUsave_patch(p) = 0
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%leafc_SASUsave_patch(p) = 0
+ cs14_veg%leafc_storage_SASUsave_patch(p) = 0
+ cs14_veg%leafc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%frootc_SASUsave_patch(p) = 0
+ cs14_veg%frootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%frootc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_storage_SASUsave_patch(p) = 0
+ cs14_veg%livestemc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_storage_SASUsave_patch(p) = 0
+ cs14_veg%deadstemc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%livecrootc_xfer_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_storage_SASUsave_patch(p) = 0
+ cs14_veg%deadcrootc_xfer_SASUsave_patch(p) = 0
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%grainc_SASUsave_patch(p) = 0
+ cs14_veg%grainc_storage_SASUsave_patch(p) = 0
+ end if
+ end if
+ leafn_SASUsave(p) = 0
+ leafn_storage_SASUsave(p) = 0
+ leafn_xfer_SASUsave(p) = 0
+ frootn_SASUsave(p) = 0
+ frootn_storage_SASUsave(p) = 0
+ frootn_xfer_SASUsave(p) = 0
+ livestemn_SASUsave(p) = 0
+ livestemn_storage_SASUsave(p) = 0
+ livestemn_xfer_SASUsave(p) = 0
+ deadstemn_SASUsave(p) = 0
+ deadstemn_storage_SASUsave(p) = 0
+ deadstemn_xfer_SASUsave(p) = 0
+ livecrootn_SASUsave(p) = 0
+ livecrootn_storage_SASUsave(p) = 0
+ livecrootn_xfer_SASUsave(p) = 0
+ deadcrootn_SASUsave(p) = 0
+ deadcrootn_storage_SASUsave(p) = 0
+ deadcrootn_xfer_SASUsave(p) = 0
+ if(ivt(p) >= npcropmin)then
+ grainn_SASUsave(p) = 0
+ end if
+ end if
+ end if
+ call update_DA_nstep()
+ end if
+
+ ! Save C storage capacity from temporary variables to module variables
+ if(hist_wrt_matrixcn_diag)then
+ matrix_cap_leafc(p) = vegmatrixc_rt(ileaf)
+ matrix_cap_leafc_storage(p) = vegmatrixc_rt(ileaf_st)
+ matrix_cap_leafc_xfer(p) = vegmatrixc_rt(ileaf_xf)
+ matrix_cap_frootc(p) = vegmatrixc_rt(ifroot)
+ matrix_cap_frootc_storage(p) = vegmatrixc_rt(ifroot_st)
+ matrix_cap_frootc_xfer(p) = vegmatrixc_rt(ifroot_xf)
+ matrix_cap_livestemc(p) = vegmatrixc_rt(ilivestem)
+ matrix_cap_livestemc_storage(p) = vegmatrixc_rt(ilivestem_st)
+ matrix_cap_livestemc_xfer(p) = vegmatrixc_rt(ilivestem_xf)
+ matrix_cap_deadstemc(p) = vegmatrixc_rt(ideadstem)
+ matrix_cap_deadstemc_storage(p) = vegmatrixc_rt(ideadstem_st)
+ matrix_cap_deadstemc_xfer(p) = vegmatrixc_rt(ideadstem_xf)
+ matrix_cap_livecrootc(p) = vegmatrixc_rt(ilivecroot)
+ matrix_cap_livecrootc_storage(p) = vegmatrixc_rt(ilivecroot_st)
+ matrix_cap_livecrootc_xfer(p) = vegmatrixc_rt(ilivecroot_xf)
+ matrix_cap_deadcrootc(p) = vegmatrixc_rt(ideadcroot)
+ matrix_cap_deadcrootc_storage(p) = vegmatrixc_rt(ideadcroot_st)
+ matrix_cap_deadcrootc_xfer(p) = vegmatrixc_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ matrix_cap_reproc(p) = vegmatrixc_rt(igrain)
+ matrix_cap_reproc_storage(p) = vegmatrixc_rt(igrain_st)
+ matrix_cap_reproc_xfer(p) = vegmatrixc_rt(igrain_xf)
+ end if
+ if(use_c13)then
+ cs13_veg%matrix_cap_leafc_patch(p) = vegmatrixc13_rt(ileaf)
+ cs13_veg%matrix_cap_leafc_storage_patch(p) = vegmatrixc13_rt(ileaf_st)
+ cs13_veg%matrix_cap_leafc_xfer_patch(p) = vegmatrixc13_rt(ileaf_xf)
+ cs13_veg%matrix_cap_frootc_patch(p) = vegmatrixc13_rt(ifroot)
+ cs13_veg%matrix_cap_frootc_storage_patch(p) = vegmatrixc13_rt(ifroot_st)
+ cs13_veg%matrix_cap_frootc_xfer_patch(p) = vegmatrixc13_rt(ifroot_xf)
+ cs13_veg%matrix_cap_livestemc_patch(p) = vegmatrixc13_rt(ilivestem)
+ cs13_veg%matrix_cap_livestemc_storage_patch(p) = vegmatrixc13_rt(ilivestem_st)
+ cs13_veg%matrix_cap_livestemc_xfer_patch(p) = vegmatrixc13_rt(ilivestem_xf)
+ cs13_veg%matrix_cap_deadstemc_patch(p) = vegmatrixc13_rt(ideadstem)
+ cs13_veg%matrix_cap_deadstemc_storage_patch(p) = vegmatrixc13_rt(ideadstem_st)
+ cs13_veg%matrix_cap_deadstemc_xfer_patch(p) = vegmatrixc13_rt(ideadstem_xf)
+ cs13_veg%matrix_cap_livecrootc_patch(p) = vegmatrixc13_rt(ilivecroot)
+ cs13_veg%matrix_cap_livecrootc_storage_patch(p) = vegmatrixc13_rt(ilivecroot_st)
+ cs13_veg%matrix_cap_livecrootc_xfer_patch(p) = vegmatrixc13_rt(ilivecroot_xf)
+ cs13_veg%matrix_cap_deadcrootc_patch(p) = vegmatrixc13_rt(ideadcroot)
+ cs13_veg%matrix_cap_deadcrootc_storage_patch(p) = vegmatrixc13_rt(ideadcroot_st)
+ cs13_veg%matrix_cap_deadcrootc_xfer_patch(p) = vegmatrixc13_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_cap_reproc_patch(p) = vegmatrixc13_rt(igrain)
+ cs13_veg%matrix_cap_reproc_storage_patch(p) = vegmatrixc13_rt(igrain_st)
+ cs13_veg%matrix_cap_reproc_xfer_patch(p) = vegmatrixc13_rt(igrain_xf)
+ end if
+ end if
+ if(use_c14)then
+ cs14_veg%matrix_cap_leafc_patch(p) = vegmatrixc14_rt(ileaf)
+ cs14_veg%matrix_cap_leafc_storage_patch(p) = vegmatrixc14_rt(ileaf_st)
+ cs14_veg%matrix_cap_leafc_xfer_patch(p) = vegmatrixc14_rt(ileaf_xf)
+ cs14_veg%matrix_cap_frootc_patch(p) = vegmatrixc14_rt(ifroot)
+ cs14_veg%matrix_cap_frootc_storage_patch(p) = vegmatrixc14_rt(ifroot_st)
+ cs14_veg%matrix_cap_frootc_xfer_patch(p) = vegmatrixc14_rt(ifroot_xf)
+ cs14_veg%matrix_cap_livestemc_patch(p) = vegmatrixc14_rt(ilivestem)
+ cs14_veg%matrix_cap_livestemc_storage_patch(p) = vegmatrixc14_rt(ilivestem_st)
+ cs14_veg%matrix_cap_livestemc_xfer_patch(p) = vegmatrixc14_rt(ilivestem_xf)
+ cs14_veg%matrix_cap_deadstemc_patch(p) = vegmatrixc14_rt(ideadstem)
+ cs14_veg%matrix_cap_deadstemc_storage_patch(p) = vegmatrixc14_rt(ideadstem_st)
+ cs14_veg%matrix_cap_deadstemc_xfer_patch(p) = vegmatrixc14_rt(ideadstem_xf)
+ cs14_veg%matrix_cap_livecrootc_patch(p) = vegmatrixc14_rt(ilivecroot)
+ cs14_veg%matrix_cap_livecrootc_storage_patch(p) = vegmatrixc14_rt(ilivecroot_st)
+ cs14_veg%matrix_cap_livecrootc_xfer_patch(p) = vegmatrixc14_rt(ilivecroot_xf)
+ cs14_veg%matrix_cap_deadcrootc_patch(p) = vegmatrixc14_rt(ideadcroot)
+ cs14_veg%matrix_cap_deadcrootc_storage_patch(p) = vegmatrixc14_rt(ideadcroot_st)
+ cs14_veg%matrix_cap_deadcrootc_xfer_patch(p) = vegmatrixc14_rt(ideadcroot_xf)
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_cap_reproc_patch(p) = vegmatrixc14_rt(igrain)
+ cs14_veg%matrix_cap_reproc_storage_patch(p) = vegmatrixc14_rt(igrain_st)
+ cs14_veg%matrix_cap_reproc_xfer_patch(p) = vegmatrixc14_rt(igrain_xf)
+ end if
+ end if
+ matrix_cap_leafn(p) = vegmatrixn_rt(ileaf)
+ matrix_cap_leafn_storage(p) = vegmatrixn_rt(ileaf_st)
+ matrix_cap_leafn_xfer(p) = vegmatrixn_rt(ileaf_xf)
+ matrix_cap_frootn(p) = vegmatrixn_rt(ifroot)
+ matrix_cap_frootn_storage(p) = vegmatrixn_rt(ifroot_st)
+ matrix_cap_frootn_xfer(p) = vegmatrixn_rt(ifroot_xf)
+ matrix_cap_livestemn(p) = vegmatrixn_rt(ilivestem)
+ matrix_cap_livestemn_storage(p) = vegmatrixn_rt(ilivestem_st)
+ matrix_cap_livestemn_xfer(p) = vegmatrixn_rt(ilivestem_xf)
+ matrix_cap_deadstemn(p) = vegmatrixn_rt(ideadstem)
+ matrix_cap_deadstemn_storage(p) = vegmatrixn_rt(ideadstem_st)
+ matrix_cap_deadstemn_xfer(p) = vegmatrixn_rt(ideadstem_xf)
+ matrix_cap_livecrootn(p) = vegmatrixn_rt(ilivecroot)
+ matrix_cap_livecrootn_storage(p) = vegmatrixn_rt(ilivecroot_st)
+ matrix_cap_livecrootn_xfer(p) = vegmatrixn_rt(ilivecroot_xf)
+ matrix_cap_deadcrootn(p) = vegmatrixn_rt(ideadcroot)
+ matrix_cap_deadcrootn_storage(p) = vegmatrixn_rt(ideadcroot_st)
+ if(ivt(p) >= npcropmin)then
+ matrix_cap_repron(p) = vegmatrixn_rt(igrain)
+ matrix_cap_repron_storage(p) = vegmatrixn_rt(igrain_st)
+ matrix_cap_repron_xfer(p) = vegmatrixn_rt(igrain_xf)
+ end if
+ end if
+
+ ! Reset accumulated variables to 0 at end of each year after calculating capacity
+ matrix_calloc_leaf_acc(p) = 0._r8
+ matrix_calloc_leafst_acc(p) = 0._r8
+ matrix_calloc_froot_acc(p) = 0._r8
+ matrix_calloc_frootst_acc(p) = 0._r8
+ matrix_calloc_livestem_acc(p) = 0._r8
+ matrix_calloc_livestemst_acc(p) = 0._r8
+ matrix_calloc_deadstem_acc(p) = 0._r8
+ matrix_calloc_deadstemst_acc(p) = 0._r8
+ matrix_calloc_livecroot_acc(p) = 0._r8
+ matrix_calloc_livecrootst_acc(p) = 0._r8
+ matrix_calloc_deadcroot_acc(p) = 0._r8
+ matrix_calloc_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_calloc_grain_acc(p) = 0._r8
+ matrix_calloc_grainst_acc(p) = 0._r8
+ end if
+
+ matrix_ctransfer_leafst_to_leafxf_acc(p) = 0._r8
+ matrix_ctransfer_leafxf_to_leaf_acc(p) = 0._r8
+ matrix_ctransfer_frootst_to_frootxf_acc(p) = 0._r8
+ matrix_ctransfer_frootxf_to_froot_acc(p) = 0._r8
+ matrix_ctransfer_livestemst_to_livestemxf_acc(p) = 0._r8
+ matrix_ctransfer_livestemxf_to_livestem_acc(p) = 0._r8
+ matrix_ctransfer_deadstemst_to_deadstemxf_acc(p) = 0._r8
+ matrix_ctransfer_deadstemxf_to_deadstem_acc(p) = 0._r8
+ matrix_ctransfer_livecrootst_to_livecrootxf_acc(p) = 0._r8
+ matrix_ctransfer_livecrootxf_to_livecroot_acc(p) = 0._r8
+ matrix_ctransfer_deadcrootst_to_deadcrootxf_acc(p) = 0._r8
+ matrix_ctransfer_deadcrootxf_to_deadcroot_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ctransfer_grainst_to_grainxf_acc(p) = 0._r8
+ matrix_ctransfer_grainxf_to_grain_acc(p) = 0._r8
+ end if
+ matrix_ctransfer_livestem_to_deadstem_acc(p) = 0._r8
+ matrix_ctransfer_livecroot_to_deadcroot_acc(p) = 0._r8
+
+ matrix_cturnover_leaf_acc(p) = 0._r8
+ matrix_cturnover_leafst_acc(p) = 0._r8
+ matrix_cturnover_leafxf_acc(p) = 0._r8
+ matrix_cturnover_froot_acc(p) = 0._r8
+ matrix_cturnover_frootst_acc(p) = 0._r8
+ matrix_cturnover_frootxf_acc(p) = 0._r8
+ matrix_cturnover_livestem_acc(p) = 0._r8
+ matrix_cturnover_livestemst_acc(p) = 0._r8
+ matrix_cturnover_livestemxf_acc(p) = 0._r8
+ matrix_cturnover_deadstem_acc(p) = 0._r8
+ matrix_cturnover_deadstemst_acc(p) = 0._r8
+ matrix_cturnover_deadstemxf_acc(p) = 0._r8
+ matrix_cturnover_livecroot_acc(p) = 0._r8
+ matrix_cturnover_livecrootst_acc(p) = 0._r8
+ matrix_cturnover_livecrootxf_acc(p) = 0._r8
+ matrix_cturnover_deadcroot_acc(p) = 0._r8
+ matrix_cturnover_deadcrootst_acc(p) = 0._r8
+ matrix_cturnover_deadcrootxf_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_cturnover_grain_acc(p) = 0._r8
+ matrix_cturnover_grainst_acc(p) = 0._r8
+ matrix_cturnover_grainxf_acc(p) = 0._r8
+ end if
+
+ if(use_c13)then
+ cs13_veg%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_calloc_grain_acc_patch(p) = 0._r8
+ cs13_veg%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ end if
+
+ cs13_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ end if
+ cs13_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ cs13_veg%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs13_veg%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ cs13_veg%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
+ end if
+ end if
+
+ if(use_c14)then
+ cs14_veg%matrix_calloc_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_leafst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_frootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livestemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadstemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_livecrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadcroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_deadcrootst_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_calloc_grain_acc_patch(p) = 0._r8
+ cs14_veg%matrix_calloc_grainst_acc_patch(p) = 0._r8
+ end if
+
+ cs14_veg%matrix_ctransfer_leafst_to_leafxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_leafxf_to_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_frootst_to_frootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_frootxf_to_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livestemst_to_livestemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livestemxf_to_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadstemst_to_deadstemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadstemxf_to_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecrootst_to_livecrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecrootxf_to_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadcrootst_to_deadcrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_deadcrootxf_to_deadcroot_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_ctransfer_grainst_to_grainxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_grainxf_to_grain_acc_patch(p) = 0._r8
+ end if
+ cs14_veg%matrix_ctransfer_livestem_to_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_ctransfer_livecroot_to_deadcroot_acc_patch(p) = 0._r8
+
+ cs14_veg%matrix_cturnover_leaf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_leafst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_leafxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_froot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_frootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_frootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livestemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstem_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstemst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadstemxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_livecrootxf_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcroot_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcrootst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_deadcrootxf_acc_patch(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ cs14_veg%matrix_cturnover_grain_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_grainst_acc_patch(p) = 0._r8
+ cs14_veg%matrix_cturnover_grainxf_acc_patch(p) = 0._r8
+ end if
+ end if
+
+ matrix_nalloc_leaf_acc(p) = 0._r8
+ matrix_nalloc_leafst_acc(p) = 0._r8
+ matrix_nalloc_froot_acc(p) = 0._r8
+ matrix_nalloc_frootst_acc(p) = 0._r8
+ matrix_nalloc_livestem_acc(p) = 0._r8
+ matrix_nalloc_livestemst_acc(p) = 0._r8
+ matrix_nalloc_deadstem_acc(p) = 0._r8
+ matrix_nalloc_deadstemst_acc(p) = 0._r8
+ matrix_nalloc_livecroot_acc(p) = 0._r8
+ matrix_nalloc_livecrootst_acc(p) = 0._r8
+ matrix_nalloc_deadcroot_acc(p) = 0._r8
+ matrix_nalloc_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_nalloc_grain_acc(p) = 0._r8
+ matrix_nalloc_grainst_acc(p) = 0._r8
+ end if
+
+ matrix_ntransfer_leafst_to_leafxf_acc(p) = 0._r8
+ matrix_ntransfer_leafxf_to_leaf_acc(p) = 0._r8
+ matrix_ntransfer_frootst_to_frootxf_acc(p) = 0._r8
+ matrix_ntransfer_frootxf_to_froot_acc(p) = 0._r8
+ matrix_ntransfer_livestemst_to_livestemxf_acc(p) = 0._r8
+ matrix_ntransfer_livestemxf_to_livestem_acc(p) = 0._r8
+ matrix_ntransfer_deadstemst_to_deadstemxf_acc(p) = 0._r8
+ matrix_ntransfer_deadstemxf_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_livecrootst_to_livecrootxf_acc(p) = 0._r8
+ matrix_ntransfer_livecrootxf_to_livecroot_acc(p) = 0._r8
+ matrix_ntransfer_deadcrootst_to_deadcrootxf_acc(p) = 0._r8
+ matrix_ntransfer_deadcrootxf_to_deadcroot_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_grainst_to_grainxf_acc(p) = 0._r8
+ matrix_ntransfer_grainxf_to_grain_acc(p) = 0._r8
+ end if
+ matrix_ntransfer_livestem_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_livecroot_to_deadcroot_acc(p) = 0._r8
+
+ matrix_ntransfer_retransn_to_leaf_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_leafst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_froot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_frootst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livestem_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livestemst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadstem_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadstemst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livecroot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_livecrootst_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadcroot_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_deadcrootst_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_ntransfer_retransn_to_grain_acc(p) = 0._r8
+ matrix_ntransfer_retransn_to_grainst_acc(p) = 0._r8
+ end if
+ matrix_ntransfer_leaf_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_froot_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_livestem_to_retransn_acc(p) = 0._r8
+ matrix_ntransfer_livecroot_to_retransn_acc(p) = 0._r8
+
+ matrix_nturnover_leaf_acc(p) = 0._r8
+ matrix_nturnover_leafst_acc(p) = 0._r8
+ matrix_nturnover_leafxf_acc(p) = 0._r8
+ matrix_nturnover_froot_acc(p) = 0._r8
+ matrix_nturnover_frootst_acc(p) = 0._r8
+ matrix_nturnover_frootxf_acc(p) = 0._r8
+ matrix_nturnover_livestem_acc(p) = 0._r8
+ matrix_nturnover_livestemst_acc(p) = 0._r8
+ matrix_nturnover_livestemxf_acc(p) = 0._r8
+ matrix_nturnover_deadstem_acc(p) = 0._r8
+ matrix_nturnover_deadstemst_acc(p) = 0._r8
+ matrix_nturnover_deadstemxf_acc(p) = 0._r8
+ matrix_nturnover_livecroot_acc(p) = 0._r8
+ matrix_nturnover_livecrootst_acc(p) = 0._r8
+ matrix_nturnover_livecrootxf_acc(p) = 0._r8
+ matrix_nturnover_deadcroot_acc(p) = 0._r8
+ matrix_nturnover_deadcrootst_acc(p) = 0._r8
+ matrix_nturnover_deadcrootxf_acc(p) = 0._r8
+ if(ivt(p) >= npcropmin)then
+ matrix_nturnover_grain_acc(p) = 0._r8
+ matrix_nturnover_grainst_acc(p) = 0._r8
+ matrix_nturnover_grainxf_acc(p) = 0._r8
+ end if
+ matrix_nturnover_retransn_acc(p) = 0._r8
+ matrix_calloc_acc(:) = 0._r8
+ matrix_ctransfer_acc(:,:) = 0._r8
+ matrix_nalloc_acc(:) = 0._r8
+ matrix_ntransfer_acc(:,:) = 0._r8
+
+ call t_stopf('CN veg matrix-finalize spinup')
+ end do
+ if(iloop .eq. iloop_avg .and. iyr .eq. nyr_forcing)iloop = 0
+ if(iyr .eq. nyr_forcing)iyr=0
+ end if
+ end if
+
+ call vegmatrixc_input%ReleaseV()
+ if ( use_c13 )then
+ call vegmatrixc13_input%ReleaseV()
+ end if
+ if ( use_c14 )then
+ call vegmatrixc14_input%ReleaseV()
+ end if
+ call vegmatrixn_input%ReleaseV()
+
+ end associate td
+ end associate sd
+ end associate od
+ end associate fr
+ end subroutine CNVegMatrix
+
+ function matrix_update_phc(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_phc
+
+ associate( &
+ matrix_phtransfer => cnveg_carbonflux_inst%matrix_phtransfer_patch , &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ doner_phc => cnveg_carbonflux_inst%matrix_phtransfer_doner_patch&
+ )
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_phc(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_phc = max(0._r8,(1._r8 - matrix_phturnover(p,doner_phc(itransfer))) / dt)
+ else
+ matrix_update_phc = rate
+ end if
+ else
+ matrix_update_phc = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_phturnover(p,doner_phc(itransfer)) = matrix_phturnover(p,doner_phc(itransfer)) + matrix_update_phc * dt
+ matrix_phtransfer(p,itransfer) = matrix_phtransfer(p,itransfer) + matrix_update_phc
+ else
+ matrix_phturnover(p,doner_phc(itransfer)) = matrix_phturnover(p,doner_phc(itransfer)) - matrix_phtransfer(p,itransfer) * dt + matrix_update_phc * dt
+ matrix_phtransfer(p,itransfer) = matrix_update_phc
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_phc
+
+ function matrix_update_gmc(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_gmc
+
+ associate( &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ matrix_gmtransfer => cnveg_carbonflux_inst%matrix_gmtransfer_patch , &
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , &
+ doner_gmc => cnveg_carbonflux_inst%matrix_gmtransfer_doner_patch & ! Input: [integer (:)] Doners of gap mortality related C transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_gmc(itransfer)) + matrix_gmturnover(p,doner_gmc(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_gmc = max(0._r8,(1._r8 - matrix_phturnover(p,doner_gmc(itransfer)) - matrix_gmturnover(p,doner_gmc(itransfer))) / dt)
+ else
+ matrix_update_gmc = rate
+ end if
+ else
+ matrix_update_gmc = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_gmturnover(p,doner_gmc(itransfer)) = matrix_gmturnover(p,doner_gmc(itransfer)) + matrix_update_gmc * dt
+ matrix_gmtransfer(p,itransfer) = matrix_gmtransfer(p,itransfer) + matrix_update_gmc
+ else
+ matrix_gmturnover(p,doner_gmc(itransfer)) = matrix_gmturnover(p,doner_gmc(itransfer)) - matrix_gmtransfer(p,itransfer) * dt + matrix_update_gmc * dt
+ matrix_gmtransfer(p,itransfer) = matrix_update_gmc
+ end if
+ return
+ end associate
+
+ end function matrix_update_gmc
+
+
+ function matrix_update_fic(p,itransfer,rate,dt,cnveg_carbonflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_fic
+
+ associate( &
+ matrix_phturnover => cnveg_carbonflux_inst%matrix_phturnover_patch , &
+ matrix_gmturnover => cnveg_carbonflux_inst%matrix_gmturnover_patch , &
+ matrix_fitransfer => cnveg_carbonflux_inst%matrix_fitransfer_patch , &
+ matrix_fiturnover => cnveg_carbonflux_inst%matrix_fiturnover_patch , &
+ doner_fic => cnveg_carbonflux_inst%matrix_fitransfer_doner_patch &
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_phturnover(p,doner_fic(itransfer)) + matrix_gmturnover(p,doner_fic(itransfer)) &
+ + matrix_fiturnover(p,doner_fic(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_fic = max(0._r8,(1._r8 - matrix_phturnover(p,doner_fic(itransfer)) &
+ - matrix_gmturnover(p,doner_fic(itransfer)) - matrix_fiturnover(p,doner_fic(itransfer))) / dt)
+ else
+ matrix_update_fic = rate
+ end if
+ else
+ matrix_update_fic = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_fiturnover(p,doner_fic(itransfer)) = matrix_fiturnover(p,doner_fic(itransfer)) + matrix_update_fic * dt
+ matrix_fitransfer(p,itransfer) = matrix_fitransfer(p,itransfer) + matrix_update_fic
+ else
+ matrix_fiturnover(p,doner_fic(itransfer)) = matrix_fiturnover(p,doner_fic(itransfer)) - matrix_fitransfer(p,itransfer) * dt + matrix_update_fic * dt
+ matrix_fitransfer(p,itransfer) = matrix_update_fic
+ end if
+
+ return
+ end associate
+
+end function matrix_update_fic
+
+ function matrix_update_phn(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer,intent(in) :: p
+ integer,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_phn
+
+ associate( &
+ matrix_nphtransfer => cnveg_nitrogenflux_inst%matrix_nphtransfer_patch , &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ doner_phn => cnveg_nitrogenflux_inst%matrix_nphtransfer_doner_patch & ! Input: [integer (:)] Doners of phenology related N transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_phn(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_phn = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_phn(itransfer))) / dt)
+ else
+ matrix_update_phn = rate
+ end if
+ else
+ matrix_update_phn = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_nphturnover(p,doner_phn(itransfer)) = matrix_nphturnover(p,doner_phn(itransfer)) + matrix_update_phn * dt
+ matrix_nphtransfer(p,itransfer) = matrix_nphtransfer(p,itransfer) + matrix_update_phn
+ else
+ matrix_nphturnover(p,doner_phn(itransfer)) = matrix_nphturnover(p,doner_phn(itransfer)) - matrix_nphtransfer(p,itransfer) * dt + matrix_update_phn * dt
+ matrix_nphtransfer(p,itransfer) = matrix_update_phn
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_phn
+
+ function matrix_update_gmn(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_gmn
+
+ associate( &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ matrix_ngmtransfer => cnveg_nitrogenflux_inst%matrix_ngmtransfer_patch , &
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , &
+ doner_gmn => cnveg_nitrogenflux_inst%matrix_ngmtransfer_doner_patch & ! Input: [integer (:)] Doners of gap mortality related N transfer
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_gmn(itransfer)) + matrix_ngmturnover(p,doner_gmn(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_gmn = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_gmn(itransfer)) - matrix_ngmturnover(p,doner_gmn(itransfer))) / dt)
+ else
+ matrix_update_gmn = rate
+ end if
+ else
+ matrix_update_gmn = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_ngmturnover(p,doner_gmn(itransfer)) = matrix_ngmturnover(p,doner_gmn(itransfer)) + matrix_update_gmn * dt
+ matrix_ngmtransfer(p,itransfer) = matrix_ngmtransfer(p,itransfer) + matrix_update_gmn
+ else
+ matrix_ngmturnover(p,doner_gmn(itransfer)) = matrix_ngmturnover(p,doner_gmn(itransfer)) - matrix_ngmtransfer(p,itransfer) * dt + matrix_update_gmn * dt
+ matrix_ngmtransfer(p,itransfer) = matrix_update_gmn
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_gmn
+
+
+ function matrix_update_fin(p,itransfer,rate,dt,cnveg_nitrogenflux_inst,matrixcheck,acc)
+
+ integer ,intent(in) :: p
+ integer ,intent(in) :: itransfer
+ real(r8),intent(in) :: rate
+ real(r8),intent(in) :: dt
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ logical ,intent(in),optional :: matrixcheck
+ logical ,intent(in),optional :: acc
+ real(r8) :: matrix_update_fin
+
+ associate( &
+ matrix_nphturnover => cnveg_nitrogenflux_inst%matrix_nphturnover_patch , &
+ matrix_ngmturnover => cnveg_nitrogenflux_inst%matrix_ngmturnover_patch , &
+ matrix_nfitransfer => cnveg_nitrogenflux_inst%matrix_nfitransfer_patch , &
+ matrix_nfiturnover => cnveg_nitrogenflux_inst%matrix_nfiturnover_patch , &
+ doner_fin => cnveg_nitrogenflux_inst%matrix_nfitransfer_doner_patch &
+ )
+
+ if(.not. present(matrixcheck) .or. matrixcheck)then
+ if((.not. present(acc) .or. acc) .and. matrix_nphturnover(p,doner_fin(itransfer)) + matrix_ngmturnover(p,doner_fin(itransfer)) &
+ + matrix_nfiturnover(p,doner_fin(itransfer)) + rate * dt .ge. 1)then
+ matrix_update_fin = max(0._r8,(1._r8 - matrix_nphturnover(p,doner_fin(itransfer)) &
+ - matrix_ngmturnover(p,doner_fin(itransfer)) - matrix_nfiturnover(p,doner_fin(itransfer))) / dt)
+ else
+ matrix_update_fin = rate
+ end if
+ else
+ matrix_update_fin = rate
+ end if
+ if(.not. present(acc) .or. acc)then
+ matrix_nfiturnover(p,doner_fin(itransfer)) = matrix_nfiturnover(p,doner_fin(itransfer)) + matrix_update_fin * dt
+ matrix_nfitransfer(p,itransfer) = matrix_nfitransfer(p,itransfer) + matrix_update_fin
+ else
+ matrix_nfiturnover(p,doner_fin(itransfer)) = matrix_nfiturnover(p,doner_fin(itransfer)) - matrix_nfitransfer(p,itransfer) * dt + matrix_update_fin * dt
+ matrix_nfitransfer(p,itransfer) = matrix_update_fin
+ end if
+
+ return
+ end associate
+
+ end function matrix_update_fin
+
+ !-----------------------------------------------------------------------
+ subroutine CNVegMatrixRest( ncid, flag )
+ ! !DESCRIPTION:
+ !
+ ! Read/write restart data needed for the CN Matrix model solution
+ !
+ ! !USES:
+ use restUtilMod , only: restartvar
+ use ncdio_pio , only: file_desc_t, ncd_int
+ !
+ ! !ARGUMENTS:
+ type(file_desc_t) , intent(inout) :: ncid ! netcdf id
+ character(len=*) , intent(in) :: flag !'read' or 'write'
+ !
+ ! !LOCAL VARIABLES:
+ logical :: readvar ! determine if variable is on initial file
+ !------------------------------------------------------------------------
+ call restartvar(ncid=ncid, flag=flag, varname='bgc_cycle_year', xtype=ncd_int, &
+ long_name='Year number in spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iyr)
+
+ call restartvar(ncid=ncid, flag=flag, varname='bgc_cycle_loop', xtype=ncd_int, &
+ long_name='Loop number in spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iloop)
+
+ !------------------------------------------------------------------------
+ end subroutine CNVegMatrixRest
+
+end module CNVegMatrixMod
diff --git a/src/biogeochem/CNVegNitrogenFluxType.F90 b/src/biogeochem/CNVegNitrogenFluxType.F90
index 3806de9838..788be23137 100644
--- a/src/biogeochem/CNVegNitrogenFluxType.F90
+++ b/src/biogeochem/CNVegNitrogenFluxType.F90
@@ -5,7 +5,14 @@ module CNVegNitrogenFluxType
use shr_log_mod , only : errMsg => shr_log_errMsg
use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
use clm_varpar , only : nlevdecomp_full, nlevdecomp, i_litr_min, i_litr_max
- use clm_varpar , only : nvegnpool
+ use clm_varpar , only : nvegnpool,nnphtrans,nngmtrans,nnfitrans,nnphouttrans,&
+ nngmouttrans,nnfiouttrans
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutn
use clm_varpar , only : mxharvests
use clm_varcon , only : spval, ispval, dzsoi_decomp
use clm_varctl , only : use_nitrif_denitrif, use_crop
@@ -277,8 +284,127 @@ module CNVegNitrogenFluxType
real(r8), pointer :: cost_nactive_patch (:) ! Average cost of active uptake (gN/m2/s)
real(r8), pointer :: cost_nretrans_patch (:) ! Average cost of retranslocation (gN/m2/s)
real(r8), pointer :: nuptake_npp_fraction_patch (:) ! frac of npp spent on N acquisition (gN/m2/s)
-
- ! Matrix solution variables
+ ! Matrix
+ real(r8), pointer :: matrix_nalloc_patch (:,:) ! B-matrix for nitrogen allocation
+ real(r8), pointer :: matrix_Ninput_patch (:) ! I-matrix for nitrogen input
+
+ real(r8), pointer :: matrix_nphtransfer_patch (:,:) ! A-matrix_phenologh for nitrogen
+ real(r8), pointer :: matrix_nphturnover_patch (:,:) ! K-matrix_phenologh for nitrogen
+ integer, pointer :: matrix_nphtransfer_doner_patch (:) ! A-matrix_phenology non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_nphtransfer_receiver_patch (:) ! A-matrix_phenology non-zero indices (row indices) for nitrogen
+
+ real(r8), pointer :: matrix_ngmtransfer_patch (:,:) ! A-matrix_gap mortality for nitrogen
+ real(r8), pointer :: matrix_ngmturnover_patch (:,:) ! K-matrix_gap mortality for nitrogen
+ integer, pointer :: matrix_ngmtransfer_doner_patch (:) ! A-matrix_gap mortality non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_ngmtransfer_receiver_patch (:) ! A-matrix_gap mortality non-zero indices (row indices) for nitrogen
+
+ real(r8), pointer :: matrix_nfitransfer_patch (:,:) ! A-matrix_fire for nitrogen
+ real(r8), pointer :: matrix_nfiturnover_patch (:,:) ! K-matrix_fire for nitrogen
+ integer, pointer :: matrix_nfitransfer_doner_patch (:) ! A-matrix_fire non-zero indices (column indices) for nitrogen
+ integer, pointer :: matrix_nfitransfer_receiver_patch (:) ! A-matrix_fire non-zero indices (row indices) for nitrogen
+
+ integer ileafst_to_ileafxf_ph ! Index of phenology related N transfer from leaf storage pool to leaf transfer pool
+ integer ileafxf_to_ileaf_ph ! Index of phenology related N transfer from leaf transfer pool to leaf pool
+ integer ifrootst_to_ifrootxf_ph ! Index of phenology related N transfer from fine root storage pool to fine root transfer pool
+ integer ifrootxf_to_ifroot_ph ! Index of phenology related N transfer from fine root transfer pool to fine root pool
+ integer ilivestemst_to_ilivestemxf_ph ! Index of phenology related N transfer from live stem storage pool to live stem transfer pool
+ integer ilivestemxf_to_ilivestem_ph ! Index of phenology related N transfer from live stem transfer pool to live stem pool
+ integer ideadstemst_to_ideadstemxf_ph ! Index of phenology related N transfer from dead stem storage pool to dead stem transfer pool
+ integer ideadstemxf_to_ideadstem_ph ! Index of phenology related N transfer from dead stem transfer pool to dead stem pool
+ integer ilivecrootst_to_ilivecrootxf_ph ! Index of phenology related N transfer from live coarse root storage pool to live coarse root transfer pool
+ integer ilivecrootxf_to_ilivecroot_ph ! Index of phenology related N transfer from live coarse root transfer pool to live coarse root pool
+ integer ideadcrootst_to_ideadcrootxf_ph ! Index of phenology related N transfer from dead coarse root storage pool to dead coarse root transfer pool
+ integer ideadcrootxf_to_ideadcroot_ph ! Index of phenology related N transfer from dead coarse root transfer pool to dead coarse root pool
+ integer ilivestem_to_ideadstem_ph ! Index of phenology related N transfer from live stem pool to dead stem pool
+ integer ilivecroot_to_ideadcroot_ph ! Index of phenology related N transfer from live coarse root pool to dead coarse root pool
+ integer iretransn_to_ileaf_ph ! Index of phenology related N transfer from retranslocation pool to leaf pool
+ integer iretransn_to_ileafst_ph ! Index of phenology related N transfer from retranslocation pool to leaf storage pool
+ integer iretransn_to_ifroot_ph ! Index of phenology related N transfer from retranslocation pool to fine root pool
+ integer iretransn_to_ifrootst_ph ! Index of phenology related N transfer from retranslocation pool to fine root storage pool
+ integer iretransn_to_ilivestem_ph ! Index of phenology related N transfer from retranslocation pool to live stem pool
+ integer iretransn_to_ilivestemst_ph ! Index of phenology related N transfer from retranslocation pool to live stem storage pool
+ integer iretransn_to_ideadstem_ph ! Index of phenology related N transfer from retranslocation pool to dead stem pool
+ integer iretransn_to_ideadstemst_ph ! Index of phenology related N transfer from retranslocation pool to dead stem storage pool
+ integer iretransn_to_ilivecroot_ph ! Index of phenology related N transfer from retranslocation pool to live coarse root pool
+ integer iretransn_to_ilivecrootst_ph ! Index of phenology related N transfer from retranslocation pool to live coarse root storage pool
+ integer iretransn_to_ideadcroot_ph ! Index of phenology related N transfer from retranslocation pool to dead coarse root pool
+ integer iretransn_to_ideadcrootst_ph ! Index of phenology related N transfer from retranslocation pool to dead coarse root storage pool
+ integer iretransn_to_igrain_ph ! Index of phenology related N transfer from retranslocation pool to grain pool
+ integer iretransn_to_igrainst_ph ! Index of phenology related N transfer from retranslocation pool to grain storage pool
+ integer ileaf_to_iout_ph ! Index of phenology related N transfer from leaf pool to outside of vegetation pools
+ integer ifroot_to_iout_ph ! Index of phenology related N transfer from fine root pool to outside of vegetation pools
+ integer ilivestem_to_iout_ph ! Index of phenology related N transfer from live stem pool to outside of vegetation pools
+ integer ileaf_to_iretransn_ph ! Index of phenology related N transfer from leaf pool to retranslocation pools
+ integer ifroot_to_iretransn_ph ! Index of phenology related N transfer from fine root pool to retranslocation pools
+ integer ilivestem_to_iretransn_ph ! Index of phenology related N transfer from live stem pool to retranslocation pools
+ integer ilivecroot_to_iretransn_ph ! Index of phenology related N transfer from live coarse root pool to retranslocation pools
+ integer igrain_to_iout_ph ! Index of phenology related N transfer from grain pool to outside of vegetation pools
+ integer iretransn_to_iout_ph ! Index of phenology related N transfer from retranslocation pool to outside of vegetation pools
+ integer ileaf_to_iout_gm ! Index of gap mortality related N transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_gm ! Index of gap mortality related N transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_gm ! Index of gap mortality related N transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_gm ! Index of gap mortality related N transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_gm ! Index of gap mortality related N transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_gm ! Index of gap mortality related N transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_gm ! Index of gap mortality related N transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_gm ! Index of gap mortality related N transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_gm ! Index of gap mortality related N transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_gm ! Index of gap mortality related N transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_gm ! Index of gap mortality related N transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_gm ! Index of gap mortality related N transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_gm ! Index of gap mortality related N transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_gm ! Index of gap mortality related N transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_gm ! Index of gap mortality related N transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_gm ! Index of gap mortality related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer iretransn_to_iout_gm ! Index of gap mortality related N transfer from retranslocation to outside of vegetation pools
+ integer ileaf_to_iout_fi ! Index of fire related N transfer from leaf pool to outside of vegetation pools
+ integer ileafst_to_iout_fi ! Index of fire related N transfer from leaf storage pool to outside of vegetation pools
+ integer ileafxf_to_iout_fi ! Index of fire related N transfer from leaf transfer pool to outside of vegetation pools
+ integer ifroot_to_iout_fi ! Index of fire related N transfer from fine root pool to outside of vegetation pools
+ integer ifrootst_to_iout_fi ! Index of fire related N transfer from fine root storage pool to outside of vegetation pools
+ integer ifrootxf_to_iout_fi ! Index of fire related N transfer from fine root transfer pool to outside of vegetation pools
+ integer ilivestem_to_iout_fi ! Index of fire related N transfer from live stem pool to outside of vegetation pools
+ integer ilivestemst_to_iout_fi ! Index of fire related N transfer from live stem storage pool to outside of vegetation pools
+ integer ilivestemxf_to_iout_fi ! Index of fire related N transfer from live stem transfer pool to outside of vegetation pools
+ integer ideadstem_to_iout_fi ! Index of fire related N transfer from dead stem pool to outside of vegetation pools
+ integer ideadstemst_to_iout_fi ! Index of fire related N transfer from dead stem storage pool to outside of vegetation pools
+ integer ideadstemxf_to_iout_fi ! Index of fire related N transfer from dead stem transfer pool to outside of vegetation pools
+ integer ilivecroot_to_iout_fi ! Index of fire related N transfer from live coarse root pool to outside of vegetation pools
+ integer ilivecrootst_to_iout_fi ! Index of fire related N transfer from live coarse root storage pool to outside of vegetation pools
+ integer ilivecrootxf_to_iout_fi ! Index of fire related N transfer from live coarse root transfer pool to outside of vegetation pools
+ integer ideadcroot_to_iout_fi ! Index of fire related N transfer from dead coarse root pool to outside of vegetation pools
+ integer ideadcrootst_to_iout_fi ! Index of fire related N transfer from dead coarse root storage pool to outside of vegetation pools
+ integer ideadcrootxf_to_iout_fi ! Index of fire related N transfer from dead coarse root transfer pool to outside of vegetation pools
+ integer iretransn_to_iout_fi ! Index of fire related N transfer from retranslocation transfer pool to outside of vegetation pools
+ integer ilivestem_to_ideadstem_fi ! Index of fire related N transfer from live stem pool to dead stem pools
+ integer ilivecroot_to_ideadcroot_fi ! Index of fire related N transfer from live coarse root pool to dead coarse root pools
+
+ integer,pointer :: list_phn_phgmn (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphn to AKphn+AKgmn
+ integer,pointer :: list_gmn_phgmn (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmn to AKphn+AKgmn
+ integer,pointer :: list_phn_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKphn to AKphn+AKgmn+AKfin
+ integer,pointer :: list_gmn_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKgmn to AKphn+AKgmn+AKfin
+ integer,pointer :: list_fin_phgmfin (:) ! Index mapping for sparse matrix addition (save to reduce computational cost): from AKfin to AKphn+AKgmn+AKfin
+ integer,pointer :: list_aphn (:) ! Indices of non-diagnoal entries in full sparse matrix Aph for N cycle
+ integer,pointer :: list_agmn (:) ! Indices of non-diagnoal entries in full sparse matrix Agm for N cycle
+ integer,pointer :: list_afin (:) ! Indices of non-diagnoal entries in full sparse matrix Afi for N cycle
+
+ type(sparse_matrix_type) :: AKphvegn ! Aph*Kph for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKgmvegn ! Agm*Kgm for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKfivegn ! Afi*Kfi for N cycle in sparse matrix format
+ type(sparse_matrix_type) :: AKallvegn ! Aph*Kph + Agm*Kgm + Afi*Kfi for N cycle in sparse matrix format
+ integer :: NE_AKallvegn ! Number of entries in AKallvegn
+ integer,pointer,dimension(:) :: RI_AKallvegn ! Row indices in Akallvegn
+ integer,pointer,dimension(:) :: CI_AKallvegn ! Column indices in AKallvegn
+ integer,pointer,dimension(:) :: RI_phn ! Row indices of non-diagonal entires in Aph for N cycle
+ integer,pointer,dimension(:) :: CI_phn ! Column indices of non-diagonal entries in Aph for N cycle
+ integer,pointer,dimension(:) :: RI_gmn ! Row indices of non-diagonal entires in Agm for N cycle
+ integer,pointer,dimension(:) :: CI_gmn ! Column indices of non-diagonal entries in Agm for N cycle
+ integer,pointer,dimension(:) :: RI_fin ! Row indices of non-diagonal entires in Afi for N cycle
+ integer,pointer,dimension(:) :: CI_fin ! Column indices of non-diagonal entries in Afi for N cycle
+ type(diag_matrix_type) :: Kvegn ! Temporary variable of Kph, Kgm or Kfi for N cycle in diagonal matrix format
+ type(vector_type) :: Xvegn ! Vegetation N of each compartment in a vector format
contains
@@ -289,7 +415,7 @@ module CNVegNitrogenFluxType
procedure , public :: ZeroGRU
procedure , public :: Summary => Summary_nitrogenflux
procedure , private :: InitAllocate
- procedure , private :: InitTransfer
+ procedure , private :: InitTransfer
procedure , private :: InitHistory
procedure , private :: InitCold
@@ -317,20 +443,337 @@ subroutine Init(this, bounds, alloc_full_veg)
end subroutine Init
subroutine InitTransfer (this)
- !
- ! !DESCRIPTION:
- ! Initialize the transfer indices for the matrix solution method
!
! !AGRUMENTS:
class (cnveg_nitrogenflux_type) :: this
+
+ this%ileaf_to_iretransn_ph = 1
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iretransn_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iretransn_ph) = iretransn
+
+ this%ileafst_to_ileafxf_ph = 2
+ this%matrix_nphtransfer_doner_patch(this%ileafst_to_ileafxf_ph) = ileaf_st
+ this%matrix_nphtransfer_receiver_patch(this%ileafst_to_ileafxf_ph) = ileaf_xf
+
+ this%ileafxf_to_ileaf_ph = 3
+ this%matrix_nphtransfer_doner_patch(this%ileafxf_to_ileaf_ph) = ileaf_xf
+ this%matrix_nphtransfer_receiver_patch(this%ileafxf_to_ileaf_ph) = ileaf
+
+ this%ifroot_to_iretransn_ph = 4
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iretransn_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iretransn_ph) = iretransn
+
+ this%ifrootst_to_ifrootxf_ph = 5
+ this%matrix_nphtransfer_doner_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ifrootst_to_ifrootxf_ph) = ifroot_xf
+
+ this%ifrootxf_to_ifroot_ph = 6
+ this%matrix_nphtransfer_doner_patch(this%ifrootxf_to_ifroot_ph) = ifroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ifrootxf_to_ifroot_ph) = ifroot
+
+ this%ilivestem_to_ideadstem_ph = 7
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_ideadstem_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_ideadstem_ph) = ideadstem
+
+ this%ilivestem_to_iretransn_ph = 8
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iretransn_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iretransn_ph) = iretransn
+
+ this%ilivestemst_to_ilivestemxf_ph = 9
+ this%matrix_nphtransfer_doner_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_st
+ this%matrix_nphtransfer_receiver_patch(this%ilivestemst_to_ilivestemxf_ph) = ilivestem_xf
- ! General indices
+ this%ilivestemxf_to_ilivestem_ph = 10
+ this%matrix_nphtransfer_doner_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem_xf
+ this%matrix_nphtransfer_receiver_patch(this%ilivestemxf_to_ilivestem_ph) = ilivestem
+
+ this%ideadstemst_to_ideadstemxf_ph = 11
+ this%matrix_nphtransfer_doner_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_st
+ this%matrix_nphtransfer_receiver_patch(this%ideadstemst_to_ideadstemxf_ph) = ideadstem_xf
+
+ this%ideadstemxf_to_ideadstem_ph = 12
+ this%matrix_nphtransfer_doner_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem_xf
+ this%matrix_nphtransfer_receiver_patch(this%ideadstemxf_to_ideadstem_ph) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_ph = 13
+ this%matrix_nphtransfer_doner_patch(this%ilivecroot_to_ideadcroot_ph) = ilivecroot
+ this%matrix_nphtransfer_receiver_patch(this%ilivecroot_to_ideadcroot_ph) = ideadcroot
+
+ this%ilivecroot_to_iretransn_ph = 14
+ this%matrix_nphtransfer_doner_patch(this%ilivecroot_to_iretransn_ph) = ilivecroot
+ this%matrix_nphtransfer_receiver_patch(this%ilivecroot_to_iretransn_ph) = iretransn
+
+ this%ilivecrootst_to_ilivecrootxf_ph = 15
+ this%matrix_nphtransfer_doner_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ilivecrootst_to_ilivecrootxf_ph) = ilivecroot_xf
+
+ this%ilivecrootxf_to_ilivecroot_ph = 16
+ this%matrix_nphtransfer_doner_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ilivecrootxf_to_ilivecroot_ph) = ilivecroot
+
+ this%ideadcrootst_to_ideadcrootxf_ph = 17
+ this%matrix_nphtransfer_doner_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_st
+ this%matrix_nphtransfer_receiver_patch(this%ideadcrootst_to_ideadcrootxf_ph) = ideadcroot_xf
+
+ this%ideadcrootxf_to_ideadcroot_ph = 18
+ this%matrix_nphtransfer_doner_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot_xf
+ this%matrix_nphtransfer_receiver_patch(this%ideadcrootxf_to_ideadcroot_ph) = ideadcroot
+
+ this%iretransn_to_ileaf_ph = 19
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ileaf_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ileaf_ph) = ileaf
+
+ this%iretransn_to_ileafst_ph = 20
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ileafst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ileafst_ph) = ileaf_st
+
+ this%iretransn_to_ifroot_ph = 21
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ifroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ifroot_ph) = ifroot
+
+ this%iretransn_to_ifrootst_ph = 22
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ifrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ifrootst_ph) = ifroot_st
+
+ this%iretransn_to_ilivestem_ph = 23
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivestem_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivestem_ph) = ilivestem
+
+ this%iretransn_to_ilivestemst_ph = 24
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivestemst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivestemst_ph) = ilivestem_st
+
+ this%iretransn_to_ideadstem_ph = 25
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadstem_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadstem_ph) = ideadstem
+
+ this%iretransn_to_ideadstemst_ph = 26
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadstemst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadstemst_ph) = ideadstem_st
+
+ this%iretransn_to_ilivecroot_ph = 27
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivecroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivecroot_ph) = ilivecroot
+
+ this%iretransn_to_ilivecrootst_ph = 28
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ilivecrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ilivecrootst_ph) = ilivecroot_st
+
+ this%iretransn_to_ideadcroot_ph = 29
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadcroot_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadcroot_ph) = ideadcroot
+
+ this%iretransn_to_ideadcrootst_ph = 30
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_ideadcrootst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_ideadcrootst_ph) = ideadcroot_st
+
if(.not. use_crop)then
- ! Indices for crop
+ this%ileaf_to_iout_ph = 31
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutn
+
+ this%ifroot_to_iout_ph = 32
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutn
+
+ this%ilivestem_to_iout_ph = 33
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutn
+
+ this%iretransn_to_iout_ph = 34
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_iout_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_iout_ph) = ioutn
else
+ this%iretransn_to_igrain_ph = 31
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_igrain_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_igrain_ph) = igrain
+
+ this%iretransn_to_igrainst_ph = 32
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_igrainst_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_igrainst_ph) = igrain_st
+
+ this%ileaf_to_iout_ph = 33
+ this%matrix_nphtransfer_doner_patch(this%ileaf_to_iout_ph) = ileaf
+ this%matrix_nphtransfer_receiver_patch(this%ileaf_to_iout_ph) = ioutn
+
+ this%ifroot_to_iout_ph = 34
+ this%matrix_nphtransfer_doner_patch(this%ifroot_to_iout_ph) = ifroot
+ this%matrix_nphtransfer_receiver_patch(this%ifroot_to_iout_ph) = ioutn
+
+ this%ilivestem_to_iout_ph = 35
+ this%matrix_nphtransfer_doner_patch(this%ilivestem_to_iout_ph) = ilivestem
+ this%matrix_nphtransfer_receiver_patch(this%ilivestem_to_iout_ph) = ioutn
+
+ this%igrain_to_iout_ph = 36
+ this%matrix_nphtransfer_doner_patch(this%igrain_to_iout_ph) = igrain
+ this%matrix_nphtransfer_receiver_patch(this%igrain_to_iout_ph) = ioutn
+
+ this%iretransn_to_iout_ph = 37
+ this%matrix_nphtransfer_doner_patch(this%iretransn_to_iout_ph) = iretransn
+ this%matrix_nphtransfer_receiver_patch(this%iretransn_to_iout_ph) = ioutn
end if
-
- end subroutine InitTransfer
+
+ this%ileaf_to_iout_gm = 1
+ this%matrix_ngmtransfer_doner_patch(this%ileaf_to_iout_gm) = ileaf
+ this%matrix_ngmtransfer_receiver_patch(this%ileaf_to_iout_gm) = ioutn
+
+ this%ileafst_to_iout_gm = 2
+ this%matrix_ngmtransfer_doner_patch(this%ileafst_to_iout_gm) = ileaf_st
+ this%matrix_ngmtransfer_receiver_patch(this%ileafst_to_iout_gm) = ioutn
+
+ this%ileafxf_to_iout_gm = 3
+ this%matrix_ngmtransfer_doner_patch(this%ileafxf_to_iout_gm) = ileaf_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ileafxf_to_iout_gm) = ioutn
+
+ this%ifroot_to_iout_gm = 4
+ this%matrix_ngmtransfer_doner_patch(this%ifroot_to_iout_gm) = ifroot
+ this%matrix_ngmtransfer_receiver_patch(this%ifroot_to_iout_gm) = ioutn
+
+ this%ifrootst_to_iout_gm = 5
+ this%matrix_ngmtransfer_doner_patch(this%ifrootst_to_iout_gm) = ifroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ifrootst_to_iout_gm) = ioutn
+
+ this%ifrootxf_to_iout_gm = 6
+ this%matrix_ngmtransfer_doner_patch(this%ifrootxf_to_iout_gm) = ifroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ifrootxf_to_iout_gm) = ioutn
+
+ this%ilivestem_to_iout_gm = 7
+ this%matrix_ngmtransfer_doner_patch(this%ilivestem_to_iout_gm) = ilivestem
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestem_to_iout_gm) = ioutn
+
+ this%ilivestemst_to_iout_gm = 8
+ this%matrix_ngmtransfer_doner_patch(this%ilivestemst_to_iout_gm) = ilivestem_st
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestemst_to_iout_gm) = ioutn
+
+ this%ilivestemxf_to_iout_gm = 9
+ this%matrix_ngmtransfer_doner_patch(this%ilivestemxf_to_iout_gm) = ilivestem_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ilivestemxf_to_iout_gm) = ioutn
+
+ this%ideadstem_to_iout_gm = 10
+ this%matrix_ngmtransfer_doner_patch(this%ideadstem_to_iout_gm) = ideadstem
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstem_to_iout_gm) = ioutn
+
+ this%ideadstemst_to_iout_gm = 11
+ this%matrix_ngmtransfer_doner_patch(this%ideadstemst_to_iout_gm) = ideadstem_st
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstemst_to_iout_gm) = ioutn
+
+ this%ideadstemxf_to_iout_gm = 12
+ this%matrix_ngmtransfer_doner_patch(this%ideadstemxf_to_iout_gm) = ideadstem_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ideadstemxf_to_iout_gm) = ioutn
+
+ this%ilivecroot_to_iout_gm = 13
+ this%matrix_ngmtransfer_doner_patch(this%ilivecroot_to_iout_gm) = ilivecroot
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecroot_to_iout_gm) = ioutn
+
+ this%ilivecrootst_to_iout_gm = 14
+ this%matrix_ngmtransfer_doner_patch(this%ilivecrootst_to_iout_gm) = ilivecroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecrootst_to_iout_gm) = ioutn
+
+ this%ilivecrootxf_to_iout_gm = 15
+ this%matrix_ngmtransfer_doner_patch(this%ilivecrootxf_to_iout_gm) = ilivecroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ilivecrootxf_to_iout_gm) = ioutn
+
+ this%ideadcroot_to_iout_gm = 16
+ this%matrix_ngmtransfer_doner_patch(this%ideadcroot_to_iout_gm) = ideadcroot
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcroot_to_iout_gm) = ioutn
+
+ this%ideadcrootst_to_iout_gm = 17
+ this%matrix_ngmtransfer_doner_patch(this%ideadcrootst_to_iout_gm) = ideadcroot_st
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcrootst_to_iout_gm) = ioutn
+
+ this%ideadcrootxf_to_iout_gm = 18
+ this%matrix_ngmtransfer_doner_patch(this%ideadcrootxf_to_iout_gm) = ideadcroot_xf
+ this%matrix_ngmtransfer_receiver_patch(this%ideadcrootxf_to_iout_gm) = ioutn
+
+ this%iretransn_to_iout_gm = 19
+ this%matrix_ngmtransfer_doner_patch(this%iretransn_to_iout_gm) = iretransn
+ this%matrix_ngmtransfer_receiver_patch(this%iretransn_to_iout_gm) = ioutn
+
+ this%ilivestem_to_ideadstem_fi = 1
+ this%matrix_nfitransfer_doner_patch(this%ilivestem_to_ideadstem_fi) = ilivestem
+ this%matrix_nfitransfer_receiver_patch(this%ilivestem_to_ideadstem_fi) = ideadstem
+
+ this%ilivecroot_to_ideadcroot_fi = 2
+ this%matrix_nfitransfer_doner_patch(this%ilivecroot_to_ideadcroot_fi) = ilivecroot
+ this%matrix_nfitransfer_receiver_patch(this%ilivecroot_to_ideadcroot_fi) = ideadcroot
+
+ this%ileaf_to_iout_fi = 3
+ this%matrix_nfitransfer_doner_patch(this%ileaf_to_iout_fi) = ileaf
+ this%matrix_nfitransfer_receiver_patch(this%ileaf_to_iout_fi) = ioutn
+
+ this%ileafst_to_iout_fi = 4
+ this%matrix_nfitransfer_doner_patch(this%ileafst_to_iout_fi) = ileaf_st
+ this%matrix_nfitransfer_receiver_patch(this%ileafst_to_iout_fi) = ioutn
+
+ this%ileafxf_to_iout_fi = 5
+ this%matrix_nfitransfer_doner_patch(this%ileafxf_to_iout_fi) = ileaf_xf
+ this%matrix_nfitransfer_receiver_patch(this%ileafxf_to_iout_fi) = ioutn
+
+ this%ifroot_to_iout_fi = 6
+ this%matrix_nfitransfer_doner_patch(this%ifroot_to_iout_fi) = ifroot
+ this%matrix_nfitransfer_receiver_patch(this%ifroot_to_iout_fi) = ioutn
+
+ this%ifrootst_to_iout_fi = 7
+ this%matrix_nfitransfer_doner_patch(this%ifrootst_to_iout_fi) = ifroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ifrootst_to_iout_fi) = ioutn
+
+ this%ifrootxf_to_iout_fi = 8
+ this%matrix_nfitransfer_doner_patch(this%ifrootxf_to_iout_fi) = ifroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ifrootxf_to_iout_fi) = ioutn
+
+ this%ilivestem_to_iout_fi = 9
+ this%matrix_nfitransfer_doner_patch(this%ilivestem_to_iout_fi) = ilivestem
+ this%matrix_nfitransfer_receiver_patch(this%ilivestem_to_iout_fi) = ioutn
+
+ this%ilivestemst_to_iout_fi = 10
+ this%matrix_nfitransfer_doner_patch(this%ilivestemst_to_iout_fi) = ilivestem_st
+ this%matrix_nfitransfer_receiver_patch(this%ilivestemst_to_iout_fi) = ioutn
+
+ this%ilivestemxf_to_iout_fi = 11
+ this%matrix_nfitransfer_doner_patch(this%ilivestemxf_to_iout_fi) = ilivestem_xf
+ this%matrix_nfitransfer_receiver_patch(this%ilivestemxf_to_iout_fi) = ioutn
+
+ this%ideadstem_to_iout_fi = 12
+ this%matrix_nfitransfer_doner_patch(this%ideadstem_to_iout_fi) = ideadstem
+ this%matrix_nfitransfer_receiver_patch(this%ideadstem_to_iout_fi) = ioutn
+
+ this%ideadstemst_to_iout_fi = 13
+ this%matrix_nfitransfer_doner_patch(this%ideadstemst_to_iout_fi) = ideadstem_st
+ this%matrix_nfitransfer_receiver_patch(this%ideadstemst_to_iout_fi) = ioutn
+
+ this%ideadstemxf_to_iout_fi = 14
+ this%matrix_nfitransfer_doner_patch(this%ideadstemxf_to_iout_fi) = ideadstem_xf
+ this%matrix_nfitransfer_receiver_patch(this%ideadstemxf_to_iout_fi) = ioutn
+
+ this%ilivecroot_to_iout_fi = 15
+ this%matrix_nfitransfer_doner_patch(this%ilivecroot_to_iout_fi) = ilivecroot
+ this%matrix_nfitransfer_receiver_patch(this%ilivecroot_to_iout_fi) = ioutn
+
+ this%ilivecrootst_to_iout_fi = 16
+ this%matrix_nfitransfer_doner_patch(this%ilivecrootst_to_iout_fi) = ilivecroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ilivecrootst_to_iout_fi) = ioutn
+
+ this%ilivecrootxf_to_iout_fi = 17
+ this%matrix_nfitransfer_doner_patch(this%ilivecrootxf_to_iout_fi) = ilivecroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ilivecrootxf_to_iout_fi) = ioutn
+
+ this%ideadcroot_to_iout_fi = 18
+ this%matrix_nfitransfer_doner_patch(this%ideadcroot_to_iout_fi) = ideadcroot
+ this%matrix_nfitransfer_receiver_patch(this%ideadcroot_to_iout_fi) = ioutn
+
+ this%ideadcrootst_to_iout_fi = 19
+ this%matrix_nfitransfer_doner_patch(this%ideadcrootst_to_iout_fi) = ideadcroot_st
+ this%matrix_nfitransfer_receiver_patch(this%ideadcrootst_to_iout_fi) = ioutn
+
+ this%ideadcrootxf_to_iout_fi = 20
+ this%matrix_nfitransfer_doner_patch(this%ideadcrootxf_to_iout_fi) = ideadcroot_xf
+ this%matrix_nfitransfer_receiver_patch(this%ideadcrootxf_to_iout_fi) = ioutn
+
+ this%iretransn_to_iout_fi = 21
+ this%matrix_nfitransfer_doner_patch(this%iretransn_to_iout_fi) = iretransn
+ this%matrix_nfitransfer_receiver_patch(this%iretransn_to_iout_fi) = ioutn
+
+ end subroutine InitTransfer
!------------------------------------------------------------------------
subroutine InitAllocate(this, bounds, alloc_full_veg)
@@ -612,10 +1055,57 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%cost_nactive_patch (begp:endp)) ; this%cost_nactive_patch (:) = nan
allocate(this%cost_nretrans_patch (begp:endp)) ; this%cost_nretrans_patch (:) = nan
allocate(this%nuptake_npp_fraction_patch (begp:endp)) ; this%nuptake_npp_fraction_patch (:) = nan
-
- ! Allocate for matrix solution arrays
- if ( use_matrixcn )then
- end if
+ ! Matrix
+ if(use_matrixcn)then
+ allocate(this%matrix_Ninput_patch (begp:endp)) ; this%matrix_Ninput_patch (:) = nan
+ allocate(this%matrix_nalloc_patch (begp:endp,1:nvegnpool)) ; this%matrix_nalloc_patch (:,:) = nan
+
+ allocate(this%matrix_nphtransfer_patch (begp:endp,1:nnphtrans)) ; this%matrix_nphtransfer_patch (:,:) = nan
+ allocate(this%matrix_nphturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_nphturnover_patch (:,:) = nan
+ allocate(this%matrix_nphtransfer_doner_patch (1:nnphtrans)) ; this%matrix_nphtransfer_doner_patch (:) = -9999
+ allocate(this%matrix_nphtransfer_receiver_patch (1:nnphtrans)) ; this%matrix_nphtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_ngmtransfer_patch (begp:endp,1:nngmtrans)) ; this%matrix_ngmtransfer_patch (:,:) = nan
+ allocate(this%matrix_ngmturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_ngmturnover_patch (:,:) = nan
+ allocate(this%matrix_ngmtransfer_doner_patch (1:nngmtrans)) ; this%matrix_ngmtransfer_doner_patch (:) = -9999
+ allocate(this%matrix_ngmtransfer_receiver_patch (1:nngmtrans)) ; this%matrix_ngmtransfer_receiver_patch(:) = -9999
+
+ allocate(this%matrix_nfitransfer_patch (begp:endp,1:nnfitrans)) ; this%matrix_nfitransfer_patch (:,:) = nan
+ allocate(this%matrix_nfiturnover_patch (begp:endp,1:nvegnpool)) ; this%matrix_nfiturnover_patch (:,:) = nan
+ allocate(this%matrix_nfitransfer_doner_patch (1:nnfitrans)) ; this%matrix_nfitransfer_doner_patch (:) = -9999
+ allocate(this%matrix_nfitransfer_receiver_patch (1:nnfitrans)) ; this%matrix_nfitransfer_receiver_patch(:) = -9999
+
+ allocate(this%list_phn_phgmn (1:nnphtrans+nvegnpool)) ; this%list_phn_phgmn = -9999
+ allocate(this%list_gmn_phgmn (1:nvegnpool)) ; this%list_gmn_phgmn = -9999
+ allocate(this%list_phn_phgmfin (1:nnphtrans+nvegnpool)) ; this%list_phn_phgmfin = -9999
+ allocate(this%list_gmn_phgmfin (1:nvegnpool)) ; this%list_gmn_phgmfin = -9999
+ allocate(this%list_fin_phgmfin (1:nnfitrans+nvegnpool)) ; this%list_fin_phgmfin = -9999
+
+ allocate(this%list_aphn (1:nnphtrans-nnphouttrans)); this%list_aphn = -9999
+ allocate(this%list_agmn (1:nngmtrans-nngmouttrans)); this%list_agmn = -9999
+ allocate(this%list_afin (1:nnfitrans-nnfiouttrans)); this%list_afin = -9999
+
+ call this%AKphvegn%InitSM (nvegnpool,begp,endp,nnphtrans-nnphouttrans+nvegnpool)
+ call this%AKgmvegn%InitSM (nvegnpool,begp,endp,nngmtrans-nngmouttrans+nvegnpool)
+ call this%AKfivegn%InitSM (nvegnpool,begp,endp,nnfitrans-nnfiouttrans+nvegnpool)
+
+ this%NE_AKallvegn = (nnphtrans-nnphouttrans+nvegnpool) + (nngmtrans-nngmouttrans+nvegnpool) + &
+ nnfitrans-nnfiouttrans+nvegnpool
+
+ call this%AKallvegn%InitSM (nvegnpool,begp,endp,this%NE_AKallvegn)
+
+ allocate(this%RI_AKallvegn (1:this%NE_AKallvegn)) ; this%RI_AKallvegn(:) = -9999
+ allocate(this%CI_AKallvegn (1:this%NE_AKallvegn)) ; this%CI_AKallvegn(:) = -9999
+ allocate(this%RI_phn (1:nnphtrans-nnphouttrans+nvegnpool)) ; this%RI_phn(:) = -9999
+ allocate(this%CI_phn (1:nnphtrans-nnphouttrans+nvegnpool)) ; this%CI_phn(:) = -9999
+ allocate(this%RI_gmn (1:nngmtrans-nngmouttrans+nvegnpool)) ; this%RI_gmn(:) = -9999
+ allocate(this%CI_gmn (1:nngmtrans-nngmouttrans+nvegnpool)) ; this%CI_gmn(:) = -9999
+ allocate(this%RI_fin (1:nnfitrans-nnfiouttrans+nvegnpool)) ; this%RI_fin(:) = -9999
+ allocate(this%CI_fin (1:nnfitrans-nnfiouttrans+nvegnpool)) ; this%CI_fin(:) = -9999
+
+ call this%Kvegn%InitDM (nvegnpool,begp,endp)
+ call this%Xvegn%InitV (nvegnpool,begp,endp)
+ end if
end subroutine InitAllocate
@@ -1248,10 +1738,12 @@ subroutine InitHistory(this, bounds)
call hist_addfld1d (fname='PLANT_NALLOC', units='gN/m^2/s', &
avgflag='A', long_name='total allocated N flux', &
ptr_patch=this%plant_nalloc_patch, default='inactive')
-
- ! Matrix solution history variables
- if ( use_matrixcn )then
- end if
+ if (use_matrixcn) then
+ this%matrix_Ninput_patch(begp:endp) = spval
+ call hist_addfld1d (fname='MATRIX PLANT_NALLOC', units='gN/m^2/s', &
+ avgflag='A', long_name='total allocated N flux for matrix', &
+ ptr_patch=this%matrix_Ninput_patch, default='inactive')
+ end if
if ( use_fun ) then
this%Nactive_patch(begp:endp) = spval
@@ -1676,7 +2168,7 @@ subroutine Restart (this, bounds, ncid, flag )
long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%Nactive_patch)
call set_missing_vals_to_constant(this%Nactive_patch, 0._r8)
-
+
call restartvar(ncid=ncid, flag=flag, varname='Nnonmyc', xtype=ncd_double, &
dim1name='pft', &
long_name='', units='', &
@@ -1792,7 +2284,7 @@ subroutine Restart (this, bounds, ncid, flag )
end subroutine Restart
!-----------------------------------------------------------------------
- subroutine SetValues ( this, nvegnpool, &
+ subroutine SetValues ( this,nvegnpool, &
num_patch, filter_patch, value_patch, &
num_column, filter_column, value_column)
!
@@ -1802,8 +2294,7 @@ subroutine SetValues ( this, nvegnpool, &
! !ARGUMENTS:
! !ARGUMENTS:
class (cnveg_nitrogenflux_type) :: this
- integer , intent(in) :: num_patch
- integer , intent(in) :: nvegnpool
+ integer , intent(in) :: num_patch,nvegnpool
integer , intent(in) :: filter_patch(:)
real(r8), intent(in) :: value_patch
integer , intent(in) :: num_column
@@ -2042,12 +2533,40 @@ subroutine SetValues ( this, nvegnpool, &
this%m_decomp_npools_to_fire_col(i,k) = value_column
end do
end do
+! Matrix
+ if(use_matrixcn)then
+ do j = 1, nvegnpool
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nalloc_patch(i,j) = value_patch
+ this%matrix_nphturnover_patch (i,j) = value_patch
+ this%matrix_ngmturnover_patch (i,j) = value_patch
+ this%matrix_nfiturnover_patch (i,j) = value_patch
+ end do
+ end do
- ! Matrix solution
- if ( use_matrixcn )then
- end if
+ do j = 1, nnphtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nphtransfer_patch (i,j) = value_patch
+ end do
+ end do
+
+ do j = 1, nngmtrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_ngmtransfer_patch (i,j) = value_patch
+ end do
+ end do
+ do j = 1, nnfitrans
+ do fi = 1,num_patch
+ i = filter_patch(fi)
+ this%matrix_nfitransfer_patch (i,j) = value_patch
+ end do
+ end do
+ end if
do k = 1, ndecomp_pools
do j = 1, nlevdecomp_full
do fi = 1,num_column
diff --git a/src/biogeochem/CNVegNitrogenStateType.F90 b/src/biogeochem/CNVegNitrogenStateType.F90
index 42bc47e102..61bb2d5d16 100644
--- a/src/biogeochem/CNVegNitrogenStateType.F90
+++ b/src/biogeochem/CNVegNitrogenStateType.F90
@@ -33,14 +33,23 @@ module CNVegNitrogenStateType
real(r8), pointer :: reproductiven_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N (crop)
real(r8), pointer :: reproductiven_storage_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N storage (crop)
real(r8), pointer :: reproductiven_xfer_patch (:,:) ! (gN/m2) reproductive (e.g., grain) N transfer (crop)
+ real(r8), pointer :: matrix_cap_repron_patch (:) ! (gN/m2) Capacity of grain N
+ real(r8), pointer :: matrix_cap_repron_storage_patch (:) ! (gN/m2) Capacity of grain N storage
+ real(r8), pointer :: matrix_cap_repron_xfer_patch (:) ! (gN/m2) Capacity of grain N transfer
real(r8), pointer :: leafn_patch (:) ! (gN/m2) leaf N
real(r8), pointer :: leafn_storage_patch (:) ! (gN/m2) leaf N storage
real(r8), pointer :: leafn_xfer_patch (:) ! (gN/m2) leaf N transfer
+ real(r8), pointer :: matrix_cap_leafn_patch (:) ! (gN/m2) Capacity of leaf N
+ real(r8), pointer :: matrix_cap_leafn_storage_patch (:) ! (gN/m2) Capacity of leaf N storage
+ real(r8), pointer :: matrix_cap_leafn_xfer_patch (:) ! (gN/m2) Capacity of leaf N transfer
real(r8), pointer :: leafn_storage_xfer_acc_patch (:) ! (gN/m2) Accmulated leaf N transfer
real(r8), pointer :: storage_ndemand_patch (:) ! (gN/m2) N demand during the offset period
real(r8), pointer :: frootn_patch (:) ! (gN/m2) fine root N
real(r8), pointer :: frootn_storage_patch (:) ! (gN/m2) fine root N storage
real(r8), pointer :: frootn_xfer_patch (:) ! (gN/m2) fine root N transfer
+ real(r8), pointer :: matrix_cap_frootn_patch (:) ! (gN/m2) Capacity of fine root N
+ real(r8), pointer :: matrix_cap_frootn_storage_patch (:) ! (gN/m2) Capacity of fine root N storage
+ real(r8), pointer :: matrix_cap_frootn_xfer_patch (:) ! (gN/m2) Capacity of fine root N transfer
real(r8), pointer :: livestemn_patch (:) ! (gN/m2) live stem N
real(r8), pointer :: livestemn_storage_patch (:) ! (gN/m2) live stem N storage
real(r8), pointer :: livestemn_xfer_patch (:) ! (gN/m2) live stem N transfer
@@ -53,14 +62,46 @@ module CNVegNitrogenStateType
real(r8), pointer :: deadcrootn_patch (:) ! (gN/m2) dead coarse root N
real(r8), pointer :: deadcrootn_storage_patch (:) ! (gN/m2) dead coarse root N storage
real(r8), pointer :: deadcrootn_xfer_patch (:) ! (gN/m2) dead coarse root N transfer
+ real(r8), pointer :: matrix_cap_livestemn_patch (:) ! (gN/m2) Capacity of live stem N
+ real(r8), pointer :: matrix_cap_livestemn_storage_patch (:) ! (gN/m2) Capacity of live stem N storage
+ real(r8), pointer :: matrix_cap_livestemn_xfer_patch (:) ! (gN/m2) Capacity of live stem N transfer
+ real(r8), pointer :: matrix_cap_deadstemn_patch (:) ! (gN/m2) Capacity of dead stem N
+ real(r8), pointer :: matrix_cap_deadstemn_storage_patch (:) ! (gN/m2) Capacity of dead stem N storage
+ real(r8), pointer :: matrix_cap_deadstemn_xfer_patch (:) ! (gN/m2) Capacity of dead stem N transfer
+ real(r8), pointer :: matrix_cap_livecrootn_patch (:) ! (gN/m2) Capacity of live coarse root N
+ real(r8), pointer :: matrix_cap_livecrootn_storage_patch (:) ! (gN/m2) Capacity of live coarse root N storage
+ real(r8), pointer :: matrix_cap_livecrootn_xfer_patch (:) ! (gN/m2) Capacity of live coarse root N transfer
+ real(r8), pointer :: matrix_cap_deadcrootn_patch (:) ! (gN/m2) Capacity of dead coarse root N
+ real(r8), pointer :: matrix_cap_deadcrootn_storage_patch (:) ! (gN/m2) Capacity of dead coarse root N storage
+ real(r8), pointer :: matrix_cap_deadcrootn_xfer_patch (:) ! (gN/m2) Capacity of dead coarse root N transfer
real(r8), pointer :: retransn_patch (:) ! (gN/m2) plant pool of retranslocated N
real(r8), pointer :: npool_patch (:) ! (gN/m2) temporary plant N pool
real(r8), pointer :: ntrunc_patch (:) ! (gN/m2) patch-level sink for N truncation
real(r8), pointer :: cropseedn_deficit_patch (:) ! (gN/m2) pool for seeding new crop growth; this is a NEGATIVE term, indicating the amount of seed usage that needs to be repaid
real(r8), pointer :: seedn_grc (:) ! (gN/m2) gridcell-level pool for seeding new pFTs via dynamic landcover
-
- ! Matrix solution variables
- ! Matrix solution pool for initial state for matrix spinup
+! Pool for initial step of year for matrix
+ real(r8), pointer :: leafn0_patch (:) ! (gN/m2) Initial value of leaf N for SASU
+ real(r8), pointer :: leafn0_storage_patch (:) ! (gN/m2) Initial value of leaf N storage for SASU
+ real(r8), pointer :: leafn0_xfer_patch (:) ! (gN/m2) Initial value of leaf N transfer for SASU
+ real(r8), pointer :: frootn0_patch (:) ! (gN/m2) Initial value of fine root N for SASU
+ real(r8), pointer :: frootn0_storage_patch (:) ! (gN/m2) Initial value of fine root N storage for SASU
+ real(r8), pointer :: frootn0_xfer_patch (:) ! (gN/m2) Initial value of fine root N transfer for SASU
+ real(r8), pointer :: livestemn0_patch (:) ! (gN/m2) Initial value of live stem N for SASU
+ real(r8), pointer :: livestemn0_storage_patch (:) ! (gN/m2) Initial value of live stem N storage for SASU
+ real(r8), pointer :: livestemn0_xfer_patch (:) ! (gN/m2) Initial value of live stem N transfer for SASU
+ real(r8), pointer :: deadstemn0_patch (:) ! (gN/m2) Initial value of dead stem N for SASU
+ real(r8), pointer :: deadstemn0_storage_patch (:) ! (gN/m2) Initial value of dead stem N storage for SASU
+ real(r8), pointer :: deadstemn0_xfer_patch (:) ! (gN/m2) Initial value of dead stem N transfer for SASU
+ real(r8), pointer :: livecrootn0_patch (:) ! (gN/m2) Initial value of live coarse root N for SASU
+ real(r8), pointer :: livecrootn0_storage_patch (:) ! (gN/m2) Initial value of live coarse root N storage for SASU
+ real(r8), pointer :: livecrootn0_xfer_patch (:) ! (gN/m2) Initial value of live coarse root N transfer for SASU
+ real(r8), pointer :: deadcrootn0_patch (:) ! (gN/m2) Initial value of dead coarse root N for SASU
+ real(r8), pointer :: deadcrootn0_storage_patch (:) ! (gN/m2) Initial value of dead coarse root N storage for SASU
+ real(r8), pointer :: deadcrootn0_xfer_patch (:) ! (gN/m2) Initial value of dead coarse root N transfer for SASU
+ real(r8), pointer :: retransn0_patch (:) ! (gN/m2) Initial value of dead coarse root N transfer for SASU
+ real(r8), pointer :: repron0_patch (:) ! (gN/m2) Initial value of grain N for SASU
+ real(r8), pointer :: repron0_storage_patch (:) ! (gN/m2) Initial value of grain N storage for SASU
+ real(r8), pointer :: repron0_xfer_patch (:) ! (gN/m2) Initial value of grain N transfer for SASU
! summary (diagnostic) state variables, not involved in mass balance
real(r8), pointer :: dispvegn_patch (:) ! (gN/m2) displayed veg nitrogen, excluding storage
@@ -69,9 +110,102 @@ module CNVegNitrogenStateType
real(r8), pointer :: totvegn_col (:) ! (gN/m2) total vegetation nitrogen (p2c)
real(r8), pointer :: totn_patch (:) ! (gN/m2) total patch-level nitrogen
real(r8), pointer :: totn_p2c_col (:) ! (gN/m2) totn_patch averaged to col
-
-
- ! acc spinup for matrix solution
+ ! acc spinup for matrix solution
+ real(r8), pointer :: matrix_nalloc_leaf_acc_patch (:) ! (gN/m2/year) Input N allocated to leaf during this year
+ real(r8), pointer :: matrix_nalloc_leafst_acc_patch (:) ! (gN/m2/year) Input N allocated to leaf storage during this year
+ real(r8), pointer :: matrix_nalloc_froot_acc_patch (:) ! (gN/m2/year) Input N allocated to fine root during this year
+ real(r8), pointer :: matrix_nalloc_frootst_acc_patch (:) ! (gN/m2/year) Input N allocated to fine root storage during this year
+ real(r8), pointer :: matrix_nalloc_livestem_acc_patch (:) ! (gN/m2/year) Input N allocated to live stem during this year
+ real(r8), pointer :: matrix_nalloc_livestemst_acc_patch (:) ! (gN/m2/year) Input N allocated to live stem storage during this year
+ real(r8), pointer :: matrix_nalloc_deadstem_acc_patch (:) ! (gN/m2/year) Input N allocated to dead stem during this year
+ real(r8), pointer :: matrix_nalloc_deadstemst_acc_patch (:) ! (gN/m2/year) Input N allocated to dead stem storage during this year
+ real(r8), pointer :: matrix_nalloc_livecroot_acc_patch (:) ! (gN/m2/year) Input N allocated to live coarse root during this year
+ real(r8), pointer :: matrix_nalloc_livecrootst_acc_patch (:) ! (gN/m2/year) Input N allocated to live coarse root storage during this year
+ real(r8), pointer :: matrix_nalloc_deadcroot_acc_patch (:) ! (gN/m2/year) Input N allocated to dead coarse root during this year
+ real(r8), pointer :: matrix_nalloc_deadcrootst_acc_patch (:) ! (gN/m2/year) Input N allocated to dead coarse root storage during this year
+ real(r8), pointer :: matrix_nalloc_grain_acc_patch (:) ! (gN/m2/year) Input N allocated to grain during this year
+ real(r8), pointer :: matrix_nalloc_grainst_acc_patch (:) ! (gN/m2/year) Input N allocated to grain storage during this year
+
+ real(r8), pointer :: matrix_ntransfer_leafst_to_leafxf_acc_patch (:) ! (gN/m2/year) N transfer from leaf storage to leaf transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_leafxf_to_leaf_acc_patch (:) ! (gN/m2/year) N transfer from leaf transfer to leaf pool during this year
+ real(r8), pointer :: matrix_ntransfer_frootst_to_frootxf_acc_patch (:) ! (gN/m2/year) N transfer from fine root storage to fine root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_frootxf_to_froot_acc_patch (:) ! (gN/m2/year) N transfer from fine root transfer to fine root pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestemst_to_livestemxf_acc_patch (:) ! (gN/m2/year) N transfer from live stem storage to live stem transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestemxf_to_livestem_acc_patch (:) ! (gN/m2/year) N transfer from live stem transfer to live stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (:) ! (gN/m2/year) N transfer from dead stem storage to dead stem transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from dead stem transfer to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root storage to live coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root transfer to live coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (:) ! (gN/m2/year) N transfer from dead coarse root storage to dead coarse root transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from dead coarse root transfer to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_grainst_to_grainxf_acc_patch (:) ! (gN/m2/year) N transfer from grain storage to grain transfer pool during this year
+ real(r8), pointer :: matrix_ntransfer_grainxf_to_grain_acc_patch (:) ! (gN/m2/year) N transfer from grain transfer to grain pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestem_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from live stem to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecroot_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root to dead coarse root pool during this year
+
+ real(r8), pointer :: matrix_ntransfer_retransn_to_leaf_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to leaf pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_leafst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to leaf storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_froot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to fine root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_frootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to fine root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livestem_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livestemst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live stem storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadstem_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead stem pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadstemst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead stem storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livecroot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_livecrootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to live coarse root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadcroot_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead coarse root pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_deadcrootst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to dead coarse root storage pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_grain_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to grain pool during this year
+ real(r8), pointer :: matrix_ntransfer_retransn_to_grainst_acc_patch (:) ! (gN/m2/year) N transfer from retranslocation to grain storage pool during this year
+
+ real(r8), pointer :: matrix_ntransfer_leaf_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from leaf to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_froot_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from fine root to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_livestem_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from live stem to retranslocation pool during this year
+ real(r8), pointer :: matrix_ntransfer_livecroot_to_retransn_acc_patch (:) ! (gN/m2/year) N transfer from live coarse root to retranslocation pool during this year
+
+ real(r8), pointer :: matrix_nturnover_leaf_acc_patch (:) ! (gN/m2/year) N turnover from leaf
+ real(r8), pointer :: matrix_nturnover_leafst_acc_patch (:) ! (gN/m2/year) N turnover from leaf storage
+ real(r8), pointer :: matrix_nturnover_leafxf_acc_patch (:) ! (gN/m2/year) N turnover from leaf transfer
+ real(r8), pointer :: matrix_nturnover_froot_acc_patch (:) ! (gN/m2/year) N turnover from root
+ real(r8), pointer :: matrix_nturnover_frootst_acc_patch (:) ! (gN/m2/year) N turnover from root storage
+ real(r8), pointer :: matrix_nturnover_frootxf_acc_patch (:) ! (gN/m2/year) N turnover from root transfer
+ real(r8), pointer :: matrix_nturnover_livestem_acc_patch (:) ! (gN/m2/year) N turnover from live stem
+ real(r8), pointer :: matrix_nturnover_livestemst_acc_patch (:) ! (gN/m2/year) N turnover from live stem storage
+ real(r8), pointer :: matrix_nturnover_livestemxf_acc_patch (:) ! (gN/m2/year) N turnover from live stem transfer
+ real(r8), pointer :: matrix_nturnover_deadstem_acc_patch (:) ! (gN/m2/year) N turnover from dead stem
+ real(r8), pointer :: matrix_nturnover_deadstemst_acc_patch (:) ! (gN/m2/year) N turnover from dead stem storage
+ real(r8), pointer :: matrix_nturnover_deadstemxf_acc_patch (:) ! (gN/m2/year) N turnover from dead stem transfer
+ real(r8), pointer :: matrix_nturnover_livecroot_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root
+ real(r8), pointer :: matrix_nturnover_livecrootst_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root storage
+ real(r8), pointer :: matrix_nturnover_livecrootxf_acc_patch (:) ! (gN/m2/year) N turnover from live coarse root transfer
+ real(r8), pointer :: matrix_nturnover_deadcroot_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root
+ real(r8), pointer :: matrix_nturnover_deadcrootst_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root storage
+ real(r8), pointer :: matrix_nturnover_deadcrootxf_acc_patch (:) ! (gN/m2/year) N turnover from dead coarse root transfer
+ real(r8), pointer :: matrix_nturnover_grain_acc_patch (:) ! (gN/m2/year) N turnover from grain
+ real(r8), pointer :: matrix_nturnover_grainst_acc_patch (:) ! (gN/m2/year) N turnover from grain storage
+ real(r8), pointer :: matrix_nturnover_grainxf_acc_patch (:) ! (gN/m2/year) N turnover from grain transfer
+ real(r8), pointer :: matrix_nturnover_retransn_acc_patch (:) ! (gN/m2/year) N turnover from retranslocation transfer
+
+ real(r8), pointer :: grainn_SASUsave_patch (:) ! (gC/m2) grain C (crop model)
+ real(r8), pointer :: grainn_storage_SASUsave_patch (:) ! (gC/m2) grain C storage (crop model)
+ real(r8), pointer :: leafn_SASUsave_patch (:) ! (gC/m2) leaf C
+ real(r8), pointer :: leafn_storage_SASUsave_patch (:) ! (gC/m2) leaf C storage
+ real(r8), pointer :: leafn_xfer_SASUsave_patch (:) ! (gC/m2) leaf C transfer
+ real(r8), pointer :: frootn_SASUsave_patch (:) ! (gC/m2) fine root C
+ real(r8), pointer :: frootn_storage_SASUsave_patch (:) ! (gC/m2) fine root C storage
+ real(r8), pointer :: frootn_xfer_SASUsave_patch (:) ! (gC/m2) fine root C transfer
+ real(r8), pointer :: livestemn_SASUsave_patch (:) ! (gC/m2) live stem C
+ real(r8), pointer :: livestemn_storage_SASUsave_patch (:) ! (gC/m2) live stem C storage
+ real(r8), pointer :: livestemn_xfer_SASUsave_patch (:) ! (gC/m2) live stem C transfer
+ real(r8), pointer :: deadstemn_SASUsave_patch (:) ! (gC/m2) dead stem C
+ real(r8), pointer :: deadstemn_storage_SASUsave_patch (:) ! (gC/m2) dead stem C storage
+ real(r8), pointer :: deadstemn_xfer_SASUsave_patch (:) ! (gC/m2) dead stem C transfer
+ real(r8), pointer :: livecrootn_SASUsave_patch (:) ! (gC/m2) live coarse root C
+ real(r8), pointer :: livecrootn_storage_SASUsave_patch (:) ! (gC/m2) live coarse root C storage
+ real(r8), pointer :: livecrootn_xfer_SASUsave_patch (:) ! (gC/m2) live coarse root C transfer
+ real(r8), pointer :: deadcrootn_SASUsave_patch (:) ! (gC/m2) dead coarse root C
+ real(r8), pointer :: deadcrootn_storage_SASUsave_patch (:) ! (gC/m2) dead coarse root C storage
+ real(r8), pointer :: deadcrootn_xfer_SASUsave_patch (:) ! (gC/m2) dead coarse root C transfer
contains
@@ -142,14 +276,29 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%reproductiven_patch (begp:endp, nrepr)) ; this%reproductiven_patch (:,:) = nan
allocate(this%reproductiven_storage_patch (begp:endp, nrepr)) ; this%reproductiven_storage_patch (:,:) = nan
allocate(this%reproductiven_xfer_patch (begp:endp, nrepr)) ; this%reproductiven_xfer_patch (:,:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_repron_patch (begp:endp)) ; this%matrix_cap_repron_patch (:) = nan
+ allocate(this%matrix_cap_repron_storage_patch (begp:endp)) ; this%matrix_cap_repron_storage_patch (:) = nan
+ allocate(this%matrix_cap_repron_xfer_patch (begp:endp)) ; this%matrix_cap_repron_xfer_patch (:) = nan
+ end if
allocate(this%leafn_patch (begp:endp)) ; this%leafn_patch (:) = nan
allocate(this%leafn_storage_patch (begp:endp)) ; this%leafn_storage_patch (:) = nan
allocate(this%leafn_xfer_patch (begp:endp)) ; this%leafn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_leafn_patch (begp:endp)) ; this%matrix_cap_leafn_patch (:) = nan
+ allocate(this%matrix_cap_leafn_storage_patch (begp:endp)) ; this%matrix_cap_leafn_storage_patch (:) = nan
+ allocate(this%matrix_cap_leafn_xfer_patch (begp:endp)) ; this%matrix_cap_leafn_xfer_patch (:) = nan
+ end if
allocate(this%leafn_storage_xfer_acc_patch (begp:endp)) ; this%leafn_storage_xfer_acc_patch (:) = nan
allocate(this%storage_ndemand_patch (begp:endp)) ; this%storage_ndemand_patch (:) = nan
allocate(this%frootn_patch (begp:endp)) ; this%frootn_patch (:) = nan
allocate(this%frootn_storage_patch (begp:endp)) ; this%frootn_storage_patch (:) = nan
allocate(this%frootn_xfer_patch (begp:endp)) ; this%frootn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_frootn_patch (begp:endp)) ; this%matrix_cap_frootn_patch (:) = nan
+ allocate(this%matrix_cap_frootn_storage_patch (begp:endp)) ; this%matrix_cap_frootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_frootn_xfer_patch (begp:endp)) ; this%matrix_cap_frootn_xfer_patch (:) = nan
+ end if
allocate(this%livestemn_patch (begp:endp)) ; this%livestemn_patch (:) = nan
allocate(this%livestemn_storage_patch (begp:endp)) ; this%livestemn_storage_patch (:) = nan
allocate(this%livestemn_xfer_patch (begp:endp)) ; this%livestemn_xfer_patch (:) = nan
@@ -162,6 +311,20 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%deadcrootn_patch (begp:endp)) ; this%deadcrootn_patch (:) = nan
allocate(this%deadcrootn_storage_patch (begp:endp)) ; this%deadcrootn_storage_patch (:) = nan
allocate(this%deadcrootn_xfer_patch (begp:endp)) ; this%deadcrootn_xfer_patch (:) = nan
+ if(use_matrixcn)then
+ allocate(this%matrix_cap_livestemn_patch (begp:endp)) ; this%matrix_cap_livestemn_patch (:) = nan
+ allocate(this%matrix_cap_livestemn_storage_patch (begp:endp)) ; this%matrix_cap_livestemn_storage_patch (:) = nan
+ allocate(this%matrix_cap_livestemn_xfer_patch (begp:endp)) ; this%matrix_cap_livestemn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_patch (begp:endp)) ; this%matrix_cap_deadstemn_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_storage_patch (begp:endp)) ; this%matrix_cap_deadstemn_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadstemn_xfer_patch (begp:endp)) ; this%matrix_cap_deadstemn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_patch (begp:endp)) ; this%matrix_cap_livecrootn_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_storage_patch (begp:endp)) ; this%matrix_cap_livecrootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_livecrootn_xfer_patch (begp:endp)) ; this%matrix_cap_livecrootn_xfer_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_patch (begp:endp)) ; this%matrix_cap_deadcrootn_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_storage_patch (begp:endp)) ; this%matrix_cap_deadcrootn_storage_patch (:) = nan
+ allocate(this%matrix_cap_deadcrootn_xfer_patch (begp:endp)) ; this%matrix_cap_deadcrootn_xfer_patch (:) = nan
+ end if
allocate(this%retransn_patch (begp:endp)) ; this%retransn_patch (:) = nan
allocate(this%npool_patch (begp:endp)) ; this%npool_patch (:) = nan
allocate(this%ntrunc_patch (begp:endp)) ; this%ntrunc_patch (:) = nan
@@ -176,8 +339,125 @@ subroutine InitAllocate(this, bounds, alloc_full_veg)
allocate(this%totn_p2c_col (begc:endc)) ; this%totn_p2c_col (:) = nan
- ! Matrix solution allocations
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ allocate(this%leafn0_patch (begp:endp)) ; this%leafn0_patch (:) = nan
+ allocate(this%leafn0_storage_patch (begp:endp)) ; this%leafn0_storage_patch (:) = nan
+ allocate(this%leafn0_xfer_patch (begp:endp)) ; this%leafn0_xfer_patch (:) = nan
+ allocate(this%frootn0_patch (begp:endp)) ; this%frootn0_patch (:) = nan
+ allocate(this%frootn0_storage_patch (begp:endp)) ; this%frootn0_storage_patch (:) = nan
+ allocate(this%frootn0_xfer_patch (begp:endp)) ; this%frootn0_xfer_patch (:) = nan
+ allocate(this%livestemn0_patch (begp:endp)) ; this%livestemn0_patch (:) = nan
+ allocate(this%livestemn0_storage_patch (begp:endp)) ; this%livestemn0_storage_patch (:) = nan
+ allocate(this%livestemn0_xfer_patch (begp:endp)) ; this%livestemn0_xfer_patch (:) = nan
+ allocate(this%deadstemn0_patch (begp:endp)) ; this%deadstemn0_patch (:) = nan
+ allocate(this%deadstemn0_storage_patch (begp:endp)) ; this%deadstemn0_storage_patch (:) = nan
+ allocate(this%deadstemn0_xfer_patch (begp:endp)) ; this%deadstemn0_xfer_patch (:) = nan
+ allocate(this%livecrootn0_patch (begp:endp)) ; this%livecrootn0_patch (:) = nan
+ allocate(this%livecrootn0_storage_patch (begp:endp)) ; this%livecrootn0_storage_patch (:) = nan
+ allocate(this%livecrootn0_xfer_patch (begp:endp)) ; this%livecrootn0_xfer_patch (:) = nan
+ allocate(this%deadcrootn0_patch (begp:endp)) ; this%deadcrootn0_patch (:) = nan
+ allocate(this%deadcrootn0_storage_patch (begp:endp)) ; this%deadcrootn0_storage_patch (:) = nan
+ allocate(this%deadcrootn0_xfer_patch (begp:endp)) ; this%deadcrootn0_xfer_patch (:) = nan
+ allocate(this%repron0_patch (begp:endp)) ; this%repron0_patch (:) = nan
+ allocate(this%repron0_storage_patch (begp:endp)) ; this%repron0_storage_patch (:) = nan
+ allocate(this%repron0_xfer_patch (begp:endp)) ; this%repron0_xfer_patch (:) = nan
+ allocate(this%retransn0_patch (begp:endp)) ; this%retransn0_patch (:) = nan
+
+ allocate(this%leafn_SASUsave_patch (begp:endp)) ; this%leafn_SASUsave_patch (:) = nan
+ allocate(this%leafn_storage_SASUsave_patch (begp:endp)) ; this%leafn_storage_SASUsave_patch (:) = nan
+ allocate(this%leafn_xfer_SASUsave_patch (begp:endp)) ; this%leafn_xfer_SASUsave_patch (:) = nan
+ allocate(this%frootn_SASUsave_patch (begp:endp)) ; this%frootn_SASUsave_patch (:) = nan
+ allocate(this%frootn_storage_SASUsave_patch (begp:endp)) ; this%frootn_storage_SASUsave_patch (:) = nan
+ allocate(this%frootn_xfer_SASUsave_patch (begp:endp)) ; this%frootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%livestemn_SASUsave_patch (begp:endp)) ; this%livestemn_SASUsave_patch (:) = nan
+ allocate(this%livestemn_storage_SASUsave_patch (begp:endp)) ; this%livestemn_storage_SASUsave_patch (:) = nan
+ allocate(this%livestemn_xfer_SASUsave_patch (begp:endp)) ; this%livestemn_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_SASUsave_patch (begp:endp)) ; this%deadstemn_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_storage_SASUsave_patch (begp:endp)) ; this%deadstemn_storage_SASUsave_patch (:) = nan
+ allocate(this%deadstemn_xfer_SASUsave_patch (begp:endp)) ; this%deadstemn_xfer_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_SASUsave_patch (begp:endp)) ; this%livecrootn_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_storage_SASUsave_patch (begp:endp)) ; this%livecrootn_storage_SASUsave_patch (:) = nan
+ allocate(this%livecrootn_xfer_SASUsave_patch (begp:endp)) ; this%livecrootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_SASUsave_patch (begp:endp)) ; this%deadcrootn_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_storage_SASUsave_patch (begp:endp)) ; this%deadcrootn_storage_SASUsave_patch (:) = nan
+ allocate(this%deadcrootn_xfer_SASUsave_patch (begp:endp)) ; this%deadcrootn_xfer_SASUsave_patch (:) = nan
+ allocate(this%grainn_SASUsave_patch (begp:endp)) ; this%grainn_SASUsave_patch (:) = nan
+ allocate(this%grainn_storage_SASUsave_patch (begp:endp)) ; this%grainn_storage_SASUsave_patch (:) = nan
+
+ allocate(this%matrix_nalloc_leaf_acc_patch (begp:endp)) ; this%matrix_nalloc_leaf_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_leafst_acc_patch (begp:endp)) ; this%matrix_nalloc_leafst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_froot_acc_patch (begp:endp)) ; this%matrix_nalloc_froot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_frootst_acc_patch (begp:endp)) ; this%matrix_nalloc_frootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livestem_acc_patch (begp:endp)) ; this%matrix_nalloc_livestem_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livestemst_acc_patch (begp:endp)) ; this%matrix_nalloc_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadstem_acc_patch (begp:endp)) ; this%matrix_nalloc_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadstemst_acc_patch (begp:endp)) ; this%matrix_nalloc_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livecroot_acc_patch (begp:endp)) ; this%matrix_nalloc_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_livecrootst_acc_patch (begp:endp)) ; this%matrix_nalloc_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadcroot_acc_patch (begp:endp)) ; this%matrix_nalloc_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_deadcrootst_acc_patch (begp:endp)) ; this%matrix_nalloc_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_grain_acc_patch (begp:endp)) ; this%matrix_nalloc_grain_acc_patch (:) = nan
+ allocate(this%matrix_nalloc_grainst_acc_patch (begp:endp)) ; this%matrix_nalloc_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_leafst_to_leafxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_leafst_to_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_leafxf_to_leaf_acc_patch (begp:endp)) ; this%matrix_ntransfer_leafxf_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_frootst_to_frootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_frootst_to_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_frootxf_to_froot_acc_patch (begp:endp)) ; this%matrix_ntransfer_frootxf_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_grainst_to_grainxf_acc_patch (begp:endp)) ; this%matrix_ntransfer_grainst_to_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_grainxf_to_grain_acc_patch (begp:endp)) ; this%matrix_ntransfer_grainxf_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestem_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestem_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_retransn_to_leaf_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_leaf_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_leafst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_leafst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_froot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_froot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_frootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_frootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livestem_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livestem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livestemst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadstem_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livecroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_grain_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_grain_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_retransn_to_grainst_acc_patch (begp:endp)) ; this%matrix_ntransfer_retransn_to_grainst_acc_patch (:) = nan
+
+ allocate(this%matrix_ntransfer_leaf_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_leaf_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_froot_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_froot_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livestem_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_livestem_to_retransn_acc_patch (:) = nan
+ allocate(this%matrix_ntransfer_livecroot_to_retransn_acc_patch (begp:endp)) ; this%matrix_ntransfer_livecroot_to_retransn_acc_patch (:) = nan
+
+ allocate(this%matrix_nturnover_leaf_acc_patch (begp:endp)) ; this%matrix_nturnover_leaf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_leafst_acc_patch (begp:endp)) ; this%matrix_nturnover_leafst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_leafxf_acc_patch (begp:endp)) ; this%matrix_nturnover_leafxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_froot_acc_patch (begp:endp)) ; this%matrix_nturnover_froot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_frootst_acc_patch (begp:endp)) ; this%matrix_nturnover_frootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_frootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_frootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestem_acc_patch (begp:endp)) ; this%matrix_nturnover_livestem_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestemst_acc_patch (begp:endp)) ; this%matrix_nturnover_livestemst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livestemxf_acc_patch (begp:endp)) ; this%matrix_nturnover_livestemxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstem_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstem_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstemst_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstemst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadstemxf_acc_patch (begp:endp)) ; this%matrix_nturnover_deadstemxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecroot_acc_patch (begp:endp)) ; this%matrix_nturnover_livecroot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecrootst_acc_patch (begp:endp)) ; this%matrix_nturnover_livecrootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_livecrootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_livecrootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcroot_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcroot_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcrootst_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcrootst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_deadcrootxf_acc_patch (begp:endp)) ; this%matrix_nturnover_deadcrootxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grain_acc_patch (begp:endp)) ; this%matrix_nturnover_grain_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grainst_acc_patch (begp:endp)) ; this%matrix_nturnover_grainst_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_grainxf_acc_patch (begp:endp)) ; this%matrix_nturnover_grainxf_acc_patch (:) = nan
+ allocate(this%matrix_nturnover_retransn_acc_patch (begp:endp)) ; this%matrix_nturnover_retransn_acc_patch (:) = nan
end if
end subroutine InitAllocate
@@ -246,8 +526,22 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='leaf N transfer', &
ptr_patch=this%leafn_xfer_patch, default='inactive')
- ! Matrix solution history fields
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N capacity', &
+ ptr_patch=this%matrix_cap_leafn_patch)
+
+ this%matrix_cap_leafn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N storage capacity', &
+ ptr_patch=this%matrix_cap_leafn_storage_patch, default='inactive')
+
+ this%matrix_cap_leafn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LEAFN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='leaf N transfer capacity', &
+ ptr_patch=this%matrix_cap_leafn_xfer_patch, default='inactive')
+
end if
if ( use_fun ) then
@@ -277,6 +571,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='fine root N transfer', &
ptr_patch=this%frootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N capacity', &
+ ptr_patch=this%matrix_cap_frootn_patch)
+
+ this%matrix_cap_frootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N storage capacity', &
+ ptr_patch=this%matrix_cap_frootn_storage_patch, default='inactive')
+
+ this%matrix_cap_frootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='FROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='fine root N transfer capacity', &
+ ptr_patch=this%matrix_cap_frootn_xfer_patch, default='inactive')
+
+ end if
+
this%livestemn_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVESTEMN', units='gN/m^2', &
avgflag='A', long_name='live stem N', &
@@ -292,6 +604,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='live stem N transfer', &
ptr_patch=this%livestemn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livestemn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N capacity', &
+ ptr_patch=this%matrix_cap_livestemn_patch)
+
+ this%matrix_cap_livestemn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N storage capacity', &
+ ptr_patch=this%matrix_cap_livestemn_storage_patch, default='inactive')
+
+ this%matrix_cap_livestemn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVESTEMN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live stem N transfer capacity', &
+ ptr_patch=this%matrix_cap_livestemn_xfer_patch, default='inactive')
+
+ end if
+
this%deadstemn_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADSTEMN', units='gN/m^2', &
avgflag='A', long_name='dead stem N', &
@@ -307,6 +637,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='dead stem N transfer', &
ptr_patch=this%deadstemn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_patch)
+
+ this%matrix_cap_deadstemn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N storage capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_storage_patch, default='inactive')
+
+ this%matrix_cap_deadstemn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADSTEMN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead stem N transfer capacity', &
+ ptr_patch=this%matrix_cap_deadstemn_xfer_patch, default='inactive')
+
+ end if
+
this%livecrootn_patch(begp:endp) = spval
call hist_addfld1d (fname='LIVECROOTN', units='gN/m^2', &
avgflag='A', long_name='live coarse root N', &
@@ -322,6 +670,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='live coarse root N transfer', &
ptr_patch=this%livecrootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_patch)
+
+ this%matrix_cap_livecrootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N storage capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_storage_patch, default='inactive')
+
+ this%matrix_cap_livecrootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='LIVECROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='live coarse root N transfer capacity', &
+ ptr_patch=this%matrix_cap_livecrootn_xfer_patch, default='inactive')
+
+ end if
+
this%deadcrootn_patch(begp:endp) = spval
call hist_addfld1d (fname='DEADCROOTN', units='gN/m^2', &
avgflag='A', long_name='dead coarse root N', &
@@ -337,6 +703,24 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='dead coarse root N transfer', &
ptr_patch=this%deadcrootn_xfer_patch, default='inactive')
+ if(use_matrixcn)then
+ this%matrix_cap_deadcrootn_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_patch)
+
+ this%matrix_cap_deadcrootn_storage_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_STORAGE_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N storage capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_storage_patch, default='inactive')
+
+ this%matrix_cap_deadcrootn_xfer_patch(begp:endp) = spval
+ call hist_addfld1d (fname='DEADCROOTN_XFER_CAP', units='gN/m^2', &
+ avgflag='I', long_name='dead coarse root N transfer capacity', &
+ ptr_patch=this%matrix_cap_deadcrootn_xfer_patch, default='inactive')
+
+ end if
+
this%retransn_patch(begp:endp) = spval
call hist_addfld1d (fname='RETRANSN', units='gN/m^2', &
avgflag='A', long_name='plant pool of retranslocated N', &
@@ -450,37 +834,38 @@ subroutine InitCold(this, bounds, &
if (patch%itype(p) == noveg) then
this%leafn_patch(p) = 0._r8
this%leafn_storage_patch(p) = 0._r8
-
- ! Matrix solution settings for bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = 0._r8
+ this%matrix_cap_leafn_storage_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- ! Matrix solution settings for bare-soil and flex-CN
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
else
this%leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
this%leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
-
- ! Matrix solution settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
+ this%matrix_cap_leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
this%frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
- ! Matrix solution settings for flex-CN
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
+ this%matrix_cap_frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
end if
end if
end if
this%leafn_xfer_patch(p) = 0._r8
- ! Matrix solution settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_xfer_patch(p) = 0._r8
end if
this%leafn_storage_xfer_acc_patch(p) = 0._r8
@@ -490,27 +875,30 @@ subroutine InitCold(this, bounds, &
this%reproductiven_patch(p,:) = 0._r8
this%reproductiven_storage_patch(p,:) = 0._r8
this%reproductiven_xfer_patch(p,:) = 0._r8
- this%cropseedn_deficit_patch(p) = 0._r8
-
- ! Matrix reproductive pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_repron_patch(p) = 0._r8
+ this%matrix_cap_repron_storage_patch(p) = 0._r8
+ this%matrix_cap_repron_xfer_patch(p) = 0._r8
end if
+ this%cropseedn_deficit_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- ! Matrix pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
this%frootn_xfer_patch(p) = 0._r8
this%livestemn_patch(p) = 0._r8
this%livestemn_storage_patch(p) = 0._r8
this%livestemn_xfer_patch(p) = 0._r8
-
- ! Matrix pool settings
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_livestemn_patch(p) = 0._r8
+ this%matrix_cap_livestemn_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemn_xfer_patch(p) = 0._r8
end if
! tree types need to be initialized with some stem mass so that
@@ -518,17 +906,21 @@ subroutine InitCold(this, bounds, &
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
end if
else
this%deadstemn_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = 0._r8
end if
end if
this%deadstemn_storage_patch(p) = 0._r8
this%deadstemn_xfer_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemn_xfer_patch(p) = 0._r8
end if
this%livecrootn_patch(p) = 0._r8
@@ -537,6 +929,14 @@ subroutine InitCold(this, bounds, &
this%deadcrootn_patch(p) = 0._r8
this%deadcrootn_storage_patch(p) = 0._r8
this%deadcrootn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_xfer_patch(p) = 0._r8
+ end if
this%retransn_patch(p) = 0._r8
this%npool_patch(p) = 0._r8
this%ntrunc_patch(p) = 0._r8
@@ -544,6 +944,128 @@ subroutine InitCold(this, bounds, &
this%storvegn_patch(p) = 0._r8
this%totvegn_patch(p) = 0._r8
this%totn_patch(p) = 0._r8
+
+ if(use_matrixcn)then
+ ! for matrix spin up and capacity calculation
+ this%leafn0_patch(p) = 1.e-30_r8
+ this%leafn0_storage_patch(p) = 1.e-30_r8
+ this%leafn0_xfer_patch(p) = 1.e-30_r8
+ this%frootn0_patch(p) = 1.e-30_r8
+ this%frootn0_storage_patch(p) = 1.e-30_r8
+ this%frootn0_xfer_patch(p) = 1.e-30_r8
+ this%livestemn0_patch(p) = 1.e-30_r8
+ this%livestemn0_storage_patch(p) = 1.e-30_r8
+ this%livestemn0_xfer_patch(p) = 1.e-30_r8
+ this%deadstemn0_patch(p) = 1.e-30_r8
+ this%deadstemn0_storage_patch(p) = 1.e-30_r8
+ this%deadstemn0_xfer_patch(p) = 1.e-30_r8
+ this%livecrootn0_patch(p) = 1.e-30_r8
+ this%livecrootn0_storage_patch(p) = 1.e-30_r8
+ this%livecrootn0_xfer_patch(p) = 1.e-30_r8
+ this%deadcrootn0_patch(p) = 1.e-30_r8
+ this%deadcrootn0_storage_patch(p) = 1.e-30_r8
+ this%deadcrootn0_xfer_patch(p) = 1.e-30_r8
+ this%repron0_patch(p) = 1.e-30_r8
+ this%repron0_storage_patch(p) = 1.e-30_r8
+ this%repron0_xfer_patch(p) = 1.e-30_r8
+ this%retransn0_patch(p) = 1.e-30_r8
+
+ this%leafn_SASUsave_patch(p) = 0._r8
+ this%leafn_storage_SASUsave_patch(p) = 0._r8
+ this%leafn_xfer_SASUsave_patch(p) = 0._r8
+ this%frootn_SASUsave_patch(p) = 0._r8
+ this%frootn_storage_SASUsave_patch(p) = 0._r8
+ this%frootn_xfer_SASUsave_patch(p) = 0._r8
+ this%livestemn_SASUsave_patch(p) = 0._r8
+ this%livestemn_storage_SASUsave_patch(p) = 0._r8
+ this%livestemn_xfer_SASUsave_patch(p) = 0._r8
+ this%deadstemn_SASUsave_patch(p) = 0._r8
+ this%deadstemn_storage_SASUsave_patch(p) = 0._r8
+ this%deadstemn_xfer_SASUsave_patch(p) = 0._r8
+ this%livecrootn_SASUsave_patch(p) = 0._r8
+ this%livecrootn_storage_SASUsave_patch(p) = 0._r8
+ this%livecrootn_xfer_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_storage_SASUsave_patch(p) = 0._r8
+ this%deadcrootn_xfer_SASUsave_patch(p) = 0._r8
+ this%grainn_SASUsave_patch(p) = 0._r8
+ this%grainn_storage_SASUsave_patch(p) = 0._r8
+
+ this%matrix_nalloc_leaf_acc_patch (p) = 0._r8
+ this%matrix_nalloc_leafst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_froot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_frootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livestem_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livestemst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadstem_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livecroot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_nalloc_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_nalloc_grain_acc_patch (p) = 0._r8
+ this%matrix_nalloc_grainst_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_leafst_to_leafxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_leafxf_to_leaf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_frootst_to_frootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_frootxf_to_froot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestemxf_to_livestem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_grainst_to_grainxf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_grainxf_to_grain_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestem_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_retransn_to_leaf_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_leafst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_froot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_frootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livestem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livestemst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadstem_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livecroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_grain_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_retransn_to_grainst_acc_patch (p) = 0._r8
+
+ this%matrix_ntransfer_leaf_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_froot_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livestem_to_retransn_acc_patch (p) = 0._r8
+ this%matrix_ntransfer_livecroot_to_retransn_acc_patch (p) = 0._r8
+
+ this%matrix_nturnover_leaf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_leafst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_leafxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_froot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_frootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_frootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestem_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestemst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livestemxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstem_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstemst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadstemxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecroot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecrootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_livecrootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcroot_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcrootst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_deadcrootxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grain_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grainst_acc_patch (p) = 0._r8
+ this%matrix_nturnover_grainxf_acc_patch (p) = 0._r8
+ this%matrix_nturnover_retransn_acc_patch (p) = 0._r8
+ end if !use_matrixcn
end if
end do
@@ -635,12 +1157,74 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='leafn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafn_xfer_patch)
+!matrix
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_leafn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='leafn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%leafn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leafst_to_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leafst_to_leafxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leafxf_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leafxf_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_restransn_to_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_restransn_to_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_leaf_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_leaf_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leaf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leaf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leafst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leafst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_leafxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_leafxf_acc_patch)
+ end if
- ! Matrix restart variables
- if ( use_matrixcn )then
- end if
-
- if ( use_fun ) then
+ if ( use_fun ) then
call restartvar(ncid=ncid, flag=flag, varname='leafn_storage_xfer_acc', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%leafn_storage_xfer_acc_patch)
@@ -648,7 +1232,7 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='storage_ndemand', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%storage_ndemand_patch)
- end if
+ end if
call restartvar(ncid=ncid, flag=flag, varname='frootn', xtype=ncd_double, &
@@ -662,6 +1246,72 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='frootn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%frootn_xfer_patch)
+
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_frootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='frootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%frootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_frootst_to_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_frootst_to_frootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_frootxf_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_frootxf_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_froot_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_froot_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_froot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_froot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_frootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_frootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_frootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_frootxf_acc_patch)
+ end if
call restartvar(ncid=ncid, flag=flag, varname='livestemn', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
@@ -710,6 +1360,272 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_xfer', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
interpinic_flag='interp', readvar=readvar, data=this%deadcrootn_xfer_patch)
+
+ if(use_matrixcn)then
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livestemn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadstemn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_livecrootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_storage_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn_xfer_cap', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_deadcrootn_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livestemn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livestemn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestemst_to_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestemxf_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestemxf_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestem_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestem_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livestem_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livestem_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livestemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livestemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadstemn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadstemn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadstemst_to_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadstemxf_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstem_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstem_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstemst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstemst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadstemxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadstemxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='livecrootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%livecrootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecrootst_to_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecrootxf_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecroot_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_livecroot_to_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_livecroot_to_retransn_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_livecrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_livecrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='deadcrootn0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%deadcrootn0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='retransn0', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%retransn0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadcrootst_to_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_deadcrootxf_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcroot_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcroot_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcrootst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcrootst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_deadcrootxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_deadcrootxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_retransn_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_retransn_acc_patch)
+ end if
call restartvar(ncid=ncid, flag=flag, varname='retransn', xtype=ncd_double, &
dim1name='pft', long_name='', units='', &
@@ -748,9 +1664,70 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
interpinic_flag='interp', readvar=readvar, data=data1dptr)
end do
+ if(use_matrixcn)then
+!--- Modify this...
+! call restartvar(ncid=ncid, flag=flag, varname='repron_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_patch)
+!
+! call restartvar(ncid=ncid, flag=flag, varname='repron_storage_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N storage capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_storage_patch)
+!
+! call restartvar(ncid=ncid, flag=flag, varname='repron_xfer_cap', xtype=ncd_double, &
+! dim1name='pft', long_name='grain N transfer capacity', units='gN/m2', &
+! interpinic_flag='interp', readvar=readvar, data=this%matrix_cap_repron_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0_storage', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0 storage', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_storage_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='repron0_xfer', xtype=ncd_double, &
+ dim1name='pft', long_name='Reproductive N0 transfer', units='gN/m2', &
+ interpinic_flag='interp', readvar=readvar, data=this%repron0_xfer_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nalloc_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nalloc_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_grainst_to_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_grainst_to_grainxf_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_grainxf_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_grainxf_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_ntransfer_retransn_to_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_ntransfer_retransn_to_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grain_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grain_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grainst_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grainst_acc_patch)
+
+ call restartvar(ncid=ncid, flag=flag, varname='matrix_nturnover_grainxf_acc', xtype=ncd_double, &
+ dim1name='pft', long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=this%matrix_nturnover_grainxf_acc_patch)
+ end if
do k = 1, nrepr
data1dptr => this%reproductiven_xfer_patch(:,k)
- ! e.g., grain-N_xfer
varname = get_repr_rest_fname(k)//'n_xfer'
call restartvar(ncid=ncid, flag=flag, varname=varname, &
xtype=ncd_double, &
@@ -825,32 +1802,38 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
if (patch%itype(p) == noveg) then
this%leafn_patch(p) = 0._r8
this%leafn_storage_patch(p) = 0._r8
-
- ! Set matrix solution variables for bare-soil
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = 0._r8
+ this%matrix_cap_leafn_storage_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
else
this%leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
this%leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(p) = leafc_patch(p) / pftcon%leafcn(patch%itype(p))
+ this%matrix_cap_leafn_storage_patch(p) = leafc_storage_patch(p) / pftcon%leafcn(patch%itype(p))
end if
if (MM_Nuptake_opt .eqv. .true.) then
this%frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
this%frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = frootc_patch(p) / pftcon%frootcn(patch%itype(p))
+ this%matrix_cap_frootn_storage_patch(p) = frootc_storage_patch(p) / pftcon%frootcn(patch%itype(p))
end if
end if
end if
this%leafn_xfer_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_xfer_patch(p) = 0._r8
end if
this%leafn_storage_xfer_acc_patch(p) = 0._r8
@@ -860,24 +1843,30 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
this%reproductiven_patch(p,:) = 0._r8
this%reproductiven_storage_patch(p,:) = 0._r8
this%reproductiven_xfer_patch(p,:) = 0._r8
- this%cropseedn_deficit_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_repron_patch(p) = 0._r8
+ this%matrix_cap_repron_storage_patch(p) = 0._r8
+ this%matrix_cap_repron_xfer_patch(p) = 0._r8
end if
+ this%cropseedn_deficit_patch(p) = 0._r8
end if
if (MM_Nuptake_opt .eqv. .false.) then ! if not running in floating CN ratio option
this%frootn_patch(p) = 0._r8
this%frootn_storage_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_patch(p) = 0._r8
+ this%matrix_cap_frootn_storage_patch(p) = 0._r8
end if
end if
this%frootn_xfer_patch(p) = 0._r8
this%livestemn_patch(p) = 0._r8
this%livestemn_storage_patch(p) = 0._r8
this%livestemn_xfer_patch(p) = 0._r8
-
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_frootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_livestemn_patch(p) = 0._r8
+ this%matrix_cap_livestemn_storage_patch(p) = 0._r8
+ this%matrix_cap_livestemn_xfer_patch(p) = 0._r8
end if
! tree types need to be initialized with some stem mass so that
@@ -885,22 +1874,37 @@ subroutine Restart ( this, bounds, ncid, flag, leafc_patch, &
if (pftcon%woody(patch%itype(p)) == 1._r8) then
this%deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = deadstemc_patch(p) / pftcon%deadwdcn(patch%itype(p))
end if
else
this%deadstemn_patch(p) = 0._r8
- if ( use_matrixcn )then
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_patch(p) = 0._r8
end if
end if
this%deadstemn_storage_patch(p) = 0._r8
this%deadstemn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_deadstemn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadstemn_xfer_patch(p) = 0._r8
+ end if
+
this%livecrootn_patch(p) = 0._r8
this%livecrootn_storage_patch(p) = 0._r8
this%livecrootn_xfer_patch(p) = 0._r8
this%deadcrootn_patch(p) = 0._r8
this%deadcrootn_storage_patch(p) = 0._r8
this%deadcrootn_xfer_patch(p) = 0._r8
+ if(use_matrixcn)then
+ this%matrix_cap_livecrootn_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_livecrootn_xfer_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_storage_patch(p) = 0._r8
+ this%matrix_cap_deadcrootn_xfer_patch(p) = 0._r8
+ end if
this%retransn_patch(p) = 0._r8
this%npool_patch(p) = 0._r8
this%ntrunc_patch(p) = 0._r8
@@ -991,6 +1995,131 @@ subroutine SetValues ( this, &
this%deadcrootn_patch(i) = value_patch
this%deadcrootn_storage_patch(i) = value_patch
this%deadcrootn_xfer_patch(i) = value_patch
+ if(use_matrixcn)then
+ this%matrix_cap_leafn_patch(i) = value_patch
+ this%matrix_cap_leafn_storage_patch(i) = value_patch
+ this%matrix_cap_leafn_xfer_patch(i) = value_patch
+ this%matrix_cap_frootn_patch(i) = value_patch
+ this%matrix_cap_frootn_storage_patch(i) = value_patch
+ this%matrix_cap_frootn_xfer_patch(i) = value_patch
+ this%matrix_cap_livestemn_patch(i) = value_patch
+ this%matrix_cap_livestemn_storage_patch(i) = value_patch
+ this%matrix_cap_livestemn_xfer_patch(i) = value_patch
+ this%matrix_cap_deadstemn_patch(i) = value_patch
+ this%matrix_cap_deadstemn_storage_patch(i) = value_patch
+ this%matrix_cap_deadstemn_xfer_patch(i) = value_patch
+ this%matrix_cap_livecrootn_patch(i) = value_patch
+ this%matrix_cap_livecrootn_storage_patch(i) = value_patch
+ this%matrix_cap_livecrootn_xfer_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_storage_patch(i) = value_patch
+ this%matrix_cap_deadcrootn_xfer_patch(i) = value_patch
+
+ this%leafn0_patch(i) = value_patch
+ this%leafn0_storage_patch(i) = value_patch
+ this%leafn0_xfer_patch(i) = value_patch
+ this%frootn0_patch(i) = value_patch
+ this%frootn0_storage_patch(i) = value_patch
+ this%frootn0_xfer_patch(i) = value_patch
+ this%livestemn0_patch(i) = value_patch
+ this%livestemn0_storage_patch(i) = value_patch
+ this%livestemn0_xfer_patch(i) = value_patch
+ this%deadstemn0_patch(i) = value_patch
+ this%deadstemn0_storage_patch(i) = value_patch
+ this%deadstemn0_xfer_patch(i) = value_patch
+ this%livecrootn0_patch(i) = value_patch
+ this%livecrootn0_storage_patch(i) = value_patch
+ this%livecrootn0_xfer_patch(i) = value_patch
+ this%deadcrootn0_patch(i) = value_patch
+ this%deadcrootn0_storage_patch(i) = value_patch
+ this%deadcrootn0_xfer_patch(i) = value_patch
+ if ( use_crop )then
+ this%repron0_patch(i) = value_patch
+ this%repron0_storage_patch(i) = value_patch
+ this%repron0_xfer_patch(i) = value_patch
+ end if
+ this%retransn0_patch(i) = value_patch
+
+ this%matrix_nalloc_leaf_acc_patch(i) = value_patch
+ this%matrix_nalloc_leafst_acc_patch(i) = value_patch
+ this%matrix_nalloc_froot_acc_patch(i) = value_patch
+ this%matrix_nalloc_frootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_livestem_acc_patch(i) = value_patch
+ this%matrix_nalloc_livestemst_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadstem_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadstemst_acc_patch(i) = value_patch
+ this%matrix_nalloc_livecroot_acc_patch(i) = value_patch
+ this%matrix_nalloc_livecrootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadcroot_acc_patch(i) = value_patch
+ this%matrix_nalloc_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_nalloc_grain_acc_patch(i) = value_patch
+ this%matrix_nalloc_grainst_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_leafst_to_leafxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_leafxf_to_leaf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_frootst_to_frootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_frootxf_to_froot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestemst_to_livestemxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestemxf_to_livestem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadstemst_to_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadstemxf_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecrootst_to_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecrootxf_to_livecroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadcrootst_to_deadcrootxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_deadcrootxf_to_deadcroot_acc_patch(i) = value_patch
+ if ( use_crop )then
+ this%matrix_ntransfer_grainst_to_grainxf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_grainxf_to_grain_acc_patch(i) = value_patch
+ end if
+ this%matrix_ntransfer_livestem_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecroot_to_deadcroot_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_retransn_to_leaf_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_leafst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_froot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_frootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livestem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livestemst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadstem_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadstemst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livecroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_livecrootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadcroot_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_grain_acc_patch(i) = value_patch
+ this%matrix_ntransfer_retransn_to_grainst_acc_patch(i) = value_patch
+
+ this%matrix_ntransfer_leaf_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_froot_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livestem_to_retransn_acc_patch(i) = value_patch
+ this%matrix_ntransfer_livecroot_to_retransn_acc_patch(i) = value_patch
+
+ this%matrix_nturnover_leaf_acc_patch(i) = value_patch
+ this%matrix_nturnover_leafst_acc_patch(i) = value_patch
+ this%matrix_nturnover_leafxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_froot_acc_patch(i) = value_patch
+ this%matrix_nturnover_frootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_frootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestem_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestemst_acc_patch(i) = value_patch
+ this%matrix_nturnover_livestemxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstem_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstemst_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadstemxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecroot_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecrootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_livecrootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcroot_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcrootst_acc_patch(i) = value_patch
+ this%matrix_nturnover_deadcrootxf_acc_patch(i) = value_patch
+ this%matrix_nturnover_retransn_acc_patch(i) = value_patch
+ if ( use_crop )then
+ this%matrix_nturnover_grain_acc_patch(i) = value_patch
+ this%matrix_nturnover_grainst_acc_patch(i) = value_patch
+ this%matrix_nturnover_grainxf_acc_patch(i) = value_patch
+ end if
+
+ end if
this%retransn_patch(i) = value_patch
this%npool_patch(i) = value_patch
this%ntrunc_patch(i) = value_patch
diff --git a/src/biogeochem/CNVegStateType.F90 b/src/biogeochem/CNVegStateType.F90
index c286c0344f..d63752c5b7 100644
--- a/src/biogeochem/CNVegStateType.F90
+++ b/src/biogeochem/CNVegStateType.F90
@@ -519,7 +519,7 @@ subroutine InitCold(this, bounds)
! --------------------------------------------------------------------
! Initialize terms needed for dust model
- ! TODO - move these terms to DUSTMod module variables
+ ! TODO - move these terms to DustEmisBase object variables
! --------------------------------------------------------------------
do c = bounds%begc, bounds%endc
diff --git a/src/biogeochem/CNVegetationFacade.F90 b/src/biogeochem/CNVegetationFacade.F90
index 61e2e9cf91..706d52da27 100644
--- a/src/biogeochem/CNVegetationFacade.F90
+++ b/src/biogeochem/CNVegetationFacade.F90
@@ -147,7 +147,7 @@ module CNVegetationFacade
! - ch4_inst
! - probably not: really seems to belong in soilbiogeochem
! - crop_inst
- ! - dust_inst
+ ! - dust_emis_inst
! - vocemis_inst
! - fireemis_inst
! - drydepvel_inst
@@ -469,6 +469,8 @@ subroutine Restart(this, bounds, ncid, flag)
use clm_varcon, only : c3_r2, c14ratio
use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn
use CNSharedParamsMod, only : use_matrixcn
+ use CNVegMatrixMod, only : CNVegMatrixRest
+ use CNSoilMatrixMod, only : CNSoilMatrixRest
!
! !ARGUMENTS:
class(cn_vegetation_type), intent(inout) :: this
@@ -545,6 +547,14 @@ subroutine Restart(this, bounds, ncid, flag)
template_multiplier = c14ratio)
end if
call this%n_products_inst%restart(bounds, ncid, flag)
+
+ if ( use_matrixcn )then
+ call CNVegMatrixRest( ncid, flag )
+ end if
+ end if
+
+ if ( use_soil_matrixcn )then
+ call CNSoilMatrixRest( ncid, flag )
end if
if (use_cndv) then
diff --git a/src/biogeochem/CropReprPoolsMod.F90 b/src/biogeochem/CropReprPoolsMod.F90
index 780b9f2d52..cbc2f3e2a2 100644
--- a/src/biogeochem/CropReprPoolsMod.F90
+++ b/src/biogeochem/CropReprPoolsMod.F90
@@ -57,6 +57,11 @@ subroutine crop_repr_pools_init()
! !DESCRIPTION:
! Initialize module-level data
!
+ ! !USES:
+ use abortutils, only: endrun
+ use shr_log_mod, only: errmsg => shr_log_errMsg
+ use CNSharedParamsMod, only: use_matrixcn
+ !
! !ARGUMENTS:
!
! !LOCAL VARIABLES:
@@ -77,16 +82,26 @@ subroutine crop_repr_pools_init()
! repr_hist_fnames(1) = 'GRAIN_MEAL', grain_hist_fnames(2) = 'GRAIN_OIL', etc.
if (for_testing_use_second_grain_pool) then
nrepr_grain = 2
+ if (use_matrixcn) then
+ call endrun(msg="ERROR: for_testing_use_second_grain_pool should be .false. when use_matrixcn = .true."//errmsg(sourcefile, __LINE__))
+ end if
else
nrepr_grain = 1
end if
if (for_testing_use_repr_structure_pool) then
nrepr_structure = 2
+ if (use_matrixcn) then
+ call endrun(msg="ERROR: for_testing_use_repr_structure_pool should be .false. when use_matrixcn = .true."//errMsg(sourcefile, __LINE__))
+ end if
else
nrepr_structure = 0
end if
nrepr = nrepr_grain + nrepr_structure
+ ! matrixcn works with nrepr = 1 only
+ if (use_matrixcn .and. nrepr /= 1) then
+ call endrun(msg="ERROR: nrepr should be 1 when use_matrixcn = .true."//errMsg(sourcefile, __LINE__))
+ end if
allocate(repr_hist_fnames(nrepr))
allocate(repr_rest_fnames(nrepr))
allocate(repr_longnames(nrepr))
diff --git a/src/biogeochem/DUSTMod.F90 b/src/biogeochem/DustEmisBase.F90
similarity index 54%
rename from src/biogeochem/DUSTMod.F90
rename to src/biogeochem/DustEmisBase.F90
index ffa2bfe6f0..c5e4260634 100644
--- a/src/biogeochem/DUSTMod.F90
+++ b/src/biogeochem/DustEmisBase.F90
@@ -1,18 +1,19 @@
-module DUSTMod
+module DustEmisBase
+#include "shr_assert.h"
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
+ !-----------------------------------------------------------------------
+ ! !DESCRIPTION:
! Routines in this module calculate Dust mobilization and dry deposition for dust.
- ! Simulates dust mobilization due to wind from the surface into the
- ! lowest atmospheric layer. On output flx_mss_vrt_dst(ndst) is the surface dust
+ ! Simulates dust mobilization due to wind from the surface into the
+ ! lowest atmospheric layer. On output flx_mss_vrt_dst(ndst) is the surface dust
! emission (kg/m**2/s) [ + = to atm].
- ! Calculates the turbulent component of dust dry deposition, (the turbulent deposition
- ! velocity through the lowest atmospheric layer). CAM will calculate the settling
- ! velocity through the whole atmospheric column. The two calculations will determine
+ ! Calculates the turbulent component of dust dry deposition, (the turbulent deposition
+ ! velocity through the lowest atmospheric layer). CAM will calculate the settling
+ ! velocity through the whole atmospheric column. The two calculations will determine
! the dust dry deposition flux to the surface.
- !
+ !
! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_kind_mod , only : r8 => shr_kind_r8
use shr_log_mod , only : errMsg => shr_log_errMsg
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use clm_varpar , only : dst_src_nbr, ndst, sz_nbr
@@ -24,83 +25,149 @@ module DUSTMod
use atm2lndType , only : atm2lnd_type
use SoilStateType , only : soilstate_type
use CanopyStateType , only : canopystate_type
- use WaterStateBulkType , only : waterstatebulk_type
- use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type
+ use WaterStateBulkType , only : waterstatebulk_type
+ use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type
use FrictionVelocityMod , only : frictionvel_type
use LandunitType , only : lun
use ColumnType , only : col
use PatchType , only : patch
- use ZenderSoilErodStreamType, only : soil_erod_stream_type
use clm_varctl , only : dust_emis_method
- !
+ !
! !PUBLIC TYPES
implicit none
private
!
- ! !PUBLIC MEMBER FUNCTIONS:
- !
- public DustEmission ! Dust mobilization
- public DustDryDep ! Turbulent dry deposition for dust
+ ! !PRIVATE DATA:
!
- ! !PUBLIC DATA:
- !
- real(r8) , allocatable :: ovr_src_snk_mss(:,:)
- real(r8) , allocatable :: dmt_vwr(:) ![m] Mass-weighted mean diameter resolved
- real(r8) , allocatable :: stk_crc(:) ![frc] Correction to Stokes settling velocity
- real(r8) tmp1 !Factor in saltation computation (named as in Charlie's code)
- real(r8) dns_aer ![kg m-3] Aerosol density
+ real(r8), parameter :: dns_aer = 2.5e+3_r8 ![kg m-3] Aerosol density
!
! !PUBLIC DATA TYPES:
!
- type, public :: dust_type
-
- real(r8), pointer, PUBLIC :: flx_mss_vrt_dst_patch (:,:) ! surface dust emission (kg/m**2/s) [ + = to atm] (ndst)
- real(r8), pointer, private :: flx_mss_vrt_dst_tot_patch (:) ! total dust flux into atmosphere
- real(r8), pointer, private :: vlc_trb_patch (:,:) ! turbulent deposition velocity (m/s) (ndst)
+ type, abstract, public :: dust_emis_base_type
+
+ real(r8) , allocatable, public :: ovr_src_snk_mss(:,:) ! overlap factors between the source and sin
+ real(r8) , allocatable, private :: dmt_vwr(:) ! [m] Mass-weighted mean diameter resolved
+ real(r8) , allocatable, private :: stk_crc(:) ! [frc] Correction to Stokes settling velocity
+ real(r8), public :: saltation_factor ! Factor in saltation computation (named as in Charlie's code)
+ real(r8), pointer, PUBLIC :: flx_mss_vrt_dst_patch (:,:) ! surface dust emission (kg/m**2/s) [ + = to atm] (ndst)
+ real(r8), pointer, public :: flx_mss_vrt_dst_tot_patch (:) ! total dust flux into atmosphere
+ real(r8), pointer, private :: vlc_trb_patch (:,:) ! turbulent deposition velocity (m/s) (ndst)
real(r8), pointer, private :: vlc_trb_1_patch (:) ! turbulent deposition velocity 1(m/s)
real(r8), pointer, private :: vlc_trb_2_patch (:) ! turbulent deposition velocity 2(m/s)
real(r8), pointer, private :: vlc_trb_3_patch (:) ! turbulent deposition velocity 3(m/s)
real(r8), pointer, private :: vlc_trb_4_patch (:) ! turbulent deposition velocity 4(m/s)
- type(soil_erod_stream_type), private :: soil_erod_stream ! Zender soil erodibility stream data
- real(r8), pointer, private :: mbl_bsn_fct_col (:) ! [dimensionless] basin factor, or soil erodibility, time-constant
contains
- procedure , public :: Init
- procedure , private :: InitAllocate
- procedure , private :: InitHistory
- procedure , private :: InitCold
- procedure , private :: InitDustVars ! Initialize variables used in subroutine Dust
+ procedure , public :: InitBase ! Base object initiatlization (allows it to be extended)
+ procedure , public :: Init => InitBase ! Initialization name used by callers
+ procedure(DustEmission_interface) , public, deferred :: DustEmission ! Dust mobilization
+ procedure , public :: CheckDustEmisIsValid ! Check that the dust emission type is valid
+ procedure , public :: DustDryDep ! Turbulent dry deposition for dust
+ procedure , public :: WritePatchToLog ! Write information on the given patch to the log file
+ procedure , public :: GetPatchVars ! Get important variables on a given patch
+ procedure , public :: GetConstVars ! Get important constant variables
+ procedure , public :: CleanBase ! Base object deallocation (allows extension)
+ procedure , public :: Clean => CleanBase ! Deallocation used by callers
+ procedure , private :: InitAllocateBase
+ procedure , private :: InitHistoryBase
+ procedure , private :: InitDustVars ! Initialize variables used in DustEmission method
+
+ end type dust_emis_base_type
+ !------------------------------------------------------------------------
- end type dust_type
+ abstract interface
!------------------------------------------------------------------------
+ subroutine DustEmission_interface (this, bounds, &
+ num_nolakep, filter_nolakep, &
+ atm2lnd_inst, soilstate_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, &
+ frictionvel_inst)
+ !
+ ! !DESCRIPTION:
+ ! Dust mobilization. This code simulates dust mobilization due to wind
+ ! from the surface into the lowest atmospheric layer
+ ! On output flx_mss_vrt_dst(ndst) is the surface dust emission
+ ! (kg/m**2/s) [ + = to atm]
+ !
+ ! !USES
+ use decompMod , only : bounds_type
+ use atm2lndType , only : atm2lnd_type
+ use SoilStateType , only : soilstate_type
+ use CanopyStateType , only : canopystate_type
+ use WaterStateBulkType , only : waterstatebulk_type
+ use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type
+ use FrictionVelocityMod , only : frictionvel_type
+
+ import :: dust_emis_base_type
+ !
+ ! !ARGUMENTS:
+ class (dust_emis_base_type) :: this
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_nolakep ! number of column non-lake points in patch filter
+ integer , intent(in) :: filter_nolakep(num_nolakep) ! patch filter for non-lake points
+ type(atm2lnd_type) , intent(in) :: atm2lnd_inst
+ type(soilstate_type) , intent(in) :: soilstate_inst
+ type(canopystate_type) , intent(in) :: canopystate_inst
+ type(waterstatebulk_type) , intent(in) :: waterstatebulk_inst
+ type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst
+ type(frictionvel_type) , intent(in) :: frictionvel_inst
+
+ end subroutine DustEmission_interface
+
+ end interface
+
character(len=*), parameter, private :: sourcefile = &
__FILE__
contains
!------------------------------------------------------------------------
- subroutine Init(this, bounds, NLFilename)
+ subroutine InitBase(this, bounds, NLFilename)
- class(dust_type) :: this
- type(bounds_type), intent(in) :: bounds
+ ! Base level initialization of this base object, this allows classes that extend
+ ! this base class to use this one and extend it with additional initialization
+ class(dust_emis_base_type) :: this
+ type(bounds_type), intent(in) :: bounds
character(len=*), intent(in) :: NLFilename
- call this%soil_erod_stream%Init( bounds, NLFilename )
- call this%InitAllocate (bounds)
- call this%InitHistory (bounds)
- call this%InitCold (bounds)
+ call this%InitAllocateBase (bounds)
+ call this%InitHistoryBase (bounds)
call this%InitDustVars (bounds)
- end subroutine Init
+ end subroutine InitBase
!------------------------------------------------------------------------
- subroutine InitAllocate(this, bounds)
+ subroutine CleanBase(this)
+ !
+ ! Base level deallocation of this base object, this allows classes that extend
+ ! this base class to use this one and extend it with additional deallocation.
+ ! !ARGUMENTS:
+ class (dust_emis_base_type) :: this
+ !
+ ! !LOCAL VARIABLES:
+ !------------------------------------------------------------------------
+
+ deallocate(this%flx_mss_vrt_dst_patch)
+ deallocate(this%flx_mss_vrt_dst_tot_patch)
+ deallocate(this%vlc_trb_patch)
+ deallocate(this%vlc_trb_1_patch)
+ deallocate(this%vlc_trb_2_patch)
+ deallocate(this%vlc_trb_3_patch)
+ deallocate(this%vlc_trb_4_patch)
+
+ deallocate (this%ovr_src_snk_mss)
+ deallocate (this%dmt_vwr)
+ deallocate (this%stk_crc)
+
+ end subroutine CleanBase
+
+ !------------------------------------------------------------------------
+ subroutine InitAllocateBase(this, bounds)
!
! !ARGUMENTS:
- class (dust_type) :: this
- type(bounds_type), intent(in) :: bounds
+ class (dust_emis_base_type) :: this
+ type(bounds_type), intent(in) :: bounds
!
! !LOCAL VARIABLES:
integer :: begp,endp
@@ -114,23 +181,26 @@ subroutine InitAllocate(this, bounds)
allocate(this%flx_mss_vrt_dst_tot_patch (begp:endp)) ; this%flx_mss_vrt_dst_tot_patch (:) = nan
allocate(this%vlc_trb_patch (begp:endp,1:ndst)) ; this%vlc_trb_patch (:,:) = nan
allocate(this%vlc_trb_1_patch (begp:endp)) ; this%vlc_trb_1_patch (:) = nan
- allocate(this%vlc_trb_2_patch (begp:endp)) ; this%vlc_trb_2_patch (:) = nan
+ allocate(this%vlc_trb_2_patch (begp:endp)) ; this%vlc_trb_2_patch (:) = nan
allocate(this%vlc_trb_3_patch (begp:endp)) ; this%vlc_trb_3_patch (:) = nan
allocate(this%vlc_trb_4_patch (begp:endp)) ; this%vlc_trb_4_patch (:) = nan
- allocate(this%mbl_bsn_fct_col (begc:endc)) ; this%mbl_bsn_fct_col (:) = nan
- end subroutine InitAllocate
+ allocate (this%ovr_src_snk_mss(1:dst_src_nbr,1:ndst)) ; this%ovr_src_snk_mss (:,:) = nan
+ allocate (this%dmt_vwr(1:ndst)) ; this%dmt_vwr (:) = nan
+ allocate (this%stk_crc(1:ndst)) ; this%stk_crc (:) = nan
+
+ end subroutine InitAllocateBase
!------------------------------------------------------------------------
- subroutine InitHistory(this, bounds)
+ subroutine InitHistoryBase(this, bounds)
!
! !USES:
use histFileMod, only : hist_addfld1d
!
!
! !ARGUMENTS:
- class (dust_type) :: this
- type(bounds_type), intent(in) :: bounds
+ class (dust_emis_base_type) :: this
+ type(bounds_type), intent(in) :: bounds
!
! !LOCAL VARIABLES:
integer :: begp,endp
@@ -165,348 +235,122 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name='turbulent deposition velocity 4', &
ptr_patch=this%vlc_trb_4_patch, default='inactive')
- if (dust_emis_method == 'Zender_2003') then
- if ( this%soil_erod_stream%UseStreams() )then
- this%mbl_bsn_fct_col(begc:endc) = spval
- call hist_addfld1d (fname='LND_MBL', units='fraction', &
- avgflag='A', long_name='Soil erodibility factor', &
- ptr_col=this%mbl_bsn_fct_col, default='inactive')
- end if
- end if
-
- end subroutine InitHistory
+ end subroutine InitHistoryBase
!-----------------------------------------------------------------------
- subroutine InitCold(this, bounds)
- !
- ! !ARGUMENTS:
- class (dust_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: c,l
- !-----------------------------------------------------------------------
-
- ! Set basin factor to 1 for now
-
- if (dust_emis_method == 'Leung_2023') then
- !do c = bounds%begc, bounds%endc
- ! l = col%landunit(c)
-
- ! if (.not.lun%lakpoi(l)) then
- ! this%mbl_bsn_fct_col(c) = 1.0_r8
- ! end if
- !end do
- call endrun( msg="Leung_2023 dust_emis_method is currently not available"//errMsg(sourcefile, __LINE__))
- else if (dust_emis_method == 'Zender_2003') then
- if ( this%soil_erod_stream%UseStreams() )then
- call this%soil_erod_stream%CalcDustSource( bounds, &
- this%mbl_bsn_fct_col(bounds%begc:bounds%endc) )
- else
- this%mbl_bsn_fct_col(:) = 1.0_r8
- end if
- else
- write(iulog,*) 'dust_emis_method not recognized = ', trim(dust_emis_method)
- call endrun( msg="dust_emis_method namelist item is not valid "//errMsg(sourcefile, __LINE__))
- end if
-
- end subroutine InitCold
- !------------------------------------------------------------------------
- subroutine DustEmission (bounds, &
- num_nolakep, filter_nolakep, &
- atm2lnd_inst, soilstate_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, &
- frictionvel_inst, dust_inst)
- !
- ! !DESCRIPTION:
- ! Dust mobilization. This code simulates dust mobilization due to wind
- ! from the surface into the lowest atmospheric layer
- ! On output flx_mss_vrt_dst(ndst) is the surface dust emission
- ! (kg/m**2/s) [ + = to atm]
- ! Source: C. Zender's dust model
- !
- ! !USES
- use shr_const_mod, only : SHR_CONST_RHOFW
- use subgridaveMod, only : p2g
+ subroutine WritePatchToLog(this, p)
!
+ ! !DESCRIPTION:
+ ! Write out information on dust emisisons for this patch to the log file
! !ARGUMENTS:
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_nolakep ! number of column non-lake points in patch filter
- integer , intent(in) :: filter_nolakep(num_nolakep) ! patch filter for non-lake points
- type(atm2lnd_type) , intent(in) :: atm2lnd_inst
- type(soilstate_type) , intent(in) :: soilstate_inst
- type(canopystate_type) , intent(in) :: canopystate_inst
- type(waterstatebulk_type) , intent(in) :: waterstatebulk_inst
- type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst
- type(frictionvel_type) , intent(in) :: frictionvel_inst
- type(dust_type) , intent(inout) :: dust_inst
-
- !
- ! !LOCAL VARIABLES
- integer :: fp,p,c,l,g,m,n ! indices
- real(r8) :: liqfrac ! fraction of total water that is liquid
- real(r8) :: wnd_frc_rat ! [frc] Wind friction threshold over wind friction
- real(r8) :: wnd_frc_slt_dlt ! [m s-1] Friction velocity increase from saltatn
- real(r8) :: wnd_rfr_dlt ! [m s-1] Reference windspeed excess over threshld
- real(r8) :: dst_slt_flx_rat_ttl
- real(r8) :: flx_mss_hrz_slt_ttl
- real(r8) :: flx_mss_vrt_dst_ttl(bounds%begp:bounds%endp)
- real(r8) :: frc_thr_wet_fct
- real(r8) :: frc_thr_rgh_fct
- real(r8) :: wnd_frc_thr_slt
- real(r8) :: wnd_rfr_thr_slt
- real(r8) :: wnd_frc_slt
- real(r8) :: lnd_frc_mbl(bounds%begp:bounds%endp)
- real(r8) :: bd
- real(r8) :: gwc_sfc
- real(r8) :: ttlai(bounds%begp:bounds%endp)
- real(r8) :: tlai_lu(bounds%begl:bounds%endl)
- real(r8) :: sumwt(bounds%begl:bounds%endl) ! sum of weights
- logical :: found ! temporary for error check
- integer :: index
- !
- ! constants
- !
- real(r8), parameter :: cst_slt = 2.61_r8 ! [frc] Saltation constant
- real(r8), parameter :: flx_mss_fdg_fct = 5.0e-4_r8 ! [frc] Empir. mass flx tuning eflx_lh_vegt
- real(r8), parameter :: vai_mbl_thr = 0.3_r8 ! [m2 m-2] VAI threshold quenching dust mobilization
- character(len=*),parameter :: subname = 'DUSTEmission'
- !------------------------------------------------------------------------
-
- associate( &
- forc_rho => atm2lnd_inst%forc_rho_downscaled_col , & ! Input: [real(r8) (:) ] downscaled density (kg/m**3)
-
- gwc_thr => soilstate_inst%gwc_thr_col , & ! Input: [real(r8) (:) ] threshold gravimetric soil moisture based on clay content
- mss_frc_cly_vld => soilstate_inst%mss_frc_cly_vld_col , & ! Input: [real(r8) (:) ] [frc] Mass fraction clay limited to 0.20
- watsat => soilstate_inst%watsat_col , & ! Input: [real(r8) (:,:) ] saturated volumetric soil water
-
- tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow
- tsai => canopystate_inst%tsai_patch , & ! Input: [real(r8) (:) ] one-sided stem area index, no burying by snow
-
- frac_sno => waterdiagnosticbulk_inst%frac_sno_col , & ! Input: [real(r8) (:) ] fraction of ground covered by snow (0 to 1)
- h2osoi_vol => waterstatebulk_inst%h2osoi_vol_col , & ! Input: [real(r8) (:,:) ] volumetric soil water (0<=h2osoi_vol<=watsat)
- h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid soil water (kg/m2)
- h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] frozen soil water (kg/m2)
-
- fv => frictionvel_inst%fv_patch , & ! Input: [real(r8) (:) ] friction velocity (m/s) (for dust model)
- u10 => frictionvel_inst%u10_patch , & ! Input: [real(r8) (:) ] 10-m wind (m/s) (created for dust model)
-
- mbl_bsn_fct => dust_inst%mbl_bsn_fct_col , & ! Input: [real(r8) (:) ] basin factor
- flx_mss_vrt_dst => dust_inst%flx_mss_vrt_dst_patch , & ! Output: [real(r8) (:,:) ] surface dust emission (kg/m**2/s)
- flx_mss_vrt_dst_tot => dust_inst%flx_mss_vrt_dst_tot_patch & ! Output: [real(r8) (:) ] total dust flux back to atmosphere (pft)
- )
-
- ttlai(bounds%begp : bounds%endp) = 0._r8
- ! make lai average at landunit level
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- ttlai(p) = tlai(p)+tsai(p)
- enddo
-
- tlai_lu(bounds%begl : bounds%endl) = spval
- sumwt(bounds%begl : bounds%endl) = 0._r8
- do p = bounds%begp,bounds%endp
- if (ttlai(p) /= spval .and. patch%active(p) .and. patch%wtlunit(p) /= 0._r8) then
- c = patch%column(p)
- l = patch%landunit(p)
- if (sumwt(l) == 0._r8) tlai_lu(l) = 0._r8
- tlai_lu(l) = tlai_lu(l) + ttlai(p) * patch%wtlunit(p)
- sumwt(l) = sumwt(l) + patch%wtlunit(p)
- end if
- end do
- found = .false.
- do l = bounds%begl,bounds%endl
- if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
- found = .true.
- index = l
- exit
- else if (sumwt(l) /= 0._r8) then
- tlai_lu(l) = tlai_lu(l)/sumwt(l)
- end if
- end do
- if (found) then
- write(iulog,*) subname//':: error: sumwt is greater than 1.0 at l= ',index
- call endrun(subgrid_index=index, subgrid_level=subgrid_level_landunit, msg=errMsg(sourcefile, __LINE__))
- end if
-
- ! Loop through patches
-
- ! initialize variables which get passed to the atmosphere
- flx_mss_vrt_dst(bounds%begp:bounds%endp,:)=0._r8
-
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- c = patch%column(p)
- l = patch%landunit(p)
-
- ! the following code from subr. lnd_frc_mbl_get was adapted for lsm use
- ! purpose: return fraction of each gridcell suitable for dust mobilization
-
- ! the "bare ground" fraction of the current sub-gridscale cell decreases
- ! linearly from 1 to 0 as VAI(=tlai+tsai) increases from 0 to vai_mbl_thr
- ! if ice sheet, wetland, or lake, no dust allowed
-
- if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
- if (tlai_lu(l) < vai_mbl_thr) then
- lnd_frc_mbl(p) = 1.0_r8 - (tlai_lu(l))/vai_mbl_thr
- else
- lnd_frc_mbl(p) = 0.0_r8
- endif
- lnd_frc_mbl(p) = lnd_frc_mbl(p) * (1.0_r8 - frac_sno(c))
- else
- lnd_frc_mbl(p) = 0.0_r8
- end if
- end do
-
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- if (lnd_frc_mbl(p)>1.0_r8 .or. lnd_frc_mbl(p)<0.0_r8) then
- write(iulog,*)'Error dstmbl: pft= ',p,' lnd_frc_mbl(p)= ',lnd_frc_mbl(p)
- call endrun(subgrid_index=p, subgrid_level=subgrid_level_patch, msg=errMsg(sourcefile, __LINE__))
- end if
- end do
+ class(dust_emis_base_type), intent(in) :: this
+ integer , intent(in) :: p ! Patch to display
- ! reset history output variables before next if-statement to avoid output = inf
+ write(iulog,*) 'flx_mss_vrt_dst_tot', this%flx_mss_vrt_dst_tot_patch(p)
+ write(iulog,*) 'vlc_trb_1', this%vlc_trb_1_patch(p)
+ write(iulog,*) 'vlc_trb_2', this%vlc_trb_2_patch(p)
+ write(iulog,*) 'vlc_trb_3', this%vlc_trb_3_patch(p)
+ write(iulog,*) 'vlc_trb_4', this%vlc_trb_4_patch(p)
+ end subroutine WritePatchToLog
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- flx_mss_vrt_dst_tot(p) = 0.0_r8
- end do
- do n = 1, ndst
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- flx_mss_vrt_dst(p,n) = 0.0_r8
- end do
- end do
-
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- c = patch%column(p)
- l = patch%landunit(p)
- g = patch%gridcell(p)
-
- ! only perform the following calculations if lnd_frc_mbl is non-zero
-
- if (lnd_frc_mbl(p) > 0.0_r8) then
-
- ! the following comes from subr. frc_thr_rgh_fct_get
- ! purpose: compute factor by which surface roughness increases threshold
- ! friction velocity (currently a constant)
-
- frc_thr_rgh_fct = 1.0_r8
-
- ! the following comes from subr. frc_thr_wet_fct_get
- ! purpose: compute factor by which soil moisture increases threshold friction velocity
- ! adjust threshold velocity for inhibition by moisture
- ! modified 4/5/2002 (slevis) to use gravimetric instead of volumetric
- ! water content
-
- bd = (1._r8-watsat(c,1))*2.7e3_r8 ![kg m-3] Bulk density of dry surface soil
- gwc_sfc = h2osoi_vol(c,1)*SHR_CONST_RHOFW/bd ![kg kg-1] Gravimetric H2O cont
- if (gwc_sfc > gwc_thr(c)) then
- frc_thr_wet_fct = sqrt(1.0_r8 + 1.21_r8 * (100.0_r8*(gwc_sfc - gwc_thr(c)))**0.68_r8)
- else
- frc_thr_wet_fct = 1.0_r8
- end if
-
- ! slevis: adding liqfrac here, because related to effects from soil water
-
- liqfrac = max( 0.0_r8, min( 1.0_r8, h2osoi_liq(c,1) / (h2osoi_ice(c,1)+h2osoi_liq(c,1)+1.0e-6_r8) ) )
-
- ! the following lines come from subr. dst_mbl
- ! purpose: adjust threshold friction velocity to acct for moisture and
- ! roughness. The ratio tmp1 / sqrt(forc_rho) comes from
- ! subr. wnd_frc_thr_slt_get which computes dry threshold
- ! friction velocity for saltation
-
- wnd_frc_thr_slt = tmp1 / sqrt(forc_rho(c)) * frc_thr_wet_fct * frc_thr_rgh_fct
-
- ! reset these variables which will be updated in the following if-block
-
- wnd_frc_slt = fv(p)
- flx_mss_hrz_slt_ttl = 0.0_r8
- flx_mss_vrt_dst_ttl(p) = 0.0_r8
-
- ! the following line comes from subr. dst_mbl
- ! purpose: threshold saltation wind speed
-
- wnd_rfr_thr_slt = u10(p) * wnd_frc_thr_slt / fv(p)
-
- ! the following if-block comes from subr. wnd_frc_slt_get
- ! purpose: compute the saltating friction velocity
- ! theory: saltation roughens the boundary layer, AKA "Owen's effect"
-
- if (u10(p) >= wnd_rfr_thr_slt) then
- wnd_rfr_dlt = u10(p) - wnd_rfr_thr_slt
- wnd_frc_slt_dlt = 0.003_r8 * wnd_rfr_dlt * wnd_rfr_dlt
- wnd_frc_slt = fv(p) + wnd_frc_slt_dlt
- end if
-
- ! the following comes from subr. flx_mss_hrz_slt_ttl_Whi79_get
- ! purpose: compute vertically integrated streamwise mass flux of particles
-
- if (wnd_frc_slt > wnd_frc_thr_slt) then
- wnd_frc_rat = wnd_frc_thr_slt / wnd_frc_slt
- flx_mss_hrz_slt_ttl = cst_slt * forc_rho(c) * (wnd_frc_slt**3.0_r8) * &
- (1.0_r8 - wnd_frc_rat) * (1.0_r8 + wnd_frc_rat) * (1.0_r8 + wnd_frc_rat) / grav
-
- ! the following loop originates from subr. dst_mbl
- ! purpose: apply land sfc and veg limitations and global tuning factor
- ! slevis: multiply flx_mss_hrz_slt_ttl by liqfrac to incude the effect
- ! of frozen soil
-
- flx_mss_hrz_slt_ttl = flx_mss_hrz_slt_ttl * lnd_frc_mbl(p) * mbl_bsn_fct(c) * &
- flx_mss_fdg_fct * liqfrac
- end if
-
- ! the following comes from subr. flx_mss_vrt_dst_ttl_MaB95_get
- ! purpose: diagnose total vertical mass flux of dust from vertically
- ! integrated streamwise mass flux
-
- dst_slt_flx_rat_ttl = 100.0_r8 * exp( log(10.0_r8) * (13.4_r8 * mss_frc_cly_vld(c) - 6.0_r8) )
- flx_mss_vrt_dst_ttl(p) = flx_mss_hrz_slt_ttl * dst_slt_flx_rat_ttl
+ !-----------------------------------------------------------------------
- end if ! lnd_frc_mbl > 0.0
+ subroutine GetPatchVars(this, p, flx_mss_vrt_dst, flx_mss_vrt_dst_tot, vlc_trb, vlc_trb_1, &
+ vlc_trb_2, vlc_trb_3, vlc_trb_4)
+ !
+ ! !DESCRIPTION:
+ ! Get important variables on the given patch
+ ! !ARGUMENTS:
+ class(dust_emis_base_type) , intent(in) :: this
+ integer , intent(in) :: p ! Patch to get
+ real(r8), optional, intent(out) :: flx_mss_vrt_dst(ndst)
+ real(r8), optional, intent(out) :: flx_mss_vrt_dst_tot
+ real(r8), optional, intent(out) :: vlc_trb(ndst)
+ real(r8), optional, intent(out) :: vlc_trb_1
+ real(r8), optional, intent(out) :: vlc_trb_2
+ real(r8), optional, intent(out) :: vlc_trb_3
+ real(r8), optional, intent(out) :: vlc_trb_4
+
+ if ( present(flx_mss_vrt_dst ) ) flx_mss_vrt_dst = this%flx_mss_vrt_dst_patch(p,:)
+ if ( present(flx_mss_vrt_dst_tot) ) flx_mss_vrt_dst_tot = this%flx_mss_vrt_dst_tot_patch(p)
+ if ( present(vlc_trb ) ) vlc_trb = this%vlc_trb_patch(p,:)
+ if ( present(vlc_trb_1) ) vlc_trb_1 = this%vlc_trb_1_patch(p)
+ if ( present(vlc_trb_2) ) vlc_trb_2 = this%vlc_trb_2_patch(p)
+ if ( present(vlc_trb_3) ) vlc_trb_3 = this%vlc_trb_3_patch(p)
+ if ( present(vlc_trb_4) ) vlc_trb_4 = this%vlc_trb_4_patch(p)
+ end subroutine GetPatchVars
- end do
-
- ! the following comes from subr. flx_mss_vrt_dst_prt in C. Zender's code
- ! purpose: partition total vertical mass flux of dust into transport bins
+ !------------------------------------------------------------------------
+ subroutine CheckDustEmisIsValid( this, p )
+ ! Check that dust emission state for this patch is valid
+ ! This means ensuring that total dust is the sum of all the dust bins
+ ! And that dry deposition for each dust bins agrees with the array of all
+ class(dust_emis_base_type) :: this
+ integer , intent(in) :: p ! Patch to display
+ integer :: i
+
+ if ( abs(sum(this%flx_mss_vrt_dst_patch(p,:)) - this%flx_mss_vrt_dst_tot_patch(p)) > 0.0_r8 )then
+ write(iulog,*) 'sum(flx_mss_vrt_dst(:)) /=flx_mss_vrt_dst_tot for p = ', p, &
+ errMsg(sourcefile, __LINE__)
+ call endrun(msg="Sum over dust bins does NOT equal total dust")
+ return
+ end if
+ i = 1
+ if ( this%vlc_trb_patch(p,i) /= this%vlc_trb_1_patch(p) )then
+ write(iulog,*) 'vlc_trb(i)) /= glc_trb for p = ', p, 'dust bin = ', i, &
+ errMsg(sourcefile, __LINE__)
+ call endrun(msg="Dry deposition for dust bin not equal to the array bin for it")
+ return
+ end if
+ i = 2
+ if ( this%vlc_trb_patch(p,i) /= this%vlc_trb_2_patch(p) )then
+ write(iulog,*) 'vlc_trb(i) /= glc_trb for p = ', p, 'dust bin = ', i, &
+ errMsg(sourcefile, __LINE__)
+ call endrun(msg="Dry deposition for dust bin not equal to the array bin for it")
+ return
+ end if
+ i = 3
+ if ( this%vlc_trb_patch(p,i) /= this%vlc_trb_3_patch(p) )then
+ write(iulog,*) 'vlc_trb(i)) /= glc_trb for p = ', p, 'dust bin = ', i, &
+ errMsg(sourcefile, __LINE__)
+ call endrun(msg="Dry deposition for dust bin not equal to the array bin for it")
+ return
+ end if
+ i = 4
+ if ( this%vlc_trb_patch(p,i) /= this%vlc_trb_4_patch(p) )then
+ write(iulog,*) 'vlc_trb(i)) /= glc_trb for p = ', p, 'dust bin = ', i, &
+ errMsg(sourcefile, __LINE__)
+ call endrun(msg="Dry deposition for dust bin not equal to the array bin for it")
+ return
+ end if
+
+ end subroutine CheckDustEmisIsValid
- do n = 1, ndst
- do m = 1, dst_src_nbr
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- if (lnd_frc_mbl(p) > 0.0_r8) then
- flx_mss_vrt_dst(p,n) = flx_mss_vrt_dst(p,n) + ovr_src_snk_mss(m,n) * flx_mss_vrt_dst_ttl(p)
- end if
- end do
- end do
- end do
+ !-----------------------------------------------------------------------
- do n = 1, ndst
- do fp = 1,num_nolakep
- p = filter_nolakep(fp)
- if (lnd_frc_mbl(p) > 0.0_r8) then
- flx_mss_vrt_dst_tot(p) = flx_mss_vrt_dst_tot(p) + flx_mss_vrt_dst(p,n)
- end if
- end do
- end do
+ subroutine GetConstVars(this, SaltationFactor )
+ !
+ ! !DESCRIPTION:
+ ! Get important constant variables
+ ! !ARGUMENTS:
+ class(dust_emis_base_type) , intent(in) :: this
+ real(r8) , intent(out) :: SaltationFactor
- end associate
+ SaltationFactor = this%saltation_factor
+ end subroutine GetConstVars
- end subroutine DustEmission
+ !------------------------------------------------------------------------
- !------------------------------------------------------------------------
- subroutine DustDryDep (bounds, &
- atm2lnd_inst, frictionvel_inst, dust_inst)
+ subroutine DustDryDep (this, bounds, &
+ atm2lnd_inst, frictionvel_inst)
!
- ! !DESCRIPTION:
+ ! !DESCRIPTION:
!
- ! Determine Turbulent dry deposition for dust. Calculate the turbulent
- ! component of dust dry deposition, (the turbulent deposition velocity
- ! through the lowest atmospheric layer. CAM will calculate the settling
- ! velocity through the whole atmospheric column. The two calculations
+ ! Determine Turbulent dry deposition for dust. Calculate the turbulent
+ ! component of dust dry deposition, (the turbulent deposition velocity
+ ! through the lowest atmospheric layer. CAM will calculate the settling
+ ! velocity through the whole atmospheric column. The two calculations
! will determine the dust dry deposition flux to the surface.
! Note: Same process should occur over oceans. For the coupled CESM,
! we may find it more efficient to let CAM calculate the turbulent dep
@@ -520,10 +364,10 @@ subroutine DustDryDep (bounds, &
use shr_const_mod, only : SHR_CONST_PI, SHR_CONST_RDAIR, SHR_CONST_BOLTZ
!
! !ARGUMENTS:
- type(bounds_type) , intent(in) :: bounds
+ class (dust_emis_base_type) :: this
+ type(bounds_type) , intent(in) :: bounds
type(atm2lnd_type) , intent(in) :: atm2lnd_inst
type(frictionvel_type) , intent(in) :: frictionvel_inst
- type(dust_type) , intent(inout) :: dust_inst
!
! !LOCAL VARIABLES
integer :: p,c,g,m,n ! indices
@@ -538,23 +382,23 @@ subroutine DustDryDep (bounds, &
real(r8) :: slp_crc(bounds%begp:bounds%endp,ndst) ! [frc] Slip correction factor
real(r8) :: vlc_grv(bounds%begp:bounds%endp,ndst) ! [m s-1] Settling velocity
real(r8) :: rss_lmn(bounds%begp:bounds%endp,ndst) ! [s m-1] Quasi-laminar layer resistance
- real(r8) :: tmp ! temporary
+ real(r8) :: tmp ! temporary
real(r8), parameter::shm_nbr_xpn_lnd=-2._r8/3._r8 ![frc] shm_nbr_xpn over land
!------------------------------------------------------------------------
- associate( &
- forc_pbot => atm2lnd_inst%forc_pbot_downscaled_col , & ! Input: [real(r8) (:) ] atm pressure (Pa)
- forc_rho => atm2lnd_inst%forc_rho_downscaled_col , & ! Input: [real(r8) (:) ] atm density (kg/m**3)
- forc_t => atm2lnd_inst%forc_t_downscaled_col , & ! Input: [real(r8) (:) ] atm temperature (K)
-
- ram1 => frictionvel_inst%ram1_patch , & ! Input: [real(r8) (:) ] aerodynamical resistance (s/m)
- fv => frictionvel_inst%fv_patch , & ! Input: [real(r8) (:) ] friction velocity (m/s)
-
- vlc_trb => dust_inst%vlc_trb_patch , & ! Output: [real(r8) (:,:) ] Turbulent deposn velocity (m/s)
- vlc_trb_1 => dust_inst%vlc_trb_1_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 1
- vlc_trb_2 => dust_inst%vlc_trb_2_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 2
- vlc_trb_3 => dust_inst%vlc_trb_3_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 3
- vlc_trb_4 => dust_inst%vlc_trb_4_patch & ! Output: [real(r8) (:) ] Turbulent deposition velocity 4
+ associate( &
+ forc_pbot => atm2lnd_inst%forc_pbot_downscaled_col , & ! Input: [real(r8) (:) ] atm pressure (Pa)
+ forc_rho => atm2lnd_inst%forc_rho_downscaled_col , & ! Input: [real(r8) (:) ] atm density (kg/m**3)
+ forc_t => atm2lnd_inst%forc_t_downscaled_col , & ! Input: [real(r8) (:) ] atm temperature (K)
+
+ ram1 => frictionvel_inst%ram1_patch , & ! Input: [real(r8) (:) ] aerodynamical resistance (s/m)
+ fv => frictionvel_inst%fv_patch , & ! Input: [real(r8) (:) ] friction velocity (m/s)
+
+ vlc_trb => this%vlc_trb_patch , & ! Output: [real(r8) (:,:) ] Turbulent deposn velocity (m/s)
+ vlc_trb_1 => this%vlc_trb_1_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 1
+ vlc_trb_2 => this%vlc_trb_2_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 2
+ vlc_trb_3 => this%vlc_trb_3_patch , & ! Output: [real(r8) (:) ] Turbulent deposition velocity 3
+ vlc_trb_4 => this%vlc_trb_4_patch & ! Output: [real(r8) (:) ] Turbulent deposition velocity 4
)
do p = bounds%begp,bounds%endp
@@ -577,11 +421,11 @@ subroutine DustDryDep (bounds, &
do m = 1, ndst
slp_crc(p,m) = 1.0_r8 + 2.0_r8 * mfp_atm * &
- (1.257_r8+0.4_r8*exp(-1.1_r8*dmt_vwr(m)/(2.0_r8*mfp_atm))) / &
- dmt_vwr(m) ![frc] Slip correction factor SeP97 p. 464
- vlc_grv(p,m) = (1.0_r8/18.0_r8) * dmt_vwr(m) * dmt_vwr(m) * dns_aer * &
+ (1.257_r8+0.4_r8*exp(-1.1_r8*this%dmt_vwr(m)/(2.0_r8*mfp_atm))) / &
+ this%dmt_vwr(m) ![frc] Slip correction factor SeP97 p. 464
+ vlc_grv(p,m) = (1.0_r8/18.0_r8) * this%dmt_vwr(m) * this%dmt_vwr(m) * dns_aer * &
grav * slp_crc(p,m) / vsc_dyn_atm(p) ![m s-1] Stokes' settling velocity SeP97 p. 466
- vlc_grv(p,m) = vlc_grv(p,m) * stk_crc(m) ![m s-1] Correction to Stokes settling velocity
+ vlc_grv(p,m) = vlc_grv(p,m) * this%stk_crc(m) ![m s-1] Correction to Stokes settling velocity
end do
end if
end do
@@ -594,7 +438,7 @@ subroutine DustDryDep (bounds, &
stk_nbr = vlc_grv(p,m) * fv(p) * fv(p) / (grav * vsc_knm_atm(p)) ![frc] SeP97 p.965
dff_aer = SHR_CONST_BOLTZ * forc_t(c) * slp_crc(p,m) / & ![m2 s-1]
- (3.0_r8*SHR_CONST_PI * vsc_dyn_atm(p) * dmt_vwr(m)) !SeP97 p.474
+ (3.0_r8*SHR_CONST_PI * vsc_dyn_atm(p) * this%dmt_vwr(m)) !SeP97 p.474
shm_nbr = vsc_knm_atm(p) / dff_aer ![frc] SeP97 p.972
shm_nbr_xpn = shm_nbr_xpn_lnd ![frc]
@@ -603,7 +447,7 @@ subroutine DustDryDep (bounds, &
! Schmidt number exponent is -2/3 over solid surfaces and
! -1/2 over liquid surfaces SlS80 p. 1014
! if (oro(i)==0.0) shm_nbr_xpn=shm_nbr_xpn_ocn else shm_nbr_xpn=shm_nbr_xpn_lnd
- ! [frc] Surface-dependent exponent for aerosol-diffusion dependence on Schmidt #
+ ! [frc] Surface-dependent exponent for aerosol-diffusion dependence on Schmidt #
tmp = shm_nbr**shm_nbr_xpn + 10.0_r8**(-3.0_r8/stk_nbr)
rss_lmn(p,m) = 1.0_r8 / (tmp * fv(p)) ![s m-1] SeP97 p.972,965
@@ -635,14 +479,15 @@ subroutine DustDryDep (bounds, &
end subroutine DustDryDep
- !------------------------------------------------------------------------
- subroutine InitDustVars(this, bounds)
+ !------------------------------------------------------------------------
+
+ subroutine InitDustVars(this, bounds)
!
- ! !DESCRIPTION:
+ ! !DESCRIPTION:
!
! Compute source efficiency factor from topography
! Initialize other variables used in subroutine Dust:
- ! ovr_src_snk_mss(m,n) and tmp1.
+ ! ovr_src_snk_mss(m,n) and saltation_factor.
! Define particle diameter and density needed by atm model
! as well as by dry dep model
! Source: Paul Ginoux (for source efficiency factor)
@@ -655,8 +500,8 @@ subroutine InitDustVars(this, bounds)
use decompMod , only : get_proc_bounds
!
! !ARGUMENTS:
- class(dust_type) :: this
- type(bounds_type), intent(in) :: bounds
+ class(dust_emis_base_type) :: this
+ type(bounds_type), intent(in) :: bounds
!
! !LOCAL VARIABLES
integer :: fc,c,l,m,n ! indices
@@ -678,7 +523,7 @@ subroutine InitDustVars(this, bounds)
real(r8) :: vlc_grv(ndst) ! [m s-1] Settling velocity
real(r8) :: ryn_nbr_grv(ndst) ! [frc] Reynolds number at terminal velocity
real(r8) :: cff_drg_grv(ndst) ! [frc] Drag coefficient at terminal velocity
- real(r8) :: tmp ! temporary
+ real(r8) :: tmp ! temporary
real(r8) :: ln_gsd ! [frc] ln(gsd)
real(r8) :: gsd_anl ! [frc] Geometric standard deviation
real(r8) :: dmt_vma ! [m] Mass median diameter analytic She84 p.75 Tabl.1
@@ -698,7 +543,7 @@ subroutine InitDustVars(this, bounds)
real(r8) :: sz_max(sz_nbr) ! [m] Size Bin maxima
real(r8) :: sz_ctr(sz_nbr) ! [m] Size Bin centers
real(r8) :: sz_dlt(sz_nbr) ! [m] Size Bin widths
-
+
! constants
real(r8), allocatable :: dmt_vma_src(:) ! [m] Mass median diameter BSM96 p. 73 Table 2
real(r8), allocatable :: gsd_anl_src(:) ! [frc] Geometric std deviation BSM96 p. 73 Table 2
@@ -710,19 +555,16 @@ subroutine InitDustVars(this, bounds)
real(r8), parameter :: dns_slt = 2650.0_r8 ! [kg m-3] Density of optimal saltation particles
!------------------------------------------------------------------------
- ! allocate module variable
- allocate (ovr_src_snk_mss(dst_src_nbr,ndst))
- allocate (dmt_vwr(ndst))
- allocate (stk_crc(ndst))
-
+ call shr_assert_all((lbound(this%ovr_src_snk_mss) == (/1,1/) ), file=sourcefile, line=__LINE__)
+ call shr_assert_all((ubound(this%ovr_src_snk_mss) == (/dst_src_nbr,ndst/) ), file=sourcefile, line=__LINE__)
! allocate local variable
- allocate (dmt_vma_src(dst_src_nbr))
- allocate (gsd_anl_src(dst_src_nbr))
- allocate (mss_frc_src(dst_src_nbr))
+ allocate (dmt_vma_src(dst_src_nbr))
+ allocate (gsd_anl_src(dst_src_nbr))
+ allocate (mss_frc_src(dst_src_nbr))
- dmt_vma_src(:) = (/ 0.832e-6_r8 , 4.82e-6_r8 , 19.38e-6_r8 /)
- gsd_anl_src(:) = (/ 2.10_r8 , 1.90_r8 , 1.60_r8 /)
- mss_frc_src(:) = (/ 0.036_r8 , 0.957_r8 , 0.007_r8 /)
+ dmt_vma_src(:) = (/ 0.832e-6_r8 , 4.82e-6_r8 , 19.38e-6_r8 /)
+ gsd_anl_src(:) = (/ 2.10_r8 , 1.90_r8 , 1.60_r8 /)
+ mss_frc_src(:) = (/ 0.036_r8 , 0.957_r8 , 0.007_r8 /)
! the following comes from (1) szdstlgn.F subroutine ovr_src_snk_frc_get
! and (2) dstszdst.F subroutine dst_szdst_ini
@@ -738,12 +580,12 @@ subroutine InitDustVars(this, bounds)
lndminjovrdmdni = log(dmt_grd(n )/dmt_vma_src(m))
ovr_src_snk_frc = 0.5_r8 * (erf(lndmaxjovrdmdni/sqrt2lngsdi) - &
erf(lndminjovrdmdni/sqrt2lngsdi))
- ovr_src_snk_mss(m,n) = ovr_src_snk_frc * mss_frc_src(m)
+ this%ovr_src_snk_mss(m,n) = ovr_src_snk_frc * mss_frc_src(m)
end do
end do
- ! The following code from subroutine wnd_frc_thr_slt_get was placed
- ! here because tmp1 needs to be defined just once
+ ! The following code from subroutine wnd_frc_thr_slt_get was placed
+ ! here because saltation_factor needs to be defined just once
ryn_nbr_frc_thr_prx_opt = 0.38_r8 + 1331.0_r8 * (100.0_r8*dmt_slt_opt)**1.56_r8
@@ -760,7 +602,7 @@ subroutine InitDustVars(this, bounds)
icf_fct = 1.0_r8 + 6.0e-07_r8 / (dns_slt * grav * (dmt_slt_opt**2.5_r8))
dns_fct = dns_slt * grav * dmt_slt_opt
- tmp1 = sqrt(icf_fct * dns_fct * ryn_nbr_frc_thr_opt_fnc)
+ this%saltation_factor = sqrt(icf_fct * dns_fct * ryn_nbr_frc_thr_opt_fnc)
! Introducing particle diameter. Needed by atm model and by dry dep model.
! Taken from Charlie Zender's subroutines dst_psd_ini, dst_sz_rsl,
@@ -794,7 +636,6 @@ subroutine InitDustVars(this, bounds)
gsd_anl = 2.0_r8 ! [frc] Geometric std dev PaG77 p. 2080 Table1
ln_gsd = log(gsd_anl)
- dns_aer = 2.5e+3_r8 ! [kg m-3] Aerosol density
! Set a fundamental statistic for each bin
@@ -829,7 +670,7 @@ subroutine InitDustVars(this, bounds)
end do
lngsdsqrttwopi_rcp = 1.0_r8 / (ln_gsd*sqrt(2.0_r8*SHR_CONST_PI))
- dmt_vwr(n) = 0.0_r8 ! [m] Mass wgted diameter resolved
+ this%dmt_vwr(n) = 0.0_r8 ! [m] Mass wgted diameter resolved
vlm_rsl(n) = 0.0_r8 ! [m3 m-3] Volume concentration resolved
do m = 1, sz_nbr
@@ -839,7 +680,7 @@ subroutine InitDustVars(this, bounds)
lgn_dst = lngsdsqrttwopi_rcp * exp(-0.5_r8*tmp*tmp) / sz_ctr(m)
! Integrate moments of size distribution
- dmt_vwr(n) = dmt_vwr(n) + sz_ctr(m) * &
+ this%dmt_vwr(n) = this%dmt_vwr(n) + sz_ctr(m) * &
SHR_CONST_PI / 6.0_r8 * (sz_ctr(m)**3.0_r8) * & ![m3] Volume
lgn_dst * sz_dlt(m) ![# m-3] Number concentrn
vlm_rsl(n) = vlm_rsl(n) + &
@@ -848,7 +689,7 @@ subroutine InitDustVars(this, bounds)
end do
- dmt_vwr(n) = dmt_vwr(n) / vlm_rsl(n) ![m] Mass weighted diameter resolved
+ this%dmt_vwr(n) = this%dmt_vwr(n) / vlm_rsl(n) ![m] Mass weighted diameter resolved
end do
@@ -867,9 +708,9 @@ subroutine InitDustVars(this, bounds)
do m = 1, ndst
slp_crc(m) = 1.0_r8 + 2.0_r8 * mfp_atm * &
- (1.257_r8+0.4_r8*exp(-1.1_r8*dmt_vwr(m)/(2.0_r8*mfp_atm))) / &
- dmt_vwr(m) ! [frc] Slip correction factor SeP97 p.464
- vlc_stk(m) = (1.0_r8/18.0_r8) * dmt_vwr(m) * dmt_vwr(m) * dns_aer * &
+ (1.257_r8+0.4_r8*exp(-1.1_r8*this%dmt_vwr(m)/(2.0_r8*mfp_atm))) / &
+ this%dmt_vwr(m) ! [frc] Slip correction factor SeP97 p.464
+ vlc_stk(m) = (1.0_r8/18.0_r8) * this%dmt_vwr(m) * this%dmt_vwr(m) * dns_aer * &
grav * slp_crc(m) / vsc_dyn_atm ! [m s-1] SeP97 p.466
end do
@@ -894,7 +735,7 @@ subroutine InitDustVars(this, bounds)
! Save terminal velocity for convergence test
vlc_grv_old = vlc_grv(m) ![m s-1]
- ryn_nbr_grv(m) = vlc_grv(m) * dmt_vwr(m) / vsc_knm_atm !SeP97 p.460
+ ryn_nbr_grv(m) = vlc_grv(m) * this%dmt_vwr(m) / vsc_knm_atm !SeP97 p.460
! Update drag coefficient based on new Reynolds number
if (ryn_nbr_grv(m) < 0.1_r8) then
@@ -918,8 +759,8 @@ subroutine InitDustVars(this, bounds)
! Update terminal velocity based on new Reynolds number and drag coeff
! [m s-1] Terminal veloc SeP97 p.467 (8.44)
- vlc_grv(m) = sqrt(4.0_r8 * grav * dmt_vwr(m) * slp_crc(m) * dns_aer / &
- (3.0_r8*cff_drg_grv(m)*dns_mdp))
+ vlc_grv(m) = sqrt(4.0_r8 * grav * this%dmt_vwr(m) * slp_crc(m) * dns_aer / &
+ (3.0_r8*cff_drg_grv(m)*dns_mdp))
eps_crr = abs((vlc_grv(m)-vlc_grv_old)/vlc_grv(m)) !Relative convergence
if (itr_idx == 12) then
! Numerical pingpong may occur when Re = 0.1, 2.0, or 500.0
@@ -942,9 +783,11 @@ subroutine InitDustVars(this, bounds)
! actual settling velocities
do m = 1, ndst
- stk_crc(m) = vlc_grv(m) / vlc_stk(m)
+ this%stk_crc(m) = vlc_grv(m) / vlc_stk(m)
end do
end subroutine InitDustVars
-end module DUSTMod
+ !------------------------------------------------------------------------
+
+end module DustEmisBase
diff --git a/src/biogeochem/DustEmisFactory.F90 b/src/biogeochem/DustEmisFactory.F90
new file mode 100644
index 0000000000..371e77d6dc
--- /dev/null
+++ b/src/biogeochem/DustEmisFactory.F90
@@ -0,0 +1,62 @@
+module DustEmisFactory
+ !---------------------------------------------------------------------------
+ !
+ ! Factory to figure out whihc dust emission method to instantiate
+ !
+ !---------------------------------------------------------------------------
+ use abortutils , only : endrun
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use clm_varctl , only : iulog
+
+ implicit none
+ save
+ private
+ !
+ public :: create_dust_emissions ! create an object of class dust_emis_base
+
+ character(len=*), parameter, private :: sourcefile = &
+ __FILE__
+
+contains
+
+ !---------------------------------------------------------------------------
+
+ function create_dust_emissions(bounds, NLFilename) result(dust_emis)
+ !---------------------------------------------------------------------------
+ ! Create a dust_emission base class objecct
+ ! The method implemented depends on namelist input
+ !---------------------------------------------------------------------------
+ use DustEmisBase , only : dust_emis_base_type
+ use DustEmisZender2003, only : dust_emis_zender2003_type
+ use clm_varctl , only : dust_emis_method
+ use decompMod , only : bounds_type
+ use shr_kind_mod , only : CL => shr_kind_cl
+ implicit none
+ ! Arguments
+ class(dust_emis_base_type), allocatable :: dust_emis
+ type(bounds_type), intent(in) :: bounds
+ character(len=*), intent(in) :: NLFilename
+ ! Local variables
+
+ select case ( trim(dust_emis_method) )
+
+ case( "Zender_2003" )
+ allocate(dust_emis, source=dust_emis_zender2003_type() )
+
+ ! This will be added when the Leung2023 comes in
+ !case( "Leung_2023" )
+ ! allocate(dust_emis, source=dust_emis_zender2003_type() )
+ case default
+ write(iulog,*) 'ERROR: unknown dust_emis_method: ', dust_emis_method, &
+ errMsg(sourcefile, __LINE__)
+ call endrun( "Unrecognized dust_emis_method" )
+
+ end select
+
+ call dust_emis%Init(bounds, NLFilename)
+
+ end function create_dust_emissions
+
+ !---------------------------------------------------------------------------
+
+end module DustEmisFactory
diff --git a/src/biogeochem/DustEmisZender2003.F90 b/src/biogeochem/DustEmisZender2003.F90
new file mode 100644
index 0000000000..cee704ad47
--- /dev/null
+++ b/src/biogeochem/DustEmisZender2003.F90
@@ -0,0 +1,470 @@
+module DustEmisZender2003
+
+ !-----------------------------------------------------------------------
+ ! !DESCRIPTION:
+ ! Routines in this module calculate Dust mobilization and dry deposition for dust.
+ ! Simulates dust mobilization due to wind from the surface into the
+ ! lowest atmospheric layer. On output flx_mss_vrt_dst(ndst) is the surface dust
+ ! emission (kg/m**2/s) [ + = to atm].
+ ! Calculates the turbulent component of dust dry deposition, (the turbulent deposition
+ ! velocity through the lowest atmospheric layer). CAM will calculate the settling
+ ! velocity through the whole atmospheric column. The two calculations will determine
+ ! the dust dry deposition flux to the surface.
+ !
+ ! !USES:
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
+ use clm_varpar , only : dst_src_nbr, ndst
+ use clm_varcon , only : grav, spval
+ use landunit_varcon , only : istcrop, istsoil
+ use clm_varctl , only : iulog
+ use abortutils , only : endrun
+ use decompMod , only : bounds_type, subgrid_level_landunit
+ use atm2lndType , only : atm2lnd_type
+ use SoilStateType , only : soilstate_type
+ use CanopyStateType , only : canopystate_type
+ use WaterStateBulkType , only : waterstatebulk_type
+ use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type
+ use FrictionVelocityMod , only : frictionvel_type
+ use LandunitType , only : lun
+ use PatchType , only : patch
+ use ZenderSoilErodStreamType, only : soil_erod_stream_type
+ use DustEmisBase , only : dust_emis_base_type
+ !
+ ! !PUBLIC TYPES
+ implicit none
+ private
+ !
+ ! !PRIVATE DATA:
+ !
+ !
+ ! !PUBLIC DATA TYPES:
+ !
+ type, public, extends(dust_emis_base_type) :: dust_emis_zender2003_type
+
+ real(r8), pointer, private :: mbl_bsn_fct_col (:) ! [dimensionless] basin factor, or soil rodibility, time-constant
+ type(soil_erod_stream_type), private :: soil_erod_stream ! Zender soil erodibility stream data
+
+ contains
+
+ procedure , public :: Init => InitZender2003
+ procedure , public :: DustEmission ! Dust mobilization
+ procedure , public :: Clean => CleanZender2003
+ procedure , private :: InitAllocate ! Allocate data
+ procedure , private :: InitHistory ! History initialization
+ procedure , private :: InitCold
+
+ end type dust_emis_zender2003_type
+
+ interface dust_emis_zender2003_type
+ ! initialize a new dust emission object
+ module procedure constructor
+ end interface dust_emis_zender2003_type
+ !------------------------------------------------------------------------
+
+ character(len=*), parameter, private :: sourcefile = &
+ __FILE__
+
+contains
+
+ !-----------------------------------------------------------------------
+ type(dust_emis_zender2003_type) function constructor()
+ !
+ ! Creates a dust emission object for Zender-2003 type
+ ! For now this is just a placeholder
+ !-----------------------------------------------------------------------
+
+ end function constructor
+
+ !------------------------------------------------------------------------
+
+ subroutine InitZender2003(this, bounds, NLFilename)
+
+ ! Initialization for this extended class, calling base level initiation and adding to it
+ class(dust_emis_zender2003_type) :: this
+ type(bounds_type), intent(in) :: bounds
+ character(len=*), intent(in) :: NLFilename
+
+ call this%soil_erod_stream%Init( bounds, NLFilename )
+ call this%InitBase(bounds, NLFilename)
+ call this%InitAllocate (bounds)
+ call this%InitHistory (bounds)
+ call this%InitCold (bounds)
+
+ end subroutine InitZender2003
+
+ !------------------------------------------------------------------------
+
+ subroutine InitAllocate(this, bounds)
+ !
+ ! !ARGUMENTS:
+ class (dust_emis_zender2003_type) :: this
+ type(bounds_type), intent(in) :: bounds
+ !
+ ! !LOCAL VARIABLES:
+ integer :: begc,endc
+ !------------------------------------------------------------------------
+
+ begc = bounds%begc ; endc = bounds%endc
+
+ allocate(this%mbl_bsn_fct_col (begc:endc)) ; this%mbl_bsn_fct_col (:) = nan
+
+ end subroutine InitAllocate
+
+ !------------------------------------------------------------------------
+
+ subroutine CleanZender2003(this)
+ !
+ ! Deallocation for this extended class, calling base level deallocation and adding to it
+ ! !ARGUMENTS:
+ class (dust_emis_zender2003_type) :: this
+ !
+ ! !LOCAL VARIABLES:
+ !------------------------------------------------------------------------
+
+ call this%CleanBase()
+ deallocate(this%mbl_bsn_fct_col)
+
+ end subroutine CleanZender2003
+
+ !------------------------------------------------------------------------
+
+ subroutine InitHistory(this, bounds)
+ !
+ ! !USES:
+ use histFileMod, only : hist_addfld1d
+ !
+ !
+ ! !ARGUMENTS:
+ class (dust_emis_zender2003_type) :: this
+ type(bounds_type), intent(in) :: bounds
+ !
+ ! !LOCAL VARIABLES:
+ integer :: begc,endc
+ !------------------------------------------------------------------------
+
+ begc = bounds%begc; endc = bounds%endc
+
+ if ( this%soil_erod_stream%UseStreams() )then
+ this%mbl_bsn_fct_col(begc:endc) = spval
+ call hist_addfld1d (fname='LND_MBL', units='fraction', &
+ avgflag='A', long_name='Soil erodibility factor', &
+ ptr_col=this%mbl_bsn_fct_col, default='inactive')
+ end if
+
+ end subroutine InitHistory
+
+ !-----------------------------------------------------------------------
+
+ subroutine InitCold(this, bounds)
+ !
+ ! Initialize values from a cold start
+ ! !ARGUMENTS:
+ class (dust_emis_zender2003_type) :: this
+ type(bounds_type), intent(in) :: bounds
+ !
+ ! !LOCAL VARIABLES:
+ integer :: c,l
+ !-----------------------------------------------------------------------
+
+ if ( this%soil_erod_stream%UseStreams() )then
+ call this%soil_erod_stream%CalcDustSource( bounds, &
+ this%mbl_bsn_fct_col(bounds%begc:bounds%endc) )
+ else
+ this%mbl_bsn_fct_col(:) = 1.0_r8
+ end if
+
+ end subroutine InitCold
+
+ !------------------------------------------------------------------------
+
+ subroutine DustEmission (this, bounds, &
+ num_nolakep, filter_nolakep, &
+ atm2lnd_inst, soilstate_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, &
+ frictionvel_inst)
+ !
+ ! !DESCRIPTION:
+ ! Dust mobilization. This code simulates dust mobilization due to wind
+ ! from the surface into the lowest atmospheric layer
+ ! On output flx_mss_vrt_dst(ndst) is the surface dust emission
+ ! (kg/m**2/s) [ + = to atm]
+ ! Source: C. Zender's dust model
+ !
+ ! !USES
+ use shr_const_mod, only : SHR_CONST_RHOFW
+ use subgridaveMod, only : p2g
+ !
+ ! !ARGUMENTS:
+ class (dust_emis_zender2003_type) :: this
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_nolakep ! number of column non-lake points in patch filter
+ integer , intent(in) :: filter_nolakep(num_nolakep) ! patch filter for non-lake points
+ type(atm2lnd_type) , intent(in) :: atm2lnd_inst
+ type(soilstate_type) , intent(in) :: soilstate_inst
+ type(canopystate_type) , intent(in) :: canopystate_inst
+ type(waterstatebulk_type) , intent(in) :: waterstatebulk_inst
+ type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst
+ type(frictionvel_type) , intent(in) :: frictionvel_inst
+
+ !
+ ! !LOCAL VARIABLES
+ integer :: fp,p,c,l,g,m,n ! indices
+ real(r8) :: liqfrac ! fraction of total water that is liquid
+ real(r8) :: wnd_frc_rat ! [frc] Wind friction threshold over wind friction
+ real(r8) :: wnd_frc_slt_dlt ! [m s-1] Friction velocity increase from saltatn
+ real(r8) :: wnd_rfr_dlt ! [m s-1] Reference windspeed excess over threshld
+ real(r8) :: dst_slt_flx_rat_ttl
+ real(r8) :: flx_mss_hrz_slt_ttl
+ real(r8) :: flx_mss_vrt_dst_ttl(bounds%begp:bounds%endp)
+ real(r8) :: frc_thr_wet_fct
+ real(r8) :: frc_thr_rgh_fct
+ real(r8) :: wnd_frc_thr_slt
+ real(r8) :: wnd_rfr_thr_slt
+ real(r8) :: wnd_frc_slt
+ real(r8) :: lnd_frc_mbl(bounds%begp:bounds%endp)
+ real(r8) :: bd
+ real(r8) :: gwc_sfc
+ real(r8) :: ttlai(bounds%begp:bounds%endp)
+ real(r8) :: tlai_lu(bounds%begl:bounds%endl)
+ real(r8) :: sumwt(bounds%begl:bounds%endl) ! sum of weights
+ logical :: found ! temporary for error check
+ integer :: index
+ !
+ ! constants
+ !
+ real(r8), parameter :: cst_slt = 2.61_r8 ! [frc] Saltation constant
+ real(r8), parameter :: flx_mss_fdg_fct = 5.0e-4_r8 ! [frc] Empir. mass flx tuning eflx_lh_vegt
+ real(r8), parameter :: vai_mbl_thr = 0.3_r8 ! [m2 m-2] VAI threshold quenching dust mobilization
+ character(len=*),parameter :: subname = 'DUSTEmission'
+ !------------------------------------------------------------------------
+
+ associate( &
+ forc_rho => atm2lnd_inst%forc_rho_downscaled_col , & ! Input: [real(r8) (:) ] downscaled density (kg/m**3)
+
+ gwc_thr => soilstate_inst%gwc_thr_col , & ! Input: [real(r8) (:) ] threshold gravimetric soil moisture based on clay content
+ mss_frc_cly_vld => soilstate_inst%mss_frc_cly_vld_col , & ! Input: [real(r8) (:) ] [frc] Mass fraction clay limited to 0.20
+ watsat => soilstate_inst%watsat_col , & ! Input: [real(r8) (:,:) ] saturated volumetric soil water
+
+ tlai => canopystate_inst%tlai_patch , & ! Input: [real(r8) (:) ] one-sided leaf area index, no burying by snow
+ tsai => canopystate_inst%tsai_patch , & ! Input: [real(r8) (:) ] one-sided stem area index, no burying by snow
+
+ frac_sno => waterdiagnosticbulk_inst%frac_sno_col , & ! Input: [real(r8) (:) ] fraction of ground covered by snow (0 to 1)
+ h2osoi_vol => waterstatebulk_inst%h2osoi_vol_col , & ! Input: [real(r8) (:,:) ] volumetric soil water (0<=h2osoi_vol<=watsat)
+ h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input: [real(r8) (:,:) ] liquid soil water (kg/m2)
+ h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input: [real(r8) (:,:) ] frozen soil water (kg/m2)
+
+ fv => frictionvel_inst%fv_patch , & ! Input: [real(r8) (:) ] friction velocity (m/s) (for dust model)
+ u10 => frictionvel_inst%u10_patch , & ! Input: [real(r8) (:) ] 10-m wind (m/s) (created for dust model)
+
+ mbl_bsn_fct => this%mbl_bsn_fct_col , & ! Input: [real(r8) (:) ] basin factor
+ flx_mss_vrt_dst => this%flx_mss_vrt_dst_patch , & ! Output: [real(r8) (:,:) ] surface dust emission (kg/m**2/s)
+ flx_mss_vrt_dst_tot => this%flx_mss_vrt_dst_tot_patch & ! Output: [real(r8) (:) ] total dust flux back to atmosphere (pft)
+ )
+
+ ttlai(bounds%begp : bounds%endp) = 0._r8
+ ! make lai average at landunit level
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ ttlai(p) = tlai(p)+tsai(p)
+ enddo
+
+ tlai_lu(bounds%begl : bounds%endl) = spval
+ sumwt(bounds%begl : bounds%endl) = 0._r8
+ do p = bounds%begp,bounds%endp
+ if (ttlai(p) /= spval .and. patch%active(p) .and. patch%wtlunit(p) /= 0._r8) then
+ c = patch%column(p)
+ l = patch%landunit(p)
+ if (sumwt(l) == 0._r8) tlai_lu(l) = 0._r8
+ tlai_lu(l) = tlai_lu(l) + ttlai(p) * patch%wtlunit(p)
+ sumwt(l) = sumwt(l) + patch%wtlunit(p)
+ end if
+ end do
+ found = .false.
+ do l = bounds%begl,bounds%endl
+ if (sumwt(l) > 1.0_r8 + 1.e-6_r8) then
+ found = .true.
+ index = l
+ exit
+ else if (sumwt(l) /= 0._r8) then
+ tlai_lu(l) = tlai_lu(l)/sumwt(l)
+ end if
+ end do
+ if (found) then
+ write(iulog,*) subname//':: error: sumwt is greater than 1.0 at l= ',index
+ call endrun(subgrid_index=index, subgrid_level=subgrid_level_landunit, msg=errMsg(sourcefile, __LINE__))
+ end if
+
+ ! Loop through patches
+
+ ! initialize variables which get passed to the atmosphere
+ flx_mss_vrt_dst(bounds%begp:bounds%endp,:)=0._r8
+
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ c = patch%column(p)
+ l = patch%landunit(p)
+
+ ! the following code from subr. lnd_frc_mbl_get was adapted for lsm use
+ ! purpose: return fraction of each gridcell suitable for dust mobilization
+
+ ! the "bare ground" fraction of the current sub-gridscale cell decreases
+ ! linearly from 1 to 0 as VAI(=tlai+tsai) increases from 0 to vai_mbl_thr
+ ! if ice sheet, wetland, or lake, no dust allowed
+
+ if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
+ if (tlai_lu(l) < vai_mbl_thr) then
+ lnd_frc_mbl(p) = 1.0_r8 - (tlai_lu(l))/vai_mbl_thr
+ else
+ lnd_frc_mbl(p) = 0.0_r8
+ endif
+ lnd_frc_mbl(p) = lnd_frc_mbl(p) * (1.0_r8 - frac_sno(c))
+ else
+ lnd_frc_mbl(p) = 0.0_r8
+ end if
+ end do
+
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ if (lnd_frc_mbl(p)>1.0_r8 .or. lnd_frc_mbl(p)<0.0_r8) then
+ write(iulog,*)'Error dstmbl: pft= ',p,' lnd_frc_mbl(p)= ',lnd_frc_mbl(p), &
+ errMsg(sourcefile, __LINE__)
+ call endrun("Bad value for dust mobilization fraction")
+ return
+ end if
+ end do
+
+ ! reset history output variables before next if-statement to avoid output = inf
+
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ flx_mss_vrt_dst_tot(p) = 0.0_r8
+ end do
+ do n = 1, ndst
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ flx_mss_vrt_dst(p,n) = 0.0_r8
+ end do
+ end do
+
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ c = patch%column(p)
+ l = patch%landunit(p)
+ g = patch%gridcell(p)
+
+ ! only perform the following calculations if lnd_frc_mbl is non-zero
+
+ if (lnd_frc_mbl(p) > 0.0_r8) then
+
+ ! the following comes from subr. frc_thr_rgh_fct_get
+ ! purpose: compute factor by which surface roughness increases threshold
+ ! friction velocity (currently a constant)
+
+ frc_thr_rgh_fct = 1.0_r8
+
+ ! the following comes from subr. frc_thr_wet_fct_get
+ ! purpose: compute factor by which soil moisture increases threshold friction velocity
+ ! adjust threshold velocity for inhibition by moisture
+ ! modified 4/5/2002 (slevis) to use gravimetric instead of volumetric
+ ! water content
+
+ bd = (1._r8-watsat(c,1))*2.7e3_r8 ![kg m-3] Bulk density of dry surface soil
+ gwc_sfc = h2osoi_vol(c,1)*SHR_CONST_RHOFW/bd ![kg kg-1] Gravimetric H2O cont
+ if (gwc_sfc > gwc_thr(c)) then
+ frc_thr_wet_fct = sqrt(1.0_r8 + 1.21_r8 * (100.0_r8*(gwc_sfc - gwc_thr(c)))**0.68_r8)
+ else
+ frc_thr_wet_fct = 1.0_r8
+ end if
+
+ ! slevis: adding liqfrac here, because related to effects from soil water
+
+ liqfrac = max( 0.0_r8, min( 1.0_r8, h2osoi_liq(c,1) / (h2osoi_ice(c,1)+h2osoi_liq(c,1)+1.0e-6_r8) ) )
+
+ ! the following lines come from subr. dst_mbl
+ ! purpose: adjust threshold friction velocity to acct for moisture and
+ ! roughness. The ratio saltation_factor / sqrt(forc_rho) comes from
+ ! subr. wnd_frc_thr_slt_get which computes dry threshold
+ ! friction velocity for saltation
+
+ wnd_frc_thr_slt = this%saltation_factor / sqrt(forc_rho(c)) * frc_thr_wet_fct * frc_thr_rgh_fct
+
+ ! reset these variables which will be updated in the following if-block
+
+ wnd_frc_slt = fv(p)
+ flx_mss_hrz_slt_ttl = 0.0_r8
+ flx_mss_vrt_dst_ttl(p) = 0.0_r8
+
+ ! the following line comes from subr. dst_mbl
+ ! purpose: threshold saltation wind speed
+
+ wnd_rfr_thr_slt = u10(p) * wnd_frc_thr_slt / fv(p)
+
+ ! the following if-block comes from subr. wnd_frc_slt_get
+ ! purpose: compute the saltating friction velocity
+ ! theory: saltation roughens the boundary layer, AKA "Owen's effect"
+
+ if (u10(p) >= wnd_rfr_thr_slt) then
+ wnd_rfr_dlt = u10(p) - wnd_rfr_thr_slt
+ wnd_frc_slt_dlt = 0.003_r8 * wnd_rfr_dlt * wnd_rfr_dlt
+ wnd_frc_slt = fv(p) + wnd_frc_slt_dlt
+ end if
+
+ ! the following comes from subr. flx_mss_hrz_slt_ttl_Whi79_get
+ ! purpose: compute vertically integrated streamwise mass flux of particles
+
+ if (wnd_frc_slt > wnd_frc_thr_slt) then
+ wnd_frc_rat = wnd_frc_thr_slt / wnd_frc_slt
+ flx_mss_hrz_slt_ttl = cst_slt * forc_rho(c) * (wnd_frc_slt**3.0_r8) * &
+ (1.0_r8 - wnd_frc_rat) * (1.0_r8 + wnd_frc_rat) * (1.0_r8 + wnd_frc_rat) / grav
+
+ ! the following loop originates from subr. dst_mbl
+ ! purpose: apply land sfc and veg limitations and global tuning factor
+ ! slevis: multiply flx_mss_hrz_slt_ttl by liqfrac to incude the effect
+ ! of frozen soil
+
+ flx_mss_hrz_slt_ttl = flx_mss_hrz_slt_ttl * lnd_frc_mbl(p) * mbl_bsn_fct(c) * &
+ flx_mss_fdg_fct * liqfrac
+ end if
+
+ ! the following comes from subr. flx_mss_vrt_dst_ttl_MaB95_get
+ ! purpose: diagnose total vertical mass flux of dust from vertically
+ ! integrated streamwise mass flux
+
+ dst_slt_flx_rat_ttl = 100.0_r8 * exp( log(10.0_r8) * (13.4_r8 * mss_frc_cly_vld(c) - 6.0_r8) )
+ flx_mss_vrt_dst_ttl(p) = flx_mss_hrz_slt_ttl * dst_slt_flx_rat_ttl
+
+ end if ! lnd_frc_mbl > 0.0
+
+ end do
+
+ ! the following comes from subr. flx_mss_vrt_dst_prt in C. Zender's code
+ ! purpose: partition total vertical mass flux of dust into transport bins
+
+ do n = 1, ndst
+ do m = 1, dst_src_nbr
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ if (lnd_frc_mbl(p) > 0.0_r8) then
+ flx_mss_vrt_dst(p,n) = flx_mss_vrt_dst(p,n) + this%ovr_src_snk_mss(m,n) * flx_mss_vrt_dst_ttl(p)
+ end if
+ end do
+ end do
+ end do
+
+ do n = 1, ndst
+ do fp = 1,num_nolakep
+ p = filter_nolakep(fp)
+ if (lnd_frc_mbl(p) > 0.0_r8) then
+ flx_mss_vrt_dst_tot(p) = flx_mss_vrt_dst_tot(p) + flx_mss_vrt_dst(p,n)
+ end if
+ end do
+ end do
+
+ end associate
+
+ end subroutine DustEmission
+
+ !------------------------------------------------------------------------
+
+end module DustEmisZender2003
\ No newline at end of file
diff --git a/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90 b/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
index bb45074e7b..0980ff5378 100644
--- a/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
+++ b/src/biogeochem/NutrientCompetitionCLM45defaultMod.F90
@@ -92,7 +92,6 @@ subroutine calc_plant_nutrient_competition (this, &
use CNVegNitrogenStateType, only : cnveg_nitrogenstate_type
use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
use SoilBiogeochemNitrogenStateType, only : soilbiogeochem_nitrogenstate_type
- use CNSharedParamsMod , only : use_fun
!
! !ARGUMENTS:
class(nutrient_competition_clm45default_type), intent(inout) :: this
@@ -114,7 +113,7 @@ subroutine calc_plant_nutrient_competition (this, &
call this%calc_plant_cn_alloc (bounds, num_soilp, filter_soilp, &
cnveg_state_inst, crop_inst, canopystate_inst, &
cnveg_carbonstate_inst, cnveg_carbonflux_inst, c13_cnveg_carbonflux_inst, &
- c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, &
+ c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, &
fpg_col=fpg_col(bounds%begc:bounds%endc))
end subroutine calc_plant_nutrient_competition
@@ -123,7 +122,7 @@ end subroutine calc_plant_nutrient_competition
subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
cnveg_state_inst, crop_inst, canopystate_inst, &
cnveg_carbonstate_inst, cnveg_carbonflux_inst, c13_cnveg_carbonflux_inst, &
- c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, cnveg_nitrogenstate_inst, fpg_col)
+ c14_cnveg_carbonflux_inst, cnveg_nitrogenflux_inst, fpg_col)
!
! !USES:
use pftconMod , only : pftcon, npcropmin
@@ -134,8 +133,7 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
use CNVegCarbonStateType , only : cnveg_carbonstate_type
use CNVegCarbonFluxType , only : cnveg_carbonflux_type
use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
- use CNVegNitrogenStateType, only : cnveg_nitrogenstate_type
- use CNSharedParamsMod , only : use_fun, use_matrixcn
+ use CNSharedParamsMod , only : use_fun
use shr_infnan_mod , only : shr_infnan_isnan
!
@@ -152,7 +150,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
type(cnveg_carbonflux_type) , intent(inout) :: c13_cnveg_carbonflux_inst
type(cnveg_carbonflux_type) , intent(inout) :: c14_cnveg_carbonflux_inst
type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
- type(cnveg_nitrogenstate_type) , intent(inout) :: cnveg_nitrogenstate_inst
real(r8) , intent(in) :: fpg_col(bounds%begc:)
!
! !LOCAL VARIABLES:
@@ -229,7 +226,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
npool_to_reproductiven_storage => cnveg_nitrogenflux_inst%npool_to_reproductiven_storage_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N storage (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
sminn_to_npool => cnveg_nitrogenflux_inst%sminn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of soil mineral N uptake (gN/m2/s)
- retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
npool_to_leafn => cnveg_nitrogenflux_inst%npool_to_leafn_patch , & ! Output: [real(r8) (:) ] allocation to leaf N (gN/m2/s)
npool_to_leafn_storage => cnveg_nitrogenflux_inst%npool_to_leafn_storage_patch , & ! Output: [real(r8) (:) ] allocation to leaf N storage (gN/m2/s)
npool_to_frootn => cnveg_nitrogenflux_inst%npool_to_frootn_patch , & ! Output: [real(r8) (:) ] allocation to fine root N (gN/m2/s)
@@ -311,11 +307,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
plant_nalloc(p) = sminn_to_npool(p) + retransn_to_npool(p)
plant_calloc(p) = plant_nalloc(p) * (c_allometry(p)/n_allometry(p))
- ! Assign the above terms to the CN-Matrix solution
- if (use_matrixcn)then
- end if
-
-
if(.not.use_fun)then !ORIGINAL CLM(CN) downregulation code.
excess_cflux(p) = availc(p) - plant_calloc(p)
! reduce gpp fluxes due to N limitation
@@ -330,13 +321,13 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
c13_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) *(1._r8 - downreg(p))
c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p) = &
c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p)*(1._r8 - downreg(p))
- end if
+ endif
if ( use_c14 ) then
c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) = &
c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p) *(1._r8 - downreg(p))
c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p) = &
c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p)*(1._r8 - downreg(p))
- end if
+ endif
end if
end if !use_fun
@@ -411,10 +402,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
end do
end if
- ! Assign above terms to the matrix solution
- if (use_matrixcn) then
- end if !end use_matrixcn
-
! Calculate the amount of carbon that needs to go into growth
! respiration storage to satisfy all of the storage growth demands.
! Allows for the fraction of growth respiration that is released at the
@@ -440,9 +427,6 @@ subroutine calc_plant_cn_alloc (this, bounds, num_soilp, filter_soilp, &
end if
cpool_to_gresp_storage(p) = gresp_storage * g1 * (1._r8 - g2)
- ! Assign above terms to the matrix solution
- if(use_matrixcn)then
- end if !end use_matrixcn
end do ! end patch loop
end associate
@@ -469,7 +453,6 @@ subroutine calc_plant_nutrient_demand(this, bounds, &
use SoilBiogeochemCarbonFluxType, only : soilbiogeochem_carbonflux_type
use SoilBiogeochemNitrogenStateType, only : soilbiogeochem_nitrogenstate_type
use EnergyFluxType , only : energyflux_type
- use CNSharedParamsMod , only : use_fun
!
! !ARGUMENTS:
class(nutrient_competition_clm45default_type), intent(inout) :: this
@@ -525,7 +508,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
use pftconMod , only : npcropmin, pftcon
use pftconMod , only : ntmp_soybean, nirrig_tmp_soybean
use pftconMod , only : ntrp_soybean, nirrig_trp_soybean
- use CNSharedParamsMod , only : use_matrixcn
use clm_time_manager , only : get_step_size_real
use CropType , only : crop_type
use CNVegStateType , only : cnveg_state_type
@@ -598,9 +580,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
livestemc => cnveg_carbonstate_inst%livestemc_patch , & ! Input: [real(r8) (:) ]
retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
- leafn => cnveg_nitrogenstate_inst%leafn_patch , & ! Input: [real(r8) (:) ] (gN/m2) leaf N
- livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N
- frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) fine root N
gpp => cnveg_carbonflux_inst%gpp_before_downreg_patch , & ! Input: [real(r8) (:) ] GPP flux before downregulation (gC/m2/s)
availc => cnveg_carbonflux_inst%availc_patch , & ! Input: [real(r8) (:) ] C flux available for allocation (gC/m2/s)
@@ -681,9 +660,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
end if !fun
grain_flag(p) = 1._r8
- ! Apply above to the matrix solution
- if(use_matrixcn)then
- end if
end if
end if
end if
diff --git a/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90 b/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
index 6f8632658d..993c0a2e9a 100644
--- a/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
+++ b/src/biogeochem/NutrientCompetitionFlexibleCNMod.F90
@@ -29,9 +29,8 @@ module NutrientCompetitionFlexibleCNMod
use CropReprPoolsMod , only : nrepr
use CNPhenologyMod , only : CropPhase
use CropType , only : cphase_leafemerge, cphase_grainfill
- use clm_varctl , only : iulog, use_crop_agsys
+ use clm_varctl , only : use_crop_agsys
use CNSharedParamsMod , only : use_matrixcn
- use abortutils , only : endrun
!
implicit none
private
@@ -61,14 +60,13 @@ module NutrientCompetitionFlexibleCNMod
module procedure constructor
end interface nutrient_competition_FlexibleCN_type
!
-
! !PRIVATE MEMBER FUNCTIONS:
private :: calc_npool_to_components_flexiblecn ! Calculate npool_to_* terms for a single patch using the FlexibleCN approach
private :: calc_npool_to_components_agsys ! Calculate npool_to_* terms for a single crop patch when using AgSys
! !PRIVATE DATA:
- logical,parameter :: matrixcheck_ph = .True. ! If matrix solution check should be applied
- logical,parameter :: acc_ph = .False. ! Another matrix check option
+ logical,parameter :: matrixcheck_ph = .True.
+ logical,parameter :: acc_ph = .False.
character(len=*), parameter, private :: sourcefile = &
__FILE__
@@ -211,7 +209,14 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
use CNSharedParamsMod , only : use_fun
use CNPrecisionControlMod , only : n_min
use clm_varcon , only : spval
-
+ !index for matrixcn
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn,nvegnpool
+ use CNVegMatrixMod , only : matrix_update_phn
!
! !ARGUMENTS:
class(nutrient_competition_FlexibleCN_type), intent(inout) :: this
@@ -238,6 +243,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
real(r8) :: gresp_storage ! temporary variable for growth resp to storage
real(r8) :: nlc ! temporary variable for total new leaf carbon allocation
real(r8) :: f5(nrepr) ! reproductive allocation parameters
+ real(r8) :: dt ! model time step
real(r8):: frootcn_storage_actual
real(r8):: frootcn_actual
@@ -249,8 +255,8 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
real(r8):: frootcn_max
real(r8):: livewdcn_max
real(r8):: frac_resp
- real(r8):: npool_to_veg ! Temporary for nitrogen pool transfer to vegetation components
- real(r8):: cpool_to_veg ! Temporary for carbon pool transfer to vegetation components
+ real(r8):: npool_to_veg
+ real(r8):: cpool_to_veg
real(r8) :: tmp
! -----------------------------------------------------------------------
@@ -292,7 +298,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
annsum_npp => cnveg_carbonflux_inst%annsum_npp_patch , & ! Input: [real(r8) (:) ] annual sum of NPP, for wood allocation
availc => cnveg_carbonflux_inst%availc_patch , & ! Output: [real(r8) (:) ] C flux available for allocation (gC/m2/s)
plant_calloc => cnveg_carbonflux_inst%plant_calloc_patch , & ! Output: [real(r8) (:) ] total allocated C flux (gC/m2/s)
- npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! Output: [real(r8) (:) ] C for growth in FUN. g/m2/s
+ npp_growth => cnveg_carbonflux_inst%npp_growth_patch , & ! output: [real(r8) (:) ] c for growth in fun. g/m2/s
cpool_to_resp => cnveg_carbonflux_inst%cpool_to_resp_patch , & ! output: [real(r8) (:) ]
cpool_to_leafc_resp => cnveg_carbonflux_inst%cpool_to_leafc_resp_patch , & ! Output: [real(r8) (:) ]
cpool_to_leafc_storage_resp => cnveg_carbonflux_inst%cpool_to_leafc_storage_resp_patch , & ! Output: [real(r8) (:) ]
@@ -329,7 +335,7 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
npool_to_reproductiven => cnveg_nitrogenflux_inst%npool_to_reproductiven_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N (gN/m2/s)
npool_to_reproductiven_storage => cnveg_nitrogenflux_inst%npool_to_reproductiven_storage_patch , & ! Output: [real(r8) (:,:) ] allocation to grain N storage (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
- retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
+ retransn => cnveg_nitrogenstate_inst%retransn_patch , & ! Input: [real(r8) (:) ] (gN/m2) plant pool of retranslocated N
sminn_to_npool => cnveg_nitrogenflux_inst%sminn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of soil mineral N uptake (gN/m2/s)
npool_to_leafn => cnveg_nitrogenflux_inst%npool_to_leafn_patch , & ! Output: [real(r8) (:) ] allocation to leaf N (gN/m2/s)
npool_to_leafn_storage => cnveg_nitrogenflux_inst%npool_to_leafn_storage_patch , & ! Output: [real(r8) (:) ] allocation to leaf N storage (gN/m2/s)
@@ -349,9 +355,31 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
Nnonmyc => cnveg_nitrogenflux_inst%Nnonmyc_patch , & ! Output: [real(r8) (:) ] Non-mycorrhizal N uptake (gN/m2/s)
Nam => cnveg_nitrogenflux_inst%Nam_patch , & ! Output: [real(r8) (:) ] AM uptake (gN/m2/s)
Necm => cnveg_nitrogenflux_inst%Necm_patch , & ! Output: [real(r8) (:) ] ECM uptake (gN/m2/s)
- sminn_to_plant_fun => cnveg_nitrogenflux_inst%sminn_to_plant_fun_patch & ! Output: [real(r8) (:) ] Total soil N uptake of FUN (gN/m2/s)
+ sminn_to_plant_fun => cnveg_nitrogenflux_inst%sminn_to_plant_fun_patch , & ! Output: [real(r8) (:) ] Total soil N uptake of FUN (gN/m2/s)
+
+ iretransn_to_ileaf => cnveg_nitrogenflux_inst%iretransn_to_ileaf_ph , & ! Transfer index (from retranslocation pool to leaf pool)
+ iretransn_to_ileafst => cnveg_nitrogenflux_inst%iretransn_to_ileafst_ph , & ! Transfer index (from retranslocation pool to leaf storage pool)
+ iretransn_to_ifroot => cnveg_nitrogenflux_inst%iretransn_to_ifroot_ph , & ! Transfer index (from retranslocation pool to fine root pool)
+ iretransn_to_ifrootst => cnveg_nitrogenflux_inst%iretransn_to_ifrootst_ph , & ! Transfer index (from retranslocation pool to fine root storage pool)
+ iretransn_to_ilivestem => cnveg_nitrogenflux_inst%iretransn_to_ilivestem_ph , & ! Transfer index (from retranslocation pool to live stem pool)
+ iretransn_to_ilivestemst => cnveg_nitrogenflux_inst%iretransn_to_ilivestemst_ph , & ! Transfer index (from retranslocation pool to live stem storage pool)
+ iretransn_to_ideadstem => cnveg_nitrogenflux_inst%iretransn_to_ideadstem_ph , & ! Transfer index (from retranslocation pool to dead stem pool)
+ iretransn_to_ideadstemst => cnveg_nitrogenflux_inst%iretransn_to_ideadstemst_ph , & ! Transfer index (from retranslocation pool to dead stem storage pool)
+ iretransn_to_ilivecroot => cnveg_nitrogenflux_inst%iretransn_to_ilivecroot_ph , & ! Transfer index (from retranslocation pool to live coarse root pool)
+ iretransn_to_ilivecrootst => cnveg_nitrogenflux_inst%iretransn_to_ilivecrootst_ph , & ! Transfer index (from retranslocation pool to live coarse root storage pool)
+ iretransn_to_ideadcroot => cnveg_nitrogenflux_inst%iretransn_to_ideadcroot_ph , & ! Transfer index (from retranslocation pool to dead coarse root pool)
+ iretransn_to_ideadcrootst => cnveg_nitrogenflux_inst%iretransn_to_ideadcrootst_ph , & ! Transfer index (from retranslocation pool to dead coarse root storage pool)
+ iretransn_to_igrain => cnveg_nitrogenflux_inst%iretransn_to_igrain_ph , & ! Transfer index (from retranslocation pool to grain pool)
+ iretransn_to_igrainst => cnveg_nitrogenflux_inst%iretransn_to_igrainst_ph , & ! Transfer index (from retranslocation pool to grain storage pool)
+ iretransn_to_iout => cnveg_nitrogenflux_inst%iretransn_to_iout_ph , & ! Transfer index (from retranslocation pool to external)
+ ileaf_to_iretransn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph , & ! Transfer index (from leaf pool to retranslocation pools)
+ ifroot_to_iretransn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph , & ! Transfer index (from fine root pool to retranslocation pools)
+ ilivestem_to_iretransn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph & ! Transfer index (from live stem pool to retranslocation pools)
)
+ ! set time steps
+ dt = get_step_size_real()
+
! patch loop to distribute the available N between the competing patches
! on the basis of relative demand, and allocate C and N to new growth and storage
@@ -408,7 +436,6 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
! turning off this correction (PET, 12/11/03), instead using bgtr in
! phenology algorithm.
-
if(use_fun)then ! if we are using FUN, we get the N available from there.
sminn_to_npool(p) = sminn_to_plant_fun(p)
else ! no FUN. :( we get N available from the FPG calculation in soilbiogeochemistry competition.
@@ -416,24 +443,23 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
endif
plant_nalloc(p) = sminn_to_npool(p) + retransn_to_npool(p)
-
- ! Assign sminn_to_npool to matrix solution
if(use_matrixcn)then
- else
- ! Non-matrix equivalent for above is in CNNStateUpdateMod:NStateUpdate1
+ associate( &
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch & ! N input of matrix
+ )
+ matrix_Ninput(p) = sminn_to_npool(p)
+ end associate
end if
if(use_fun)then
- plant_calloc(p) = npp_growth(p)
-
- ! Assign npp_growth to matrix solution
+ plant_calloc(p) = npp_growth(p)
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = npp_growth(p)
end if
else
plant_calloc(p) = availc(p)
-
- ! Assign availc to matrix solution
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = availc(p)
end if
end if
@@ -450,11 +476,10 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_leafc_storage(p) = nlc * (1._r8 - fcur)
cpool_to_frootc(p) = nlc * f1 * fcur
cpool_to_frootc_storage(p) = nlc * f1 * (1._r8 - fcur)
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_leafc(p) + cpool_to_leafc_storage(p) &
+ + cpool_to_frootc(p) + cpool_to_frootc_storage(p)
end if
-
if (woody(ivt(p)) == 1._r8) then
cpool_to_livestemc(p) = nlc * f3 * f4 * fcur
cpool_to_livestemc_storage(p) = nlc * f3 * f4 * (1._r8 - fcur)
@@ -464,9 +489,12 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_livecrootc_storage(p) = nlc * f2 * f3 * f4 * (1._r8 - fcur)
cpool_to_deadcrootc(p) = nlc * f2 * f3 * (1._r8 - f4) * fcur
cpool_to_deadcrootc_storage(p) = nlc * f2 * f3 * (1._r8 - f4) * (1._r8 - fcur)
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_livestemc(p) + cpool_to_livestemc_storage(p) &
+ + cpool_to_deadstemc(p) + cpool_to_deadstemc_storage(p) &
+ + cpool_to_livecrootc(p) + cpool_to_livecrootc_storage(p) &
+ + cpool_to_deadcrootc(p) + cpool_to_deadcrootc_storage(p)
end if
end if
if (ivt(p) >= npcropmin) then ! skip 2 generic crops
@@ -482,14 +510,63 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_reproductivec(p,k) = nlc * f5(k) * fcur
cpool_to_reproductivec_storage(p,k) = nlc * f5(k) * (1._r8 -fcur)
end do
-
- ! Assign above terms to cpool_to_veg for matrix solution
if(use_matrixcn)then
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_livestemc(p) + cpool_to_livestemc_storage(p) &
+ + cpool_to_deadstemc(p) + cpool_to_deadstemc_storage(p) &
+ + cpool_to_livecrootc(p) + cpool_to_livecrootc_storage(p) &
+ + cpool_to_deadcrootc(p) + cpool_to_deadcrootc_storage(p)
+ do k = 1, nrepr
+ cpool_to_veg = cpool_to_veg &
+ + cpool_to_reproductivec(p,k) + cpool_to_reproductivec_storage(p,k)
+ end do
end if
end if
- ! Assign above cpool_to_* terms to matrix solution
if (use_matrixcn) then
+ associate( &
+ matrix_Cinput => cnveg_carbonflux_inst%matrix_Cinput_patch, & ! C input of matrix
+ matrix_alloc => cnveg_carbonflux_inst%matrix_alloc_patch & ! B-matrix for carbon allocation
+ )
+ matrix_Cinput(p) = cpool_to_veg
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ileaf) = cpool_to_leafc(p) / cpool_to_veg
+ matrix_alloc(p,ileaf_st) = cpool_to_leafc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ifroot) = cpool_to_frootc(p) / cpool_to_veg
+ matrix_alloc(p,ifroot_st) = cpool_to_frootc_storage(p) / cpool_to_veg
+ end if
+
+ if (woody(ivt(p)) == 1._r8) then
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ilivestem) = cpool_to_livestemc(p) / cpool_to_veg
+ matrix_alloc(p,ilivestem_st) = cpool_to_livestemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem) = cpool_to_deadstemc(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem_st) = cpool_to_deadstemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot) = cpool_to_livecrootc(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot_st) = cpool_to_livecrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot) = cpool_to_deadcrootc(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot_st) = cpool_to_deadcrootc_storage(p) / cpool_to_veg
+ end if
+ end if
+ if (ivt(p) >= npcropmin) then ! skip 2 generic crops
+ if(cpool_to_veg .ne. 0)then
+ matrix_alloc(p,ilivestem) = cpool_to_livestemc(p) / cpool_to_veg
+ matrix_alloc(p,ilivestem_st) = cpool_to_livestemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem) = cpool_to_deadstemc(p) / cpool_to_veg
+ matrix_alloc(p,ideadstem_st) = cpool_to_deadstemc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot) = cpool_to_livecrootc(p) / cpool_to_veg
+ matrix_alloc(p,ilivecroot_st) = cpool_to_livecrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot) = cpool_to_deadcrootc(p) / cpool_to_veg
+ matrix_alloc(p,ideadcroot_st) = cpool_to_deadcrootc_storage(p) / cpool_to_veg
+ matrix_alloc(p,igrain) = 0.0_r8
+ matrix_alloc(p,igrain_st) = 0.0_r8
+ do k = 1, nrepr
+ matrix_alloc(p,igrain) = matrix_alloc(p,igrain) + cpool_to_reproductivec(p,k) / cpool_to_veg
+ matrix_alloc(p,igrain_st) = matrix_alloc(p,igrain_st) + cpool_to_reproductivec_storage(p,k) / cpool_to_veg
+ end do
+ end if
+ end if
+ end associate
end if !use_matrixcn
! Calculate the amount of carbon that needs to go into growth
@@ -755,8 +832,8 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
cpool_to_frootc_storage_resp(p) + cpool_to_livecrootc_resp(p) + cpool_to_livecrootc_storage_resp(p) + &
cpool_to_livestemc_resp(p) + cpool_to_livestemc_storage_resp(p)
- ! Assign cpool_to_resp term to matrix solution
if(use_matrixcn)then
+ cnveg_carbonflux_inst%matrix_Cinput_patch(p) = cnveg_carbonflux_inst%matrix_Cinput_patch(p) - cpool_to_resp(p)
end if
end if ! end of if (carbon_resp_opt == 1 .AND. laisun(p)+laisha(p) > 0.0_r8) then
@@ -767,28 +844,80 @@ subroutine calc_plant_cn_alloc(this, bounds, num_soilp, filter_soilp, &
!end if
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ! Do matrix update of above terms
if(use_matrixcn)then
associate( &
+ matrix_Ninput => cnveg_nitrogenflux_inst%matrix_Ninput_patch, & ! N input of matrix
+ matrix_nalloc => cnveg_nitrogenflux_inst%matrix_nalloc_patch, & ! B-matrix for nitrogen allocation
psnsun_to_cpool => cnveg_carbonflux_inst%psnsun_to_cpool_patch, & !
psnshade_to_cpool => cnveg_carbonflux_inst%psnshade_to_cpool_patch & !
)
- if(use_c13 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0.)then
+ if(use_c13 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0._r8)then
+ associate( &
+ matrix_C13input => cnveg_carbonflux_inst%matrix_C13input_patch & ! C13 input of matrix
+ )
+ matrix_C13input(p) = plant_calloc(p) * &
+ ((c13_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p)+ c13_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p))/ &
+ (psnsun_to_cpool(p)+psnshade_to_cpool(p)))
+ end associate
end if
- if(use_c14 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0.)then
+ if(use_c14 .and. psnsun_to_cpool(p)+psnshade_to_cpool(p).ne. 0._r8)then
+ associate( &
+ matrix_C14input => cnveg_carbonflux_inst%matrix_C14input_patch & ! C14 input of matrix
+ )
+ matrix_C14input(p) = plant_calloc(p) * &
+ ((c14_cnveg_carbonflux_inst%psnsun_to_cpool_patch(p)+ c14_cnveg_carbonflux_inst%psnshade_to_cpool_patch(p))/ &
+ (psnsun_to_cpool(p)+psnshade_to_cpool(p)))
+ end associate
end if
+ npool_to_veg = npool_to_leafn(p) + npool_to_leafn_storage(p) &
+ + npool_to_frootn(p) + npool_to_frootn_storage(p) &
+ + npool_to_livestemn(p) + npool_to_livestemn_storage(p) &
+ + npool_to_deadstemn(p) + npool_to_deadstemn_storage(p) &
+ + npool_to_livecrootn(p) + npool_to_livecrootn_storage(p) &
+ + npool_to_deadcrootn(p) + npool_to_deadcrootn_storage(p)
if (ivt(p) >= npcropmin)then
+ npool_to_veg = npool_to_veg + npool_to_reproductiven(p,1) + npool_to_reproductiven_storage(p,1)
end if
- if(npool_to_veg .ne. 0)then
+ if(npool_to_veg .ne. 0._r8)then
+ matrix_nalloc(p,ileaf ) = npool_to_leafn(p) / npool_to_veg
+ matrix_nalloc(p,ileaf_st ) = npool_to_leafn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ifroot ) = npool_to_frootn(p) / npool_to_veg
+ matrix_nalloc(p,ifroot_st ) = npool_to_frootn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ilivestem ) = npool_to_livestemn(p) / npool_to_veg
+ matrix_nalloc(p,ilivestem_st ) = npool_to_livestemn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ideadstem ) = npool_to_deadstemn(p) / npool_to_veg
+ matrix_nalloc(p,ideadstem_st ) = npool_to_deadstemn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ilivecroot ) = npool_to_livecrootn(p) / npool_to_veg
+ matrix_nalloc(p,ilivecroot_st ) = npool_to_livecrootn_storage(p) / npool_to_veg
+ matrix_nalloc(p,ideadcroot ) = npool_to_deadcrootn(p) / npool_to_veg
+ matrix_nalloc(p,ideadcroot_st ) = npool_to_deadcrootn_storage(p) / npool_to_veg
if (ivt(p) >= npcropmin)then
+ matrix_nalloc(p,igrain ) = npool_to_reproductiven(p,1) / npool_to_veg
+ matrix_nalloc(p,igrain_st ) = npool_to_reproductiven_storage(p,1) / npool_to_veg
end if
+ matrix_Ninput(p) = npool_to_veg - retransn_to_npool(p)
else
- if(retransn(p) .ne. 0)then
+ if(retransn(p) .ne. 0._r8)then
+ retransn_to_npool(p) = retransn(p) * matrix_update_phn(p,iretransn_to_iout,retransn_to_npool(p)/retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
end if
end if
-
- if(retransn(p) .ne. 0)then
+
+ if(retransn(p) .ne. 0._r8)then
+ tmp = matrix_update_phn(p,iretransn_to_ileaf ,matrix_nalloc(p,ileaf ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ileafst ,matrix_nalloc(p,ileaf_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ifroot ,matrix_nalloc(p,ifroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ifrootst ,matrix_nalloc(p,ifroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivestem ,matrix_nalloc(p,ilivestem ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivestemst ,matrix_nalloc(p,ilivestem_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadstem ,matrix_nalloc(p,ideadstem ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadstemst ,matrix_nalloc(p,ideadstem_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivecroot ,matrix_nalloc(p,ilivecroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ilivecrootst ,matrix_nalloc(p,ilivecroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadcroot ,matrix_nalloc(p,ideadcroot ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_ideadcrootst ,matrix_nalloc(p,ideadcroot_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
if(ivt(p) >= npcropmin)then
+ tmp = matrix_update_phn(p,iretransn_to_igrain ,matrix_nalloc(p,igrain ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
+ tmp = matrix_update_phn(p,iretransn_to_igrainst ,matrix_nalloc(p,igrain_st ) * retransn_to_npool(p) / retransn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,.True.)
end if
end if
end associate
@@ -1247,12 +1376,10 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
! - livestemn_to_retransn
!
! !USES:
- use pftconMod , only : npcropmin, pftcon
use pftconMod , only : ntmp_soybean, nirrig_tmp_soybean
use pftconMod , only : ntrp_soybean, nirrig_trp_soybean
use clm_varcon , only : dzsoi_decomp
use clm_varpar , only : nlevdecomp
- use clm_time_manager , only : get_step_size_real
use CanopyStateType , only : canopystate_type
use CropType , only : crop_type
use CNVegStateType , only : cnveg_state_type
@@ -1266,6 +1393,13 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
use CNSharedParamsMod , only : use_fun
use CNPrecisionControlMod , only : n_min
use clm_varcon , only : spval
+ use clm_varpar , only : ileaf,ileaf_st,ileaf_xf,ifroot,ifroot_st,ifroot_xf,&
+ ilivestem,ilivestem_st,ilivestem_xf,&
+ ideadstem,ideadstem_st,ideadstem_xf,&
+ ilivecroot,ilivecroot_st,ilivecroot_xf,&
+ ideadcroot,ideadcroot_st,ideadcroot_xf,&
+ igrain,igrain_st,igrain_xf,iretransn,ioutc,ioutn
+ use CNVegMatrixMod , only : matrix_update_phn
! !ARGUMENTS:
class(nutrient_competition_FlexibleCN_type), intent(inout) :: this
type(bounds_type) , intent(in) :: bounds
@@ -1356,16 +1490,16 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
plant_ndemand => cnveg_nitrogenflux_inst%plant_ndemand_patch , & ! Output: [real(r8) (:) ] N flux required to support initial GPP (gN/m2/s)
avail_retransn => cnveg_nitrogenflux_inst%avail_retransn_patch , & ! Output: [real(r8) (:) ] N flux available from retranslocation pool (gN/m2/s)
retransn_to_npool => cnveg_nitrogenflux_inst%retransn_to_npool_patch , & ! Output: [real(r8) (:) ] deployment of retranslocated N (gN/m2/s)
- leafn_to_litter => cnveg_nitrogenflux_inst%leafn_to_litter_patch , & ! Output: [real(r8) (:) ] leaf N litterfall (gN/m2/s)
- frootn_to_litter => cnveg_nitrogenflux_inst%frootn_to_litter_patch , & ! Output: [real(r8) (:) ] fine root N litterfall (gN/m2/s)
- livestemn_to_litter => cnveg_nitrogenflux_inst%livestemn_to_litter_patch , & ! Input: [real(r8) (:) ] livestem N to litter (gN/m2/s)
leafn_to_retransn => cnveg_nitrogenflux_inst%leafn_to_retransn_patch , & ! Output: [real(r8) (:) ]
frootn_to_retransn => cnveg_nitrogenflux_inst%frootn_to_retransn_patch , & ! Output: [real(r8) (:) ]
+ livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch,& ! Output: [real(r8) (:) ]
livestemn => cnveg_nitrogenstate_inst%livestemn_patch , & ! Input: [real(r8) (:) ] (gN/m2) livestem N
frootn => cnveg_nitrogenstate_inst%frootn_patch , & ! Input: [real(r8) (:) ] (gN/m2) fine root N
- livestemn_to_retransn => cnveg_nitrogenflux_inst%livestemn_to_retransn_patch,& ! Output: [real(r8) (:) ]
sminn_vr => soilbiogeochem_nitrogenstate_inst%sminn_vr_col , & ! Input: [real(r8) (:,:) ] (gN/m3) soil mineral N
- t_scalar => soilbiogeochem_carbonflux_inst%t_scalar_col & ! Input: [real(r8) (:,:) ] soil temperature scalar for decomp
+ t_scalar => soilbiogeochem_carbonflux_inst%t_scalar_col , & ! Input: [real(r8) (:,:) ] soil temperature scalar for decomp
+ ileaf_to_iretransn_phn => cnveg_nitrogenflux_inst%ileaf_to_iretransn_ph, &
+ ifroot_to_iretransn_phn => cnveg_nitrogenflux_inst%ifroot_to_iretransn_ph, &
+ ilivestem_to_iretransn_phn => cnveg_nitrogenflux_inst%ilivestem_to_iretransn_ph &
)
! set time steps
@@ -1386,7 +1520,6 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
this%actual_leafcn(p) = leafc(p) / leafn(p)
end if
-
leafcn_min = leafcn(ivt(p)) - 10.0_r8
leafcn_max = leafcn(ivt(p)) + 10.0_r8
@@ -1478,14 +1611,15 @@ subroutine calc_plant_nitrogen_demand(this, bounds, &
frootn_to_retransn(p) = t1 * max(frootn(p) - (frootc(p) / ffrootcn(ivt(p))),0._r8)
end if
grain_flag(p) = 1._r8
-
- ! Update matrix terms above
if(use_matrixcn)then
if(leafn(p) .ne. 0._r8)then
+ leafn_to_retransn(p) = leafn(p) * matrix_update_phn(p,ileaf_to_iretransn_phn,leafn_to_retransn(p) / leafn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
if(frootn(p) .ne. 0._r8)then
+ frootn_to_retransn(p) = frootn(p) * matrix_update_phn(p,ifroot_to_iretransn_phn,frootn_to_retransn(p) / frootn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
if(livestemn(p) .ne. 0._r8)then
+ livestemn_to_retransn(p) = livestemn(p) * matrix_update_phn(p,ilivestem_to_iretransn_phn,livestemn_to_retransn(p) / livestemn(p),dt,cnveg_nitrogenflux_inst,matrixcheck_ph,acc_ph)
end if
end if
diff --git a/src/biogeochem/test/CMakeLists.txt b/src/biogeochem/test/CMakeLists.txt
index 81fe9bbaf0..e22a720523 100644
--- a/src/biogeochem/test/CMakeLists.txt
+++ b/src/biogeochem/test/CMakeLists.txt
@@ -2,3 +2,4 @@ add_subdirectory(Species_test)
add_subdirectory(CNVegComputeSeed_test)
add_subdirectory(CNPhenology_test)
add_subdirectory(Latbaset_test)
+add_subdirectory(DustEmis_test)
diff --git a/src/biogeochem/test/DustEmis_test/CMakeLists.txt b/src/biogeochem/test/DustEmis_test/CMakeLists.txt
new file mode 100644
index 0000000000..9239d16e22
--- /dev/null
+++ b/src/biogeochem/test/DustEmis_test/CMakeLists.txt
@@ -0,0 +1,6 @@
+set (pfunit_sources
+ test_DustEmisZender2003.pf)
+
+add_pfunit_ctest(DustEmis
+ TEST_SOURCES "${pfunit_sources}"
+ LINK_LIBRARIES clm csm_share esmf_wrf_timemgr)
diff --git a/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf b/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf
new file mode 100644
index 0000000000..8641b8cceb
--- /dev/null
+++ b/src/biogeochem/test/DustEmis_test/test_DustEmisZender2003.pf
@@ -0,0 +1,291 @@
+module test_DustEmisZender2003
+
+ ! Tests of DustEmisZender2003
+
+ use funit
+ use unittestDustEmisInputs, only : unittest_dust_emis_input_type
+ use unittestSubgridMod, only : bounds
+ use DustEmisBase
+ use DustEmisZender2003
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use DustEmisFactory, only : create_dust_emissions
+
+ implicit none
+
+ real(r8), parameter :: tol = 1.e-18_r8
+
+ @TestCase
+ type, extends(TestCase) :: TestDustEmisZender2003
+ class(dust_emis_base_type), allocatable :: dust_emis
+ type(unittest_dust_emis_input_type) :: input
+ contains
+ procedure :: setUp
+ procedure :: tearDown
+ procedure :: print_values
+ procedure :: validate_patch
+ end type TestDustEmisZender2003
+
+contains
+
+ !-----------------------------------------------------------------------
+
+ subroutine setUp(this)
+ class(TestDustEmisZender2003), intent(inout) :: this
+ ! Allocate and initialize the test object for input objects dust-emission needs
+ character(len=5) :: NLFilename = 'none'
+
+ call this%input%setUp()
+
+ ! Create the dust emission object last
+ allocate(this%dust_emis, source = create_dust_emissions(bounds, NLFilename))
+ end subroutine setUp
+
+ !-----------------------------------------------------------------------
+
+ subroutine tearDown(this)
+ class(TestDustEmisZender2003), intent(inout) :: this
+
+ call this%dust_emis%Clean()
+ call this%input%tearDown()
+ end subroutine tearDown
+
+ !-----------------------------------------------------------------------
+
+ subroutine print_values(this)
+ ! For debugging
+ use PatchType, only : patch
+ class(TestDustEmisZender2003), intent(inout) :: this
+ real(r8) :: SaltationFactor
+ integer :: p, c
+
+ call this%input%print_values()
+ call this%dust_emis%GetConstVars( SaltationFactor )
+ do c = bounds%begc, bounds%endc
+ print *, 'saltation per rho = ', (SaltationFactor / this%input%atm2lnd_inst%forc_rho_downscaled_col(c))
+ end do
+ do p = bounds%begp, bounds%endp
+ c = patch%column(p)
+ print *, 'Wind threshold fraction = ', (SaltationFactor / this%input%atm2lnd_inst%forc_rho_downscaled_col(c)) &
+ / this%input%frictionvel_inst%fv_patch(p)
+ call this%dust_emis%WritePatchToLog( p )
+ end do
+ end subroutine print_values
+
+ !-----------------------------------------------------------------------
+
+ subroutine validate_patch(this, p)
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer, intent(in) :: p
+
+ call this%dust_emis%CheckDustEmisIsValid( p )
+ end subroutine validate_patch
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine check_dust_emis(this)
+ ! Check dust emissions for default values
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p
+ real(r8) :: flx_mss_vrt_dst_tot
+ real(r8) :: vlc_trb_1
+ real(r8) :: vlc_trb_2
+ real(r8) :: vlc_trb_3
+ real(r8) :: vlc_trb_4
+
+ call this%input%create_atm2lnd()
+ call this%input%create_fv()
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ call this%print_values() ! Call print subroutine just to make sure it can be used for debugging
+ do p = bounds%begp, bounds%endp
+ call this%validate_patch(p)
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot, &
+ vlc_trb_1=vlc_trb_1, vlc_trb_2=vlc_trb_2, vlc_trb_3=vlc_trb_3, &
+ vlc_trb_4=vlc_trb_4)
+ @assertEqual( flx_mss_vrt_dst_tot, 2.583480541056971d-6, tolerance=tol )
+ @assertEqual( vlc_trb_1, 3.407721147709135d-003, tolerance=tol )
+ @assertEqual( vlc_trb_2, 4.961153753164878d-003, tolerance=tol )
+ @assertEqual( vlc_trb_3, 4.980100969983446d-003, tolerance=tol )
+ @assertEqual( vlc_trb_4, 4.977071672163210d-003, tolerance=tol )
+ end do
+
+ end subroutine check_dust_emis
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine dust_zero_for_fixed_ratio(this)
+ ! Check dust emissions are zero for a no wind
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p
+ real(r8) :: flx_mss_vrt_dst_tot
+ real(r8) :: fv
+ real(r8) :: SaltationFactor
+
+ call this%input%create_atm2lnd()
+ call this%dust_emis%GetConstVars( SaltationFactor )
+ ! Figure out what fv needs to be so that the wind threshold will be u10*(1/(1-eps))
+ fv = ( SaltationFactor / sqrt( this%input%atm2lnd_inst%forc_rho_downscaled_col(bounds%begc)) ) - 1.d-15
+ call this%input%create_fv( fv=fv )
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%validate_patch(p)
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ @assertEqual( flx_mss_vrt_dst_tot, 0.0_r8 )
+ end do
+
+ end subroutine dust_zero_for_fixed_ratio
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine dust_zero_when_fsno_one(this)
+ ! Check dust emissions are zero when snow fraction is identically 1
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p
+ real(r8) :: flx_mss_vrt_dst_tot
+
+ call this%input%create_atm2lnd()
+ this%input%water_inst%waterdiagnosticbulk_inst%frac_sno_col(:) = 1.0_r8
+ call this%input%create_fv( )
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ @assertEqual( flx_mss_vrt_dst_tot, 0.0_r8 )
+ end do
+
+ end subroutine dust_zero_when_fsno_one
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine dust_zero_non_veg_lu(this)
+ ! Check dust emissions are zero for non-veg landunits
+ use landunit_varcon, only: istcrop, max_lunit
+ use LandunitType, only : lun
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p, l
+ real(r8) :: flx_mss_vrt_dst_tot
+
+ call this%input%create_atm2lnd()
+ call this%input%create_fv( )
+ ! Set the lanunit type for
+ do l = istcrop+1, max_lunit
+ lun%itype(bounds%begl:bounds%endl) = l
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ @assertEqual( flx_mss_vrt_dst_tot, 0.0_r8 )
+ end do
+ end do
+
+ end subroutine dust_zero_non_veg_lu
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine aborts_on_bad_dust_mobility(this)
+ ! Check dust abort when dust mobility is bad
+ class(TestDustEmisZender2003), intent(inout) :: this
+ real(r8) :: flx_mss_vrt_dst_tot
+ character(100) :: expected_msg
+
+ call this%input%create_atm2lnd()
+ call this%input%create_fv( )
+ ! Dust should abort with an error on dust mobility when snow fraction greater than 1
+ this%input%water_inst%waterdiagnosticbulk_inst%frac_sno_col(:) = 1.0_r8 + 1.e-15_r8
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ expected_msg = "ABORTED: Bad value for dust mobilization fraction"
+ @assertExceptionRaised(expected_msg)
+
+ end subroutine aborts_on_bad_dust_mobility
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine dust_zero_when_tlai_high(this)
+ use PatchType, only : patch
+ ! Check dust emissions are zero when LAI is high enough
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p
+ real(r8) :: flx_mss_vrt_dst_tot
+
+ ! Explicitly set the patch type to a hard-coded 1 (so NOT bare-soil)
+ ! pft indices can't be used without reading them from the parameter file
+ !
+ ! To do this fully the subgrid setup in unittestDustEmisInputs to baresoil
+ ! should really be run again. But, just doing this is likely sufficient for testing
+ patch%itype(bounds%begp:bounds%endp) = 1
+ call this%input%create_atm2lnd()
+ call this%input%create_fv( )
+ this%input%canopystate_inst%tlai_patch(:) = 0.3_r8
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%validate_patch(p)
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ @assertEqual( flx_mss_vrt_dst_tot, 0.0_r8 )
+ end do
+
+ end subroutine dust_zero_when_tlai_high
+
+ !-----------------------------------------------------------------------
+
+ @Test
+ subroutine check_dust_emis_increasing_wind(this)
+ ! Check dust emissions with increasing wind
+ class(TestDustEmisZender2003), intent(inout) :: this
+ integer :: p, c
+ real(r8) :: flx_mss_vrt_dst_tot
+ real(r8) :: fv = 4.0_r8
+ real(r8) :: u10 = 10._r8
+ real(r8) :: total_dust0, total_dust_higher
+
+ ! Run baseline u10
+ call this%input%create_atm2lnd()
+ call this%input%create_fv( u10=u10, fv=fv )
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%validate_patch(p)
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ total_dust0 = flx_mss_vrt_dst_tot
+ @assertEqual( flx_mss_vrt_dst_tot, 2.273879554711299d-5, tolerance=tol )
+ end do
+ ! Double u10 and show result is higher
+ call this%input%create_fv( u10=u10*2.0_r8, fv=fv)
+ call this%dust_emis%DustEmission(bounds, this%input%num_nolakep, this%input%filter_nolakep, this%input%atm2lnd_inst, &
+ this%input%soilstate_inst, this%input%canopystate_inst, this%input%water_inst%waterstatebulk_inst, &
+ this%input%water_inst%waterdiagnosticbulk_inst, this%input%frictionvel_inst)
+ call this%dust_emis%DustDryDep(bounds, this%input%atm2lnd_inst, this%input%frictionvel_inst)
+ do p = bounds%begp, bounds%endp
+ call this%validate_patch(p)
+ call this%dust_emis%GetPatchVars( p, flx_mss_vrt_dst_tot=flx_mss_vrt_dst_tot )
+ total_dust_higher = flx_mss_vrt_dst_tot
+ @assertEqual( flx_mss_vrt_dst_tot, 3.792794484764924d-5, tolerance=tol )
+ end do
+ @assertGreaterThan( total_dust_higher, total_dust0 )
+
+ end subroutine check_dust_emis_increasing_wind
+
+ !-----------------------------------------------------------------------
+
+end module test_DustEmisZender2003
\ No newline at end of file
diff --git a/src/biogeophys/CMakeLists.txt b/src/biogeophys/CMakeLists.txt
index 2ffc346670..07b88b07bf 100644
--- a/src/biogeophys/CMakeLists.txt
+++ b/src/biogeophys/CMakeLists.txt
@@ -7,6 +7,7 @@ list(APPEND clm_sources
BalanceCheckMod.F90
CanopyStateType.F90
EnergyFluxType.F90
+ FrictionVelocityMod.F90
GlacierSurfaceMassBalanceMod.F90
HillslopeHydrologyUtilsMod.F90
HumanIndexMod.F90
@@ -24,6 +25,7 @@ list(APPEND clm_sources
SoilHydrologyType.F90
SoilStateType.F90
SoilWaterRetentionCurveMod.F90
+ SoilStateInitTimeConstMod.F90
SolarAbsorbedType.F90
PhotosynthesisMod.F90
SurfaceAlbedoType.F90
diff --git a/src/biogeophys/CanopyFluxesMod.F90 b/src/biogeophys/CanopyFluxesMod.F90
index 58334a70c0..a969dc0583 100644
--- a/src/biogeophys/CanopyFluxesMod.F90
+++ b/src/biogeophys/CanopyFluxesMod.F90
@@ -1624,7 +1624,8 @@ subroutine CanopyFluxes(bounds, num_exposedvegp, filter_exposedvegp,
! snocan < rel_epsilon * snocan_baseline will be set to zero
! See NumericsMod for rel_epsilon value
call truncate_small_values(fn, filterp, begp, endp, &
- snocan_baseline(begp:endp), snocan(begp:endp))
+ snocan_baseline(begp:endp), snocan(begp:endp), &
+ custom_rel_epsilon=1.e-10_r8)
if ( use_fates ) then
diff --git a/src/biogeophys/CanopyStateType.F90 b/src/biogeophys/CanopyStateType.F90
index 313f7a83f3..4bfc08fc80 100644
--- a/src/biogeophys/CanopyStateType.F90
+++ b/src/biogeophys/CanopyStateType.F90
@@ -72,6 +72,8 @@ module CanopyStateType
procedure, public :: UpdateAccVars
procedure, public :: Restart
+ procedure, public :: SetNMLForTesting ! Set namelist for unit-testing
+
end type CanopyState_type
character(len=*), parameter, private :: sourcefile = &
@@ -442,6 +444,21 @@ subroutine ReadNML( this, NLFilename )
end subroutine ReadNML
+ !-----------------------------------------------------------------------
+
+ subroutine SetNMLForTesting( this )
+ !
+ ! Set canopy parameter namelist control settings for unit-testing
+ !
+ class(canopystate_type) :: this
+ ! LOCAL VARIABLES:
+ !-----------------------------------------------------------------------
+
+
+ this%leaf_mr_vcm = 0.015_r8
+
+ end subroutine SetNMLForTesting
+
!-----------------------------------------------------------------------
subroutine UpdateAccVars (this, bounds)
!
diff --git a/src/biogeophys/FrictionVelocityMod.F90 b/src/biogeophys/FrictionVelocityMod.F90
index 7cea2a22f9..042415f545 100644
--- a/src/biogeophys/FrictionVelocityMod.F90
+++ b/src/biogeophys/FrictionVelocityMod.F90
@@ -89,6 +89,8 @@ module FrictionVelocityMod
procedure, public :: FrictionVelocity ! Calculate friction velocity
procedure, public :: MoninObukIni ! Initialization of the Monin-Obukhov length
+ procedure, public :: InitForTesting ! version of Init meant for unit testing
+
! Private procedures
procedure, private :: InitAllocate
procedure, private :: InitHistory
@@ -122,6 +124,22 @@ subroutine Init(this, bounds, NLFilename, params_ncid)
end subroutine Init
+ !------------------------------------------------------------------------
+ subroutine InitForTesting(this, bounds)
+ ! Initialization for unit testing, hardcodes namelist and parameter file settings
+ class(frictionvel_type) :: this
+ type(bounds_type), intent(in) :: bounds
+
+ call this%InitAllocate(bounds)
+ call this%InitHistory(bounds)
+ call this%InitCold(bounds)
+ this%zetamaxstable = 0.5_r8
+ this%zsno = 0.00085_r8
+ this%zlnd = 0.000775_r8
+ this%zglc = 0.00230000005_r8
+
+ end subroutine InitForTesting
+
!------------------------------------------------------------------------
subroutine InitAllocate(this, bounds)
!
diff --git a/src/biogeophys/IrrigationMod.F90 b/src/biogeophys/IrrigationMod.F90
index 27cf050dd3..11c9132eea 100644
--- a/src/biogeophys/IrrigationMod.F90
+++ b/src/biogeophys/IrrigationMod.F90
@@ -221,9 +221,8 @@ module IrrigationMod
! There is no reason to make this a tunable parameter, because the behavior it governs
! (the trigger for irrigation) can be tuned via other parameters.
!
- ! TODO(wjs, 2016-09-08) It looks like there is other code in CLM that also uses an
- ! assumed wilting point (CNRootDynMod, maybe others). We should probably make this a
- ! shared parameter, e.g., in clm_varcon.
+ ! TODO(wjs, 2016-09-08, updated by slevis 2024-07-06) assumed wilting point:
+ ! Make this a shared parameter? E.g., in clm_varcon
real(r8), parameter, private :: wilting_point_smp = -150000._r8
! Conversion factors
diff --git a/src/biogeophys/SaturatedExcessRunoffMod.F90 b/src/biogeophys/SaturatedExcessRunoffMod.F90
index 5643a95394..9956a7dfb8 100644
--- a/src/biogeophys/SaturatedExcessRunoffMod.F90
+++ b/src/biogeophys/SaturatedExcessRunoffMod.F90
@@ -12,8 +12,8 @@ module SaturatedExcessRunoffMod
use shr_log_mod , only : errMsg => shr_log_errMsg
use decompMod , only : bounds_type
use abortutils , only : endrun
- use clm_varctl , only : iulog, use_vichydro, crop_fsat_equals_zero
- use clm_varcon , only : spval
+ use clm_varctl , only : iulog, use_vichydro, crop_fsat_equals_zero, hillslope_fsat_equals_zero
+ use clm_varcon , only : spval,ispval
use LandunitType , only : landunit_type
use landunit_varcon , only : istcrop
use ColumnType , only : column_type
@@ -266,6 +266,19 @@ subroutine SaturatedExcessRunoff (this, bounds, num_hydrologyc, filter_hydrology
end do
endif
+ ! ------------------------------------------------------------------------
+ ! Set fsat to zero for upland hillslope columns
+ ! ------------------------------------------------------------------------
+ if (hillslope_fsat_equals_zero) then
+ do fc = 1, num_hydrologyc
+ c = filter_hydrologyc(fc)
+ if(col%is_hillslope_column(c) .and. col%active(c)) then
+ ! Set fsat to zero for upland columns
+ if (col%cold(c) /= ispval) fsat(c) = 0._r8
+ endif
+ end do
+ endif
+
! ------------------------------------------------------------------------
! Compute qflx_sat_excess_surf
!
diff --git a/src/biogeophys/SoilStateInitTimeConstMod.F90 b/src/biogeophys/SoilStateInitTimeConstMod.F90
index 9122b56890..e47577c9b9 100644
--- a/src/biogeophys/SoilStateInitTimeConstMod.F90
+++ b/src/biogeophys/SoilStateInitTimeConstMod.F90
@@ -17,6 +17,11 @@ module SoilStateInitTimeConstMod
! !PUBLIC MEMBER FUNCTIONS:
public :: SoilStateInitTimeConst
public :: readParams
+
+ ! PRIVATE FUNCTIONS MADE PUBLIC Just for unit-testing:
+ public :: ThresholdSoilMoistZender2003
+ public :: ThresholdSoilMoistKok2014
+ public :: MassFracClay
!
! !PRIVATE MEMBER FUNCTIONS:
private :: ReadNL
@@ -702,8 +707,8 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
do c = begc,endc
g = col%gridcell(c)
- soilstate_inst%gwc_thr_col(c) = 0.17_r8 + 0.14_r8 * clay3d(g,1) * 0.01_r8
- soilstate_inst%mss_frc_cly_vld_col(c) = min(clay3d(g,1) * 0.01_r8, 0.20_r8)
+ soilstate_inst%gwc_thr_col(c) = ThresholdSoilMoistZender2003( clay3d(g,1) )
+ soilstate_inst%mss_frc_cly_vld_col(c) = MassFracClay( clay3d(g,1) )
end do
! --------------------------------------------------------------------
@@ -715,4 +720,77 @@ subroutine SoilStateInitTimeConst(bounds, soilstate_inst, nlfilename)
end subroutine SoilStateInitTimeConst
+ !------------------------------------------------------------------------------
+
+ real(r8) function ThresholdSoilMoistZender2003( clay )
+ !------------------------------------------------------------------------------
+ !
+ ! Calculate the threshold soil moisture needed for dust emission, based on clay content
+ ! This was the original equation with a = 1 / (%clay) being the tuning factor for soil
+ ! moisture effect in Zender's 2003 dust emission scheme.
+ !
+ ! 0.17 and 0.14 are fitting coefficients in Fecan et al. (1999), and 0.01 is used to
+ ! convert surface clay fraction from percentage to fraction.
+ !
+ !------------------------------------------------------------------------------
+ ! For future developments Danny M. Leung decided (Dec, 2023) that the Leung et al. (2023) o
+ ! dust emission scheme in the CESM will use Zender's tuning as well, which overall
+ ! encourages more dust emissions from seriamid and more marginal dust sources.
+ ! Another advantage of using this tuning factor instead of a = 1 is that the dust emission
+ ! threshold is linearly dependent on the clay fraction instead of parabolically dependent
+ ! on clay fraction as in the above line. This means that dust emission becomes a little
+ ! less sensitive to clay content (soil texture).
+ !
+ ! Also see the notes below for ThresholdSoilMoistKok2014.
+ !
+ ! Notes from: dmleung 19 Feb 2024.
+ !
+ !------------------------------------------------------------------------------
+ use abortUtils , only : endrun
+ use shr_infnan_mod, only : nan => shr_infnan_nan, assignment(=)
+ real(r8), intent(IN) :: clay ! Fraction of clay in the soil (%)
+
+ if ( clay < 0.0_r8 .or. clay > 100.0_r8 )then
+ ThresholdSoilMoistZender2003 = nan
+ call endrun( 'Clay fraction is out of bounds (0 to 100)')
+ return
+ end if
+ ThresholdSoilMoistZender2003 = 0.17_r8 + 0.14_r8 * clay * 0.01_r8
+ end function ThresholdSoilMoistZender2003
+
+ !------------------------------------------------------------------------------
+
+ real(r8) function ThresholdSoilMoistKok2014( clay )
+ !------------------------------------------------------------------------------
+ ! Calculate the threshold soil moisture needed for dust emission, based on clay content
+ !
+ ! The below calculates the threshold gravimetric water content for the dust emission
+ ! calculation in DustEmis. The equation comes from Eq. 14 of Fecan et al.
+ ! (1999; https://doi.org/10.1007/s00585-999-0149-7).
+ ! gwc_thr_col = 0.17*clay3d + 0.0014*(clay3d**2), and we only concern the topmost
+ ! soil layer. Charlie Zender later on added a tuning factor (a) such that the
+ ! equation becomes gwc_thr_col = a*[0.17*clay3d + 0.0014*(clay3d**2)].
+ ! (Zender et al., 2003a; https://doi.org/10.1029/2002JD002775)
+ ! Kok et al. (2014a, b) chose to use a = 1. Resulting in this function
+ ! Charlie Zender (2003a) chose: a = 1/clay3d, which gives the ThresholdSoilMoistZender2003
+ ! function above.
+ !
+ ! Notes from: dmleung 24 May 2024.
+ !------------------------------------------------------------------------------
+ real(r8), intent(IN) :: clay ! Fraction of clay in the soil (%)
+
+ ThresholdSoilMoistKok2014 = 0.01_r8*(0.17_r8*clay + 0.0014_r8*clay*clay)
+ end function ThresholdSoilMoistKok2014
+
+ !------------------------------------------------------------------------------
+
+ real(r8) function MassFracClay( clay )
+ ! Calculate the mass fraction of clay needed for dust emission, based on clay content
+ real(r8), intent(IN) :: clay ! Fraction of lay in the soil (%)
+
+ MassFracClay = min(clay * 0.01_r8, 0.20_r8)
+ end function MassFracClay
+
+ !------------------------------------------------------------------------------
+
end module SoilStateInitTimeConstMod
diff --git a/src/biogeophys/SoilStateType.F90 b/src/biogeophys/SoilStateType.F90
index e301cc27b9..2e7225f962 100644
--- a/src/biogeophys/SoilStateType.F90
+++ b/src/biogeophys/SoilStateType.F90
@@ -9,7 +9,7 @@ module SoilStateType
use abortutils , only : endrun
use clm_varpar , only : nlevsoi, nlevgrnd, nlevlak, nlayer, nlevsno, nlevmaxurbgrnd
use clm_varcon , only : spval
- use clm_varctl , only : use_hydrstress, use_cn, use_lch4, use_dynroot, use_fates
+ use clm_varctl , only : use_hydrstress, use_cn, use_lch4, use_fates
use clm_varctl , only : iulog, hist_wrtch4diag
use LandunitType , only : lun
use ColumnType , only : col
@@ -231,20 +231,6 @@ subroutine InitHistory(this, bounds)
ptr_col=this%bsw_col, default='inactive')
end if
- if (use_dynroot) then
- this%rootfr_patch(begp:endp,:) = spval
- call hist_addfld2d (fname='ROOTFR', units='proportion', type2d='levgrnd', &
- avgflag='A', long_name='fraction of roots in each soil layer', &
- ptr_patch=this%rootfr_patch, default='active')
- end if
-
- if ( use_dynroot ) then
- this%root_depth_patch(begp:endp) = spval
- call hist_addfld1d (fname='ROOT_DEPTH', units="m", &
- avgflag='A', long_name='rooting depth', &
- ptr_patch=this%root_depth_patch )
- end if
-
if (use_cn) then
this%rootr_patch(begp:endp,:) = spval
call hist_addfld2d (fname='ROOTR', units='proportion', type2d='levgrnd', &
@@ -393,15 +379,7 @@ subroutine Restart(this, bounds, ncid, flag)
scale_by_thickness=.true., &
interpinic_flag='interp', readvar=readvar, data=this%hk_l_col)
- if( use_dynroot ) then
- call restartvar(ncid=ncid, flag=flag, varname='rootfr', xtype=ncd_double, &
- dim1name='pft', dim2name='levgrnd', switchdim=.true., &
- long_name='root fraction', units='', &
- scale_by_thickness=.false., &
- interpinic_flag='interp', readvar=readrootfr, data=this%rootfr_patch)
- else
- readrootfr = .false.
- end if
+ readrootfr = .false.
if (flag=='read' .and. .not. readrootfr ) then
if (masterproc) then
write(iulog,*) "can't find rootfr in restart (or initial) file..."
diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90
index 4c985f0ab3..c680b13306 100644
--- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90
+++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90
@@ -210,7 +210,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
use clm_varctl , only : iulog
use abortutils , only : endrun
use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd
- use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on
+ use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, urban_explicit_ac
!
! !ARGUMENTS:
implicit none
@@ -236,6 +236,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
real(r8) :: t_floor_bef(bounds%begl:bounds%endl) ! floor temperature at previous time step (K)
real(r8) :: t_building_bef(bounds%begl:bounds%endl) ! internal building air temperature at previous time step [K]
real(r8) :: t_building_bef_hac(bounds%begl:bounds%endl)! internal building air temperature before applying HAC [K]
+ real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning flux under AC adoption saturation (W/m**2)
real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1)
real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1)
real(r8) :: hcv_shdwi(bounds%begl:bounds%endl) ! shadewall convective heat transfer coefficient (W m-2 K-1)
@@ -324,6 +325,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
t_floor => temperature_inst%t_floor_lun , & ! InOut: [real(r8) (:)] floor temperature (K)
t_building => temperature_inst%t_building_lun , & ! InOut: [real(r8) (:)] internal building air temperature (K)
+ p_ac => urbantv_inst%p_ac , & ! Input: [real(r8) (:)] air-conditioning penetration rate (a fraction between 0 and 1)
t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K)
t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K)
@@ -923,9 +925,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec,
! rho_dair(l) = pstd / (rair*t_building(l))
if (t_building_bef_hac(l) > t_building_max(l)) then
- t_building(l) = t_building_max(l)
- eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
- - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme:
+ ! Here, t_building_max is the AC saturation setpoint
+ eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_max(l) &
+ - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) &
+ * dtime / (ht_roof(l) * rho_dair(l) * cpair * wtlunit_roof(l))
+ eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l)
+ else
+ t_building(l) = t_building_max(l)
+ eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
+ - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) )
+ end if
+
else if (t_building_bef_hac(l) < t_building_min(l)) then
t_building(l) = t_building_min(l)
eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) &
diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90
index c490ad27cc..4b7b80e4fe 100644
--- a/src/biogeophys/UrbanParamsType.F90
+++ b/src/biogeophys/UrbanParamsType.F90
@@ -101,6 +101,7 @@ module UrbanParamsType
character(len= *), parameter, public :: urban_hac_on = 'ON'
character(len= *), parameter, public :: urban_wasteheat_on = 'ON_WASTEHEAT'
character(len= 16), public :: urban_hac = urban_hac_off
+ logical, public :: urban_explicit_ac = .true. ! whether to use explicit, time-varying AC adoption rate
logical, public :: urban_traffic = .false. ! urban traffic fluxes
! !PRIVATE MEMBER DATA:
@@ -847,7 +848,7 @@ subroutine UrbanReadNML ( NLFilename )
integer :: unitn ! unit for namelist file
character(len=32) :: subname = 'UrbanReadNML' ! subroutine name
- namelist / clmu_inparm / urban_hac, urban_traffic, building_temp_method
+ namelist / clmu_inparm / urban_hac, urban_explicit_ac, urban_traffic, building_temp_method
!EOP
!-----------------------------------------------------------------------
@@ -875,6 +876,7 @@ subroutine UrbanReadNML ( NLFilename )
! Broadcast namelist variables read in
call shr_mpi_bcast(urban_hac, mpicom)
+ call shr_mpi_bcast(urban_explicit_ac, mpicom)
call shr_mpi_bcast(urban_traffic, mpicom)
call shr_mpi_bcast(building_temp_method, mpicom)
@@ -886,6 +888,7 @@ subroutine UrbanReadNML ( NLFilename )
!
if ( masterproc )then
write(iulog,*) ' urban air conditioning/heating and wasteheat = ', urban_hac
+ write(iulog,*) ' urban explicit air-conditioning adoption rate = ', urban_explicit_ac
write(iulog,*) ' urban traffic flux = ', urban_traffic
end if
diff --git a/src/biogeophys/test/CMakeLists.txt b/src/biogeophys/test/CMakeLists.txt
index 5c15858210..7a0a1e8fbb 100644
--- a/src/biogeophys/test/CMakeLists.txt
+++ b/src/biogeophys/test/CMakeLists.txt
@@ -5,6 +5,7 @@ add_subdirectory(HillslopeHydrology_test)
add_subdirectory(SnowHydrology_test)
add_subdirectory(Photosynthesis_test)
add_subdirectory(Balance_test)
+add_subdirectory(SoilStateInitTimeConst_test)
add_subdirectory(TotalWaterAndHeat_test)
add_subdirectory(Wateratm2lnd_test)
add_subdirectory(WaterTracerContainerType_test)
diff --git a/src/biogeophys/test/SoilStateInitTimeConst_test/CMakeLists.txt b/src/biogeophys/test/SoilStateInitTimeConst_test/CMakeLists.txt
new file mode 100644
index 0000000000..df58da9875
--- /dev/null
+++ b/src/biogeophys/test/SoilStateInitTimeConst_test/CMakeLists.txt
@@ -0,0 +1,6 @@
+set (pfunit_sources
+ test_dust_soil_clay_functions.pf)
+
+add_pfunit_ctest(SoilStateInit
+ TEST_SOURCES "${pfunit_sources}"
+ LINK_LIBRARIES clm csm_share)
diff --git a/src/biogeophys/test/SoilStateInitTimeConst_test/test_dust_soil_clay_functions.pf b/src/biogeophys/test/SoilStateInitTimeConst_test/test_dust_soil_clay_functions.pf
new file mode 100644
index 0000000000..5a8f858286
--- /dev/null
+++ b/src/biogeophys/test/SoilStateInitTimeConst_test/test_dust_soil_clay_functions.pf
@@ -0,0 +1,81 @@
+module test_dust_soil_clay_functions
+
+ ! Tests of SoilStateInitTimeConst functions for dust emission in regard to clay content
+
+ use funit
+ use SoilStateInitTimeConstMod
+ use shr_kind_mod , only : r8 => shr_kind_r8
+
+ implicit none
+
+ @TestCase
+ type, extends(TestCase) :: TestDustEmisSoilFunctions
+ contains
+ procedure :: setUp
+ procedure :: tearDown
+ end type TestDustEmisSoilFunctions
+
+ real(r8), parameter :: tol = 1.e-16_r8
+
+contains
+
+ subroutine setUp(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ end subroutine setUp
+
+ subroutine tearDown(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ end subroutine tearDown
+
+ @Test
+ subroutine TestClayOutOfRangeThreshold(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ real(r8) :: value
+ character(len=100) :: expected_msg
+
+ value = ThresholdSoilMoistZender2003( -1.e-15_r8 )
+ expected_msg = "ABORTED: Clay fraction is out of bounds (0 to 100)"
+ @assertExceptionRaised(expected_msg)
+ value = ThresholdSoilMoistZender2003( 1._r8 + 1.-15_r8 )
+ @assertExceptionRaised(expected_msg)
+ end subroutine TestClayOutOfRangeThreshold
+
+ @Test
+ subroutine TestThresholdValues(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ real(r8) :: value
+
+ value = ThresholdSoilMoistZender2003( 0.0_r8 )
+ @assertEqual( value, 0.17_r8, tolerance=tol )
+ value = ThresholdSoilMoistZender2003( 100.0_r8 )
+ @assertEqual( value, 0.31_r8, tolerance=tol )
+ end subroutine TestThresholdValues
+
+ @Test
+ subroutine TestThresholdKok2014Values(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ real(r8) :: value
+
+ value = ThresholdSoilMoistKok2014( 0.0_r8 )
+ @assertEqual( value, 0.0_r8, tolerance=tol )
+ value = ThresholdSoilMoistKok2014( 100.0_r8 )
+ @assertEqual( value, 0.31_r8, tolerance=tol )
+ value = ThresholdSoilMoistKok2014( 1.0_r8 )
+ @assertEqual( value, 0.001714_r8, tolerance=tol )
+ end subroutine TestThresholdKok2014Values
+
+ @Test
+ subroutine TestClayMassFracValues(this)
+ class(TestDustEmisSoilFunctions), intent(inout) :: this
+ real(r8) :: value
+
+ value = MassFracClay( 0.0_r8 )
+ @assertEqual( value, 0.0_r8, tolerance=tol )
+ value = MassFracClay( 20.0_r8 )
+ @assertEqual( value, 0.20_r8, tolerance=tol )
+ value = MassFracClay( 25.0_r8 )
+ @assertEqual( value, 0.20_r8, tolerance=tol )
+
+ end subroutine TestClayMassFracValues
+
+end module test_dust_soil_clay_functions
diff --git a/src/cpl/mct/ExcessIceStreamType.F90 b/src/cpl/mct/ExcessIceStreamType.F90
deleted file mode 100644
index 5c5394233c..0000000000
--- a/src/cpl/mct/ExcessIceStreamType.F90
+++ /dev/null
@@ -1,144 +0,0 @@
-module ExcessIceStreamType
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Stub for ExcessIceStreams for the MCT driver. So that MCT can be used
- ! without excess ice streams.
- !
- ! !USES
- use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use spmdMod , only : mpicom, masterproc
- use clm_varctl , only : iulog
- use abortutils , only : endrun
- use decompMod , only : bounds_type
-
- ! !PUBLIC TYPES:
- implicit none
- private
-
- public :: UseExcessIceStreams ! If streams will be used
-
- type, public :: excessicestream_type
- contains
-
- ! !PUBLIC MEMBER FUNCTIONS:
- procedure, public :: Init ! Initialize and read data in
- procedure, public :: CalcExcessIce ! Calculate excess ice ammount
-
- ! !PRIVATE MEMBER FUNCTIONS:
- procedure, private :: ReadNML ! Read in namelist
-
- end type excessicestream_type
- ! ! PRIVATE DATA:
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
-
-!==============================================================================
-contains
-!==============================================================================
-
- subroutine Init(this, bounds, NLFilename)
- !
- !
- ! arguments
- implicit none
- class(excessicestream_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
-
- !
- ! local variables
-
- call this%ReadNML( bounds, NLFileName )
- end subroutine Init
-
- subroutine CalcExcessIce(this,bounds,exice_bulk_init)
-
- ! only transfers grid values to columns
- implicit none
- class(excessicestream_type) :: this
- type(bounds_type), intent(in) :: bounds
- real(r8) , intent(inout) :: exice_bulk_init(bounds%begc:bounds%endc)
- !
- ! !LOCAL VARIABLES:
-
- end subroutine CalcExcessIce
-
- logical function UseExcessIceStreams()
- !
- ! !DESCRIPTION:
- ! Return true if
- !
- ! !USES:
- !
- ! !ARGUMENTS:
- implicit none
- !
- ! !LOCAL VARIABLES:
- UseExcessIceStreams = .false.
-end function UseExcessIceStreams
-
-subroutine ReadNML(this, bounds, NLFilename)
- !
- ! Read the namelist data stream information.
- !
- ! Uses:
- use shr_nl_mod , only : shr_nl_find_group_name
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use shr_mpi_mod , only : shr_mpi_bcast
- !
- ! arguments
- implicit none
- class(excessicestream_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! local variables
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- logical :: use_excess_ice_streams = .false. ! logical to turn on use of excess ice streams
- character(len=CL) :: stream_fldFileName_exice = ' '
- character(len=CL) :: stream_mapalgo_exice = 'none'
- character(len=*), parameter :: namelist_name = 'exice_streams' ! MUST agree with name in namelist and read
- character(len=*), parameter :: subName = "('exice_streams::ReadNML')"
- !-----------------------------------------------------------------------
-
- namelist /exice_streams/ & ! MUST agree with namelist_name above
- stream_mapalgo_exice, stream_fldFileName_exice, use_excess_ice_streams
- !-----------------------------------------------------------------------
- ! Default values for namelist
-
- ! Read excess ice namelist
- if (masterproc) then
- open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call shr_nl_find_group_name(nu_nml, namelist_name, status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=exice_streams,iostat=nml_error) ! MUST agree with namelist_name above
- if (nml_error /= 0) then
- call endrun(msg=' ERROR reading '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__))
- end if
- else
- call endrun(msg=' ERROR finding '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__))
- end if
- close(nu_nml)
- endif
-
- call shr_mpi_bcast(use_excess_ice_streams , mpicom)
-
- if (masterproc) then
- if ( use_excess_ice_streams ) then
- call endrun(msg=' ERROR excess ice streams can NOT be on for the MCT driver'//errMsg(sourcefile, __LINE__))
- end if
- if ( trim(stream_fldFileName_exice) /= '' ) then
- call endrun(msg=' ERROR stream_fldFileName_exice can NOT be set for the MCT driver'//errMsg(sourcefile, __LINE__))
- end if
- if ( trim(stream_mapalgo_exice) /= 'none' ) then
- call endrun(msg=' ERROR stream_mapalgo_exice can only be none for the MCT driver'//errMsg(sourcefile, __LINE__))
- end if
- endif
-
-end subroutine ReadNML
-
-end module ExcessIceStreamType
diff --git a/src/cpl/mct/FireDataBaseType.F90 b/src/cpl/mct/FireDataBaseType.F90
deleted file mode 100644
index 0ee635b2fa..0000000000
--- a/src/cpl/mct/FireDataBaseType.F90
+++ /dev/null
@@ -1,561 +0,0 @@
-module FireDataBaseType
-
-#include "shr_assert.h"
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! module for handling of fire data
- !
- ! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL
- use shr_strdata_mod , only : shr_strdata_type, shr_strdata_create, shr_strdata_print
- use shr_strdata_mod , only : shr_strdata_advance
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use clm_varctl , only : iulog, inst_name
- use spmdMod , only : masterproc, mpicom, comp_id
- use fileutils , only : getavu, relavu
- use domainMod , only : ldomain
- use abortutils , only : endrun
- use decompMod , only : bounds_type
- use FireMethodType , only : fire_method_type
- use lnd_set_decomp_and_domain, only : gsmap_global
- use mct_mod
- !
- implicit none
- private
- !
- ! !PUBLIC TYPES:
- public :: fire_base_type
-
- !
- type, abstract, extends(fire_method_type) :: fire_base_type
- private
- ! !PRIVATE MEMBER DATA:
-
- real(r8), public, pointer :: forc_lnfm(:) ! Lightning frequency
- real(r8), public, pointer :: forc_hdm(:) ! Human population density
-
- real(r8), public, pointer :: gdp_lf_col(:) ! col global real gdp data (k US$/capita)
- real(r8), public, pointer :: peatf_lf_col(:) ! col global peatland fraction data (0-1)
- integer , public, pointer :: abm_lf_col(:) ! col global peak month of crop fire emissions
-
- type(shr_strdata_type) :: sdat_hdm ! Human population density input data stream
- type(shr_strdata_type) :: sdat_lnfm ! Lightning input data stream
-
- contains
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- procedure, public :: FireInit => BaseFireInit ! Initialization of Fire
- procedure, public :: BaseFireInit ! Initialization of Fire
- procedure(FireReadNML_interface), public, deferred :: FireReadNML ! Read in namelist for Fire
- procedure, public :: FireInterp ! Interpolate fire data
- procedure(need_lightning_and_popdens_interface), public, deferred :: &
- need_lightning_and_popdens ! Returns true if need lightning & popdens
- !
- ! !PRIVATE MEMBER FUNCTIONS:
- procedure, private :: hdm_init ! position datasets for dynamic human population density
- procedure, private :: hdm_interp ! interpolates between two years of human pop. density file data
- procedure, private :: lnfm_init ! position datasets for Lightning
- procedure, private :: lnfm_interp ! interpolates between two years of Lightning file data
- procedure, private :: surfdataread ! read fire related data from surface data set
- end type fire_base_type
- !-----------------------------------------------------------------------
-
- abstract interface
- !-----------------------------------------------------------------------
- function need_lightning_and_popdens_interface(this) result(need_lightning_and_popdens)
- !
- ! !DESCRIPTION:
- ! Returns true if need lightning and popdens, false otherwise
- !
- ! USES
- import :: fire_base_type
- !
- ! !ARGUMENTS:
- class(fire_base_type), intent(in) :: this
- logical :: need_lightning_and_popdens ! function result
- !-----------------------------------------------------------------------
- end function need_lightning_and_popdens_interface
- end interface
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
-
-contains
-
- !-----------------------------------------------------------------------
- subroutine FireReadNML_interface( this, NLFilename )
- !
- ! !DESCRIPTION:
- ! Read the namelist for Fire
- !
- ! !USES:
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- end subroutine FireReadNML_interface
-
- !-----------------------------------------------------------------------
- subroutine BaseFireInit( this, bounds, NLFilename )
- !
- ! !DESCRIPTION:
- ! Initialize CN Fire module
- ! !USES:
- use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename
- !-----------------------------------------------------------------------
-
- if ( this%need_lightning_and_popdens() ) then
- ! Allocate lightning forcing data
- allocate( this%forc_lnfm(bounds%begg:bounds%endg) )
- this%forc_lnfm(bounds%begg:) = nan
- ! Allocate pop dens forcing data
- allocate( this%forc_hdm(bounds%begg:bounds%endg) )
- this%forc_hdm(bounds%begg:) = nan
-
- ! Allocate real gdp data
- allocate(this%gdp_lf_col(bounds%begc:bounds%endc))
- ! Allocate peatland fraction data
- allocate(this%peatf_lf_col(bounds%begc:bounds%endc))
- ! Allocates peak month of crop fire emissions
- allocate(this%abm_lf_col(bounds%begc:bounds%endc))
-
-
- call this%hdm_init(bounds, NLFilename)
- call this%hdm_interp(bounds)
- call this%lnfm_init(bounds, NLFilename)
- call this%lnfm_interp(bounds)
- call this%surfdataread(bounds)
- end if
-
- end subroutine BaseFireInit
-
- !-----------------------------------------------------------------------
- subroutine FireInterp(this,bounds)
- !
- ! !DESCRIPTION:
- ! Interpolate CN Fire datasets
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- !-----------------------------------------------------------------------
-
- if ( this%need_lightning_and_popdens() ) then
- call this%hdm_interp(bounds)
- call this%lnfm_interp(bounds)
- end if
-
- end subroutine FireInterp
-
- !-----------------------------------------------------------------------
- subroutine hdm_init( this, bounds, NLFilename )
- !
- ! !DESCRIPTION:
- ! Initialize data stream information for population density.
- !
- ! !USES:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use clm_nlUtilsMod , only : find_nlgroup_name
- use ndepStreamMod , only : clm_domain_mct
- use histFileMod , only : hist_addfld1d
- !
- ! !ARGUMENTS:
- implicit none
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! !LOCAL VARIABLES:
- integer :: stream_year_first_popdens ! first year in pop. dens. stream to use
- integer :: stream_year_last_popdens ! last year in pop. dens. stream to use
- integer :: model_year_align_popdens ! align stream_year_first_hdm with
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldFileName_popdens ! population density streams filename
- character(len=CL) :: popdensmapalgo = 'bilinear' ! mapping alogrithm for population density
- character(len=CL) :: popdens_tintalgo = 'nearest'! time interpolation alogrithm for population density
- character(len=CL) :: stream_meshfile_popdens ! not used
- character(*), parameter :: subName = "('hdmdyn_init')"
- character(*), parameter :: F00 = "('(hdmdyn_init) ',4a)"
- !-----------------------------------------------------------------------
-
- namelist /popd_streams/ &
- stream_year_first_popdens, &
- stream_year_last_popdens, &
- model_year_align_popdens, &
- popdensmapalgo, &
- stream_fldFileName_popdens, &
- stream_meshfile_popdens , &
- popdens_tintalgo
-
- ! Default values for namelist
- stream_year_first_popdens = 1 ! first year in stream to use
- stream_year_last_popdens = 1 ! last year in stream to use
- model_year_align_popdens = 1 ! align stream_year_first_popdens with this model year
- stream_fldFileName_popdens = ' '
-
- ! Read popd_streams namelist
- if (masterproc) then
- nu_nml = getavu()
- open( nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call find_nlgroup_name(nu_nml, 'popd_streams', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=popd_streams,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(msg='ERROR reading popd_streams namelist'//errMsg(sourcefile, __LINE__))
- end if
- end if
- close(nu_nml)
- call relavu( nu_nml )
- endif
-
- call shr_mpi_bcast(stream_year_first_popdens, mpicom)
- call shr_mpi_bcast(stream_year_last_popdens, mpicom)
- call shr_mpi_bcast(model_year_align_popdens, mpicom)
- call shr_mpi_bcast(stream_fldFileName_popdens, mpicom)
- call shr_mpi_bcast(popdens_tintalgo, mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) 'popdens_streams settings:'
- write(iulog,*) ' stream_year_first_popdens = ',stream_year_first_popdens
- write(iulog,*) ' stream_year_last_popdens = ',stream_year_last_popdens
- write(iulog,*) ' model_year_align_popdens = ',model_year_align_popdens
- write(iulog,*) ' stream_fldFileName_popdens = ',stream_fldFileName_popdens
- write(iulog,*) ' popdens_tintalgo = ',popdens_tintalgo
- write(iulog,*) ' '
- endif
-
- call clm_domain_mct (bounds, dom_clm)
-
- call shr_strdata_create(this%sdat_hdm,name="clmhdm", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=stream_year_first_popdens, &
- yearLast=stream_year_last_popdens, &
- yearAlign=model_year_align_popdens, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_popdens), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domAreaName='area', &
- domMaskName='mask', &
- filePath='', &
- filename=(/trim(stream_fldFileName_popdens)/) , &
- fldListFile='hdm', &
- fldListModel='hdm', &
- fillalgo='none', &
- mapalgo=popdensmapalgo, &
- calendar=get_calendar(), &
- tintalgo=popdens_tintalgo, &
- taxmode='extend' )
-
- if (masterproc) then
- call shr_strdata_print(this%sdat_hdm,'population density data')
- endif
-
- ! Add history fields
- call hist_addfld1d (fname='HDM', units='counts/km^2', &
- avgflag='A', long_name='human population density', &
- ptr_lnd=this%forc_hdm, default='inactive')
-
- end subroutine hdm_init
-
- !-----------------------------------------------------------------------
- subroutine hdm_interp( this, bounds)
- !
- ! !DESCRIPTION:
- ! Interpolate data stream information for population density.
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: g, ig
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- !-----------------------------------------------------------------------
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(this%sdat_hdm, mcdate, sec, mpicom, 'hdmdyn')
-
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- this%forc_hdm(g) = this%sdat_hdm%avs(1)%rAttr(1,ig)
- end do
-
- end subroutine hdm_interp
-
- !-----------------------------------------------------------------------
- subroutine lnfm_init( this, bounds, NLFilename )
- !
- ! !DESCRIPTION:
- !
- ! Initialize data stream information for Lightning.
- !
- ! !USES:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use clm_nlUtilsMod , only : find_nlgroup_name
- use ndepStreamMod , only : clm_domain_mct
- use histFileMod , only : hist_addfld1d
- !
- ! !ARGUMENTS:
- implicit none
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename
- !
- ! !LOCAL VARIABLES:
- integer :: stream_year_first_lightng ! first year in Lightning stream to use
- integer :: stream_year_last_lightng ! last year in Lightning stream to use
- integer :: model_year_align_lightng ! align stream_year_first_lnfm with
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldFileName_lightng ! lightning stream filename to read
- character(len=CL) :: lightng_tintalgo = 'linear'! time interpolation alogrithm
- character(len=CL) :: lightngmapalgo = 'bilinear'! Mapping alogrithm
- character(*), parameter :: subName = "('lnfmdyn_init')"
- character(*), parameter :: F00 = "('(lnfmdyn_init) ',4a)"
- !-----------------------------------------------------------------------
-
- namelist /light_streams/ &
- stream_year_first_lightng, &
- stream_year_last_lightng, &
- model_year_align_lightng, &
- lightngmapalgo, &
- stream_fldFileName_lightng, &
- lightng_tintalgo
-
- ! Default values for namelist
- stream_year_first_lightng = 1 ! first year in stream to use
- stream_year_last_lightng = 1 ! last year in stream to use
- model_year_align_lightng = 1 ! align stream_year_first_lnfm with this model year
- stream_fldFileName_lightng = ' '
-
- ! Read light_streams namelist
- if (masterproc) then
- nu_nml = getavu()
- open( nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call find_nlgroup_name(nu_nml, 'light_streams', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=light_streams,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(msg='ERROR reading light_streams namelist'//errMsg(sourcefile, __LINE__))
- end if
- end if
- close(nu_nml)
- call relavu( nu_nml )
- endif
-
- call shr_mpi_bcast(stream_year_first_lightng, mpicom)
- call shr_mpi_bcast(stream_year_last_lightng, mpicom)
- call shr_mpi_bcast(model_year_align_lightng, mpicom)
- call shr_mpi_bcast(stream_fldFileName_lightng, mpicom)
- call shr_mpi_bcast(lightng_tintalgo, mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) 'light_stream settings:'
- write(iulog,*) ' stream_year_first_lightng = ',stream_year_first_lightng
- write(iulog,*) ' stream_year_last_lightng = ',stream_year_last_lightng
- write(iulog,*) ' model_year_align_lightng = ',model_year_align_lightng
- write(iulog,*) ' stream_fldFileName_lightng = ',stream_fldFileName_lightng
- write(iulog,*) ' lightng_tintalgo = ',lightng_tintalgo
- write(iulog,*) ' '
- endif
-
- call clm_domain_mct (bounds, dom_clm)
-
- call shr_strdata_create(this%sdat_lnfm,name="clmlnfm", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=stream_year_first_lightng, &
- yearLast=stream_year_last_lightng, &
- yearAlign=model_year_align_lightng, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_lightng), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domAreaName='area', &
- domMaskName='mask', &
- filePath='', &
- filename=(/trim(stream_fldFileName_lightng)/), &
- fldListFile='lnfm', &
- fldListModel='lnfm', &
- fillalgo='none', &
- tintalgo=lightng_tintalgo, &
- mapalgo=lightngmapalgo, &
- calendar=get_calendar(), &
- taxmode='cycle' )
-
- if (masterproc) then
- call shr_strdata_print(this%sdat_lnfm,'Lightning data')
- endif
-
- ! Add history fields
- call hist_addfld1d (fname='LNFM', units='counts/km^2/hr', &
- avgflag='A', long_name='Lightning frequency', &
- ptr_lnd=this%forc_lnfm, default='inactive')
-
- end subroutine lnfm_init
-
- !-----------------------------------------------------------------------
- subroutine lnfm_interp(this, bounds )
- !
- ! !DESCRIPTION:
- ! Interpolate data stream information for Lightning.
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: g, ig
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- !-----------------------------------------------------------------------
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(this%sdat_lnfm, mcdate, sec, mpicom, 'lnfmdyn')
-
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- this%forc_lnfm(g) = this%sdat_lnfm%avs(1)%rAttr(1,ig)
- end do
-
- end subroutine lnfm_interp
-
- !-----------------------------------------------------------------------
- subroutine surfdataread(this, bounds)
- !
- ! !DESCRIPTION:
- ! Read surface data set to populate relevant fire-related variables
- !
- ! !USES:
- use spmdMod , only : masterproc
- use clm_varctl , only : nsrest, nsrStartup, fsurdat
- use clm_varcon , only : grlnd
- use ColumnType , only : col
- use fileutils , only : getfil
- use ncdio_pio
- !
- ! !ARGUMENTS:
- class(fire_base_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: g,c ! indices
- type(file_desc_t) :: ncid ! netcdf id
- logical :: readvar ! true => variable is on initial dataset
- character(len=256) :: locfn ! local filename
- real(r8), pointer :: gdp(:) ! global gdp data (needs to be a pointer for use in ncdio)
- real(r8), pointer :: peatf(:) ! global peatf data (needs to be a pointer for use in ncdio)
- integer, pointer :: abm(:) ! global abm data (needs to be a pointer for use in ncdio)
- !-----------------------------------------------------------------------
-
- ! --------------------------------------------------------------------
- ! Open surface dataset
- ! --------------------------------------------------------------------
-
- call getfil (fsurdat, locfn, 0)
- call ncd_pio_openfile (ncid, locfn, 0)
-
- ! --------------------------------------------------------------------
- ! Read in GDP data
- ! --------------------------------------------------------------------
-
- allocate(gdp(bounds%begg:bounds%endg))
- call ncd_io(ncid=ncid, varname='gdp', flag='read', data=gdp, dim1name=grlnd, readvar=readvar)
- if (.not. readvar) then
- call endrun(msg=' ERROR: gdp NOT on surfdata file'//errMsg(sourcefile, __LINE__))
- end if
- do c = bounds%begc, bounds%endc
- g = col%gridcell(c)
- this%gdp_lf_col(c) = gdp(g)
- end do
- deallocate(gdp)
-
- ! --------------------------------------------------------------------
- ! Read in peatf data
- ! --------------------------------------------------------------------
-
- allocate(peatf(bounds%begg:bounds%endg))
- call ncd_io(ncid=ncid, varname='peatf', flag='read', data=peatf, dim1name=grlnd, readvar=readvar)
- if (.not. readvar) then
- call endrun(msg=' ERROR: peatf NOT on surfdata file'//errMsg(sourcefile, __LINE__))
- end if
- do c = bounds%begc, bounds%endc
- g = col%gridcell(c)
- this%peatf_lf_col(c) = peatf(g)
- end do
- deallocate(peatf)
-
- ! --------------------------------------------------------------------
- ! Read in ABM data
- ! --------------------------------------------------------------------
-
- allocate(abm(bounds%begg:bounds%endg))
- call ncd_io(ncid=ncid, varname='abm', flag='read', data=abm, dim1name=grlnd, readvar=readvar)
- if (.not. readvar) then
- call endrun(msg=' ERROR: abm NOT on surfdata file'//errMsg(sourcefile, __LINE__))
- end if
- do c = bounds%begc, bounds%endc
- g = col%gridcell(c)
- this%abm_lf_col(c) = abm(g)
- end do
- deallocate(abm)
-
- ! Close file
-
- call ncd_pio_closefile(ncid)
-
- if (masterproc) then
- write(iulog,*) 'Successfully read fmax, soil color, sand and clay boundary data'
- write(iulog,*)
- endif
-
- end subroutine surfdataread
-
-
-end module FireDataBaseType
diff --git a/src/cpl/mct/SoilMoistureStreamMod.F90 b/src/cpl/mct/SoilMoistureStreamMod.F90
deleted file mode 100644
index 8b366d6c8e..0000000000
--- a/src/cpl/mct/SoilMoistureStreamMod.F90
+++ /dev/null
@@ -1,418 +0,0 @@
-module SoilMoistureStreamMod
-
- ! **********************************************************************
- ! --------------------------- IMPORTANT NOTE ---------------------------
- !
- ! In cases using the NUOPC driver/mediator, we use a different version of this module,
- ! based on CDEPS, which resides in src/cpl/nuopc/. Changes to the science here should
- ! also be made in the similar file in src/cpl/nuopc. Once we start using CDEPS by
- ! default, we can remove this version and move the CDEPS-based version into its place.
- ! **********************************************************************
-
-#include "shr_assert.h"
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Read in soil moisture from data stream
- !
- ! !USES:
- use shr_strdata_mod , only : shr_strdata_type, shr_strdata_create
- use shr_strdata_mod , only : shr_strdata_print, shr_strdata_advance
- use shr_kind_mod , only : r8 => shr_kind_r8
- use shr_kind_mod , only : CL => shr_kind_CL, CXX => shr_kind_CXX
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use decompMod , only : bounds_type, subgrid_level_column
- use abortutils , only : endrun
- use clm_varctl , only : iulog, use_soil_moisture_streams, inst_name
- use clm_varcon , only : grlnd
- use controlMod , only : NLFilename
- use domainMod , only : ldomain
- use LandunitType , only : lun
- use ColumnType , only : col
- use SoilStateType , only : soilstate_type
- use WaterStateBulkType , only : waterstatebulk_type
- use perf_mod , only : t_startf, t_stopf
- use spmdMod , only : masterproc, mpicom, comp_id
- use lnd_set_decomp_and_domain , only : gsMap_lnd2Dsoi_gdc2glo
- use mct_mod
- use ncdio_pio
- !
- ! !PUBLIC TYPES:
- implicit none
- private
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: PrescribedSoilMoistureInit ! position datasets for soil moisture
- public :: PrescribedSoilMoistureAdvance ! Advance the soil moisture stream (outside of Open-MP loops)
- public :: PrescribedSoilMoistureInterp ! interpolates between two periods of soil moisture data
-
- ! !PRIVATE MEMBER DATA:
- type(shr_strdata_type) :: sdat_soilm ! soil moisture input data stream
- integer :: ism ! Soil moisture steram index
- integer, allocatable :: g_to_ig(:) ! Array matching gridcell index to data index
- logical :: soilm_ignore_data_if_missing ! If should ignore overridding a point with soil moisture data
- ! from the streams file, if the streams file shows that point
- ! as missing (namelist item)
- !
- ! !PRIVATE TYPES:
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
- !-----------------------------------------------------------------------
-
-contains
-
- !-----------------------------------------------------------------------
- !
- ! soil_moisture_init
- !
- !-----------------------------------------------------------------------
- subroutine PrescribedSoilMoistureInit(bounds)
- !
- ! Initialize data stream information for soil moisture.
- !
- !
- ! !USES:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use clm_nlUtilsMod , only : find_nlgroup_name
- use ndepStreamMod , only : clm_domain_mct
- use shr_stream_mod , only : shr_stream_file_null
- use shr_string_mod , only : shr_string_listCreateField
- use clm_varpar , only : nlevsoi
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type), intent(in) :: bounds ! bounds
- !
- ! !LOCAL VARIABLES:
- integer :: i ! index
- integer :: stream_year_first_soilm ! first year in Ustar stream to use
- integer :: stream_year_last_soilm ! last year in Ustar stream to use
- integer :: model_year_align_soilm ! align stream_year_first_soilm with
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- integer :: soilm_offset ! Offset in time for dataset (sec)
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldfilename_soilm ! ustar stream filename to read
- character(len=CL) :: soilm_tintalgo = 'linear' ! Time interpolation alogrithm
-
- character(*), parameter :: subName = "('PrescribedSoilMoistureInit')"
- character(*), parameter :: F00 = "('(PrescribedSoilMoistureInit) ',4a)"
- character(*), parameter :: soilmString = "H2OSOI" ! base string for field string
- character(CXX) :: fldList ! field string
- !-----------------------------------------------------------------------
- !
- ! deal with namelist variables here in init
- !
- namelist /soil_moisture_streams/ &
- stream_year_first_soilm, &
- stream_year_last_soilm, &
- model_year_align_soilm, &
- soilm_tintalgo, &
- soilm_offset, &
- soilm_ignore_data_if_missing, &
- stream_fldfilename_soilm
-
- ! Default values for namelist
- stream_year_first_soilm = 1 ! first year in stream to use
- stream_year_last_soilm = 1 ! last year in stream to use
- model_year_align_soilm = 1 ! align stream_year_first_soilm with this model year
- stream_fldfilename_soilm = shr_stream_file_null
- soilm_offset = 0
- soilm_ignore_data_if_missing = .false.
-
- ! Read soilm_streams namelist
- if (masterproc) then
- open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call find_nlgroup_name(nu_nml, 'soil_moisture_streams', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=soil_moisture_streams,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(subname // ':: ERROR reading soil_moisture_streams namelist')
- end if
- else
- call endrun(subname // ':: ERROR finding soilm_streams namelist')
- end if
- close(nu_nml)
- endif
-
- call shr_mpi_bcast(stream_year_first_soilm, mpicom)
- call shr_mpi_bcast(stream_year_last_soilm, mpicom)
- call shr_mpi_bcast(model_year_align_soilm, mpicom)
- call shr_mpi_bcast(stream_fldfilename_soilm, mpicom)
- call shr_mpi_bcast(soilm_tintalgo, mpicom)
- call shr_mpi_bcast(soilm_offset, mpicom)
- call shr_mpi_bcast(soilm_ignore_data_if_missing, mpicom)
-
- if (masterproc) then
-
- write(iulog,*) ' '
- write(iulog,*) 'soil_moisture_stream settings:'
- write(iulog,*) ' stream_year_first_soilm = ',stream_year_first_soilm
- write(iulog,*) ' stream_year_last_soilm = ',stream_year_last_soilm
- write(iulog,*) ' model_year_align_soilm = ',model_year_align_soilm
- write(iulog,*) ' stream_fldfilename_soilm = ',trim(stream_fldfilename_soilm)
- write(iulog,*) ' soilm_tintalgo = ',trim(soilm_tintalgo)
- write(iulog,*) ' soilm_offset = ',soilm_offset
- if ( soilm_ignore_data_if_missing )then
- write(iulog,*) ' Do NOT override a point with streams data if the streams data is missing'
- else
- write(iulog,*) ' Abort, if you find a model point where the input streams data is set to missing value'
- end if
-
- endif
-
- call clm_domain_mct (bounds, dom_clm, nlevels=nlevsoi)
-
- ! create the field list for these fields...use in shr_strdata_create
- fldList = trim(soilmString)
- if (masterproc) write(iulog,*) 'fieldlist: ', trim(fldList)
-
- call shr_strdata_create(sdat_soilm,name="soil_moisture", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsMap_lnd2Dsoi_gdc2glo, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- nzg=nlevsoi, &
- yearFirst=stream_year_first_soilm, &
- yearLast=stream_year_last_soilm, &
- yearAlign=model_year_align_soilm, &
- offset=soilm_offset, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_soilm), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domZvarName='levsoi' , &
- domAreaName='area', &
- domMaskName='mask', &
- filePath='', &
- filename=(/stream_fldFileName_soilm/), &
- fldListFile=fldList, &
- fldListModel=fldList, &
- fillalgo='none', &
- mapalgo='none', &
- tintalgo=soilm_tintalgo, &
- calendar=get_calendar(), &
- dtlimit = 15._r8, &
- taxmode='cycle' )
-
- if (masterproc) then
- call shr_strdata_print(sdat_soilm,'soil moisture data')
- endif
-
- end subroutine PrescribedSoilMoistureInit
-
-
- !-----------------------------------------------------------------------
- !
- ! PrescribedSoilMoistureAdvance
- !
- !-----------------------------------------------------------------------
- subroutine PrescribedSoilMoistureAdvance( bounds )
- !
- ! Advanace the prescribed soil moisture stream
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- !
- ! !ARGUMENTS:
- type(bounds_type) , intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- character(len=CL) :: stream_var_name
- integer :: g, ig
- integer :: ier ! error code
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- stream_var_name = 'H2OSOI'
-
- ! Determine variable index
- ism = mct_aVect_indexRA(sdat_soilm%avs(1),trim(stream_var_name))
-
- call shr_strdata_advance(sdat_soilm, mcdate, sec, mpicom, trim(stream_var_name))
-
- ! Map gridcell to AV index
- ier = 0
- if ( .not. allocated(g_to_ig) )then
- allocate (g_to_ig(bounds%begg:bounds%endg), stat=ier)
- if (ier /= 0) then
- write(iulog,*) 'Prescribed soil moisture allocation error'
- call endrun(msg=errMsg(sourcefile, __LINE__))
- end if
-
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- g_to_ig(g) = ig
- end do
- end if
-
- end subroutine PrescribedSoilMoistureAdvance
-
- !-----------------------------------------------------------------------
- !
- ! PrescribedSoilMoistureInterp
- !
- !-----------------------------------------------------------------------
- subroutine PrescribedSoilMoistureInterp(bounds, soilstate_inst, &
- waterstatebulk_inst)
- !
- ! Assign data stream information for prescribed soil moisture.
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- use clm_varpar , only : nlevsoi
- use clm_varcon , only : denh2o, denice, watmin, spval
- use landunit_varcon , only : istsoil, istcrop
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type) , intent(in) :: bounds
- type(soilstate_type) , intent(in) :: soilstate_inst
- type(waterstatebulk_type) , intent(inout) :: waterstatebulk_inst
- !
- ! !LOCAL VARIABLES:
- integer :: c, g, j, ig, n
- real(r8) :: soilm_liq_frac ! liquid fraction of soil moisture
- real(r8) :: soilm_ice_frac ! ice fraction of soil moisture
- real(r8) :: moisture_increment ! soil moisture adjustment increment
- real(r8) :: h2osoi_vol_initial ! initial vwc value
- character(*), parameter :: subName = "('PrescribedSoilMoistureInterp')"
-
- !-----------------------------------------------------------------------
-
- SHR_ASSERT_FL( (lbound(sdat_soilm%avs(1)%rAttr,1) == ism ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(sdat_soilm%avs(1)%rAttr,1) == ism ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(g_to_ig,1) <= bounds%begg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(g_to_ig,1) >= bounds%endg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(sdat_soilm%avs(1)%rAttr,2) <= g_to_ig(bounds%begg) ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(sdat_soilm%avs(1)%rAttr,2) >= g_to_ig(bounds%endg)+(nlevsoi-1)*size(g_to_ig) ), sourcefile, __LINE__)
- associate( &
- dz => col%dz , & ! Input: [real(r8) (:,:) ] layer depth (m)
- watsat => soilstate_inst%watsat_col , & ! Input: [real(r8) (:,:) ] volumetric soil water at saturation (porosity)
- h2osoi_liq => waterstatebulk_inst%h2osoi_liq_col , & ! Input/Output: [real(r8) (:,:) ] liquid water (kg/m2)
- h2osoi_ice => waterstatebulk_inst%h2osoi_ice_col , & ! Input/Output: [real(r8) (:,:) ] ice water (kg/m2)
- h2osoi_vol => waterstatebulk_inst%h2osoi_vol_col , & ! Output: volumetric soil water (m3/m3)
- h2osoi_vol_prs => waterstatebulk_inst%h2osoi_vol_prs_grc & ! Output: prescribed volumetric soil water (m3/m3)
- )
- SHR_ASSERT_FL( (lbound(h2osoi_vol,1) <= bounds%begc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_vol,1) >= bounds%endc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_vol,2) == 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_vol,2) >= nlevsoi ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(dz,1) <= bounds%begc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(dz,1) >= bounds%endc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(dz,2) <= 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(dz,2) >= nlevsoi ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(watsat,1) <= bounds%begc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(watsat,1) >= bounds%endc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(watsat,2) <= 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(watsat,2) >= nlevsoi ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_liq,1) <= bounds%begc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_liq,1) >= bounds%endc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_liq,2) <= 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_liq,2) >= nlevsoi ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_ice,1) <= bounds%begc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_ice,1) >= bounds%endc ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_ice,2) <= 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_ice,2) >= nlevsoi ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_vol_prs,1) <= bounds%begg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_vol_prs,1) >= bounds%endg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(h2osoi_vol_prs,2) == 1 ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(h2osoi_vol_prs,2) >= nlevsoi ), sourcefile, __LINE__)
- !
- ! Set the prescribed soil moisture read from the file everywhere
- !
- do g = bounds%begg, bounds%endg
- ig = g_to_ig(g)
- do j = 1, nlevsoi
-
- !n = ig + (j-1)*size(g_to_ig)
- n = ig + (j-1)*size(g_to_ig)
-
- h2osoi_vol_prs(g,j) = sdat_soilm%avs(1)%rAttr(ism,n)
-
- ! If soil moiture is being interpolated in time and the result is
- ! large that probably means one of the two data points is missing (set to spval)
- if ( h2osoi_vol_prs(g,j) > 10.0_r8 .and. (h2osoi_vol_prs(g,j) /= spval) )then
- h2osoi_vol_prs(g,j) = spval
- end if
-
- end do
- end do
-
- do c = bounds%begc, bounds%endc
- !
- ! Set variable for each gridcell/column combination
- !
- g = col%gridcell(c)
- ig = g_to_ig(g)
-
- ! EBK Jan/2020, also check weights on gridcell (See https://github.com/ESCOMP/CTSM/issues/847)
- if ( (lun%itype(col%landunit(c)) == istsoil) .or. (lun%itype(col%landunit(c)) == istcrop) .and. &
- (col%wtgcell(c) /= 0._r8) ) then
- ! this is a 2d field (gridcell/nlevsoi) !
- do j = 1, nlevsoi
-
- n = ig + (j-1)*size(g_to_ig)
-
- ! if soil water is zero, liq/ice fractions cannot be calculated
- if((h2osoi_liq(c, j) + h2osoi_ice(c, j)) > 0._r8) then
-
- ! save original soil moisture value
- h2osoi_vol_initial = h2osoi_vol(c,j)
-
- ! Check if the vegetated land mask from the dataset on the
- ! file is different
- if ( (h2osoi_vol_prs(g,j) == spval) .and. (h2osoi_vol_initial /= spval) )then
- if ( soilm_ignore_data_if_missing )then
- cycle
- else
- write(iulog,*) 'Input soil moisture dataset is not vegetated as expected: gridcell=', &
- g, ' active = ', col%active(c)
- call endrun(subgrid_index=c, subgrid_level=subgrid_level_column, &
- msg = subname // &
- ' ERROR:: The input soil moisture stream is NOT vegetated for one of the land points' )
- end if
- end if
-
- ! update volumetric soil moisture from data prescribed from the file
- h2osoi_vol(c,j) = h2osoi_vol_prs(g,j)
-
-
- ! calculate liq/ice mass fractions
- soilm_liq_frac = h2osoi_liq(c, j) /(h2osoi_liq(c, j) + h2osoi_ice(c, j))
- soilm_ice_frac = h2osoi_ice(c, j) /(h2osoi_liq(c, j) + h2osoi_ice(c, j))
-
- ! calculate moisture increment
- moisture_increment = h2osoi_vol(c,j) - h2osoi_vol_initial
- ! add limitation check
- moisture_increment = min((watsat(c,j) - h2osoi_vol_initial),max(-(h2osoi_vol_initial-watmin),moisture_increment))
-
- ! update liq/ice water mass due to (volumetric) moisture increment
- h2osoi_liq(c,j) = h2osoi_liq(c,j) + (soilm_liq_frac * moisture_increment * dz(c, j) * denh2o)
- h2osoi_ice(c,j) = h2osoi_ice(c,j) + (soilm_ice_frac * moisture_increment * dz(c, j) * denice)
-
- else
- call endrun(subgrid_index=c, subgrid_level=subgrid_level_column, &
- msg = subname // ':: ERROR h2osoil liquid plus ice is zero')
- endif
- enddo
- endif
- end do
-
- end associate
-
- end subroutine PrescribedSoilMoistureInterp
-
-end module SoilMoistureStreamMod
diff --git a/src/cpl/mct/UrbanTimeVarType.F90 b/src/cpl/mct/UrbanTimeVarType.F90
deleted file mode 100644
index 805ac47fbf..0000000000
--- a/src/cpl/mct/UrbanTimeVarType.F90
+++ /dev/null
@@ -1,314 +0,0 @@
-module UrbanTimeVarType
-
- !------------------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Urban Time Varying Data
- !
- ! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_CL
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use abortutils , only : endrun
- use decompMod , only : bounds_type, subgrid_level_landunit
- use clm_varctl , only : iulog, inst_name
- use landunit_varcon , only : isturb_MIN, isturb_MAX
- use clm_varcon , only : spval
- use LandunitType , only : lun
- use GridcellType , only : grc
- use mct_mod
- use shr_strdata_mod , only : shr_strdata_type
- !
- implicit none
- save
- private
- !
- !
-
- ! !PUBLIC TYPE
- type, public :: urbantv_type
-
- real(r8), public, pointer :: t_building_max(:) ! lun maximum internal building air temperature (K)
- type(shr_strdata_type) :: sdat_urbantv ! urban time varying input data stream
- contains
-
- ! !PUBLIC MEMBER FUNCTIONS:
- procedure, public :: Init ! Allocate and initialize urbantv
- procedure, public :: urbantv_init ! Initialize urban time varying stream
- procedure, public :: urbantv_interp ! Interpolate urban time varying stream
-
- end type urbantv_type
-
- !-----------------------------------------------------------------------
- character(15), private :: stream_var_name(isturb_MIN:isturb_MAX)
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
-
-contains
-
- !-----------------------------------------------------------------------
- subroutine Init(this, bounds, NLFilename)
- !
- ! Allocate module variables and data structures
- !
- ! !USES:
- use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- use histFileMod , only : hist_addfld1d
- !
- ! !ARGUMENTS:
- class(urbantv_type) :: this
- type(bounds_type) , intent(in) :: bounds
- character(len=*) , intent(in) :: NLFilename ! Namelist filename
- !
- ! !LOCAL VARIABLES:
- integer :: begl, endl
- !---------------------------------------------------------------------
-
- begl = bounds%begl; endl = bounds%endl
-
- ! Allocate urbantv data structure
-
- allocate(this%t_building_max (begl:endl)) ; this%t_building_max (:) = nan
-
- call this%urbantv_init(bounds, NLFilename)
- call this%urbantv_interp(bounds)
-
- ! Add history fields
- call hist_addfld1d (fname='TBUILD_MAX', units='K', &
- avgflag='A', long_name='prescribed maximum interior building temperature', &
- ptr_lunit=this%t_building_max, default='inactive', set_nourb=spval, &
- l2g_scale_type='unity')
-
-
- end subroutine Init
-
- !-----------------------------------------------------------------------
-
- !-----------------------------------------------------------------------
- subroutine urbantv_init(this, bounds, NLFilename)
- !
- ! !DESCRIPTION:
- ! Initialize data stream information for urban time varying data
- !
- ! !USES:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use clm_nlUtilsMod , only : find_nlgroup_name
- use ndepStreamMod , only : clm_domain_mct
- use spmdMod , only : masterproc, mpicom, comp_id
- use fileutils , only : getavu, relavu
- use shr_mpi_mod , only : shr_mpi_bcast
- use shr_string_mod , only : shr_string_listAppend
- use shr_strdata_mod , only : shr_strdata_create, shr_strdata_print
- use domainMod , only : ldomain
- use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- use landunit_varcon , only : isturb_TBD, isturb_HD, isturb_MD
- use lnd_set_decomp_and_domain , only : gsmap_global
- !
- ! !ARGUMENTS:
- implicit none
- class(urbantv_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! !LOCAL VARIABLES:
- integer :: begl, endl ! landunits
- integer :: ifield ! field index
- integer :: stream_year_first_urbantv ! first year in urban tv stream to use
- integer :: stream_year_last_urbantv ! last year in urban tv stream to use
- integer :: model_year_align_urbantv ! align stream_year_first_urbantv
- ! with this model year
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldFileName_urbantv ! urban tv streams filename
- character(len=CL) :: urbantvmapalgo = 'nn' ! mapping alogrithm for urban ac
- character(len=CL) :: urbantv_tintalgo = 'linear' ! time interpolation alogrithm
- character(len=CL) :: fldList ! field string
- character(*), parameter :: urbantvString = "tbuildmax_" ! base string for field string
- character(*), parameter :: subName = "('urbantv_init')"
- character(*), parameter :: F00 = "('(urbantv_init) ',4a)"
- !-----------------------------------------------------------------------
- namelist /urbantv_streams/ &
- stream_year_first_urbantv, &
- stream_year_last_urbantv, &
- model_year_align_urbantv, &
- urbantvmapalgo, &
- stream_fldFileName_urbantv, &
- urbantv_tintalgo
- !-----------------------------------------------------------------------
-
- begl = bounds%begl; endl = bounds%endl
-
- ! Default values for namelist
- stream_year_first_urbantv = 1 ! first year in stream to use
- stream_year_last_urbantv = 1 ! last year in stream to use
- model_year_align_urbantv = 1 ! align stream_year_first_urbantv with this model year
- stream_fldFileName_urbantv = ' '
-
- ! Read urbantv_streams namelist
- if (masterproc) then
- nu_nml = getavu()
- open( nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call find_nlgroup_name(nu_nml, 'urbantv_streams', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=urbantv_streams,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(msg='ERROR reading urbantv_streams namelist'//errMsg(sourcefile, __LINE__))
- end if
- end if
- close(nu_nml)
- call relavu( nu_nml )
- endif
-
- call shr_mpi_bcast(stream_year_first_urbantv, mpicom)
- call shr_mpi_bcast(stream_year_last_urbantv, mpicom)
- call shr_mpi_bcast(model_year_align_urbantv, mpicom)
- call shr_mpi_bcast(stream_fldFileName_urbantv, mpicom)
- call shr_mpi_bcast(urbantv_tintalgo, mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) 'urbantv_streams settings:'
- write(iulog,*) ' stream_year_first_urbantv = ',stream_year_first_urbantv
- write(iulog,*) ' stream_year_last_urbantv = ',stream_year_last_urbantv
- write(iulog,*) ' model_year_align_urbantv = ',model_year_align_urbantv
- write(iulog,*) ' stream_fldFileName_urbantv = ',stream_fldFileName_urbantv
- write(iulog,*) ' urbantv_tintalgo = ',urbantv_tintalgo
- write(iulog,*) ' '
- endif
-
- call clm_domain_mct (bounds, dom_clm)
-
- ! create the field list for these urbantv fields...use in shr_strdata_create
- stream_var_name(:) = "NOT_SET"
- stream_var_name(isturb_TBD) = urbantvString//"TBD"
- stream_var_name(isturb_HD) = urbantvString//"HD"
- stream_var_name(isturb_MD) = urbantvString//"MD"
- fldList = ""
- do ifield = isturb_MIN, isturb_MAX
- call shr_string_listAppend( fldList, stream_var_name(ifield) )
- end do
-
- call shr_strdata_create(this%sdat_urbantv,name="clmurbantv", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=stream_year_first_urbantv, &
- yearLast=stream_year_last_urbantv, &
- yearAlign=model_year_align_urbantv, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_urbantv), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domAreaName='area', &
- domMaskName='LANDMASK', &
- filePath='', &
- filename=(/trim(stream_fldFileName_urbantv)/) , &
- fldListFile=fldList, &
- fldListModel=fldList, &
- fillalgo='none', &
- mapalgo=urbantvmapalgo, &
- calendar=get_calendar(), &
- tintalgo=urbantv_tintalgo, &
- taxmode='extend' )
-
- if (masterproc) then
- call shr_strdata_print(this%sdat_urbantv,'urban time varying data')
- endif
-
-
- end subroutine urbantv_init
-
- !-----------------------------------------------------------------------
- subroutine urbantv_interp(this, bounds)
- !
- ! !DESCRIPTION:
- ! Interpolate data stream information for urban time varying data.
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- use spmdMod , only : mpicom
- use shr_strdata_mod , only : shr_strdata_advance
- use clm_instur , only : urban_valid
- !
- ! !ARGUMENTS:
- class(urbantv_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- logical :: found
- integer :: l, glun, ig, g, ip
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- integer :: lindx ! landunit index
- integer :: gindx ! gridcell index
- !-----------------------------------------------------------------------
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(this%sdat_urbantv, mcdate, sec, mpicom, 'urbantvdyn')
-
- do l = bounds%begl,bounds%endl
- if (lun%urbpoi(l)) then
- glun = lun%gridcell(l)
- ip = mct_aVect_indexRA(this%sdat_urbantv%avs(1),trim(stream_var_name(lun%itype(l))))
- !
- ! Determine vector index corresponding to glun
- !
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- if (g == glun) exit
- end do
-
- this%t_building_max(l) = this%sdat_urbantv%avs(1)%rAttr(ip,ig)
- else
- this%t_building_max(l) = spval
- end if
- end do
-
- found = .false.
- do l = bounds%begl,bounds%endl
- if (lun%urbpoi(l)) then
- glun = lun%gridcell(l)
- !
- ! Determine vector index corresponding to glun
- !
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- if (g == glun) exit
- end do
-
- if ( .not. urban_valid(g) .or. (this%t_building_max(l) <= 0._r8)) then
- found = .true.
- gindx = g
- lindx = l
- exit
- end if
- end if
- end do
- if ( found ) then
- write(iulog,*)'ERROR: no valid urban data for g= ',gindx
- write(iulog,*)'landunit type: ',lun%itype(lindx)
- write(iulog,*)'urban_valid: ',urban_valid(gindx)
- write(iulog,*)'t_building_max: ',this%t_building_max(lindx)
- call endrun(subgrid_index=lindx, subgrid_level=subgrid_level_landunit, &
- msg=errmsg(sourcefile, __LINE__))
- end if
-
-
- end subroutine urbantv_interp
-
- !-----------------------------------------------------------------------
-
-end module UrbanTimeVarType
diff --git a/src/cpl/mct/ch4FInundatedStreamType.F90 b/src/cpl/mct/ch4FInundatedStreamType.F90
deleted file mode 100644
index 3c26f4d109..0000000000
--- a/src/cpl/mct/ch4FInundatedStreamType.F90
+++ /dev/null
@@ -1,389 +0,0 @@
-module ch4FInundatedStreamType
-
-#include "shr_assert.h"
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Contains methods for reading in finundated streams file for methane code.
- !
- ! !USES
- use shr_kind_mod , only: r8 => shr_kind_r8, CL => shr_kind_cl
- use spmdMod , only: mpicom, masterproc
- use clm_varctl , only: iulog, inst_name
- use abortutils , only: endrun
- use decompMod , only: bounds_type
- use ch4varcon , only: finundation_mtd
-
- ! !PUBLIC TYPES:
- implicit none
- private
- save
-
- type, public :: ch4finundatedstream_type
- real(r8), pointer, private :: zwt0_gdc (:) ! col coefficient for determining finundated (m)
- real(r8), pointer, private :: f0_gdc (:) ! col maximum inundated fraction for a gridcell (for methane code)
- real(r8), pointer, private :: p3_gdc (:) ! col coefficient for determining finundated (m)
- real(r8), pointer, private :: fws_slope_gdc (:) ! col slope in fws = slope * tws + intercept (A coefficient)
- real(r8), pointer, private :: fws_intercept_gdc (:) ! col slope in fws = slope * tws + intercept (B coefficient)
- contains
-
- ! !PUBLIC MEMBER FUNCTIONS:
- procedure, public :: Init ! Initialize and read data in
- procedure, public :: CalcFinundated ! Calculate finundated based on input streams
- procedure, public :: UseStreams ! If streams will be used
-
- ! !PRIVATE MEMBER FUNCTIONS:
- procedure, private :: InitAllocate ! Allocate data
-
- end type ch4finundatedstream_type
-
-
- ! ! PRIVATE DATA:
-
- type, private :: streamcontrol_type
- character(len=CL) :: stream_fldFileName_ch4finundated ! Filename
- character(len=CL) :: ch4finundatedmapalgo ! map algo
- character(len=CL) :: fldList ! List of fields to read
- contains
- procedure, private :: ReadNML ! Read in namelist
- end type streamcontrol_type
-
- type(streamcontrol_type), private :: control ! Stream control data
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
- !==============================================================================
-
-contains
-
- !==============================================================================
-
- subroutine Init(this, bounds, NLFilename)
- !
- ! Initialize the ch4 finundated stream object
- !
- ! Uses:
- use clm_time_manager , only : get_calendar, get_curr_date
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use shr_nl_mod , only : shr_nl_find_group_name
- use shr_mpi_mod , only : shr_mpi_bcast
- use ndepStreamMod , only : clm_domain_mct
- use domainMod , only : ldomain
- use decompMod , only : bounds_type
- use mct_mod , only : mct_ggrid, mct_avect_indexra
- use shr_strdata_mod , only : shr_strdata_type, shr_strdata_create
- use shr_strdata_mod , only : shr_strdata_print, shr_strdata_advance
- use spmdMod , only : comp_id, iam
- use ch4varcon , only : finundation_mtd_h2osfc
- use ch4varcon , only : finundation_mtd_ZWT_inversion, finundation_mtd_TWS_inversion
- use lnd_set_decomp_and_domain , only : gsmap_global
- !
- ! arguments
- implicit none
- class(ch4finundatedstream_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! local variables
- integer :: ig, g ! Indices
- type(mct_ggrid) :: dom_clm ! domain information
- type(shr_strdata_type) :: sdat ! input data stream
- integer :: index_ZWT0 = 0 ! Index of ZWT0 field
- integer :: index_F0 = 0 ! Index of F0 field
- integer :: index_P3 = 0 ! Index of P3 field
- integer :: index_FWS_TWS_A = 0 ! Index of FWS_TWS_A field
- integer :: index_FWS_TWS_B = 0 ! Index of FWS_TWS_B field
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- character(len=*), parameter :: stream_name = 'ch4finundated'
- character(*), parameter :: subName = "('ch4finundatedstream::Init')"
- !-----------------------------------------------------------------------
- if ( finundation_mtd /= finundation_mtd_h2osfc )then
- call this%InitAllocate( bounds )
- call control%ReadNML( bounds, NLFileName )
-
- if ( this%useStreams() )then
- call clm_domain_mct (bounds, dom_clm)
-
- call shr_strdata_create(sdat,name=stream_name, &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=1996, &
- yearLast=1996, &
- yearAlign=1, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(control%stream_fldFileName_ch4finundated), &
- domTvarName='time', &
- domXvarName='LONGXY' , &
- domYvarName='LATIXY' , &
- domAreaName='AREA', &
- domMaskName='LANDMASK', &
- filePath='', &
- filename=(/trim(control%stream_fldFileName_ch4finundated)/), &
- fldListFile=control%fldList, &
- fldListModel=control%fldList, &
- fillalgo='none', &
- mapalgo=control%ch4finundatedmapalgo, &
- calendar=get_calendar(), &
- taxmode='extend' )
-
- if (masterproc) then
- call shr_strdata_print(sdat,'CLM '//stream_name//' data')
- endif
-
- if( finundation_mtd == finundation_mtd_ZWT_inversion )then
- index_ZWT0 = mct_avect_indexra(sdat%avs(1),'ZWT0')
- index_F0 = mct_avect_indexra(sdat%avs(1),'F0' )
- index_P3 = mct_avect_indexra(sdat%avs(1),'P3' )
- else if( finundation_mtd == finundation_mtd_TWS_inversion )then
- index_FWS_TWS_A = mct_avect_indexra(sdat%avs(1),'FWS_TWS_A')
- index_FWS_TWS_B = mct_avect_indexra(sdat%avs(1),'FWS_TWS_B')
- end if
-
-
- ! Explicitly set current date to a hardcoded constant value. Otherwise
- ! using the real date can cause roundoff differences that are
- ! detrected as issues with exact restart. EBK M05/20/2017
- !call get_curr_date(year, mon, day, sec)
- year = 1996
- mon = 12
- day = 31
- sec = 0
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(sdat, mcdate, sec, mpicom, 'ch4finundated')
-
- ! Get the data
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- if ( index_ZWT0 > 0 )then
- this%zwt0_gdc(g) = sdat%avs(1)%rAttr(index_ZWT0,ig)
- end if
- if ( index_F0 > 0 )then
- this%f0_gdc(g) = sdat%avs(1)%rAttr(index_F0,ig)
- end if
- if ( index_P3 > 0 )then
- this%p3_gdc(g) = sdat%avs(1)%rAttr(index_P3,ig)
- end if
- if ( index_FWS_TWS_A > 0 )then
- this%fws_slope_gdc(g) = sdat%avs(1)%rAttr(index_FWS_TWS_A,ig)
- end if
- if ( index_FWS_TWS_B > 0 )then
- this%fws_intercept_gdc(g) = sdat%avs(1)%rAttr(index_FWS_TWS_B,ig)
- end if
- end do
- end if
- end if
-
- end subroutine Init
-
- !-----------------------------------------------------------------------
- logical function UseStreams(this)
- !
- ! !DESCRIPTION:
- ! Return true if
- !
- ! !USES:
- !
- ! !ARGUMENTS:
- implicit none
- class(ch4finundatedstream_type) :: this
- !
- ! !LOCAL VARIABLES:
- if ( trim(control%stream_fldFileName_ch4finundated) == '' )then
- UseStreams = .false.
- else
- UseStreams = .true.
- end if
- end function UseStreams
-
- !-----------------------------------------------------------------------
- subroutine InitAllocate(this, bounds)
- !
- ! !DESCRIPTION:
- ! Allocate module variables and data structures
- !
- ! !USES:
- use shr_infnan_mod, only: nan => shr_infnan_nan, assignment(=)
- use ch4varcon , only: finundation_mtd_ZWT_inversion, finundation_mtd_TWS_inversion
- !
- ! !ARGUMENTS:
- implicit none
- class(ch4finundatedstream_type) :: this
- type(bounds_type), intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: begc, endc
- integer :: begg, endg
- !---------------------------------------------------------------------
-
- begc = bounds%begc; endc = bounds%endc
- begg = bounds%begg; endg = bounds%endg
-
- if( finundation_mtd == finundation_mtd_ZWT_inversion )then
- allocate(this%zwt0_gdc (begg:endg)) ; this%zwt0_gdc (:) = nan
- allocate(this%f0_gdc (begg:endg)) ; this%f0_gdc (:) = nan
- allocate(this%p3_gdc (begg:endg)) ; this%p3_gdc (:) = nan
- else if( finundation_mtd == finundation_mtd_TWS_inversion )then
- allocate(this%fws_slope_gdc (begg:endg)) ; this%fws_slope_gdc (:) = nan
- allocate(this%fws_intercept_gdc(begg:endg)) ; this%fws_intercept_gdc(:) = nan
- end if
-
- end subroutine InitAllocate
-
- !-----------------------------------------------------------------------
- subroutine CalcFinundated(this, bounds, num_soilc, filter_soilc, soilhydrology_inst, &
- waterdiagnosticbulk_inst, qflx_surf_lag_col, finundated )
- !
- ! !DESCRIPTION:
- !
- ! Calculate finundated according to the appropriate methodology
- !
- ! !USES:
- use ColumnType , only : col
- use ch4varcon , only : finundation_mtd_h2osfc, finundation_mtd_ZWT_inversion
- use ch4varcon , only : finundation_mtd_TWS_inversion
- use clm_varpar , only : nlevsoi
- use SoilHydrologyType, only : soilhydrology_type
- use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type
- !
- ! !ARGUMENTS:
- implicit none
- class(ch4finundatedstream_type) :: this
- type(bounds_type) , intent(in) :: bounds
- integer , intent(in) :: num_soilc ! number of column soil points in column filter
- integer , intent(in) :: filter_soilc(:) ! column filter for soil points
- type(soilhydrology_type) , intent(in) :: soilhydrology_inst
- type(waterdiagnosticbulk_type) , intent(in) :: waterdiagnosticbulk_inst
- real(r8) , intent(in) :: qflx_surf_lag_col(bounds%begc:) !time-lagged surface runoff (mm H2O /s)
- real(r8) , intent(inout) :: finundated(bounds%begc:) ! fractional inundated area in soil column (excluding dedicated wetland columns)
- !
- ! !LOCAL VARIABLES:
- integer :: g, c, fc ! Indices
- real(r8) :: zwt_actual ! Total water storage (ZWT) to use either perched or total depending on conditions
-
- SHR_ASSERT_ALL_FL((ubound(qflx_surf_lag_col) == (/bounds%endc/)), sourcefile, __LINE__)
- SHR_ASSERT_ALL_FL((ubound(finundated) == (/bounds%endc/)), sourcefile, __LINE__)
-
- associate( &
- z => col%z , & ! Input: [real(r8) (:,:) ] layer depth (m) (-nlevsno+1:nlevsoi)
- zwt => soilhydrology_inst%zwt_col , & ! Input: [real(r8) (:) ] water table depth (m)
- zwt_perched => soilhydrology_inst%zwt_perched_col , & ! Input: [real(r8) (:) ] perched water table depth (m)
- tws => waterdiagnosticbulk_inst%tws_grc , & ! Input: [real(r8) (:) ] total water storage (kg m-2)
- frac_h2osfc => waterdiagnosticbulk_inst%frac_h2osfc_col & ! Input: [real(r8) (:) ] fraction of ground covered by surface water (0 to 1)
- )
-
- ! Calculate finundated
- do fc = 1, num_soilc
- c = filter_soilc(fc)
- g = col%gridcell(c)
- select case( finundation_mtd )
- case ( finundation_mtd_h2osfc )
- finundated(c) = frac_h2osfc(c)
- case ( finundation_mtd_ZWT_inversion )
- if (this%zwt0_gdc(g) > 0._r8) then
- if (zwt_perched(c) < z(c,nlevsoi)-1.e-5_r8 .and. zwt_perched(c) < zwt(c)) then
- zwt_actual = zwt_perched(c)
- else
- zwt_actual = zwt(c)
- end if
- finundated(c) = this%f0_gdc(g) * exp(-zwt_actual/this%zwt0_gdc(g)) + this%p3_gdc(g)*qflx_surf_lag_col(c)
- else
- finundated(c) = this%p3_gdc(g)*qflx_surf_lag_col(c)
- end if
- case ( finundation_mtd_TWS_inversion )
- finundated(c) = this%fws_slope_gdc(g) * tws(g) + this%fws_intercept_gdc(g)
- end select
- finundated(c) = min( 1.0_r8, max( 0.0_r8, finundated(c) ) )
- end do
- end associate
-
- end subroutine CalcFinundated
- !==============================================================================
-
- subroutine ReadNML(this, bounds, NLFilename)
- !
- ! Read the namelist data stream information.
- !
- ! Uses:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use shr_nl_mod , only : shr_nl_find_group_name
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use shr_mpi_mod , only : shr_mpi_bcast
- use fileutils , only : getavu, relavu
- use ch4varcon , only : finundation_mtd_ZWT_inversion, finundation_mtd_TWS_inversion
- !
- ! arguments
- implicit none
- class(streamcontrol_type) :: this
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! local variables
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- character(len=CL) :: stream_fldFileName_ch4finundated = ' '
- character(len=CL) :: ch4finundatedmapalgo = 'bilinear'
- character(len=*), parameter :: namelist_name = 'ch4finundated' ! MUST agree with name in namelist and read
- character(len=*), parameter :: shr_strdata_unset = 'NOT_SET'
- character(len=*), parameter :: subName = "('ch4finundated::ReadNML')"
- character(len=*), parameter :: F00 = "('(ch4finundated_readnml) ',4a)"
- !-----------------------------------------------------------------------
-
- namelist /ch4finundated/ & ! MUST agree with namelist_name above
- ch4finundatedmapalgo, stream_fldFileName_ch4finundated
-
- ! Default values for namelist
-
- ! Read ch4finundated namelist
- if (masterproc) then
- nu_nml = getavu()
- open( nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call shr_nl_find_group_name(nu_nml, namelist_name, status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=ch4finundated,iostat=nml_error) ! MUST agree with namelist_name above
- if (nml_error /= 0) then
- call endrun(msg=' ERROR reading '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__))
- end if
- else
- call endrun(msg=' ERROR finding '//namelist_name//' namelist'//errMsg(sourcefile, __LINE__))
- end if
- close(nu_nml)
- call relavu( nu_nml )
- endif
-
- call shr_mpi_bcast(stream_fldFileName_ch4finundated, mpicom)
- call shr_mpi_bcast(ch4finundatedmapalgo , mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) namelist_name, ' stream settings:'
- write(iulog,*) ' stream_fldFileName_ch4finundated = ',stream_fldFileName_ch4finundated
- write(iulog,*) ' ch4finundatedmapalgo = ',ch4finundatedmapalgo
- write(iulog,*) ' '
- endif
- this%stream_fldFileName_ch4finundated = stream_fldFileName_ch4finundated
- this%ch4finundatedmapalgo = ch4finundatedmapalgo
- if ( finundation_mtd == finundation_mtd_ZWT_inversion )then
- this%fldList = "ZWT0:F0:P3"
- else if ( finundation_mtd == finundation_mtd_TWS_inversion )then
- this%fldList = "FWS_TWS_A:FWS_TWS_B"
- else
- call endrun(msg=' ERROR do NOT know what list of variables to read for this finundation_mtd type'// &
- errMsg(sourcefile, __LINE__))
- end if
-
- end subroutine ReadNML
-
-end module ch4FInundatedStreamType
diff --git a/src/cpl/mct/clm_cpl_indices.F90 b/src/cpl/mct/clm_cpl_indices.F90
deleted file mode 100644
index 09ed89e92d..0000000000
--- a/src/cpl/mct/clm_cpl_indices.F90
+++ /dev/null
@@ -1,330 +0,0 @@
-module clm_cpl_indices
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Module containing the indices for the fields passed between CLM and
- ! the driver. Includes the River Transport Model fields (RTM) and the
- ! fields needed by the land-ice component (sno).
- !
- ! !USES:
-
- use shr_sys_mod, only : shr_sys_abort
- implicit none
-
- SAVE
- private ! By default make data private
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: clm_cpl_indices_set ! Set the coupler indices
- !
- ! !PUBLIC DATA MEMBERS:
- !
- integer , public :: glc_nec ! number of elevation classes for glacier_mec landunits
- ! (from coupler) - must equal maxpatch_glc from namelist
-
- ! lnd -> drv (required)
-
- integer, public ::index_l2x_Flrl_rofsur ! lnd->rtm input liquid surface fluxes
- integer, public ::index_l2x_Flrl_rofgwl ! lnd->rtm input liquid gwl fluxes
- integer, public ::index_l2x_Flrl_rofsub ! lnd->rtm input liquid subsurface fluxes
- integer, public ::index_l2x_Flrl_rofi ! lnd->rtm input frozen fluxes
- integer, public ::index_l2x_Flrl_irrig ! irrigation withdrawal
-
- integer, public ::index_l2x_Sl_t ! temperature
- integer, public ::index_l2x_Sl_tref ! 2m reference temperature
- integer, public ::index_l2x_Sl_qref ! 2m reference specific humidity
- integer, public ::index_l2x_Sl_avsdr ! albedo: direct , visible
- integer, public ::index_l2x_Sl_anidr ! albedo: direct , near-ir
- integer, public ::index_l2x_Sl_avsdf ! albedo: diffuse, visible
- integer, public ::index_l2x_Sl_anidf ! albedo: diffuse, near-ir
- integer, public ::index_l2x_Sl_snowh ! snow height
- integer, public ::index_l2x_Sl_u10 ! 10m wind
- integer, public ::index_l2x_Sl_ddvel ! dry deposition velocities (optional)
- integer, public ::index_l2x_Sl_fv ! friction velocity
- integer, public ::index_l2x_Sl_ram1 ! aerodynamical resistance
- integer, public ::index_l2x_Sl_soilw ! volumetric soil water
- integer, public ::index_l2x_Fall_taux ! wind stress, zonal
- integer, public ::index_l2x_Fall_tauy ! wind stress, meridional
- integer, public ::index_l2x_Fall_lat ! latent heat flux
- integer, public ::index_l2x_Fall_sen ! sensible heat flux
- integer, public ::index_l2x_Fall_lwup ! upward longwave heat flux
- integer, public ::index_l2x_Fall_evap ! evaporation water flux
- integer, public ::index_l2x_Fall_swnet ! heat flux shortwave net
- integer, public ::index_l2x_Fall_fco2_lnd ! co2 flux **For testing set to 0
- integer, public ::index_l2x_Fall_flxdst1 ! dust flux size bin 1
- integer, public ::index_l2x_Fall_flxdst2 ! dust flux size bin 2
- integer, public ::index_l2x_Fall_flxdst3 ! dust flux size bin 3
- integer, public ::index_l2x_Fall_flxdst4 ! dust flux size bin 4
- integer, public ::index_l2x_Fall_flxvoc ! MEGAN fluxes
- integer, public ::index_l2x_Fall_flxfire ! Fire fluxes
- integer, public ::index_l2x_Sl_ztopfire ! Top of fire emissions (m)
-
- ! In the following, index 0 is bare land, other indices are glc elevation classes
- integer, allocatable, public ::index_l2x_Sl_tsrf(:) ! glc MEC temperature
- integer, allocatable, public ::index_l2x_Sl_topo(:) ! glc MEC topo height
- integer, allocatable, public ::index_l2x_Flgl_qice(:) ! glc MEC ice flux
-
- integer, public ::index_x2l_Sa_methane
- integer, public ::index_l2x_Fall_methane
-
- integer, public :: nflds_l2x = 0
-
- ! drv -> lnd (required)
-
- integer, public ::index_x2l_Sa_z ! bottom atm level height
- integer, public ::index_x2l_Sa_topo ! atm surface height (m)
- integer, public ::index_x2l_Sa_u ! bottom atm level zon wind
- integer, public ::index_x2l_Sa_v ! bottom atm level mer wind
- integer, public ::index_x2l_Sa_ptem ! bottom atm level pot temp
- integer, public ::index_x2l_Sa_shum ! bottom atm level spec hum
- integer, public ::index_x2l_Sa_pbot ! bottom atm level pressure
- integer, public ::index_x2l_Sa_tbot ! bottom atm level temp
- integer, public ::index_x2l_Faxa_lwdn ! downward lw heat flux
- integer, public ::index_x2l_Faxa_rainc ! prec: liquid "convective"
- integer, public ::index_x2l_Faxa_rainl ! prec: liquid "large scale"
- integer, public ::index_x2l_Faxa_snowc ! prec: frozen "convective"
- integer, public ::index_x2l_Faxa_snowl ! prec: frozen "large scale"
- integer, public ::index_x2l_Faxa_swndr ! sw: nir direct downward
- integer, public ::index_x2l_Faxa_swvdr ! sw: vis direct downward
- integer, public ::index_x2l_Faxa_swndf ! sw: nir diffuse downward
- integer, public ::index_x2l_Faxa_swvdf ! sw: vis diffuse downward
- integer, public ::index_x2l_Sa_co2prog ! bottom atm level prognostic co2
- integer, public ::index_x2l_Sa_co2diag ! bottom atm level diagnostic co2
- integer, public ::index_x2l_Faxa_bcphidry ! flux: Black Carbon hydrophilic dry deposition
- integer, public ::index_x2l_Faxa_bcphodry ! flux: Black Carbon hydrophobic dry deposition
- integer, public ::index_x2l_Faxa_bcphiwet ! flux: Black Carbon hydrophilic wet deposition
- integer, public ::index_x2l_Faxa_ocphidry ! flux: Organic Carbon hydrophilic dry deposition
- integer, public ::index_x2l_Faxa_ocphodry ! flux: Organic Carbon hydrophobic dry deposition
- integer, public ::index_x2l_Faxa_ocphiwet ! flux: Organic Carbon hydrophilic dry deposition
- integer, public ::index_x2l_Faxa_dstwet1 ! flux: Size 1 dust -- wet deposition
- integer, public ::index_x2l_Faxa_dstwet2 ! flux: Size 2 dust -- wet deposition
- integer, public ::index_x2l_Faxa_dstwet3 ! flux: Size 3 dust -- wet deposition
- integer, public ::index_x2l_Faxa_dstwet4 ! flux: Size 4 dust -- wet deposition
- integer, public ::index_x2l_Faxa_dstdry1 ! flux: Size 1 dust -- dry deposition
- integer, public ::index_x2l_Faxa_dstdry2 ! flux: Size 2 dust -- dry deposition
- integer, public ::index_x2l_Faxa_dstdry3 ! flux: Size 3 dust -- dry deposition
- integer, public ::index_x2l_Faxa_dstdry4 ! flux: Size 4 dust -- dry deposition
-
- integer, public ::index_x2l_Faxa_nhx ! flux nhx from atm
- integer, public ::index_x2l_Faxa_noy ! flux noy from atm
-
- integer, public ::index_x2l_Flrr_flood ! rtm->lnd rof flood flux
- integer, public ::index_x2l_Flrr_volr ! rtm->lnd rof volr total volume
- integer, public ::index_x2l_Flrr_volrmch ! rtm->lnd rof volr main channel volume
-
- ! In the following, index 0 is bare land, other indices are glc elevation classes
- integer, allocatable, public ::index_x2l_Sg_ice_covered(:) ! Fraction of glacier from glc model
- integer, allocatable, public ::index_x2l_Sg_topo(:) ! Topo height from glc model
- integer, allocatable, public ::index_x2l_Flgg_hflx(:) ! Heat flux from glc model
-
- integer, public ::index_x2l_Sg_icemask
- integer, public ::index_x2l_Sg_icemask_coupled_fluxes
-
- integer, public :: nflds_x2l = 0
-
- !-----------------------------------------------------------------------
-
-contains
-
- !-----------------------------------------------------------------------
- subroutine clm_cpl_indices_set( )
- !
- ! !DESCRIPTION:
- ! Set the coupler indices needed by the land model coupler
- ! interface.
- !
- ! !USES:
- use seq_flds_mod , only: seq_flds_x2l_fields, seq_flds_l2x_fields
- use mct_mod , only: mct_aVect, mct_aVect_init, mct_avect_indexra
- use mct_mod , only: mct_aVect_clean, mct_avect_nRattr
- use shr_drydep_mod , only: drydep_fields_token, n_drydep
- use shr_megan_mod , only: shr_megan_fields_token, shr_megan_mechcomps_n
- use shr_fire_emis_mod,only: shr_fire_emis_fields_token, shr_fire_emis_ztop_token, shr_fire_emis_mechcomps_n
- use clm_varctl , only: ndep_from_cpl
- use glc_elevclass_mod, only: glc_get_num_elevation_classes, glc_elevclass_as_string
- !
- ! !ARGUMENTS:
- implicit none
- !
- ! !REVISION HISTORY:
- ! Author: Mariana Vertenstein
- ! 01/2011, Erik Kluzek: Added protex headers
- !
- ! !LOCAL VARIABLES:
- type(mct_aVect) :: l2x ! temporary, land to coupler
- type(mct_aVect) :: x2l ! temporary, coupler to land
- integer :: num
- character(len=:), allocatable :: nec_str ! string version of glc elev. class number
- character(len=64) :: name
- character(len=32) :: subname = 'clm_cpl_indices_set' ! subroutine name
- !-----------------------------------------------------------------------
-
- ! Determine attribute vector indices
-
- ! create temporary attribute vectors
- call mct_aVect_init(x2l, rList=seq_flds_x2l_fields, lsize=1)
- nflds_x2l = mct_avect_nRattr(x2l)
-
- call mct_aVect_init(l2x, rList=seq_flds_l2x_fields, lsize=1)
- nflds_l2x = mct_avect_nRattr(l2x)
-
- !-------------------------------------------------------------
- ! clm -> drv
- !-------------------------------------------------------------
-
- index_l2x_Flrl_rofsur = mct_avect_indexra(l2x,'Flrl_rofsur')
- index_l2x_Flrl_rofgwl = mct_avect_indexra(l2x,'Flrl_rofgwl')
- index_l2x_Flrl_rofsub = mct_avect_indexra(l2x,'Flrl_rofsub')
- index_l2x_Flrl_rofi = mct_avect_indexra(l2x,'Flrl_rofi')
- index_l2x_Flrl_irrig = mct_avect_indexra(l2x,'Flrl_irrig')
-
- index_l2x_Sl_t = mct_avect_indexra(l2x,'Sl_t')
- index_l2x_Sl_snowh = mct_avect_indexra(l2x,'Sl_snowh')
- index_l2x_Sl_avsdr = mct_avect_indexra(l2x,'Sl_avsdr')
- index_l2x_Sl_anidr = mct_avect_indexra(l2x,'Sl_anidr')
- index_l2x_Sl_avsdf = mct_avect_indexra(l2x,'Sl_avsdf')
- index_l2x_Sl_anidf = mct_avect_indexra(l2x,'Sl_anidf')
- index_l2x_Sl_tref = mct_avect_indexra(l2x,'Sl_tref')
- index_l2x_Sl_qref = mct_avect_indexra(l2x,'Sl_qref')
- index_l2x_Sl_u10 = mct_avect_indexra(l2x,'Sl_u10')
- index_l2x_Sl_ram1 = mct_avect_indexra(l2x,'Sl_ram1')
- index_l2x_Sl_fv = mct_avect_indexra(l2x,'Sl_fv')
- index_l2x_Sl_soilw = mct_avect_indexra(l2x,'Sl_soilw',perrwith='quiet')
-
- if ( n_drydep>0 )then
- index_l2x_Sl_ddvel = mct_avect_indexra(l2x, trim(drydep_fields_token))
- else
- index_l2x_Sl_ddvel = 0
- end if
-
- index_l2x_Fall_taux = mct_avect_indexra(l2x,'Fall_taux')
- index_l2x_Fall_tauy = mct_avect_indexra(l2x,'Fall_tauy')
- index_l2x_Fall_lat = mct_avect_indexra(l2x,'Fall_lat')
- index_l2x_Fall_sen = mct_avect_indexra(l2x,'Fall_sen')
- index_l2x_Fall_lwup = mct_avect_indexra(l2x,'Fall_lwup')
- index_l2x_Fall_evap = mct_avect_indexra(l2x,'Fall_evap')
- index_l2x_Fall_swnet = mct_avect_indexra(l2x,'Fall_swnet')
- index_l2x_Fall_flxdst1 = mct_avect_indexra(l2x,'Fall_flxdst1')
- index_l2x_Fall_flxdst2 = mct_avect_indexra(l2x,'Fall_flxdst2')
- index_l2x_Fall_flxdst3 = mct_avect_indexra(l2x,'Fall_flxdst3')
- index_l2x_Fall_flxdst4 = mct_avect_indexra(l2x,'Fall_flxdst4')
-
- index_l2x_Fall_fco2_lnd = mct_avect_indexra(l2x,'Fall_fco2_lnd',perrwith='quiet')
-
- index_l2x_Fall_methane = mct_avect_indexra(l2x,'Fall_methane',perrWith='quiet')
-
- ! MEGAN fluxes
- if (shr_megan_mechcomps_n>0) then
- index_l2x_Fall_flxvoc = mct_avect_indexra(l2x,trim(shr_megan_fields_token))
- else
- index_l2x_Fall_flxvoc = 0
- endif
-
- ! Fire fluxes
- if (shr_fire_emis_mechcomps_n>0) then
- index_l2x_Fall_flxfire = mct_avect_indexra(l2x,trim(shr_fire_emis_fields_token))
- index_l2x_Sl_ztopfire = mct_avect_indexra(l2x,trim(shr_fire_emis_ztop_token))
- else
- index_l2x_Fall_flxfire = 0
- index_l2x_Sl_ztopfire = 0
- endif
-
- !-------------------------------------------------------------
- ! drv -> clm
- !-------------------------------------------------------------
-
- index_x2l_Sa_z = mct_avect_indexra(x2l,'Sa_z')
- index_x2l_Sa_topo = mct_avect_indexra(x2l,'Sa_topo')
- index_x2l_Sa_u = mct_avect_indexra(x2l,'Sa_u')
- index_x2l_Sa_v = mct_avect_indexra(x2l,'Sa_v')
- index_x2l_Sa_ptem = mct_avect_indexra(x2l,'Sa_ptem')
- index_x2l_Sa_pbot = mct_avect_indexra(x2l,'Sa_pbot')
- index_x2l_Sa_tbot = mct_avect_indexra(x2l,'Sa_tbot')
- index_x2l_Sa_shum = mct_avect_indexra(x2l,'Sa_shum')
- index_x2l_Sa_co2prog = mct_avect_indexra(x2l,'Sa_co2prog',perrwith='quiet')
- index_x2l_Sa_co2diag = mct_avect_indexra(x2l,'Sa_co2diag',perrwith='quiet')
-
- index_x2l_Sa_methane = mct_avect_indexra(x2l,'Sa_methane',perrWith='quiet')
-
- index_x2l_Flrr_volr = mct_avect_indexra(x2l,'Flrr_volr')
- index_x2l_Flrr_volrmch = mct_avect_indexra(x2l,'Flrr_volrmch')
-
- index_x2l_Faxa_lwdn = mct_avect_indexra(x2l,'Faxa_lwdn')
- index_x2l_Faxa_rainc = mct_avect_indexra(x2l,'Faxa_rainc')
- index_x2l_Faxa_rainl = mct_avect_indexra(x2l,'Faxa_rainl')
- index_x2l_Faxa_snowc = mct_avect_indexra(x2l,'Faxa_snowc')
- index_x2l_Faxa_snowl = mct_avect_indexra(x2l,'Faxa_snowl')
- index_x2l_Faxa_swndr = mct_avect_indexra(x2l,'Faxa_swndr')
- index_x2l_Faxa_swvdr = mct_avect_indexra(x2l,'Faxa_swvdr')
- index_x2l_Faxa_swndf = mct_avect_indexra(x2l,'Faxa_swndf')
- index_x2l_Faxa_swvdf = mct_avect_indexra(x2l,'Faxa_swvdf')
- index_x2l_Faxa_bcphidry = mct_avect_indexra(x2l,'Faxa_bcphidry')
- index_x2l_Faxa_bcphodry = mct_avect_indexra(x2l,'Faxa_bcphodry')
- index_x2l_Faxa_bcphiwet = mct_avect_indexra(x2l,'Faxa_bcphiwet')
- index_x2l_Faxa_ocphidry = mct_avect_indexra(x2l,'Faxa_ocphidry')
- index_x2l_Faxa_ocphodry = mct_avect_indexra(x2l,'Faxa_ocphodry')
- index_x2l_Faxa_ocphiwet = mct_avect_indexra(x2l,'Faxa_ocphiwet')
- index_x2l_Faxa_dstdry1 = mct_avect_indexra(x2l,'Faxa_dstdry1')
- index_x2l_Faxa_dstdry2 = mct_avect_indexra(x2l,'Faxa_dstdry2')
- index_x2l_Faxa_dstdry3 = mct_avect_indexra(x2l,'Faxa_dstdry3')
- index_x2l_Faxa_dstdry4 = mct_avect_indexra(x2l,'Faxa_dstdry4')
- index_x2l_Faxa_dstwet1 = mct_avect_indexra(x2l,'Faxa_dstwet1')
- index_x2l_Faxa_dstwet2 = mct_avect_indexra(x2l,'Faxa_dstwet2')
- index_x2l_Faxa_dstwet3 = mct_avect_indexra(x2l,'Faxa_dstwet3')
- index_x2l_Faxa_dstwet4 = mct_avect_indexra(x2l,'Faxa_dstwet4')
-
- index_x2l_Faxa_nhx = mct_avect_indexra(x2l,'Faxa_nhx', perrWith='quiet')
- index_x2l_Faxa_noy = mct_avect_indexra(x2l,'Faxa_noy', perrWith='quiet')
-
- if (index_x2l_Faxa_nhx > 0 .and. index_x2l_Faxa_noy > 0) then
- ndep_from_cpl = .true.
- end if
-
- index_x2l_Flrr_flood = mct_avect_indexra(x2l,'Flrr_flood')
-
- !-------------------------------------------------------------
- ! glc coupling
- !-------------------------------------------------------------
-
- index_x2l_Sg_icemask = mct_avect_indexra(x2l,'Sg_icemask')
- index_x2l_Sg_icemask_coupled_fluxes = mct_avect_indexra(x2l,'Sg_icemask_coupled_fluxes')
-
- glc_nec = glc_get_num_elevation_classes()
- if (glc_nec < 1) then
- call shr_sys_abort('ERROR: In CLM4.5 and later, glc_nec must be at least 1.')
- end if
-
- ! Create coupling fields for all glc elevation classes (1:glc_nec) plus bare land
- ! (index 0).
- allocate(index_l2x_Sl_tsrf(0:glc_nec))
- allocate(index_l2x_Sl_topo(0:glc_nec))
- allocate(index_l2x_Flgl_qice(0:glc_nec))
- allocate(index_x2l_Sg_ice_covered(0:glc_nec))
- allocate(index_x2l_Sg_topo(0:glc_nec))
- allocate(index_x2l_Flgg_hflx(0:glc_nec))
-
- do num = 0,glc_nec
- nec_str = glc_elevclass_as_string(num)
-
- name = 'Sg_ice_covered' // nec_str
- index_x2l_Sg_ice_covered(num) = mct_avect_indexra(x2l,trim(name))
- name = 'Sg_topo' // nec_str
- index_x2l_Sg_topo(num) = mct_avect_indexra(x2l,trim(name))
- name = 'Flgg_hflx' // nec_str
- index_x2l_Flgg_hflx(num) = mct_avect_indexra(x2l,trim(name))
-
- name = 'Sl_tsrf' // nec_str
- index_l2x_Sl_tsrf(num) = mct_avect_indexra(l2x,trim(name))
- name = 'Sl_topo' // nec_str
- index_l2x_Sl_topo(num) = mct_avect_indexra(l2x,trim(name))
- name = 'Flgl_qice' // nec_str
- index_l2x_Flgl_qice(num) = mct_avect_indexra(l2x,trim(name))
- end do
-
- call mct_aVect_clean(x2l)
- call mct_aVect_clean(l2x)
-
- end subroutine clm_cpl_indices_set
-
-!=======================================================================
-
-end module clm_cpl_indices
diff --git a/src/cpl/mct/laiStreamMod.F90 b/src/cpl/mct/laiStreamMod.F90
deleted file mode 100644
index 47d25287b7..0000000000
--- a/src/cpl/mct/laiStreamMod.F90
+++ /dev/null
@@ -1,241 +0,0 @@
-module laiStreamMod
-
-#include "shr_assert.h"
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Read LAI from stream
- !
- ! !USES:
- use shr_strdata_mod , only : shr_strdata_type, shr_strdata_create
- use shr_strdata_mod , only : shr_strdata_print, shr_strdata_advance
- use shr_kind_mod , only : r8=>shr_kind_r8, CL=>shr_kind_CL, CS=>shr_kind_CS, CXX=>shr_kind_CXX
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use decompMod , only : bounds_type
- use abortutils , only : endrun
- use clm_varctl , only : iulog, inst_name
- use perf_mod , only : t_startf, t_stopf
- use spmdMod , only : masterproc, mpicom, comp_id
- use ncdio_pio
- use mct_mod
- !
- ! !PUBLIC TYPES:
- implicit none
- private
-
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: lai_init ! position datasets for LAI
- public :: lai_advance ! Advance the LAI streams (outside of a Open-MP threading loop)
- public :: lai_interp ! interpolates between two years of LAI data (when LAI streams
-
- ! !PRIVATE MEMBER DATA:
- integer, allocatable :: g_to_ig(:) ! Array matching gridcell index to data index
- type(shr_strdata_type) :: sdat_lai ! LAI input data stream
-
- character(len=*), parameter :: sourcefile = &
- __FILE__
-
-!==============================================================================
-contains
-!==============================================================================
-
- subroutine lai_init(bounds)
- !
- ! Initialize data stream information for LAI.
- !
- ! !USES:
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use shr_stream_mod , only : shr_stream_file_null
- use shr_string_mod , only : shr_string_listCreateField
- use clm_nlUtilsMod , only : find_nlgroup_name
- use ndepStreamMod , only : clm_domain_mct
- use histFileMod , only : hist_addfld1d
- use domainMod , only : ldomain
- use controlMod , only : NLFilename
- use lnd_set_decomp_and_domain , only : gsmap_global
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type), intent(in) :: bounds ! bounds
- !
- ! !LOCAL VARIABLES:
- integer :: stream_year_first_lai ! first year in Lai stream to use
- integer :: stream_year_last_lai ! last year in Lai stream to use
- integer :: model_year_align_lai ! align stream_year_first_lai with
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldFileName_lai ! lai stream filename to read
- character(len=CL) :: lai_mapalgo = 'bilinear' ! Mapping alogrithm
- character(len=CL) :: lai_tintalgo = 'linear' ! Time interpolation alogrithm
- character(len=CXX) :: fldList ! field string
- character(*), parameter :: laiString = "LAI" ! base string for field string
- integer , parameter :: numLaiFields = 16 ! number of fields to build field string
- character(*), parameter :: subName = "('laidyn_init')"
- !-----------------------------------------------------------------------
- !
- ! deal with namelist variables here in init
- !
- namelist /lai_streams/ &
- stream_year_first_lai, &
- stream_year_last_lai, &
- model_year_align_lai, &
- lai_mapalgo, &
- stream_fldFileName_lai, &
- lai_tintalgo
-
- ! Default values for namelist
- stream_year_first_lai = 1 ! first year in stream to use
- stream_year_last_lai = 1 ! last year in stream to use
- model_year_align_lai = 1 ! align stream_year_first_lai with this model year
- stream_fldFileName_lai = shr_stream_file_null
-
- ! Read lai_streams namelist
- if (masterproc) then
- open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call find_nlgroup_name(nu_nml, 'lai_streams', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=lai_streams,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(subname // ':: ERROR reading lai_streams namelist')
- end if
- else
- call endrun(subname // ':: ERROR finding lai_streams namelist')
- end if
- close(nu_nml)
- endif
- call shr_mpi_bcast(stream_year_first_lai , mpicom)
- call shr_mpi_bcast(stream_year_last_lai , mpicom)
- call shr_mpi_bcast(model_year_align_lai , mpicom)
- call shr_mpi_bcast(stream_fldFileName_lai , mpicom)
- call shr_mpi_bcast(lai_tintalgo , mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) 'lai_stream settings:'
- write(iulog,*) ' stream_year_first_lai = ',stream_year_first_lai
- write(iulog,*) ' stream_year_last_lai = ',stream_year_last_lai
- write(iulog,*) ' model_year_align_lai = ',model_year_align_lai
- write(iulog,*) ' stream_fldFileName_lai = ',trim(stream_fldFileName_lai)
- write(iulog,*) ' lai_tintalgo = ',trim(lai_tintalgo)
- endif
-
- call clm_domain_mct (bounds, dom_clm)
-
- ! create the field list for these lai fields...use in shr_strdata_create
- fldList = shr_string_listCreateField( numLaiFields, laiString )
-
- call shr_strdata_create(sdat_lai,name="laidyn", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=stream_year_first_lai, &
- yearLast=stream_year_last_lai, &
- yearAlign=model_year_align_lai, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_lai), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domAreaName='area', &
- domMaskName='mask', &
- filePath='', &
- filename=(/stream_fldFileName_lai/), &
- fldListFile=fldList, &
- fldListModel=fldList, &
- fillalgo='none', &
- mapalgo=lai_mapalgo, &
- tintalgo=lai_tintalgo, &
- calendar=get_calendar(), &
- taxmode='cycle' )
-
- if (masterproc) then
- call shr_strdata_print(sdat_lai,'LAI data')
- endif
-
- end subroutine lai_init
-
- !==============================================================================
- subroutine lai_advance( bounds )
- !
- ! Advance LAI streams
- !
- ! !USES:
- use clm_time_manager, only : get_curr_date
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type) , intent(in) :: bounds
- !
- ! !LOCAL VARIABLES:
- integer :: g, ig ! Indices
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- !-----------------------------------------------------------------------
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(sdat_lai, mcdate, sec, mpicom, 'laidyn')
- if ( .not. allocated(g_to_ig) )then
- allocate (g_to_ig(bounds%begg:bounds%endg) )
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- g_to_ig(g) = ig
- end do
- end if
-
- end subroutine lai_advance
-
- !==============================================================================
- subroutine lai_interp(bounds, canopystate_inst)
- !
- ! Interpolate data stream information for Lai.
- !
- ! !USES:
- use pftconMod , only : noveg
- use CanopyStateType , only : canopystate_type
- use PatchType , only : patch
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type) , intent(in) :: bounds
- type(canopystate_type) , intent(inout) :: canopystate_inst
- !
- ! !LOCAL VARIABLES:
- integer :: ivt, p, ip, ig
- character(len=CL) :: stream_var_name
- !-----------------------------------------------------------------------
- SHR_ASSERT_FL( (lbound(g_to_ig,1) <= bounds%begg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(g_to_ig,1) >= bounds%endg ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (lbound(sdat_lai%avs(1)%rAttr,2) <= g_to_ig(bounds%begg) ), sourcefile, __LINE__)
- SHR_ASSERT_FL( (ubound(sdat_lai%avs(1)%rAttr,2) >= g_to_ig(bounds%endg) ), sourcefile, __LINE__)
-
- do p = bounds%begp, bounds%endp
- ivt = patch%itype(p)
- ! Set lai for each gridcell/patch combination
- if (ivt /= noveg) then
- ! vegetated pft
- write(stream_var_name,"(i6)") ivt
- stream_var_name = 'LAI_'//trim(adjustl(stream_var_name))
- ip = mct_aVect_indexRA(sdat_lai%avs(1),trim(stream_var_name))
- ig = g_to_ig(patch%gridcell(p))
- canopystate_inst%tlai_patch(p) = sdat_lai%avs(1)%rAttr(ip,ig)
- else
- ! non-vegetated pft
- canopystate_inst%tlai_patch(p) = 0._r8
- endif
- end do
-
- end subroutine lai_interp
-
-end module LaiStreamMod
diff --git a/src/cpl/mct/lnd_comp_mct.F90 b/src/cpl/mct/lnd_comp_mct.F90
deleted file mode 100644
index e50602a378..0000000000
--- a/src/cpl/mct/lnd_comp_mct.F90
+++ /dev/null
@@ -1,632 +0,0 @@
-module lnd_comp_mct
-
- !---------------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Interface of the active land model component of CESM the CLM (Community Land Model)
- ! with the main CESM driver. This is a thin interface taking CESM driver information
- ! in MCT (Model Coupling Toolkit) format and converting it to use by CLM.
- !
- ! !uses:
- use shr_kind_mod , only : r8 => shr_kind_r8
- use shr_sys_mod , only : shr_sys_flush
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use mct_mod , only : mct_avect, mct_gsmap, mct_gGrid
- use decompmod , only : bounds_type
- use lnd_import_export, only : lnd_import, lnd_export
- !
- ! !public member functions:
- implicit none
- private ! by default make data private
- !
- ! !public member functions:
- public :: lnd_init_mct ! clm initialization
- public :: lnd_run_mct ! clm run phase
- public :: lnd_final_mct ! clm finalization/cleanup
- !
- ! !private member functions:
- private :: lnd_domain_mct ! set the land model domain information
- private :: lnd_handle_resume ! handle pause/resume signals from the coupler
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
-
-!====================================================================================
-contains
-!====================================================================================
-
- subroutine lnd_init_mct( EClock, cdata_l, x2l_l, l2x_l, NLFilename )
- !
- ! !DESCRIPTION:
- ! Initialize land surface model and obtain relevant atmospheric model arrays
- ! back from (i.e. albedos, surface temperature and snow cover over land).
- !
- ! !USES:
- use shr_kind_mod , only : shr_kind_cl
- use abortutils , only : endrun
- use clm_time_manager , only : get_nstep, set_timemgr_init
- use clm_initializeMod, only : initialize1, initialize2
- use clm_instMod , only : water_inst, lnd2atm_inst, lnd2glc_inst
- use clm_varctl , only : finidat, single_column, clm_varctl_set, iulog
- use clm_varctl , only : inst_index, inst_suffix, inst_name
- use clm_varorb , only : eccen, obliqr, lambm0, mvelpp
- use controlMod , only : control_setNL
- use decompMod , only : get_proc_bounds
- use domainMod , only : ldomain
- use shr_file_mod , only : shr_file_setLogUnit, shr_file_setLogLevel
- use shr_file_mod , only : shr_file_getLogUnit, shr_file_getLogLevel
- use shr_file_mod , only : shr_file_getUnit, shr_file_setIO
- use seq_cdata_mod , only : seq_cdata, seq_cdata_setptrs
- use seq_timemgr_mod , only : seq_timemgr_EClockGetData
- use seq_infodata_mod , only : seq_infodata_type, seq_infodata_GetData, seq_infodata_PutData, &
- seq_infodata_start_type_start, seq_infodata_start_type_cont, &
- seq_infodata_start_type_brnch
- use seq_comm_mct , only : seq_comm_suffix, seq_comm_inst, seq_comm_name
- use seq_flds_mod , only : seq_flds_x2l_fields, seq_flds_l2x_fields
- use spmdMod , only : masterproc, spmd_init
- use clm_varctl , only : nsrStartup, nsrContinue, nsrBranch
- use clm_cpl_indices , only : clm_cpl_indices_set
- use mct_mod , only : mct_aVect_init, mct_aVect_zero, mct_gsMap, mct_gsMap_init
- use decompMod , only : gindex_global
- use lnd_set_decomp_and_domain, only : lnd_set_decomp_and_domain_from_surfrd, gsmap_global
- use ESMF
- !
- ! !ARGUMENTS:
- type(ESMF_Clock), intent(inout) :: EClock ! Input synchronization clock
- type(seq_cdata), intent(inout) :: cdata_l ! Input land-model driver data
- type(mct_aVect), intent(inout) :: x2l_l, l2x_l ! land model import and export states
- character(len=*), optional, intent(in) :: NLFilename ! Namelist filename to read
- !
- ! !LOCAL VARIABLES:
- integer :: LNDID ! Land identifyer
- integer :: mpicom_lnd ! MPI communicator
- type(mct_gsMap), pointer :: GSMap_lnd ! Land model MCT GS map
- type(mct_gGrid), pointer :: dom_l ! Land model domain
- type(seq_infodata_type), pointer :: infodata ! CESM driver level info data
- integer :: lsize ! size of attribute vector
- integer :: gsize ! global size
- integer :: g,i,j ! indices
- integer :: dtime_sync ! coupling time-step from the input synchronization clock
- logical :: exists ! true if file exists
- logical :: atm_aero ! Flag if aerosol data sent from atm model
- real(r8) :: scmlat ! single-column latitude
- real(r8) :: scmlon ! single-column longitude
- character(len=SHR_KIND_CL) :: caseid ! case identifier name
- character(len=SHR_KIND_CL) :: ctitle ! case description title
- character(len=SHR_KIND_CL) :: starttype ! start-type (startup, continue, branch, hybrid)
- character(len=SHR_KIND_CL) :: calendar ! calendar type name
- character(len=SHR_KIND_CL) :: hostname ! hostname of machine running on
- character(len=SHR_KIND_CL) :: version ! Model version
- character(len=SHR_KIND_CL) :: username ! user running the model
- integer :: nsrest ! clm restart type
- integer :: ref_ymd ! reference date (YYYYMMDD)
- integer :: ref_tod ! reference time of day (sec)
- integer :: start_ymd ! start date (YYYYMMDD)
- integer :: start_tod ! start time of day (sec)
- logical :: brnch_retain_casename ! flag if should retain the case name on a branch start type
- integer :: lbnum ! input to memory diagnostic
- integer :: shrlogunit,shrloglev ! old values for log unit and log level
- type(bounds_type) :: bounds ! bounds
- logical :: noland
- integer :: ni,nj
- real(r8) , parameter :: rundef = -9999999._r8
- character(len=32), parameter :: sub = 'lnd_init_mct'
- character(len=*), parameter :: format = "('("//trim(sub)//") :',A)"
- !-----------------------------------------------------------------------
-
- ! Set cdata data
- call seq_cdata_setptrs(cdata_l, ID=LNDID, mpicom=mpicom_lnd, &
- gsMap=GSMap_lnd, dom=dom_l, infodata=infodata)
-
- ! Determine attriute vector indices
- call clm_cpl_indices_set()
-
- ! Initialize clm MPI communicator
- call spmd_init( mpicom_lnd, LNDID )
-
-#if (defined _MEMTRACE)
- if(masterproc) then
- lbnum=1
- call memmon_dump_fort('memmon.out','lnd_init_mct:start::',lbnum)
- endif
-#endif
-
- inst_name = seq_comm_name(LNDID)
- inst_index = seq_comm_inst(LNDID)
- inst_suffix = seq_comm_suffix(LNDID)
- ! Initialize io log unit
-
- call shr_file_getLogUnit (shrlogunit)
- if (masterproc) then
- inquire(file='lnd_modelio.nml'//trim(inst_suffix),exist=exists)
- if (exists) then
- iulog = shr_file_getUnit()
- call shr_file_setIO('lnd_modelio.nml'//trim(inst_suffix),iulog)
- end if
- write(iulog,format) "CLM land model initialization"
- else
- iulog = shrlogunit
- end if
-
- call shr_file_getLogLevel(shrloglev)
- call shr_file_setLogUnit (iulog)
-
- ! Use infodata to set orbital values
- call seq_infodata_GetData( infodata, orb_eccen=eccen, orb_mvelpp=mvelpp, &
- orb_lambm0=lambm0, orb_obliqr=obliqr )
-
- ! Consistency check on namelist filename
- call control_setNL("lnd_in"//trim(inst_suffix))
-
- ! Initialize clm
- ! initialize1 reads namelists
- ! decomp and domain are set in lnd_set_decomp_and_domain_from_surfrd
- ! initialize2 performs the rest of initialization
- call seq_timemgr_EClockGetData(EClock, &
- start_ymd=start_ymd, &
- start_tod=start_tod, ref_ymd=ref_ymd, &
- ref_tod=ref_tod, &
- calendar=calendar, &
- dtime=dtime_sync)
- if (masterproc) then
- write(iulog,*)'dtime = ',dtime_sync
- end if
- call seq_infodata_GetData(infodata, case_name=caseid, &
- case_desc=ctitle, single_column=single_column, &
- scmlat=scmlat, scmlon=scmlon, &
- brnch_retain_casename=brnch_retain_casename, &
- start_type=starttype, model_version=version, &
- hostname=hostname, username=username )
-
- ! Single Column
- if ( single_column .and. (scmlat == rundef .or. scmlon == rundef ) ) then
- call endrun(msg=' ERROR:: single column mode on -- but scmlat and scmlon are NOT set'//&
- errMsg(sourcefile, __LINE__))
- end if
-
- ! Note that we assume that CTSM's internal dtime matches the coupling time step.
- ! i.e., we currently do NOT allow sub-cycling within a coupling time step.
- call set_timemgr_init( calendar_in=calendar, start_ymd_in=start_ymd, start_tod_in=start_tod, &
- ref_ymd_in=ref_ymd, ref_tod_in=ref_tod, dtime_in=dtime_sync)
-
- if ( trim(starttype) == trim(seq_infodata_start_type_start)) then
- nsrest = nsrStartup
- else if (trim(starttype) == trim(seq_infodata_start_type_cont) ) then
- nsrest = nsrContinue
- else if (trim(starttype) == trim(seq_infodata_start_type_brnch)) then
- nsrest = nsrBranch
- else
- call endrun( sub//' ERROR: unknown starttype' )
- end if
-
- ! set default values for run control variables
- call clm_varctl_set(caseid_in=caseid, ctitle_in=ctitle, &
- brnch_retain_casename_in=brnch_retain_casename, &
- single_column_in=single_column, scmlat_in=scmlat, &
- scmlon_in=scmlon, nsrest_in=nsrest, version_in=version, &
- hostname_in=hostname, username_in=username)
-
- ! Read namelists
- call initialize1(dtime=dtime_sync)
-
- ! Initialize decomposition and domain (ldomain) type
- call lnd_set_decomp_and_domain_from_surfrd(noland, ni, nj)
-
- ! If no land then exit out of initialization
- if ( noland ) then
-
- call seq_infodata_PutData( infodata, lnd_present =.false.)
- call seq_infodata_PutData( infodata, lnd_prognostic=.false.)
-
- else
-
- ! Determine if aerosol and dust deposition come from atmosphere component
- call seq_infodata_GetData(infodata, atm_aero=atm_aero )
- if ( .not. atm_aero )then
- call endrun( sub//' ERROR: atmosphere model MUST send aerosols to CLM' )
- end if
-
- ! Initialize clm gsMap, clm domain and clm attribute vectors
- call get_proc_bounds( bounds )
- lsize = bounds%endg - bounds%begg + 1
- gsize = ldomain%ni * ldomain%nj
- call mct_gsMap_init( gsMap_lnd, gindex_global, mpicom_lnd, LNDID, lsize, gsize )
- gsmap_global => gsmap_lnd ! module variable in lnd_set_decomp_and_domain
- call lnd_domain_mct( bounds, lsize, gsMap_lnd, dom_l )
- call mct_aVect_init(x2l_l, rList=seq_flds_x2l_fields, lsize=lsize)
- call mct_aVect_zero(x2l_l)
- call mct_aVect_init(l2x_l, rList=seq_flds_l2x_fields, lsize=lsize)
- call mct_aVect_zero(l2x_l)
-
- ! Finish initializing clm
- call initialize2(ni,nj)
-
- ! Create land export state
- call lnd_export(bounds, water_inst%waterlnd2atmbulk_inst, lnd2atm_inst, lnd2glc_inst, l2x_l%rattr)
-
- ! Fill in infodata settings
- call seq_infodata_PutData(infodata, lnd_prognostic=.true.)
- call seq_infodata_PutData(infodata, lnd_nx=ldomain%ni, lnd_ny=ldomain%nj)
- call lnd_handle_resume( cdata_l )
-
- ! Reset shr logging to original values
- call shr_file_setLogUnit (shrlogunit)
- call shr_file_setLogLevel(shrloglev)
-
-#if (defined _MEMTRACE)
- if(masterproc) then
- write(iulog,*) TRIM(Sub) // ':end::'
- lbnum=1
- call memmon_dump_fort('memmon.out','lnd_int_mct:end::',lbnum)
- call memmon_reset_addr()
- endif
-#endif
- end if
-
- end subroutine lnd_init_mct
-
- !====================================================================================
- subroutine lnd_run_mct(EClock, cdata_l, x2l_l, l2x_l)
- !
- ! !DESCRIPTION:
- ! Run clm model
- !
- ! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8
- use clm_instMod , only : water_inst, lnd2atm_inst, atm2lnd_inst, lnd2glc_inst, glc2lnd_inst
- use clm_driver , only : clm_drv
- use clm_time_manager, only : get_curr_date, get_nstep, get_curr_calday, get_step_size
- use clm_time_manager, only : advance_timestep, update_rad_dtime
- use decompMod , only : get_proc_bounds
- use abortutils , only : endrun
- use clm_varctl , only : iulog
- use clm_varorb , only : eccen, obliqr, lambm0, mvelpp
- use shr_file_mod , only : shr_file_setLogUnit, shr_file_setLogLevel
- use shr_file_mod , only : shr_file_getLogUnit, shr_file_getLogLevel
- use seq_cdata_mod , only : seq_cdata, seq_cdata_setptrs
- use seq_timemgr_mod , only : seq_timemgr_EClockGetData, seq_timemgr_StopAlarmIsOn
- use seq_timemgr_mod , only : seq_timemgr_RestartAlarmIsOn, seq_timemgr_EClockDateInSync
- use seq_infodata_mod, only : seq_infodata_type, seq_infodata_GetData
- use spmdMod , only : masterproc, mpicom
- use perf_mod , only : t_startf, t_stopf, t_barrierf
- use shr_orb_mod , only : shr_orb_decl
- use ESMF
- !
- ! !ARGUMENTS:
- type(ESMF_Clock) , intent(inout) :: EClock ! Input synchronization clock from driver
- type(seq_cdata) , intent(inout) :: cdata_l ! Input driver data for land model
- type(mct_aVect) , intent(inout) :: x2l_l ! Import state to land model
- type(mct_aVect) , intent(inout) :: l2x_l ! Export state from land model
- !
- ! !LOCAL VARIABLES:
- integer :: ymd_sync ! Sync date (YYYYMMDD)
- integer :: yr_sync ! Sync current year
- integer :: mon_sync ! Sync current month
- integer :: day_sync ! Sync current day
- integer :: tod_sync ! Sync current time of day (sec)
- integer :: ymd ! CLM current date (YYYYMMDD)
- integer :: yr ! CLM current year
- integer :: mon ! CLM current month
- integer :: day ! CLM current day
- integer :: tod ! CLM current time of day (sec)
- integer :: dtime ! time step increment (sec)
- integer :: nstep ! time step index
- logical :: rstwr_sync ! .true. ==> write restart file before returning
- logical :: rstwr ! .true. ==> write restart file before returning
- logical :: nlend_sync ! Flag signaling last time-step
- logical :: nlend ! .true. ==> last time-step
- logical :: dosend ! true => send data back to driver
- logical :: doalb ! .true. ==> do albedo calculation on this time step
- logical :: rof_prognostic ! .true. => running with a prognostic ROF model
- logical :: glc_present ! .true. => running with a non-stub GLC model
- real(r8) :: nextsw_cday ! calday from clock of next radiation computation
- real(r8) :: caldayp1 ! clm calday plus dtime offset
- integer :: shrlogunit,shrloglev ! old values for share log unit and log level
- integer :: lbnum ! input to memory diagnostic
- integer :: g,i,lsize ! counters
- real(r8) :: calday ! calendar day for nstep
- real(r8) :: declin ! solar declination angle in radians for nstep
- real(r8) :: declinp1 ! solar declination angle in radians for nstep+1
- real(r8) :: eccf ! earth orbit eccentricity factor
- real(r8) :: recip ! reciprical
- logical,save :: first_call = .true. ! first call work
- type(seq_infodata_type),pointer :: infodata ! CESM information from the driver
- type(mct_gGrid), pointer :: dom_l ! Land model domain data
- type(bounds_type) :: bounds ! bounds
- character(len=32) :: rdate ! date char string for restart file names
- character(len=32), parameter :: sub = "lnd_run_mct"
- !---------------------------------------------------------------------------
-
- ! Determine processor bounds
-
- call get_proc_bounds(bounds)
-
-#if (defined _MEMTRACE)
- if(masterproc) then
- lbnum=1
- call memmon_dump_fort('memmon.out','lnd_run_mct:start::',lbnum)
- endif
-#endif
-
- ! Reset shr logging to my log file
- call shr_file_getLogUnit (shrlogunit)
- call shr_file_getLogLevel(shrloglev)
- call shr_file_setLogUnit (iulog)
-
- ! Determine time of next atmospheric shortwave calculation
- call seq_cdata_setptrs(cdata_l, infodata=infodata, dom=dom_l)
- call seq_timemgr_EClockGetData(EClock, &
- curr_ymd=ymd, curr_tod=tod_sync, &
- curr_yr=yr_sync, curr_mon=mon_sync, curr_day=day_sync)
- call seq_infodata_GetData(infodata, nextsw_cday=nextsw_cday )
-
- dtime = get_step_size()
-
- ! Handle pause/resume signals from coupler
- call lnd_handle_resume( cdata_l )
-
- write(rdate,'(i4.4,"-",i2.2,"-",i2.2,"-",i5.5)') yr_sync,mon_sync,day_sync,tod_sync
- nlend_sync = seq_timemgr_StopAlarmIsOn( EClock )
- rstwr_sync = seq_timemgr_RestartAlarmIsOn( EClock )
-
- ! Determine if we're running with a prognostic ROF model, and if we're running with a
- ! non-stub GLC model. These won't change throughout the run, but we can't count on
- ! their being set in initialization, so need to get them in the run method.
-
- call seq_infodata_GetData( infodata, &
- rof_prognostic=rof_prognostic, &
- glc_present=glc_present)
-
- ! Map MCT to land data type
- ! Perform downscaling if appropriate
-
-
- ! Map to clm (only when state and/or fluxes need to be updated)
-
- call t_startf ('lc_lnd_import')
- call lnd_import( bounds, &
- x2l = x2l_l%rattr, &
- glc_present = glc_present, &
- atm2lnd_inst = atm2lnd_inst, &
- glc2lnd_inst = glc2lnd_inst, &
- wateratm2lndbulk_inst = water_inst%wateratm2lndbulk_inst)
- call t_stopf ('lc_lnd_import')
-
- ! Use infodata to set orbital values if updated mid-run
-
- call seq_infodata_GetData( infodata, orb_eccen=eccen, orb_mvelpp=mvelpp, &
- orb_lambm0=lambm0, orb_obliqr=obliqr )
-
- ! Loop over time steps in coupling interval
-
- dosend = .false.
- do while(.not. dosend)
-
- ! Determine if dosend
- ! When time is not updated at the beginning of the loop - then return only if
- ! are in sync with clock before time is updated
- !
- ! NOTE(wjs, 2020-03-09) I think the do while (.not. dosend) loop only is important
- ! for the first time step (when we run 2 steps). After that, we now assume that we
- ! run one time step per coupling interval (based on setting the model's dtime from
- ! the driver). (According to Mariana Vertenstein, sub-cycling (running multiple
- ! land model time steps per coupling interval) used to be supported, but hasn't
- ! been fully supported for a long time.) We may want to rework this logic to make
- ! this more explicit, or - ideally - get rid of this extra time step at the start
- ! of the run, at which point I think we could do away with this looping entirely.
-
- call get_curr_date( yr, mon, day, tod )
- ymd = yr*10000 + mon*100 + day
- tod = tod
- dosend = (seq_timemgr_EClockDateInSync( EClock, ymd, tod))
-
- ! Determine doalb based on nextsw_cday sent from atm model
-
- nstep = get_nstep()
- caldayp1 = get_curr_calday(offset=dtime, reuse_day_365_for_day_366=.true.)
- if (nstep == 0) then
- doalb = .false.
- else if (nstep == 1) then
- doalb = (abs(nextsw_cday- caldayp1) < 1.e-10_r8)
- else
- doalb = (nextsw_cday >= -0.5_r8)
- end if
- call update_rad_dtime(doalb)
-
- ! Determine if time to write restart and stop
-
- rstwr = .false.
- if (rstwr_sync .and. dosend) rstwr = .true.
- nlend = .false.
- if (nlend_sync .and. dosend) nlend = .true.
-
- ! Run clm
-
- call t_barrierf('sync_clm_run1', mpicom)
- call t_startf ('clm_run')
- call t_startf ('shr_orb_decl')
- calday = get_curr_calday(reuse_day_365_for_day_366=.true.)
- call shr_orb_decl( calday , eccen, mvelpp, lambm0, obliqr, declin , eccf )
- call shr_orb_decl( nextsw_cday, eccen, mvelpp, lambm0, obliqr, declinp1, eccf )
- call t_stopf ('shr_orb_decl')
- call clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, rof_prognostic)
- call t_stopf ('clm_run')
-
- ! Create l2x_l export state - add river runoff input to l2x_l if appropriate
-
- call t_startf ('lc_lnd_export')
- call lnd_export(bounds, water_inst%waterlnd2atmbulk_inst, lnd2atm_inst, lnd2glc_inst, l2x_l%rattr)
- call t_stopf ('lc_lnd_export')
-
- ! Advance clm time step
-
- call t_startf ('lc_clm2_adv_timestep')
- call advance_timestep()
- call t_stopf ('lc_clm2_adv_timestep')
-
- end do
-
- ! Check that internal clock is in sync with master clock
-
- call get_curr_date( yr, mon, day, tod, offset=-dtime )
- ymd = yr*10000 + mon*100 + day
- tod = tod
- if ( .not. seq_timemgr_EClockDateInSync( EClock, ymd, tod ) )then
- call seq_timemgr_EclockGetData( EClock, curr_ymd=ymd_sync, curr_tod=tod_sync )
- write(iulog,*)' clm ymd=',ymd ,' clm tod= ',tod
- write(iulog,*)'sync ymd=',ymd_sync,' sync tod= ',tod_sync
- call endrun( sub//":: CLM clock not in sync with Master Sync clock" )
- end if
-
- ! Reset shr logging to my original values
-
- call shr_file_setLogUnit (shrlogunit)
- call shr_file_setLogLevel(shrloglev)
-
-#if (defined _MEMTRACE)
- if(masterproc) then
- lbnum=1
- call memmon_dump_fort('memmon.out','lnd_run_mct:end::',lbnum)
- call memmon_reset_addr()
- endif
-#endif
-
- first_call = .false.
-
- end subroutine lnd_run_mct
-
- !====================================================================================
- subroutine lnd_final_mct( EClock, cdata_l, x2l_l, l2x_l)
- !
- ! !DESCRIPTION:
- ! Finalize land surface model
-
- use seq_cdata_mod ,only : seq_cdata, seq_cdata_setptrs
- use seq_timemgr_mod ,only : seq_timemgr_EClockGetData, seq_timemgr_StopAlarmIsOn
- use seq_timemgr_mod ,only : seq_timemgr_RestartAlarmIsOn, seq_timemgr_EClockDateInSync
- use esmf
- !
- ! !ARGUMENTS:
- type(ESMF_Clock) , intent(inout) :: EClock ! Input synchronization clock from driver
- type(seq_cdata) , intent(inout) :: cdata_l ! Input driver data for land model
- type(mct_aVect) , intent(inout) :: x2l_l ! Import state to land model
- type(mct_aVect) , intent(inout) :: l2x_l ! Export state from land model
- !---------------------------------------------------------------------------
-
- ! fill this in
- end subroutine lnd_final_mct
-
- !====================================================================================
- subroutine lnd_domain_mct( bounds, lsize, gsMap_l, dom_l )
- !
- ! !DESCRIPTION:
- ! Send the land model domain information to the coupler
- !
- ! !USES:
- use clm_varcon , only: re
- use domainMod , only: ldomain
- use spmdMod , only: iam
- use mct_mod , only: mct_gGrid_importIAttr
- use mct_mod , only: mct_gGrid_importRAttr, mct_gGrid_init, mct_gsMap_orderedPoints
- use seq_flds_mod, only: seq_flds_dom_coord, seq_flds_dom_other
- !
- ! !ARGUMENTS:
- type(bounds_type), intent(in) :: bounds ! bounds
- integer , intent(in) :: lsize ! land model domain data size
- type(mct_gsMap), intent(inout) :: gsMap_l ! Output land model MCT GS map
- type(mct_ggrid), intent(out) :: dom_l ! Output domain information for land model
- !
- ! Local Variables
- integer :: g,i,j ! index
- real(r8), pointer :: data(:) ! temporary
- integer , pointer :: idata(:) ! temporary
- !---------------------------------------------------------------------------
- !
- ! Initialize mct domain type
- ! lat/lon in degrees, area in radians^2, mask is 1 (land), 0 (non-land)
- ! Note that in addition land carries around landfrac for the purposes of domain checking
- !
- call mct_gGrid_init( GGrid=dom_l, CoordChars=trim(seq_flds_dom_coord), &
- OtherChars=trim(seq_flds_dom_other), lsize=lsize )
- !
- ! Allocate memory
- !
- allocate(data(lsize))
- !
- ! Determine global gridpoint number attribute, GlobGridNum, which is set automatically by MCT
- !
- call mct_gsMap_orderedPoints(gsMap_l, iam, idata)
- call mct_gGrid_importIAttr(dom_l,'GlobGridNum',idata,lsize)
- !
- ! Determine domain (numbering scheme is: West to East and South to North to South pole)
- ! Initialize attribute vector with special value
- !
- data(:) = -9999.0_R8
- call mct_gGrid_importRAttr(dom_l,"lat" ,data,lsize)
- call mct_gGrid_importRAttr(dom_l,"lon" ,data,lsize)
- call mct_gGrid_importRAttr(dom_l,"area" ,data,lsize)
- call mct_gGrid_importRAttr(dom_l,"aream",data,lsize)
- data(:) = 0.0_R8
- call mct_gGrid_importRAttr(dom_l,"mask" ,data,lsize)
- !
- ! Fill in correct values for domain components
- ! Note aream will be filled in in the atm-lnd mapper
- !
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%lonc(g)
- end do
- call mct_gGrid_importRattr(dom_l,"lon",data,lsize)
-
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%latc(g)
- end do
- call mct_gGrid_importRattr(dom_l,"lat",data,lsize)
-
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%area(g)/(re*re)
- end do
- call mct_gGrid_importRattr(dom_l,"area",data,lsize)
-
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = real(ldomain%mask(g), r8)
- end do
- call mct_gGrid_importRattr(dom_l,"mask",data,lsize)
-
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = real(ldomain%frac(g), r8)
- end do
- call mct_gGrid_importRattr(dom_l,"frac",data,lsize)
-
- deallocate(data)
- deallocate(idata)
-
- end subroutine lnd_domain_mct
-
- !====================================================================================
- subroutine lnd_handle_resume( cdata_l )
- !
- ! !DESCRIPTION:
- ! Handle resume signals for Data Assimilation (DA)
- !
- ! !USES:
- use clm_time_manager , only : update_DA_nstep
- use seq_cdata_mod , only : seq_cdata, seq_cdata_setptrs
- implicit none
- ! !ARGUMENTS:
- type(seq_cdata), intent(inout) :: cdata_l ! Input land-model driver data
- ! !LOCAL VARIABLES:
- logical :: resume_from_data_assim ! flag if we are resuming after data assimulation was done
- !---------------------------------------------------------------------------
-
- ! Check to see if restart was modified and we are resuming from data
- ! assimilation
- call seq_cdata_setptrs(cdata_l, post_assimilation=resume_from_data_assim)
- if ( resume_from_data_assim ) call update_DA_nstep()
-
- end subroutine lnd_handle_resume
-
-end module lnd_comp_mct
diff --git a/src/cpl/mct/lnd_import_export.F90 b/src/cpl/mct/lnd_import_export.F90
deleted file mode 100644
index 537abd49d9..0000000000
--- a/src/cpl/mct/lnd_import_export.F90
+++ /dev/null
@@ -1,354 +0,0 @@
-module lnd_import_export
-
- use shr_kind_mod , only: r8 => shr_kind_r8, cl=>shr_kind_cl
- use abortutils , only: endrun
- use decompmod , only: bounds_type, subgrid_level_gridcell
- use lnd2atmType , only: lnd2atm_type
- use lnd2glcMod , only: lnd2glc_type
- use atm2lndType , only: atm2lnd_type
- use glc2lndMod , only: glc2lnd_type
- use Waterlnd2atmBulkType , only: waterlnd2atmbulk_type
- use Wateratm2lndBulkType , only: wateratm2lndbulk_type
- use clm_cpl_indices
- use GridcellType , only : grc
- !
- implicit none
- !===============================================================================
-
-contains
-
- !===============================================================================
- subroutine lnd_import( bounds, x2l, glc_present, atm2lnd_inst, glc2lnd_inst, wateratm2lndbulk_inst)
-
- !---------------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Convert the input data from the coupler to the land model
- !
- ! !USES:
- use seq_flds_mod , only: seq_flds_x2l_fields
- use clm_varctl , only: co2_type, co2_ppmv, iulog, use_c13
- use clm_varctl , only: ndep_from_cpl
- use clm_varcon , only: c13ratio
- use domainMod , only: ldomain
- use lnd_import_export_utils, only : derive_quantities, check_for_errors, check_for_nans
- !
- ! !ARGUMENTS:
- type(bounds_type) , intent(in) :: bounds ! bounds
- real(r8) , intent(in) :: x2l(:,:) ! driver import state to land model
- logical , intent(in) :: glc_present ! .true. => running with a non-stub GLC model
- type(atm2lnd_type) , intent(inout) :: atm2lnd_inst ! clm internal input data type
- type(glc2lnd_type) , intent(inout) :: glc2lnd_inst ! clm internal input data type
- type(wateratm2lndbulk_type), intent(inout) :: wateratm2lndbulk_inst ! clm internal input data type
- !
- ! !LOCAL VARIABLES:
- integer :: begg, endg ! bounds
- integer :: g,i,k,nstep,ier ! indices, number of steps, and error code
- real(r8) :: qsat_kg_kg ! saturation specific humidity (kg/kg)
- real(r8) :: forc_pbot ! atmospheric pressure (Pa)
- real(r8) :: forc_rainc(bounds%begg:bounds%endg) ! rainxy Atm flux mm/s
- real(r8) :: forc_rainl(bounds%begg:bounds%endg) ! rainxy Atm flux mm/s
- real(r8) :: forc_snowc(bounds%begg:bounds%endg) ! snowfxy Atm flux mm/s
- real(r8) :: forc_snowl(bounds%begg:bounds%endg) ! snowfxl Atm flux mm/s
- real(r8) :: co2_ppmv_diag ! temporary
- real(r8) :: co2_ppmv_prog ! temporary
- real(r8) :: co2_ppmv_val ! temporary
- integer :: co2_type_idx ! integer flag for co2_type options
- character(len=32) :: fname ! name of field that is NaN
- character(len=32), parameter :: sub = 'lnd_import'
-
- !---------------------------------------------------------------------------
-
- ! Set bounds
- begg = bounds%begg; endg = bounds%endg
-
- co2_type_idx = 0
- if (co2_type == 'prognostic') then
- co2_type_idx = 1
- else if (co2_type == 'diagnostic') then
- co2_type_idx = 2
- end if
- if (co2_type == 'prognostic' .and. index_x2l_Sa_co2prog == 0) then
- call endrun( sub//' ERROR: must have nonzero index_x2l_Sa_co2prog for co2_type equal to prognostic' )
- else if (co2_type == 'diagnostic' .and. index_x2l_Sa_co2diag == 0) then
- call endrun( sub//' ERROR: must have nonzero index_x2l_Sa_co2diag for co2_type equal to diagnostic' )
- end if
-
- ! Note that the precipitation fluxes received from the coupler
- ! are in units of kg/s/m^2. To convert these precipitation rates
- ! in units of mm/sec, one must divide by 1000 kg/m^3 and multiply
- ! by 1000 mm/m resulting in an overall factor of unity.
- ! Below the units are therefore given in mm/s.
-
- do g = begg,endg
- i = 1 + (g - begg)
-
- ! Determine flooding input, sign convention is positive downward and
- ! hierarchy is atm/glc/lnd/rof/ice/ocn. so water sent from rof to land is negative,
- ! change the sign to indicate addition of water to system.
-
- wateratm2lndbulk_inst%forc_flood_grc(g) = -x2l(index_x2l_Flrr_flood,i)
-
- wateratm2lndbulk_inst%volr_grc(g) = x2l(index_x2l_Flrr_volr,i) * (ldomain%area(g) * 1.e6_r8)
- wateratm2lndbulk_inst%volrmch_grc(g)= x2l(index_x2l_Flrr_volrmch,i) * (ldomain%area(g) * 1.e6_r8)
-
- ! Determine required receive fields
-
- atm2lnd_inst%forc_hgt_grc(g) = x2l(index_x2l_Sa_z,i) ! zgcmxy Atm state m
- atm2lnd_inst%forc_topo_grc(g) = x2l(index_x2l_Sa_topo,i) ! Atm surface height (m)
- atm2lnd_inst%forc_u_grc(g) = x2l(index_x2l_Sa_u,i) ! forc_uxy Atm state m/s
- atm2lnd_inst%forc_v_grc(g) = x2l(index_x2l_Sa_v,i) ! forc_vxy Atm state m/s
- atm2lnd_inst%forc_solad_not_downscaled_grc(g,2) = x2l(index_x2l_Faxa_swndr,i) ! forc_sollxy Atm flux W/m^2
- atm2lnd_inst%forc_solad_not_downscaled_grc(g,1) = x2l(index_x2l_Faxa_swvdr,i) ! forc_solsxy Atm flux W/m^2
- atm2lnd_inst%forc_solai_grc(g,2) = x2l(index_x2l_Faxa_swndf,i) ! forc_solldxy Atm flux W/m^2
- atm2lnd_inst%forc_solai_grc(g,1) = x2l(index_x2l_Faxa_swvdf,i) ! forc_solsdxy Atm flux W/m^2
-
- atm2lnd_inst%forc_th_not_downscaled_grc(g) = x2l(index_x2l_Sa_ptem,i) ! forc_thxy Atm state K
- wateratm2lndbulk_inst%forc_q_not_downscaled_grc(g) = x2l(index_x2l_Sa_shum,i) ! forc_qxy Atm state kg/kg
- atm2lnd_inst%forc_pbot_not_downscaled_grc(g) = x2l(index_x2l_Sa_pbot,i) ! ptcmxy Atm state Pa
- atm2lnd_inst%forc_t_not_downscaled_grc(g) = x2l(index_x2l_Sa_tbot,i) ! forc_txy Atm state K
- atm2lnd_inst%forc_lwrad_not_downscaled_grc(g) = x2l(index_x2l_Faxa_lwdn,i) ! flwdsxy Atm flux W/m^2
-
- forc_rainc(g) = x2l(index_x2l_Faxa_rainc,i) ! mm/s
- forc_rainl(g) = x2l(index_x2l_Faxa_rainl,i) ! mm/s
- forc_snowc(g) = x2l(index_x2l_Faxa_snowc,i) ! mm/s
- forc_snowl(g) = x2l(index_x2l_Faxa_snowl,i) ! mm/s
-
- ! atmosphere coupling, for prognostic/prescribed aerosols
- atm2lnd_inst%forc_aer_grc(g,1) = x2l(index_x2l_Faxa_bcphidry,i)
- atm2lnd_inst%forc_aer_grc(g,2) = x2l(index_x2l_Faxa_bcphodry,i)
- atm2lnd_inst%forc_aer_grc(g,3) = x2l(index_x2l_Faxa_bcphiwet,i)
- atm2lnd_inst%forc_aer_grc(g,4) = x2l(index_x2l_Faxa_ocphidry,i)
- atm2lnd_inst%forc_aer_grc(g,5) = x2l(index_x2l_Faxa_ocphodry,i)
- atm2lnd_inst%forc_aer_grc(g,6) = x2l(index_x2l_Faxa_ocphiwet,i)
- atm2lnd_inst%forc_aer_grc(g,7) = x2l(index_x2l_Faxa_dstwet1,i)
- atm2lnd_inst%forc_aer_grc(g,8) = x2l(index_x2l_Faxa_dstdry1,i)
- atm2lnd_inst%forc_aer_grc(g,9) = x2l(index_x2l_Faxa_dstwet2,i)
- atm2lnd_inst%forc_aer_grc(g,10) = x2l(index_x2l_Faxa_dstdry2,i)
- atm2lnd_inst%forc_aer_grc(g,11) = x2l(index_x2l_Faxa_dstwet3,i)
- atm2lnd_inst%forc_aer_grc(g,12) = x2l(index_x2l_Faxa_dstdry3,i)
- atm2lnd_inst%forc_aer_grc(g,13) = x2l(index_x2l_Faxa_dstwet4,i)
- atm2lnd_inst%forc_aer_grc(g,14) = x2l(index_x2l_Faxa_dstdry4,i)
-
- if (index_x2l_Sa_methane /= 0) then
- atm2lnd_inst%forc_pch4_grc(g) = x2l(index_x2l_Sa_methane,i)
- endif
-
- !--------------------------
- ! Check for nans from coupler
- !--------------------------
-
- call check_for_nans(x2l(:,i), fname, begg, "x2l")
-
- end do
-
- !--------------------------
- ! Derived quantities for required fields
- ! and corresponding error checks
- !--------------------------
-
- call derive_quantities(bounds, atm2lnd_inst, wateratm2lndbulk_inst, &
- forc_rainc, forc_rainl, forc_snowc, forc_snowl)
-
- call check_for_errors(bounds, atm2lnd_inst, wateratm2lndbulk_inst)
-
- ! Determine derived quantities for optional fields
- ! Note that the following does unit conversions from ppmv to partial pressures (Pa)
- ! Note that forc_pbot is in Pa
-
- do g = begg,endg
- i = 1 + (g - begg)
-
- forc_pbot = atm2lnd_inst%forc_pbot_not_downscaled_grc(g)
-
- ! Determine optional receive fields
- if (index_x2l_Sa_co2prog /= 0) then
- co2_ppmv_prog = x2l(index_x2l_Sa_co2prog,i) ! co2 atm state prognostic
- else
- co2_ppmv_prog = co2_ppmv
- end if
- if (index_x2l_Sa_co2diag /= 0) then
- co2_ppmv_diag = x2l(index_x2l_Sa_co2diag,i) ! co2 atm state diagnostic
- else
- co2_ppmv_diag = co2_ppmv
- end if
-
- if (co2_type_idx == 1) then
- co2_ppmv_val = co2_ppmv_prog
- else if (co2_type_idx == 2) then
- co2_ppmv_val = co2_ppmv_diag
- else
- co2_ppmv_val = co2_ppmv
- end if
- if ( (co2_ppmv_val < 10.0_r8) .or. (co2_ppmv_val > 15000.0_r8) )then
- call endrun(subgrid_index=g, subgrid_level=subgrid_level_gridcell, &
- msg = sub//' ERROR: CO2 is outside of an expected range' )
- end if
- atm2lnd_inst%forc_pco2_grc(g) = co2_ppmv_val * 1.e-6_r8 * forc_pbot
- if (use_c13) then
- atm2lnd_inst%forc_pc13o2_grc(g) = co2_ppmv_val * c13ratio * 1.e-6_r8 * forc_pbot
- end if
-
- if (ndep_from_cpl) then
- ! The coupler is sending ndep in units if kgN/m2/s - and clm uses units of gN/m2/sec - so the
- ! following conversion needs to happen
- atm2lnd_inst%forc_ndep_grc(g) = (x2l(index_x2l_Faxa_nhx, i) + x2l(index_x2l_faxa_noy, i))*1000._r8
- end if
-
- end do
-
- call glc2lnd_inst%set_glc2lnd_fields_mct( &
- bounds = bounds, &
- glc_present = glc_present, &
- ! NOTE(wjs, 2017-12-13) the x2l argument doesn't have the typical bounds
- ! subsetting (bounds%begg:bounds%endg). This mirrors the lack of these bounds in
- ! the call to lnd_import from lnd_run_mct. This is okay as long as this code is
- ! outside a clump loop.
- x2l = x2l, &
- index_x2l_Sg_ice_covered = index_x2l_Sg_ice_covered, &
- index_x2l_Sg_topo = index_x2l_Sg_topo, &
- index_x2l_Flgg_hflx = index_x2l_Flgg_hflx, &
- index_x2l_Sg_icemask = index_x2l_Sg_icemask, &
- index_x2l_Sg_icemask_coupled_fluxes = index_x2l_Sg_icemask_coupled_fluxes)
-
- end subroutine lnd_import
-
- !===============================================================================
-
- subroutine lnd_export( bounds, waterlnd2atmbulk_inst, lnd2atm_inst, lnd2glc_inst, l2x)
-
- !---------------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Convert the data to be sent from the clm model to the coupler
- !
- ! !USES:
- use shr_kind_mod , only : r8 => shr_kind_r8
- use seq_flds_mod , only : seq_flds_l2x_fields
- use clm_varctl , only : iulog
- use shr_drydep_mod , only : n_drydep
- use shr_megan_mod , only : shr_megan_mechcomps_n
- use shr_fire_emis_mod , only : shr_fire_emis_mechcomps_n
- use lnd_import_export_utils, only : check_for_nans
- !
- ! !ARGUMENTS:
- implicit none
- type(bounds_type) , intent(in) :: bounds ! bounds
- type(lnd2atm_type), intent(inout) :: lnd2atm_inst ! clm land to atmosphere exchange data type
- type(lnd2glc_type), intent(inout) :: lnd2glc_inst ! clm land to atmosphere exchange data type
- type(waterlnd2atmbulk_type), intent(in) :: waterlnd2atmbulk_inst
- real(r8) , intent(out) :: l2x(:,:)! land to coupler export state on land grid
- !
- ! !LOCAL VARIABLES:
- integer :: begg, endg ! bounds
- integer :: g,i,k ! indices
- integer :: ier ! error status
- integer :: nstep ! time step index
- integer :: dtime ! time step
- integer :: num ! counter
- character(len=32) :: fname ! name of field that is NaN
- character(len=32), parameter :: sub = 'lnd_export'
- !---------------------------------------------------------------------------
-
- ! Set bounds
- begg = bounds%begg; endg = bounds%endg
-
- ! cesm sign convention is that fluxes are positive downward
-
- l2x(:,:) = 0.0_r8
-
- do g = begg,endg
- i = 1 + (g-begg)
- l2x(index_l2x_Sl_t,i) = lnd2atm_inst%t_rad_grc(g)
- l2x(index_l2x_Sl_snowh,i) = waterlnd2atmbulk_inst%h2osno_grc(g)
- l2x(index_l2x_Sl_avsdr,i) = lnd2atm_inst%albd_grc(g,1)
- l2x(index_l2x_Sl_anidr,i) = lnd2atm_inst%albd_grc(g,2)
- l2x(index_l2x_Sl_avsdf,i) = lnd2atm_inst%albi_grc(g,1)
- l2x(index_l2x_Sl_anidf,i) = lnd2atm_inst%albi_grc(g,2)
- l2x(index_l2x_Sl_tref,i) = lnd2atm_inst%t_ref2m_grc(g)
- l2x(index_l2x_Sl_qref,i) = waterlnd2atmbulk_inst%q_ref2m_grc(g)
- l2x(index_l2x_Sl_u10,i) = lnd2atm_inst%u_ref10m_grc(g)
- l2x(index_l2x_Fall_taux,i) = -lnd2atm_inst%taux_grc(g)
- l2x(index_l2x_Fall_tauy,i) = -lnd2atm_inst%tauy_grc(g)
- l2x(index_l2x_Fall_lat,i) = -lnd2atm_inst%eflx_lh_tot_grc(g)
- l2x(index_l2x_Fall_sen,i) = -lnd2atm_inst%eflx_sh_tot_grc(g)
- l2x(index_l2x_Fall_lwup,i) = -lnd2atm_inst%eflx_lwrad_out_grc(g)
- l2x(index_l2x_Fall_evap,i) = -waterlnd2atmbulk_inst%qflx_evap_tot_grc(g)
- l2x(index_l2x_Fall_swnet,i) = lnd2atm_inst%fsa_grc(g)
- if (index_l2x_Fall_fco2_lnd /= 0) then
- l2x(index_l2x_Fall_fco2_lnd,i) = -lnd2atm_inst%net_carbon_exchange_grc(g)
- end if
-
- ! Additional fields for DUST, PROGSSLT, dry-deposition and VOC
- ! These are now standard fields, but the check on the index makes sure the driver handles them
- if (index_l2x_Sl_ram1 /= 0 ) l2x(index_l2x_Sl_ram1,i) = lnd2atm_inst%ram1_grc(g)
- if (index_l2x_Sl_fv /= 0 ) l2x(index_l2x_Sl_fv,i) = lnd2atm_inst%fv_grc(g)
- if (index_l2x_Sl_soilw /= 0 ) l2x(index_l2x_Sl_soilw,i) = waterlnd2atmbulk_inst%h2osoi_vol_grc(g,1)
- if (index_l2x_Fall_flxdst1 /= 0 ) l2x(index_l2x_Fall_flxdst1,i)= -lnd2atm_inst%flxdst_grc(g,1)
- if (index_l2x_Fall_flxdst2 /= 0 ) l2x(index_l2x_Fall_flxdst2,i)= -lnd2atm_inst%flxdst_grc(g,2)
- if (index_l2x_Fall_flxdst3 /= 0 ) l2x(index_l2x_Fall_flxdst3,i)= -lnd2atm_inst%flxdst_grc(g,3)
- if (index_l2x_Fall_flxdst4 /= 0 ) l2x(index_l2x_Fall_flxdst4,i)= -lnd2atm_inst%flxdst_grc(g,4)
-
-
- ! for dry dep velocities
- if (index_l2x_Sl_ddvel /= 0 ) then
- l2x(index_l2x_Sl_ddvel:index_l2x_Sl_ddvel+n_drydep-1,i) = &
- lnd2atm_inst%ddvel_grc(g,:n_drydep)
- end if
-
- ! for MEGAN VOC emis fluxes
- if (index_l2x_Fall_flxvoc /= 0 ) then
- l2x(index_l2x_Fall_flxvoc:index_l2x_Fall_flxvoc+shr_megan_mechcomps_n-1,i) = &
- -lnd2atm_inst%flxvoc_grc(g,:shr_megan_mechcomps_n)
- end if
-
-
- ! for fire emis fluxes
- if (index_l2x_Fall_flxfire /= 0 ) then
- l2x(index_l2x_Fall_flxfire:index_l2x_Fall_flxfire+shr_fire_emis_mechcomps_n-1,i) = &
- -lnd2atm_inst%fireflx_grc(g,:shr_fire_emis_mechcomps_n)
- l2x(index_l2x_Sl_ztopfire,i) = lnd2atm_inst%fireztop_grc(g)
- end if
-
- if (index_l2x_Fall_methane /= 0) then
- l2x(index_l2x_Fall_methane,i) = -lnd2atm_inst%ch4_surf_flux_tot_grc(g)
- endif
-
- ! sign convention is positive downward with
- ! hierarchy of atm/glc/lnd/rof/ice/ocn.
- ! I.e. water sent from land to rof is positive
-
- l2x(index_l2x_Flrl_rofsur,i) = waterlnd2atmbulk_inst%qflx_rofliq_qsur_grc(g)
-
- ! subsurface runoff is the sum of qflx_drain and qflx_perched_drain
- l2x(index_l2x_Flrl_rofsub,i) = waterlnd2atmbulk_inst%qflx_rofliq_qsub_grc(g) &
- + waterlnd2atmbulk_inst%qflx_rofliq_drain_perched_grc(g)
-
- ! qgwl sent individually to coupler
- l2x(index_l2x_Flrl_rofgwl,i) = waterlnd2atmbulk_inst%qflx_rofliq_qgwl_grc(g)
-
- ! ice sent individually to coupler
- l2x(index_l2x_Flrl_rofi,i) = waterlnd2atmbulk_inst%qflx_rofice_grc(g)
-
- ! irrigation flux to be removed from main channel storage (negative)
- l2x(index_l2x_Flrl_irrig,i) = - waterlnd2atmbulk_inst%qirrig_grc(g)
-
- ! glc coupling
- ! We could avoid setting these fields if glc_present is .false., if that would
- ! help with performance. (The downside would be that we wouldn't have these fields
- ! available for diagnostic purposes or to force a later T compset with dlnd.)
- do num = 0,glc_nec
- l2x(index_l2x_Sl_tsrf(num),i) = lnd2glc_inst%tsrf_grc(g,num)
- l2x(index_l2x_Sl_topo(num),i) = lnd2glc_inst%topo_grc(g,num)
- l2x(index_l2x_Flgl_qice(num),i) = lnd2glc_inst%qice_grc(g,num)
- end do
-
- !--------------------------
- ! Check for nans to coupler
- !--------------------------
-
- call check_for_nans(l2x(:,i), fname, begg, "l2x")
-
- end do
-
- end subroutine lnd_export
-
-end module lnd_import_export
diff --git a/src/cpl/mct/lnd_set_decomp_and_domain.F90 b/src/cpl/mct/lnd_set_decomp_and_domain.F90
deleted file mode 100644
index 0a37554313..0000000000
--- a/src/cpl/mct/lnd_set_decomp_and_domain.F90
+++ /dev/null
@@ -1,352 +0,0 @@
-module lnd_set_decomp_and_domain
-
- use shr_kind_mod , only : r8 => shr_kind_r8
- use spmdMod , only : masterproc
- use clm_varctl , only : iulog
- use mct_mod , only : mct_gsMap
-
- implicit none
- private ! except
-
- ! public member routines
- public :: lnd_set_decomp_and_domain_from_surfrd
-
- ! private member routines
- private :: surfrd_get_globmask ! Reads global land mask (needed for setting domain decomp)
- private :: surfrd_get_grid ! Read grid/ladnfrac data into domain (after domain decomp)
-
- ! translation between local and global indices at gridcell level
- type(mct_gsmap), pointer, public :: gsmap_global
-
- ! translation between local and global indices at gridcell level for multiple levels
- ! needed for 3d soil moisture stream
- type(mct_gsmap), target , public :: gsMap_lnd2Dsoi_gdc2glo
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
-
-!===============================================================================
-contains
-!===============================================================================
-
- subroutine lnd_set_decomp_and_domain_from_surfrd(noland, ni, nj)
-
- ! Initialize ldomain data types
-
- use clm_varpar , only: nlevsoi
- use clm_varctl , only: fatmlndfrc, use_soil_moisture_streams
- use decompInitMod , only: decompInit_lnd
- use decompMod , only: bounds_type, get_proc_bounds
- use domainMod , only: ldomain, domain_check
-
- ! input/output variables
- logical, intent(out) :: noland
- integer, intent(out) :: ni, nj ! global grid sizes
-
- ! local variables
- integer ,pointer :: amask(:) ! global land mask
- integer :: begg, endg ! processor bounds
- type(bounds_type) :: bounds ! bounds
- character(len=32) :: subname = 'lnd_set_decomp_and_domain_from_surfrd'
- !-----------------------------------------------------------------------
-
- ! Read in global land grid and land mask (amask)- needed to set decomposition
- ! global memory for amask is allocate in surfrd_get_glomask - must be deallocated below
- if (masterproc) then
- write(iulog,*) 'Attempting to read global land mask from ',trim(fatmlndfrc)
- endif
-
- ! Get global mask, ni and nj
- call surfrd_get_globmask(filename=fatmlndfrc, mask=amask, ni=ni, nj=nj)
-
- ! Exit early if no valid land points
- if ( all(amask == 0) )then
- if (masterproc) write(iulog,*) trim(subname)//': no valid land points do NOT run clm'
- noland = .true.
- return
- else
- noland = .false.
- end if
-
- ! Determine ctsm gridcell decomposition and processor bounds for gridcells
- call decompInit_lnd(ni, nj, amask)
- deallocate(amask)
- if (use_soil_moisture_streams) call decompInit_lnd3D(ni, nj, nlevsoi)
-
- ! Initialize bounds for just gridcells
- ! Remaining bounds (landunits, columns, patches) will be determined
- ! after the call to decompInit_glcp - so get_proc_bounds is called
- ! twice and the gridcell information is just filled in twice
- call get_proc_bounds(bounds)
-
- ! Get grid cell bounds values
- begg = bounds%begg
- endg = bounds%endg
-
- ! Initialize ldomain data type
- if (masterproc) then
- write(iulog,*) 'Attempting to read ldomain from ',trim(fatmlndfrc)
- endif
- call surfrd_get_grid(begg, endg, ldomain, fatmlndfrc)
- if (masterproc) then
- call domain_check(ldomain)
- endif
- ldomain%mask = 1 !!! TODO - is this needed?
-
- end subroutine lnd_set_decomp_and_domain_from_surfrd
-
- !-----------------------------------------------------------------------
- subroutine surfrd_get_globmask(filename, mask, ni, nj)
-
- ! Read the surface dataset grid related information
- ! This is used to set the domain decomposition - so global data is read here
-
- use fileutils , only : getfil
- use ncdio_pio , only : ncd_io, ncd_pio_openfile, ncd_pio_closefile, ncd_inqfdims, file_desc_t
- use abortutils , only : endrun
- use shr_log_mod, only : errMsg => shr_log_errMsg
-
- ! input/output variables
- character(len=*), intent(in) :: filename ! grid filename
- integer , pointer :: mask(:) ! grid mask
- integer , intent(out) :: ni, nj ! global grid sizes
-
- ! local variables
- logical :: isgrid2d
- integer :: dimid,varid ! netCDF id's
- integer :: ns ! size of grid on file
- integer :: n,i,j ! index
- integer :: ier ! error status
- type(file_desc_t) :: ncid ! netcdf id
- character(len=256) :: locfn ! local file name
- logical :: readvar ! read variable in or not
- integer , allocatable :: idata2d(:,:)
- character(len=32) :: subname = 'surfrd_get_globmask' ! subroutine name
- !-----------------------------------------------------------------------
-
- if (filename == ' ') then
- mask(:) = 1
- else
- ! Check if file exists
- if (masterproc) then
- if (filename == ' ') then
- write(iulog,*) trim(subname),' ERROR: filename must be specified '
- call endrun(msg=errMsg(sourcefile, __LINE__))
- endif
- end if
-
- ! Open file
- call getfil( filename, locfn, 0 )
- call ncd_pio_openfile (ncid, trim(locfn), 0)
-
- ! Determine dimensions and if grid file is 2d or 1d
- call ncd_inqfdims(ncid, isgrid2d, ni, nj, ns)
- if (masterproc) then
- write(iulog,*)'lat/lon grid flag (isgrid2d) is ',isgrid2d
- end if
- allocate(mask(ns))
- mask(:) = 1
- if (isgrid2d) then
- ! Grid is 2d
- allocate(idata2d(ni,nj))
- idata2d(:,:) = 1
- call ncd_io(ncid=ncid, varname='LANDMASK', data=idata2d, flag='read', readvar=readvar)
- if (.not. readvar) then
- call ncd_io(ncid=ncid, varname='mask', data=idata2d, flag='read', readvar=readvar)
- end if
- if (readvar) then
- do j = 1,nj
- do i = 1,ni
- n = (j-1)*ni + i
- mask(n) = idata2d(i,j)
- enddo
- enddo
- end if
- deallocate(idata2d)
- else
- ! Grid is not 2d
- call ncd_io(ncid=ncid, varname='LANDMASK', data=mask, flag='read', readvar=readvar)
- if (.not. readvar) then
- call ncd_io(ncid=ncid, varname='mask', data=mask, flag='read', readvar=readvar)
- end if
- end if
- if (.not. readvar) call endrun( msg=' ERROR: landmask not on fatmlndfrc file'//errMsg(sourcefile, __LINE__))
-
- ! Close file
- call ncd_pio_closefile(ncid)
- end if
-
- end subroutine surfrd_get_globmask
-
- !-----------------------------------------------------------------------
- subroutine surfrd_get_grid(begg, endg, ldomain, filename)
-
- ! Read the surface dataset grid related information:
- ! This is called after the domain decomposition has been created
- ! - real latitude of grid cell (degrees)
- ! - real longitude of grid cell (degrees)
-
- use clm_varcon , only : spval, re, grlnd
- use domainMod , only : domain_type, lon1d, lat1d, domain_init
- use fileutils , only : getfil
- use abortutils , only : endrun
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use ncdio_pio , only : file_desc_t, ncd_pio_openfile, ncd_pio_closefile
- use ncdio_pio , only : ncd_io, check_var, ncd_inqfdims, check_dim_size
- use pio
-
- ! input/output variables
- integer , intent(in) :: begg, endg
- type(domain_type) , intent(inout) :: ldomain ! domain to init
- character(len=*) , intent(in) :: filename ! grid filename
-
- ! local variables
- type(file_desc_t) :: ncid ! netcdf id
- integer :: beg ! local beg index
- integer :: end ! local end index
- integer :: ni,nj,ns ! size of grid on file
- logical :: readvar ! true => variable is on input file
- logical :: isgrid2d ! true => file is 2d lat/lon
- logical :: istype_domain ! true => input file is of type domain
- real(r8), allocatable :: rdata2d(:,:) ! temporary
- character(len=16) :: vname ! temporary
- character(len=256) :: locfn ! local file name
- integer :: n ! indices
- character(len=32) :: subname = 'surfrd_get_grid' ! subroutine name
- !-----------------------------------------------------------------------
-
- if (masterproc) then
- if (filename == ' ') then
- write(iulog,*) trim(subname),' ERROR: filename must be specified '
- call endrun(msg=errMsg(sourcefile, __LINE__))
- endif
- end if
-
- call getfil( filename, locfn, 0 )
- call ncd_pio_openfile (ncid, trim(locfn), 0)
-
- ! Determine dimensions
- call ncd_inqfdims(ncid, isgrid2d, ni, nj, ns)
-
- ! Determine isgrid2d flag for domain
- call domain_init(ldomain, isgrid2d=isgrid2d, ni=ni, nj=nj, nbeg=begg, nend=endg)
-
- ! Determine type of file - old style grid file or new style domain file
- call check_var(ncid=ncid, varname='xc', readvar=readvar)
- if (readvar)then
- istype_domain = .true.
- else
- istype_domain = .false.
- end if
-
- ! Read in area, lon, lat
- if (istype_domain) then
- call ncd_io(ncid=ncid, varname= 'area', flag='read', data=ldomain%area, &
- dim1name=grlnd, readvar=readvar)
- ! convert from radians**2 to km**2
- ldomain%area = ldomain%area * (re**2)
- if (.not. readvar) call endrun( msg=' ERROR: area NOT on file'//errMsg(sourcefile, __LINE__))
- call ncd_io(ncid=ncid, varname= 'xc', flag='read', data=ldomain%lonc, &
- dim1name=grlnd, readvar=readvar)
- if (.not. readvar) call endrun( msg=' ERROR: xc NOT on file'//errMsg(sourcefile, __LINE__))
- call ncd_io(ncid=ncid, varname= 'yc', flag='read', data=ldomain%latc, &
- dim1name=grlnd, readvar=readvar)
- if (.not. readvar) call endrun( msg=' ERROR: yc NOT on file'//errMsg(sourcefile, __LINE__))
- else
- call endrun( msg=" ERROR: can no longer read non domain files" )
- end if
-
- if (isgrid2d) then
- allocate(rdata2d(ni,nj), lon1d(ni), lat1d(nj))
- if (istype_domain) vname = 'xc'
- call ncd_io(ncid=ncid, varname=trim(vname), data=rdata2d, flag='read', readvar=readvar)
- lon1d(:) = rdata2d(:,1)
- if (istype_domain) vname = 'yc'
- call ncd_io(ncid=ncid, varname=trim(vname), data=rdata2d, flag='read', readvar=readvar)
- lat1d(:) = rdata2d(1,:)
- deallocate(rdata2d)
- end if
-
- ! Check lat limited to -90,90
- if (minval(ldomain%latc) < -90.0_r8 .or. &
- maxval(ldomain%latc) > 90.0_r8) then
- write(iulog,*) trim(subname),' WARNING: lat/lon min/max is ', &
- minval(ldomain%latc),maxval(ldomain%latc)
- endif
- if ( any(ldomain%lonc < 0.0_r8) )then
- call endrun( msg=' ERROR: lonc is negative (see https://github.com/ESCOMP/ctsm/issues/507)' &
- //errMsg(sourcefile, __LINE__))
- endif
- call ncd_io(ncid=ncid, varname='mask', flag='read', data=ldomain%mask, &
- dim1name=grlnd, readvar=readvar)
- if (.not. readvar) then
- call endrun( msg=' ERROR: LANDMASK NOT on fracdata file'//errMsg(sourcefile, __LINE__))
- end if
- call ncd_io(ncid=ncid, varname='frac', flag='read', data=ldomain%frac, &
- dim1name=grlnd, readvar=readvar)
- if (.not. readvar) then
- call endrun( msg=' ERROR: LANDFRAC NOT on fracdata file'//errMsg(sourcefile, __LINE__))
- end if
-
- call ncd_pio_closefile(ncid)
-
- end subroutine surfrd_get_grid
-
- !------------------------------------------------------------------------------
- subroutine decompInit_lnd3D(lni,lnj,lnk)
- !
- ! !DESCRIPTION:
- ! Create a 3D decomposition gsmap for the global 2D grid with soil levels
- ! as the 3rd dimesnion.
- !
- ! !USES:
- use decompMod, only : gindex_global, bounds_type, get_proc_bounds
- use spmdMod , only : comp_id, mpicom
- use mct_mod , only : mct_gsmap_init
- !
- ! !ARGUMENTS:
- integer , intent(in) :: lni,lnj,lnk ! domain global size
- !
- ! !LOCAL VARIABLES:
- integer :: m,n,k ! indices
- integer :: begg,endg,lsize,gsize ! used for gsmap init
- integer :: begg3d,endg3d
- integer, pointer :: gindex(:) ! global index for gsmap init
- type(bounds_type) :: bounds
- !------------------------------------------------------------------------------
-
- ! Initialize gsmap_lnd2dsoi_gdc2glo
- call get_proc_bounds(bounds)
- begg = bounds%begg; endg=bounds%endg
-
- begg3d = (begg-1)*lnk + 1
- endg3d = endg*lnk
- lsize = (endg3d - begg3d + 1 )
- allocate(gindex(begg3d:endg3d))
- do k = 1, lnk
- do n = begg,endg
- m = (begg-1)*lnk + (k-1)*(endg-begg+1) + (n-begg+1)
- gindex(m) = gindex_global(n-begg+1) + (k-1)*(lni*lnj)
- enddo
- enddo
- gsize = lni * lnj * lnk
- call mct_gsMap_init(gsMap_lnd2Dsoi_gdc2glo, gindex, mpicom, comp_id, lsize, gsize)
-
- ! Diagnostic output
-
- if (masterproc) then
- write(iulog,*)' 3D GSMap'
- write(iulog,*)' longitude points = ',lni
- write(iulog,*)' latitude points = ',lnj
- write(iulog,*)' soil levels = ',lnk
- write(iulog,*)' gsize = ',gsize
- write(iulog,*)' lsize = ',lsize
- write(iulog,*)' bounds(gindex) = ',size(gindex)
- write(iulog,*)
- end if
-
- deallocate(gindex)
-
- end subroutine decompInit_lnd3D
-
-end module lnd_set_decomp_and_domain
diff --git a/src/cpl/mct/ndepStreamMod.F90 b/src/cpl/mct/ndepStreamMod.F90
deleted file mode 100644
index d26ff7c95e..0000000000
--- a/src/cpl/mct/ndepStreamMod.F90
+++ /dev/null
@@ -1,376 +0,0 @@
-module ndepStreamMod
-
- !-----------------------------------------------------------------------
- ! !DESCRIPTION:
- ! Contains methods for reading in nitrogen deposition data file
- ! Also includes functions for dynamic ndep file handling and
- ! interpolation.
- !
- ! !USES
- use shr_kind_mod, only: r8 => shr_kind_r8, CL => shr_kind_cl
- use shr_strdata_mod, only: shr_strdata_type, shr_strdata_create
- use shr_strdata_mod, only: shr_strdata_print, shr_strdata_advance
- use mct_mod , only: mct_ggrid
- use spmdMod , only: mpicom, masterproc, comp_id, iam
- use clm_varctl , only: iulog, inst_name
- use abortutils , only: endrun
- use decompMod , only: bounds_type
- use domainMod , only: ldomain
-
- ! !PUBLIC TYPES:
- implicit none
- private
-
- ! !PUBLIC MEMBER FUNCTIONS:
- public :: ndep_init ! position datasets for dynamic ndep
- public :: ndep_interp ! interpolates between two years of ndep file data
- public :: clm_domain_mct ! Sets up MCT domain for this resolution
-
- ! !PRIVATE MEMBER FUNCTIONS:
- private :: check_units ! Check the units and make sure they can be used
-
- ! ! PRIVATE TYPES
- type(shr_strdata_type) :: sdat ! input data stream
- integer :: stream_year_first_ndep ! first year in stream to use
- integer :: stream_year_last_ndep ! last year in stream to use
- integer :: model_year_align_ndep ! align stream_year_firstndep with
- logical :: divide_by_secs_per_yr = .true. ! divide by the number of seconds per year
-
- character(len=*), parameter, private :: sourcefile = &
- __FILE__
- !==============================================================================
-
-contains
-
- !==============================================================================
-
- subroutine ndep_init(bounds, NLFilename)
- !
- ! Initialize data stream information.
- !
- ! Uses:
- use shr_kind_mod , only : CS => shr_kind_cs
- use clm_time_manager , only : get_calendar
- use ncdio_pio , only : pio_subsystem
- use shr_pio_mod , only : shr_pio_getiotype
- use shr_nl_mod , only : shr_nl_find_group_name
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use shr_mpi_mod , only : shr_mpi_bcast
- use lnd_set_decomp_and_domain , only : gsMap_lnd2Dsoi_gdc2glo, gsmap_global
- !
- ! arguments
- implicit none
- type(bounds_type), intent(in) :: bounds
- character(len=*), intent(in) :: NLFilename ! Namelist filename
- !
- ! local variables
- integer :: nu_nml ! unit for namelist file
- integer :: nml_error ! namelist i/o error flag
- type(mct_ggrid) :: dom_clm ! domain information
- character(len=CL) :: stream_fldFileName_ndep
- character(len=CL) :: ndepmapalgo = 'bilinear'
- character(len=CL) :: ndep_tintalgo = 'linear'
- character(len=CS) :: ndep_taxmode = 'extend'
- character(len=CL) :: ndep_varlist = 'NDEP_year'
- character(*), parameter :: shr_strdata_unset = 'NOT_SET'
- character(*), parameter :: subName = "('ndepdyn_init')"
- character(*), parameter :: F00 = "('(ndepdyn_init) ',4a)"
- !-----------------------------------------------------------------------
-
- namelist /ndepdyn_nml/ &
- stream_year_first_ndep, &
- stream_year_last_ndep, &
- model_year_align_ndep, &
- ndepmapalgo, ndep_taxmode, &
- ndep_varlist, &
- stream_fldFileName_ndep, &
- ndep_tintalgo
-
- ! Default values for namelist
- stream_year_first_ndep = 1 ! first year in stream to use
- stream_year_last_ndep = 1 ! last year in stream to use
- model_year_align_ndep = 1 ! align stream_year_first_ndep with this model year
- stream_fldFileName_ndep = ' '
-
- ! Read ndepdyn_nml namelist
- if (masterproc) then
- open( newunit=nu_nml, file=trim(NLFilename), status='old', iostat=nml_error )
- call shr_nl_find_group_name(nu_nml, 'ndepdyn_nml', status=nml_error)
- if (nml_error == 0) then
- read(nu_nml, nml=ndepdyn_nml,iostat=nml_error)
- if (nml_error /= 0) then
- call endrun(msg=' ERROR reading ndepdyn_nml namelist'//errMsg(sourcefile, __LINE__))
- end if
- else
- call endrun(msg=' ERROR finding ndepdyn_nml namelist'//errMsg(sourcefile, __LINE__))
- end if
- close(nu_nml)
- endif
-
- call shr_mpi_bcast(stream_year_first_ndep , mpicom)
- call shr_mpi_bcast(stream_year_last_ndep , mpicom)
- call shr_mpi_bcast(model_year_align_ndep , mpicom)
- call shr_mpi_bcast(stream_fldFileName_ndep, mpicom)
- call shr_mpi_bcast(ndep_varlist , mpicom)
- call shr_mpi_bcast(ndep_taxmode , mpicom)
- call shr_mpi_bcast(ndep_tintalgo , mpicom)
-
- if (masterproc) then
- write(iulog,*) ' '
- write(iulog,*) 'ndepdyn stream settings:'
- write(iulog,*) ' stream_year_first_ndep = ',stream_year_first_ndep
- write(iulog,*) ' stream_year_last_ndep = ',stream_year_last_ndep
- write(iulog,*) ' model_year_align_ndep = ',model_year_align_ndep
- write(iulog,*) ' stream_fldFileName_ndep = ',stream_fldFileName_ndep
- write(iulog,*) ' ndep_varList = ',ndep_varList
- write(iulog,*) ' ndep_taxmode = ',ndep_taxmode
- write(iulog,*) ' ndep_tintalgo = ',ndep_tintalgo
- write(iulog,*) ' '
- endif
- ! Read in units
- call check_units( stream_fldFileName_ndep, ndep_varList )
-
- ! Set domain and create streams
- call clm_domain_mct (bounds, dom_clm)
-
- call shr_strdata_create(sdat,name="clmndep", &
- pio_subsystem=pio_subsystem, &
- pio_iotype=shr_pio_getiotype(inst_name), &
- mpicom=mpicom, compid=comp_id, &
- gsmap=gsmap_global, ggrid=dom_clm, &
- nxg=ldomain%ni, nyg=ldomain%nj, &
- yearFirst=stream_year_first_ndep, &
- yearLast=stream_year_last_ndep, &
- yearAlign=model_year_align_ndep, &
- offset=0, &
- domFilePath='', &
- domFileName=trim(stream_fldFileName_ndep), &
- domTvarName='time', &
- domXvarName='lon' , &
- domYvarName='lat' , &
- domAreaName='area', &
- domMaskName='mask', &
- filePath='', &
- filename=(/trim(stream_fldFileName_ndep)/),&
- fldListFile=ndep_varlist, &
- fldListModel=ndep_varlist, &
- fillalgo='none', &
- mapalgo=ndepmapalgo, &
- tintalgo=ndep_tintalgo, &
- calendar=get_calendar(), &
- taxmode=ndep_taxmode )
-
-
- if (masterproc) then
- call shr_strdata_print(sdat,'CLMNDEP data')
- endif
-
- end subroutine ndep_init
- !================================================================
-
- subroutine check_units( stream_fldFileName_ndep, ndep_varList )
- !-------------------------------------------------------------------
- ! Check that units are correct on the file and if need any conversion
- use ncdio_pio , only : ncd_pio_openfile, ncd_inqvid, ncd_getatt, ncd_pio_closefile, ncd_nowrite
- use ncdio_pio , only : file_desc_t, var_desc_t
- use shr_kind_mod , only : CS => shr_kind_cs
- use shr_log_mod , only : errMsg => shr_log_errMsg
- use shr_string_mod, only : shr_string_listGetName
- implicit none
-
- !-----------------------------------------------------------------------
- !
- ! Arguments
- character(len=*), intent(IN) :: stream_fldFileName_ndep ! ndep filename
- character(len=*), intent(IN) :: ndep_varList ! ndep variable list to examine
- !
- ! Local variables
- type(file_desc_t) :: ncid ! NetCDF filehandle for ndep file
- type(var_desc_t) :: vardesc ! variable descriptor
- integer :: varid ! variable index
- logical :: readvar ! If variable was read
- character(len=CS) :: ndepunits! ndep units
- character(len=CS) :: fname ! ndep field name
- !-----------------------------------------------------------------------
- call ncd_pio_openfile( ncid, trim(stream_fldFileName_ndep), ncd_nowrite )
- call shr_string_listGetName( ndep_varList, 1, fname )
- call ncd_inqvid( ncid, fname, varid, vardesc, readvar=readvar )
- if ( readvar ) then
- call ncd_getatt( ncid, varid, "units", ndepunits )
- else
- call endrun(msg=' ERROR finding variable: '//trim(fname)//" in file: "// &
- trim(stream_fldFileName_ndep)//errMsg(sourcefile, __LINE__))
- end if
- call ncd_pio_closefile( ncid )
-
- ! Now check to make sure they are correct
- if ( trim(ndepunits) == "g(N)/m2/s" )then
- divide_by_secs_per_yr = .false.
- else if ( trim(ndepunits) == "g(N)/m2/yr" )then
- divide_by_secs_per_yr = .true.
- else
- call endrun(msg=' ERROR in units for nitrogen deposition equal to: '//trim(ndepunits)//" not units expected"// &
- errMsg(sourcefile, __LINE__))
- end if
-
- end subroutine check_units
-
- !================================================================
- subroutine ndep_interp(bounds, atm2lnd_inst)
-
- !-----------------------------------------------------------------------
- use clm_time_manager, only : get_curr_date, get_curr_days_per_year
- use clm_varcon , only : secspday
- use atm2lndType , only : atm2lnd_type
- !
- ! Arguments
- type(bounds_type) , intent(in) :: bounds
- type(atm2lnd_type), intent(inout) :: atm2lnd_inst
- !
- ! Local variables
- integer :: g, ig
- integer :: year ! year (0, ...) for nstep+1
- integer :: mon ! month (1, ..., 12) for nstep+1
- integer :: day ! day of month (1, ..., 31) for nstep+1
- integer :: sec ! seconds into current date for nstep+1
- integer :: mcdate ! Current model date (yyyymmdd)
- integer :: dayspyr ! days per year
- !-----------------------------------------------------------------------
-
- call get_curr_date(year, mon, day, sec)
- mcdate = year*10000 + mon*100 + day
-
- call shr_strdata_advance(sdat, mcdate, sec, mpicom, 'ndepdyn')
-
- if ( divide_by_secs_per_yr )then
- ig = 0
- dayspyr = get_curr_days_per_year( )
- do g = bounds%begg,bounds%endg
- ig = ig+1
- atm2lnd_inst%forc_ndep_grc(g) = sdat%avs(1)%rAttr(1,ig) / (secspday * dayspyr)
- end do
- else
- ig = 0
- do g = bounds%begg,bounds%endg
- ig = ig+1
- atm2lnd_inst%forc_ndep_grc(g) = sdat%avs(1)%rAttr(1,ig)
- end do
- end if
-
- end subroutine ndep_interp
-
- !==============================================================================
- subroutine clm_domain_mct(bounds, dom_clm, nlevels)
-
- !-------------------------------------------------------------------
- ! Set domain data type for internal clm grid
- use clm_varcon , only : re
- use domainMod , only : ldomain
- use mct_mod , only : mct_ggrid, mct_gsMap_lsize, mct_gGrid_init
- use mct_mod , only : mct_gsMap_orderedPoints, mct_gGrid_importIAttr
- use mct_mod , only : mct_gGrid_importRAttr, mct_gsMap
- use lnd_set_decomp_and_domain , only : gsMap_lnd2Dsoi_gdc2glo, gsmap_global
- implicit none
- !
- ! arguments
- type(bounds_type), intent(in) :: bounds
- type(mct_ggrid), intent(out) :: dom_clm ! Output domain information for land model
- integer, intent(in), optional :: nlevels ! Number of levels if this is a 3D field
- !
- ! local variables
- integer :: g,i,j,k ! index
- integer :: lsize ! land model domain data size
- real(r8), pointer :: data(:) ! temporary
- integer , pointer :: idata(:) ! temporary
- integer :: nlevs ! Number of vertical levels
- type(mct_gsMap), pointer :: gsmap => null() ! MCT GS map
- !-------------------------------------------------------------------
- ! SEt number of levels, and get the GS map for either the 2D or 3D grid
- nlevs = 1
- if ( present(nlevels) ) nlevs = nlevels
- if ( nlevs == 1 ) then
- gsmap => gsmap_global
- else
- gsmap => gsMap_lnd2Dsoi_gdc2glo
- end if
- !
- ! Initialize mct domain type
- ! lat/lon in degrees, area in radians^2, mask is 1 (land), 0 (non-land)
- ! Note that in addition land carries around landfrac for the purposes of domain checking
- !
- lsize = mct_gsMap_lsize(gsmap, mpicom)
- call mct_gGrid_init( GGrid=dom_clm, &
- CoordChars='lat:lon:hgt', OtherChars='area:aream:mask:frac', lsize=lsize )
- !
- ! Allocate memory
- !
- allocate(data(lsize))
- !
- ! Determine global gridpoint number attribute, GlobGridNum, which is set automatically by MCT
- !
- call mct_gsMap_orderedPoints(gsmap, iam, idata)
- gsmap => null()
- call mct_gGrid_importIAttr(dom_clm,'GlobGridNum',idata,lsize)
- !
- ! Determine domain (numbering scheme is: West to East and South to North to South pole)
- ! Initialize attribute vector with special value
- !
- data(:) = -9999.0_R8
- call mct_gGrid_importRAttr(dom_clm,"lat" ,data,lsize)
- call mct_gGrid_importRAttr(dom_clm,"lon" ,data,lsize)
- call mct_gGrid_importRAttr(dom_clm,"area" ,data,lsize)
- call mct_gGrid_importRAttr(dom_clm,"aream",data,lsize)
- data(:) = 0.0_R8
- call mct_gGrid_importRAttr(dom_clm,"mask" ,data,lsize)
- !
- ! Determine bounds
- !
- ! Fill in correct values for domain components
- ! Note aream will be filled in in the atm-lnd mapper
- !
- do k = 1, nlevs
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%lonc(g)
- end do
- end do
- call mct_gGrid_importRattr(dom_clm,"lon",data,lsize)
-
- do k = 1, nlevs
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%latc(g)
- end do
- end do
- call mct_gGrid_importRattr(dom_clm,"lat",data,lsize)
-
- do k = 1, nlevs
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = ldomain%area(g)/(re*re)
- end do
- end do
- call mct_gGrid_importRattr(dom_clm,"area",data,lsize)
-
- do k = 1, nlevs
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = real(ldomain%mask(g), r8)
- end do
- end do
- call mct_gGrid_importRattr(dom_clm,"mask",data,lsize)
-
- do k = 1, nlevs
- do g = bounds%begg,bounds%endg
- i = 1 + (g - bounds%begg)
- data(i) = real(ldomain%frac(g), r8)
- end do
- end do
- call mct_gGrid_importRattr(dom_clm,"frac",data,lsize)
-
- deallocate(data)
- deallocate(idata)
-
- end subroutine clm_domain_mct
-
-end module ndepStreamMod
diff --git a/src/cpl/nuopc/lnd_import_export.F90 b/src/cpl/nuopc/lnd_import_export.F90
index 11cc807640..b9966f81e9 100644
--- a/src/cpl/nuopc/lnd_import_export.F90
+++ b/src/cpl/nuopc/lnd_import_export.F90
@@ -248,7 +248,6 @@ subroutine advertise_fields(gcomp, flds_scalar_name, glc_present, cism_evolve, r
if (shr_megan_mechcomps_n .ne. megan_nflds) call shr_sys_abort('ERROR: megan field count mismatch')
! CARMA volumetric soil water from land
- ! TODO: is the following correct - the CARMA field exchange is very confusing in mct
call shr_carma_readnl('drv_flds_in', carma_fields)
! export to atm
diff --git a/src/cpl/share_esmf/UrbanTimeVarType.F90 b/src/cpl/share_esmf/UrbanTimeVarType.F90
index 088ec9eeae..926a2c0557 100644
--- a/src/cpl/share_esmf/UrbanTimeVarType.F90
+++ b/src/cpl/share_esmf/UrbanTimeVarType.F90
@@ -24,6 +24,7 @@ module UrbanTimeVarType
type, public :: urbantv_type
!
real(r8), public, pointer :: t_building_max(:) ! lun maximum internal building air temperature (K)
+ real(r8), public, pointer :: p_ac(:) ! lun air-conditioning adoption rate (unitless, between 0 and 1)
type(shr_strdata_type) :: sdat_urbantv ! urban time varying input data stream
contains
! !PUBLIC MEMBER FUNCTIONS:
@@ -31,8 +32,10 @@ module UrbanTimeVarType
procedure, public :: urbantv_init ! Initialize urban time varying stream
procedure, public :: urbantv_interp ! Interpolate urban time varying stream
end type urbantv_type
-
- character(15), private :: stream_varnames(isturb_MIN:isturb_MAX)
+
+ integer , private :: stream_varname_MIN ! minimum index for stream_varnames
+ integer , private :: stream_varname_MAX ! maximum index for stream_varnames
+ character(15), private, pointer :: stream_varnames(:) ! urban time varying variable names
character(len=*), parameter, private :: sourcefile = &
__FILE__
@@ -48,6 +51,7 @@ subroutine Init(this, bounds, NLFilename)
! !USES:
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use histFileMod , only : hist_addfld1d
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
class(urbantv_type) :: this
@@ -60,9 +64,22 @@ subroutine Init(this, bounds, NLFilename)
begl = bounds%begl; endl = bounds%endl
+ ! Determine the minimum and maximum indices for stream_varnames
+ stream_varname_MIN = 1
+ ! Get value for the maximum index for stream_varnames: if using explicit AC adoption scheme,
+ ! then set maximum index to 6 for reading in tbuildmax and p_ac for three urban density classes;
+ ! otherwise, set to 3 to only read in tbuildmax for three urban density classes.
+ if (urban_explicit_ac) then
+ stream_varname_MAX = 6
+ else
+ stream_varname_MAX = 3
+ end if
+
! Allocate urbantv data structure
allocate(this%t_building_max(begl:endl)); this%t_building_max(:) = nan
+ allocate(this%p_ac(begl:endl)); this%p_ac(:) = nan
+ allocate(stream_varnames(stream_varname_MIN:stream_varname_MAX))
call this%urbantv_init(bounds, NLFilename)
call this%urbantv_interp(bounds)
@@ -72,6 +89,12 @@ subroutine Init(this, bounds, NLFilename)
avgflag='A', long_name='prescribed maximum interior building temperature', &
ptr_lunit=this%t_building_max, default='inactive', set_nourb=spval, &
l2g_scale_type='unity')
+ if (urban_explicit_ac) then
+ call hist_addfld1d (fname='P_AC', units='a fraction between 0 and 1', &
+ avgflag='A', long_name='prescribed air-conditioning ownership rate', &
+ ptr_lunit=this%p_ac, default='inactive', set_nourb=spval, &
+ l2g_scale_type='unity')
+ end if
end subroutine Init
@@ -88,6 +111,7 @@ subroutine urbantv_init(this, bounds, NLFilename)
use landunit_varcon , only : isturb_tbd, isturb_hd, isturb_md
use dshr_strdata_mod , only : shr_strdata_init_from_inline
use lnd_comp_shr , only : mesh, model_clock
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
implicit none
@@ -107,7 +131,6 @@ subroutine urbantv_init(this, bounds, NLFilename)
character(len=CL) :: urbantvmapalgo = 'nn' ! mapping alogrithm for urban ac
character(len=CL) :: urbantv_tintalgo = 'linear' ! time interpolation alogrithm
integer :: rc ! error code
- character(*), parameter :: urbantvString = "tbuildmax_" ! base string for field string
character(*), parameter :: subName = "('urbantv_init')"
!-----------------------------------------------------------------------
@@ -126,9 +149,14 @@ subroutine urbantv_init(this, bounds, NLFilename)
model_year_align_urbantv = 1 ! align stream_year_first_urbantv with this model year
stream_fldFileName_urbantv = ' '
stream_meshfile_urbantv = ' '
- stream_varnames(isturb_tbd) = urbantvString//"TBD"
- stream_varnames(isturb_hd) = urbantvString//"HD"
- stream_varnames(isturb_md) = urbantvString//"MD"
+ stream_varnames(1) = "tbuildmax_TBD"
+ stream_varnames(2) = "tbuildmax_HD"
+ stream_varnames(3) = "tbuildmax_MD"
+ if (urban_explicit_ac) then
+ stream_varnames(4) = "p_ac_TBD"
+ stream_varnames(5) = "p_ac_HD"
+ stream_varnames(6) = "p_ac_MD"
+ end if
! Read urbantv_streams namelist
if (masterproc) then
@@ -159,7 +187,7 @@ subroutine urbantv_init(this, bounds, NLFilename)
write(iulog,'(a,a)' ) ' stream_fldFileName_urbantv = ',stream_fldFileName_urbantv
write(iulog,'(a,a)' ) ' stream_meshfile_urbantv = ',stream_meshfile_urbantv
write(iulog,'(a,a)' ) ' urbantv_tintalgo = ',urbantv_tintalgo
- do n = isturb_tbd,isturb_md
+ do n = stream_varname_MIN,stream_varname_MAX
write(iulog,'(a,a)' ) ' stream_varname = ',trim(stream_varnames(n))
end do
write(iulog,*) ' '
@@ -176,8 +204,8 @@ subroutine urbantv_init(this, bounds, NLFilename)
stream_lev_dimname = 'null', &
stream_mapalgo = trim(urbantvmapalgo), &
stream_filenames = (/trim(stream_fldfilename_urbantv)/), &
- stream_fldlistFile = stream_varnames(isturb_tbd:isturb_md),&
- stream_fldListModel = stream_varnames(isturb_tbd:isturb_md),&
+ stream_fldlistFile = stream_varnames(stream_varname_MIN:stream_varname_MAX), &
+ stream_fldListModel = stream_varnames(stream_varname_MIN:stream_varname_MAX), &
stream_yearFirst = stream_year_first_urbantv, &
stream_yearLast = stream_year_last_urbantv, &
stream_yearAlign = model_year_align_urbantv, &
@@ -204,6 +232,8 @@ subroutine urbantv_interp(this, bounds)
use clm_instur , only : urban_valid
use dshr_methods_mod , only : dshr_fldbun_getfldptr
use dshr_strdata_mod , only : shr_strdata_advance
+ use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
+ use UrbanParamsType , only : urban_explicit_ac
!
! !ARGUMENTS:
class(urbantv_type) :: this
@@ -235,8 +265,8 @@ subroutine urbantv_interp(this, bounds)
! Create 2d array for all stream variable data
lsize = bounds%endg - bounds%begg + 1
- allocate(dataptr2d(lsize, isturb_MIN:isturb_MAX))
- do n = isturb_MIN,isturb_MAX
+ allocate(dataptr2d(lsize, stream_varname_MIN:stream_varname_MAX))
+ do n = stream_varname_MIN,stream_varname_MAX
call dshr_fldbun_getFldPtr(this%sdat_urbantv%pstrm(1)%fldbun_model, trim(stream_varnames(n)), &
fldptr1=dataptr1d, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) then
@@ -249,18 +279,26 @@ subroutine urbantv_interp(this, bounds)
end do
end do
- ! Determine this%tbuilding_max for all landunits
+ ! Determine this%tbuilding_max (and this%p_ac, if applicable) for all landunits
do l = bounds%begl,bounds%endl
if (lun%urbpoi(l)) then
! Note that since l is within [begl, endl] bounds, we can assume
! lun%gricell(l) is within [begg, endg]
ig = lun%gridcell(l) - bounds%begg + 1
- ! Since we are within an urban land unit, we know that
- ! lun%itype is within [pisturb_MIN, isturb_MAX]
- this%t_building_max(l) = dataptr2d(ig, lun%itype(l))
+ do n = stream_varname_MIN,stream_varname_MAX
+ if (stream_varnames((lun%itype(l)-6)) == stream_varnames(n)) then
+ this%t_building_max(l) = dataptr2d(ig,n)
+ end if
+ if (urban_explicit_ac) then
+ if (stream_varnames((lun%itype(l)-3)) == stream_varnames(n)) then
+ this%p_ac(l) = dataptr2d(ig,n)
+ end if
+ end if
+ end do
else
this%t_building_max(l) = spval
+ this%p_ac(l) = spval
end if
end do
deallocate(dataptr2d)
@@ -272,11 +310,17 @@ subroutine urbantv_interp(this, bounds)
do g = bounds%begg,bounds%endg
if (g == lun%gridcell(l)) exit
end do
+ ! Check for valid urban data
if ( .not. urban_valid(g) .or. (this%t_building_max(l) <= 0._r8)) then
found = .true.
gindx = g
lindx = l
exit
+ else if (urban_explicit_ac .and. (this%p_ac(l) < 0._r8 .or. this%p_ac(l) > 1._r8)) then
+ found = .true.
+ gindx = g
+ lindx = l
+ exit
end if
end if
end do
@@ -285,6 +329,7 @@ subroutine urbantv_interp(this, bounds)
write(iulog,*)'landunit type: ',lun%itype(lindx)
write(iulog,*)'urban_valid: ',urban_valid(gindx)
write(iulog,*)'t_building_max: ',this%t_building_max(lindx)
+ write(iulog,*)'p_ac: ',this%p_ac(lindx)
call endrun(subgrid_index=lindx, subgrid_level=subgrid_level_landunit, &
msg=errmsg(sourcefile, __LINE__))
end if
diff --git a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90 b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
index 45f4340d6a..1bc6ab929e 100644
--- a/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
+++ b/src/dyn_subgrid/dynFATESLandUseChangeMod.F90
@@ -26,13 +26,40 @@ module dynFATESLandUseChangeMod
! Landuse state at beginning of year (fraction of gridcell), landuse state name x gridcell
real(r8), allocatable, public :: landuse_states(:,:)
+ ! TODO SSR: Ask Charlie for description to go here
+ real(r8), allocatable, public :: landuse_harvest(:,:)
+
! Number of landuse transition and state names
integer, public, parameter :: num_landuse_transition_vars = 108
integer, public, parameter :: num_landuse_state_vars = 12
+ integer, public, parameter :: num_landuse_harvest_vars = 5
+
+ ! Define the fates landuse namelist mode switch values
+ character(len=18), public, parameter :: fates_harvest_no_logging = 'no_harvest'
+ character(len=18), public, parameter :: fates_harvest_logging_only = 'event_code'
+ character(len=18), public, parameter :: fates_harvest_clmlanduse = 'landuse_timeseries'
+ character(len=18), public, parameter :: fates_harvest_luh_area = 'luhdata_area'
+ character(len=18), public, parameter :: fates_harvest_luh_mass = 'luhdata_mass'
+
+ ! Define landuse harvest unit integer representation
+ integer, public, parameter :: landuse_harvest_area_units = 1
+ integer, public, parameter :: landuse_harvest_mass_units = 2
+ integer, public :: landuse_harvest_units
! landuse filename
type(dyn_file_type), target :: dynFatesLandUse_file
+ ! LUH2 raw wood harvest area fraction
+ ! LUH2 data set variable names can be found at https://luh.umd.edu/LUH2/LUH2_v2h_README.pdf
+ character(len=10), target :: landuse_harvest_area_varnames(num_landuse_harvest_vars) = &
+ [character(len=10) :: 'primf_harv', 'primn_harv', 'secmf_harv', 'secyf_harv', 'secnf_harv']
+
+ ! LUH2 raw wood harvest biomass carbon
+ character(len=10), target :: landuse_harvest_mass_varnames(num_landuse_harvest_vars) = &
+ [character(len=10) :: 'primf_bioh', 'primn_bioh', 'secmf_bioh', 'secyf_bioh', 'secnf_bioh']
+
+ character(len=10), public, pointer :: landuse_harvest_varnames(:) => null()
+
! Land use name arrays
character(len=5), public, parameter :: landuse_state_varnames(num_landuse_state_vars) = &
[character(len=5) :: 'primf','primn','secdf','secdn','pastr','range', &
@@ -64,8 +91,9 @@ module dynFATESLandUseChangeMod
'c3nfx_to_c3ann','c3nfx_to_c4ann','c3nfx_to_c3per','c3nfx_to_c4per', &
'c3nfx_to_secdf','c3nfx_to_secdn','c3nfx_to_pastr','c3nfx_to_range','c3nfx_to_urban']
- type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each landuse variable
- type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each landuse variable
+ type(dyn_var_time_uninterp_type) :: landuse_transition_vars(num_landuse_transition_vars) ! value of each transitions variable
+ type(dyn_var_time_uninterp_type) :: landuse_state_vars(num_landuse_state_vars) ! value of each state variable
+ type(dyn_var_time_uninterp_type) :: landuse_harvest_vars(num_landuse_harvest_vars) ! value of each harvest variable
public :: dynFatesLandUseInit
public :: dynFatesLandUseInterp
@@ -79,14 +107,15 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename)
! Initialize data structures for land use information.
! !USES:
- use clm_varctl , only : use_cn, use_fates_luh
+ use clm_varctl , only : use_cn, use_fates_luh, fates_harvest_mode
+ use clm_varctl , only : use_fates_potentialveg
use dynVarTimeUninterpMod , only : dyn_var_time_uninterp_type
use dynTimeInfoMod , only : YEAR_POSITION_START_OF_TIMESTEP
use dynTimeInfoMod , only : YEAR_POSITION_END_OF_TIMESTEP
! !ARGUMENTS:
type(bounds_type), intent(in) :: bounds ! proc-level bounds
- character(len=*) , intent(in) :: landuse_filename ! name of file containing land use information
+ character(len=*) , intent(in) :: landuse_filename ! name of file containing landuse timeseries information (fates luh2)
! !LOCAL VARIABLES
integer :: varnum, i ! counter for harvest variables
@@ -111,37 +140,69 @@ subroutine dynFatesLandUseInit(bounds, landuse_filename)
if (ier /= 0) then
call endrun(msg=' allocation error for landuse_transitions'//errMsg(__FILE__, __LINE__))
end if
+ allocate(landuse_harvest(num_landuse_harvest_vars,bounds%begg:bounds%endg),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_harvest'//errMsg(__FILE__, __LINE__))
+ end if
+ ! Initialize the states, transitions and harvest mapping percentages as zero by default
landuse_states = 0._r8
landuse_transitions = 0._r8
-
- if (use_fates_luh) then
-
- ! Generate the dyn_file_type object. Note that the land use data being read in is for the
- ! transitions occuring within the current year
- dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP)
-
- ! Get initial land use data
- num_points = (bounds%endg - bounds%begg + 1)
- landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor?
- do varnum = 1, num_landuse_transition_vars
- landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( &
- dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), &
- dim1name=grlnd, conversion_factor=1.0_r8, &
- do_check_sums_equal_1=.false., data_shape=landuse_shape)
- end do
- do varnum = 1, num_landuse_state_vars
- landuse_state_vars(varnum) = dyn_var_time_uninterp_type( &
- dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), &
- dim1name=grlnd, conversion_factor=1.0_r8, &
- do_check_sums_equal_1=.false., data_shape=landuse_shape)
- end do
+ landuse_harvest = 0._r8
+
+ ! Avoid initializing the landuse timeseries file if in fates potential vegetation mode
+ if (.not. use_fates_potentialveg) then
+ if (use_fates_luh) then
+
+ ! Generate the dyn_file_type object.
+ ! Start calls get_prev_date, whereas end calls get_curr_date
+ dynFatesLandUse_file = dyn_file_type(landuse_filename, YEAR_POSITION_END_OF_TIMESTEP)
+
+ ! Get initial land use data from the fates luh2 timeseries dataset
+ num_points = (bounds%endg - bounds%begg + 1)
+ landuse_shape(1) = num_points ! Does this need an explicit array shape to be passed to the constructor?
+ do varnum = 1, num_landuse_transition_vars
+ landuse_transition_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_transition_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+ do varnum = 1, num_landuse_state_vars
+ landuse_state_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_state_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+
+ ! Get the harvest rate data from the fates luh2 timeseries dataset if enabled
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then
+
+ ! change the harvest varnames being used depending on the mode selected
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area ) then
+ landuse_harvest_varnames => landuse_harvest_area_varnames
+ landuse_harvest_units = landuse_harvest_area_units
+ elseif (trim(fates_harvest_mode) .eq. fates_harvest_luh_mass ) then
+ landuse_harvest_varnames => landuse_harvest_mass_varnames
+ landuse_harvest_units = landuse_harvest_mass_units
+ else
+ call endrun(msg=' undefined fates harvest mode selected'//errMsg(__FILE__, __LINE__))
+ end if
+
+ do varnum = 1, num_landuse_harvest_vars
+ landuse_harvest_vars(varnum) = dyn_var_time_uninterp_type( &
+ dyn_file=dynFatesLandUse_file, varname=landuse_harvest_varnames(varnum), &
+ dim1name=grlnd, conversion_factor=1.0_r8, &
+ do_check_sums_equal_1=.false., data_shape=landuse_shape)
+ end do
+ end if
+ end if
+
+ ! Since fates needs state data during initialization, make sure to call
+ ! the interpolation routine at the start
+ call dynFatesLandUseInterp(bounds,init_state=.true.)
end if
- ! Since fates needs state data during initialization, make sure to call
- ! the interpolation routine at the start
- call dynFatesLandUseInterp(bounds,init_state=.true.)
-
end subroutine dynFatesLandUseInit
@@ -159,7 +220,7 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
! !USES:
use dynTimeInfoMod , only : time_info_type
- use clm_varctl , only : use_cn
+ use clm_varctl , only : use_cn, fates_harvest_mode
! !ARGUMENTS:
type(bounds_type), intent(in) :: bounds ! proc-level bounds
@@ -181,13 +242,14 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
init_flag = init_state
end if
- ! Get the current year
+ ! Get the data for the current year
call dynFatesLandUse_file%time_info%set_current_year()
if (dynFatesLandUse_file%time_info%is_before_time_series() .and. .not.(init_flag)) then
! Reset the land use transitions to zero for safety
landuse_transitions(1:num_landuse_transition_vars,bounds%begg:bounds%endg) = 0._r8
landuse_states(1:num_landuse_state_vars,bounds%begg:bounds%endg) = 0._r8
+ landuse_harvest(1:num_landuse_harvest_vars,bounds%begg:bounds%endg) = 0._r8
else
! Loop through all variables on the data file and put data into the temporary array
! then update the global state and transitions array.
@@ -200,6 +262,13 @@ subroutine dynFatesLandUseInterp(bounds, init_state)
call landuse_state_vars(varnum)%get_current_data(this_data)
landuse_states(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg)
end do
+ if (trim(fates_harvest_mode) .eq. fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) .eq. fates_harvest_luh_mass) then
+ do varnum = 1, num_landuse_harvest_vars
+ call landuse_harvest_vars(varnum)%get_current_data(this_data)
+ landuse_harvest(varnum,bounds%begg:bounds%endg) = this_data(bounds%begg:bounds%endg)
+ end do
+ end if
deallocate(this_data)
end if
diff --git a/src/dyn_subgrid/dynGrossUnrepMod.F90 b/src/dyn_subgrid/dynGrossUnrepMod.F90
index 8d0e7ee004..7ad860f0ce 100644
--- a/src/dyn_subgrid/dynGrossUnrepMod.F90
+++ b/src/dyn_subgrid/dynGrossUnrepMod.F90
@@ -24,6 +24,7 @@ module dynGrossUnrepMod
use clm_varpar , only : natpft_size, i_litr_min, i_litr_max, i_met_lit
use ColumnType , only : col
use PatchType , only : patch
+ use CNSharedParamsMod , only : use_matrixcn
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
@@ -157,6 +158,7 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
use pftconMod , only : noveg, nbrdlf_evr_shrub, nc4_grass
use clm_varcon , only : secspday
use clm_time_manager, only : get_step_size_real, is_beg_curr_year
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
! !ARGUMENTS:
integer , intent(in) :: num_soilp ! number of soil patches in filter
@@ -266,7 +268,44 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
gru_livestemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livestemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
gru_deadstemn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadstemn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
gru_livecrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_livecrootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
- gru_deadcrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_xfer_to_atm_patch & ! Output: [real(r8) (:)]
+ gru_deadcrootn_xfer_to_atm => cnveg_nitrogenflux_inst%gru_deadcrootn_xfer_to_atm_patch , & ! Output: [real(r8) (:)]
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm &
)
dtime = get_step_size_real()
@@ -294,61 +333,157 @@ subroutine CNGrossUnrep (num_soilp, filter_soilp, &
m = 0._r8
end if
- ! patch-level gross unrepresented landcover change carbon fluxes
- ! displayed pools
- gru_leafc_to_litter(p) = leafc(p) * m
- gru_frootc_to_litter(p) = frootc(p) * m
- gru_livestemc_to_atm(p) = livestemc(p) * m
- gru_deadstemc_to_atm(p) = deadstemc(p) * m * convfrac(ivt(p))
- gru_wood_productc_gain(p) = deadstemc(p) * m * (1._r8 - convfrac(ivt(p)))
- gru_livecrootc_to_litter(p) = livecrootc(p) * m
- gru_deadcrootc_to_litter(p) = deadcrootc(p) * m
- gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
-
- ! storage pools
- gru_leafc_storage_to_atm(p) = leafc_storage(p) * m
- gru_frootc_storage_to_atm(p) = frootc_storage(p) * m
- gru_livestemc_storage_to_atm(p) = livestemc_storage(p) * m
- gru_deadstemc_storage_to_atm(p) = deadstemc_storage(p) * m
- gru_livecrootc_storage_to_atm(p) = livecrootc_storage(p) * m
- gru_deadcrootc_storage_to_atm(p) = deadcrootc_storage(p) * m
- gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
-
- ! transfer pools
- gru_leafc_xfer_to_atm(p) = leafc_xfer(p) * m
- gru_frootc_xfer_to_atm(p) = frootc_xfer(p) * m
- gru_livestemc_xfer_to_atm(p) = livestemc_xfer(p) * m
- gru_deadstemc_xfer_to_atm(p) = deadstemc_xfer(p) * m
- gru_livecrootc_xfer_to_atm(p) = livecrootc_xfer(p) * m
- gru_deadcrootc_xfer_to_atm(p) = deadcrootc_xfer(p) * m
- gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
-
- ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
- ! displayed pools
- gru_leafn_to_litter(p) = leafn(p) * m
- gru_frootn_to_litter(p) = frootn(p) * m
- gru_livestemn_to_atm(p) = livestemn(p) * m
- gru_deadstemn_to_atm(p) = deadstemn(p) * m * convfrac(ivt(p))
- gru_wood_productn_gain(p) = deadstemn(p) * m * (1._r8 - convfrac(ivt(p)))
- gru_livecrootn_to_litter(p) = livecrootn(p) * m
- gru_deadcrootn_to_litter(p) = deadcrootn(p) * m
- gru_retransn_to_litter(p) = retransn(p) * m
-
- ! storage pools
- gru_leafn_storage_to_atm(p) = leafn_storage(p) * m
- gru_frootn_storage_to_atm(p) = frootn_storage(p) * m
- gru_livestemn_storage_to_atm(p) = livestemn_storage(p) * m
- gru_deadstemn_storage_to_atm(p) = deadstemn_storage(p) * m
- gru_livecrootn_storage_to_atm(p) = livecrootn_storage(p) * m
- gru_deadcrootn_storage_to_atm(p) = deadcrootn_storage(p) * m
-
- ! transfer pools
- gru_leafn_xfer_to_atm(p) = leafn_xfer(p) * m
- gru_frootn_xfer_to_atm(p) = frootn_xfer(p) * m
- gru_livestemn_xfer_to_atm(p) = livestemn_xfer(p) * m
- gru_deadstemn_xfer_to_atm(p) = deadstemn_xfer(p) * m
- gru_livecrootn_xfer_to_atm(p) = livecrootn_xfer(p) * m
- gru_deadcrootn_xfer_to_atm(p) = deadcrootn_xfer(p) * m
+ if(.not. use_matrixcn)then
+ ! patch-level gross unrepresented landcover change carbon fluxes
+ ! displayed pools
+ gru_leafc_to_litter(p) = leafc(p) * m
+ gru_frootc_to_litter(p) = frootc(p) * m
+ gru_livestemc_to_atm(p) = livestemc(p) * m
+ gru_deadstemc_to_atm(p) = deadstemc(p) * m * convfrac(ivt(p))
+ gru_wood_productc_gain(p) = deadstemc(p) * m * (1._r8 - convfrac(ivt(p)))
+ gru_livecrootc_to_litter(p) = livecrootc(p) * m
+ gru_deadcrootc_to_litter(p) = deadcrootc(p) * m
+ gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ gru_leafc_storage_to_atm(p) = leafc_storage(p) * m
+ gru_frootc_storage_to_atm(p) = frootc_storage(p) * m
+ gru_livestemc_storage_to_atm(p) = livestemc_storage(p) * m
+ gru_deadstemc_storage_to_atm(p) = deadstemc_storage(p) * m
+ gru_livecrootc_storage_to_atm(p) = livecrootc_storage(p) * m
+ gru_deadcrootc_storage_to_atm(p) = deadcrootc_storage(p) * m
+ gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ gru_leafc_xfer_to_atm(p) = leafc_xfer(p) * m
+ gru_frootc_xfer_to_atm(p) = frootc_xfer(p) * m
+ gru_livestemc_xfer_to_atm(p) = livestemc_xfer(p) * m
+ gru_deadstemc_xfer_to_atm(p) = deadstemc_xfer(p) * m
+ gru_livecrootc_xfer_to_atm(p) = livecrootc_xfer(p) * m
+ gru_deadcrootc_xfer_to_atm(p) = deadcrootc_xfer(p) * m
+ gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
+
+ ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
+ ! displayed pools
+ gru_leafn_to_litter(p) = leafn(p) * m
+ gru_frootn_to_litter(p) = frootn(p) * m
+ gru_livestemn_to_atm(p) = livestemn(p) * m
+ gru_deadstemn_to_atm(p) = deadstemn(p) * m * convfrac(ivt(p))
+ gru_wood_productn_gain(p) = deadstemn(p) * m * (1._r8 - convfrac(ivt(p)))
+ gru_livecrootn_to_litter(p) = livecrootn(p) * m
+ gru_deadcrootn_to_litter(p) = deadcrootn(p) * m
+ gru_retransn_to_litter(p) = retransn(p) * m
+
+ ! storage pools
+ gru_leafn_storage_to_atm(p) = leafn_storage(p) * m
+ gru_frootn_storage_to_atm(p) = frootn_storage(p) * m
+ gru_livestemn_storage_to_atm(p) = livestemn_storage(p) * m
+ gru_deadstemn_storage_to_atm(p) = deadstemn_storage(p) * m
+ gru_livecrootn_storage_to_atm(p) = livecrootn_storage(p) * m
+ gru_deadcrootn_storage_to_atm(p) = deadcrootn_storage(p) * m
+
+ ! transfer pools
+ gru_leafn_xfer_to_atm(p) = leafn_xfer(p) * m
+ gru_frootn_xfer_to_atm(p) = frootn_xfer(p) * m
+ gru_livestemn_xfer_to_atm(p) = livestemn_xfer(p) * m
+ gru_deadstemn_xfer_to_atm(p) = deadstemn_xfer(p) * m
+ gru_livecrootn_xfer_to_atm(p) = livecrootn_xfer(p) * m
+ gru_deadcrootn_xfer_to_atm(p) = deadcrootn_xfer(p) * m
+ else ! matrixcn solution
+ ! patch-level gross unrepresented landcover change carbon fluxes
+ ! displayed pools
+ gru_leafc_to_litter(p) = matrix_update_gmc(p,ileaf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc(p)
+ gru_frootc_to_litter(p) = matrix_update_gmc(p,ifroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc(p)
+ gru_livestemc_to_atm(p) = matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc(p)
+ gru_deadstemc_to_atm(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m * convfrac(ivt(p)),dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ gru_wood_productc_gain(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m * (1._r8 - convfrac(ivt(p))),dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ gru_livecrootc_to_litter(p) = matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc(p)
+ gru_deadcrootc_to_litter(p) = matrix_update_gmc(p,ideadcroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc(p)
+ gru_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ gru_leafc_storage_to_atm(p) = matrix_update_gmc(p,ileafst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_storage(p)
+ gru_frootc_storage_to_atm(p) = matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_storage(p)
+ gru_livestemc_storage_to_atm(p) = matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_storage(p)
+ gru_deadstemc_storage_to_atm(p) = matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_storage(p)
+ gru_livecrootc_storage_to_atm(p) = matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_storage(p)
+ gru_deadcrootc_storage_to_atm(p) = matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_storage(p)
+ gru_gresp_storage_to_atm(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ gru_leafc_xfer_to_atm(p) = matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_xfer(p)
+ gru_frootc_xfer_to_atm(p) = matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_xfer(p)
+ gru_livestemc_xfer_to_atm(p) = matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_xfer(p)
+ gru_deadstemc_xfer_to_atm(p) = matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_xfer(p)
+ gru_livecrootc_xfer_to_atm(p) = matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_xfer(p)
+ gru_deadcrootc_xfer_to_atm(p) = matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_xfer(p)
+ gru_gresp_xfer_to_atm(p) = gresp_xfer(p) * m
+
+ ! patch-level gross unrepresented landcover change mortality nitrogen fluxes
+ ! displayed pools
+ gru_leafn_to_litter(p) = matrix_update_gmn(p,ileaf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn(p)
+ gru_frootn_to_litter(p) = matrix_update_gmn(p,ifroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn(p)
+ gru_livestemn_to_atm(p) = matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn(p)
+ gru_deadstemn_to_atm(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m * convfrac(ivt(p)),dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ gru_wood_productn_gain(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m * (1._r8 - convfrac(ivt(p))),dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ gru_livecrootn_to_litter(p) = matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn(p)
+ gru_deadcrootn_to_litter(p) = matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn(p)
+ gru_retransn_to_litter(p) = matrix_update_gmn(p,iretransn_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ retransn(p)
+
+ ! storage pools
+ gru_leafn_storage_to_atm(p) = matrix_update_gmn(p,ileafst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_storage(p)
+ gru_frootn_storage_to_atm(p) = matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_storage(p)
+ gru_livestemn_storage_to_atm(p) = matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_storage(p)
+ gru_deadstemn_storage_to_atm(p) = matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_storage(p)
+ gru_livecrootn_storage_to_atm(p) = matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)* &
+ livecrootn_storage(p)
+ gru_deadcrootn_storage_to_atm(p) = matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)* &
+ deadcrootn_storage(p)
+ ! transfer pools
+ gru_leafn_xfer_to_atm(p) = matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_xfer(p)
+ gru_frootn_xfer_to_atm(p) = matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_xfer(p)
+ gru_livestemn_xfer_to_atm(p) = matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_xfer(p)
+ gru_deadstemn_xfer_to_atm(p) = matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_xfer(p)
+ gru_livecrootn_xfer_to_atm(p) = matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn_xfer(p)
+ gru_deadcrootn_xfer_to_atm(p) = matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn_xfer(p)
+ end if
end if ! end tree block
diff --git a/src/dyn_subgrid/dynHarvestMod.F90 b/src/dyn_subgrid/dynHarvestMod.F90
index d5a72aa547..fa4f5c33bb 100644
--- a/src/dyn_subgrid/dynHarvestMod.F90
+++ b/src/dyn_subgrid/dynHarvestMod.F90
@@ -23,8 +23,8 @@ module dynHarvestMod
use clm_varcon , only : grlnd
use ColumnType , only : col
use PatchType , only : patch
- use clm_varctl , only : use_fates
use CNSharedParamsMod , only : use_matrixcn
+ use clm_varctl , only : use_fates
!
! !PUBLIC MEMBER FUNCTIONS:
implicit none
@@ -245,6 +245,7 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
use pftconMod , only : noveg, nbrdlf_evr_shrub
use clm_varcon , only : secspday
use clm_time_manager, only : get_step_size_real, is_beg_curr_year
+ use CNVegMatrixMod , only : matrix_update_gmc, matrix_update_gmn
!
! !ARGUMENTS:
integer , intent(in) :: num_soilp ! number of soil patches in filter
@@ -351,7 +352,44 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
hrv_livestemn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_livestemn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
hrv_deadstemn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadstemn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
hrv_livecrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_livecrootn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
- hrv_deadcrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadcrootn_xfer_to_litter_patch & ! Output: [real(r8) (:)]
+ hrv_deadcrootn_xfer_to_litter => cnveg_nitrogenflux_inst%hrv_deadcrootn_xfer_to_litter_patch , & ! Output: [real(r8) (:)]
+ ileaf_to_iout_gmc => cnveg_carbonflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmc => cnveg_carbonflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmc => cnveg_carbonflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmc => cnveg_carbonflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmc => cnveg_carbonflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmc => cnveg_carbonflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmc => cnveg_carbonflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmc => cnveg_carbonflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmc => cnveg_carbonflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmc => cnveg_carbonflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmc => cnveg_carbonflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmc => cnveg_carbonflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmc => cnveg_carbonflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmc => cnveg_carbonflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmc => cnveg_carbonflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmc => cnveg_carbonflux_inst%ideadcrootxf_to_iout_gm , &
+ ileaf_to_iout_gmn => cnveg_nitrogenflux_inst%ileaf_to_iout_gm , &
+ ileafst_to_iout_gmn => cnveg_nitrogenflux_inst%ileafst_to_iout_gm , &
+ ileafxf_to_iout_gmn => cnveg_nitrogenflux_inst%ileafxf_to_iout_gm , &
+ ifroot_to_iout_gmn => cnveg_nitrogenflux_inst%ifroot_to_iout_gm , &
+ ifrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootst_to_iout_gm , &
+ ifrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ifrootxf_to_iout_gm , &
+ ilivestem_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestem_to_iout_gm , &
+ ilivestemst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemst_to_iout_gm , &
+ ilivestemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivestemxf_to_iout_gm , &
+ ideadstem_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstem_to_iout_gm , &
+ ideadstemst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemst_to_iout_gm , &
+ ideadstemxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadstemxf_to_iout_gm , &
+ ilivecroot_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecroot_to_iout_gm , &
+ ilivecrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootst_to_iout_gm , &
+ ilivecrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ilivecrootxf_to_iout_gm , &
+ ideadcroot_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcroot_to_iout_gm , &
+ ideadcrootst_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootst_to_iout_gm , &
+ ideadcrootxf_to_iout_gmn => cnveg_nitrogenflux_inst%ideadcrootxf_to_iout_gm , &
+ iretransn_to_iout_gmn => cnveg_nitrogenflux_inst%iretransn_to_iout_gm &
)
dtime = get_step_size_real()
@@ -389,9 +427,9 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
m = 0._r8
end if
- ! patch-level harvest carbon fluxes
- ! displayed pools
if(.not. use_matrixcn)then
+ ! patch-level harvest carbon fluxes
+ ! displayed pools
hrv_leafc_to_litter(p) = leafc(p) * m
hrv_frootc_to_litter(p) = frootc(p) * m
hrv_livestemc_to_litter(p) = livestemc(p) * m
@@ -447,8 +485,96 @@ subroutine CNHarvest (num_soilp, filter_soilp, &
! NOTE: The non-matrix part of this update is in CNCStatUpdate2 CStateUpdate2h (EBK 11/25/2019)
! and for Nitrogen The non-matrix part of this update is in CNNStatUpdate2 NStateUpdate2h (EBK 11/25/2019)
else
+ ! patch-level harvest carbon fluxes
+ ! displayed pools
+ hrv_leafc_to_litter(p) = matrix_update_gmc(p,ileaf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc(p)
+ hrv_frootc_to_litter(p) = matrix_update_gmc(p,ifroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc(p)
+ hrv_livestemc_to_litter(p) = matrix_update_gmc(p,ilivestem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc(p)
+ wood_harvestc(p) = matrix_update_gmc(p,ideadstem_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc(p)
+ hrv_livecrootc_to_litter(p) = matrix_update_gmc(p,ilivecroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc(p)
+ hrv_deadcrootc_to_litter(p) = matrix_update_gmc(p,ideadcroot_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc(p)
+ hrv_xsmrpool_to_atm(p) = xsmrpool(p) * m
+
+ ! storage pools
+ hrv_leafc_storage_to_litter(p) = matrix_update_gmc(p,ileafst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_storage(p)
+ hrv_frootc_storage_to_litter(p) = matrix_update_gmc(p,ifrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_storage(p)
+ hrv_livestemc_storage_to_litter(p) = matrix_update_gmc(p,ilivestemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_storage(p)
+ hrv_deadstemc_storage_to_litter(p) = matrix_update_gmc(p,ideadstemst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_storage(p)
+ hrv_livecrootc_storage_to_litter(p) = matrix_update_gmc(p,ilivecrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_storage(p)
+ hrv_deadcrootc_storage_to_litter(p) = matrix_update_gmc(p,ideadcrootst_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_storage(p)
+ hrv_gresp_storage_to_litter(p) = gresp_storage(p) * m
+
+ ! transfer pools
+ hrv_leafc_xfer_to_litter(p) = matrix_update_gmc(p,ileafxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ leafc_xfer(p)
+ hrv_frootc_xfer_to_litter(p) = matrix_update_gmc(p,ifrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ frootc_xfer(p)
+ hrv_livestemc_xfer_to_litter(p) = matrix_update_gmc(p,ilivestemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livestemc_xfer(p)
+ hrv_deadstemc_xfer_to_litter(p) = matrix_update_gmc(p,ideadstemxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadstemc_xfer(p)
+ hrv_livecrootc_xfer_to_litter(p) = matrix_update_gmc(p,ilivecrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ livecrootc_xfer(p)
+ hrv_deadcrootc_xfer_to_litter(p) = matrix_update_gmc(p,ideadcrootxf_to_iout_gmc,m,dtime,cnveg_carbonflux_inst,.True.,.True.) * &
+ deadcrootc_xfer(p)
+ hrv_gresp_xfer_to_litter(p) = gresp_xfer(p) * m
+
+ ! patch-level harvest mortality nitrogen fluxes
+ ! displayed pools
+ hrv_leafn_to_litter(p) = matrix_update_gmn(p,ileaf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn(p)
+ hrv_frootn_to_litter(p) = matrix_update_gmn(p,ifroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn(p)
+ hrv_livestemn_to_litter(p) = matrix_update_gmn(p,ilivestem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn(p)
+ wood_harvestn(p) = matrix_update_gmn(p,ideadstem_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn(p)
+ hrv_livecrootn_to_litter(p) = matrix_update_gmn(p,ilivecroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn(p)
+ hrv_deadcrootn_to_litter(p) = matrix_update_gmn(p,ideadcroot_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn(p)
+ hrv_retransn_to_litter(p) = matrix_update_gmn(p,iretransn_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ retransn(p)
+
+ ! storage pools
+ hrv_leafn_storage_to_litter(p) = matrix_update_gmn(p,ileafst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ leafn_storage(p)
+ hrv_frootn_storage_to_litter(p) = matrix_update_gmn(p,ifrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ frootn_storage(p)
+ hrv_livestemn_storage_to_litter(p) = matrix_update_gmn(p,ilivestemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ livestemn_storage(p)
+ hrv_deadstemn_storage_to_litter(p) = matrix_update_gmn(p,ideadstemst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) *&
+ deadstemn_storage(p)
+ hrv_livecrootn_storage_to_litter(p) = matrix_update_gmn(p,ilivecrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)*&
+ livecrootn_storage(p)
+ hrv_deadcrootn_storage_to_litter(p) = matrix_update_gmn(p,ideadcrootst_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.)*&
+ deadcrootn_storage(p)
+ ! transfer pools
+ hrv_leafn_xfer_to_litter(p) = matrix_update_gmn(p,ileafxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ leafn_xfer(p)
+ hrv_frootn_xfer_to_litter(p) = matrix_update_gmn(p,ifrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ frootn_xfer(p)
+ hrv_livestemn_xfer_to_litter(p) = matrix_update_gmn(p,ilivestemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livestemn_xfer(p)
+ hrv_deadstemn_xfer_to_litter(p) = matrix_update_gmn(p,ideadstemxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadstemn_xfer(p)
+ hrv_livecrootn_xfer_to_litter(p) = matrix_update_gmn(p,ilivecrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ livecrootn_xfer(p)
+ hrv_deadcrootn_xfer_to_litter(p) = matrix_update_gmn(p,ideadcrootxf_to_iout_gmn,m,dtime,cnveg_nitrogenflux_inst,.True.,.True.) * &
+ deadcrootn_xfer(p)
end if
-
end if ! end tree block
end do ! end of pft loop
diff --git a/src/dyn_subgrid/dynSubgridDriverMod.F90 b/src/dyn_subgrid/dynSubgridDriverMod.F90
index e5ca3f002e..ea1210521d 100644
--- a/src/dyn_subgrid/dynSubgridDriverMod.F90
+++ b/src/dyn_subgrid/dynSubgridDriverMod.F90
@@ -89,6 +89,11 @@ subroutine dynSubgrid_init(bounds_proc, glc_behavior, crop_inst)
! Note that dynpft_init needs to be called from outside any loops over clumps - so
! this routine needs to be called from outside any loops over clumps.
!
+ !
+ ! !USES:
+ use clm_varctl , only : fates_harvest_mode
+ use dynFATESLandUseChangeMod , only : fates_harvest_clmlanduse
+ !
! !ARGUMENTS:
type(bounds_type) , intent(in) :: bounds_proc ! processor-level bounds
type(glc_behavior_type) , intent(in) :: glc_behavior
@@ -123,7 +128,7 @@ subroutine dynSubgrid_init(bounds_proc, glc_behavior, crop_inst)
! flanduse_timeseries file. However, this could theoretically be changed so that the
! harvest data were separated from the pftdyn data, allowing them to differ in the
! years over which they apply.
- if (get_do_harvest()) then
+ if (get_do_harvest() .or. trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
call dynHarvest_init(bounds_proc, harvest_filename=get_flanduse_timeseries())
end if
@@ -201,7 +206,7 @@ subroutine dynSubgrid_driver(bounds_proc,
! OUTSIDE any loops over clumps in the driver.
!
! !USES:
- use clm_varctl , only : use_cn, use_fates, use_fates_luh
+ use clm_varctl , only : use_cn, use_fates, use_fates_luh, use_fates_potentialveg
use dynInitColumnsMod , only : initialize_new_columns
use dynConsBiogeophysMod , only : dyn_hwcontent_init, dyn_hwcontent_final
use dynEDMod , only : dyn_ED
@@ -290,7 +295,7 @@ subroutine dynSubgrid_driver(bounds_proc,
call dynurban_interp(bounds_proc)
end if
- if (use_fates_luh) then
+ if (use_fates_luh .and. .not. use_fates_potentialveg) then
call dynFatesLandUseInterp(bounds_proc)
end if
diff --git a/src/fates b/src/fates
new file mode 160000
index 0000000000..1982b0032c
--- /dev/null
+++ b/src/fates
@@ -0,0 +1 @@
+Subproject commit 1982b0032c3cab6278892eccb85f643114ffb1af
diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90
index e660ab9d8d..01c0ec409e 100644
--- a/src/main/clm_driver.F90
+++ b/src/main/clm_driver.F90
@@ -62,7 +62,6 @@ module clm_driver
use ndepStreamMod , only : ndep_interp
use cropcalStreamMod , only : cropcal_advance, cropcal_interp
use ch4Mod , only : ch4, ch4_init_gridcell_balance_check, ch4_init_column_balance_check
- use DUSTMod , only : DustDryDep, DustEmission
use VOCEmissionMod , only : VOCEmission
!
use filterMod , only : setFilters
@@ -806,15 +805,15 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro
call t_startf('bgc')
! Dust mobilization (C. Zender's modified codes)
- call DustEmission(bounds_clump, &
+ call dust_emis_inst%DustEmission(bounds_clump, &
filter(nc)%num_nolakep, filter(nc)%nolakep, &
atm2lnd_inst, soilstate_inst, canopystate_inst, &
water_inst%waterstatebulk_inst, water_inst%waterdiagnosticbulk_inst, &
- frictionvel_inst, dust_inst)
+ frictionvel_inst)
! Dust dry deposition (C. Zender's modified codes)
- call DustDryDep(bounds_clump, &
- atm2lnd_inst, frictionvel_inst, dust_inst)
+ call dust_emis_inst%DustDryDep(bounds_clump, &
+ atm2lnd_inst, frictionvel_inst)
! VOC emission (A. Guenther's MEGAN (2006) model)
call VOCEmission(bounds_clump, &
@@ -1309,7 +1308,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro
atm2lnd_inst, surfalb_inst, temperature_inst, frictionvel_inst, &
water_inst, &
energyflux_inst, solarabs_inst, drydepvel_inst, &
- vocemis_inst, fireemis_inst, dust_inst, ch4_inst, glc_behavior, &
+ vocemis_inst, fireemis_inst, dust_emis_inst, ch4_inst, glc_behavior, &
lnd2atm_inst, &
net_carbon_exchange_grc = net_carbon_exchange_grc(bounds_proc%begg:bounds_proc%endg))
deallocate(net_carbon_exchange_grc)
diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90
index b9d74c418a..a134265e02 100644
--- a/src/main/clm_instMod.F90
+++ b/src/main/clm_instMod.F90
@@ -45,7 +45,7 @@ module clm_instMod
use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
use CropType , only : crop_type
use DryDepVelocity , only : drydepvel_type
- use DUSTMod , only : dust_type
+ use DustEmisBase , only : dust_emis_base_type
use EnergyFluxType , only : energyflux_type
use FrictionVelocityMod , only : frictionvel_type
use GlacierSurfaceMassBalanceMod , only : glacier_smb_type
@@ -151,7 +151,7 @@ module clm_instMod
! General biogeochem types
type(ch4_type) , public :: ch4_inst
type(crop_type) , public :: crop_inst
- type(dust_type) , public :: dust_inst
+ class(dust_emis_base_type), public, allocatable :: dust_emis_inst
type(vocemis_type) , public :: vocemis_inst
type(fireemis_type) , public :: fireemis_inst
type(drydepvel_type), public :: drydepvel_inst
@@ -200,9 +200,11 @@ subroutine clm_instInit(bounds)
use SoilWaterRetentionCurveFactoryMod , only : create_soil_water_retention_curve
use decompMod , only : get_proc_bounds
use BalanceCheckMod , only : GetBalanceCheckSkipSteps
+ use clm_varctl , only : flandusepftdat
use clm_varctl , only : use_hillslope
use HillslopeHydrologyMod , only : SetHillslopeSoilThickness
use initVerticalMod , only : setSoilLayerClass
+ use DustEmisFactory , only : create_dust_emissions
!
! !ARGUMENTS
type(bounds_type), intent(in) :: bounds ! processor bounds
@@ -296,11 +298,11 @@ subroutine clm_instInit(bounds)
! Initialization of public data types
call temperature_inst%Init(bounds, &
- urbanparams_inst%em_roof(begl:endl), &
- urbanparams_inst%em_wall(begl:endl), &
- urbanparams_inst%em_improad(begl:endl), &
- urbanparams_inst%em_perroad(begl:endl), &
- IsSimpleBuildTemp(), IsProgBuildTemp() )
+ em_roof_lun=urbanparams_inst%em_roof(begl:endl), &
+ em_wall_lun=urbanparams_inst%em_wall(begl:endl), &
+ em_improad_lun=urbanparams_inst%em_improad(begl:endl), &
+ em_perroad_lun=urbanparams_inst%em_perroad(begl:endl), &
+ is_simple_buildtemp=IsSimpleBuildTemp(), is_prog_buildtemp=IsProgBuildTemp() )
call active_layer_inst%Init(bounds)
@@ -350,7 +352,7 @@ subroutine clm_instInit(bounds)
call surfrad_inst%Init(bounds)
- call dust_inst%Init(bounds, NLFilename)
+ allocate(dust_emis_inst, source = create_dust_emissions(bounds, NLFilename))
allocate(scf_method, source = CreateAndInitSnowCoverFraction( &
snow_cover_fraction_method = snow_cover_fraction_method, &
@@ -447,7 +449,7 @@ subroutine clm_instInit(bounds)
! Initialize the Functionaly Assembled Terrestrial Ecosystem Simulator (FATES)
!
if (use_fates) then
- call clm_fates%Init(bounds)
+ call clm_fates%Init(bounds, flandusepftdat)
end if
deallocate (h2osno_col)
diff --git a/src/main/clm_varctl.F90 b/src/main/clm_varctl.F90
index 678f386f23..2556626d79 100644
--- a/src/main/clm_varctl.F90
+++ b/src/main/clm_varctl.F90
@@ -115,7 +115,7 @@ module clm_varctl
character(len=fname_len), public :: fsnowaging = ' ' ! snow aging parameters file name
character(len=fname_len), public :: fatmlndfrc = ' ' ! lnd frac file on atm grid
- ! only needed for LILAC and MCT drivers
+ ! only needed for LILAC
!----------------------------------------------------------
! Flag to read ndep rather than obtain it from coupler
@@ -287,6 +287,19 @@ module clm_varctl
logical, public :: use_c13 = .false. ! true => use C-13 model
logical, public :: use_c14 = .false. ! true => use C-14 model
+ !----------------------------------------------------------
+ ! CN matrix
+ !----------------------------------------------------------
+ logical, public :: spinup_matrixcn = .false. !.false. ! true => use acc spinup
+ logical, public :: hist_wrt_matrixcn_diag = .false.!.false. ! true => use acc spinup
+ ! SASU
+ integer, public :: nyr_forcing = 10 ! length of forcing years for the spin up. eg. if DATM_CLMNCEP_YR_START=1901;DATM_CLMNCEP_YR_END=1920, then nyr_forcing = 20
+ integer, public :: nyr_SASU = 1 ! length of each semi-analytic solution. eg. nyr_SASU=5, analytic solutions will be calculated every five years.
+ ! nyr_SASU=1: the fastest SASU, but inaccurate; nyr_SASU=nyr_forcing(eg. 20): the lowest SASU but accurate
+ integer, public :: iloop_avg = -999 ! The restart file will be based on the average of all analytic solutions within the iloop_avg^th loop.
+ ! eg. if nyr_forcing = 20, iloop_avg = 8, the restart file in yr 160 will be based on analytic solutions from yr 141 to 160.
+ ! The number of the analytic solutions within one loop depends on ratio between nyr_forcing and nyr_SASU.
+ ! eg. if nyr_forcing = 20, nyr_SASU = 5, number of analytic solutions is 20/5=4
! BUG(wjs, 2018-10-25, ESCOMP/ctsm#67) There is a bug that causes incorrect values for C
! isotopes if running init_interp from a case without C isotopes to a case with C
@@ -321,7 +334,7 @@ module clm_varctl
! > 1 for external data (lightning and/or anthropogenic ignitions)
! see bld/namelist_files/namelist_definition_clm4_5.xml for details
logical, public :: use_fates_tree_damage = .false. ! true => turn on tree damage module
- logical, public :: use_fates_logging = .false. ! true => turn on logging module
+ character(len=256), public :: fates_harvest_mode = '' ! five different harvest modes; see namelist definition
logical, public :: use_fates_planthydro = .false. ! true => turn on fates hydro
logical, public :: use_fates_cohort_age_tracking = .false. ! true => turn on cohort age tracking
logical, public :: use_fates_ed_st3 = .false. ! true => static stand structure
@@ -344,7 +357,10 @@ module clm_varctl
integer, dimension(2), public :: fates_history_dimlevel = (/2,2/)
logical, public :: use_fates_luh = .false. ! true => use FATES landuse data mode
+ logical, public :: use_fates_lupft = .false. ! true => use FATES landuse x pft static mapping mode
+ logical, public :: use_fates_potentialveg = .false. ! true => FATES potential veg only
character(len=256), public :: fluh_timeseries = '' ! filename for fates landuse timeseries data
+ character(len=256), public :: flandusepftdat = '' ! filename for fates landuse x pft data
character(len=256), public :: fates_inventory_ctrl_filename = '' ! filename for inventory control
! FATES SP AND FATES BGC are MUTUTALLY EXCLUSIVE, THEY CAN'T BOTH BE ON
@@ -416,6 +432,8 @@ module clm_varctl
logical, public :: use_hillslope = .false. ! true => use multi-column hillslope hydrology
logical, public :: downscale_hillslope_meteorology = .false. ! true => downscale meteorological forcing in hillslope model
logical, public :: use_hillslope_routing = .false. ! true => use surface water routing in hillslope hydrology
+ logical, public :: hillslope_fsat_equals_zero = .false. ! set saturated excess runoff to zero for hillslope columns
+
!----------------------------------------------------------
! excess ice physics switch
@@ -428,12 +446,6 @@ module clm_varctl
logical, public :: use_hydrstress = .false. ! true => use plant hydraulic stress calculation
- !----------------------------------------------------------
- ! dynamic root switch
- !----------------------------------------------------------
-
- logical, public :: use_dynroot = .false. ! true => use dynamic root module
-
!----------------------------------------------------------
! glacier_mec control variables: default values (may be overwritten by namelist)
!----------------------------------------------------------
diff --git a/src/main/clm_varpar.F90 b/src/main/clm_varpar.F90
index 4ddacc38e4..4456ab16af 100644
--- a/src/main/clm_varpar.F90
+++ b/src/main/clm_varpar.F90
@@ -86,10 +86,53 @@ module clm_varpar
integer, public :: i_oli_mic = -9 ! index of oligotrophic microbial pool; overwritten in SoilBiogeochemDecompCascade*Mod
integer, public :: i_cwd = -9 ! index of cwd pool; overwritten in SoilBiogeochemDecompCascade*Mod
integer, public :: i_cwdl2 = -9 ! index of cwd to l2 transition; overwritten in SoilBiogeochemDecompCascade*Mod
+ integer, public, parameter :: ileaf = 1 ! leaf pool index
+ integer, public, parameter :: ileaf_st = 2 ! leaf storage pool index
+ integer, public, parameter :: ileaf_xf = 3 ! leaf transfer pool index
+ integer, public, parameter :: ifroot = 4 ! fine root pool index
+ integer, public, parameter :: ifroot_st = 5 ! fine root storage pool index
+ integer, public, parameter :: ifroot_xf = 6 ! fine root transfer pool index
+ integer, public, parameter :: ilivestem = 7 ! live stem pool index
+ integer, public, parameter :: ilivestem_st = 8 ! live stem storage pool index
+ integer, public, parameter :: ilivestem_xf = 9 ! live stem transfer pool index
+ integer, public, parameter :: ideadstem = 10 ! dead stem pool index
+ integer, public, parameter :: ideadstem_st = 11 ! dead stem storage pool index
+ integer, public, parameter :: ideadstem_xf = 12 ! dead stem transfer pool index
+ integer, public, parameter :: ilivecroot = 13 ! live coarse root pool index
+ integer, public, parameter :: ilivecroot_st = 14 ! live coarse root storage pool index
+ integer, public, parameter :: ilivecroot_xf = 15 ! live coarse root transfer pool index
+ integer, public, parameter :: ideadcroot = 16 ! dead coarse root pool index
+ integer, public, parameter :: ideadcroot_st = 17 ! dead coarse root storage pool index
+ integer, public, parameter :: ideadcroot_xf = 18 ! dead coarse root transfer pool index
+ integer, public, parameter :: igrain = 19 ! grain pool index
+ integer, public, parameter :: igrain_st = 20 ! grain storage pool index
+ integer, public, parameter :: igrain_xf = 21 ! grain transfer pool index
+
+ integer, public :: ncphtrans !maximum number of vegetation C transfers through phenology
+ integer, public :: ncphouttrans !maximum number of vegetation C transfers out of vegetation through phenology
+ integer, public :: ncgmtrans !maximum number of vegetation C transfers through gap mortality
+ integer, public :: ncgmouttrans !maximum number of vegetation C transfers out of vegetation through gap mortality
+ integer, public :: ncfitrans !maximum number of vegetation C transfers through fire
+ integer, public :: ncfiouttrans !maximum number of vegetation C transfers out of vegetation trhough fire
+ integer, public :: nnphtrans !maximum number of vegetation N transfers through phenology
+ integer, public :: nnphouttrans !maximum number of vegetation N transfers out of vegetation through phenology
+ integer, public :: nngmtrans !maximum number of vegetation N transfers through gap mortality
+ integer, public :: nngmouttrans !maximum number of vegetation N transfers out of vegetation through gap mortality
+ integer, public :: nnfitrans !maximum number of vegetation N transfers through fire
+ integer, public :: nnfiouttrans !maximum number of vegetation N transfers out of vegetation trhough fire
+
+ integer, public :: iretransn ! retranslocation pool index
+
+ integer, public :: ioutc ! external C pool index
+ integer, public :: ioutn ! external N pool index
integer, public :: ndecomp_pools_max
- integer, public :: ndecomp_pools
+ integer, public :: ndecomp_pools ! total number of pools
integer, public :: ndecomp_cascade_transitions
+ integer, public :: ndecomp_cascade_outtransitions
+
+ ! for soil matrix
+ integer, public :: ndecomp_pools_vr ! ndecomp_pools * levels in the vertical
! Indices used in surface file read and set in clm_varpar_init
@@ -285,9 +328,29 @@ subroutine clm_varpar_init(actual_maxsoil_patches, surf_numpft, surf_numcft, act
! CN Matrix settings
if (use_crop)then
nvegcpool = nvegpool_natveg + nvegpool_crop
+ ncphtrans = 18
+ nnphtrans = 37
+ ncphouttrans = 4
+ nnphouttrans = 5
else
nvegcpool = nvegpool_natveg
+ ncphtrans = 17
+ nnphtrans = 34
+ ncphouttrans = 3
+ nnphouttrans = 4
end if
+ ncgmtrans = 18
+ ncgmouttrans = 18
+ ncfitrans = 20
+ ncfiouttrans = 18
+ nngmtrans = 19
+ nngmouttrans = 19
+ nnfitrans = 21
+ nnfiouttrans = 19
+ nvegnpool = nvegcpool + 1
+ iretransn = nvegnpool
+ ioutc = nvegcpool + 1
+ ioutn = nvegnpool + 1
end subroutine clm_varpar_init
diff --git a/src/main/controlMod.F90 b/src/main/controlMod.F90
index 634128798b..c5c5bd9f64 100644
--- a/src/main/controlMod.F90
+++ b/src/main/controlMod.F90
@@ -39,8 +39,9 @@ module controlMod
use UrbanParamsType , only: UrbanReadNML
use HumanIndexMod , only: HumanIndexReadNML
use CNPrecisionControlMod , only: CNPrecisionControlReadNML
- use CNSharedParamsMod , only: use_fun
+ use CNSharedParamsMod , only: use_fun, use_matrixcn
use CIsoAtmTimeseriesMod , only: use_c14_bombspike, atm_c14_filename, use_c13_timeseries, atm_c13_filename
+ use SoilBiogeochemDecompCascadeConType, only : use_soil_matrixcn
use SoilBiogeochemCompetitionMod , only: suplnitro, suplnNon
use SoilBiogeochemLittVertTranspMod , only: som_adv_flux, max_depth_cryoturb
use SoilBiogeochemVerticalProfileMod , only: surfprof_exp
@@ -121,6 +122,7 @@ subroutine control_init(dtime)
use CNNDynamicsMod , only : CNNDynamicsReadNML
use CNPhenologyMod , only : CNPhenologyReadNML
use landunit_varcon , only : max_lunit
+ use CNSoilMatrixMod , only : CNSoilMatrixInit
!
! ARGUMENTS
integer, intent(in) :: dtime ! model time step (seconds)
@@ -185,6 +187,10 @@ subroutine control_init(dtime)
namelist /clm_inparm / &
deepmixing_depthcrit, deepmixing_mixfact, lake_melt_icealb
+ ! CN Matrix solution
+ namelist /clm_inparm / &
+ use_matrixcn, use_soil_matrixcn, hist_wrt_matrixcn_diag, spinup_matrixcn, nyr_forcing, nyr_sasu, iloop_avg
+
! lake_melt_icealb is of dimension numrad
! Glacier_mec info
@@ -228,7 +234,7 @@ subroutine control_init(dtime)
! FATES Flags
namelist /clm_inparm/ fates_paramfile, use_fates, &
- fates_spitfire_mode, use_fates_logging, &
+ fates_spitfire_mode, fates_harvest_mode, &
use_fates_planthydro, use_fates_ed_st3, &
use_fates_cohort_age_tracking, &
use_fates_ed_prescribed_phys, &
@@ -237,7 +243,10 @@ subroutine control_init(dtime)
use_fates_nocomp, &
use_fates_sp, &
use_fates_luh, &
+ use_fates_lupft, &
+ use_fates_potentialveg, &
fluh_timeseries, &
+ flandusepftdat, &
fates_inventory_ctrl_filename, &
fates_parteh_mode, &
fates_seeddisp_cadence, &
@@ -270,9 +279,9 @@ subroutine control_init(dtime)
namelist /clm_inparm/ use_hillslope_routing
- namelist /clm_inparm/ use_hydrstress
+ namelist /clm_inparm/ hillslope_fsat_equals_zero
- namelist /clm_inparm/ use_dynroot
+ namelist /clm_inparm/ use_hydrstress
namelist /clm_inparm/ &
use_c14_bombspike, atm_c14_filename, use_c13_timeseries, atm_c13_filename
@@ -324,6 +333,14 @@ subroutine control_init(dtime)
runtyp(nsrContinue + 1) = 'restart'
runtyp(nsrBranch + 1) = 'branch '
+ if(use_fates)then
+ use_matrixcn = .false.
+ use_soil_matrixcn = .false.
+ hist_wrt_matrixcn_diag = .false.
+ spinup_matrixcn = .false.
+ end if
+ nyr_forcing = 10
+
! Set clumps per procoessor
#if (defined _OPENMP)
@@ -598,9 +615,9 @@ subroutine control_init(dtime)
call CNPhenologyReadNML ( NLFilename )
end if
- ! ----------------------------------------------------------------------
- ! Initialize the CN soil matrix namelist items
- ! ----------------------------------------------------------------------
+ ! CN soil matrix
+
+ call CNSoilMatrixInit()
! ----------------------------------------------------------------------
! consistency checks
@@ -613,11 +630,6 @@ subroutine control_init(dtime)
errMsg(sourcefile, __LINE__))
end if
- if ( use_dynroot .and. use_hydrstress ) then
- call endrun(msg=' ERROR:: dynroot and hydrstress can NOT be on at the same time'//&
- errMsg(sourcefile, __LINE__))
- end if
-
! Check on run type
if (nsrest == iundef) then
call endrun(msg=' ERROR:: must set nsrest'//&
@@ -791,7 +803,7 @@ subroutine control_spmd()
call mpi_bcast (for_testing_allow_interp_non_ciso_to_ciso, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (fates_spitfire_mode, 1, MPI_INTEGER, 0, mpicom, ier)
- call mpi_bcast (use_fates_logging, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (fates_harvest_mode, len(fates_harvest_mode) , MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (use_fates_planthydro, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_tree_damage, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_cohort_age_tracking, 1, MPI_LOGICAL, 0, mpicom, ier)
@@ -802,10 +814,14 @@ subroutine control_spmd()
call mpi_bcast (use_fates_nocomp, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_sp, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_luh, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_fates_lupft, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_fates_potentialveg, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (use_fates_bgc, 1, MPI_LOGICAL, 0, mpicom, ier)
call mpi_bcast (fates_inventory_ctrl_filename, len(fates_inventory_ctrl_filename), MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (fates_paramfile, len(fates_paramfile) , MPI_CHARACTER, 0, mpicom, ier)
call mpi_bcast (fluh_timeseries, len(fluh_timeseries) , MPI_CHARACTER, 0, mpicom, ier)
+ call mpi_bcast (flandusepftdat, len(flandusepftdat) , MPI_CHARACTER, 0, mpicom, ier)
+
call mpi_bcast (fates_parteh_mode, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (fates_seeddisp_cadence, 1, MPI_INTEGER, 0, mpicom, ier)
call mpi_bcast (fates_history_dimlevel, 2, MPI_INTEGER, 0, mpicom, ier)
@@ -841,9 +857,16 @@ subroutine control_spmd()
call mpi_bcast (use_hillslope_routing, 1, MPI_LOGICAL, 0, mpicom, ier)
- call mpi_bcast (use_hydrstress, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (hillslope_fsat_equals_zero, 1, MPI_LOGICAL, 0, mpicom, ier)
- call mpi_bcast (use_dynroot, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (use_soil_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (hist_wrt_matrixcn_diag, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (spinup_matrixcn, 1, MPI_LOGICAL, 0, mpicom, ier)
+ call mpi_bcast (nyr_forcing, 1, MPI_INTEGER, 0, mpicom, ier)
+ call mpi_bcast (nyr_sasu, 1, MPI_INTEGER, 0, mpicom, ier)
+ call mpi_bcast (iloop_avg, 1, MPI_INTEGER, 0, mpicom, ier)
+ call mpi_bcast (use_hydrstress, 1, MPI_LOGICAL, 0, mpicom, ier)
if (use_cn .or. use_fates) then
! vertical soil mixing variables
@@ -1126,13 +1149,13 @@ subroutine control_print ()
write(iulog,*) ' land-ice albedos (unitless 0-1) = ', albice
write(iulog,*) ' hillslope hydrology = ', use_hillslope
- write(iulog,*) ' downscale hillslope meteorology = ', downscale_hillslope_meteorology
+ write(iulog,*) ' downscale hillslope meteorology = ', downscale_hillslope_meteorology
write(iulog,*) ' hillslope routing = ', use_hillslope_routing
+ write(iulog,*) ' hillslope_fsat_equals_zero = ', hillslope_fsat_equals_zero
write(iulog,*) ' pre-defined soil layer structure = ', soil_layerstruct_predefined
write(iulog,*) ' user-defined soil layer structure = ', soil_layerstruct_userdefined
write(iulog,*) ' user-defined number of soil layers = ', soil_layerstruct_userdefined_nlevsoi
write(iulog,*) ' plant hydraulic stress = ', use_hydrstress
- write(iulog,*) ' dynamic roots = ', use_dynroot
if (nsrest == nsrContinue) then
write(iulog,*) 'restart warning:'
write(iulog,*) ' Namelist not checked for agreement with initial run.'
@@ -1176,7 +1199,7 @@ subroutine control_print ()
write(iulog, *) ' use_fates = ', use_fates
if (use_fates) then
write(iulog, *) ' fates_spitfire_mode = ', fates_spitfire_mode
- write(iulog, *) ' use_fates_logging = ', use_fates_logging
+ write(iulog, *) ' fates_harvest_mode = ', fates_harvest_mode
write(iulog, *) ' fates_paramfile = ', fates_paramfile
write(iulog, *) ' fates_parteh_mode = ', fates_parteh_mode
write(iulog, *) ' use_fates_planthydro = ', use_fates_planthydro
@@ -1189,7 +1212,10 @@ subroutine control_print ()
write(iulog, *) ' use_fates_nocomp = ', use_fates_nocomp
write(iulog, *) ' use_fates_sp = ', use_fates_sp
write(iulog, *) ' use_fates_luh= ', use_fates_luh
+ write(iulog, *) ' use_fates_lupft= ', use_fates_lupft
+ write(iulog, *) ' use_fates_potentialveg = ', use_fates_potentialveg
write(iulog, *) ' fluh_timeseries = ', trim(fluh_timeseries)
+ write(iulog, *) ' flandusepftdat = ', trim(flandusepftdat)
write(iulog, *) ' fates_seeddisp_cadence = ', fates_seeddisp_cadence
write(iulog, *) ' fates_seeddisp_cadence: 0, 1, 2, 3 => off, daily, monthly, or yearly dispersal'
write(iulog, *) ' fates_inventory_ctrl_filename = ', trim(fates_inventory_ctrl_filename)
diff --git a/src/main/glc2lndMod.F90 b/src/main/glc2lndMod.F90
index ecd6818210..2d0dbb5791 100644
--- a/src/main/glc2lndMod.F90
+++ b/src/main/glc2lndMod.F90
@@ -78,7 +78,6 @@ module glc2lndMod
! - set_glc2lnd_fields
! - update_glc2lnd_fracs
! - update_glc2lnd_topo
- procedure, public :: set_glc2lnd_fields_mct ! set coupling fields sent from glc to lnd
procedure, public :: set_glc2lnd_fields_nuopc ! set coupling fields sent from glc to lnd
procedure, public :: update_glc2lnd_fracs ! update subgrid fractions based on input from GLC
procedure, public :: update_glc2lnd_topo ! update topographic heights
@@ -242,61 +241,6 @@ subroutine Clean(this)
end subroutine Clean
- !-----------------------------------------------------------------------
- subroutine set_glc2lnd_fields_mct(this, bounds, glc_present, x2l, &
- index_x2l_Sg_ice_covered, index_x2l_Sg_topo, index_x2l_Flgg_hflx, &
- index_x2l_Sg_icemask, index_x2l_Sg_icemask_coupled_fluxes)
- !
- ! !DESCRIPTION:
- ! Set coupling fields sent from glc to lnd
- !
- ! If glc_present is true, then the given fields are all assumed to be valid; if
- ! glc_present is false, then these fields are ignored.
- !
- ! !ARGUMENTS:
- class(glc2lnd_type), intent(inout) :: this
- type(bounds_type) , intent(in) :: bounds
- logical , intent(in) :: glc_present ! true if running with a non-stub glc model
- real(r8) , intent(in) :: x2l(:, bounds%begg: ) ! driver import state to land model [field, gridcell]
- integer , intent(in) :: index_x2l_Sg_ice_covered( 0: ) ! indices of ice-covered field in x2l, for each elevation class
- integer , intent(in) :: index_x2l_Sg_topo( 0: ) ! indices of topo field in x2l, for each elevation class
- integer , intent(in) :: index_x2l_Flgg_hflx( 0: ) ! indices of heat flux field in x2l, for each elevation class
- integer , intent(in) :: index_x2l_Sg_icemask ! index of icemask field in x2l
- integer , intent(in) :: index_x2l_Sg_icemask_coupled_fluxes ! index of icemask_coupled_fluxes field in x2l
- !
- ! !LOCAL VARIABLES:
- integer :: g
- integer :: ice_class
-
- character(len=*), parameter :: subname = 'set_glc2lnd_fields_mct'
- !-----------------------------------------------------------------------
-
- SHR_ASSERT_FL((ubound(x2l, 2) == bounds%endg), sourcefile, __LINE__)
- SHR_ASSERT_ALL_FL((ubound(index_x2l_Sg_ice_covered) == (/maxpatch_glc/)), sourcefile, __LINE__)
- SHR_ASSERT_ALL_FL((ubound(index_x2l_Sg_topo) == (/maxpatch_glc/)), sourcefile, __LINE__)
- SHR_ASSERT_ALL_FL((ubound(index_x2l_Flgg_hflx) == (/maxpatch_glc/)), sourcefile, __LINE__)
-
- if (glc_present) then
- do g = bounds%begg, bounds%endg
- do ice_class = 0, maxpatch_glc
- this%frac_grc(g,ice_class) = x2l(index_x2l_Sg_ice_covered(ice_class),g)
- this%topo_grc(g,ice_class) = x2l(index_x2l_Sg_topo(ice_class),g)
- this%hflx_grc(g,ice_class) = x2l(index_x2l_Flgg_hflx(ice_class),g)
- end do
- this%icemask_grc(g) = x2l(index_x2l_Sg_icemask,g)
- this%icemask_coupled_fluxes_grc(g) = x2l(index_x2l_Sg_icemask_coupled_fluxes,g)
- end do
-
- call this%set_glc2lnd_fields_wrapup(bounds)
- else
- if (glc_do_dynglacier) then
- call endrun(' ERROR: With glc_present false (e.g., a stub glc model), glc_do_dynglacier must be false '// &
- errMsg(sourcefile, __LINE__))
- end if
- end if
-
- end subroutine set_glc2lnd_fields_mct
-
!-----------------------------------------------------------------------
subroutine set_glc2lnd_fields_nuopc(this, bounds, glc_present, &
frac_grc, topo_grc, hflx_grc, icemask_grc, icemask_coupled_fluxes_grc)
diff --git a/src/main/lnd2atmMod.F90 b/src/main/lnd2atmMod.F90
index 1cda0cff91..503f4b9585 100644
--- a/src/main/lnd2atmMod.F90
+++ b/src/main/lnd2atmMod.F90
@@ -20,7 +20,7 @@ module lnd2atmMod
use lnd2atmType , only : lnd2atm_type
use atm2lndType , only : atm2lnd_type
use ch4Mod , only : ch4_type
- use DUSTMod , only : dust_type
+ use DustEmisBase , only : dust_emis_base_type
use DryDepVelocity , only : drydepvel_type
use VocEmissionMod , only : vocemis_type
use CNFireEmissionsMod , only : fireemis_type
@@ -150,7 +150,7 @@ subroutine lnd2atm(bounds, &
atm2lnd_inst, surfalb_inst, temperature_inst, frictionvel_inst, &
water_inst, &
energyflux_inst, solarabs_inst, drydepvel_inst, &
- vocemis_inst, fireemis_inst, dust_inst, ch4_inst, glc_behavior, &
+ vocemis_inst, fireemis_inst, dust_emis_inst, ch4_inst, glc_behavior, &
lnd2atm_inst, &
net_carbon_exchange_grc)
!
@@ -173,7 +173,7 @@ subroutine lnd2atm(bounds, &
type(drydepvel_type) , intent(in) :: drydepvel_inst
type(vocemis_type) , intent(in) :: vocemis_inst
type(fireemis_type) , intent(in) :: fireemis_inst
- type(dust_type) , intent(in) :: dust_inst
+ class(dust_emis_base_type) , intent(in) :: dust_emis_inst
type(ch4_type) , intent(in) :: ch4_inst
type(glc_behavior_type) , intent(in) :: glc_behavior
type(lnd2atm_type) , intent(inout) :: lnd2atm_inst
@@ -332,7 +332,7 @@ subroutine lnd2atm(bounds, &
! dust emission flux
call p2g(bounds, ndst, &
- dust_inst%flx_mss_vrt_dst_patch(bounds%begp:bounds%endp, :), &
+ dust_emis_inst%flx_mss_vrt_dst_patch(bounds%begp:bounds%endp, :), &
lnd2atm_inst%flxdst_grc (bounds%begg:bounds%endg, :), &
p2c_scale_type='unity', c2l_scale_type= 'unity', l2g_scale_type='unity')
diff --git a/src/main/pftconMod.F90 b/src/main/pftconMod.F90
index e5379100e0..7988b57e75 100644
--- a/src/main/pftconMod.F90
+++ b/src/main/pftconMod.F90
@@ -280,9 +280,6 @@ module pftconMod
real(r8), allocatable :: FUN_fracfixers(:) ! Fraction of C that can be used for fixation.
- ! pft parameters for dynamic root code
- real(r8), allocatable :: root_dmx(:) !maximum root depth
-
contains
procedure, public :: Init
@@ -494,7 +491,6 @@ subroutine InitAllocate (this)
allocate( this%kn_nonmyc (0:mxpft) )
allocate( this%kr_resorb (0:mxpft) )
allocate( this%perecm (0:mxpft) )
- allocate( this%root_dmx (0:mxpft) )
allocate( this%fun_cn_flex_a (0:mxpft) )
allocate( this%fun_cn_flex_b (0:mxpft) )
allocate( this%fun_cn_flex_c (0:mxpft) )
@@ -520,7 +516,7 @@ subroutine InitRead(this)
use fileutils , only : getfil
use ncdio_pio , only : ncd_io, ncd_pio_closefile, ncd_pio_openfile, file_desc_t
use ncdio_pio , only : ncd_inqdid, ncd_inqdlen
- use clm_varctl , only : paramfile, use_fates, use_flexibleCN, use_dynroot, use_biomass_heat_storage, z0param_method
+ use clm_varctl , only : paramfile, use_fates, use_flexibleCN, use_biomass_heat_storage, z0param_method
use spmdMod , only : masterproc
use CLMFatesParamInterfaceMod, only : FatesReadPFTs
use SoilBiogeochemDecompCascadeConType, only : mimics_decomp, decomp_method
@@ -1105,13 +1101,8 @@ subroutine InitRead(this)
end if
!
- ! Dynamic Root variables for crops
!
- if ( use_crop .and. use_dynroot )then
- call ncd_io('root_dmx', this%root_dmx, 'read', ncid, readvar=readv)
- if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__))
- end if
-
+ !
call ncd_io('nstem',this%nstem, 'read', ncid, readvar=readv)
if ( .not. readv ) call endrun(msg=' ERROR: error in reading in pft data'//errMsg(sourcefile, __LINE__))
call ncd_io('taper',this%taper, 'read', ncid, readvar=readv)
@@ -1583,7 +1574,6 @@ subroutine Clean(this)
deallocate( this%kn_nonmyc)
deallocate( this%kr_resorb)
deallocate( this%perecm)
- deallocate( this%root_dmx)
deallocate( this%fun_cn_flex_a)
deallocate( this%fun_cn_flex_b)
deallocate( this%fun_cn_flex_c)
diff --git a/src/main/surfrdUtilsMod.F90 b/src/main/surfrdUtilsMod.F90
index 007770b3c3..b79f97e0b4 100644
--- a/src/main/surfrdUtilsMod.F90
+++ b/src/main/surfrdUtilsMod.F90
@@ -317,8 +317,8 @@ subroutine collapse_to_dominant(weight, lower_bound, upper_bound, begg, endg, n_
! original sum of all the weights
wt_sum(g) = sum(weight(g,:))
- if (present(do_not_collapse) .and. do_not_collapse(g)) then
- cycle
+ if (present(do_not_collapse)) then
+ if (do_not_collapse(g)) cycle
end if
max_indices = 0 ! initialize
diff --git a/src/soilbiogeochem/CNSoilMatrixMod.F90 b/src/soilbiogeochem/CNSoilMatrixMod.F90
new file mode 100644
index 0000000000..56c1f11b5c
--- /dev/null
+++ b/src/soilbiogeochem/CNSoilMatrixMod.F90
@@ -0,0 +1,940 @@
+module CNSoilMatrixMod
+
+!#include "shr_assert.h"
+ !-----------------------------------------------------------------------
+ ! The matrix model of CLM5.0 was developed by Yiqi Luo EcoLab members,
+ ! Drs. Xingjie Lu, Yuanyuan Huang and Zhengguang Du, at Northern Arizona University
+ !----------------------------------------------------------------------------------
+ !
+ ! DESCRIPTION:
+ ! Module for CLM5.0BGC matrices
+ ! The matrix equation
+ ! Xn+1 = Xn + I*dt + (A*K(ksi) - Kfire - tri/dz)*Xn*dt
+ ! Or
+ ! Xn+1 = Xn + I*dt + (A*K(ksi) - Kfire - V)*Xn*dt
+
+ ! !USES:
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use decompMod , only : bounds_type
+ use abortutils , only : endrun
+ use clm_time_manager , only : get_step_size, is_end_curr_month,get_curr_date,update_DA_nstep
+ use clm_time_manager , only : is_first_restart_step,is_beg_curr_year,is_end_curr_year,is_first_step_of_this_run_segment
+ use clm_varpar , only : ndecomp_pools, nlevdecomp, ndecomp_pools_vr !number of biogeochemically active soil layers
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_cascade_outtransitions
+ use clm_varpar , only : i_cwd
+ use clm_varcon , only : dzsoi_decomp,zsoi,secspday,c3_r2,c14ratio
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use CNVegCarbonFluxType , only : cnveg_carbonflux_type
+ use CNVegNitrogenFluxType , only : cnveg_nitrogenflux_type
+ use SoilBiogeochemStateType , only : soilbiogeochem_state_type
+ use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type
+ use SoilBiogeochemCarbonFluxType , only : soilbiogeochem_carbonflux_type
+ use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
+ use SoilBiogeochemNitrogenFluxType , only : soilbiogeochem_nitrogenflux_type
+ use CNSharedParamsMod , only : CNParamsShareInst
+ use SoilStateType , only : soilstate_type
+ use clm_varctl , only : spinup_matrixcn, hist_wrt_matrixcn_diag, nyr_forcing, nyr_SASU, iloop_avg
+ use ColumnType , only : col
+ use GridcellType , only : grc
+ use clm_varctl , only : use_c13, use_c14, iulog
+ use perf_mod , only : t_startf, t_stopf
+ use SparseMatrixMultiplyMod , only : sparse_matrix_type, diag_matrix_type, vector_type
+ use MatrixMod , only : inverse
+!
+ implicit none
+ private
+ !
+ ! !PUBLIC MEMBER FUNCTIONS:
+ public:: CNSoilMatrixInit ! Initialization for CN Soil Matrix solution
+ public:: CNSoilMatrix
+ public:: CNSoilMatrixRest ! Restart for CN Soil Matrix solution
+
+ ! ! PRIVATE MEMBER DATA:
+ integer,save, private :: iyr=0 ! Cycling year number into forcing sequence
+ integer,save, private :: iloop=0 ! The iloop^th forcing loop
+ !-----------------------------------------------------------------------
+
+contains
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrixInit( )
+ ! !DESCRIPTION: Initialization for CN soil Matrix solution
+ ! !ARGUMENTS:
+ ! !LOCAL VARIABLES:
+ !-----------------------------------------------------------------------
+
+ if ( use_soil_matrixcn ) then
+ write(iulog,*) 'CN Soil matrix solution is on'
+ write(iulog,*) '*****************************'
+ if ( spinup_matrixcn ) then
+ write(iulog,*) ' Matrix spinup is on'
+ write(iulog,*) ' *******************'
+ write(iulog,*) ' nyr_forcing = ', nyr_forcing
+ write(iulog,*) ' nyr_SASU = ', nyr_SASU
+ write(iulog,*) ' iloop_avg = ', iloop_avg
+ end if
+ if ( hist_wrt_matrixcn_diag )then
+ write(iulog,*) ' Extra matrix solution tracability output is turned on'
+ else
+ write(iulog,*) ' no extra matrix solution tracability output'
+ end if
+ else
+ write(iulog,*) 'CN Soil matrix solution is off'
+ end if
+ end subroutine CNSoilMatrixInit
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrix(bounds,num_soilc, filter_soilc, num_actfirec, filter_actfirec,&
+ cnveg_carbonflux_inst,soilbiogeochem_carbonstate_inst, &
+ soilbiogeochem_carbonflux_inst,soilbiogeochem_state_inst, &
+ cnveg_nitrogenflux_inst, soilbiogeochem_nitrogenflux_inst, &
+ soilbiogeochem_nitrogenstate_inst,c13_soilbiogeochem_carbonstate_inst,&
+ c13_soilbiogeochem_carbonflux_inst,c14_soilbiogeochem_carbonstate_inst,&
+ c14_soilbiogeochem_carbonflux_inst)
+ ! !DESCRIPTION:
+ ! !ARGUMENTS:
+ type(bounds_type) , intent(in) :: bounds
+ integer , intent(in) :: num_soilc ! number of soil columns in filter
+ integer , intent(in) :: filter_soilc(:) ! filter for soil columns
+ integer , intent(in) :: num_actfirec ! number of soil columns in filter
+ integer , intent(in) :: filter_actfirec(:) ! filter for soil columns
+ type(cnveg_carbonflux_type) , intent(inout) :: cnveg_carbonflux_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: soilbiogeochem_carbonflux_inst
+ type(soilbiogeochem_state_type) , intent(inout) :: soilbiogeochem_state_inst
+ type(cnveg_nitrogenflux_type) , intent(inout) :: cnveg_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenflux_type) , intent(inout) :: soilbiogeochem_nitrogenflux_inst
+ type(soilbiogeochem_nitrogenstate_type) , intent(inout) :: soilbiogeochem_nitrogenstate_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: c13_soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: c13_soilbiogeochem_carbonflux_inst
+ type(soilbiogeochem_carbonstate_type) , intent(inout) :: c14_soilbiogeochem_carbonstate_inst
+ type(soilbiogeochem_carbonflux_type) , intent(inout) :: c14_soilbiogeochem_carbonflux_inst
+
+ ! !LOCAL VARIABLES:
+ integer :: fc,j,i, l,k ! indices
+ integer :: c !
+ real(r8):: dt ! time step (seconds)
+ real(r8):: epsi,fire_delta ! small number
+
+ integer :: begc,endc ! bounds
+ real(r8),dimension(bounds%begc:bounds%endc,nlevdecomp*(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)) :: a_ma_vr,na_ma_vr
+
+ real(r8),dimension(bounds%begc:bounds%endc,1:ndecomp_pools_vr,1) :: soilmatrixc_cap,soilmatrixc13_cap,soilmatrixc14_cap,soilmatrixn_cap
+ real(r8), dimension(1:ndecomp_pools_vr,1:ndecomp_pools_vr) :: AKinv,AKinvn
+
+ real(r8),dimension(bounds%begc:bounds%endc,1:nlevdecomp,1:ndecomp_pools) :: cn_decomp_pools
+ integer :: Ntrans
+ integer tranlist_a
+ integer j_decomp,j_lev,ilev,idecomp
+ integer,dimension(:) :: kfire_i(1:ndecomp_pools_vr)
+ integer,dimension(:) :: kfire_j(1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: Cinter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: C13inter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: C14inter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ real(r8),dimension(:,:) :: Ninter_old(bounds%begc:bounds%endc,1:ndecomp_pools_vr)
+ logical,save :: list_ready1_fire = .False.
+ logical,save :: list_ready1_nofire = .False.
+ logical,save :: list_ready2_fire = .False.
+ logical,save :: list_ready2_nofire = .False.
+ logical,save :: list_ready3_fire = .False.
+ logical,save :: init_readyAsoilc = .False.
+ logical,save :: init_readyAsoiln = .False.
+ logical isbegofyear
+
+ !-----------------------------------------------------------------------
+ begc = bounds%begc; endc = bounds%endc
+
+! SHR_ASSERT_ALL((ubound(cn_decomp_pools) == (/endc,nlevdecomp,ndecomp_pools/)) , errMsg(sourcefile, __LINE__))
+ associate( &
+ cs_soil => soilbiogeochem_carbonstate_inst , & ! In/Output
+ ns_soil => soilbiogeochem_nitrogenstate_inst , & ! In/Output
+ cs13_soil => c13_soilbiogeochem_carbonstate_inst, & ! In/Output
+ cs14_soil => c14_soilbiogeochem_carbonstate_inst, & ! In/Output
+ cf13_soil => c13_soilbiogeochem_carbonflux_inst, & ! In/Output
+ cf14_soil => c14_soilbiogeochem_carbonflux_inst, & ! In/Output
+
+ fpi_vr => soilbiogeochem_state_inst%fpi_vr_col ,&!Input:[real(r8)(:,:)]fraction of potential immobilization (no units)
+ cascade_donor_pool => decomp_cascade_con%cascade_donor_pool ,&!Input:[integer(:)]which pool is C taken from for a given decomposition step
+ cascade_receiver_pool => decomp_cascade_con%cascade_receiver_pool ,&!Input:[integer(:)]which pool is C added to for a given decomposition step
+ floating_cn_ratio_decomp_pools=> decomp_cascade_con%floating_cn_ratio_decomp_pools ,&!Input:[logical(:)]TRUE => pool has fixed C:N ratio
+ initial_cn_ratio => decomp_cascade_con%initial_cn_ratio ,&!Input:[real(r8)(:)]c:n ratio for initialization of pools
+ rf_decomp_cascade => soilbiogeochem_carbonflux_inst%rf_decomp_cascade_col ,&!Input:[real(r8)(:,:,:)]respired fraction in decomposition step (frac)
+ pathfrac_decomp_cascade => soilbiogeochem_carbonflux_inst%pathfrac_decomp_cascade_col,&!Input:[real(r8)(:,:,:)]what fraction of C leaving a given pool passes
+ ! through a given transition (frac)
+ is_cwd => decomp_cascade_con%is_cwd ,&!Input:[logical(:)]TRUE => pool is a cwd pool
+ is_litter => decomp_cascade_con%is_litter ,&!Input:[logical(:)]TRUE => pool is a litter pool
+
+ hr => soilbiogeochem_carbonflux_inst%hr_col ,&!Output:[real(r8)(:)]heterotrophic respiration
+ trcr_ctendency => soilbiogeochem_carbonflux_inst%decomp_cpools_transport_tendency_col,&
+ trcr_ntendency => soilbiogeochem_nitrogenflux_inst%decomp_npools_transport_tendency_col,&
+ m_decomp_cpools_to_fire => cnveg_carbonflux_inst%m_decomp_cpools_to_fire_col ,&!Output:[real(r8)(:,:)]vertically-integrated decomposing C fire loss
+ tri_ma_vr => soilbiogeochem_carbonflux_inst%tri_ma_vr ,&!Input:[real(r8)(:,:)]vertical C transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
+ matrix_decomp_fire_k => soilbiogeochem_carbonflux_inst%matrix_decomp_fire_k_col ,&!Input:[real(r8)(:,:)]decomposition rate due to fire (gC*m3)/(gC*m3*step))
+
+ AKsoilc => soilbiogeochem_carbonflux_inst%AKsoilc ,&!Output:[SparseMatrix] A*K for C transfers between pools
+ RI_a => soilbiogeochem_carbonflux_inst%RI_a ,&!In/Output:[Integer(:)] Row numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ CI_a => soilbiogeochem_carbonflux_inst%CI_a ,&!In/Output:[Integer(:)] Column numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ AKsoiln => soilbiogeochem_nitrogenflux_inst%AKsoiln ,&!Output:[SparseMatrix] A*K for N transfers between pools
+ RI_na => soilbiogeochem_nitrogenflux_inst%RI_na ,&!In/Output:[Integer(:)] Row numbers of all entries from AKsoiln, Automatically generated by SetValueA
+ CI_na => soilbiogeochem_nitrogenflux_inst%CI_na ,&!In/Output:[Integer(:)] Column numbers of all entries from AKsoiln, Automatically generated by SetValueA
+
+ A_i => decomp_cascade_con%A_i ,&!Input:[integer(:)] Prescribed row number of all elements in a_ma_vr
+ A_j => decomp_cascade_con%A_j ,&!Input:[integer(:)] Prescribed column number of all elements in na_ma_vr
+ spm_tranlist_a => decomp_cascade_con%spm_tranlist_a ,&!Input:[integer(:,:)] Prescribed subscripts to map 2D variables (transitions,soil layer) to 1D sparse matrix format in a_ma_vr and na_ma_vr
+
+ AVsoil => soilbiogeochem_carbonflux_inst%AVsoil ,&!Output:[SparseMatrix] V for C and N transfers between soil layers
+ tri_i => decomp_cascade_con%tri_i ,&!Input:[integer(:)] Prescribed row index of all entries in AVsoil
+ tri_j => decomp_cascade_con%tri_j ,&!Input:[integer(:)] Prescribed column index of all entries in AVsoil
+ Ntri_setup => decomp_cascade_con%Ntri_setup ,&!Input:[integer] Number of non-zero entries in AVsoil
+
+ AKfiresoil => soilbiogeochem_carbonflux_inst%AKfiresoil,&!Output:[SparseMatrix] Kfire for CN transfers from soil to atm due to fire
+
+ AKallsoilc => soilbiogeochem_carbonflux_inst%AKallsoilc ,&!Output:[SparseMatrix] (A*K+V-Kfire) for soil C cycle
+ NE_AKallsoilc => soilbiogeochem_carbonflux_inst%NE_AKallsoilc ,&!In/Output:[Integer] Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ RI_AKallsoilc => soilbiogeochem_carbonflux_inst%RI_AKallsoilc ,&!In/Output:[Integer(:)] Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ CI_AKallsoilc => soilbiogeochem_carbonflux_inst%CI_AKallsoilc ,&!In/Output:[Integer(:)] Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ AKallsoiln => soilbiogeochem_nitrogenflux_inst%AKallsoiln ,&!Output:[SparseMatrix] (A*K+V-Kfire) for soil N cycle
+ NE_AKallsoiln => soilbiogeochem_nitrogenflux_inst%NE_AKallsoiln,&!In/Output:[Integer] Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ RI_AKallsoiln => soilbiogeochem_nitrogenflux_inst%RI_AKallsoiln,&!In/Output:[Integer(:)] Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ CI_AKallsoiln => soilbiogeochem_nitrogenflux_inst%CI_AKallsoiln,&!In/Output:[Integer(:)] Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ AKXcacc => soilbiogeochem_carbonstate_inst%AKXcacc ,&!In/Output:[SparseMatrix] Accumulated transfers for soil C cycle
+ AKXnacc => soilbiogeochem_nitrogenstate_inst%AKXnacc ,&!In/Output:[SparseMatrix] Accumulated transfers for soil N cycle
+ n_all_entries => decomp_cascade_con%n_all_entries ,&!Input:[integer] Number of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ all_i => decomp_cascade_con%all_i ,&!Input:[integer(:)] Prescribed row index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ all_j => decomp_cascade_con%all_j ,&!Input:[integer(:)] Prescribed column index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil ,&!Output:[DiagonalMatrix] C turnover rate in different soil pools and layers
+ Ksoiln => soilbiogeochem_nitrogenflux_inst%Ksoiln ,&!Output:[DiagonalMatrix] N turnover rate in different soil pools and layers
+ Xdiagsoil => soilbiogeochem_carbonflux_inst%Xdiagsoil ,&!Output:[DiagonalMatrix] Temporary C and N state variable to calculate accumulation transfers
+ matrix_Cinter => soilbiogeochem_carbonstate_inst%matrix_Cinter ,&!In/Output:[Vector] Soil C state variables (gC/m3) in different soil pools and layers
+ matrix_Ninter => soilbiogeochem_nitrogenstate_inst%matrix_Ninter ,&!In/Output:[Vector] Soil N state variables (gN/m3) in different soil pools and layers
+ matrix_Cinter13=> c13_soilbiogeochem_carbonstate_inst%matrix_Cinter,&!In/Output:[Vector] Soil C13 state variables (gC13/m3) in different soil pools and layers
+ matrix_Cinter14=> c14_soilbiogeochem_carbonstate_inst%matrix_Cinter,&!In/Output:[Vector] Soil C14 state variables (gC14/m3) in different soil pools and layers
+ matrix_Cinput => soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C input to different soil compartments (pools and layers) (gC/m3/step)
+ matrix_Cinput13=> c13_soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C13 input to different soil compartments (pools and layers) (gC13/m3/step)
+ matrix_Cinput14=> c14_soilbiogeochem_carbonflux_inst%matrix_Cinput ,&!Input:[Vector] C14 input to different soil compartments (pools and layers) (gC14/m3/step)
+ matrix_Ninput => soilbiogeochem_nitrogenflux_inst%matrix_Ninput ,&!Input:[Vector] N input to different soil compartments (pools and layers) (gN/m3/step)
+
+ list_Asoilc => decomp_cascade_con%list_Asoilc ,&!In/Output:[Integer(:)] Saves mapping indices from a_ma_vr to AKsoilc
+ list_Asoiln => decomp_cascade_con%list_Asoiln ,&!In/Output:[Integer(:)] Saves mapping indices from na_ma_vr to AKsoiln
+ list_V_AKVfire => decomp_cascade_con%list_V_AKVfire ,&!In/Output:[Integer(:)] Saves mapping indices from V to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_fire_AKVfire=> decomp_cascade_con%list_fire_AKVfire,&!In/Output:[Integer(:)] Saves mapping indices from Kfire to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_AK_AKVfire => decomp_cascade_con%list_AK_AKVfire ,&!In/Output:[Integer(:)] Saves mapping indices from A*K to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ list_AK_AKV => decomp_cascade_con%list_AK_AKV ,&!In/Output:[Integer(:)] Saves mapping indices from A*K to (A*K+V) in the addition subroutine SPMP_AB
+ list_V_AKV => decomp_cascade_con%list_V_AKV &!In/Output:[Integer(:)] Saves mapping indices from V to (A*K+V) in the addition subroutine SPMP_AB
+ )
+
+ ! set time steps
+ call t_startf('CN Soil matrix-init. matrix')
+ dt = real( get_step_size(), r8 )
+
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ epsi = 1.e-8_r8
+
+ isbegofyear = is_beg_curr_year()
+
+ ! calculate c:n ratios of applicable pools
+ do l = 1, ndecomp_pools
+ if ( floating_cn_ratio_decomp_pools(l)) then
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if ( ns_soil%decomp_npools_vr_col(c,j,l) > 0._r8 ) then
+ cn_decomp_pools(c,j,l) = cs_soil%decomp_cpools_vr_col(c,j,l) / ns_soil%decomp_npools_vr_col(c,j,l)
+ else
+ cn_decomp_pools(c,j,l) = initial_cn_ratio(l)
+ end if
+ end do
+ end do
+ else
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cn_decomp_pools(c,j,l) = initial_cn_ratio(l)
+ end do
+ end do
+ end if
+ end do
+
+ call t_stopf('CN Soil matrix-init. matrix')
+
+ call t_startf('CN Soil matrix-assign matrix-a-na')
+ ! Calculate non-diagonal entries (a_ma_vr and na_ma_vr) in transfer coefficient matrix A
+ do k = 1, ndecomp_cascade_transitions
+ if(cascade_receiver_pool(k) .ne. 0)then !transition to atmosphere
+ do j = 1, nlevdecomp
+ tranlist_a = spm_tranlist_a(j,k)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ a_ma_vr(c,tranlist_a) = (1.0_r8-rf_decomp_cascade(c,j,k))*pathfrac_decomp_cascade(c,j,k)
+ if( .not. floating_cn_ratio_decomp_pools(cascade_receiver_pool(k)))then
+ na_ma_vr(c,tranlist_a) = (1.0_r8-rf_decomp_cascade(c,j,k))* &
+ (cn_decomp_pools(c,j,cascade_donor_pool(k))/cn_decomp_pools(c,j,cascade_receiver_pool(k)))*pathfrac_decomp_cascade(c,j,k)
+ else
+ na_ma_vr(c,tranlist_a) = pathfrac_decomp_cascade(c,j,k)
+ end if
+ end do
+ end do
+ end if
+ end do
+
+ call t_stopf('CN Soil matrix-assign matrix-a-na')
+
+ ! Update the turnover rate matrix K with N limitation (fpi_vr)
+
+ ! Assign old value to vector, and be ready for matrix operation
+ call t_startf('CN Soil matrix-assign matrix-inter')
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter%V(c,j+(i-1)*nlevdecomp) = cs_soil%decomp_cpools_vr_col(c,j,i)
+ Cinter_old(c,j+(i-1)*nlevdecomp) = cs_soil%decomp_cpools_vr_col(c,j,i)
+ !Cinter_old is saved for accumulation of C transfer calculation and C flux (hr and fire) adjustment
+ matrix_Ninter%V(c,j+(i-1)*nlevdecomp) = ns_soil%decomp_npools_vr_col(c,j,i)
+ Ninter_old(c,j+(i-1)*nlevdecomp) = ns_soil%decomp_npools_vr_col(c,j,i)
+ !Ninter_old is saved for accumulation of N transfer calculation
+ end do
+ end do
+ end do
+ if ( use_c13 )then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter13%V(c,j+(i-1)*nlevdecomp) = cs13_soil%decomp_cpools_vr_col(c,j,i)
+ C13inter_old(c,j+(i-1)*nlevdecomp) = cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ end if !c13
+
+ if ( use_c14 )then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter14%V(c,j+(i-1)*nlevdecomp) = cs14_soil%decomp_cpools_vr_col(c,j,i)
+ C14inter_old(c,j+(i-1)*nlevdecomp) = cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ end if !c14
+ call t_stopf('CN Soil matrix-assign matrix-inter')
+
+ call Ksoiln%SetValueCopyDM(num_soilc,filter_soilc,Ksoil )
+ do i = 1,ndecomp_pools
+ if ( .not. floating_cn_ratio_decomp_pools(i) ) then
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(ns_soil%decomp_npools_vr_col(c,j,i) > 0)then
+ Ksoiln%DM(c,j+(i-1)*nlevdecomp) = Ksoil%DM(c,j+(i-1)*nlevdecomp) * cs_soil%decomp_cpools_vr_col(c,j,i) / ns_soil%decomp_npools_vr_col(c,j,i) / initial_cn_ratio(i)
+ end if
+ end do
+ end do
+ end if
+ end do
+ ! Save the C and N pool size at begin of each year, which are used to calculate C and N capacity at end of each year.
+ call t_startf('CN Soil matrix-assign matrix-decomp0')
+ if (is_beg_curr_year())then
+ iyr = iyr + 1
+ if(mod(iyr-1,nyr_forcing) .eq. 0)then
+ iloop = iloop + 1
+ end if
+ if(.not. spinup_matrixcn .or. spinup_matrixcn .and. mod(iyr-1,nyr_SASU) .eq. 0)then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%decomp0_cpools_vr_col(c,j,i)=cs_soil%decomp_cpools_vr_col(c,j,i)
+ if(use_c13)then
+ cs13_soil%decomp0_cpools_vr_col(c,j,i)=cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp0_cpools_vr_col(c,j,i)=cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ ns_soil%decomp0_npools_vr_col(c,j,i)=ns_soil%decomp_npools_vr_col(c,j,i)
+ end do
+ end do
+ end do
+ where(cs_soil%decomp0_cpools_vr_col .lt. epsi)
+ cs_soil%decomp0_cpools_vr_col = epsi
+ end where
+ if(use_c13)then
+ where(cs13_soil%decomp0_cpools_vr_col .lt. epsi*c3_r2)
+ cs13_soil%decomp0_cpools_vr_col = epsi*c3_r2
+ end where
+ end if
+ if(use_c14)then
+ where(cs14_soil%decomp0_cpools_vr_col .lt. epsi*c14ratio)
+ cs14_soil%decomp0_cpools_vr_col = epsi*c14ratio
+ end where
+ end if
+ where(ns_soil%decomp0_npools_vr_col .lt. epsi)
+ ns_soil%decomp0_npools_vr_col = epsi
+ end where
+ end if
+ end if
+ call t_stopf('CN Soil matrix-assign matrix-decomp0')
+
+ ! Set C transfer matrix Ac from a_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAK1')
+ call AKsoilc%SetValueA(begc,endc,num_soilc,filter_soilc,a_ma_vr,A_i,A_j,Ntrans,init_readyAsoilc,list_Asoilc,RI_a,CI_a)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAK1')
+
+ ! Set N transfer matrix An from na_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAK2')
+ call AKsoiln%SetValueA(begc,endc,num_soilc,filter_soilc,na_ma_vr,A_i,A_j,Ntrans,init_readyAsoiln,list_Asoiln,RI_na,CI_na)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAK2')
+
+ ! calculate matrix Ac*K for C
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMM_AK1')
+ call AKsoilc%SPMM_AK(num_soilc,filter_soilc,Ksoil)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMM_AK1')
+
+ ! calculate matrix An*K for N
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMM_AK2')
+ call AKsoiln%SPMM_AK(num_soilc,filter_soilc,Ksoiln)
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMM_AK2')
+
+ ! Set vertical transfer matrix V from tri_ma_vr
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SetValueAV,AKfire')
+ call AVsoil%SetValueSM(begc,endc,num_soilc,filter_soilc,tri_ma_vr(begc:endc,1:Ntri_setup),tri_i,tri_j,Ntri_setup)
+
+ ! Set fire decomposition matrix Kfire from matrix_decomp_fire_k
+ do j=1,ndecomp_pools_vr
+ kfire_i(j) = j
+ kfire_j(j) = j
+ end do
+ call AKfiresoil%SetValueSM(begc,endc,num_soilc,filter_soilc,matrix_decomp_fire_k(begc:endc,1:ndecomp_pools_vr),kfire_i,kfire_j,ndecomp_pools_vr)
+ if(use_c14)then
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cf14_soil%matrix_decomp_fire_k_col(c,j+(i-1)*nlevdecomp) = cf14_soil%matrix_decomp_fire_k_col(c,j+(i-1)*nlevdecomp) &
+ + matrix_decomp_fire_k(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ call cf14_soil%AKfiresoil%SetValueSM(begc,endc,num_soilc,filter_soilc,&
+ cf14_soil%matrix_decomp_fire_k_col(begc:endc,1:ndecomp_pools_vr),kfire_i,kfire_j,ndecomp_pools_vr)
+ end if
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SetValueAV,AKfire')
+
+ ! Calculate AKallsoilc = A*K + AVsoil + AKfiresoil. (AKfiresoil = -Kfire)
+ ! When no fire, AKallsoilc = A*K + AVsoil
+ ! When fire is on, AKallsoilc = A*K + AVsoil + AKfiresoil
+ ! Here, AKallsoilc represents all soil C transfer rate (gC/(gC*m3*step))
+ ! and AKallsoiln represents all soil N transfer rate (gN/(gN*m3*step))
+
+ call t_startf('CN Soil matrix-matrix mult1-lev3-SPMP_AB')
+ if(num_actfirec .eq. 0)then
+ call AKallsoilc%SPMP_AB(num_soilc,filter_soilc,AKsoilc,AVsoil,list_ready1_nofire,list_A=list_AK_AKV, list_B=list_V_AKV,&
+ NE_AB=NE_AKallsoilc,RI_AB=RI_AKallsoilc,CI_AB=CI_AKallsoilc)
+ call AKallsoiln%SPMP_AB(num_soilc,filter_soilc,AKsoiln,AVsoil,list_ready2_nofire,list_A=list_AK_AKV, list_B=list_V_AKV,&
+ NE_AB=NE_AKallsoiln,RI_AB=RI_AKallsoiln,CI_AB=CI_AKallsoiln)
+ else
+ call AKallsoilc%SPMP_ABC(num_soilc,filter_soilc,AKsoilc,AVsoil,AKfiresoil,list_ready1_fire,list_A=list_AK_AKVfire,&
+ list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=NE_AKallsoilc,RI_ABC=RI_AKallsoilc,CI_ABC=CI_AKallsoilc,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirec,filter_actunit_C=filter_actfirec)
+ call AKallsoiln%SPMP_ABC(num_soilc,filter_soilc,AKsoiln,AVsoil,AKfiresoil,list_ready2_fire,list_A=list_AK_AKVfire,&
+ list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=NE_AKallsoiln,RI_ABC=RI_AKallsoiln,CI_ABC=CI_AKallsoiln,&
+ use_actunit_list_C=.True.,num_actunit_C=num_actfirec,filter_actunit_C=filter_actfirec)
+ end if
+ if(use_c14)then
+ call cf14_soil%AKallsoilc%SPMP_ABC(num_soilc,filter_soilc,AKsoilc,AVsoil,cf14_soil%AKfiresoil,list_ready3_fire,&
+ list_A=list_AK_AKVfire,list_B=list_V_AKVfire,list_C=list_fire_AKVfire,NE_ABC=cf14_soil%NE_AKallsoilc,&
+ RI_ABC=cf14_soil%RI_AKallsoilc,CI_ABC=cf14_soil%CI_AKallsoilc)
+ end if
+
+ call t_stopf('CN Soil matrix-matrix mult1-lev3-SPMP_AB')
+
+ call t_startf('CN Soil matrix-matrix mult2-lev2')
+
+ ! Update soil C pool size: X(matrix_Cinter) = X(matrix_Cinter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter)
+ ! Update soil N pool size: X(matrix_Ninter) = X(matrix_Ninter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Ninter)
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ do i=1,AVsoil%NE
+ ilev = mod(AVsoil%RI(i)-1,nlevdecomp)+1
+ idecomp = (AVsoil%RI(i) - ilev)/nlevdecomp + 1
+ trcr_ctendency(c,ilev,idecomp) = trcr_ctendency(c,ilev,idecomp) + AVsoil%M(c,i)*matrix_Cinter%V(c,AVsoil%CI(i)) / dt
+ trcr_ntendency(c,ilev,idecomp) = trcr_ntendency(c,ilev,idecomp) + AVsoil%M(c,i)*matrix_Ninter%V(c,AVsoil%CI(i)) / dt
+ end do
+ end do
+
+ call matrix_Cinter%SPMM_AX(num_soilc,filter_soilc,AKallsoilc)
+ call matrix_Ninter%SPMM_AX(num_soilc,filter_soilc,AKallsoiln)
+
+ ! Update soil C13 pool size: X(matrix_Cinter13) = X(matrix_Cinter13) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter13)
+ if ( use_c13)then
+ call matrix_Cinter13%SPMM_AX(num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+ ! Update soil C14 pool size: X(matrix_Cinter14) = X(matrix_Cinter14) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter14)
+ if ( use_c14)then
+ call matrix_Cinter14%SPMM_AX(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ end if
+
+ ! Update soil C pool size: X(matrix_Cinter) = X(matrix_Cinter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter) + I(matrix_Cinput)
+ ! Update soil N pool size: X(matrix_Ninter) = X(matrix_Ninter) + (A*K + AVsoil + AKfiresoil) * X(matrix_Ninter) + I(matrix_Ninput)
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter%V(c,j) = matrix_Cinput%V(c,j) + matrix_Cinter%V(c,j)
+ matrix_Ninter%V(c,j) = matrix_Ninput%V(c,j) + matrix_Ninter%V(c,j)
+ end do
+ end do
+
+ ! Update soil C13 pool size: X(matrix_Cinter13) = X(matrix_Cinter13) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter13) + I(matrix_Cinput13)
+ if ( use_c13)then
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter13%V(c,j) = matrix_Cinput13%V(c,j) + matrix_Cinter13%V(c,j)
+ end do
+ end do
+ end if
+
+ ! Update soil C14 pool size: X(matrix_Cinter14) = X(matrix_Cinter14) + (A*K + AVsoil + AKfiresoil) * X(matrix_Cinter14) + I(matrix_Cinput14)
+ if ( use_c14)then
+ do j = 1, ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ matrix_Cinter14%V(c,j) = matrix_Cinput14%V(c,j) + matrix_Cinter14%V(c,j)
+ end do
+ end do
+ end if !c14
+
+ ! Adjust heterotrophic respiration and fire flux because the pool size updating order is different between default and matrix code, balance error will occur
+ ! while sudden big changes happen in C pool, eg. crop harvest and fire.
+ call t_stopf('CN Soil matrix-matrix mult2-lev2')
+
+ call t_startf('CN Soil matrix-assign back')
+
+ ! Send vector type soil C and N pool size back to decomp_cpools_vr_col and decomp_npools_vr_col
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter%V(c,j+(i-1)*nlevdecomp)
+ ns_soil%decomp_npools_vr_col(c,j,i) = matrix_Ninter%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+
+ if( use_c13 ) then
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter13%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ end if
+
+ if( use_c14 ) then
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = matrix_Cinter14%V(c,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ end do
+ end if
+
+ call t_stopf('CN Soil matrix-assign back')
+
+ if(use_soil_matrixcn .and. (hist_wrt_matrixcn_diag .or. spinup_matrixcn))then
+
+ ! Accumulate C transfers during a whole calendar year to calculate the C and N capacity
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%in_acc (c,j) = cs_soil%in_acc (c,j) + matrix_Cinput%V(c,j)
+ ns_soil%in_nacc(c,j) = ns_soil%in_nacc(c,j) + matrix_Ninput%V(c,j)
+ end do
+ end do
+ if(use_c13)then
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs13_soil%in_acc (c,j) = cs13_soil%in_acc (c,j) + matrix_Cinput13%V(c,j)
+ end do
+ end do
+ end if
+ if(use_c14)then
+ do j=1,ndecomp_pools*nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs14_soil%in_acc (c,j) = cs14_soil%in_acc (c,j) + matrix_Cinput14%V(c,j)
+ end do
+ end do
+ end if
+
+ if(use_c13)then
+ call cf13_soil%AKallsoilc%SetValueCopySM (num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+! if(use_c14)then
+! call cf14_soil%AKallsoilc%SetValueCopySM (num_soilc,filter_soilc,AKallsoilc)
+! end if
+ ! Calculate all the soil C transfers in current time step.
+ ! After this step, AKallsoilc represents all the C transfers (gC/m3/step)
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,Cinter_old(begc:endc,1:ndecomp_pools_vr))
+ call AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+
+ if(use_c13)then
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,C13inter_old(begc:endc,1:ndecomp_pools_vr))
+ call cf13_soil%AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+ end if
+
+ if(use_c14)then
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,C14inter_old(begc:endc,1:ndecomp_pools_vr))
+ call cf14_soil%AKallsoilc%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+ end if
+
+ ! Calculate all the soil N transfers in current time step
+ ! After this step, AKallsoiln represents all the N transfers (gN/m3/step)
+ call Xdiagsoil%SetValueDM(begc,endc,num_soilc,filter_soilc,Ninter_old(begc:endc,1:ndecomp_pools_vr))
+ call AKallsoiln%SPMM_AK(num_soilc,filter_soilc,Xdiagsoil)
+
+ !
+ ! Accumulate soil C transfers: AKXcacc = AKXcacc + AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if ( is_first_restart_step() )then
+ call AKXcacc%CopyIdxSM( AKallsoilc )
+ end if
+ if ( AKXcacc%IsValuesSetSM() )then
+ call AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call AKXcacc%SetValueCopySM(num_soilc,filter_soilc,AKallsoilc)
+ end if
+
+ !
+ ! Accumulate soil C13 transfers: cs13_soil%AKXcacc = cs13_soil%AKXcacc + cs13_soil%AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if(use_c13)then
+ if ( is_first_restart_step() )then
+ call cs13_soil%AKXcacc%CopyIdxSM( cf13_soil%AKallsoilc )
+ end if
+ if ( cs13_soil%AKXcacc%IsValuesSetSM() )then
+ call cs13_soil%AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,cf13_soil%AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call cs13_soil%AKXcacc%SetValueCopySM(num_soilc,filter_soilc,cf13_soil%AKallsoilc)
+ end if
+ end if
+
+ !
+ ! Accumulate soil C14 transfers: cs14_soil%AKXcacc = cs14_soil%AKXcacc + cs14_soil%AKallsoilc
+ !
+ ! Copy indices from AKallsoilc on restart step
+ if(use_c14)then
+ if ( is_first_restart_step() )then
+ call cs14_soil%AKXcacc%CopyIdxSM( cf14_soil%AKallsoilc )
+ end if
+ if ( cs14_soil%AKXcacc%IsValuesSetSM() )then
+ call cs14_soil%AKXcacc%SPMP_B_ACC(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ else
+ ! This should only happen on the first time-step
+ call cs14_soil%AKXcacc%SetValueCopySM(num_soilc,filter_soilc,cf14_soil%AKallsoilc)
+ end if
+ end if
+
+ !
+ ! Accumulate soil N transfers: AKXnacc = AKXnacc + AKallsoiln
+ !
+ ! Copy indices from AKallsoiln on restart step
+ if ( is_first_restart_step() )then
+ call AKXnacc%CopyIdxSM( AKallsoiln )
+ end if
+ if ( AKXnacc%IsValuesSetSM() )then
+ call AKXnacc%SPMP_B_ACC(num_soilc,filter_soilc,AKallsoiln)
+ else
+ ! This should only happen on the first time-step
+ call AKXnacc%SetValueCopySM(num_soilc,filter_soilc,AKallsoiln)
+ end if
+
+ call t_startf('CN Soil matrix-calc. C capacity')
+ if((.not. spinup_matrixcn .and. is_end_curr_year()) .or. (spinup_matrixcn .and. is_end_curr_year() .and. mod(iyr,nyr_SASU) .eq. 0))then
+ ! Copy C transfers from sparse matrix to 2D temporary variables tran_acc and tran_nacc
+ ! Calculate the C and N transfer rate by dividing CN transfer by base value saved at begin of each year.
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ ns_soil%tran_nacc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ if(use_c13)then
+ cs13_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%tran_acc (c,1:ndecomp_pools_vr,1:ndecomp_pools_vr) = 0._r8
+ end if
+ end do
+ do j=1,n_all_entries
+ j_lev = mod(all_j(j)-1,nlevdecomp)+1
+ j_decomp = (all_j(j) - j_lev)/nlevdecomp + 1
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%tran_acc(c,all_i(j),all_j(j)) = AKXcacc%M(c,j) / cs_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ ns_soil%tran_nacc(c,all_i(j),all_j(j)) = AKXnacc%M(c,j) / ns_soil%decomp0_npools_vr_col(c,j_lev,j_decomp)
+ if(use_c13)then
+ cs13_soil%tran_acc(c,all_i(j),all_j(j)) = cs13_soil%AKXcacc%M(c,j) / cs13_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ end if
+ if(use_c14)then
+ cs14_soil%tran_acc(c,all_i(j),all_j(j)) = cs14_soil%AKXcacc%M(c,j) / cs14_soil%decomp0_cpools_vr_col(c,j_lev,j_decomp)
+ end if
+ end do
+ end do
+
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+
+ if(use_c13)then
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs13_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs13_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+ end if
+
+ if(use_c14)then
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(cs14_soil%tran_acc(c,i,i)) .le. epsi)then !avoid inversion nan
+ cs14_soil%tran_acc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+ end if
+
+ do i=1,ndecomp_pools_vr
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if (abs(ns_soil%tran_nacc(c,i,i)) .le. epsi)then
+ ns_soil%tran_nacc(c,i,i) = 1.e+36_r8
+ end if
+ end do
+ end do
+
+ ! Calculate capacity
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ call inverse(cs_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs_soil%in_acc(c,1:ndecomp_pools_vr))
+ if(use_c13)then
+ call inverse(cs13_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc13_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs13_soil%in_acc(c,1:ndecomp_pools_vr))
+ end if
+ if(use_c14)then
+ call inverse(cs14_soil%tran_acc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixc14_cap(c,:,1) = -matmul(AKinv(1:ndecomp_pools_vr,1:ndecomp_pools_vr),cs14_soil%in_acc(c,1:ndecomp_pools_vr))
+ end if
+ call inverse(ns_soil%tran_nacc(c,1:ndecomp_pools_vr,1:ndecomp_pools_vr),AKinvn(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ndecomp_pools_vr)
+ soilmatrixn_cap(c,:,1) = -matmul(AKinvn(1:ndecomp_pools_vr,1:ndecomp_pools_vr),ns_soil%in_nacc(c,1:ndecomp_pools_vr))
+ end do
+
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(use_c13 .and. soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(use_c14 .and. soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ if(soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .lt. 0)then
+ soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) = 0._r8
+ endif
+ end do
+ end do
+ end do
+
+
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(nyr_SASU .eq. nyr_forcing .and. &
+ (soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)/cs_soil%decomp0_cpools_vr_col(c,j,i) .gt. 100 .and. soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+5_r8 &
+ .or. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)/ns_soil%decomp0_npools_vr_col(c,j,i) .gt. 100 .and. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+3_r8) &
+ .or. nyr_SASU .lt. nyr_forcing .and. i .eq. i_cwd .and. &
+ (soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)/cs_soil%decomp0_cpools_vr_col(c,j,i) .gt. 100 .and. soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+5_r8 &
+ .or. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)/ns_soil%decomp0_npools_vr_col(c,j,i) .gt. 100 .and. soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) .gt. 1.e+3_r8) )then
+ soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter%V(c,j+(i-1)*nlevdecomp)
+ if(use_c13)then
+ soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter13%V(c,j+(i-1)*nlevdecomp)
+ end if
+ if(use_c14)then
+ soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Cinter14%V(c,j+(i-1)*nlevdecomp)
+ end if
+ soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1) = matrix_Ninter%V(c,j+(i-1)*nlevdecomp)
+ end if
+ end do
+ end do
+ end do
+
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(any(soilmatrixc_cap(c,:,1) .gt. 1.e+8_r8) .or. any(soilmatrixn_cap(c,:,1) .gt. 1.e+8_r8))then
+ soilmatrixc_cap(c,:,1) = matrix_Cinter%V(c,:)
+ if(use_c13)then
+ soilmatrixc13_cap(c,:,1) = matrix_Cinter13%V(c,:)
+ end if
+ if(use_c14)then
+ soilmatrixc14_cap(c,:,1) = matrix_Cinter14%V(c,:)
+ end if
+ soilmatrixn_cap(c,:,1) = matrix_Ninter%V(c,:)
+ end if
+ end do
+
+ ! If spin up is on, the capacity replaces the pool size with capacity.
+ ! Copy the capacity into a 3D variable, and be ready to write to history files.
+ do i=1,ndecomp_pools
+ do j = 1,nlevdecomp
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ if(spinup_matrixcn .and. .not. is_first_step_of_this_run_segment())then
+ cs_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(floating_cn_ratio_decomp_pools(i))then
+ ns_soil%decomp_npools_vr_col(c,j,i) = soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)
+ else
+ ns_soil%decomp_npools_vr_col(c,j,i) = cs_soil%decomp_cpools_vr_col(c,j,i) / cn_decomp_pools(c,j,i)
+ end if
+ ! calculate the average of the storage capacity when iloop equals to iloop_avg
+ if(iloop .eq. iloop_avg)then
+ cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs_soil%decomp_cpools_vr_col(c,j,i)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs13_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) + cs14_soil%decomp_cpools_vr_col(c,j,i)
+ end if
+ ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) = ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) + ns_soil%decomp_npools_vr_col(c,j,i)
+ if(iyr .eq. nyr_forcing)then
+ cs_soil%decomp_cpools_vr_col(c,j,i) = cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_col(c,j,i) = cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_col(c,j,i) = cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ end if
+ ns_soil%decomp_npools_vr_col(c,j,i) = ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) / (nyr_forcing/nyr_SASU)
+ cs_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ if(use_c13)then
+ cs13_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%decomp_cpools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ ns_soil%decomp_npools_vr_SASUsave_col(c,j,i) = 0._r8
+ end if
+ end if
+ end if
+ cs_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc_cap(c,j+(i-1)*nlevdecomp,1)
+ if(use_c13)then
+ cs13_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc13_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ if(use_c14)then
+ cs14_soil%matrix_cap_decomp_cpools_vr_col(c,j,i) = soilmatrixc14_cap(c,j+(i-1)*nlevdecomp,1)
+ end if
+ ns_soil%matrix_cap_decomp_npools_vr_col(c,j,i) = soilmatrixn_cap(c,j+(i-1)*nlevdecomp,1)
+ end do
+ end do
+ end do
+
+ if(spinup_matrixcn)call update_DA_nstep()
+ if(iloop .eq. iloop_avg .and. iyr .eq. nyr_forcing)iloop = 0
+ if(iyr .eq. nyr_forcing)iyr = 0
+
+ ! Reset to accumulation variables to 0 at end of each year
+ do j=1,n_all_entries
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ AKXcacc%M(c,j) = 0._r8
+ if(use_c13)then
+ cs13_soil%AKXcacc%M(c,j) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%AKXcacc%M(c,j) = 0._r8
+ end if
+ AKXnacc%M(c,j) = 0._r8
+ end do
+ end do
+
+ do fc = 1,num_soilc
+ c = filter_soilc(fc)
+ cs_soil%in_acc (c,:) = 0._r8
+ if(use_c13)then
+ cs13_soil%in_acc (c,:) = 0._r8
+ end if
+ if(use_c14)then
+ cs14_soil%in_acc (c,:) = 0._r8
+ end if
+ ns_soil%in_nacc (c,:) = 0._r8
+ end do
+ end if
+ call t_stopf('CN Soil matrix-calc. C capacity')
+ end if !is out_matrix
+
+ end associate
+ end subroutine CNSoilMatrix
+
+ !-----------------------------------------------------------------------
+ subroutine CNSoilMatrixRest( ncid, flag )
+ ! !DESCRIPTION:
+ !
+ ! Read/write restart data needed for the CN soil Matrix model solution
+ !
+ ! !USES:
+ use restUtilMod , only: restartvar
+ use ncdio_pio , only: file_desc_t, ncd_int
+ !
+ ! !ARGUMENTS:
+ type(file_desc_t) , intent(inout) :: ncid ! netcdf id
+ character(len=*) , intent(in) :: flag !'read' or 'write'
+ !
+ ! !LOCAL VARIABLES:
+ logical :: readvar ! determine if variable is on initial file
+ !------------------------------------------------------------------------
+ call restartvar(ncid=ncid, flag=flag, varname='soil_cycle_year', xtype=ncd_int, &
+ long_name='Year number in soil spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iyr)
+
+ call restartvar(ncid=ncid, flag=flag, varname='soil_cycle_loop', xtype=ncd_int, &
+ long_name='Loop number in soil spinup cycle sequence', units='years', &
+ interpinic_flag='skip', readvar=readvar, data=iloop)
+
+ !------------------------------------------------------------------------
+ end subroutine CNSoilMatrixRest
+
+end module CNSoilMatrixMod
+
diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
index 2cb28f04e9..23f24e44d5 100644
--- a/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemCarbonFluxType.F90
@@ -3,8 +3,8 @@ module SoilBiogeochemCarbonFluxType
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use decompMod , only : bounds_type
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevcan
- use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi, i_cwdl2
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, ndecomp_cascade_outtransitions
+ use clm_varpar , only : nlevdecomp_full, nlevgrnd, nlevdecomp, nlevsoi, ndecomp_pools_vr, i_cwdl2
use clm_varcon , only : spval, ispval, dzsoi_decomp
use clm_varctl , only : use_fates,use_cn
use pftconMod , only : pftcon
@@ -40,6 +40,7 @@ module SoilBiogeochemCarbonFluxType
real(r8), pointer :: rf_decomp_cascade_col (:,:,:) ! (frac) respired fraction in decomposition step
real(r8), pointer :: pathfrac_decomp_cascade_col (:,:,:) ! (frac) what fraction of C passes from donor to receiver pool through a given transition
real(r8), pointer :: decomp_k_col (:,:,:) ! rate coefficient for decomposition (1./sec)
+ ! foi soil-matrix
real(r8), pointer :: hr_vr_col (:,:) ! (gC/m3/s) total vertically-resolved het. resp. from decomposing C pools
real(r8), pointer :: o_scalar_col (:,:) ! fraction by which decomposition is limited by anoxia
real(r8), pointer :: w_scalar_col (:,:) ! fraction by which decomposition is limited by moisture availability
@@ -61,8 +62,25 @@ module SoilBiogeochemCarbonFluxType
real(r8), pointer :: fates_litter_flux (:) ! (gC/m2/s) A summary of the total litter
! flux passed in from FATES.
! This is a diagnostic for balance checks only
+ ! track tradiagonal matrix
+ real(r8), pointer :: matrix_decomp_fire_k_col (:,:) ! decomposition rate due to fire (gC*m3)/(gC*m3*step))
+ real(r8), pointer :: tri_ma_vr (:,:) ! vertical C transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
+
+ type(sparse_matrix_type) :: AKsoilc ! A*K for C transfers between pools
+ type(sparse_matrix_type) :: AVsoil ! V for C and N transfers between soil layers
+ type(sparse_matrix_type) :: AKfiresoil ! Kfire for CN transfers from soil to atm due to fire
+ type(sparse_matrix_type) :: AKallsoilc ! (A*K+V-Kfire) for soil C cycle
+ integer :: NE_AKallsoilc ! Number of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_AKallsoilc ! Row numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: CI_AKallsoilc ! Column numbers of entries in AKallsoilc, Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_a ! Row numbers of all entries from AKsoilc, Automatically generated by SetValueA
+ integer,pointer,dimension(:) :: CI_a ! Column numbers of all entries from AKsoilc, Automatically generated by SetValueA
+
+ type(diag_matrix_type) :: Ksoil ! CN turnover rate in different soil pools and layers
+ type(diag_matrix_type) :: Xdiagsoil ! Temporary C and N state variable to calculate accumulation transfers
+
+ type(vector_type) :: matrix_Cinput ! C input to different soil compartments (pools and layers) (gC/m3/step)
-
contains
procedure , public :: Init
@@ -168,6 +186,25 @@ subroutine InitAllocate(this, bounds)
end if
if(use_soil_matrixcn)then
+ allocate(this%matrix_decomp_fire_k_col(begc:endc,1:nlevdecomp*ndecomp_pools)); this%matrix_decomp_fire_k_col(:,:)= nan
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ call this%AKsoilc%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+ndecomp_pools*nlevdecomp)
+ call this%AVsoil%InitSM (ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%Ntri_setup)
+ call this%AKfiresoil%InitSM (ndecomp_pools*nlevdecomp,begc,endc,ndecomp_pools*nlevdecomp)
+ call this%AKallsoilc%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+decomp_cascade_con%Ntri_setup+nlevdecomp)
+ this%NE_AKallsoilc = Ntrans+ndecomp_pools*nlevdecomp+decomp_cascade_con%Ntri_setup+ndecomp_pools*nlevdecomp
+ allocate(this%RI_AKallsoilc(1:this%NE_AKallsoilc)); this%RI_AKallsoilc(1:this%NE_AKallsoilc)=-9999
+ allocate(this%CI_AKallsoilc(1:this%NE_AKallsoilc)); this%CI_AKallsoilc(1:this%NE_AKallsoilc)=-9999
+ Ntrans_diag = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp+ndecomp_pools_vr
+ allocate(this%RI_a(1:Ntrans_diag)); this%RI_a(1:Ntrans_diag) = -9999
+ allocate(this%CI_a(1:Ntrans_diag)); this%CI_a(1:Ntrans_diag) = -9999
+ call this%Ksoil%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%Xdiagsoil%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%matrix_Cinput%InitV(ndecomp_pools*nlevdecomp,begc,endc)
+
+ allocate(this%tri_ma_vr(begc:endc,1:decomp_cascade_con%Ntri_setup))
+ else
+ allocate(this%tri_ma_vr(1,1)); this%tri_ma_vr(:,:) = nan
end if
allocate(this%litr_lig_c_to_n_col(begc:endc))
@@ -724,6 +761,22 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
! for matrix
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_pools
+ do j = 1, nlevdecomp
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%matrix_decomp_fire_k_col(i,j+nlevdecomp*(k-1)) = value_column
+ end do
+ end do
+ end do
+ call this%matrix_Cinput%SetValueV_scaler(num_column,filter_column(1:num_column),value_column)
+ !
+ do k = 1,decomp_cascade_con%Ntri_setup
+ do fi = 1,num_column
+ i = filter_column(fi)
+ this%tri_ma_vr(i,k) = value_column
+ end do
+ end do
end if
do j = 1, nlevdecomp_full
do fi = 1,num_column
diff --git a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90 b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
index de269a4c78..768811925d 100644
--- a/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemCarbonStateType.F90
@@ -27,6 +27,8 @@ module SoilBiogeochemCarbonStateType
! all c pools involved in decomposition
real(r8), pointer :: decomp_cpools_vr_col (:,:,:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
+ real(r8), pointer :: decomp0_cpools_vr_col(:,:,:) ! (gC/m3) vertically-resolved C baseline (initial value of this year) in decomposing (litter, cwd, soil) pools in dimension (col,nlev,npools)
+ real(r8), pointer :: decomp_cpools_vr_SASUsave_col(:,:,:) ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) c pools
real(r8), pointer :: decomp_soilc_vr_col (:,:) ! (gC/m3) vertically-resolved decomposing total soil c pool
real(r8), pointer :: ctrunc_vr_col (:,:) ! (gC/m3) vertically-resolved column-level sink for C truncation
@@ -54,6 +56,17 @@ module SoilBiogeochemCarbonStateType
! Matrix-cn
+ real(r8), pointer :: matrix_cap_decomp_cpools_col (:,:) ! (gC/m2) C capacity in decomposing (litter, cwd, soil) N pools in dimension (col,npools)
+ real(r8), pointer :: matrix_cap_decomp_cpools_vr_col (:,:,:) ! (gC/m3) vertically-resolved C capacity in decomposing (litter, cwd, soil) pools in dimension(col,nlev,npools)
+ real(r8), pointer :: in_acc (:,:) ! (gC/m3/yr) accumulated litter fall C input per year in dimension(col,nlev*npools)
+ real(r8), pointer :: in_acc_2d (:,:,:) ! (gC/m3/yr) accumulated litter fall C input per year in dimension(col,nlev,npools)
+ real(r8), pointer :: tran_acc (:,:,:) ! (gC/m3/yr) accumulated C transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools)
+ real(r8), pointer :: vert_up_tran_acc (:,:,:) ! (gC/m3/yr) accumulated upward vertical C transport in dimension(col,nlev,npools)
+ real(r8), pointer :: vert_down_tran_acc (:,:,:) ! (gC/m3/yr) accumulated downward vertical C transport in dimension(col,nlev,npools)
+ real(r8), pointer :: exit_acc (:,:,:) ! (gC/m3/yr) accumulated exit C in dimension(col,nlev,npools)
+ real(r8), pointer :: hori_tran_acc (:,:,:) ! (gC/m3/yr) accumulated C transport between pools at the same level in dimension(col,nlev,ntransfers)
+ type(sparse_matrix_type) :: AKXcacc ! (gC/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools) in sparse matrix type
+ type(vector_type) :: matrix_Cinter ! (gC/m3) vertically-resolved decomposing (litter, cwd, soil) N pools in dimension(col,nlev*npools) in vector type
contains
@@ -113,17 +126,41 @@ subroutine InitAllocate(this, bounds)
allocate( this%decomp_cpools_col (begc :endc,1:ndecomp_pools)) ; this%decomp_cpools_col (:,:) = nan
allocate( this%decomp_cpools_1m_col (begc :endc,1:ndecomp_pools)) ; this%decomp_cpools_1m_col (:,:) = nan
+ if(use_soil_matrixcn)then
+ allocate( this%matrix_cap_decomp_cpools_col (begc :endc,1:ndecomp_pools)) ; this%matrix_cap_decomp_cpools_col (:,:) = nan
+ end if
allocate( this%ctrunc_vr_col(begc :endc,1:nlevdecomp_full)) ;
this%ctrunc_vr_col (:,:) = nan
allocate(this%decomp_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
this%decomp_cpools_vr_col(:,:,:)= nan
-
- ! Matrix-spinup
+ !matrix-spinup
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%matrix_cap_decomp_cpools_vr_col(:,:,:)= nan
+ allocate(this%decomp0_cpools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%decomp0_cpools_vr_col(:,:,:)= nan
+ allocate(this%decomp_cpools_vr_SASUsave_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%decomp_cpools_vr_SASUsave_col(:,:,:)= nan
+ allocate(this%in_acc(begc:endc,1:nlevdecomp*ndecomp_pools))
+ this%in_acc(:,:)= nan
+ allocate(this%tran_acc(begc:endc,1:nlevdecomp*ndecomp_pools,1:nlevdecomp*ndecomp_pools))
+ this%tran_acc(:,:,:)= nan
+
+ allocate(this%in_acc_2d(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%in_acc_2d(:,:,:)= nan
+ allocate(this%vert_up_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_up_tran_acc(:,:,:)= nan
+ allocate(this%vert_down_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_down_tran_acc(:,:,:)= nan
+ allocate(this%exit_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%exit_acc(:,:,:)= nan
+ allocate(this%hori_tran_acc(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions))
+ this%hori_tran_acc(:,:,:)= nan
+ call this%AKXcacc%InitSM(ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%n_all_entries)
+ call this%matrix_Cinter%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
-
allocate(this%decomp_soilc_vr_col(begc:endc,1:nlevdecomp_full))
this%decomp_soilc_vr_col(:,:)= nan
@@ -217,11 +254,24 @@ subroutine InitHistory(this, bounds, carbon_type)
! Matrix solution history fields
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(begc:endc,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr)
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end do
@@ -317,11 +367,24 @@ subroutine InitHistory(this, bounds, carbon_type)
! Matrix solution history fields
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(begc:endc,:,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = 'C13_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = 'C13 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC13/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr, default='inactive')
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = 'C13_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = 'C13 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC13/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end do
end if
@@ -420,11 +483,22 @@ subroutine InitHistory(this, bounds, carbon_type)
end if
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(begc:endc,:,:) = spval
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
+ data2dptr => this%matrix_cap_decomp_cpools_vr_col(:,1:nlevsoi,l)
+ fieldname = 'C14_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap_vr'
+ longname = 'C14 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gC14/m^3', type2d='levsoi', &
+ avgflag='I', long_name=longname, ptr_col=data2dptr, default='inactive')
endif
if ( nlevdecomp_full .eq. 1)then
+ data1dptr => this%matrix_cap_decomp_cpools_col(:,l)
+ fieldname = 'C14_'//trim(decomp_cascade_con%decomp_pool_name_history(l))//'C_Cap'
+ longname = 'C14 '//trim(decomp_cascade_con%decomp_pool_name_history(l))//' C capacity'
+ call hist_addfld1d (fname=fieldname, units='gC14/m^2', &
+ avgflag='I', long_name=longname, ptr_col=data1dptr)
end if
end do
end if
@@ -502,8 +576,10 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do c = bounds%begc, bounds%endc
l = col%landunit(c)
- ! matrix-spinup
+ ! matrix spinup
if(use_soil_matrixcn)then
+ this%in_acc(c,:) = 0._r8
+ this%AKXcacc%M(c,:) = 0._r8
end if
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
@@ -514,10 +590,12 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
if (zsoi(j) < decomp_cascade_con%initial_stock_soildepth ) then !! only initialize upper soil column
this%decomp_cpools_vr_col(c,j,k) = decomp_cascade_con%initial_stock(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = decomp_cascade_con%initial_stock(k)
end if
else
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
endif
end do
@@ -528,6 +606,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
end do
this%ctrunc_vr_col(c,j) = 0._r8
@@ -536,6 +615,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
this%decomp_cpools_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
this%decomp_cpools_1m_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,1:ndecomp_pools) = decomp_cascade_con%initial_stock(1:ndecomp_pools)
end if
else
@@ -544,6 +624,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(c,j,k) * ratio
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(c,j,k) * ratio
end if
end do
this%ctrunc_vr_col(c,j) = c12_soilbiogeochem_carbonstate_inst%ctrunc_vr_col(c,j) * ratio
@@ -553,6 +634,7 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
do k = 1, ndecomp_pools
this%decomp_cpools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(c,j,k) = 0._r8
end if
end do
this%ctrunc_vr_col(c,j) = 0._r8
@@ -562,11 +644,28 @@ subroutine InitCold(this, bounds, ratio, c12_soilbiogeochem_carbonstate_inst)
this%decomp_cpools_col(c,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_col(c,k) * ratio
this%decomp_cpools_1m_col(c,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_1m_col(c,k) * ratio
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_col(c,k) * ratio
end if
end do
endif
if(use_soil_matrixcn)then
+ do j = 1, nlevdecomp_full
+ do k = 1, ndecomp_pools
+ this%in_acc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_acc(c,j,k) = 0._r8
+ this%vert_down_tran_acc(c,j,k) = 0._r8
+ this%exit_acc(c,j,k) = 0._r8
+ this%decomp0_cpools_vr_col(c,j,k) = max(this%decomp_cpools_vr_col(c,j,k),1.e-30_r8)
+ this%decomp_cpools_vr_SASUsave_col(c,j,k) = 0._r8
+ end do
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_acc(c,j,k) = 0._r8
+ end do
+ end do
+ do j = 1,decomp_cascade_con%n_all_entries
+ this%AKXcacc%M(c,j) = 0._r8
+ end do
end if
end if
@@ -669,6 +768,126 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c'
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -699,6 +918,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=ptr2d)
if(use_soil_matrixcn)then
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
end if
if (flag=='read' .and. .not. readvar) then
write(iulog,*) 'initializing soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col' &
@@ -709,6 +938,9 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
this%decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(i,j,k) * c3_r2
endif
if(use_soil_matrixcn)then
+ if (this%matrix_cap_decomp_cpools_vr_col(i,j,k) /= spval .and. .not. isnan(this%matrix_cap_decomp_cpools_vr_col(i,j,k)) ) then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(i,j,k) * c3_r2
+ endif
end if
end do
end do
@@ -716,6 +948,113 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c_13'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c_13'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -741,6 +1080,16 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
scale_by_thickness=.false., &
interpinic_flag='interp', readvar=readvar, data=ptr2d)
if(use_soil_matrixcn)then
+ ptr2d => this%matrix_cap_decomp_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_cpools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
end if
if (flag=='read' .and. .not. readvar) then
write(iulog,*) 'initializing soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col with atmospheric c14 value for: '//&
@@ -751,6 +1100,9 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
this%decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col(i,j,k) * c3_r2
endif
if(use_soil_matrixcn)then
+ if (this%matrix_cap_decomp_cpools_vr_col(i,j,k) /= spval .and. .not. isnan(this%matrix_cap_decomp_cpools_vr_col(i,j,k)) ) then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = c12_soilbiogeochem_carbonstate_inst%matrix_cap_decomp_cpools_vr_col(i,j,k) * c3_r2
+ endif
end if
end do
end do
@@ -758,6 +1110,113 @@ subroutine Restart ( this, bounds, ncid, flag, carbon_type, totvegc_col, c12_so
end do
if (use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc_2d(:,j,i) = this%in_acc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_acc(:,i_lev,i_decomp) = this%AKXcacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_acc(:,i_lev,k) = this%AKXcacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'c_14'
+ ptr2d => this%in_acc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_acc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'c_14'
+ ptr2d => this%hori_tran_acc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_acc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', fill_value=spval, scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+ if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_acc(:,j+(i-1)*nlevdecomp) = this%in_acc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_up_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXcacc%M(:,i) = this%vert_down_tran_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXcacc%M(:,i) = this%exit_acc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXcacc%M(:,i) = this%hori_tran_acc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
+ end if
end if
ptr2d => this%ctrunc_vr_col
@@ -895,6 +1354,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
this%decomp_cpools_col(i,k) = value_column
this%decomp_cpools_1m_col(i,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(i,k) = value_column
end if
end do
end do
@@ -905,6 +1365,8 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
i = filter_column(fi)
this%decomp_cpools_vr_col(i,j,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_vr_col(i,j,k) = value_column
+ this%decomp0_cpools_vr_col(i,j,k) = value_column
end if
end do
end do
@@ -915,17 +1377,28 @@ subroutine SetValues ( this, num_column, filter_column, value_column)
do k = 1, ndecomp_pools
do fi = 1, num_column
i = filter_column(fi)
+ this%in_acc_2d(i,j,k) = value_column
+ this%vert_up_tran_acc(i,j,k) = value_column
+ this%vert_down_tran_acc(i,j,k) = value_column
+ this%exit_acc(i,j,k) = value_column
end do
end do
do k = 1, ndecomp_cascade_transitions
do fi = 1, num_column
i = filter_column(fi)
+ this%hori_tran_acc(i,j,k) = value_column
end do
end do
end do
end if
if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%AKXcacc%M(i,j) = value_column
+ end do
+ end do
end if
end subroutine SetValues
@@ -963,6 +1436,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
c = filter_allc(fc)
this%decomp_cpools_col(c,l) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,l) = 0._r8
end if
end do
end do
@@ -974,6 +1448,9 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
this%decomp_cpools_col(c,l) + &
this%decomp_cpools_vr_col(c,j,l) * dzsoi_decomp(j)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_cpools_col(c,l) = &
+ this%matrix_cap_decomp_cpools_col(c,l) + &
+ this%matrix_cap_decomp_cpools_vr_col(c,j,l) * dzsoi_decomp(j)
end if
end do
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
index f4785fc4d8..49fc95d6f5 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeBGCMod.F90
@@ -588,7 +588,8 @@ subroutine decomp_rate_constants_bgc(bounds, num_bgc_soilc, filter_bgc_soilc, &
w_scalar => soilbiogeochem_carbonflux_inst%w_scalar_col , & ! Output: [real(r8) (:,:) ] soil water scalar for decomp
o_scalar => soilbiogeochem_carbonflux_inst%o_scalar_col , & ! Output: [real(r8) (:,:) ] fraction by which decomposition is limited by anoxia
decomp_k => soilbiogeochem_carbonflux_inst%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
- spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
+ spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
)
mino2lim = CNParamsShareInst%mino2lim
@@ -910,9 +911,16 @@ subroutine decomp_rate_constants_bgc(bounds, num_bgc_soilc, filter_bgc_soilc, &
! Above into soil matrix
if(use_soil_matrixcn)then
+ Ksoil%DM(c,j+nlevdecomp*(i_met_lit-1)) = decomp_k(c,j,i_met_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_cel_lit-1)) = decomp_k(c,j,i_cel_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_lig_lit-1)) = decomp_k(c,j,i_lig_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_act_som-1)) = decomp_k(c,j,i_act_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_slo_som-1)) = decomp_k(c,j,i_slo_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_pas_som-1)) = decomp_k(c,j,i_pas_som) * dt
! same for cwd but only if fates is not enabled; fates handles CWD
! on its own structure
if (.not. use_fates) then
+ Ksoil%DM(c,j+nlevdecomp*(i_cwd-1)) = decomp_k(c,j,i_cwd) * dt
end if
end if !use_soil_matrixcn
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
index 0474ab9a63..929db2a46f 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeConType.F90
@@ -8,10 +8,11 @@ module SoilBiogeochemDecompCascadeConType
use shr_kind_mod , only : r8 => shr_kind_r8
use abortutils , only : endrun
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevdecomp
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, nlevdecomp, ndecomp_pools_vr
+ use clm_varpar , only : ndecomp_cascade_outtransitions
use clm_varcon , only : ispval
- use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
use clm_varctl , only : iulog
+ use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
!
implicit none
@@ -47,6 +48,25 @@ module SoilBiogeochemDecompCascadeConType
real(r8) , pointer :: spinup_factor(:) ! factor by which to scale AD and relevant processes by
! Matrix data
+ integer,pointer :: spm_tranlist_a(:,:) ! Prescribed subscripts to map 2D variables (transitions,soil layer) to 1D sparse matrix format in a_ma_vr and na_ma_vr
+ integer,pointer :: A_i(:) ! Prescribed row number of all elements in a_ma_vr
+ integer,pointer :: A_j(:) ! Prescribed column number of all elements in na_ma_vr
+ integer,pointer :: tri_i(:) ! Prescribed row index of all entries in AVsoil
+ integer,pointer :: tri_j(:) ! Prescribed column index of all entries in AVsoil
+ integer,pointer :: all_i(:) ! Prescribed row index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ integer,pointer :: all_j(:) ! Prescribed column index of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+
+ integer,pointer :: list_V_AKVfire (:) ! Saves mapping indices from V to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_AK_AKVfire(:) ! Saves mapping indices from A*K to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_fire_AKVfire(:) ! Saves mapping indices from Kfire to (A*K+V-Kfire) in the addition subroutine SPMP_ABC
+ integer,pointer :: list_AK_AKV (:) ! Saves mapping indices from A*K to (A*K+V) in the addition subroutine SPMP_AB
+ integer,pointer :: list_V_AKV (:) ! Saves mapping indices from V to (A*K+V) in the addition subroutine SPMP_AB
+ integer,pointer :: list_Asoilc (:) ! Saves mapping indices from a_ma_vr to AKsoilc
+ integer,pointer :: list_Asoiln (:) ! Saves mapping indices from na_ma_vr to AKsoiln
+
+ integer, public :: n_all_entries ! Number of all entries in AKallsoilc, AKallsoiln, AKXcacc, and AKXnacc
+ integer, public :: Ntrans_setup ! Number of horizontal transfers between soil and litter pools
+ integer, public :: Ntri_setup ! Number of non-zero entries in AVsoil
end type decomp_cascade_type
@@ -55,7 +75,7 @@ module SoilBiogeochemDecompCascadeConType
integer, public, parameter :: century_decomp = 1 ! CENTURY decomposition method type
integer, public, parameter :: mimics_decomp = 2 ! MIMICS decomposition method type
integer, public :: decomp_method = ispval ! Type of decomposition to use
- logical, public, parameter :: use_soil_matrixcn = .false. ! true => use cn matrix solution for soil BGC
+ logical, public :: use_soil_matrixcn = .false. ! true => use cn matrix solution for soil BGC
type(decomp_cascade_type), public :: decomp_cascade_con
!------------------------------------------------------------------------
@@ -153,7 +173,7 @@ subroutine decomp_cascade_par_init( NLFilename )
ndecomp_cascade_transitions = 7
ndecomp_pools_max = 8
end if
- ! Set ndecomp_pools_vr needed for Matrix solution
+ ndecomp_pools_vr = ndecomp_pools * nlevdecomp
end subroutine decomp_cascade_par_init
@@ -196,9 +216,12 @@ subroutine init_decomp_cascade_constants( )
allocate(decomp_cascade_con%is_cellulose(ibeg:ndecomp_pools))
allocate(decomp_cascade_con%is_lignin(ibeg:ndecomp_pools))
allocate(decomp_cascade_con%spinup_factor(1:ndecomp_pools))
-
- ! Allocate soil matrix data
if(use_soil_matrixcn)then
+ allocate(decomp_cascade_con%spm_tranlist_a(1:nlevdecomp,1:ndecomp_cascade_transitions)); decomp_cascade_con%spm_tranlist_a(:,:) = -9999
+ allocate(decomp_cascade_con%A_i(1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp));decomp_cascade_con%A_i(:) = -9999
+ allocate(decomp_cascade_con%A_j(1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp));decomp_cascade_con%A_j(:) = -9999
+ allocate(decomp_cascade_con%tri_i(1:(3*nlevdecomp-2)*(ndecomp_pools-1))); decomp_cascade_con%tri_i(:) = -9999
+ allocate(decomp_cascade_con%tri_j(1:(3*nlevdecomp-2)*(ndecomp_pools-1))); decomp_cascade_con%tri_j(:) = -9999
end if
!-- properties of each pathway along decomposition cascade
@@ -225,25 +248,122 @@ subroutine init_decomp_cascade_constants( )
decomp_cascade_con%spinup_factor(1:ndecomp_pools) = nan
end if
- ! Soil matrix sizes
if(use_soil_matrixcn)then
+ decomp_cascade_con%Ntrans_setup = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ decomp_cascade_con%Ntri_setup = (3*nlevdecomp-2)*(ndecomp_pools - 1) !exclude one cwd
else
- ! Set to missing value if not used
+ decomp_cascade_con%Ntrans_setup = -9999
+ decomp_cascade_con%Ntri_setup = -9999
end if
end subroutine init_decomp_cascade_constants
- !------------------------------------------------------------------------
- subroutine InitSoilTransfer()
- !
- ! !DESCRIPTION:
- ! Initialize sparse matrix variables and index. Count possible non-zero entries and record their x and y in the matrix.
- ! Collect those non-zero entry information, and save them into the list.
- !------------------------------------------------------------------------
- ! !USES:
- use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
- ! !LOGAL VARIABLES:
- integer i,j,k,m,n
+ subroutine InitSoilTransfer()
+! Initialize sparse matrix variables and index. Count possible non-zero entries and record their x and y in the matrix.
+! Collect those non-zero entry information, and save them into the list.
+
+ use SparseMatrixMultiplyMod, only : sparse_matrix_type, diag_matrix_type, vector_type
+
+ integer i,j,k,m,n
+ integer,dimension(:) :: ntrans_per_donor(1:ndecomp_pools)
+ real(r8),dimension(:) :: SM(1:1,1:decomp_cascade_con%Ntrans_setup),TRI(1:1,1:decomp_cascade_con%Ntri_setup)
+ type(sparse_matrix_type) :: AK, AV, AKfire, AKallsoil!, AKtmp1, AKtmp2
+ logical list_ready,init_readyAK
+ integer num_soilc,filter_c(1:1)
- end subroutine InitSoilTransfer
+ init_readyAK = .false.
+ ntrans_per_donor = 0
+
+ do k = 1,ndecomp_cascade_transitions
+ ntrans_per_donor(decomp_cascade_con%cascade_donor_pool(k)) &
+ = ntrans_per_donor(decomp_cascade_con%cascade_donor_pool(k)) + 1
+ end do
+
+ k = 0
+ n = 1
+ do i = 1,ndecomp_pools
+ do j=1,nlevdecomp
+ do m=1,ntrans_per_donor(i)
+ if(decomp_cascade_con%cascade_receiver_pool(m+k) .ne. 0)then
+ decomp_cascade_con%spm_tranlist_a(j,m+k) = n
+ decomp_cascade_con%A_i(n) = (decomp_cascade_con%cascade_receiver_pool(m+k)-1)*nlevdecomp+j
+ decomp_cascade_con%A_j(n) = (decomp_cascade_con%cascade_donor_pool(m+k)-1)*nlevdecomp+j
+ n = n + 1
+ end if
+ end do
+ end do
+ k = k + ntrans_per_donor(i)
+ end do
+
+ SM = 1._r8
+ if(n-1 .ne. decomp_cascade_con%Ntrans_setup)then
+ write(iulog,*) 'error in InitSoilTransfer: number of transfers is error in count'
+ end if
+
+ n = 1
+ do i = 1,ndecomp_pools
+ do j = 1, nlevdecomp
+ if(.not. decomp_cascade_con%is_cwd(i))then
+ if (j > 1) then ! avoid tranfer from for example,soil1_1st layer to litr3_10th layer
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j - 1
+ n = n + 1
+ end if
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j
+ n = n + 1
+ if (j < nlevdecomp) then ! avoid tranfer from for example, litr3_10th layer to soil1_1st layer
+ TRI(1,n) = 1._r8
+ decomp_cascade_con%tri_j(n) = (i-1)*nlevdecomp + j
+ decomp_cascade_con%tri_i(n) = (i-1)*nlevdecomp + j + 1
+ n = n + 1
+ end if
+ end if
+ end do
+ end do
+
+ if(n-1 .ne. decomp_cascade_con%Ntri_setup)then
+ write(iulog,*) 'error in InitSoilTransfer: number of vertical-transfers is error in count'
+ end if
+
+ num_soilc = 1
+ filter_c(1:1) = 1
+ if ( AK%IsAllocSM() ) call AK%ReleaseSM()
+ call AK%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AK%SetValueA(1,1,num_soilc,filter_c(1:num_soilc),SM,decomp_cascade_con%A_i,decomp_cascade_con%A_j,decomp_cascade_con%Ntrans_setup,init_readyAK)
+ allocate(decomp_cascade_con%list_AK_AKVfire(1:AK%NE))
+ allocate(decomp_cascade_con%list_AK_AKV (1:AK%NE))
+
+ if ( AV%IsAllocSM() ) call AV%ReleaseSM()
+ call AV%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AV%SetValueSM(1,1,num_soilc,filter_c(1:num_soilc),TRI,decomp_cascade_con%tri_i,decomp_cascade_con%tri_j,decomp_cascade_con%Ntri_setup)
+ allocate(decomp_cascade_con%list_V_AKVfire (1:AV%NE))
+ allocate(decomp_cascade_con%list_V_AKV (1:AV%NE))
+
+ if ( AKfire%IsAllocSM() ) call AKfire%ReleaseSM()
+ call AKfire%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AKfire%SetValueA_diag(num_soilc,filter_c(1:num_soilc),1._r8)
+ allocate(decomp_cascade_con%list_fire_AKVfire(1:AKfire%NE))
+
+ list_ready = .false.
+ if ( AKallsoil%IsAllocSM() ) call AKallsoil%ReleaseSM()
+ call AKallsoil%InitSM(ndecomp_pools*nlevdecomp,1,1)
+ call AKallsoil%SPMP_ABC(num_soilc,filter_c(1:num_soilc),AK,AV,AKfire,list_ready)
+
+ decomp_cascade_con%n_all_entries = AKallsoil%NE
+ allocate(decomp_cascade_con%all_i(1:decomp_cascade_con%n_all_entries))
+ allocate(decomp_cascade_con%all_j(1:decomp_cascade_con%n_all_entries))
+ decomp_cascade_con%all_i(:) = AKallsoil%RI(1:decomp_cascade_con%n_all_entries)
+ decomp_cascade_con%all_j(:) = AKallsoil%CI(1:decomp_cascade_con%n_all_entries)
+
+ allocate(decomp_cascade_con%list_Asoilc (1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp))
+ allocate(decomp_cascade_con%list_Asoiln (1:(ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp))
+
+ call AK%ReleaseSM()
+ call AV%ReleaseSM()
+ call AKfire%ReleaseSM()
+ call AKallsoil%ReleaseSM()
+ end subroutine InitSoilTransfer
end module SoilBiogeochemDecompCascadeConType
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
index 65091755f5..e9bb60bcec 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompCascadeMIMICSMod.F90
@@ -18,7 +18,7 @@ module SoilBiogeochemDecompCascadeMIMICSMod
use spmdMod , only : masterproc
use abortutils , only : endrun
use CNSharedParamsMod , only : CNParamsShareInst, nlev_soildecomp_standard
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, InitSoilTransfer, use_soil_matrixcn
use SoilBiogeochemStateType , only : soilbiogeochem_state_type
use SoilBiogeochemCarbonFluxType , only : soilbiogeochem_carbonflux_type
use SoilBiogeochemCarbonStateType , only : soilbiogeochem_carbonstate_type
@@ -734,6 +734,8 @@ subroutine init_decompcascade_mimics(bounds, soilbiogeochem_state_inst, soilstat
nue_decomp_cascade(i_cwdl2) = 1.0_r8
end if
+ if (use_soil_matrixcn) call InitSoilTransfer()
+
deallocate(params_inst%mimics_mge)
deallocate(params_inst%mimics_vmod)
deallocate(params_inst%mimics_vint)
@@ -763,7 +765,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
! decomposition cascade model
!
! !USES:
- use clm_time_manager , only : get_average_days_per_year
+ use clm_time_manager , only : get_average_days_per_year, get_step_size
use clm_varcon , only : secspday, secsphr, tfrz
use clm_varcon , only : g_to_mg, cm3_to_m3
use subgridAveMod , only : p2c
@@ -822,6 +824,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
integer :: p, fp, c, fc, j, k, l, s ! indices
integer :: pf ! fates patch index
integer :: nc ! clump index
+ real(r8):: dt ! decomposition time step
real(r8):: days_per_year ! days per year
real(r8):: depth_scalar(bounds%begc:bounds%endc,1:nlevdecomp)
real(r8):: w_d_o_scalars ! product of w_scalar * depth_scalar * o_scalar
@@ -882,6 +885,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
cn_col => soilbiogeochem_carbonflux_inst%cn_col , & ! Output: [real(r8) (:,:) ] C:N ratio
ligninNratioAvg => soilbiogeochem_carbonflux_inst%litr_lig_c_to_n_col, & ! Input: [real(r8) (:) ] C:N ratio of litter lignin
decomp_k => soilbiogeochem_carbonflux_inst%decomp_k_col , & ! Output: [real(r8) (:,:,:) ] rate for decomposition (1./sec)
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil , & ! Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
spinup_factor => decomp_cascade_con%spinup_factor & ! Input: [real(r8) (:) ] factor for AD spinup associated with each pool
)
@@ -892,6 +896,7 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
mino2lim = CNParamsShareInst%mino2lim
days_per_year = get_average_days_per_year()
+ dt = real( get_step_size(), r8 )
! ! Set "decomp_depth_efolding" parameter
! decomp_depth_efolding = CNParamsShareInst%decomp_depth_efolding
@@ -1311,6 +1316,23 @@ subroutine decomp_rates_mimics(bounds, num_bgc_soilc, filter_bgc_soilc, &
if (get_do_tillage()) then
call get_apply_tillage_multipliers(idop, c, j, decomp_k(c,j,:))
end if
+
+! Above into soil matrix
+ if(use_soil_matrixcn)then
+ Ksoil%DM(c,j+nlevdecomp*(i_met_lit-1)) = decomp_k(c,j,i_met_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_str_lit-1)) = decomp_k(c,j,i_str_lit) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_avl_som-1)) = decomp_k(c,j,i_avl_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_phys_som-1)) = decomp_k(c,j,i_phys_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_chem_som-1)) = decomp_k(c,j,i_chem_som) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_cop_mic-1)) = decomp_k(c,j,i_cop_mic) * dt
+ Ksoil%DM(c,j+nlevdecomp*(i_oli_mic-1)) = decomp_k(c,j,i_oli_mic) * dt
+ ! same for cwd but only if fates is not enabled; fates handles
+ ! CWD
+ ! on its own structure
+ if (.not. use_fates) then
+ Ksoil%DM(c,j+nlevdecomp*(i_cwd-1)) = decomp_k(c,j,i_cwd) * dt
+ end if
+ end if !use_soil_matrixcn
end do
end do
diff --git a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90 b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
index 9bd8b13008..6be924bcf5 100644
--- a/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemDecompMod.F90
@@ -131,7 +131,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc,
decomp_cascade_hr_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_hr_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
decomp_cascade_ctransfer_vr => soilbiogeochem_carbonflux_inst%decomp_cascade_ctransfer_vr_col , & ! Output: [real(r8) (:,:,:) ] vertically-resolved het. resp. from decomposing C pools (gC/m3/s)
phr_vr => soilbiogeochem_carbonflux_inst%phr_vr_col , & ! Input: [real(r8) (:,:) ] potential HR (gC/m3/s)
- fphr => soilbiogeochem_carbonflux_inst%fphr_col & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+ fphr => soilbiogeochem_carbonflux_inst%fphr_col , & ! Output: [real(r8) (:,:) ] fraction of potential SOM + LITTER heterotrophic
+ Ksoil => soilbiogeochem_carbonflux_inst%Ksoil & ! In/Output: [real(r8) (:,:,:) ] rate constant for decomposition (1./sec)
)
! column loop to calculate actual immobilization and decomp rates, following
@@ -177,6 +178,8 @@ subroutine SoilBiogeochemDecomp (bounds, num_bgc_soilc, filter_bgc_soilc,
p_decomp_cpool_loss(c,j,k) = p_decomp_cpool_loss(c,j,k) * fpi_vr(c,j)
pmnf_decomp_cascade(c,j,k) = pmnf_decomp_cascade(c,j,k) * fpi_vr(c,j)
if (use_soil_matrixcn)then ! correct only when one transfer from each litter pool
+ Ksoil%DM(c,j+nlevdecomp*(cascade_donor_pool(k)-1)) = &
+ Ksoil%DM(c,j+nlevdecomp*(cascade_donor_pool(k)-1)) * fpi_vr(c,j)
end if
if (.not. use_nitrif_denitrif) then
sminn_to_denit_decomp_cascade_vr(c,j,k) = 0._r8
diff --git a/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90 b/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
index e58e2f22d6..889fda5bdb 100644
--- a/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemLittVertTranspMod.F90
@@ -149,9 +149,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
real(r8) :: epsilon ! small number
real(r8), pointer :: conc_ptr(:,:,:) ! pointer, concentration state variable being transported
real(r8), pointer :: source(:,:,:) ! pointer, source term
- real(r8), pointer :: trcr_tendency_ptr(:,:,:) ! pointer, store the vertical tendency (gain/loss due to vertical transport)
- ! Pointer for matrix
-
+ real(r8), pointer :: trcr_tendency_ptr(:,:,:) ! poiner, store the vertical tendency (gain/loss due to vertical transport)
+ real(r8), pointer :: matrix_input(:,:) ! poiner, store the vertical tendency (gain/loss due to vertical transport)
!-----------------------------------------------------------------------
! Set statement functions
@@ -165,7 +164,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
altmax_lastyear => active_layer_inst%altmax_lastyear_col , & ! Input: [real(r8) (:) ] prior year maximum annual depth of thaw
som_adv_coef => soilbiogeochem_state_inst%som_adv_coef_col , & ! Output: [real(r8) (:,:) ] SOM advective flux (m/s)
- som_diffus_coef => soilbiogeochem_state_inst%som_diffus_coef_col & ! Output: [real(r8) (:,:) ] SOM diffusivity due to bio/cryo-turbation (m2/s)
+ som_diffus_coef => soilbiogeochem_state_inst%som_diffus_coef_col,& ! Output: [real(r8) (:,:) ] SOM diffusivity due to bio/cryo-turbation (m2/s)
+ tri_ma_vr => soilbiogeochem_carbonflux_inst%tri_ma_vr & ! Output: [real(r8) (:,:) ] Vertical CN transfer rate in sparse matrix format (gC*m3)/(gC*m3*step))
)
!Set parameters of vertical mixing of SOM
@@ -237,16 +237,17 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
!------ loop over litter/som types
do i_type = 1, ntype
- ! For matrix solution figure out which matrix data to point to
select case (i_type)
case (1) ! C
conc_ptr => soilbiogeochem_carbonstate_inst%decomp_cpools_vr_col
source => soilbiogeochem_carbonflux_inst%decomp_cpools_sourcesink_col
trcr_tendency_ptr => soilbiogeochem_carbonflux_inst%decomp_cpools_transport_tendency_col
+ matrix_input => soilbiogeochem_carbonflux_inst%matrix_Cinput%V
case (2) ! N
conc_ptr => soilbiogeochem_nitrogenstate_inst%decomp_npools_vr_col
source => soilbiogeochem_nitrogenflux_inst%decomp_npools_sourcesink_col
trcr_tendency_ptr => soilbiogeochem_nitrogenflux_inst%decomp_npools_transport_tendency_col
+ matrix_input => soilbiogeochem_nitrogenflux_inst%matrix_Ninput%V
case (3)
if ( use_c13 ) then
! C13
@@ -399,6 +400,8 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
r_tri(c,j) = source(c,j,s) * dzsoi_decomp(j) /dtime + (a_p_0 - adv_flux(c,j)) * conc_trcr(c,j)
if(s .eq. 1 .and. i_type .eq. 1 .and. use_soil_matrixcn )then !vertical matrix are the same for all pools
do i = 1,ndecomp_pools-1 !excluding cwd
+ tri_ma_vr(c,1+(i-1)*(nlevdecomp*3-2)) = (b_tri(c,j) - a_p_0) / dzsoi_decomp(j) * (-dtime)
+ tri_ma_vr(c,3+(i-1)*(nlevdecomp*3-2)) = c_tri(c,j) / dzsoi_decomp(j) * (-dtime)
end do
end if
elseif (j < nlevdecomp+1) then
@@ -409,12 +412,17 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
if(s .eq. 1 .and. i_type .eq. 1 .and. use_soil_matrixcn )then
if(j .le. col%nbedrock(c))then
do i = 1,ndecomp_pools-1
+ tri_ma_vr(c,j*3-4+(i-1)*(nlevdecomp*3-2)) = a_tri(c,j) / dzsoi_decomp(j) * (-dtime)
if(j .ne. nlevdecomp)then
+ tri_ma_vr(c,j*3 +(i-1)*(nlevdecomp*3-2)) = c_tri(c,j) / dzsoi_decomp(j) * (-dtime)
end if
+ tri_ma_vr(c,j*3-2+(i-1)*(nlevdecomp*3-2)) = (b_tri(c,j) - a_p_0) / dzsoi_decomp(j) * (-dtime)
end do
else
if(j .eq. col%nbedrock(c) + 1 .and. j .ne. nlevdecomp .and. j .gt. 1)then
do i = 1,ndecomp_pools-1
+ tri_ma_vr(c,(j-1)*3-2+(i-1)*(nlevdecomp*3-2)) = tri_ma_vr(c,(j-1)*3-2+(i-1)*(nlevdecomp*3-2)) &
+ + a_tri(c,j) / dzsoi_decomp(j-1)*(-dtime)
end do
end if
end if
@@ -463,11 +471,11 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
trcr_tendency_ptr(c,j,s) = trcr_tendency_ptr(c,j,s) / dtime
end do
end do
- else
- ! For matrix solution set the matrix input array
+ else ! For matrix solution set the matrix input array
do j = 1,nlevdecomp
do fc =1,num_bgc_soilc
c = filter_bgc_soilc(fc)
+ matrix_input(c,j+(s-1)*nlevdecomp) = matrix_input(c,j+(s-1)*nlevdecomp) + source(c,j,s)
end do
end do
end if !soil_matrix
@@ -479,7 +487,7 @@ subroutine SoilBiogeochemLittVertTransp(bounds, num_bgc_soilc, filter_bgc_soilc,
if(.not. use_soil_matrixcn)then
conc_trcr(c,j) = conc_ptr(c,j,s) + source(c,j,s)
else
- ! For matrix solution set the matrix input array
+ matrix_input(c,j+(s-1)*nlevdecomp) = matrix_input(c,j+(s-1)*nlevdecomp) + source(c,j,s)
end if
if (j > col%nbedrock(c) .and. source(c,j,s) > 0._r8) then
write(iulog,*) 'source >0',c,j,s,source(c,j,s)
diff --git a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90 b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
index 4b70459aca..8655b6c72d 100644
--- a/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNStateUpdate1Mod.F90
@@ -9,11 +9,12 @@ module SoilBiogeochemNStateUpdate1Mod
use clm_time_manager , only : get_step_size_real
use clm_varpar , only : nlevdecomp, ndecomp_cascade_transitions
use clm_varctl , only : iulog, use_nitrif_denitrif, use_crop
+ use SoilBiogeochemDecompCascadeConType , only : use_soil_matrixcn
use clm_varcon , only : nitrif_n2o_loss_frac
use SoilBiogeochemStateType , only : soilbiogeochem_state_type
use SoilBiogeochemNitrogenStateType , only : soilbiogeochem_nitrogenstate_type
use SoilBiogeochemNitrogenfluxType , only : soilbiogeochem_nitrogenflux_type
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
use CNSharedParamsMod , only : use_fun
use ColumnType , only : col
!
@@ -118,49 +119,48 @@ subroutine SoilBiogeochemNStateUpdate1(num_bgc_soilc, filter_bgc_soilc, &
end if
! decomposition fluxes
- if (.not. use_soil_matrixcn) then
- do k = 1, ndecomp_cascade_transitions
+ ! TODO slevis: improve indentation
+ if (.not. use_soil_matrixcn) then
+ do k = 1, ndecomp_cascade_transitions
+ do j = 1, nlevdecomp
+ ! column loop
+ do fc = 1,num_bgc_soilc
+ c = filter_bgc_soilc(fc)
+
+ nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
+ nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
+ nf%decomp_cascade_ntransfer_vr_col(c,j,k) * dt
+ end do
+ end do
+ end do
+
+
+ do k = 1, ndecomp_cascade_transitions
+ if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
do j = 1, nlevdecomp
! column loop
do fc = 1,num_bgc_soilc
c = filter_bgc_soilc(fc)
+ nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
+ nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) + &
+ (nf%decomp_cascade_ntransfer_vr_col(c,j,k) + &
+ nf%decomp_cascade_sminn_flux_vr_col(c,j,k)) * dt
+ end do
+ end do
+ else ! terminal transitions
+ do j = 1, nlevdecomp
+ ! column loop
+ do fc = 1,num_bgc_soilc
+ c = filter_bgc_soilc(fc)
nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
- nf%decomp_cascade_ntransfer_vr_col(c,j,k) * dt
+ nf%decomp_cascade_sminn_flux_vr_col(c,j,k) * dt
end do
end do
- end do
-
-
- do k = 1, ndecomp_cascade_transitions
- if ( cascade_receiver_pool(k) /= 0 ) then ! skip terminal transitions
- do j = 1, nlevdecomp
- ! column loop
- do fc = 1,num_bgc_soilc
- c = filter_bgc_soilc(fc)
-
- nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) = &
- nf%decomp_npools_sourcesink_col(c,j,cascade_receiver_pool(k)) + &
- (nf%decomp_cascade_ntransfer_vr_col(c,j,k) + &
- nf%decomp_cascade_sminn_flux_vr_col(c,j,k)) * dt
- end do
- end do
- else ! terminal transitions
- do j = 1, nlevdecomp
- ! column loop
- do fc = 1,num_bgc_soilc
- c = filter_bgc_soilc(fc)
- nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) = &
- nf%decomp_npools_sourcesink_col(c,j,cascade_donor_pool(k)) - &
- nf%decomp_cascade_sminn_flux_vr_col(c,j,k) * dt
- end do
- end do
- end if
- end do
- else
- ! Matrix solution equvalent to above is in CNSoilMatrixMod.F90? (TODO check on this)
- end if !
+ end if
+ end do
+ end if !
if (.not. use_nitrif_denitrif) then
diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
index 90213b8123..94d5b4324f 100644
--- a/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNitrogenFluxType.F90
@@ -3,8 +3,8 @@ module SoilBiogeochemNitrogenFluxType
use shr_kind_mod , only : r8 => shr_kind_r8
use shr_infnan_mod , only : nan => shr_infnan_nan, assignment(=)
use shr_log_mod , only : errMsg => shr_log_errMsg
- use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools
- use clm_varpar , only : nlevdecomp_full, nlevdecomp
+ use clm_varpar , only : ndecomp_cascade_transitions, ndecomp_pools, ndecomp_cascade_outtransitions
+ use clm_varpar , only : nlevdecomp_full, nlevdecomp, ndecomp_pools_vr
use clm_varcon , only : spval, ispval, dzsoi_decomp
use decompMod , only : bounds_type
use clm_varctl , only : use_nitrif_denitrif, use_crop, use_fates
@@ -12,7 +12,7 @@ module SoilBiogeochemNitrogenFluxType
use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
use abortutils , only : endrun
use LandunitType , only : lun
- use ColumnType , only : col
+ use ColumnType , only : col
use SparseMatrixMultiplyMod , only : sparse_matrix_type, diag_matrix_type, vector_type
!
! !PUBLIC TYPES:
@@ -132,7 +132,16 @@ module SoilBiogeochemNitrogenFluxType
! flux passed in from FATES.
! This is a diagnostic for balance checks only
! track tradiagonal matrix
-
+ type(sparse_matrix_type) :: AKsoiln ! A*K for N transfers between pools
+ type(sparse_matrix_type) :: AKallsoiln ! (A*K+V-Kfire) for soil N cycle
+ integer :: NE_AKallsoiln ! Number of non-zero entries in AKallsoiln. Automatically generated by functions SPMP_*
+ integer,pointer,dimension(:) :: RI_AKallsoiln ! Row numbers of entries in AKallsoiln. Automatically generated by functions in SPMP_*
+ integer,pointer,dimension(:) :: CI_AKallsoiln ! Column numbers of entries in AKallsoiln, Automatically generated by functions in SPMP_*
+ integer,pointer,dimension(:) :: RI_na ! Row numbers of all entries from AKsoiln. Automatically generated by SetValueA
+ integer,pointer,dimension(:) :: CI_na ! Column numbers of all entries from AKsoiln. Automatically generated by SetValueA
+ type(diag_matrix_type) :: Ksoiln ! N turnover rate in different soil pools and layers
+ type(vector_type) :: matrix_Ninput ! N input to different soil compartments (pools and layers) (gN/m3/step)
+
contains
procedure , public :: Init
@@ -173,7 +182,7 @@ subroutine InitAllocate(this, bounds)
type(bounds_type) , intent(in) :: bounds
!
! !LOCAL VARIABLES:
- integer :: begc,endc ! column begin and end indices
+ integer :: begc,endc,Ntrans,Ntrans_diag
!------------------------------------------------------------------------
begc = bounds%begc; endc = bounds%endc
@@ -282,8 +291,20 @@ subroutine InitAllocate(this, bounds)
allocate(this%fates_litter_flux(0:0)); this%fates_litter_flux(:) = nan
end if
- ! Allocate soil Matrix setug
+ ! Allocate soil Matrix setup
if(use_soil_matrixcn)then
+
+ Ntrans = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp
+ call this%AKsoiln%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+ndecomp_pools*nlevdecomp)
+ call this%AKallsoiln%InitSM (ndecomp_pools*nlevdecomp,begc,endc,Ntrans+decomp_cascade_con%Ntri_setup+nlevdecomp)
+ this%NE_AKallsoiln = (Ntrans+nlevdecomp*ndecomp_pools) + (Ntrans+decomp_cascade_con%Ntri_setup + nlevdecomp) + (ndecomp_pools*nlevdecomp)
+ allocate(this%RI_AKallsoiln(1:this%NE_AKallsoiln)); this%RI_AKallsoiln(1:this%NE_AKallsoiln)=-9999
+ allocate(this%CI_AKallsoiln(1:this%NE_AKallsoiln)); this%CI_AKallsoiln(1:this%NE_AKallsoiln)=-9999
+ Ntrans_diag = (ndecomp_cascade_transitions-ndecomp_cascade_outtransitions)*nlevdecomp+ndecomp_pools_vr
+ allocate(this%RI_na(1:Ntrans_diag)); this%RI_na(1:Ntrans_diag) = -9999
+ allocate(this%CI_na(1:Ntrans_diag)); this%CI_na(1:Ntrans_diag) = -9999
+ call this%Ksoiln%InitDM (ndecomp_pools*nlevdecomp,begc,endc)
+ call this%matrix_Ninput%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
end subroutine InitAllocate
@@ -1005,8 +1026,9 @@ subroutine SetValues ( this, &
this%decomp_npools_leached_col(i,k) = value_column
end do
end do
-
+
if(use_soil_matrixcn)then
+ call this%matrix_Ninput%SetValueV_scaler(num_column,filter_column(1:num_column),value_column)
end if
do k = 1, ndecomp_pools
diff --git a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90 b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
index ee889503d0..d3042b02e8 100644
--- a/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
+++ b/src/soilbiogeochem/SoilBiogeochemNitrogenStateType.F90
@@ -12,10 +12,10 @@ module SoilBiogeochemNitrogenStateType
use clm_varpar , only : nlevdecomp_full, nlevdecomp, nlevsoi
use clm_varcon , only : spval, dzsoi_decomp, zisoi
use clm_varctl , only : use_nitrif_denitrif, use_fates_bgc
- use SoilBiogeochemDecompCascadeConType , only : mimics_decomp, century_decomp, decomp_method, use_soil_matrixcn
use clm_varctl , only : iulog, override_bgc_restart_mismatch_dump, spinup_state
use landunit_varcon , only : istcrop, istsoil
- use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con
+ use SoilBiogeochemDecompCascadeConType , only : decomp_cascade_con, use_soil_matrixcn
+ use SoilBiogeochemDecompCascadeConType , only : mimics_decomp, century_decomp, decomp_method
use LandunitType , only : lun
use ColumnType , only : col
use GridcellType , only : grc
@@ -30,6 +30,8 @@ module SoilBiogeochemNitrogenStateType
type, public :: soilbiogeochem_nitrogenstate_type
real(r8), pointer :: decomp_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
+ real(r8), pointer :: decomp0_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved N baseline (initial value of this year) in decomposing (litter, cwd, soil) pools in dimension (col,nlev,npools)
+ real(r8), pointer :: decomp_npools_vr_SASUsave_col(:,:,:) ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools
real(r8), pointer :: decomp_soiln_vr_col (:,:) ! col (gN/m3) vertically-resolved decomposing total soil N pool
@@ -66,6 +68,17 @@ module SoilBiogeochemNitrogenStateType
real(r8), pointer :: totn_grc (:) ! (gN/m2) total gridcell nitrogen
! Matrix-cn
+ real(r8), pointer :: matrix_cap_decomp_npools_col (:,:) ! col (gN/m2) N capacity in decomposing (litter, cwd, soil) N pools in dimension (col,npools)
+ real(r8), pointer :: matrix_cap_decomp_npools_vr_col (:,:,:) ! col (gN/m3) vertically-resolved N capacity in decomposing (litter, cwd, soil) pools in dimension(col,nlev,npools)
+ real(r8), pointer :: in_nacc (:,:) ! col (gN/m3/yr) accumulated litter fall N input per year in dimension(col,nlev*npools)
+ real(r8), pointer :: in_nacc_2d (:,:,:) ! col (gN/m3/yr) accumulated litter fall N input per year in dimension(col,nlev,npools)
+ real(r8), pointer :: tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools)
+ real(r8), pointer :: vert_up_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated upward vertical N transport in dimension(col,nlev,npools)
+ real(r8), pointer :: vert_down_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated downward vertical N transport in dimension(col,nlev,npools)
+ real(r8), pointer :: exit_nacc (:,:,:) ! col (gN/m3/yr) accumulated exit N in dimension(col,nlev,npools)
+ real(r8), pointer :: hori_tran_nacc (:,:,:) ! col (gN/m3/yr) accumulated N transport between pools at the same level in dimension(col,nlev,ntransfers)
+ type(sparse_matrix_type) :: AKXnacc ! col (gN/m3/yr) accumulated N transfers from j to i (col,i,j) per year in dimension(col,nlev*npools,nlev*npools) in sparse matrix type
+ type(vector_type) :: matrix_Ninter ! col (gN/m3) vertically-resolved decomposing (litter, cwd, soil) N pools in dimension(col,nlev*npools) in vector type
contains
@@ -140,11 +153,36 @@ subroutine InitAllocate(this, bounds)
allocate(this%decomp_npools_col (begc:endc,1:ndecomp_pools)) ; this%decomp_npools_col (:,:) = nan
allocate(this%decomp_npools_1m_col (begc:endc,1:ndecomp_pools)) ; this%decomp_npools_1m_col (:,:) = nan
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_npools_col (begc:endc,1:ndecomp_pools)) ; this%matrix_cap_decomp_npools_col (:,:) = nan
end if
allocate(this%decomp_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
this%decomp_npools_vr_col(:,:,:)= nan
if(use_soil_matrixcn)then
+ allocate(this%matrix_cap_decomp_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%matrix_cap_decomp_npools_vr_col(:,:,:)= nan
+! for matrix-spinup
+ allocate(this%decomp0_npools_vr_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%decomp0_npools_vr_col(:,:,:)= nan
+ allocate(this%decomp_npools_vr_SASUsave_col(begc:endc,1:nlevdecomp_full,1:ndecomp_pools));
+ this%decomp_npools_vr_SASUsave_col(:,:,:)= nan
+ allocate(this%in_nacc(begc:endc,1:nlevdecomp*ndecomp_pools))
+ this%in_nacc(:,:)= nan
+ allocate(this%tran_nacc(begc:endc,1:nlevdecomp*ndecomp_pools,1:nlevdecomp*ndecomp_pools))
+ this%tran_nacc(:,:,:)= nan
+
+ allocate(this%in_nacc_2d(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%in_nacc_2d(:,:,:)= nan
+ allocate(this%vert_up_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_up_tran_nacc(:,:,:)= nan
+ allocate(this%vert_down_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%vert_down_tran_nacc(:,:,:)= nan
+ allocate(this%exit_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_pools))
+ this%exit_nacc(:,:,:)= nan
+ allocate(this%hori_tran_nacc(begc:endc,1:nlevdecomp_full,1:ndecomp_cascade_transitions))
+ this%hori_tran_nacc(:,:,:)= nan
+ call this%AKXnacc%InitSM(ndecomp_pools*nlevdecomp,begc,endc,decomp_cascade_con%n_all_entries)
+ call this%matrix_Ninter%InitV (ndecomp_pools*nlevdecomp,begc,endc)
end if
allocate(this%decomp_soiln_vr_col(begc:endc,1:nlevdecomp_full))
this%decomp_soiln_vr_col(:,:)= nan
@@ -195,10 +233,12 @@ subroutine InitHistory(this, bounds)
this%decomp_npools_vr_col(begc:endc,:,:) = spval
this%decomp_npools_1m_col(begc:endc,:) = spval
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(begc:endc,:,:) = spval
end if
end if
this%decomp_npools_col(begc:endc,:) = spval
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(begc:endc,:) = spval
end if
do l = 1, ndecomp_pools
if ( nlevdecomp_full > 1 ) then
@@ -209,6 +249,12 @@ subroutine InitHistory(this, bounds)
avgflag='A', long_name=longname, &
ptr_col=data2dptr)
if(use_soil_matrixcn)then
+ data2dptr => this%matrix_cap_decomp_npools_vr_col(:,:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'N_Cap_vr'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' N capacity (vertically resolved)'
+ call hist_addfld2d (fname=fieldname, units='gN/m^3', type2d='levdcmp', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data2dptr)
end if
endif
@@ -220,6 +266,12 @@ subroutine InitHistory(this, bounds)
ptr_col=data1dptr)
if(nlevdecomp_full .eq. 1)then
if(use_soil_matrixcn)then
+ data1dptr => this%matrix_cap_decomp_npools_col(:,l)
+ fieldname = trim(decomp_cascade_con%decomp_pool_name_history(l))//'N_Cap'
+ longname = trim(decomp_cascade_con%decomp_pool_name_history(l))//' N capacity'
+ call hist_addfld1d (fname=fieldname, units='gN/m^2', &
+ avgflag='I', long_name=longname, &
+ ptr_col=data1dptr)
end if
end if
@@ -382,6 +434,7 @@ subroutine InitCold(this, bounds, &
l = col%landunit(c)
! matrix-spinup
if(use_soil_matrixcn)then
+ this%in_nacc(c,:) = 0._r8
end if
if (lun%itype(l) == istsoil .or. lun%itype(l) == istcrop) then
@@ -393,9 +446,19 @@ subroutine InitCold(this, bounds, &
do k = 1, ndecomp_pools
this%decomp_npools_vr_col(c,j,k) = decomp_cpools_vr_col(c,j,k) / decomp_cascade_con%initial_cn_ratio(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(c,j,k) = decomp_cpools_vr_col(c,j,k) / decomp_cascade_con%initial_cn_ratio(k)
+ this%in_nacc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_nacc(c,j,k) = 0._r8
+ this%vert_down_tran_nacc(c,j,k) = 0._r8
+ this%exit_nacc(c,j,k) = 0._r8
+ this%decomp0_npools_vr_col(c,j,k) = max(this%decomp_npools_vr_col(c,j,k),1.e-30_r8)
+ this%decomp_npools_vr_SASUsave_col(c,j,k) = 0._r8
end if
end do
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_nacc(c,j,k) = 0._r8
+ end do
end if
this%sminn_vr_col(c,j) = 0._r8
@@ -403,6 +466,9 @@ subroutine InitCold(this, bounds, &
end do
if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ this%AKXnacc%M(c,j) = 0._r8
+ end do
end if
if ( nlevdecomp > 1 ) then
@@ -410,9 +476,18 @@ subroutine InitCold(this, bounds, &
do k = 1, ndecomp_pools
this%decomp_npools_vr_col(c,j,k) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(c,j,k) = 0._r8
+ this%in_nacc_2d(c,j,k) = 0._r8
+ this%vert_up_tran_nacc(c,j,k) = 0._r8
+ this%vert_down_tran_nacc(c,j,k) = 0._r8
+ this%exit_nacc(c,j,k) = 0._r8
+ this%decomp0_npools_vr_col(c,j,k) = this%decomp_npools_vr_col(c,j,k)
end if
end do
if(use_soil_matrixcn)then
+ do k = 1, ndecomp_cascade_transitions
+ this%hori_tran_nacc(c,j,k) = 0._r8
+ end do
end if
this%sminn_vr_col(c,j) = 0._r8
this%ntrunc_vr_col(c,j) = 0._r8
@@ -422,6 +497,7 @@ subroutine InitCold(this, bounds, &
this%decomp_npools_col(c,k) = decomp_cpools_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
this%decomp_npools_1m_col(c,k) = decomp_cpools_1m_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,k) = decomp_cpools_col(c,k) / decomp_cascade_con%initial_cn_ratio(k)
end if
end do
@@ -539,12 +615,128 @@ subroutine Restart ( this, bounds, ncid, flag, totvegc_col )
errMsg(sourcefile, __LINE__))
end if
end do
- if(flag=='write')then
- if(use_soil_matrixcn)then
+ if(use_soil_matrixcn)then
+ if(flag=='write')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_nacc_2d(:,j,i) = this%in_nacc(:,j+(i-1)*nlevdecomp)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%vert_up_tran_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%vert_down_tran_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%exit_nacc(:,i_lev,i_decomp) = this%AKXnacc%M(:,i)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%hori_tran_nacc(:,i_lev,k) = this%AKXnacc%M(:,i)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i,i_decomp,j_decomp,i_lev,j_lev
+ end do
end if
+
+ do k = 1, ndecomp_pools
+ varname=trim(decomp_cascade_con%decomp_pool_name_restart(k))//'n'
+ ptr2d => this%matrix_cap_decomp_npools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_Cap_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., scale_by_thickness=.false., &
+ long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%decomp0_npools_vr_col(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"0_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., scale_by_thickness=.false., &
+ long_name='', units='', &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%in_nacc_2d(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_input_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_up_tran_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_up_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%vert_down_tran_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_vert_down_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ ptr2d => this%exit_nacc(:,:,k)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_exit_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
+
+ do i = 1, ndecomp_cascade_transitions
+ varname=trim(decomp_cascade_con%cascade_step_name(i))//'n'
+ ptr2d => this%hori_tran_nacc(:,:,i)
+ call restartvar(ncid=ncid, flag=flag, varname=trim(varname)//"_hori_tran_nacc_vr", xtype=ncd_double, &
+ dim1name='column', dim2name='levgrnd', switchdim=.true., &
+ long_name='', units='', scale_by_thickness=.false., &
+ interpinic_flag='interp', readvar=readvar, data=ptr2d)
+ end do
end if
+
if(use_soil_matrixcn)then
if(flag=='read')then
+ do i = 1,ndecomp_pools
+ do j = 1,nlevdecomp
+ this%in_nacc(:,j+(i-1)*nlevdecomp) = this%in_nacc_2d(:,j,i)
+ end do
+ end do
+ do i = 1,decomp_cascade_con%n_all_entries
+ found = .false.
+ j_lev = mod(decomp_cascade_con%all_j(i) - 1,nlevdecomp) + 1
+ j_decomp = (decomp_cascade_con%all_j(i) - j_lev)/nlevdecomp + 1
+ i_lev = mod(decomp_cascade_con%all_i(i) - 1,nlevdecomp) + 1
+ i_decomp = (decomp_cascade_con%all_i(i) - i_lev)/nlevdecomp + 1
+ if(i_decomp .eq. j_decomp .and. j_lev - i_lev .eq. 1)then
+ this%AKXnacc%M(:,i) = this%vert_up_tran_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev - j_lev .eq. 1)then
+ this%AKXnacc%M(:,i) = this%vert_down_tran_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ if(i_decomp .eq. j_decomp .and. i_lev .eq. j_lev)then
+ this%AKXnacc%M(:,i) = this%exit_nacc(:,i_lev,i_decomp)
+ found = .true.
+ else
+ do k=1,ndecomp_cascade_transitions
+ if(i_decomp .ne. j_decomp .and. i_lev .eq. j_lev .and. &
+ i_decomp .eq. decomp_cascade_con%cascade_receiver_pool(k) .and. &
+ j_decomp .eq. decomp_cascade_con%cascade_donor_pool(k) .and. .not. found)then
+ this%AKXnacc%M(:,i) = this%hori_tran_nacc(:,i_lev,k)
+ found = .true.
+ end if
+ end do
+ end if
+ end if
+ end if
+ if(.not. found) write(iulog,*) 'Error in storing matrix restart variables',i
+ end do
end if
end if
@@ -775,6 +967,7 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
this%decomp_npools_col(i,k) = value_column
this%decomp_npools_1m_col(i,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(i,k) = value_column
end if
end do
end do
@@ -786,6 +979,8 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
i = filter_column(fi)
this%decomp_npools_vr_col(i,j,k) = value_column
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_vr_col(i,j,k) = value_column
+ this%decomp0_npools_vr_col(i,j,k) = value_column
end if
end do
end do
@@ -799,6 +994,32 @@ subroutine SetValues ( this, num_column, filter_column, value_column )
! Set values for the matrix solution
if(use_soil_matrixcn)then
+ do j = 1,nlevdecomp
+ do k = 1, ndecomp_pools
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%in_nacc_2d(i,j,k) = value_column
+ this%vert_up_tran_nacc(i,j,k) = value_column
+ this%vert_down_tran_nacc(i,j,k) = value_column
+ this%exit_nacc(i,j,k) = value_column
+ end do
+ end do
+ do k = 1, ndecomp_cascade_transitions
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%hori_tran_nacc(i,j,k) = value_column
+ end do
+ end do
+ end do
+ end if
+
+ if(use_soil_matrixcn)then
+ do j = 1,decomp_cascade_con%n_all_entries
+ do fi = 1, num_column
+ i = filter_column(fi)
+ this%AKXnacc%M(i,j) = value_column
+ end do
+ end do
end if
end subroutine SetValues
@@ -857,6 +1078,7 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
c = filter_allc(fc)
this%decomp_npools_col(c,l) = 0._r8
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,l) = 0._r8
end if
end do
do j = 1, nlevdecomp
@@ -866,6 +1088,9 @@ subroutine Summary(this, bounds, num_allc, filter_allc, num_bgc_soilc, filter_bg
this%decomp_npools_col(c,l) + &
this%decomp_npools_vr_col(c,j,l) * dzsoi_decomp(j)
if(use_soil_matrixcn)then
+ this%matrix_cap_decomp_npools_col(c,l) = &
+ this%matrix_cap_decomp_npools_col(c,l) + &
+ this%matrix_cap_decomp_npools_vr_col(c,j,l) * dzsoi_decomp(j)
end if
end do
end do
diff --git a/src/unit_test_shr/CMakeLists.txt b/src/unit_test_shr/CMakeLists.txt
index 9bf95c728f..f6a204bd72 100644
--- a/src/unit_test_shr/CMakeLists.txt
+++ b/src/unit_test_shr/CMakeLists.txt
@@ -9,6 +9,7 @@ sourcelist_to_parent(clm_genf90_sources)
list(APPEND clm_sources "${clm_genf90_sources}")
list(APPEND clm_sources
+ unittestDustEmisInputs.F90
unittestFilterBuilderMod.F90
unittestGlcMec.F90
unittestSimpleSubgridSetupsMod.F90
diff --git a/src/unit_test_shr/unittestDustEmisInputs.F90 b/src/unit_test_shr/unittestDustEmisInputs.F90
new file mode 100644
index 0000000000..6b15680ef7
--- /dev/null
+++ b/src/unit_test_shr/unittestDustEmisInputs.F90
@@ -0,0 +1,251 @@
+module unittestDustEmisInputs
+
+ ! unit testing dust emission inputs
+
+ use unittestSubgridMod, only : bounds, unittest_subgrid_teardown
+ use unittestSimpleSubgridSetupsMod, only : setup_single_veg_patch
+ use clm_varpar, only : nlevsoi, nlevgrnd, clm_varpar_init
+ use clm_varctl, only : soil_layerstruct_predefined, create_crop_landunit, use_crop, create_crop_landunit
+ use shr_kind_mod , only : r8 => shr_kind_r8
+ use unittestFilterBuilderMod, only : filter_from_range
+ use atm2lndType, only : atm2lnd_type, atm2lnd_params_type
+ use SoilStateType, only : soilstate_type
+ use CanopyStateType, only : canopystate_type
+ use TemperatureType, only : temperature_type
+ use WaterType, only : water_type
+ use FrictionVelocityMod, only : frictionvel_type
+ use unittestWaterTypeFactory, only : unittest_water_type_factory_type
+ use SoilStateInitTimeConstMod, only : ThresholdSoilMoistZender2003, MassFracClay
+
+ implicit none
+ private
+
+ type, public :: unittest_dust_emis_input_type
+ integer, allocatable :: filter_nolakep(:) ! non-lake filter (patches)
+ integer :: num_nolakep ! number of patches in non-lake filter
+ type(atm2lnd_type) :: atm2lnd_inst
+ type(soilstate_type) :: soilstate_inst
+ type(canopystate_type) :: canopystate_inst
+ type(temperature_type), private :: temperature_inst
+ type(unittest_water_type_factory_type), private :: water_factory
+ type(water_type) :: water_inst
+ type(frictionvel_type) :: frictionvel_inst
+ contains
+ procedure, public :: setUp
+ procedure, public :: tearDown
+ procedure, private:: setupSoilState
+ procedure, public :: create_atm2lnd
+ procedure, public :: create_fv
+ procedure, public :: print_values
+ end type unittest_dust_emis_input_type
+
+contains
+
+ !-----------------------------------------------------------------------
+
+ subroutine setUp(this)
+ use ColumnType, only : col
+ class(unittest_dust_emis_input_type), intent(inout) :: this
+ ! Allocate and initiatlize the test object for input objects dust-emission needs
+
+ character(len=5) :: NLFilename = 'none'
+ real(r8), allocatable :: urb_em(:)
+ integer :: begl, endl, begc, endc
+ integer :: c
+ type(atm2lnd_params_type) :: atm2lnd_params
+ integer, parameter :: snl = 3
+
+ ! Settings needed for clm_varpar
+ soil_layerstruct_predefined = '20SL_8.5m'
+ create_crop_landunit = .true.
+ use_crop = .false.
+ call clm_varpar_init( actual_maxsoil_patches=17, surf_numpft=15, surf_numcft=2, actual_nlevurb=5 )
+ ! Water object initialization -- before subgrid
+ call this%water_factory%init()
+ call this%water_factory%setup_before_subgrid( &
+ my_nlevsoi = nlevsoi, &
+ nlevgrnd_additional = nlevgrnd - nlevsoi, &
+ my_nlevsno = snl)
+ ! Setup the subgrid structure for a single bare-soil patch
+ call setup_single_veg_patch( pft_type=0 )
+ begl = bounds%begl
+ endl = bounds%endl
+ begc = bounds%begc
+ endc = bounds%endc
+
+ ! Create the nolake filter
+ call filter_from_range(start=bounds%begp, end=bounds%endp, numf=this%num_nolakep, filter=this%filter_nolakep)
+ ! atmosphere to land parameter object
+ atm2lnd_params = atm2lnd_params_type( repartition_rain_snow = .false., &
+ glcmec_downscale_longwave = .false., &
+ lapse_rate = 0.01_r8 & ! arbitrary (this is unused for these tests)
+ )
+ call this%atm2lnd_inst%InitForTesting(bounds, atm2lnd_params)
+ ! Water and soil state -- after the subgrid setup
+ call this%water_factory%setup_after_subgrid(snl = snl)
+ call this%setupSoilState( ) ! This needs to happen before the water_type object creation
+ call this%water_factory%create_water_type(this%water_inst, watsat_col=this%soilstate_inst%watsat_col)
+ ! Canopy state, friction velocity, and temperature state ojects
+ call this%canopystate_inst%SetNMLForTesting()
+ call this%canopystate_inst%Init(bounds)
+ call this%frictionvel_inst%InitForTesting(bounds)
+ allocate( urb_em(begl:endl) )
+ urb_em(begl:endl) = 0.99_r8 ! Arbitrary won't matter here
+ call this%temperature_inst%Init(bounds, &
+ em_roof_lun=urb_em(begl:endl), &
+ em_wall_lun=urb_em(begl:endl), &
+ em_improad_lun=urb_em(begl:endl), &
+ em_perroad_lun=urb_em(begl:endl), &
+ is_simple_buildtemp=.true., is_prog_buildtemp=.false.)
+ deallocate( urb_em )
+ end subroutine setUp
+
+ !-----------------------------------------------------------------------
+
+ subroutine tearDown(this)
+ class(unittest_dust_emis_input_type), intent(inout) :: this
+
+ call this%water_factory%teardown(this%water_inst)
+ call unittest_subgrid_teardown()
+ call this%atm2lnd_inst%Clean()
+ deallocate( this%filter_nolakep )
+ end subroutine tearDown
+
+ !-----------------------------------------------------------------------
+
+ subroutine setupSoilState(this)
+ !
+ ! !DESCRIPTION:
+ ! Sets up the external environment used by Dust emissions - i.e., things accessed via
+ ! 'use' statements.
+ !
+ ! Assumes nlevgrnd and nlevsoi have been set, and that all necessary subgrid setup has
+ ! been completed.
+ !
+ use ColumnType, only : col
+ use GridcellType, only : grc
+ class(unittest_dust_emis_input_type), intent(in) :: this
+ !
+ integer :: c,j
+ real(r8), parameter :: clay = 10.0_r8
+
+ !-----------------------------------------------------------------------
+ ! Setting the soil structrure is needed for water_state types
+ col%dz(:,1:nlevgrnd) = 1.0_r8
+ do j = 1, nlevgrnd
+ do c = bounds%begc, bounds%endc
+ col%z(c,j) = sum(col%dz(c,1:j-1)) + 0.5_r8*col%dz(c,j)
+ end do
+ end do
+
+ call this%soilstate_inst%Init(bounds)
+ do c = bounds%begc, bounds%endc
+ this%soilstate_inst%watsat_col(c,:) = 0.05_r8 * (c - bounds%begc + 1)
+ end do
+ ! These are needed for dust emissions initialization
+ do c = bounds%begc, bounds%endc
+ this%soilstate_inst%gwc_thr_col(c) = ThresholdSoilMoistZender2003( clay )
+ this%soilstate_inst%mss_frc_cly_vld_col(c) = MassFracClay( clay )
+ end do
+
+ end subroutine setupSoilState
+
+ !-----------------------------------------------------------------------
+
+ subroutine create_atm2lnd(this, forc_t, forc_pbot, forc_rho )
+ ! Initializes some fields needed for dust emissions in this%atm2lnd_inst, and sets
+ ! forcing fields based on inputs. Excluded inputs are given a default value
+ class(unittest_dust_emis_input_type), intent(inout) :: this
+ real(r8), intent(in), optional :: forc_t(:)
+ real(r8), intent(in), optional :: forc_pbot(:)
+ real(r8), intent(in), optional :: forc_rho(:)
+
+ real(r8), parameter :: forc_t_default = 301._r8
+ real(r8), parameter :: forc_pbot_default = 100000._r8
+ real(r8), parameter :: forc_rho_default = 1.1_r8
+ ! ------------------------------------------------------------------------
+
+ if (present(forc_t)) then
+ this%atm2lnd_inst%forc_t_downscaled_col(bounds%begc:bounds%endc) = forc_t(:)
+ else
+ this%atm2lnd_inst%forc_t_downscaled_col(bounds%begc:bounds%endc) = forc_t_default
+ end if
+
+ if (present(forc_pbot)) then
+ this%atm2lnd_inst%forc_pbot_downscaled_col(bounds%begc:bounds%endc) = forc_pbot(:)
+ else
+ this%atm2lnd_inst%forc_pbot_downscaled_col(bounds%begc:bounds%endc) = forc_pbot_default
+ end if
+
+ if (present(forc_rho)) then
+ this%atm2lnd_inst%forc_rho_downscaled_col(bounds%begc:bounds%endc) = forc_rho(:)
+ else
+ this%atm2lnd_inst%forc_rho_downscaled_col(bounds%begc:bounds%endc) = forc_rho_default
+ end if
+
+ end subroutine create_atm2lnd
+
+ !-----------------------------------------------------------------------
+
+ subroutine create_fv(this, fv, u10, ram1)
+ ! Initializes some fields needed for dust emissions in this%frictionvel_inst, and sets
+ ! fields based on inputs. Excluded inputs are given a default value
+ class(unittest_dust_emis_input_type), intent(inout) :: this
+ real(r8), intent(in), optional :: fv
+ real(r8), intent(in), optional :: u10
+ real(r8), intent(in), optional :: ram1
+
+ real(r8), parameter :: fv_default = 2.0_r8
+ real(r8), parameter :: u10_default = 4._r8
+ real(r8), parameter :: ram1_default = 200._r8
+ ! ------------------------------------------------------------------------
+
+ if (present(fv)) then
+ this%frictionvel_inst%fv_patch(bounds%begp:bounds%endp) = fv
+ else
+ this%frictionvel_inst%fv_patch(bounds%begp:bounds%endp) = fv_default
+ end if
+
+ if (present(u10)) then
+ this%frictionvel_inst%u10_patch(bounds%begp:bounds%endp) = u10
+ else
+ this%frictionvel_inst%u10_patch(bounds%begp:bounds%endp) = u10_default
+ end if
+
+ if (present(ram1)) then
+ this%frictionvel_inst%ram1_patch(bounds%begp:bounds%endp) = ram1
+ else
+ this%frictionvel_inst%ram1_patch(bounds%begp:bounds%endp) = ram1_default
+ end if
+
+ end subroutine create_fv
+
+ !-----------------------------------------------------------------------
+
+ subroutine print_values(this)
+ use LandunitType, only : lun
+ use PatchType, only : patch
+ class(unittest_dust_emis_input_type), intent(inout) :: this
+ integer :: p, c, l
+
+ do l = bounds%begl, bounds%endl
+ print *, 'landunit type= ', lun%itype(l)
+ end do
+ do c = bounds%begc, bounds%endc
+ print *, 'watsat = ', this%soilstate_inst%watsat_col(c,1)
+ print *, 'h2osoi_vol = ', this%water_inst%waterstatebulk_inst%h2osoi_vol_col(c,1)
+ print *, 'frac_sno = ', this%water_inst%waterdiagnosticbulk_inst%frac_sno_col(c)
+ print *, 'mss_frac_clay_vld = ', this%soilstate_inst%mss_frc_cly_vld_col(c)
+ end do
+ do p = bounds%begp, bounds%endp
+ print *, 'patch type= ', patch%itype(p)
+ print *, 'patch weight= ', patch%wtgcell(p)
+ print *, 'patch active= ', patch%active(p)
+ print *, 'tlai = ', this%canopystate_inst%tlai_patch(p)
+ print *, 'tsai = ', this%canopystate_inst%tsai_patch(p)
+ end do
+ end subroutine print_values
+
+ !-----------------------------------------------------------------------
+
+end module unittestDustEmisInputs
\ No newline at end of file
diff --git a/src/unit_test_stubs/share_esmf/CMakeLists.txt b/src/unit_test_stubs/share_esmf/CMakeLists.txt
index 5eb2d42415..5ffce0ba94 100644
--- a/src/unit_test_stubs/share_esmf/CMakeLists.txt
+++ b/src/unit_test_stubs/share_esmf/CMakeLists.txt
@@ -1,5 +1,6 @@
list(APPEND clm_sources
ExcessIceStreamType.F90
+ ZenderSoilErodStreamType.F90
)
sourcelist_to_parent(clm_sources)
diff --git a/src/unit_test_stubs/share_esmf/ZenderSoilErodStreamType.F90 b/src/unit_test_stubs/share_esmf/ZenderSoilErodStreamType.F90
new file mode 100644
index 0000000000..570fcec05f
--- /dev/null
+++ b/src/unit_test_stubs/share_esmf/ZenderSoilErodStreamType.F90
@@ -0,0 +1,88 @@
+module ZenderSoilErodStreamType
+
+ !-----------------------------------------------------------------------
+ ! !DESCRIPTION:
+ ! UNIT-TEST STUB for ZenderSoilErodStreamType
+ !
+ ! !USES
+ use shr_kind_mod , only : r8 => shr_kind_r8, CL => shr_kind_cl
+ use shr_log_mod , only : errMsg => shr_log_errMsg
+ use abortutils , only : endrun
+ use decompMod , only : bounds_type
+
+ ! !PUBLIC TYPES:
+ implicit none
+ private
+
+ type, public :: soil_erod_stream_type
+ contains
+
+ ! !PUBLIC MEMBER FUNCTIONS:
+ procedure, public :: Init ! Initialize and read data in
+ procedure, public :: CalcDustSource ! Calculate dust source spatial filter (basically truncating stream data value smaller than 0.1 following CAM's practice) based on input streams
+ procedure, public :: UseStreams ! If streams will be used
+
+ end type soil_erod_stream_type
+
+ character(len=*), parameter, private :: sourcefile = &
+ __FILE__
+
+!==============================================================================
+contains
+!==============================================================================
+
+ subroutine Init(this, bounds, NLFilename)
+ !
+ ! Initialize the Zender soil eroditability stream object
+ !
+ ! Uses:
+ !
+ ! arguments
+ implicit none
+ class(soil_erod_stream_type) :: this
+ type(bounds_type), intent(in) :: bounds
+ character(len=*), intent(in) :: NLFilename ! Namelist filename
+ !
+ ! local variables
+ !-----------------------------------------------------------------------
+
+ end subroutine Init
+
+ !==============================================================================
+ logical function UseStreams(this)
+ !
+ ! !DESCRIPTION:
+ ! Return true if the Zender method is being used and the soil erodability
+ ! file is being used with it
+ !
+ ! !USES:
+ !
+ ! !ARGUMENTS:
+ implicit none
+ class(soil_erod_stream_type) :: this
+ !
+ ! !LOCAL VARIABLES:
+ UseStreams = .false.
+ end function UseStreams
+
+ !==============================================================================
+ subroutine CalcDustSource(this, bounds, soil_erod)
+ !
+ ! !DESCRIPTION:
+ ! Calculate the soil eroditability for the Zender dust method.
+ !
+ ! !USES:
+ !USES
+ !
+ ! !ARGUMENTS:
+ implicit none
+ class(soil_erod_stream_type) :: this
+ type(bounds_type) , intent(in) :: bounds
+ real(r8) , intent(inout) :: soil_erod(bounds%begc:) ! [fraction] rock drag partition factor (roughness effect)
+ !
+ ! !LOCAL VARIABLES:
+ !---------------------------------------------------------------------
+
+ end subroutine CalcDustSource
+
+end module ZenderSoilErodStreamType
diff --git a/src/utils/clmfates_interfaceMod.F90 b/src/utils/clmfates_interfaceMod.F90
index fcd5cb5230..e3e7644b90 100644
--- a/src/utils/clmfates_interfaceMod.F90
+++ b/src/utils/clmfates_interfaceMod.F90
@@ -54,12 +54,15 @@ module CLMFatesInterfaceMod
use clm_varctl , only : use_fates_cohort_age_tracking
use clm_varctl , only : use_fates_ed_st3
use clm_varctl , only : use_fates_ed_prescribed_phys
- use clm_varctl , only : use_fates_logging
+ use clm_varctl , only : fates_harvest_mode
use clm_varctl , only : use_fates_inventory_init
use clm_varctl , only : use_fates_fixed_biogeog
use clm_varctl , only : use_fates_nocomp
use clm_varctl , only : use_fates_sp
use clm_varctl , only : use_fates_luh
+ use clm_varctl , only : use_fates_lupft
+ use clm_varctl , only : use_fates_potentialveg
+ use clm_varctl , only : flandusepftdat
use clm_varctl , only : fates_seeddisp_cadence
use clm_varctl , only : fates_inventory_ctrl_filename
use clm_varctl , only : use_nitrif_denitrif
@@ -167,7 +170,6 @@ module CLMFatesInterfaceMod
use FATESFireBase , only : fates_fire_base_type
use FATESFireFactoryMod , only : no_fire, scalar_lightning, successful_ignitions,&
anthro_ignitions, anthro_suppression
- use dynSubgridControlMod , only : get_do_harvest
use dynHarvestMod , only : num_harvest_inst, harvest_varnames
use dynHarvestMod , only : harvest_units, mass_units, unitless_units
use dynHarvestMod , only : dynHarvest_interp_resolve_harvesttypes
@@ -180,7 +182,14 @@ module CLMFatesInterfaceMod
use dynFATESLandUseChangeMod, only : num_landuse_transition_vars, num_landuse_state_vars
use dynFATESLandUseChangeMod, only : landuse_transitions, landuse_states
use dynFATESLandUseChangeMod, only : landuse_transition_varnames, landuse_state_varnames
- use dynFATESLandUseChangeMod, only : dynFatesLandUseInterp
+ use dynFATESLandUseChangeMod, only : num_landuse_harvest_vars
+ use dynFATESLandUseChangeMod, only : fates_harvest_no_logging
+ use dynFATESLandUseChangeMod, only : fates_harvest_clmlanduse
+ use dynFATESLandUseChangeMod, only : fates_harvest_luh_area
+ use dynFATESLandUseChangeMod, only : fates_harvest_luh_mass
+ use dynFATESLandUseChangeMod, only : landuse_harvest
+ use dynFATESLandUseChangeMod, only : landuse_harvest_units
+ use dynFATESLandUseChangeMod, only : landuse_harvest_varnames
implicit none
@@ -273,6 +282,8 @@ module CLMFatesInterfaceMod
character(len=*), parameter, private :: sourcefile = &
__FILE__
+ integer, parameter :: num_landuse_pft_vars = 4
+
public :: CLMFatesGlobals1
public :: CLMFatesGlobals2
public :: CrossRefHistoryFields
@@ -386,6 +397,7 @@ subroutine CLMFatesGlobals2()
integer :: pass_cohort_age_tracking
integer :: pass_tree_damage
integer :: pass_use_luh
+ integer :: pass_use_potentialveg
integer :: pass_num_luh_states
integer :: pass_num_luh_transitions
@@ -483,13 +495,6 @@ subroutine CLMFatesGlobals2()
end if
call set_fates_ctrlparms('use_ed_st3',ival=pass_ed_st3)
- if(use_fates_logging) then
- pass_logging = 1
- else
- pass_logging = 0
- end if
- call set_fates_ctrlparms('use_logging',ival=pass_logging)
-
if(use_fates_ed_prescribed_phys) then
pass_ed_prescribed_phys = 1
else
@@ -511,26 +516,30 @@ subroutine CLMFatesGlobals2()
end if
call set_fates_ctrlparms('use_cohort_age_tracking',ival=pass_cohort_age_tracking)
- ! check fates logging namelist value first because hlm harvest overrides it
- if(use_fates_logging) then
- pass_logging = 1
- else
- pass_logging = 0
- end if
-
- if(get_do_harvest()) then
- pass_logging = 1
- pass_num_lu_harvest_cats = num_harvest_inst
- pass_lu_harvest = 1
- else
- pass_lu_harvest = 0
- pass_num_lu_harvest_cats = 0
+ ! FATES logging and harvest modes
+ pass_logging = 0
+ pass_lu_harvest = 0
+ pass_num_lu_harvest_cats = 0
+ if (trim(fates_harvest_mode) /= fates_harvest_no_logging) then
+ pass_logging = 1 ! Time driven logging, without landuse harvest
+ ! CLM landuse timeseries driven harvest rates
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
+ pass_num_lu_harvest_cats = num_harvest_inst
+ pass_lu_harvest = 1
+
+ ! LUH2 landuse timeseries driven harvest rates
+ else if (trim(fates_harvest_mode)== fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode)== fates_harvest_luh_mass) then
+ pass_lu_harvest = 1
+ pass_num_lu_harvest_cats = num_landuse_harvest_vars
+ end if
end if
call set_fates_ctrlparms('use_lu_harvest',ival=pass_lu_harvest)
call set_fates_ctrlparms('num_lu_harvest_cats',ival=pass_num_lu_harvest_cats)
call set_fates_ctrlparms('use_logging',ival=pass_logging)
+ ! FATES landuse modes
if(use_fates_luh) then
pass_use_luh = 1
pass_num_luh_states = num_landuse_state_vars
@@ -540,10 +549,18 @@ subroutine CLMFatesGlobals2()
pass_num_luh_states = 0
pass_num_luh_transitions = 0
end if
+
call set_fates_ctrlparms('use_luh2',ival=pass_use_luh)
call set_fates_ctrlparms('num_luh2_states',ival=pass_num_luh_states)
call set_fates_ctrlparms('num_luh2_transitions',ival=pass_num_luh_transitions)
+ if ( use_fates_potentialveg ) then
+ pass_use_potentialveg = 1
+ else
+ pass_use_potentialveg = 0
+ end if
+ call set_fates_ctrlparms('use_fates_potentialveg',ival=pass_use_potentialveg)
+
if(use_fates_inventory_init) then
pass_inventory_init = 1
else
@@ -675,7 +692,7 @@ end subroutine CLMFatesTimesteps
! ====================================================================================
- subroutine init(this, bounds_proc )
+ subroutine init(this, bounds_proc, flandusepftdat)
! ---------------------------------------------------------------------------------
! This initializes the hlm_fates_interface_type
@@ -704,6 +721,7 @@ subroutine init(this, bounds_proc )
! Input Arguments
class(hlm_fates_interface_type), intent(inout) :: this
type(bounds_type),intent(in) :: bounds_proc
+ character(len=*), intent(in) :: flandusepftdat
! local variables
integer :: nclumps ! Number of threads
@@ -721,6 +739,9 @@ subroutine init(this, bounds_proc )
integer :: ndecomp
integer :: numg
+ real(r8), allocatable :: landuse_pft_map(:,:,:)
+ real(r8), allocatable :: landuse_bareground(:)
+
! Initialize the FATES communicators with the HLM
! This involves to stages
! 1) allocate the vectors
@@ -753,6 +774,13 @@ subroutine init(this, bounds_proc )
write(iulog,*) 'clm_fates%init(): allocating for ',nclumps,' threads'
end if
+ ! Retrieve the landuse x pft static data if the file is present
+ if (use_fates_fixed_biogeog .and. use_fates_luh) then
+ call GetLandusePFTData(bounds_proc, flandusepftdat, landuse_pft_map, landuse_bareground)
+ end if
+
+ nclumps = get_proc_clumps()
+
allocate(copy_fates_var(bounds_proc%begc:bounds_proc%endc))
copy_fates_var(:) = .false.
@@ -857,18 +885,26 @@ subroutine init(this, bounds_proc )
this%fates(nc)%sites(s)%lat = grc%latdeg(g)
this%fates(nc)%sites(s)%lon = grc%londeg(g)
- this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8
- ! initialize static layers for reduced complexity FATES versions from HLM
- ! maybe make this into a subroutine of it's own later.
- do m = surfpft_lb,surfpft_ub
- ft = m - surfpft_lb
- this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,m)
- end do
+ ! Transfer the landuse x pft data to fates via bc_in if file is given
+ if (use_fates_fixed_biogeog) then
+ if (use_fates_luh) then
+ this%fates(nc)%bc_in(s)%pft_areafrac_lu(:,1:num_landuse_pft_vars) = landuse_pft_map(g,:,1:num_landuse_pft_vars)
+ this%fates(nc)%bc_in(s)%baregroundfrac = landuse_bareground(g)
+ else
+ ! initialize static layers for reduced complexity FATES versions from HLM
+ ! maybe make this into a subroutine of it's own later.
+ this%fates(nc)%bc_in(s)%pft_areafrac(:)=0._r8
+ do m = surfpft_lb,surfpft_ub
+ ft = m - surfpft_lb
+ this%fates(nc)%bc_in(s)%pft_areafrac(ft)=wt_nat_patch(g,m)
+ end do
- if (abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub)) - 1.0_r8) > sum_to_1_tol) then
- write(iulog,*) 'pft_area error in interfc ', s, sum(this%fates(nc)%bc_in(s)%pft_areafrac(:)) - 1.0_r8
- call endrun(msg=errMsg(sourcefile, __LINE__))
- end if
+ if (abs(sum(this%fates(nc)%bc_in(s)%pft_areafrac(surfpft_lb:surfpft_ub)) - 1.0_r8) > sum_to_1_tol) then
+ write(iulog,*) 'pft_area error in interfc ', s, sum(this%fates(nc)%bc_in(s) %pft_areafrac(:)) - 1.0_r8
+ call endrun(msg=errMsg(sourcefile, __LINE__))
+ end if
+ end if
+ end if
end do !site
! Initialize site-level static quantities dictated by the HLM
@@ -910,6 +946,12 @@ subroutine init(this, bounds_proc )
! Fire data to send to FATES
call create_fates_fire_data_method( this%fates_fire_data_method )
+ ! deallocate the local landuse x pft array
+ if (use_fates_fixed_biogeog .and. use_fates_luh) then
+ deallocate(landuse_pft_map)
+ deallocate(landuse_bareground)
+ end if
+
call t_stopf('fates_init')
end subroutine init
@@ -1026,7 +1068,8 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
! Set the FATES global time and date variables
call GetAndSetTime
- if (get_do_harvest()) then
+ ! Get harvest rates for CLM landuse timeseries driven rates
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
call dynHarvest_interp_resolve_harvesttypes(bounds_clump, &
harvest_rates=harvest_rates(begg:endg,1:num_harvest_inst), &
after_start_of_harvest_ts=after_start_of_harvest_ts)
@@ -1152,7 +1195,7 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
! for now there is one veg column per gridcell, so store all harvest data in each site
! this will eventually change
! today's hlm harvest flag needs to be set no matter what
- if (get_do_harvest()) then
+ if (trim(fates_harvest_mode) == fates_harvest_clmlanduse) then
if (after_start_of_harvest_ts) then
this%fates(nc)%bc_in(s)%hlm_harvest_rates(1:num_harvest_inst) = harvest_rates(g,1:num_harvest_inst)
else
@@ -1170,6 +1213,12 @@ subroutine dynamics_driv(this, nc, bounds_clump, &
write(iulog,*) harvest_units
call endrun(msg=errMsg(sourcefile, __LINE__))
end if
+
+ else if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) == fates_harvest_luh_mass) then
+ this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g)
+ this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames
+ this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units
endif
if (use_fates_luh) then
@@ -2132,6 +2181,13 @@ subroutine init_coldstart(this, waterstatebulk_inst, waterdiagnosticbulk_inst, &
this%fates(nc)%bc_in(s)%hlm_luh_state_names = landuse_state_varnames
this%fates(nc)%bc_in(s)%hlm_luh_transitions = landuse_transitions(:,g)
this%fates(nc)%bc_in(s)%hlm_luh_transition_names = landuse_transition_varnames
+
+ if (trim(fates_harvest_mode) == fates_harvest_luh_area .or. &
+ trim(fates_harvest_mode) == fates_harvest_luh_mass) then
+ this%fates(nc)%bc_in(s)%hlm_harvest_rates = landuse_harvest(:,g)
+ this%fates(nc)%bc_in(s)%hlm_harvest_catnames = landuse_harvest_varnames
+ this%fates(nc)%bc_in(s)%hlm_harvest_units = landuse_harvest_units
+ end if
end if
end do
@@ -3755,6 +3811,112 @@ subroutine GetAndSetTime()
end subroutine GetAndSetTime
+ ! ======================================================================================
+
+ subroutine GetLandusePFTData(bounds, landuse_pft_file, landuse_pft_map, landuse_bareground)
+
+ ! !DESCRIPTION:
+ ! Read in static landuse x pft file
+
+ ! !USES:
+ use fileutils , only : getfil
+ use ncdio_pio , only : file_desc_t, ncd_io, ncd_inqdlen
+ use ncdio_pio , only : ncd_pio_openfile, ncd_pio_closefile
+ use decompMod , only : BOUNDS_LEVEL_PROC
+ use clm_varcon, only : grlnd
+ use FatesConstantsMod, only : fates_unset_r8
+
+
+ ! !ARGUMENTS:
+ type(bounds_type), intent(in) :: bounds ! proc-level bounds
+ character(len=*) , intent(in) :: landuse_pft_file ! name of file containing static landuse x pft information
+ real(r8), allocatable, intent(inout) :: landuse_pft_map(:,:,:)
+ real(r8), allocatable, intent(inout) :: landuse_bareground(:)
+
+ ! !LOCAL VARIABLES
+ integer :: varnum ! variable number
+ integer :: dimid, dimlen ! dimension id number and length
+ integer :: ier ! error id
+ character(len=256) :: locfn ! local file name
+ type(file_desc_t) :: ncid ! netcdf id
+ real(r8), pointer :: arraylocal(:,:) ! local array for reading fraction data
+ real(r8), pointer :: arraylocal_bareground(:) ! local array for reading bareground data
+ logical :: readvar ! true => variable is on dataset
+ !character(len=16), parameter :: grlnd = 'lndgrid' ! name of lndgrid
+
+ integer, parameter :: dim_landuse_pft = 14
+
+ ! Land use name arrays
+ character(len=10), parameter :: landuse_pft_map_varnames(num_landuse_pft_vars) = &
+ [character(len=10) :: 'frac_primr','frac_secnd','frac_pastr','frac_range'] !need to move 'frac_surf' to a different variable
+
+ character(len=*), parameter :: subname = 'GetLandusePFTData'
+
+ !-----------------------------------------------------------------------
+
+ ! Check to see if the landuse file name has been provided
+ ! Note: getfile checks this as well
+ if (masterproc) then
+ write(iulog,*) 'Attempting to read landuse x pft data .....'
+ if (landuse_pft_file == ' ') then
+ write(iulog,*)'landuse_pft_file must be specified'
+ call endrun(msg=errMsg(__FILE__, __LINE__))
+ endif
+ endif
+
+ ! Initialize the landuse x pft arrays and initialize to unset
+ allocate(landuse_pft_map(bounds%begg:bounds%endg,dim_landuse_pft,num_landuse_pft_vars),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_pft_map'//errMsg(__FILE__, __LINE__))
+ end if
+ landuse_pft_map = fates_unset_r8
+
+ allocate(landuse_bareground(bounds%begg:bounds%endg),stat=ier)
+ if (ier /= 0) then
+ call endrun(msg=' allocation error for landuse_bareground'//errMsg(__FILE__, __LINE__))
+ end if
+ landuse_bareground = fates_unset_r8
+
+
+ ! Get the local filename and open the file
+ call getfil(landuse_pft_file, locfn, 0)
+ call ncd_pio_openfile (ncid, trim(locfn), 0)
+
+ ! Check that natpft dimension on the file matches the target array dimensions
+ call ncd_inqdlen(ncid, dimid, dimlen, 'natpft')
+ if (dimlen /= dim_landuse_pft) then
+ write(iulog,*) 'natpft dimensions on the landuse x pft file do not match target array size'
+ call endrun(msg=errMsg(__FILE__, __LINE__))
+ end if
+
+ ! Allocate a temporary array since ncdio expects a pointer
+ allocate(arraylocal(bounds%begg:bounds%endg,dim_landuse_pft))
+ allocate(arraylocal_bareground(bounds%begg:bounds%endg))
+
+ ! Read the landuse x pft data from file
+ do varnum = 1, num_landuse_pft_vars
+ call ncd_io(ncid=ncid, varname=landuse_pft_map_varnames(varnum), flag='read', &
+ data=arraylocal, dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) &
+ call endrun(msg='ERROR: '//trim(landuse_pft_map_varnames(varnum))// &
+ ' NOT on landuse x pft file'//errMsg(__FILE__, __LINE__))
+ landuse_pft_map(bounds%begg:bounds%endg,:,varnum) = arraylocal(bounds%begg:bounds%endg,:)
+ end do
+
+ ! Read the bareground data from file. This is per gridcell only.
+ call ncd_io(ncid=ncid, varname='frac_brgnd', flag='read', &
+ data=arraylocal_bareground, dim1name=grlnd, readvar=readvar)
+ if (.not. readvar) call endrun(msg='ERROR: frac_brgnd NOT on landuse x pft file'//errMsg(__FILE__, __LINE__))
+ landuse_bareground(bounds%begg:bounds%endg) = arraylocal_bareground(bounds%begg:bounds%endg)
+
+ ! Deallocate the temporary local array point and close the file
+ deallocate(arraylocal)
+ deallocate(arraylocal_bareground)
+ call ncd_pio_closefile(ncid)
+
+ end subroutine GetLandusePFTData
+
+
!-----------------------------------------------------------------------
end module CLMFatesInterfaceMod
diff --git a/test/tools/CLM_compare.sh b/test/tools/CLM_compare.sh
deleted file mode 100755
index 38f547c3ab..0000000000
--- a/test/tools/CLM_compare.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 2 ]; then
- echo "CLM_compare.sh: incorrect number of input arguments"
- exit 1
-fi
-
-echo "CLM_compare.sh: comparing $1 "
-echo " with $2"
-
-##note syntax here as stderr and stdout from cprnc command go
-##to separate places!
-${CPRNC_EXE} ${CPRNC_OPT} $1 $2 2>&1 > cprnc.out
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "CLM_compare.sh: error doing comparison, cprnc error= $rc"
- exit 2
-fi
-
-result_old=`perl -e 'while (my $ll = <>) \
- { if ($ll =~ /(\d+)[^0-9]+compared[^0-9]+(\d+)/) \
- { print "PASS" if $1>0 && $2==0 }}' cprnc.out`
-if grep -c "the two files seem to be IDENTICAL" cprnc.out > /dev/null; then
- result=PASS
-elif grep -c "the two files seem to be DIFFERENT" cprnc.out > /dev/null; then
- result=FAIL
-else
- result=$result_old
-fi
-
-if [ "$result" = "PASS" ]; then
- echo "CLM_compare.sh: files are b4b"
-else
- echo "CLM_compare.sh: files are NOT b4b"
- exit 3
-fi
-
-exit 0
diff --git a/test/tools/Makefile b/test/tools/Makefile
deleted file mode 100644
index b5031abdba..0000000000
--- a/test/tools/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Makefile to build clm testing documentation
-#
-
-# Get list of tests_ files
-SOURCES = $(wildcard tests_*)
-
-all: test_table.html
-
-test_table.html: $(SOURCES)
- gen_test_table.sh
-
diff --git a/test/tools/README b/test/tools/README
deleted file mode 100644
index c545f625b8..0000000000
--- a/test/tools/README
+++ /dev/null
@@ -1,73 +0,0 @@
-$CTSMROOT/clm/test/tools/README 06/08/2018
-
-Scripts for testing the CLM support tools with many different
-configurations and run-time options.
-
-I. MAIN SCRIPTS:
-
-test_driver.sh - Test the CLM offline tools
-
-To use...
-
-./test_driver.sh -i
-
-on Derecho
-
-qcmd -l walltime=08:00:00 -- ./test_driver.sh -i >& run.out &
-
-And to for example to compare to another baseline code (in this case ctsm5.1.dev066, which would need to be cloned at the given
-path) ...
-
-qcmd -l walltime=08:00:00 -- env BL_ROOT=/glade/scratch/erik/ctsm5.1.dev066 ./test_driver.sh -i >& run.out &
-
-on izumi
-
-nohup ./test_driver.sh -i >& run.out &
-
-release tests
-
-qcmd -l walltime=10:00:00 -- env CLM_INPUT_TESTS=`pwd`/tests_posttag_nompi_regression \
-./test_driver.sh -i >& run_regress.out &
-
-To run neon-specific tests, please use login nodes:
-env CLM_INPUT_TESTS=`pwd`/tests_pretag_nompi_neon ./test_driver.sh -i > & run_neon.out &
-
-
-Intended for use on NCAR machines Derecho, Casper (DAV) and izumi.
-
-II. RUNNING test_driver.sh TOOLS TESTING:
-
-Basic use:
-
-./test_driver.sh -i
-./test_driver.sh -h # to get help on options
-
-Important environment variables (just used by test_driver.sh)
-
-BL_ROOT ---------------- Root directory of CLM baseline code to compare to
- (if not set BL test will not be performed)
-BL_TESTDIR ------------- Root directory of where to put baseline tests
-CLM_INPUT_TESTS -------- Filename of file with list of tests to perform
-CLM_TESTDIR ------------ Root directory of where to put most tests
-CLM_RETAIN_FILES ------- If set to TRUE -- don't cleanup files after testing
-CLM_FC ----------------- Use given compiler
-CLM_JOBID -------------- Job identification number to use (rather than process ID)
-CLM_THREADS ------------ Number of open-MP threads to use
- (by default this is set differently by machine)
-CLM_SOFF --------------- If set to TRUE -- stop on first failed test (default FALSE)
-
-Important files for test_driver tools testing:
-
-test_driver.sh ------- Main test script for tools
-nl_files ------------- Directory with various namelists to test
-config_files --------- Directory with various configurations to test
-input_tests_master --- Master list of tests
-tests_pretag_* ------- Tests for specific machines to do by default before a tag is done
-tests_posttag_* ------ Tests for specific machines to do for more extensive testing
- after a tag is done
-CLM_compare.sh ------- Compares output history files between two cases
-T*.sh ---------------- Basic test script to do a specific type of test
-gen_test_table.sh ---- Creates HTML table of tests
-Makefile ------------- Will build the HTML table of tests
-
-../../tools/README.testing - Information on how the testing works for the CLM tools
diff --git a/test/tools/README.testnames b/test/tools/README.testnames
deleted file mode 100644
index 74dbe8e5f3..0000000000
--- a/test/tools/README.testnames
+++ /dev/null
@@ -1,69 +0,0 @@
-Tests for test_driver are for the CLM tools only.
-
-Test naming conventions for the test_driver.sh script:
-
-Test names are:
-
-xxnmi
-
-Where: xx is the two-letter test type
- sm=smoke, br=branch, er=exact restart, bl=base-line comparision,
- cb=configure-build, rp=reproducibility, op=OpenMP threading for tools
-
-n is the configuration type:
-
-1 -- unused
-2 -- unused
-3 -- unused
-4 -- unused
-5 -- unused
-6 -- unused
-7 -- unused
-8 -- unused
-9 -- mesh_maker
-0 -- run_neon
-a -- modify_data
-b -- subset_data
-c -- mkprocdata_map
-d -- mkmapgrids
-e -- unused
-f -- unused
-g -- unused
-h -- unused
-i -- tools scripts
-
-m is the resolution
-
-0 -- 0.9x1.25
-1 -- 48x96
-5 -- 10x15
-6 -- 5x5_amazon
-7 -- 1x1 brazil
-8 -- US-UMB
-9 -- 4x5
-a -- NEON YELL
-b -- NEON KONA
-c -- NEON OSBS
-d -- SouthAmerica
-e -- 1850PanTropics
-f -- PanBoreal
-g -- AlaskaTananaValley
-h -- single point from the 0.9x1.25 grid (Township SD)
-y -- 1.9x2.5 with transient 1850-2100 for rcp=2.6 and glacier-MEC on
-T -- 1x1_numaIA
-Z -- 10x15 with crop on
-@ -- ne120np4
-# -- ne30np4
-
-i is the specific test (usually this implies...)
-
-1 -- Serial script
-2 -- Serial
-3 -- OpenMP only
-4 -- serial, DEBUG
-7 -- OpenMP only second test, DEBUG
-8 -- OpenMP only third test, DEBUG
-9 -- Serial Script
-0 -- Serial Script
-
-
diff --git a/test/tools/TBLCFGtools.sh b/test/tools/TBLCFGtools.sh
deleted file mode 100755
index 6276c885e2..0000000000
--- a/test/tools/TBLCFGtools.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TBLCFGtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-if [ -z "$BL_ROOT" ] && [ -z "$BL_TESTDIR" ]; then
- echo "TBL.sh: no environment variables set for baseline test - will skip"
- exit 255
-fi
-
-tool=$(basename $1)
-test_name=TBLCFGtools.$tool.$2.$3
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLCFGtools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLCFGtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TBLCFGtools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TBLCFGtools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TBLCFGtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-echo "TBLCFGtools.sh: calling TSMCFGtools.sh to run $tool executable"
-${CLM_SCRIPTDIR}/TSMCFGtools.sh $1 $2 $3
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TBLCFGtools.sh: error from TSMCFGtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-if [ -n "${BL_ROOT}" ]; then
- if [ -z "$BL_TESTDIR" ]; then
- BL_TESTDIR=${CLM_TESTDIR}.bl
- fi
- echo "TBLCFGtools.sh: generating baseline data from root $BL_ROOT - results in $BL_TESTDIR"
-
- echo "TBLCFGtools.sh: calling ****baseline**** TSMCFGtools.sh for smoke test"
- bl_dir=`/bin/ls -1d ${BL_ROOT}/test/tools`
- env CLM_TESTDIR=${BL_TESTDIR} \
- CLM_ROOT=${BL_ROOT} \
- CLM_SCRIPTDIR=$bl_dir \
- $bl_dir/TSMCFGtools.sh $1 $2 $3
- rc=$?
- if [ $rc -ne 0 ]; then
- echo "TBLCFGtools.sh: error from *baseline* TSMCFGtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
- fi
-fi
-
-echo "TBLCFGtools.sh: starting b4b comparisons "
-files_to_compare=`cd ${CLM_TESTDIR}/TSMCFGtools.$tool.$2.$3; ls *.nc`
-if [ -z "${files_to_compare}" ] && [ "$debug" != "YES" ]; then
- echo "TBLCFGtools.sh: error locating files to compare"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-all_comparisons_good="TRUE"
-for compare_file in ${files_to_compare}; do
-
- env CPRNC_OPT="-m" \
- ${CLM_SCRIPTDIR}/CLM_compare.sh \
- ${BL_TESTDIR}/TSMCFGtools.$tool.$2.$3/${compare_file} \
- ${CLM_TESTDIR}/TSMCFGtools.$tool.$2.$3/${compare_file}
- rc=$?
- mv cprnc.out cprnc.${compare_file}.out
- if [ $rc -eq 0 ]; then
- echo "TBLCFGtools.sh: comparison successful; output in ${rundir}/cprnc.${compare_file}.out"
- else
- echo "TBLCFGtools.sh: error from CLM_compare.sh= $rc; see ${rundir}/cprnc.${compare_file}.out for details
-"
- all_comparisons_good="FALSE"
- fi
-done
-
-if [ ${all_comparisons_good} = "TRUE" ]; then
- echo "TBLCFGtools.sh: baseline test passed"
- echo "PASS" > TestStatus
- if [ $CLM_RETAIN_FILES != "TRUE" ]; then
- echo "TBLCFGtools.sh: removing some unneeded files to save disc space"
- rm *.nc
- rm *.r*
- fi
-else
- echo "TBLCFGtools.sh: at least one file comparison did not pass"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 7
-fi
-
-exit 0
diff --git a/test/tools/TBLscript_tools.sh b/test/tools/TBLscript_tools.sh
deleted file mode 100755
index d05492c687..0000000000
--- a/test/tools/TBLscript_tools.sh
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TBLscript_tools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-if [ -z "$BL_ROOT" ] && [ -z "$BL_TESTDIR" ]; then
- echo "TBLscript_tools.sh: no environment variables set for baseline test - will skip"
- exit 255
-fi
-
-test_name=TBLscript_tools.$1.$2.$3
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLscript_tools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLscript_tools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TBLscript_tools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TBLscript_tools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TBLscript_tools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-echo "TBLscript_tools.sh: calling TSMscript_tools.sh to run $1 executable"
-${CLM_SCRIPTDIR}/TSMscript_tools.sh $1 $2 $3
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TBLscript_tools.sh: error from TSMtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-if [ -n "${BL_ROOT}" ]; then
- if [ -z "$BL_TESTDIR" ]; then
- BL_TESTDIR=${CLM_TESTDIR}.bl
- fi
- echo "TBLscript_tools.sh: generating baseline data from root $BL_ROOT - results in $BL_TESTDIR"
-
- echo "TBLscript_tools.sh: calling ****baseline**** TSMtools.sh for smoke test"
- bl_dir=`/bin/ls -1d ${BL_ROOT}/test/tools`
- env CLM_TESTDIR=${BL_TESTDIR} \
- CLM_SCRIPTDIR=$bl_dir \
- CLM_ROOT=$BL_ROOT \
- CTSM_ROOT=$BL_ROOT \
- CIME_ROOT=$BL_ROOT/cime \
- $bl_dir/TSMscript_tools.sh $1 $2 $3
- rc=$?
- if [ $rc -ne 0 ]; then
- echo "TBLscript_tools.sh: error from *baseline* TSMscript_tools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
- fi
-fi
-
-echo "TBLscript_tools.sh: starting b4b comparisons "
-files_to_compare=`cd ${CLM_TESTDIR}/TSMscript_tools.$1.$2.$3; ls *.nc`
-if [ -z "${files_to_compare}" ] && [ "$debug" != "YES" ]; then
- echo "TBLscript_tools.sh: error locating files to compare"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-all_comparisons_good="TRUE"
-for compare_file in ${files_to_compare}; do
-
- env CPRNC_OPT="-m" \
- ${CLM_SCRIPTDIR}/CLM_compare.sh \
- ${BL_TESTDIR}/TSMscript_tools.$1.$2.$3/${compare_file} \
- ${CLM_TESTDIR}/TSMscript_tools.$1.$2.$3/${compare_file}
- rc=$?
- mv cprnc.out cprnc.${compare_file}.out
- if [ $rc -eq 0 ]; then
- echo "TBLscript_tools.sh: comparison successful; output in ${rundir}/cprnc.${compare_file}.out"
- else
- echo "TBLscript_tools.sh: error from CLM_compare.sh= $rc; see ${rundir}/cprnc.${compare_file}.out for details"
- all_comparisons_good="FALSE"
- fi
-done
-
-if [ ${all_comparisons_good} = "TRUE" ]; then
- echo "TBLscript_tools.sh: baseline test passed"
- echo "PASS" > TestStatus
- if [ $CLM_RETAIN_FILES != "TRUE" ]; then
- echo "TBLscript_tools.sh: removing some unneeded files to save disc space"
- rm *.nc
- rm *.r*
- fi
-else
- echo "TBLscript_tools.sh: at least one file comparison did not pass"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 7
-fi
-
-
-
-exit 0
diff --git a/test/tools/TBLtools.sh b/test/tools/TBLtools.sh
deleted file mode 100755
index 555ea7d1be..0000000000
--- a/test/tools/TBLtools.sh
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TBLtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-if [ -z "$BL_ROOT" ] && [ -z "$BL_TESTDIR" ]; then
- echo "TBL.sh: no environment variables set for baseline test - will skip"
- exit 255
-fi
-
-test_name=TBLtools.$1.$2.$3
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLtools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TBLtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TBLtools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TBLtools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TBLtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-echo "TBLtools.sh: calling TSMtools.sh to run $1 executable"
-${CLM_SCRIPTDIR}/TSMtools.sh $1 $2 $3
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TBLtools.sh: error from TSMtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-if [ -n "${BL_ROOT}" ]; then
- if [ -z "$BL_TESTDIR" ]; then
- BL_TESTDIR=${CLM_TESTDIR}.bl
- fi
- echo "TBLtools.sh: generating baseline data from root $BL_ROOT - results in $BL_TESTDIR"
-
- echo "TBLtools.sh: calling ****baseline**** TSMtools.sh for smoke test"
- bl_dir=`/bin/ls -1d ${BL_ROOT}/test/tools`
- env CLM_TESTDIR=${BL_TESTDIR} \
- CLM_ROOT=${BL_ROOT} \
- CLM_SCRIPTDIR=$bl_dir \
- $bl_dir/TSMtools.sh $1 $2 $3
- rc=$?
- if [ $rc -ne 0 ]; then
- echo "TBLtools.sh: error from *baseline* TSMtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
- fi
-fi
-
-echo "TBLtools.sh: starting b4b comparisons "
-files_to_compare=`cd ${CLM_TESTDIR}/TSMtools.$1.$2.$3; ls *.nc`
-if [ -z "${files_to_compare}" ] && [ "$debug" != "YES" ]; then
- echo "TBLtools.sh: error locating files to compare"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-all_comparisons_good="TRUE"
-for compare_file in ${files_to_compare}; do
-
- env CPRNC_OPT="-m" \
- ${CLM_SCRIPTDIR}/CLM_compare.sh \
- ${BL_TESTDIR}/TSMtools.$1.$2.$3/${compare_file} \
- ${CLM_TESTDIR}/TSMtools.$1.$2.$3/${compare_file}
- rc=$?
- mv cprnc.out cprnc.${compare_file}.out
- if [ $rc -eq 0 ]; then
- echo "TBLtools.sh: comparison successful; output in ${rundir}/cprnc.${compare_file}.out"
- else
- echo "TBLtools.sh: error from CLM_compare.sh= $rc; see ${rundir}/cprnc.${compare_file}.out for details
-"
- all_comparisons_good="FALSE"
- fi
-done
-
-if [ ${all_comparisons_good} = "TRUE" ]; then
- echo "TBLtools.sh: baseline test passed"
- echo "PASS" > TestStatus
- if [ $CLM_RETAIN_FILES != "TRUE" ]; then
- echo "TBLtools.sh: removing some unneeded files to save disc space"
- rm *.nc
- rm *.r*
- fi
-else
- echo "TBLtools.sh: at least one file comparison did not pass"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 7
-fi
-
-exit 0
diff --git a/test/tools/TCBCFGtools.sh b/test/tools/TCBCFGtools.sh
deleted file mode 100755
index 5c0b015123..0000000000
--- a/test/tools/TCBCFGtools.sh
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 2 ]; then
- echo "TCBCFGtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-tool=$(basename $1)
-test_name=TCBCFGtools.$tool.$2
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TCBCFGtools.sh: build test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TCBCFGtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TCBCFGtools.sh: build test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TCBCFGtools.sh: this build test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-cfgdir=`ls -1d ${CLM_ROOT}/tools/${1}`
-if [ $? -ne 0 ];then
- cfgdir=`ls -1d ${CIME_ROOT}/tools/mapping/${1}*`
- echo "use: $cfgdir"
-fi
-blddir=${CLM_TESTDIR}/${test_name}/src
-if [ -d ${blddir} ]; then
- rm -r ${blddir}
-fi
-mkdir -p ${blddir}
-if [ $? -ne 0 ]; then
- echo "TCBCFGtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${blddir}
-
-echo "TCBCFGtools.sh: building $tool executable; output in ${blddir}/test.log"
-#
-# Copy build files over
-#
-cp $cfgdir/src/Makefile .
-cp $cfgdir/src/Filepath .
-#
-# Add cfgdir path to beginning of each path in Filepath
-#
-touch Filepath
-while read filepath_arg; do
- echo "${cfgdir}/src/${filepath_arg}" >> Filepath
-done < ${cfgdir}/src/Filepath
-
-#
-# Figure out configuration
-#
-if [ ! -f ${CLM_SCRIPTDIR}/config_files/$tool ]; then
- echo "TCB.sh: configure options file ${CLM_SCRIPTDIR}/config_files/$tool not found"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-##construct string of args to configure
-config_string=" "
-while read config_arg; do
- config_string="${config_string}${config_arg} "
-done < ${CLM_SCRIPTDIR}/config_files/$tool
-
-if [ "$TOOLSLIBS" != "" ]; then
- export SLIBS=$TOOLSLIBS
-fi
-echo "env CIMEROOT=$CLM_ROOT/cime COMPILER=$CESM_COMP $config_string $CLM_ROOT/cime/tools/configure --macros-format Makefile --machine $CESM_MACH $TOOLS_CONF_STRING"
-env CIMEROOT=$CLM_ROOT/cime COMPILER=$CESM_COMP $config_string $CLM_ROOT/cime/tools/configure --macros-format Makefile --machine $CESM_MACH $TOOLS_CONF_STRING >> test.log 2>&1
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TCBCFGtools.sh: configure failed, error from configure= $rc"
- echo "TCBCFGtools.sh: see ${blddir}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
-fi
-
-. $INITMODULES
-. ./.env_mach_specific.sh
-
-attempt=1
-still_compiling="TRUE"
-while [ $still_compiling = "TRUE" ]; do
-
- echo "TCBCFGtools.sh: call to make:"
- echo " ${MAKE_CMD} USER_CPPDEFS=-DLINUX"
- if [ "$debug" != "YES" ]; then
- ${MAKE_CMD} USER_CPPDEFS=-DLINUX >> test.log 2>&1
- status="PASS"
- rc=$?
- else
- status="GEN"
- rc=0
- fi
- if [ $rc -eq 0 ]; then
- echo "TCBCFGtools.sh: make was successful"
- echo "TCBCFGtools.sh: configure and build test passed"
- echo "$status" > TestStatus
- if [ $CLM_RETAIN_FILES != "TRUE" ]; then
- echo "TCBCFGtools.sh: removing some unneeded files to save disc space"
- rm *.o
- rm *.mod
- fi
- still_compiling="FALSE"
- elif [ $attempt -lt 10 ] && \
- grep -c "LICENSE MANAGER PROBLEM" test.log > /dev/null; then
- attempt=`expr $attempt + 1`
- echo "TCBCFGtools.sh: encountered License Manager Problem; launching attempt #$attempt"
- else
- echo "TCBCFGtools.sh: clm build failed, error from make= $rc"
- echo "TCBCFGtools.sh: see ${blddir}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
- fi
-done
-if [ "$TOOLSLIBS" != "" ]; then
- export -n SLIBS
-fi
-
-exit 0
diff --git a/test/tools/TCBtools.sh b/test/tools/TCBtools.sh
deleted file mode 100755
index 205b2e9da0..0000000000
--- a/test/tools/TCBtools.sh
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 2 ]; then
- echo "TCBtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-test_name=TCBtools.$1.$2
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TCBtools.sh: build test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TCBtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TCBtools.sh: build test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TCBtools.sh: this build test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-cfgdir=`ls -1d ${CLM_ROOT}/tools/$1`
-blddir=${CLM_TESTDIR}/${test_name}/src
-if [ -d ${blddir} ]; then
- rm -r ${blddir}
-fi
-mkdir -p ${blddir}
-if [ $? -ne 0 ]; then
- echo "TCBtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${blddir}
-
-echo "TCBtools.sh: building $1 executable; output in ${blddir}/test.log"
-#
-# Copy build files over
-#
-cp $cfgdir/src/Makefile .
-cp $cfgdir/src/Srcfiles .
-cp $cfgdir/src/Mkdepends .
-cp $cfgdir/src/Makefile.common .
-#
-# Add cfgdir path to beginning of each path in Filepath
-#
-touch Filepath
-while read filepath_arg; do
- echo "${cfgdir}/src/${filepath_arg}" >> Filepath
-done < ${cfgdir}/src/Filepath
-
-#
-# Figure out configuration
-#
-if [ ! -f ${CLM_SCRIPTDIR}/config_files/$2 ]; then
- echo "TCB.sh: configure options file ${CLM_SCRIPTDIR}/config_files/$2 not found"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-##construct string of args to configure
-config_string="$TOOLS_MAKE_STRING TOOLROOT=$cfgdir "
-while read config_arg; do
- config_string="${config_string}${config_arg} "
-done < ${CLM_SCRIPTDIR}/config_files/$2
-
-attempt=1
-still_compiling="TRUE"
-if [ "$TOOLSLIBS" != "" ]; then
- export SLIBS=$TOOLSLIBS
-fi
-while [ $still_compiling = "TRUE" ]; do
-
- ln -s Macros.make Macros
-
- echo "TCBtools.sh: call to make:"
- echo " ${MAKE_CMD} ${config_string} "
- if [ "$debug" != "YES" ]; then
- ${MAKE_CMD} ${config_string} >> test.log 2>&1
- status="PASS"
- rc=$(( $rc + $? ))
- else
- status="GEN"
- rc=0
- fi
- if [ $rc -eq 0 ]; then
- echo "TCBtools.sh: make was successful"
- echo "TCBtools.sh: configure and build test passed"
- echo "$status" > TestStatus
- if [ $CLM_RETAIN_FILES != "TRUE" ]; then
- echo "TCBtools.sh: removing some unneeded files to save disc space"
- rm *.o
- rm *.mod
- fi
- still_compiling="FALSE"
- elif [ $attempt -lt 10 ] && \
- grep -c "LICENSE MANAGER PROBLEM" test.log > /dev/null; then
- attempt=`expr $attempt + 1`
- echo "TCBtools.sh: encountered License Manager Problem; launching attempt #$attempt"
- else
- echo "TCBtools.sh: clm build failed, error from make= $rc"
- echo "TCBtools.sh: see ${CLM_TESTDIR}/${test_name}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
- fi
-done
-if [ "$TOOLSLIBS" != "" ]; then
- export -n SLIBS
-fi
-
-exit 0
diff --git a/test/tools/TSMCFGtools.sh b/test/tools/TSMCFGtools.sh
deleted file mode 100755
index b667a4c6ec..0000000000
--- a/test/tools/TSMCFGtools.sh
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TSMCFGtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-tool=$(basename $1)
-test_name=TSMCFGtools.$tool.$2.$3
-
-
-if [ -z "$CLM_RERUN" ]; then
- CLM_RERUN="no"
-fi
-
-if [ "$CLM_RERUN" != "yes" ] && [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMCFGtools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMCFGtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TSMCFGtools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TSMCFGtools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-cfgdir=`ls -1d ${CLM_ROOT}/tools/${1}*`
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TSMCFGtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-echo "TSMCFGtools.sh: calling TCBCFGtools.sh to prepare $tool executable"
-${CLM_SCRIPTDIR}/TCBCFGtools.sh $1 $2
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TSMCFGtools.sh: error from TCBtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-echo "TSMCFGtools.sh: running $tool output in ${rundir}/test.log"
-
-if [ "$2" = "CFGtools__o" ] || [ "$2" = "CFGtools__do" ]; then
- toolrun="env OMP_NUM_THREADS=${CLM_THREADS} ${CLM_TESTDIR}/TCBCFGtools.$tool.$2/${tool}*"
-else
- toolrun="${CLM_TESTDIR}/TCBCFGtools.$tool.$2/${tool}*"
-fi
-
-runfile="${CLM_SCRIPTDIR}/nl_files/$tool.$3"
-if [ ! -f "${runfile}" ]; then
- echo "TSMCFGtools.sh: error ${runfile} input run file not found"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
-fi
-
-echo "Run file type = ${3#*.}"
-if [ ${3#*.} == "runoptions" ]; then
- runopts=`cat ${runfile} | sed -e "s|CSMDATA|$CSMDATA|g"`
- echo "$toolrun $runopts"
- cp $cfgdir/*.nc .
- if [ "$debug" != "YES" ] && [ "$compile_only" != "YES" ]; then
- $toolrun $runopts >> test.log 2>&1
- rc=$?
- status="PASS"
- else
- echo "Successfully created file" > test.log
- status="GEN"
- rc=0
- fi
-else
- echo "$toolrun < ${runfile}"
- if [ "$debug" != "YES" ] && [ "$compile_only" != "YES" ]; then
- $toolrun < ${runfile} >> test.log 2>&1
- rc=$?
- status="PASS"
- else
- echo "Successfully created file" > test.log
- status="GEN"
- rc=0
- fi
-fi
-
-if [ $rc -eq 0 ] && grep -ci "Successfully created " test.log > /dev/null; then
- echo "TSMCFGtools.sh: smoke test passed"
- echo "$status" > TestStatus
-else
- echo "TSMCFGtools.sh: error running $tool, error= $rc"
- echo "TSMCFGtools.sh: see ${CLM_TESTDIR}/${test_name}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-exit 0
diff --git a/test/tools/TSMscript_tools.sh b/test/tools/TSMscript_tools.sh
deleted file mode 100755
index 943fec97f2..0000000000
--- a/test/tools/TSMscript_tools.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TSMscript_tools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-test_name=TSMscript_tools.$1.$2.$3
-
-if [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMscript_tools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMscript_tools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TSMscript_tools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TSMscript_tools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-cfgdir=`ls -1d ${CLM_ROOT}/tools/$1`
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TSMscript_tools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-optfile=${3%^*}
-cfgfile=${3#*^}
-
-if [ "$optfile" != "$3" ]; then
- echo "TSMscript_tools.sh: calling TCBtools.sh to prepare $1 executable"
- ${CLM_SCRIPTDIR}/TCBtools.sh $1 $cfgfile
- rc=$?
- if [ $rc -ne 0 ]; then
- echo "TSMscript_tools.sh: error from TCBtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
- fi
- tcbtools=${CLM_TESTDIR}/TCBtools.$1.$cfgfile
-else
- tcbtools="$rundir"
-fi
-
-scopts=`cat ${CLM_SCRIPTDIR}/nl_files/$optfile | sed -e "s|CSMDATA|$CSMDATA|g" | sed -e "s|EXEDIR|$tcbtools|g" | sed -e "s|CFGDIR|$cfgdir|g"`
-scopts=`echo $scopts | sed -e "s|CTSM_ROOT|$CTSM_ROOT|g" | sed -e "s|CIME_ROOT|$CIME_ROOT|g"`
-
-echo "TSMscript_tools.sh: running ${cfgdir}/$2 with $scopts; output in ${rundir}/test.log"
-
-if [ ! -f "${cfgdir}/$2" ]; then
- echo "TSMscript_tools.sh: error ${cfgdir}/$2 input script not found"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
-fi
-
-if [ "$debug" != "YES" ] && [ "$compile_only" != "YES" ]; then
- ${cfgdir}/$2 $scopts >> test.log 2>&1
- rc=$?
- status="PASS"
-else
- echo "success" > test.log
- status="GEN"
- rc=0
-fi
-
-if [ $rc -eq 0 ] && grep -ci "Successfully " test.log > /dev/null; then
- echo "TSMscript_tools.sh: smoke test passed"
- echo "$status" > TestStatus
- # Copy files from subdirectories up...
- # (use hard links rather than symbolic links because 'ln -s' does funny
- # things when there are no matching files)
- ln */*.nc */*/*.nc .
-else
- echo "TSMscript_tools.sh: error running $2, error= $rc"
- echo "TSMscript_tools.sh: see ${CLM_TESTDIR}/${test_name}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-exit 0
diff --git a/test/tools/TSMtools.sh b/test/tools/TSMtools.sh
deleted file mode 100755
index 33a2316973..0000000000
--- a/test/tools/TSMtools.sh
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/bin/sh
-#
-
-if [ $# -ne 3 ]; then
- echo "TSMtools.sh: incorrect number of input arguments"
- exit 1
-fi
-
-test_name=TSMtools.$1.$2.$3
-
-if [ -z "$CLM_RERUN" ]; then
- CLM_RERUN="no"
-fi
-
-if [ "$CLM_RERUN" != "yes" ] && [ -f ${CLM_TESTDIR}/${test_name}/TestStatus ]; then
- if grep -c PASS ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMtools.sh: smoke test has already passed; results are in "
- echo " ${CLM_TESTDIR}/${test_name}"
- exit 0
- elif grep -c GEN ${CLM_TESTDIR}/${test_name}/TestStatus > /dev/null; then
- echo "TSMtools.sh: test already generated"
- else
- read fail_msg < ${CLM_TESTDIR}/${test_name}/TestStatus
- prev_jobid=${fail_msg#*job}
-
- if [ $JOBID = $prev_jobid ]; then
- echo "TSMtools.sh: smoke test has already failed for this job - will not reattempt; "
- echo " results are in: ${CLM_TESTDIR}/${test_name}"
- exit 2
- else
- echo "TSMtools.sh: this smoke test failed under job ${prev_jobid} - moving those results to "
- echo " ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid and trying again"
- cp -rp ${CLM_TESTDIR}/${test_name} ${CLM_TESTDIR}/${test_name}_FAIL.job$prev_jobid
- fi
- fi
-fi
-
-cfgdir=`ls -1d ${CLM_ROOT}/tools/$1`
-rundir=${CLM_TESTDIR}/${test_name}
-if [ -d ${rundir} ]; then
- rm -r ${rundir}
-fi
-mkdir -p ${rundir}
-if [ $? -ne 0 ]; then
- echo "TSMtools.sh: error, unable to create work subdirectory"
- exit 3
-fi
-cd ${rundir}
-
-echo "Copy any text files over"
-cp $cfgdir/*.txt $rundir
-
-echo "TSMtools.sh: calling TCBtools.sh to prepare $1 executable"
-${CLM_SCRIPTDIR}/TCBtools.sh $1 $2
-rc=$?
-if [ $rc -ne 0 ]; then
- echo "TSMtools.sh: error from TCBtools.sh= $rc"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 4
-fi
-
-echo "TSMtools.sh: running $1; output in ${rundir}/test.log"
-
-if [ "$3" = "tools__o" ] || [ "$3" = "tools__do" ]; then
- toolrun="env OMP_NUM_THREADS=${CLM_THREADS} ${CLM_TESTDIR}/TCBtools.$1.$2/$1"
-else
- toolrun="${CLM_TESTDIR}/TCBtools.$1.$2/$1"
-fi
-
-runfile="${cfgdir}/$1.$3"
-
-if [ ! -f "${runfile}" ]; then
- runfile="${CLM_SCRIPTDIR}/nl_files/$1.$3"
- if [ ! -f "${runfile}" ]; then
- echo "TSMtools.sh: error ${runfile} input run file not found"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 5
- fi
-fi
-
-echo "Run file type = ${3#*.}"
-if [ ${3#*.} == "runoptions" ]; then
- echo "$toolrun "`cat ${runfile}`
- cp $cfgdir/*.nc .
- if [ "$debug" != "YES" ] && [ "$compile_only" != "YES" ]; then
- $toolrun `cat ${runfile}` >> test.log 2>&1
- rc=$?
- status="PASS"
- else
- echo "Successfully created file" > test.log
- status="GEN"
- rc=0
- fi
-else
- echo "$toolrun < ${runfile}"
- if [ "$debug" != "YES" ] && [ "$compile_only" != "YES" ]; then
- $toolrun < ${runfile} >> test.log 2>&1
- rc=$?
- status="PASS"
- else
- echo "Successfully created file" > test.log
- status="GEN"
- rc=0
- fi
-fi
-
-if [ $rc -eq 0 ] && grep -ci "Successfully created " test.log > /dev/null; then
- echo "TSMtools.sh: smoke test passed"
- echo "$status" > TestStatus
-else
- echo "TSMtools.sh: error running $1, error= $rc"
- echo "TSMtools.sh: see ${CLM_TESTDIR}/${test_name}/test.log for details"
- echo "FAIL.job${JOBID}" > TestStatus
- exit 6
-fi
-
-exit 0
diff --git a/test/tools/config_files/CFGtools__ds b/test/tools/config_files/CFGtools__ds
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/tools/config_files/README b/test/tools/config_files/README
deleted file mode 100644
index bdfe5e0dd0..0000000000
--- a/test/tools/config_files/README
+++ /dev/null
@@ -1,9 +0,0 @@
-_do => debug on, omp only on
-_ds => debug on, serial mode (neither mpi nor omp)
-
-_o => debug off, omp only on
-_s => debug off, serial mode (neither mpi nor omp)
-
-tools__ds => options for tools, debug on, serial mode
-tools__do => options for tools, debug on, omp only on
-tools__o => options for tools, debug off, omp only on
diff --git a/test/tools/config_files/tools__do b/test/tools/config_files/tools__do
deleted file mode 100644
index 7f061ed65d..0000000000
--- a/test/tools/config_files/tools__do
+++ /dev/null
@@ -1 +0,0 @@
-SMP=TRUE OPT=FALSE
diff --git a/test/tools/config_files/tools__ds b/test/tools/config_files/tools__ds
deleted file mode 100644
index cf2d414b28..0000000000
--- a/test/tools/config_files/tools__ds
+++ /dev/null
@@ -1 +0,0 @@
-OPT=FALSE
diff --git a/test/tools/config_files/tools__o b/test/tools/config_files/tools__o
deleted file mode 100644
index 8821e0bc5a..0000000000
--- a/test/tools/config_files/tools__o
+++ /dev/null
@@ -1 +0,0 @@
-SMP=TRUE OPT=TRUE
diff --git a/test/tools/config_files/tools__s b/test/tools/config_files/tools__s
deleted file mode 100644
index 507973f8be..0000000000
--- a/test/tools/config_files/tools__s
+++ /dev/null
@@ -1 +0,0 @@
-OPT=TRUE
diff --git a/test/tools/gen_test_table.sh b/test/tools/gen_test_table.sh
deleted file mode 100755
index 0791ad0447..0000000000
--- a/test/tools/gen_test_table.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/sh
-#
-
-# this script, when executed in the directory containing the test-driver
-# scripts (~/test/system) will loop through the default test
-# lists for pre and post tag testing of clm and create an html file
-# (test_table.html) with the specifics of each test detailed
-
-outfile="./test_table.html"
-
-echo '' > $outfile
-echo '' >> $outfile
-echo '' >> $outfile
-echo '' >> $outfile
-echo 'CLM Testing Information Page' >> $outfile
-echo '' >> $outfile
-echo '' >> $outfile
-
-#########################################################################################
-for input_file in `ls tests_*` ; do
- echo '' >> $outfile
- echo "$input_file" >> $outfile
- echo "" >> $outfile
- echo "test# | " >> $outfile
- echo "testid | " >> $outfile
- echo "test script | " >> $outfile
- echo "arg1 | " >> $outfile
- echo "arg2 | " >> $outfile
- echo "arg3 | " >> $outfile
- echo "
" >> $outfile
-
- test_list=""
- while read input_line; do
- test_list="${test_list}${input_line} "
- done < ./${input_file}
-
- count=0
- ##loop through the tests of input file
- for test_id in ${test_list}; do
- echo "" >> $outfile
- count=`expr $count + 1`
- while [ ${#count} -lt 3 ]; do
- count="0${count}"
- done
- echo " $count | " >> $outfile
-
- master_line=`grep $test_id ./input_tests_master`
- dir=""
- for arg in ${master_line}; do
- arg1=${arg%^*}
- arg2=${arg#*^}
- if [ -d ../../tools/$arg ]; then
- dir=$arg
- elif [ -f ./nl_files/$arg ]; then
- echo "$arg | " >> $outfile
- elif [ -f ./config_files/$arg ]; then
- echo "$arg | " >> $outfile
- elif [ -f ./nl_files/$arg1 ] && [ -f ./nl_files/$arg2 ]; then
- echo "$arg1^" \
- "$arg2 | " >> $outfile
- elif [ -f ./nl_files/$arg1 ] && [ -f ./config_files/$arg2 ]; then
- echo "$arg1^" \
- "$arg2 | " >> $outfile
- elif [ -f ../../tools/$dir/$dir.$arg ]; then
- echo "$arg | " >> $outfile
- else
- echo "$arg | " >> $outfile
- fi
- done
- echo '
' >> $outfile
- done
- echo '
' >> $outfile
- echo '' >> $outfile
- echo ' ' >> $outfile
- echo '
' >> $outfile
-done
-echo '' >> $outfile
-echo '' >> $outfile
-
-exit 0
diff --git a/test/tools/get_cprnc_diffs.sh b/test/tools/get_cprnc_diffs.sh
deleted file mode 100755
index 360220cb71..0000000000
--- a/test/tools/get_cprnc_diffs.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-
-# This script extracts lines from the output of cprnc that tell us
-# which variables differ between two files
-#
-# Usage: get_cprnc_diffs filename
-
-# ----------------------------------------------------------------------
-# SET PARAMETERS HERE
-# ----------------------------------------------------------------------
-
-# maximum number of differences to extract from the cprnc output
-maxdiffs=200
-
-# ----------------------------------------------------------------------
-# LOCAL FUNCTIONS DEFINED HERE
-# ----------------------------------------------------------------------
-
-# This function gets differences for one prefix (e.g., "RMS")
-# Usage: get_diffs prefix
-# (also uses $infile and $maxdiffs from the parent script)
-function get_diffs {
- prefix=$1
- outfile=${infile}.${prefix}.$$
- grep "$prefix" $infile > $outfile
- numlines=`wc -l $outfile | awk '{print $1}'`
- if [ $numlines -gt $maxdiffs ]; then
- echo "WARNING: Too many instances of $prefix - only printing last $maxdiffs"
- tail -$maxdiffs $outfile
- else
- cat $outfile
- fi
- rm $outfile
-}
-
-# ----------------------------------------------------------------------
-# BEGIN MAIN SCRIPT
-# ----------------------------------------------------------------------
-
-# ----------------------------------------------------------------------
-# Handle command-line arguments
-# ----------------------------------------------------------------------
-
-if [[ $# -ne 1 ]]; then
- echo "Usage: get_cprnc_diffs filename"
- exit 1
-fi
-
-infile=$1
-
-# ----------------------------------------------------------------------
-# Do the processing
-# ----------------------------------------------------------------------
-
-get_diffs RMS
-get_diffs FILLDIFF
diff --git a/test/tools/input_tests_master b/test/tools/input_tests_master
deleted file mode 100644
index 7da8c19803..0000000000
--- a/test/tools/input_tests_master
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-smc#4 TSMscript_tools.sh mkprocdata_map mkprocdata_map_wrap mkprocdata_ne30_to_f19_I2000^tools__ds
-blc#4 TBLscript_tools.sh mkprocdata_map mkprocdata_map_wrap mkprocdata_ne30_to_f19_I2000^tools__ds
-
-sm0c1 TSMscript_tools.sh site_and_regional run_neon.py run_neon_OSBS
-bl0c1 TBLscript_tools.sh site_and_regional run_neon.py run_neon_OSBS
-sm0a1 TSMscript_tools.sh site_and_regional run_neon.py run_neon_YELL_PRISM
-bl0a1 TBLscript_tools.sh site_and_regional run_neon.py run_neon_YELL_PRISM
-
-smba1 TSMscript_tools.sh site_and_regional subset_data subset_data_YELL
-blba1 TBLscript_tools.sh site_and_regional subset_data subset_data_YELL
-smbb1 TSMscript_tools.sh site_and_regional subset_data subset_data_KONA
-blbb1 TBLscript_tools.sh site_and_regional subset_data subset_data_KONA
-smb81 TSMscript_tools.sh site_and_regional subset_data subset_data_US-UMB
-blb81 TBLscript_tools.sh site_and_regional subset_data subset_data_US-UMB
-smbh1 TSMscript_tools.sh site_and_regional subset_data subset_data_f09_1x1pt_townshipSD
-blbh1 TBLscript_tools.sh site_and_regional subset_data subset_data_f09_1x1pt_townshipSD
-smbd1 TSMscript_tools.sh site_and_regional subset_data subset_data_f09_58x45pt_SouthAmerica
-blbd1 TBLscript_tools.sh site_and_regional subset_data subset_data_f09_58x45pt_SouthAmerica
-smbe1 TSMscript_tools.sh site_and_regional subset_data subset_data_f09_90x288pt_1850PanTropics
-blbe1 TBLscript_tools.sh site_and_regional subset_data subset_data_f09_90x288pt_1850PanTropics
-smbf1 TSMscript_tools.sh site_and_regional subset_data subset_data_f09_37x288pt_PanBoreal
-blbf1 TBLscript_tools.sh site_and_regional subset_data subset_data_f09_37x288pt_PanBoreal
-smbg1 TSMscript_tools.sh site_and_regional subset_data subset_data_f09_4x9pt_AlaskaTananaValley
-blbg1 TBLscript_tools.sh site_and_regional subset_data subset_data_f09_4x9pt_AlaskaTananaValley
-
-sm901 TSMscript_tools.sh site_and_regional mesh_maker mesh_maker_fv09
-bl901 TBLscript_tools.sh site_and_regional mesh_maker mesh_maker_fv09
-
-smaa2 TSMscript_tools.sh site_and_regional modify_singlept_site_neon.py modify_data_YELL
-blaa2 TBLscript_tools.sh site_and_regional modify_singlept_site_neon.py modify_data_YELL
diff --git a/test/tools/nl_files/mesh_maker_fv09 b/test/tools/nl_files/mesh_maker_fv09
deleted file mode 100644
index 7de951fee1..0000000000
--- a/test/tools/nl_files/mesh_maker_fv09
+++ /dev/null
@@ -1 +0,0 @@
- --input CSMDATA/atm/datm7/domain.lnd.fv0.9x1.25_gx1v6.090309.nc --lat yc --lon xc --overwrite --mask mask --area area --verbose
diff --git a/test/tools/nl_files/mkmapdata_if10 b/test/tools/nl_files/mkmapdata_if10
deleted file mode 100644
index f726ea34e7..0000000000
--- a/test/tools/nl_files/mkmapdata_if10
+++ /dev/null
@@ -1 +0,0 @@
--r 10x15 --fast --batch
diff --git a/test/tools/nl_files/mkmapdata_ne30np4 b/test/tools/nl_files/mkmapdata_ne30np4
deleted file mode 100644
index ae435ac2bc..0000000000
--- a/test/tools/nl_files/mkmapdata_ne30np4
+++ /dev/null
@@ -1 +0,0 @@
--r ne30np4 --fast --batch
diff --git a/test/tools/nl_files/mkprocdata_ne30_to_f19_I2000 b/test/tools/nl_files/mkprocdata_ne30_to_f19_I2000
deleted file mode 100644
index af85dcf226..0000000000
--- a/test/tools/nl_files/mkprocdata_ne30_to_f19_I2000
+++ /dev/null
@@ -1 +0,0 @@
--i CSMDATA/lnd/clm2/test_mkprocdata_map/clm4054_ne30g16_I2000.clm2.h0.2000-01_c170430.nc -o ne30output_onf19grid.nc -m CSMDATA/lnd/clm2/test_mkprocdata_map/map_ne30np4_nomask_to_fv1.9x2.5_nomask_aave_da_c121107.nc -t CSMDATA/lnd/clm2/test_mkprocdata_map/clm4054_f19g16_I2000.clm2.h0.2000-01_c170430.nc -e EXEDIR
diff --git a/test/tools/nl_files/modify_data_YELL b/test/tools/nl_files/modify_data_YELL
deleted file mode 100644
index 0d180e8bf6..0000000000
--- a/test/tools/nl_files/modify_data_YELL
+++ /dev/null
@@ -1 +0,0 @@
---neon_site YELL --surf_dir CSMDATA/lnd/clm2/surfdata_esmf/NEON --out_dir EXEDIR --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/run_neon_OSBS b/test/tools/nl_files/run_neon_OSBS
deleted file mode 100644
index 0c274b13ad..0000000000
--- a/test/tools/nl_files/run_neon_OSBS
+++ /dev/null
@@ -1 +0,0 @@
---verbose --run-type ad --setup-only --neon-site OSBS
diff --git a/test/tools/nl_files/run_neon_YELL_PRISM b/test/tools/nl_files/run_neon_YELL_PRISM
deleted file mode 100644
index f5ebdf9fdf..0000000000
--- a/test/tools/nl_files/run_neon_YELL_PRISM
+++ /dev/null
@@ -1 +0,0 @@
---verbose --run-type transient --setup-only --neon-site YELL --prism --neon-version v2 --experiment toolstest
diff --git a/test/tools/nl_files/subset_data_KONA b/test/tools/nl_files/subset_data_KONA
deleted file mode 100644
index 0df59b1b17..0000000000
--- a/test/tools/nl_files/subset_data_KONA
+++ /dev/null
@@ -1 +0,0 @@
-point --lon 263.38956 --lat 39.1082 --site KONA --dompft 17 19 23 45 --pctpft 28 12 32 28 --crop --create-surface --outdir EXEDIR/KONA_user-mod_and_data --user-mods-dir EXEDIR/KONA_user-mod_and_data --verbose --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_US-UMB b/test/tools/nl_files/subset_data_US-UMB
deleted file mode 100644
index 935b0dc99d..0000000000
--- a/test/tools/nl_files/subset_data_US-UMB
+++ /dev/null
@@ -1 +0,0 @@
-point --lon 275.28626 --lat 45.5598 --site 1x1_US-UMB --dompft 7 --cap-saturation --uniform-snowpack --create-surface --outdir EXEDIR/US-UMB_user-mod_and_data --user-mods-dir EXEDIR/US-UMB_user-mod_and_data --verbose --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_YELL b/test/tools/nl_files/subset_data_YELL
deleted file mode 100644
index 0d6960e7f5..0000000000
--- a/test/tools/nl_files/subset_data_YELL
+++ /dev/null
@@ -1 +0,0 @@
-point --lon 250.45804 --lat 44.95597 --site YELL --dompft 1 --crop --uniform-snowpack --cap-saturation --create-surface --outdir EXEDIR/YELL_user-mod_and_data --user-mods-dir EXEDIR/YELL_user-mod_and_data --silent --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_f09_1x1pt_townshipSD b/test/tools/nl_files/subset_data_f09_1x1pt_townshipSD
deleted file mode 100644
index aa25c07d1e..0000000000
--- a/test/tools/nl_files/subset_data_f09_1x1pt_townshipSD
+++ /dev/null
@@ -1 +0,0 @@
-point --lon 257.5 --lat 43.822 --site f09_1x1pt_townshipSD --include-nonveg --crop --create-datm --create-user-mods --datm-syr 2000 --datm-eyr 2000 --create-surface --outdir EXEDIR/f09_US_pt_user-mod_and_data --user-mods-dir EXEDIR/f09_US_pt_user-mod_and_data --verbose --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_f09_37x288pt_PanBoreal b/test/tools/nl_files/subset_data_f09_37x288pt_PanBoreal
deleted file mode 100644
index 448b5052d6..0000000000
--- a/test/tools/nl_files/subset_data_f09_37x288pt_PanBoreal
+++ /dev/null
@@ -1 +0,0 @@
-region --lat1 55 --lat2 89.1 --lon1 0 --lon2 360 --create-mesh --create-surface --create-domain --create-user-mods --verbose --overwrite --reg f09_37x288pt_PanBoreal --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_f09_4x9pt_AlaskaTananaValley b/test/tools/nl_files/subset_data_f09_4x9pt_AlaskaTananaValley
deleted file mode 100644
index 9928d78429..0000000000
--- a/test/tools/nl_files/subset_data_f09_4x9pt_AlaskaTananaValley
+++ /dev/null
@@ -1 +0,0 @@
-region --lat1 62 --lat2 66 --lon1 -152 --lon2 -141 --create-mesh --create-domain --create-surface --create-user-mods --verbose --overwrite --reg f09_4x9pt_AlaskaTananaValley --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_f09_58x45pt_SouthAmerica b/test/tools/nl_files/subset_data_f09_58x45pt_SouthAmerica
deleted file mode 100644
index 201dd2c76c..0000000000
--- a/test/tools/nl_files/subset_data_f09_58x45pt_SouthAmerica
+++ /dev/null
@@ -1 +0,0 @@
-region --lat1 -40 --lat2 15 --lon1 275 --lon2 330 --create-mesh --create-surface --create-user-mods --create-domain --create-landuse --verbose --overwrite --reg f09_58x45_SouthAmerica --inputdata-dir CSMDATA
diff --git a/test/tools/nl_files/subset_data_f09_90x288pt_1850PanTropics b/test/tools/nl_files/subset_data_f09_90x288pt_1850PanTropics
deleted file mode 100644
index 1c9d5eace9..0000000000
--- a/test/tools/nl_files/subset_data_f09_90x288pt_1850PanTropics
+++ /dev/null
@@ -1 +0,0 @@
-region --lat1 -55 --lat2 30 --lon1 0 --lon2 360 --crop --create-surface --create-domain --create-mesh --overwrite --reg f09_90x288pt_1850PanTropics --inputdata-dir CSMDATA --cfg-file CTSM_ROOT/tools/mksurfdata_map/default_data_1850.cfg --verbose
diff --git a/test/tools/show_var_diffs.sh b/test/tools/show_var_diffs.sh
deleted file mode 100755
index f462d4ad0c..0000000000
--- a/test/tools/show_var_diffs.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-
-# This script processes a log file that was output by test_driver,
-# giving lists of all variables with differences in values (those with
-# RMS errors), and all variables with differences in fill patterns.
-#
-# This assumes that the log file contains output like:
-# RMS foo
-# RMS bar
-# FILLDIFF foo
-# FILLDIFF bar
-# Some characteristics of these output lines are:
-# - they begin with a leading space, followed by RMS or FILLDIFF
-# - the variable name is in the second column of the line
-#
-# Note that (as of 4-5-12) the log file only contains output from the
-# last file that didn't match, so this could potentially miss
-# something -- especially if there are both h0 and h1 files in the
-# comparison.
-
-# Usage: show_var_diffs logfile
-
-# ----------------------------------------------------------------------
-# LOCAL FUNCTIONS DEFINED HERE
-# ----------------------------------------------------------------------
-
-# This function shows the differences for one prefix (e.g., "RMS")
-# Usage: show_diffs prefix
-# (also uses $logfile from the parent script)
-#
-# Matches lines that start with the regular expression "^ ${prefix}"
-# (note that one leading space is expected before the prefix)
-#
-# Assumes that the variable name is in the second column of matching lines
-function show_diffs {
- prefix=$1
-
- # first determine if there were warnings relating to this prefix
- grep "WARNING: Too many instances of ${prefix}" $logfile > /dev/null
- if [ $? -eq 0 ]; then # found a warning
- echo "WARNING: Some output was truncated; this may not be a complete list"
- fi
-
- # now make a list of all variables matching this prefix
- grep "^ ${prefix}" $logfile > $logfile.tmp.$$
- if [ $? -eq 0 ]; then
- awk '{print $2}' $logfile.tmp.$$ | sort | uniq
- else
- echo "(no differences)"
- fi
-
- rm $logfile.tmp.$$
-}
-
-# ----------------------------------------------------------------------
-# BEGIN MAIN SCRIPT
-# ----------------------------------------------------------------------
-
-# ----------------------------------------------------------------------
-# Handle command-line arguments
-# ----------------------------------------------------------------------
-
-if [[ $# -ne 1 ]]; then
- echo "Usage: show_var_diffs logfile"
- exit 1
-fi
-
-logfile=$1
-
-# ----------------------------------------------------------------------
-# Do the processing
-# ----------------------------------------------------------------------
-
-echo "Variables with differences in values:"
-show_diffs "RMS"
-
-echo ""
-echo "Variables with differences in fill patterns:"
-show_diffs "FILLDIFF"
\ No newline at end of file
diff --git a/test/tools/test_driver.sh b/test/tools/test_driver.sh
deleted file mode 100755
index f93301a530..0000000000
--- a/test/tools/test_driver.sh
+++ /dev/null
@@ -1,722 +0,0 @@
-#!/bin/sh
-#
-# test_driver.sh: driver script for the offline testing of CLM of tools
-#
-# interactive usage on all machines:
-#
-# env ./test_driver.sh -i
-#
-# valid arguments:
-# -i interactive usage
-# -d debug usage -- display tests that will run -- but do NOT actually execute them
-# -f force batch submission (avoids user prompt)
-# -h displays this help message
-#
-#
-# **pass environment variables by preceding above commands
-# with 'env var1=setting var2=setting '
-# **more details in the CLM testing user's guide, accessible
-# from the CLM developers web page
-
-
-#will attach timestamp onto end of script name to prevent overwriting
-cur_time=`date '+%H:%M:%S'`
-
-hostname=`hostname`
-echo $hostname
-case $hostname in
-
- ##Derecho
- derecho* | dec*)
- submit_script="test_driver_derecho${cur_time}.sh"
-
-##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-cat > ./${submit_script} << EOF
-#!/bin/sh
-#
-
-interactive="YES"
-input_file="tests_pretag_derecho_nompi"
-c_threads=128
-
-export INITMODULES="/glade/u/apps/derecho/23.06/spack/opt/spack/lmod/8.7.20/gcc/7.5.0/pdxb/lmod/lmod/init/sh"
-. \$INITMODULES
-
-module --force purge
-module load ncarenv
-module load craype
-module load intel
-module load mkl
-module load ncarcompilers
-module load netcdf
-module load nco
-module load ncl
-
-#omp threads
-if [ -z "\$CLM_THREADS" ]; then #threads NOT set on command line
- export CLM_THREADS=\$c_threads
-fi
-
-# Stop on first failed test
-if [ -z "\$CLM_SOFF" ]; then #CLM_SOFF NOT set
- export CLM_SOFF=FALSE
-fi
-
-export CESM_MACH="derecho"
-export CESM_COMP="intel"
-
-export NETCDF_DIR=\$NETCDF
-export INC_NETCDF=\$NETCDF/include
-export LIB_NETCDF=\$NETCDF/lib
-export MAKE_CMD="gmake -j "
-export CFG_STRING=""
-export TOOLS_MAKE_STRING="USER_FC=ifort USER_LINKER=ifort USER_CPPDEFS=-DLINUX"
-export MACH_WORKSPACE=\$SCRATCH
-export CPRNC_EXE="$CESMDATAROOT/cprnc/cprnc"
-dataroot="$CESMDATAROOT/inputdata"
-export TOOLSLIBS=""
-export REGRID_PROC=1
-export TOOLS_CONF_STRING="--mpilib mpi-serial"
-
-
-echo_arg=""
-
-EOF
-#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
- ;;
-
- ##cheyenne
- cheyenne* | r*i*n*)
- submit_script="test_driver_cheyenne${cur_time}.sh"
-
-#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-at > ./${submit_script} << EOF
-!/bin/sh
-
-
-interactive="YES"
-input_file="tests_pretag_cheyenne_nompi"
-c_threads=36
-
-
-export INITMODULES="/glade/u/apps/ch/opt/lmod/8.1.7/lmod/lmod/init/sh"
-. \$INITMODULES
-
-module purge
-module load ncarenv
-module load intel
-module load mkl
-module load ncarcompilers
-module load netcdf
-
-module load nco
-module load ncl
-
-module load conda
-
-
-##omp threads
-if [ -z "\$CLM_THREADS" ]; then #threads NOT set on command line
- export CLM_THREADS=\$c_threads
-fi
-
-# Stop on first failed test
-if [ -z "\$CLM_SOFF" ]; then #CLM_SOFF NOT set
- export CLM_SOFF=FALSE
-fi
-
-export CESM_MACH="cheyenne"
-export CESM_COMP="intel"
-
-export NETCDF_DIR=\$NETCDF
-export INC_NETCDF=\$NETCDF/include
-export LIB_NETCDF=\$NETCDF/lib
-export MAKE_CMD="gmake -j "
-export CFG_STRING=""
-export TOOLS_MAKE_STRING="USER_FC=ifort USER_LINKER=ifort USER_CPPDEFS=-DLINUX"
-export MACH_WORKSPACE="/glade/scratch"
-export CPRNC_EXE="$CESMDATAROOT/tools/cime/tools/cprnc/cprnc.cheyenne"
-dataroot="$CESMDATAROOT"
-export TOOLSLIBS=""
-export REGRID_PROC=1
-export TOOLS_CONF_STRING="--mpilib mpi-serial"
-
-
-echo_arg=""
-
-EOF
-##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
- ;;
-
- ## DAV cluster
- casper* | pronghorn*)
- submit_script="test_driver_dav${cur_time}.sh"
-
-##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-cat > ./${submit_script} << EOF
-#!/bin/sh
-#
-
-interactive="YES"
-input_file="tests_posttag_dav_mpi"
-c_threads=36
-
-
-export INITMODULES="/glade/u/apps/ch/opt/lmod/8.1.7/lmod/lmod/init/sh"
-. \$INITMODULES
-
-module purge
-module load ncarenv
-module load intel
-module load mkl
-module load ncarcompilers
-module load netcdf
-module load openmpi
-
-module load nco
-module load conda
-module load ncl
-
-
-##omp threads
-if [ -z "\$CLM_THREADS" ]; then #threads NOT set on command line
- export CLM_THREADS=\$c_threads
-fi
-
-# Stop on first failed test
-if [ -z "\$CLM_SOFF" ]; then #CLM_SOFF NOT set
- export CLM_SOFF=FALSE
-fi
-
-export CESM_MACH="cheyenne"
-export CESM_COMP="intel"
-
-export NETCDF_DIR=\$NETCDF
-export INC_NETCDF=\$NETCDF/include
-export LIB_NETCDF=\$NETCDF/lib
-export MAKE_CMD="gmake -j "
-export CFG_STRING=""
-export TOOLS_MAKE_STRING="USER_FC=ifort USER_LINKER=ifort USER_CPPDEFS=-DLINUX"
-export MACH_WORKSPACE="/glade/scratch"
-export CPRNC_EXE="$CESMDATAROOT/tools/cime/tools/cprnc/cprnc.cheyenne"
-dataroot="$CESMDATAROOT"
-export TOOLSLIBS=""
-export TOOLS_CONF_STRING="--mpilib mpich"
-
-
-echo_arg=""
-
-EOF
-##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
- ;;
-
- ## hobart
- hobart* | h*.cgd.ucar.edu)
- submit_script="test_driver_hobart_${cur_time}.sh"
- export PATH=/cluster/torque/bin:${PATH}
-
-##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-cat > ./${submit_script} << EOF
-#!/bin/sh
-#
-
-# Name of the queue (CHANGE THIS if needed)
-#PBS -q long
-# Number of nodes (CHANGE THIS if needed)
-#PBS -l nodes=1:ppn=24
-# output file base name
-#PBS -N test_dr
-# Put standard error and standard out in same file
-#PBS -j oe
-# Export all Environment variables
-#PBS -V
-# End of options
-
-if [ -n "\$PBS_JOBID" ]; then #batch job
- export JOBID=\`echo \${PBS_JOBID} | cut -f1 -d'.'\`
- initdir=\${PBS_O_WORKDIR}
-fi
-
-if [ "\$PBS_ENVIRONMENT" = "PBS_BATCH" ]; then
- interactive="NO"
- input_file="tests_posttag_hobart"
-else
- interactive="YES"
- input_file="tests_posttag_hobart_nompi"
-fi
-
-##omp threads
-if [ -z "\$CLM_THREADS" ]; then #threads NOT set on command line
- export CLM_THREADS=2
-fi
-export CLM_RESTART_THREADS=1
-
-##mpi tasks
-export CLM_TASKS=24
-export CLM_RESTART_TASKS=20
-
-export P4_GLOBMEMSIZE=500000000
-
-
-export CESM_MACH="hobart"
-
-ulimit -s unlimited
-ulimit -c unlimited
-
-export CESM_COMP="intel"
-export TOOLS_MAKE_STRING="USER_FC=ifort USER_CC=icc "
-export TOOLS_CONF_STRING=" -mpilib mpi-serial"
-export CFG_STRING=""
-export INITMODULES="/usr/share/Modules/init/sh"
-
-. \$INITMODULES
-module purge
-module load compiler/intel
-module load tool/nco
-module load tool/netcdf
-module load lang/python
-
-export NETCDF_DIR=\$NETCDF_PATH
-export INC_NETCDF=\${NETCDF_PATH}/include
-export LIB_NETCDF=\${NETCDF_PATH}/lib
-export MAKE_CMD="gmake -j 5" ##using hyper-threading on hobart
-export MACH_WORKSPACE="/scratch/cluster"
-export CPRNC_EXE=/fs/cgd/csm/tools/cprnc/cprnc
-export DATM_QIAN_DATA_DIR="/project/tss/atm_forcing.datm7.Qian.T62.c080727"
-dataroot="/fs/cgd/csm"
-export TOOLSSLIBS=""
-echo_arg="-e"
-
-EOF
-##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
- ;;
-
- ## izumi
- izumi* | i*.unified.ucar.edu)
- submit_script="test_driver_izumi_${cur_time}.sh"
- export PATH=/cluster/torque/bin:${PATH}
-
-##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-cat > ./${submit_script} << EOF
-#!/bin/sh
-#
-
-# Name of the queue (CHANGE THIS if needed)
-#PBS -q long
-# Number of nodes (CHANGE THIS if needed)
-#PBS -l nodes=1:ppn=24
-# output file base name
-#PBS -N test_dr
-# Put standard error and standard out in same file
-#PBS -j oe
-# Export all Environment variables
-#PBS -V
-# End of options
-
-if [ -n "\$PBS_JOBID" ]; then #batch job
- export JOBID=\`echo \${PBS_JOBID} | cut -f1 -d'.'\`
- initdir=\${PBS_O_WORKDIR}
-fi
-
-if [ "\$PBS_ENVIRONMENT" = "PBS_BATCH" ]; then
- interactive="NO"
- input_file="tests_posttag_izumi"
-else
- interactive="YES"
- input_file="tests_posttag_izumi_nompi"
-fi
-
-##omp threads
-if [ -z "\$CLM_THREADS" ]; then #threads NOT set on command line
- export CLM_THREADS=2
-fi
-export CLM_RESTART_THREADS=1
-
-##mpi tasks
-export CLM_TASKS=24
-export CLM_RESTART_TASKS=20
-
-export P4_GLOBMEMSIZE=500000000
-
-
-export CESM_MACH="izumi"
-
-ulimit -s unlimited
-ulimit -c unlimited
-
-export CESM_COMP="intel"
-export TOOLS_MAKE_STRING="USER_FC=ifort USER_CC=icc "
-export TOOLS_CONF_STRING=" -mpilib mpi-serial"
-export CFG_STRING=""
-export INITMODULES="/usr/share/Modules/init/sh"
-
-. \$INITMODULES
-module purge
-module load compiler/intel
-module load tool/nco
-module load tool/netcdf
-module load lang/python
-
-export NETCDF_DIR=\$NETCDF_PATH
-export INC_NETCDF=\${NETCDF_PATH}/include
-export LIB_NETCDF=\${NETCDF_PATH}/lib
-export MAKE_CMD="gmake -j 5" ##using hyper-threading on izumi
-export MACH_WORKSPACE="/scratch/cluster"
-export CPRNC_EXE=/fs/cgd/csm/tools/cprnc/cprnc.izumi
-export DATM_QIAN_DATA_DIR="/project/tss/atm_forcing.datm7.Qian.T62.c080727"
-dataroot="/fs/cgd/csm"
-export TOOLSSLIBS=""
-echo_arg="-e"
-
-EOF
-##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
- ;;
-
- * )
- echo "Only setup to work on: derecho, cheyenne, hobart and izumi"
- exit
-
-
-esac
-
-##vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv writing to batch script vvvvvvvvvvvvvvvvvvv
-cat >> ./${submit_script} << EOF
-
-export CPRNC_OPT=""
-if [ -n "\${CLM_JOBID}" ]; then
- export JOBID=\${CLM_JOBID}
-fi
-##check if interactive job
-
-if [ "\$interactive" = "YES" ]; then
-
- if [ -z "\${JOBID}" ]; then
- export JOBID=\$\$
- fi
- echo "test_driver.sh: interactive run - setting JOBID to \$JOBID"
- if [ \$0 = "test_driver.sh" ]; then
- initdir="."
- else
- initdir=\${0%/*}
- fi
-else
- echo "ERROR: you *always* need to use the interactive option (-i)"
- echo " currently doesn't work without it"
- exit 3
-fi
-
-##establish script dir and clm_root
-if [ -f \${initdir}/test_driver.sh ]; then
- export CLM_SCRIPTDIR=\`cd \${initdir}; pwd \`
- export CLM_ROOT=\`cd \${CLM_SCRIPTDIR}/../..; pwd \`
- export CTSM_ROOT=\${CLM_ROOT}
- if [ -d \${CLM_ROOT}/cime ]; then
- export CIME_ROOT=\${CLM_ROOT}/cime
- else
- export CIME_ROOT=\${CLM_ROOT}/../../cime
- fi
- if [ ! -d \${CIME_ROOT} ]; then
- echo "ERROR: trouble finding the CIME_ROOT directory: \$CIME_ROOT"
- exit 3
- fi
-else
- if [ -n "\${CLM_ROOT}" ] && [ -f \${CLM_ROOT}/test/tools/test_driver.sh ]; then
- export CLM_SCRIPTDIR=\`cd \${CLM_ROOT}/test/tools; pwd \`
- else
- echo "ERROR: unable to determine script directory "
- echo " if initiating batch job from directory other than the one containing test_driver.sh, "
- echo " you must set the environment variable CLM_ROOT to the full path of directory containing "
- echo " . "
- exit 3
- fi
-fi
-
-# Setup conda environment
-conda activate ctsm_pylib
-if [ \$? -ne 0 ]; then
- echo "ERROR: Trouble activating the ctsm_pylib conda environment, be sure it's setup with \$CLM_ROOT/py_env_create, then rerun"
- exit 4
-fi
-
-##output files
-clm_log=\${initdir}/td.\${JOBID}.log
-if [ -f \$clm_log ]; then
- rm \$clm_log
-fi
-clm_status=\${initdir}/td.\${JOBID}.status
-if [ -f \$clm_status ]; then
- rm \$clm_status
-fi
-
-##setup test work directory
-if [ -z "\$CLM_TESTDIR" ]; then
- export CLM_TESTDIR=\${MACH_WORKSPACE}/\$LOGNAME/clmTests/test-driver.\${JOBID}
- if [ -d \$CLM_TESTDIR ] && [ \$CLM_RETAIN_FILES != "TRUE" ]; then
- rm -r \$CLM_TESTDIR
- fi
-fi
-if [ ! -d \$CLM_TESTDIR ]; then
- mkdir -p \$CLM_TESTDIR
- if [ \$? -ne 0 ]; then
- echo "ERROR: unable to create work directory \$CLM_TESTDIR"
- exit 4
- fi
-fi
-
-## MCT and PIO build directorys
-export MCT_LIBDIR=\$CLM_TESTDIR/mct
-export PIO_LIBDIR=\$CLM_TESTDIR/pio
-
-##set our own environment vars
-export CSMDATA=\${dataroot}/inputdata
-export DIN_LOC_ROOT=\${CSMDATA}
-export MPI_TYPE_MAX=100000
-
-##process other env vars possibly coming in
-if [ -z "\$CLM_RETAIN_FILES" ]; then
- export CLM_RETAIN_FILES=FALSE
-fi
-if [ -n "\${CLM_INPUT_TESTS}" ]; then
- input_file=\$CLM_INPUT_TESTS
-else
- input_file=\${CLM_SCRIPTDIR}/\${input_file}
-fi
-if [ ! -f \${input_file} ]; then
- echo "ERROR: unable to locate input file \${input_file}"
- exit 5
-fi
-
-if [ \$interactive = "YES" ]; then
- echo "reading tests from \${input_file}"
-else
- echo "reading tests from \${input_file}" >> \${clm_log}
-fi
-
-num_tests=\`wc -w < \${input_file}\`
-echo "STATUS OF CLM TESTING UNDER JOB \${JOBID}; scheduled to run \$num_tests tests from:" >> \${clm_status}
-echo "\$input_file" >> \${clm_status}
-echo "" >> \${clm_status}
-echo " on machine: $hostname" >> \${clm_status}
-if [ -n "${BL_ROOT}" ]; then
- echo "tests of baseline will use source code from:" >> \${clm_status}
- echo "\$BL_ROOT" >> \${clm_status}
-fi
-if [ \$interactive = "NO" ]; then
- echo "see \${clm_log} for more detailed output" >> \${clm_status}
-fi
-echo "" >> \${clm_status}
-
-test_list=""
-while read input_line; do
- test_list="\${test_list}\${input_line} "
-done < \${input_file}
-
-
-##initialize flags, counter
-skipped_tests="NO"
-pending_tests="NO"
-count=0
-
-##loop through the tests of input file
-for test_id in \${test_list}; do
- count=\`expr \$count + 1\`
- while [ \${#count} -lt 3 ]; do
- count="0\${count}"
- done
-
- master_line=\`grep \$test_id \${CLM_SCRIPTDIR}/input_tests_master\`
- status_out=""
- for arg in \${master_line}; do
- status_out="\${status_out}\${arg} "
- done
-
- if [ -z "\$status_out" ]; then
- echo "No test matches \$test_id in \${CLM_SCRIPTDIR}/input_tests_master"
- exit 3
- fi
-
- test_cmd=\${status_out#* }
-
- status_out="\${count} \${status_out}"
-
- if [ \$interactive = "YES" ]; then
- echo ""
- echo "***********************************************************************************"
- echo "\${status_out}"
- echo "***********************************************************************************"
- else
- echo "" >> \${clm_log}
- echo "***********************************************************************************"\
- >> \${clm_log}
- echo "\$status_out" >> \${clm_log}
- echo "***********************************************************************************"\
- >> \${clm_log}
- fi
-
- if [ \${#status_out} -gt 94 ]; then
- status_out=\`echo "\${status_out}" | cut -c1-100\`
- fi
- while [ \${#status_out} -lt 97 ]; do
- status_out="\${status_out}."
- done
-
- echo \$echo_arg "\$status_out\c" >> \${clm_status}
-
- if [ \$interactive = "YES" ]; then
- \${CLM_SCRIPTDIR}/\${test_cmd}
- rc=\$?
- else
- \${CLM_SCRIPTDIR}/\${test_cmd} >> \${clm_log} 2>&1
- rc=\$?
- fi
- if [ \$rc -eq 0 ]; then
- echo "PASS" >> \${clm_status}
- elif [ \$rc -eq 255 ]; then
- echo "SKIPPED*" >> \${clm_status}
- skipped_tests="YES"
- elif [ \$rc -eq 254 ]; then
- echo "PENDING**" >> \${clm_status}
- pending_tests="YES"
- else
- echo " rc=\$rc FAIL" >> \${clm_status}
- if [ "\$CLM_SOFF" = "TRUE" ]; then
- echo "stopping on first failure" >> \${clm_status}
- echo "stopping on first failure" >> \${clm_log}
- exit 6
- fi
- fi
-done
-
-echo "end of input" >> \${clm_status}
-if [ \$interactive = "YES" ]; then
- echo "end of input"
-else
- echo "end of input" >> \${clm_log}
-fi
-
-if [ \$skipped_tests = "YES" ]; then
- echo "* please verify that any skipped tests are not required of your clm commit" >> \${clm_status}
-fi
-if [ \$pending_tests = "YES" ]; then
- echo "** tests that are pending must be checked manually for a successful completion" >> \${clm_status}
- if [ \$interactive = "NO" ]; then
- echo " see the test's output in \${clm_log} " >> \${clm_status}
- echo " for the location of test results" >> \${clm_status}
- fi
-fi
-
-if [ "\$interactive" = "YES" ]; then
- passInt="test_driver.sh-i"
-else
- passInt="test_driver.sh"
-fi
-
-../../bld/unit_testers/xFail/wrapClmTests.pl -statusFile "\${clm_status}" -numberOfTests "\${num_tests}" -callingScript "\${passInt}"
-
-exit 0
-
-EOF
-##^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to batch script ^^^^^^^^^^^^^^^^^^^
-
-
-chmod a+x $submit_script
-if [ ! -z "$CLM_RETAIN_FILES" ]; then
- export CLM_RETAIN_FILES="FALSE"
-fi
-arg1=${1##*-}
-case $arg1 in
- [iI]* )
- debug="NO"
- interactive="YES"
- compile_only="NO"
- export debug
- export interactive
- export compile_only
- ./${submit_script}
- exit 0
- ;;
-
- [cC]* )
- debug="NO"
- interactive="YES"
- compile_only="YES"
- export debug
- export CLM_RETAIN_FILES="TRUE"
- export interactive
- export compile_only
- export CLM_RETAIN_FILES="TRUE"
- ./${submit_script}
- exit 0
- ;;
-
- [dD]* )
- debug="YES"
- interactive="YES"
- compile_only="NO"
- export debug
- export interactive
- export compile_only
- ./${submit_script}
- exit 0
- ;;
-
- [fF]* )
- debug="NO"
- interactive="NO"
- compile_only="NO"
- export debug
- export interactive
- export compile_only
- ;;
-
- "" )
- echo ""
- echo "**********************"
- echo "$submit_script has been created and will be submitted to the batch queue..."
- echo "(ret) to continue, (a) to abort"
- read ans
- case $ans in
- [aA]* )
- echo "aborting...type ./test_driver.sh -h for help message"
- exit 0
- ;;
- esac
- debug="NO"
- interactive="NO"
- compile_only="NO"
- export debug
- export interactive
- export compile_only
- ;;
-
- * )
- echo ""
- echo "**********************"
- echo "usage on derecho, cheyenne, hobart, and izumi: "
- echo "./test_driver.sh -i"
- echo ""
- echo "valid arguments: "
- echo "-i interactive usage"
- echo "-c compile-only usage (run configure and compile do not run clm)"
- echo "-d debug-only usage (run configure and build-namelist do NOT compile or run clm)"
- echo "-f force batch submission (avoids user prompt)"
- echo "-h displays this help message"
- echo ""
- echo "**pass environment variables by preceding above commands "
- echo " with 'env var1=setting var2=setting '"
- echo ""
- echo "**********************"
- exit 0
- ;;
-esac
-
-echo "submitting..."
-case $hostname in
- #default
- * )
- echo "no submission capability on this machine use the interactive option: -i"
- exit 0
- ;;
-
-esac
-exit 0
diff --git a/test/tools/tests_posttag_hobart_nompi b/test/tools/tests_posttag_hobart_nompi
deleted file mode 100644
index c185428868..0000000000
--- a/test/tools/tests_posttag_hobart_nompi
+++ /dev/null
@@ -1 +0,0 @@
-smc#4 blc#4
diff --git a/test/tools/tests_posttag_nompi_regression b/test/tools/tests_posttag_nompi_regression
deleted file mode 100644
index c185428868..0000000000
--- a/test/tools/tests_posttag_nompi_regression
+++ /dev/null
@@ -1 +0,0 @@
-smc#4 blc#4
diff --git a/test/tools/tests_pretag_cheyenne_nompi b/test/tools/tests_pretag_cheyenne_nompi
deleted file mode 100644
index e92ffaaaad..0000000000
--- a/test/tools/tests_pretag_cheyenne_nompi
+++ /dev/null
@@ -1,3 +0,0 @@
-smc#4 blc#4
-smba1 blba1
-smbd1 blbd1
diff --git a/test/tools/tests_pretag_derecho_nompi b/test/tools/tests_pretag_derecho_nompi
deleted file mode 100644
index 5fdaf335ae..0000000000
--- a/test/tools/tests_pretag_derecho_nompi
+++ /dev/null
@@ -1,9 +0,0 @@
-smba1 blba1
-smbd1 blbd1
-sm0a1 bl0a1
-sm0c1 bl0c1
-smaa2 blaa2
-smba1 blba1
-smb81 blb81
-smbc1 blbc1
-smbd1 blbd1
diff --git a/test/tools/tests_pretag_nompi_neon b/test/tools/tests_pretag_nompi_neon
deleted file mode 100644
index e5fa27e6c4..0000000000
--- a/test/tools/tests_pretag_nompi_neon
+++ /dev/null
@@ -1,8 +0,0 @@
-sm0a1 bl0a1
-sm0c1 bl0c1
-smaa2 blaa2
-smba1 blba1
-smbb1 blbb1
-smb81 blb81
-smbc1 blbc1
-smbd1 blbd1
diff --git a/tools/mksurfdata_esmf/README.md b/tools/mksurfdata_esmf/README.md
index 11cb69c681..a9c0b80de6 100644
--- a/tools/mksurfdata_esmf/README.md
+++ b/tools/mksurfdata_esmf/README.md
@@ -41,7 +41,7 @@ In addition for the build: python, bash-shell, CMake and GNU-Make are required
These libraries need to be built such that they can all work together in the
same executable. Hence, the above order may be required in building them.
-CTSM externals that are required are: cime and ccs_config. See [Building](#building-the-executable) on getting
+CTSM submodules that are required are: cime and ccs_config. See [Building](#building-the-executable) on getting
those. A python environment that includes particular packages is also required
we demonstrate how to use the ctsm_pylib environment that we support in CTSM.
@@ -93,7 +93,7 @@ https://github.com/ESCOMP/CTSM/issues/2341
``` shell
# Assuming pwd is the tools/mksurfdata_esmf directory
- ./manage_externals/checkout_externals # Assuming at the top level of the CTSM/CESM checkout
+ ./bin/git-fleximod update # Assuming at the top level of the CTSM/CESM checkout
```
This will bring in CIME and ccs_config which are required for building.