<workflowRun _class='org.jenkinsci.plugins.workflow.job.WorkflowRun'><action _class='hudson.model.CauseAction'><cause _class='hudson.triggers.SCMTrigger$SCMTriggerCause'><shortDescription>Started by an SCM change</shortDescription></cause></action><action></action><action _class='jenkins.metrics.impl.TimeInQueueAction'><blockedDurationMillis>0</blockedDurationMillis><blockedTimeMillis>0</blockedTimeMillis><buildableDurationMillis>0</buildableDurationMillis><buildableTimeMillis>0</buildableTimeMillis><buildingDurationMillis>3487899</buildingDurationMillis><executingTimeMillis>3486190</executingTimeMillis><executorUtilization>1.0</executorUtilization><subTaskCount>1</subTaskCount><waitingDurationMillis>5187</waitingDurationMillis><waitingTimeMillis>5187</waitingTimeMillis></action><action _class='org.jenkinsci.plugins.workflow.libs.LibrariesAction'></action><action></action><action></action><action _class='hudson.plugins.git.util.BuildData'><buildsByBranchName><refsremotesoriginmaster _class='hudson.plugins.git.util.Build'><buildNumber>258</buildNumber><marked><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><branch><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><name>refs/remotes/origin/master</name></branch></marked><revision><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><branch><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><name>refs/remotes/origin/master</name></branch></revision></refsremotesoriginmaster></buildsByBranchName><lastBuiltRevision><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><branch><SHA1>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</SHA1><name>refs/remotes/origin/master</name></branch></lastBuiltRevision><remoteUrl>https://github.com/larson-group/clubb.git</remoteUrl><scmName></scmName></action><action></action><action _class='org.jenkinsci.plugins.workflow.cps.EnvActionImpl'></action><action></action><action></action><action></action><action></action><action></action><action></action><action _class='org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction'></action><action _class='org.jenkinsci.plugins.pipeline.modeldefinition.actions.RestartDeclarativePipelineAction'></action><action></action><action _class='org.jenkinsci.plugins.workflow.job.views.FlowGraphAction'></action><action></action><action></action><action></action><building>false</building><displayName>#258</displayName><duration>3487899</duration><estimatedDuration>4068209</estimatedDuration><fullDisplayName>clubb_BFB_multi_col_gpu_nvhpc_test #258</fullDisplayName><id>258</id><keepLog>false</keepLog><number>258</number><queueId>10390</queueId><result>SUCCESS</result><timestamp>1791879366531</timestamp><url>http://carson.math.uwm.edu/jenkins/view/all/job/clubb_BFB_multi_col_gpu_nvhpc_test/258/</url><changeSet _class='hudson.plugins.git.GitChangeSetList'><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>LLM_prompts/SHORTCUTS.md</affectedPath><affectedPath>.agents/skills/clubb-change-messages/SKILL.md</affectedPath><affectedPath>AGENTS.md</affectedPath><affectedPath>LLM_prompts/change_messages.md</affectedPath><commitId>fc9087d1a7a4a8f71c74f5763ece34f18328d200</commitId><timestamp>1791830025000</timestamp><author><absoluteUrl>http://carson.math.uwm.edu/jenkins/user/noreply</absoluteUrl><fullName>noreply</fullName></author><authorEmail>noreply@github.com</authorEmail><comment>Add CLUBB commit and PR writing guidance (#1391)

* Add CLUBB commit and PR writing guidance

Add a canonical workflow and historical examples for writing specific titles
and explaining purpose, motivation, results and testing. Scope BFB claims to
their comparisons and distinguish tolerance matches from bitwise equality.
A thin repo skill, shortcut and AGENTS link make the workflow discoverable.

This addresses generated messages that bury the reason for a change or
overstate what testing establishes. Six historical PR/commit drafting pairs
passed independent review. Skill format, 20 local links, canonical-text
consistency and git diff --check passed. BFB is not applicable to these
documentation-only changes.

* Keep only the final commit and PR writing workflow

Remove the worked historical examples and their references. The repository
should contain the final reusable guidance; the research and evaluation
artifacts stay outside it. The shortcut and repo skill still point to one
canonical workflow.

