idaholab / HERON

Holistic Energy Resource Optimization Network (HERON) is a modeling toolset and plugin for RAVEN to accelerate stochastic technoeconomic assessment of the economic viability of various grid-energy system configurations, especially with application to electrical grids and integrated energy systems (IES).
Apache License 2.0
24 stars 38 forks source link

[DEFECT] Using External Function as Resource Transfer not implemented #253

Open GabrielSoto-INL opened 1 year ago

GabrielSoto-INL commented 1 year ago

Defect Description

Describe the defect I tried to implement a component resource transfer using an external function instead of a linear transfer function. The HERON documentation says this is possible but it has not been implemented yet. For example, I edited HERON/tests/integration_tests/mechanics/storage_func/heron_input.xml to include the external function call within one of the components on Line 70: image

What did you expect to see happen?
What did you see instead?

I got an error when running outer.xml. In the outer~inner file, I see:

************************************************************************
--------------------------------------------------
There were 2 warnings during the simulation run:
(1 time) <class 'DeprecationWarning'> "variables" node inputted but has been deprecated!  Please list variables in the "inputs" and "outputs" nodes instead.  This Warning will result in an error in RAVEN 3.0!
(1 time) Nothing to write to CSV! Checking metadata ...
--------------------------------------------------
Exception in thread 3:
Traceback (most recent call last):
  File "C:\Users\sotogj\Miniconda3\envs\raven_libraries\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\sotogj\Miniconda3\envs\raven_libraries\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\sotogj\projects\raven\ravenframework\Runners\SharedMemoryRunner.py", line 115, in <lambda>
    self.thread = InterruptibleThread(target = lambda q, *arg : q.append(self.functionToRun(*arg)),
  File "C:\Users\sotogj\projects\raven\ravenframework\Models\EnsembleModel.py", line 515, in evaluateSample
    returnValue = (Input,self._externalRun(Input, jobHandler))
  File "C:\Users\sotogj\projects\raven\ravenframework\Models\EnsembleModel.py", line 683, in _externalRun
    iterationCount, jobHandler)
  File "C:\Users\sotogj\projects\raven\ravenframework\Models\EnsembleModel.py", line 779, in __advanceModel
    f'failed! Trace:\n{"*"*72}\n{msg}\n{"*"*72}')
  File "C:\Users\sotogj\projects\raven\ravenframework\BaseClasses\MessageUser.py", line 77, in raiseAnError
    self.messageHandler.error(self, etype, msg, str(tag), verbosity, color)
  File "C:\Users\sotogj\projects\raven\ravenframework\MessageHandler.py", line 235, in error
    raise etype(message)
RuntimeError: The Model "dispatch" id "dispatch++3" failed! Trace:
************************************************************************
Traceback (most recent call last):
          File "C:\Users\sotogj\projects\raven\ravenframework\Models\EnsembleModel.py", line 744, in __advanceModel
            evaluation = modelToExecute['Instance'].evaluateSample.original_function(modelToExecute['Instance'], origInputList, samplerType, inputKwargs)
          File "C:\Users\sotogj\projects\raven\ravenframework\Models\ExternalModel.py", line 324, in evaluateSample
            result,instSelf = self._externalRun(inRun,)
          File "C:\Users\sotogj\projects\raven\ravenframework\Models\ExternalModel.py", line 266, in _externalRun
            self.sim.run(externalSelf, InputDict)
          File "C:\Users\sotogj\projects\HERON\src\DispatchManager.py", line 733, in run
            dispatch, metrics = runner.run(raven_vars)
          File "C:\Users\sotogj\projects\HERON\src\DispatchManager.py", line 211, in run
            all_dispatch, metrics = self._do_dispatch(meta, all_structure, project_life, interp_years, segs, seg_type)
          File "C:\Users\sotogj\projects\HERON\src\DispatchManager.py", line 287, in _do_dispatch
            dispatch = self._dispatcher.dispatch(self._case, self._components, self._sources, meta)
          File "C:\Users\sotogj\projects\HERON\src\dispatch\pyomo_dispatch.py", line 201, in dispatch
            initial_levels, meta)
          File "C:\Users\sotogj\projects\HERON\src\dispatch\pyomo_dispatch.py", line 298, in dispatch_window
            self._create_production(m, comp, meta) # variables
          File "C:\Users\sotogj\projects\HERON\src\dispatch\pyomo_dispatch.py", line 464, in _create_production
            self._create_transfer(m, comp, prod_name)
          File "C:\Users\sotogj\projects\HERON\src\dispatch\pyomo_dispatch.py", line 587, in _create_transfer
            ratios = self._get_transfer_coeffs(m, comp)
        AssertionError

************************************************************************

Seems the capability has not been implemented yet, there are some TODOs still in the create_transfer method in Pyomo dispatch.

Do you have a suggested fix for the development team?

In the create_transfer method within pyomo_dispatch.py, HERON should be able to check for a Function type (as well as the standard Linear type) transfer function. It would be good to allow the user to either provide the transfer functions or to set the constraints themselves.

Describe how to Reproduce Steps to reproduce the behavior:

  1. Run outer.xml for storage_func test while adding external function call as shown in snapshot above.

Platform (please complete the following information):


For Change Control Board: Issue Review

This review should occur before any development is performed as a response to this issue.


For Change Control Board: Issue Closure

This review should occur when the issue is imminently going to be closed.