Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow axial expansion related classes to be more extensible #1918

Closed
drewj-tp opened this issue Sep 30, 2024 · 4 comments · Fixed by #1920
Closed

Allow axial expansion related classes to be more extensible #1918

drewj-tp opened this issue Sep 30, 2024 · 4 comments · Fixed by #1920
Assignees
Labels
enhancement New feature or request

Comments

@drewj-tp
Copy link
Contributor

I'm working on some internal axial expansion work and finding myself needing to modify some of the functionality on the base class. In some cases I can call super and be good, but in other places I need a bit more control. I've got some partially developed code that I wanted to present in a ticket before fully submitting the PR. Estimating 10/6 for draft PR.

ExpanionData.computeThermalExpansionFactors

One example is modifications to how ExpansionData computes expansion factors for a given component. The current logic for this method is fully encased in a single method

def computeThermalExpansionFactors(self):
"""Computes expansion factors for all components via thermal expansion."""
for b in self._a:
for c in getSolidComponents(b):
if self.expandFromTinputToThot:
# get thermal expansion factor between c.inputTemperatureInC & c.temperatureInC
self._expansionFactors[c] = c.getThermalExpansionFactor()
elif c in self.componentReferenceTemperature:
growFrac = c.getThermalExpansionFactor(
T0=self.componentReferenceTemperature[c]
)
self._expansionFactors[c] = growFrac
else:
# We want expansion factors relative to componentReferenceTemperature not
# Tinput. But for this component there isn't a componentReferenceTemperature, so
# we'll assume that the expansion factor is 1.0.
self._expansionFactors[c] = 1.0

but there isn't a simple way to drop in more bespoke expansion into this method without rewriting the entire routine. So, I propose cracking this method specifically into one primary method and two helper methods, more or less like

def  computeThermalExpansionFactors(self):
    for b in self._a:
        self._blockThermalExpansionFactors(b)  # name TBD
def _blockThermalExpansionFactors(self, b):
    for c in getSolidComponents(b):
        self._componentThermalExpansionFactors(c)
def _componentThermalExpansionFactors(self, c):
    # more or less the internals of the current implementation

Assembly axial link check

The logic for determining if two components are axially linked is vital for determining how the tops and bottoms of blocks move through expansion. This logic is performed in _determinedLinked and isn't really overridable from within

lstLinkedC = [None, None]
for ib, linkdBlk in enumerate(self.linkedBlocks[b]):
if linkdBlk is not None:
for otherC in getSolidComponents(linkdBlk.getChildren()):
if _determineLinked(c, otherC):
if lstLinkedC[ib] is not None:
errMsg = (
"Multiple component axial linkages have been found for "
f"Component {c}; Block {b}; Assembly {b.parent}."
" This is indicative of an error in the blueprints! Linked "
f"components found are {lstLinkedC[ib]} and {otherC}"
)
runLog.error(msg=errMsg)
raise RuntimeError(errMsg)
lstLinkedC[ib] = otherC

I propose a staticmethod that points back to that function. Subclasses can use or override this method if they need additional logic for determining component linking.

Small data class for axial links

The data structure for the linking between blocks and between components is dict[T, list[T | None, T | None]] so there's lines like

b.p.zbottom = self.linked.linkedBlocks[b][0].p.ztop

where it may not be immediately clear (outside of some neighboring comments) what position [0] in this returned value represents.

I would like to add a small dataclass like

class Link:
    lower: T | None
    upper: T | None

(type T standin) that would make that above code snippet (and others) look like

b.p.zbottom = self.linked.linkedBlocks[b].lower.p.ztop

that's more readable in my opinion.

Other considerations

  1. Provide an iterator form of getSolidComponents since we mostly use it for iteration - Provide more Composite.iter* methods #1915
  2. Combine check for zero-valued and negative expansion factors - Refactor Axial Expansion #1861 (comment)
  3. Remove unnecessary spec for dummy block #1453
@drewj-tp drewj-tp added the enhancement New feature or request label Sep 30, 2024
@drewj-tp drewj-tp self-assigned this Sep 30, 2024
@keckler
Copy link
Member

keckler commented Sep 30, 2024

Whatever you end up implementing here (I did not read this ticket in extreme detail), please make sure you consider this PR: #1376

That PR was closed because for whatever reason we haven't pulled the trigger on it, and it became stale. But we very much intend to merge it or something similar to it into the framework in the near future.

Maybe file that under your "Other considerations" section above.

@albeanth
Copy link
Member

albeanth commented Sep 30, 2024

That PR was closed because for whatever reason we haven't pulled the trigger on it, and it became stale. But we very much intend to merge it or something similar to it into the framework in the near future.

@keckler don't you worry! It'll come back soon! It's on the (edge of the) radar

@drewj-tp
Copy link
Contributor Author

Whatever you end up implementing here (I did not read this ticket in extreme detail), please make sure you consider this PR: #1376

I think this will introduce functionality to help improve / extend the component linking. I'll make a comment on the changes I think will be useful and we can chat about some solutions or workarounds

@albeanth
Copy link
Member

albeanth commented Oct 4, 2024

@drewj-tp what you propose for computing the thermal expansion factors sounds good to me.

for assembly axial link check -- if you are proposing splitting up _getLinkedComponents into smaller methods for extensibility improvements, cool. yeah that would be nice.

for the data class -- sure. Yeah, that would be nice. You are effectively replacing the 0/1 indexing for lower/upper; which is undoubtedly more readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants