Skip to content

Fix CUSTOM_OBJFUNC support in Python layer#2756

Open
riddhi1228 wants to merge 12 commits intosu2code:developfrom
riddhi1228:fix/custom-objfunc-python-layer
Open

Fix CUSTOM_OBJFUNC support in Python layer#2756
riddhi1228 wants to merge 12 commits intosu2code:developfrom
riddhi1228:fix/custom-objfunc-python-layer

Conversation

@riddhi1228
Copy link

@riddhi1228 riddhi1228 commented Mar 12, 2026

This PR fixes the handling of CUSTOM_OBJFUNC in the Python interface.

Problem

When evaluating custom objective functions, the Python layer could raise
a KeyError because CUSTOM_OBJFUNC was missing from historyMap.py

Solution

  • Added if (false) AddHistoryOutput("CUSTOM_OBJFUNC", ...) in CFlowOutput.cpp
    so updateHistoryMap.py registers it correctly
  • Fixed updateHistoryMap.py parser to handle if (false) AddHistoryOutput pattern
  • Fixed multi-line BGS_ENTHALPY call in CFlowIncOutput.cpp so parser works correctly
  • Regenerated historyMap.py with CUSTOM_OBJFUNC correctly registered

Fixes #2586

- Register CUSTOM_OBJFUNC in historyMap
- Normalize Custom_ObjFunc header to CUSTOM_OBJFUNC key
- Prevent KeyError when evaluating custom objective functions

Fixes su2code#2586
@pcarruscag pcarruscag changed the base branch from master to develop March 12, 2026 16:28
@pcarruscag
Copy link
Member

==================== Start Test: sphere_ffd_def_bspline ====================
/github/workspace/tests/TestCases/deformation/spherical_ffd
sphere_ffd_def_bspline: PASSED
execution command: SU2_DEF def_spherical_bspline.cfg > def_spherical_bspline.log 2>&1
test_iter=10
test_vals (stored): 0.002068
sim_vals (computed): 0.002068
delta_vals: 0.000000
test duration: 0.03 min
Traceback (most recent call last):
  File "/github/workspace/install/bin/continuous_adjoint.py", line 32, in <module>
    import SU2
  File "/github/workspace/install/bin/SU2/__init__.py", line 19, in <module>
    from SU2 import eval
  File "/github/workspace/install/bin/SU2/eval/__init__.py", line 1, in <module>
    from SU2.eval.functions import function as func
  File "/github/workspace/install/bin/SU2/eval/functions.py", line 92
    header_to_key = {v["HEADER"]: k for k, v in su2io.historyOutFields.items()}
    ^
IndentationError: unexpected indent

@riddhi1228
Copy link
Author

Fixed — the indentation error on line 92 has been corrected and black formatting applied. Thanks for catching it.

@riddhi1228
Copy link
Author

The black formatting check is failing on historyMap.py even though black 22.6.0 reports no changes needed locally and the file is unchanged on the develop branch. This appears to be a pre-existing formatting issue in the repo rather than something introduced by this PR. Happy to investigate further if you can point me to what the CI is reformatting exactly.

@pcarruscag
Copy link
Member

It's ok. The bigger issue is that this historyMap.py file should be generated, not edited manually.
Can you try to run the script that generates the historyMap (it's somewhere in SU2_PY) and see if the tests still pass?

…n test

- Add if (false) AddHistoryOutput for CUSTOM_OBJFUNC in CFlowOutput.cpp
  so updateHistoryMap.py registers it correctly
- Fix updateHistoryMap.py parser to handle 'if (false) AddHistoryOutput' pattern
- Fix multi-line AddHistoryOutput in CFlowIncOutput.cpp for BGS_ENTHALPY
- Regenerate historyMap.py with CUSTOM_OBJFUNC entry
- Fix regression test configs: rename AVG_TOTALTEMP to SURFACE_TOTAL_TEMPERATURE
  (AVG_TOTALTEMP was renamed in the C++ output layer but configs were never updated)

Fixes su2code#2586
@riddhi1228
Copy link
Author

Hi @pcarruscag, updated the PR based on your feedback:

  • Moved the fix to CFlowOutput.cpp using if (false) AddHistoryOutput("CUSTOM_OBJFUNC", ...)
    as done in Fixing Custom Objective Function for Unsteady Adjoint  #2587
  • Fixed updateHistoryMap.py parser to handle the if (false) pattern and a pre-existing
    multi-line BGS_ENTHALPY call in CFlowIncOutput.cpp that was causing an IndexError
  • Regenerated historyMap.pyCUSTOM_OBJFUNC and its derived fields are now correctly registered
  • Fixed the 2 failing regression tests from Fixing Custom Objective Function for Unsteady Adjoint  #2587: AVG_TOTALTEMP was renamed to
    SURFACE_TOTAL_TEMPERATURE in the C++ layer but 3 test configs were never updated

@pcarruscag
Copy link
Member

There are errors in the tests
parallel_regression.py, serial_regression.py, and serial_regression_AD.py.
Please iterate on them locally, I cannot copy the logs for you each time.

Traceback (most recent call last):
  File "/github/workspace/install/bin/shape_optimization.py", line 313, in <module>
    main()
  File "/github/workspace/install/bin/shape_optimization.py", line 184, in main
    shape_optimization(
  File "/github/workspace/install/bin/shape_optimization.py", line 289, in shape_optimization
    SU2.opt.SLSQP(project, x0, xb, its, accu)
  File "/github/workspace/install/bin/SU2/opt/scipy_tools.py", line 128, in scipy_slsqp
    outputs = fmin_slsqp(
  File "/usr/lib/python3/dist-packages/scipy/optimize/slsqp.py", line 207, in fmin_slsqp
    res = _minimize_slsqp(func, x0, args, jac=fprime, bounds=bounds,
  File "/usr/lib/python3/dist-packages/scipy/optimize/slsqp.py", line 423, in _minimize_slsqp
    g = append(fprime(x), 0.0)
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 327, in function_wrapper
    return function(*(wrapper_args + args))
  File "/github/workspace/install/bin/SU2/opt/scipy_tools.py", line 434, in obj_df
    dobj_list = project.obj_df(x)
  File "/github/workspace/install/bin/SU2/opt/project.py", line 248, in obj_df
    return self._eval(konfig, func, dvs)
  File "/github/workspace/install/bin/SU2/opt/project.py", line 211, in _eval
    vals = design._eval(func, *args)
  File "/github/workspace/install/bin/SU2/eval/design.py", line 151, in _eval
    vals = eval_func(*inputs)
  File "/github/workspace/install/bin/SU2/eval/design.py", line 365, in obj_df
    grad = su2grad(obj_list, grad_method, config, state)
  File "/github/workspace/install/bin/SU2/eval/gradients.py", line 97, in gradient
    grads = adjoint(func_name, config, state)
  File "/github/workspace/install/bin/SU2/eval/gradients.py", line 214, in adjoint
    function(func_name, config, state)
  File "/github/workspace/install/bin/SU2/eval/functions.py", line 133, in function
    func_out = state["FUNCTIONS"]["COMBO"]
KeyError: 'COMBO'

riddhi1228 and others added 3 commits March 17, 2026 05:25
…ion calls

- Skip AddHistoryOutput calls where field name contains '+' (dynamic calls)
- Regenerate historyMap.py with correct entries, no malformed keys
- CUSTOM_OBJFUNC now correctly registered
@riddhi1228
Copy link
Author

I ran updateHistoryMap.py as requested, but the script appears to produce a different historyMap.py than what's currently in develop — it adds 28 new keys and removes 14 existing ones (including RMS_ENTHALPY, RMS_TEMPERATURE) which breaks the regression tests. This seems to be a pre-existing issue where the generator is out of sync with the current codebase.

The CUSTOM_OBJFUNC fix in CFlowOutput.cpp and updateHistoryMap.py parser changes are correct. Should I:

  1. Submit just those two files and leave historyMap.py regeneration for a separate cleanup PR?
  2. Or is there a specific version of the generator I should be using?

@pcarruscag
Copy link
Member

ok let's go back to what you had before then, I don't want to waste more time with python scripts

Per maintainer feedback, reverting to direct edit approach.
The updateHistoryMap.py generator is out of sync with the current
codebase and produces incorrect output.

Fixes su2code#2586
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants