NatLabRockies / NatLabRockies/H2Integrate
SLC: Add check for controllers that only work with a specific architecture
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 26
- Forks
- 44
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 16
Description
I'd imagine that future system level controllers will be made for specific system designs. For example, the PLM control strategies are pretty specific to grid/battery architectures. Any controller that is made for a specific system architecture should have a check in the setup() method to ensure that it's only being used in that case. In the case for a controller is specific to grid/battery design, this controller should check two things:
- The number and types of technologies. Ex: grid/battery system means 1 "dispatchable" tech and 1 "storage" tech. Check that the input technologies have 1 dispatchable and 1 storage and nothing else
- The connection flow of the technology type. Ex: Check that the dispatchable tech (grid) is upstream and connected to the storage tech (battery)
The check for 1 is pretty simple, it could be implemented similar to this:
allowable_tech_classifications = {"dispatchable": 1, "storage": 1, "flexible": 0, "fixed": 0}
for classifier, allowable_number in allowable_tech_classifications.items():
if allowable_number is None:
continue
n_techs = getattr(self, f"{classifier}_techs")
if n_techs != allowable_number:
raise ValueError("fCannot have {n_techs} {classifier} techs for this controller. Must have {allowable_number} {classifier} techs")
My proposed solution for step 2 is to have the required system architecture defined as a Directional Graph (from network). Each node is named as the type of classifier.
required_architecture = nx.DiGraph()
required_architecture.add_edge("dispatchable-0", "storage-0")
# etc
then remake the technology graph input with a similar naming convention
input_architecture = nx.DiGraph()
classifier_name_mapper = {}
for ii,edge in enumerate(slc_topology["technology_graph"].edges):
if (source_name:=classifier_name_mapper.get(edge[0],None) is None:
source_name = f"{slc_topology['tech_control_classifiers'].get(edge[0], 'other')-{ii}"
classifier_name_mapper[edge[0]] = source_name
if (dest_name:=classifier_name_mapper.get(edge[1],None) is None:
dest_name = f"{slc_topology['tech_control_classifiers'].get(edge[1], 'other')-{ii}"
classifier_name_mapper[edge[1]] = dest_name
input_architecture.add_edge(source_name, dest_name)
Then compare the required_architecture and input_architecture in whatever way is necessary to ensure that the controller is capable of handling that input architecture.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating system-level controller setup() methods and the slc_topology inputs, especially technology_graph and tech_control_classifiers. Review how technology classifications and connections are currently represented, then define how controller-specific architecture requirements should be compared. Done means controllers reject unsupported technology counts and connection flows with clear errors, with coverage for the grid/battery example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100