Repository: ESMCI/cime

Issue:
CHARGE_ACCOUNT no longer allows for sub-projects
When using the `-p/--project` option in CIME, it is assumed that the name of the account to charge for compute time and the project directory are the same. However, on machines like Titan and Summit, time often needs to be charged to a subproject like `cli106ice`, but the project directory doesn't reflect the subproject name (`/lustre/atlas/proj-shared/cli106ice/` is not a valid path, and instead should be `/lustre/atlas/proj-shared/cli106/`). This is discussed in issue E3SM-Project/E3SM#1588

PR E3SM-Project/E3SM#1718 added an optional `CHARGE_ACCOUNT` which allow for charging sub-projects while using the `PROJECT` name for directory paths. 

However, issue ESMCI/cime#2676 thought that `CHARGE_ACCOUNT` and `PROJECT` should always be the same, and PR ESMCI/cime#2763 removed the ability to use subprojects. 

Because Summit will be a supported machine, and Titan is a machine currently used,  ESMCI/cime#2763 should be reverted. 

@billsacks , @sarich 


Discussion:

Resolving patch:
diff --git a/scripts/lib/CIME/case/case.py b/scripts/lib/CIME/case/case.py
--- a/scripts/lib/CIME/case/case.py
+++ b/scripts/lib/CIME/case/case.py
@@ -885,19 +885,16 @@ def configure(self, compset_name, grid_name, machine_name=None,
         self.set_value("REALUSER", os.environ["USER"])
 
         # Set project id
+        if project is None:
+            project = get_project(machobj)
         if project is not None:
             self.set_value("PROJECT", project)
-            self.set_value("CHARGE_ACCOUNT", project)
-        else:
-            project = get_project(machobj)
-            if project is not None:
-                self.set_value("PROJECT", project)
-            elif machobj.get_value("PROJECT_REQUIRED"):
-                expect(project is not None, "PROJECT_REQUIRED is true but no project found")
-            # Get charge_account id if it exists
-            charge_account = get_charge_account(machobj)
-            if charge_account is not None:
-                self.set_value("CHARGE_ACCOUNT", charge_account)
+        elif machobj.get_value("PROJECT_REQUIRED"):
+            expect(project is not None, "PROJECT_REQUIRED is true but no project found")
+        # Get charge_account id if it exists
+        charge_account = get_charge_account(machobj, project)
+        if charge_account is not None:
+            self.set_value("CHARGE_ACCOUNT", charge_account)
 
         # Resolve the CIME_OUTPUT_ROOT variable, other than this
         # we don't want to resolve variables until we need them
diff --git a/scripts/lib/CIME/utils.py b/scripts/lib/CIME/utils.py
--- a/scripts/lib/CIME/utils.py
+++ b/scripts/lib/CIME/utils.py
@@ -936,7 +936,7 @@ def get_project(machobj=None):
     logger.info("No project info available")
     return None
 
-def get_charge_account(machobj=None):
+def get_charge_account(machobj=None, project=None):
     """
     Hierarchy for choosing CHARGE_ACCOUNT:
     1. Environment variable CHARGE_ACCOUNT
@@ -948,11 +948,11 @@ def get_charge_account(machobj=None):
     >>> import CIME.XML.machines
     >>> machobj = CIME.XML.machines.Machines(machine="theta")
     >>> project = get_project(machobj)
-    >>> charge_account = get_charge_account(machobj)
+    >>> charge_account = get_charge_account(machobj, project)
     >>> project == charge_account
     True
     >>> os.environ["CHARGE_ACCOUNT"] = "ChargeAccount"
-    >>> get_charge_account(machobj)
+    >>> get_charge_account(machobj, project)
     'ChargeAccount'
     >>> del os.environ["CHARGE_ACCOUNT"]
     """
@@ -975,7 +975,7 @@ def get_charge_account(machobj=None):
             return charge_account
 
     logger.info("No charge_account info available, using value from PROJECT")
-    return get_project(machobj)
+    return project
 
 def find_files(rootdir, pattern):
     """


Test patch:
diff --git a/scripts/create_test b/scripts/create_test
--- a/scripts/create_test
+++ b/scripts/create_test
@@ -183,8 +183,9 @@ def parse_command_line(args, description):
 
     parser.add_argument("-p", "--project",
                         help="Specify a project id for the case (optional)."
-                        "\nUsed for accounting when on a batch system."
-                        "\nThe default is user-specified environment variable PROJECT")
+                        "\nUsed for accounting and directory permissions when on a batch system."
+                        "\nThe default is user or machine specified by PROJECT."
+                        "\nAccounting (only) may be overridden by user or machine specified CHARGE_ACCOUNT.")
 
     parser.add_argument("-t", "--test-id",
                         help="Specify an 'id' for the test. This is simply a string that is appended "