Skill-format validation, all 19 local guidance links and git diff --check
passed. BFB is not applicable to these documentation-only changes.
</comment><date>2026-10-12 13:33:45 -0500</date><id>fc9087d1a7a4a8f71c74f5763ece34f18328d200</id><msg>Add CLUBB commit and PR writing guidance (#1391)</msg><path><editType>edit</editType><file>LLM_prompts/SHORTCUTS.md</file></path><path><editType>add</editType><file>LLM_prompts/change_messages.md</file></path><path><editType>add</editType><file>.agents/skills/clubb-change-messages/SKILL.md</file></path><path><editType>edit</editType><file>AGENTS.md</file></path></item><item _class='hudson.plugins.git.GitChangeSet'><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_advance_core_subs.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_xp2_xpyp.py</affectedPath><affectedPath>clubb_jax/src/Benchmark_cases/cobra.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_wp2_wp3.py</affectedPath><affectedPath>clubb_python_api/clubb_python/prescribe_forcings.py</affectedPath><affectedPath>clubb_jax/src/CLUBB_core/advance_windm_edsclrm_module.py</affectedPath><affectedPath>src/Benchmark_cases/time_dependent_input.F90</affectedPath><affectedPath>clubb_python_api/clubb_python/CLUBB_core/parameters_tunable.py</affectedPath><affectedPath>clubb_python_api/clubb_python/CLUBB_core/numerical_check.py</affectedPath><affectedPath>src/CLUBB_core/advance_windm_edsclrm_module.F90</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_driver_lifecycle.py</affectedPath><affectedPath>clubb_python_driver/advance_clubb_core.py</affectedPath><affectedPath>clubb_jax/src/Benchmark_cases/time_dependent_input.py</affectedPath><affectedPath>utilities/pytests/auto_llm_generated_pytests/test_expldiff_settings_rules.py</affectedPath><affectedPath>clubb_python_api/f2py_fortran_wrappers/advance_windm_edsclrm_module_wrapper.F90</affectedPath><affectedPath>clubb_jax/src/CLUBB_core/advance_clubb_core_module.py</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_expldiff_edsclrm_forcing.py</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_pressure_coord_forcing.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_init_sequence.py</affectedPath><affectedPath>clubb_python_api/clubb_python/CLUBB_core/advance_windm_edsclrm.py</affectedPath><affectedPath>clubb_jax/src/clubb_case_initalization.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_windm_edsclrm.py</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_windm_edsclrm_scalar_indices.py</affectedPath><affectedPath>experimental/experimental_pdfs/python/dash_additions/misc_labs/sam_lscale.py</affectedPath><affectedPath>src/CLUBB_core/numerical_check.F90</affectedPath><affectedPath>clubb_python_api/clubb_python/derived_types/nu_vert_res_dep.py</affectedPath><affectedPath>clubb_python_driver/advance_clubb_to_end.py</affectedPath><affectedPath>clubb_python_driver/clubb_case_initalization.py</affectedPath><affectedPath>src/CLUBB_core/advance_clubb_core_module.F90</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_cobra_sfclyr.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_core.py</affectedPath><affectedPath>clubb_jax/src/Benchmark_cases/prescribe_forcings.py</affectedPath><affectedPath>src/clubb_driver.F90</affectedPath><affectedPath>utilities/clubb_settings_validation.py</affectedPath><affectedPath>tests/run_clubb_settings_validation_test.py</affectedPath><affectedPath>src/Benchmark_cases/prescribe_forcings.F90</affectedPath><affectedPath>clubb_jax/src/CLUBB_core/numerical_check.py</affectedPath><affectedPath>clubb_python_api/clubb_f2py.pyf</affectedPath><affectedPath>clubb_jax/src/advance_clubb_to_end.py</affectedPath><affectedPath>clubb_python_api/f2py_fortran_wrappers/numerical_check_wrapper.F90</affectedPath><affectedPath>src/Benchmark_cases/cobra.F90</affectedPath><affectedPath>clubb_jax/pytests/auto_llm_generated_pytests/test_forcing_port_structure.py</affectedPath><affectedPath>clubb_python_api/f2py_fortran_wrappers/prescribe_forcings_module_wrapper.F90</affectedPath><affectedPath>clubb_jax/src/CLUBB_core/err_info_codes.py</affectedPath><affectedPath>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_xm_wpxp.py</affectedPath><commitId>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</commitId><timestamp>1791843053000</timestamp><author><absoluteUrl>http://carson.math.uwm.edu/jenkins/user/noreply</absoluteUrl><fullName>noreply</fullName></author><authorEmail>noreply@github.com</authorEmail><comment>Fix arm97+l do expldiff rtm thlm+set edsclrm f early (#1386)

* Do not force the thlm/rtm copies in the expldiff eddy-scalar solve

With l_do_expldiff_rtm_thlm, advance_windm_edsclrm copies thlm into
edsclrm(:,:,edsclr_dim-1) and rtm into edsclrm(:,:,edsclr_dim), advances all
eddy scalars, and copies those two slots back into thlm and rtm. The solve
added edsclrm_forcing of each slot to the copies, but thlm and rtm are
already advanced with thlm_forcing and rtm_forcing in advance_xm_wpxp.

In the standalone driver the slots are filled by iiedsclr_thl/iiedsclr_rt:
- arm_97 (iiedsclr_rt = 1, iiedsclr_thl = 2) put thlm_forcing [K/s] on rtm,
  so rtm &lt; 0 at ~5.5-8.8 km within the first steps (flag11 / expldiff).
- With the slots in expldiff order, rtm_forcing was applied twice and arm_97
  still hit rtm &lt; 0 near 12 km after 1379 of 5580 steps.

The copies now get no forcing. Mirrored in the JAX port.

Only changes runs with l_do_expldiff_rtm_thlm = .true. and non-zero
edsclrm_forcing in the last two eddy scalars, therefore BIT_CHANGING for
those. Default runs are bit-for-bit identical (arm_97, 1076 variables).

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;

* not hardwire the thlm and rtm edsclrm variables to be the last two; instead use sclr_idx%iiedsclr_thlm and sclr_idx%iiedsclr_rtm

Previously l_do_expldiff_rtm_thlm = true forced the last slot to be rtm and the one before that to be thlm.
If in the ..._model.in file iiedsclr_rt     = 1 ! Location in the edsclrm array to place total water
and iiedsclr_thl    = 2 ! Location in the edsclrm array to place a scalar like thetal
a switcheroo happens.
But if we use a not hardcoded indexing we need to check for out of bounds and distinctness of the 2 indices.

* Zero edsclrm_forcings early in apply_time_dependent_forcings_from_array

Check edsclrm_forcings != 0 instead of zeroing in advance_windm_edsclrm
BIT_CHANGING for l_do_expldiff_rtm_thlm = .true. for arm_97 and for cobra.

Python changes include: clubb_jax, clubb_python (+f2py) + tests

* Check l_do_expldiff_rtm_thlm eddy scalars in check_clubb_settings_api

1. Move the eddy-scalar checks into check_clubb_settings_api

check_clubb_settings_api now takes edsclr_dim and sclr_idx.
With l_do_expldiff_rtm_thlm = .true. it stops the run if
- edsclr_dim &lt;= 1, since the copies of thlm and rtm need two eddy
  scalars, or
- iiedsclr_thl and iiedsclr_rt are not distinct indices in
  1:edsclr_dim.
The index check moved to check_clubb_settings_api from advance_windm_edsclrm.
The check that edsclrm_forcing is zero for the thlm/rtm copies stays in
advance_windm_edsclrm, because prescribe_forcings sets edsclrm_forcing
every time step, after the settings check has run.

Callers in Fortran and mirrors (clubb-jax, python api) are updated

Behavior change: l_do_expldiff_rtm_thlm = .true. with fewer than two
eddy scalars used to skip explicit diffusion silently and now stops at
setup. This affects flag sets that turn the flag on for every case,
e.g. flag11 in input/flag_sets/run_bindiff_w_flags_config_core_flags.json.
Host models must pass the new arguments; CAM must also set
sclr_idx%iiedsclr_thl/iiedsclr_rt when clubb_l_do_expldiff_rtm_thlm is
on, since it leaves them at -1.

2. Fix the Python API

- calc_derived_params now requires nu_vert_res_dep and always pushes
  it to the F2PY storage (new helper NuVertResDep.zeros(ngrdcol)).
  Before, nu_vert_res_dep=None kept the previous call's stored arrays,
  and calc_derived_params only allocates them when unallocated. So a
  call with more columns than an earlier one in the same process wrote
  out of bounds. This crashed the in-process Python API pytest suite
  once the windm tests used two columns.
- clubb_f2py.pyf was missing l_do_expldiff_rtm_thlm for
  f2py_prescribe_forcings, so the Python driver failed on every case.

3. Gate the JAX rerun settings check at debug level 0

set_case_initial_conditions in the JAX driver now runs
check_clubb_settings at debug level &gt;= 0, matching clubb_driver.F90
since 9429ba2f1.

Also: put l_do_expldiff_rtm_thlm on its own line in the
time_dependent_input/prescribe_forcings argument lists.

Bit-for-bit: default-flag output is unchanged, and arm_97 with
l_do_expldiff_rtm_thlm = .true. matches the previous commit exactly.

Tested: debug + Python build and source checks; settings parity test;
Python API pytests (237 passed in one process); JAX pytests (791
passed); utilities settings-rule pytests; python-vs-fortran and
jax-vs-fortran bomex/atex; bomex and cobra with the flag stop at setup
in the Fortran, Python and JAX drivers.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;

* Do not apply surface fluxes to the expldiff thlm/rtm eddy-scalar copies

With l_do_expldiff_rtm_thlm, advance_windm_edsclrm copies thlm and rtm into
the iiedsclr_thl and iiedsclr_rt eddy scalars, solves all eddy scalars with
their surface flux wpedsclrp(:,gr%k_lb_zm,:) (from wpedsclrp_sfc) and copies
the two slots back. thlm and rtm already get wpthlp_sfc and wprtp_sfc in
advance_xm_wpxp, so a non-zero surface flux on the copies applies it twice.

Same approach as the edsclrm_forcing fix:

1. cobra_sfclyr (the only case that sets these fluxes) takes
   l_do_expldiff_rtm_thlm and sets wpedsclrp_sfc of the thlm/rtm copies to
   zero when it is on. set_sclr_sfc_rtm_thlm already zeroes all eddy-scalar
   surface fluxes.
2. advance_windm_edsclrm stops with a fatal error if the surface flux of
   either copy is non-zero, after the edsclrm_forcing check.

Mirrored in the JAX port (new reason code
ERR_WINDM_EDSCLRM_SFC_FLUX_EXPLDIFF_COPY; marks the columns fatal without
returning early, like the forcing check). No Python API wrapper changes.
CAM zeroes all eddy-scalar surface fluxes, so it is unaffected.

Default cobra output is unchanged. But technically BIT_CHANGING for cobra + l_use_expldiff_rtm_thlm

* Compute cobra's CO2 surface flux per column

cobra_sfclyr converted the CO2 surface flux with each column's surface
density inside the column loop, but stored it in the scalar CO2_flx2, and
the later loops gave every column that one value:

- CPU: every column got the last column's CO2 flux. Standalone columns
  currently share one density profile, so results were unaffected.
- OpenACC: the scalar was private to the device loop, and the later loops
  copied the never-set host value (implicit firstprivate). In the GPU
  build cobra's CO2 surface flux was 0 at every step.

CO2_flx2 is now a per-column array (enter/exit data create/delete like
other case routines). The JAX port already computes it per column.

Bit-for-bit: CPU cobra output is unchanged (1 and 2 columns, standard
stats incl. the CO2 scalars). GPU cobra output changes: before, the CO2
surface flux was 0 and CO2 differed from the CPU run by up to 10%;
now the CO2 scalars match the CPU run to ~1e-11 relative, like the other
fields.

Tested: gfortran debug build and source checks; standalone check of
cobra_sfclyr with two columns of different density (before: column 1 got
column 2's flux); nvhpc 24.3 OpenACC build and cobra on a Quadro P4000.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;

* removed the idiot proofing

* fully removed idiot proofing for l_do_expldiff_rtm_thlm+esclrdim

---------

Co-authored-by: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</comment><date>2026-10-12 17:10:53 -0500</date><id>4292a70f53a6b6c4eab864fe27b8fd9af5d86909</id><msg>Fix arm97+l do expldiff rtm thlm+set edsclrm f early (#1386)</msg><path><editType>edit</editType><file>clubb_python_api/f2py_fortran_wrappers/numerical_check_wrapper.F90</file></path><path><editType>edit</editType><file>clubb_jax/src/clubb_case_initalization.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_core.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_advance_core_subs.py</file></path><path><editType>edit</editType><file>src/Benchmark_cases/time_dependent_input.F90</file></path><path><editType>edit</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_pressure_coord_forcing.py</file></path><path><editType>edit</editType><file>src/Benchmark_cases/prescribe_forcings.F90</file></path><path><editType>add</editType><file>utilities/pytests/auto_llm_generated_pytests/test_expldiff_settings_rules.py</file></path><path><editType>edit</editType><file>src/Benchmark_cases/cobra.F90</file></path><path><editType>edit</editType><file>clubb_python_api/f2py_fortran_wrappers/advance_windm_edsclrm_module_wrapper.F90</file></path><path><editType>edit</editType><file>clubb_python_driver/advance_clubb_to_end.py</file></path><path><editType>edit</editType><file>clubb_python_driver/clubb_case_initalization.py</file></path><path><editType>edit</editType><file>src/clubb_driver.F90</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_python/prescribe_forcings.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_xp2_xpyp.py</file></path><path><editType>edit</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_driver_lifecycle.py</file></path><path><editType>edit</editType><file>src/CLUBB_core/advance_windm_edsclrm_module.F90</file></path><path><editType>edit</editType><file>clubb_python_driver/advance_clubb_core.py</file></path><path><editType>edit</editType><file>experimental/experimental_pdfs/python/dash_additions/misc_labs/sam_lscale.py</file></path><path><editType>edit</editType><file>clubb_jax/src/CLUBB_core/numerical_check.py</file></path><path><editType>add</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_expldiff_edsclrm_forcing.py</file></path><path><editType>edit</editType><file>clubb_jax/src/Benchmark_cases/cobra.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_init_sequence.py</file></path><path><editType>edit</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_forcing_port_structure.py</file></path><path><editType>edit</editType><file>src/CLUBB_core/advance_clubb_core_module.F90</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_windm_edsclrm.py</file></path><path><editType>edit</editType><file>src/CLUBB_core/numerical_check.F90</file></path><path><editType>edit</editType><file>utilities/clubb_settings_validation.py</file></path><path><editType>edit</editType><file>clubb_jax/src/CLUBB_core/err_info_codes.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_wp2_wp3.py</file></path><path><editType>edit</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_cobra_sfclyr.py</file></path><path><editType>edit</editType><file>clubb_python_api/pytests/auto_llm_generated_pytests/test_call_tree_advance_xm_wpxp.py</file></path><path><editType>add</editType><file>clubb_jax/pytests/auto_llm_generated_pytests/test_windm_edsclrm_scalar_indices.py</file></path><path><editType>edit</editType><file>clubb_jax/src/CLUBB_core/advance_clubb_core_module.py</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_f2py.pyf</file></path><path><editType>edit</editType><file>tests/run_clubb_settings_validation_test.py</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_python/CLUBB_core/numerical_check.py</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_python/CLUBB_core/parameters_tunable.py</file></path><path><editType>edit</editType><file>clubb_jax/src/advance_clubb_to_end.py</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_python/CLUBB_core/advance_windm_edsclrm.py</file></path><path><editType>edit</editType><file>clubb_python_api/f2py_fortran_wrappers/prescribe_forcings_module_wrapper.F90</file></path><path><editType>edit</editType><file>clubb_jax/src/Benchmark_cases/time_dependent_input.py</file></path><path><editType>edit</editType><file>clubb_python_api/clubb_python/derived_types/nu_vert_res_dep.py</file></path><path><editType>edit</editType><file>clubb_jax/src/Benchmark_cases/prescribe_forcings.py</file></path><path><editType>edit</editType><file>clubb_jax/src/CLUBB_core/advance_windm_edsclrm_module.py</file></path></item><kind>git</kind></changeSet><culprit><absoluteUrl>http://carson.math.uwm.edu/jenkins/user/noreply</absoluteUrl><fullName>noreply</fullName></culprit><inProgress>false</inProgress><nextBuild><number>259</number><url>http://carson.math.uwm.edu/jenkins/view/all/job/clubb_BFB_multi_col_gpu_nvhpc_test/259/</url></nextBuild><previousBuild><number>257</number><url>http://carson.math.uwm.edu/jenkins/view/all/job/clubb_BFB_multi_col_gpu_nvhpc_test/257/</url></previousBuild></workflowRun>