cottax.consumers.architectures

Where the problems under a top go: MDF, IDF, SAND and MDA as one op each, over the cut rules and a closing handed in, asking every problem met what it is.

Dependency:

interface refusals (interface: ModelReading, what a problem is to an

|| || || || architecture, three questions; Closing, how a group of || / || || cuts is closed, chosen. refusals: every refusal kind) || closing <–’ || (closing: closed, every group closed at a name of its own; || || || CloseFunctionalCycles, the op recording a rule) / / /

architectures <—–’ (architectures: Architecture, its two scopes Monolithic and

|| Coupled, the four levels and their finals MDF, IDF, SAND, || MDA; Boxes: Bodies, Disciplines, Solves; Resolution) /

part <– declaration.interface (part: Architecting, the four as a surface’s methods, closed

by the closing it holds)

interface_types (At, AtFirstMember: where a closure binds, what a closing

is built on)

class Architecture[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: StagedOp[N, V], Generic[N, V]

An MDAO architecture, with a top (Monolithic) or without (Coupled).

A StagedOp, since each stage is decided off the graph the one before leaves; like any composition it proves nothing of its own, every op it applies being checked.

  1. what the level absorbs is combined (absorbing), and every cycle then off the level’s own is resolved (outside);

  2. the cycles of the level’s scope are cut over the boxes the final names, and each group is closed with one problem, the closure;

  3. every problem lying wholly inside another’s body is nested there, at every depth (unless the final combines declared problems, which then combines it as any); then every problem on each cycle of the scope is placed as the final’s combining says, the closures apart from the problems the model declared.

rule: CutRule[N, V]

the MDA method.

Type:

What is cut on each cycle

closing: Closing[N, V]

the op, and where its problem binds.

Type:

How a group is closed

boxes: AbstractVar[Boxes[N, V]]

Which solves in the scope the rule sees as one function each.

design: AbstractVar[tuple[N, ...]]

the top, or none.

Type:

The problems that are the level’s own and not models

combines_declared: ClassVar[bool] = True

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_nothing_nested>, <function check_implicit_models>)

(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.

Type:

What the op needs of the graph before it can compute anything

abstractmethod scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

abstractmethod outside(graph: NestingGraph[N, V])[source]

What resolves the cycles the scope leaves out, once absorbed.

Return type:

tuple[GraphOp[N, V], ...]

abstractmethod absorbing(graph: NestingGraph[N, V])[source]

What is combined before anything is cut.

Return type:

tuple[GraphOp[N, V], ...]

abstractmethod combining(opened: NestingGraph[N, V], closures: Sequence[N])[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

Return type:

Sequence[GraphOp[N, V]]

stages(graph: NestingGraph[N, V])[source]

Absorb; resolve what then lies outside; cut and close the scope of what is left; place every problem on its cycles, the closures being the problems the cutting bound.

Return type:

Generator[Sequence[GraphOp[N, V]], NestingGraph[N, V], None]

nesting_inside(scope: NestingGraph[N, V])[source]

Each problem of the scope lying wholly inside another’s body nested there, read before anything is cut; none where the final combines declared problems.

Return type:

tuple[GraphOp[N, V], ...]

resolution(graph: NestingGraph[N, V])[source]

The whole derivation: each stage’s ops and the graph it leaves. Refused as apply refuses.

Return type:

Resolution[N, V]

cycles_under(opened: NestingGraph[N, V], closures: Sequence[N])[source]

Per cycle of the scope in opened, the problems on it: the closures the cutting bound and the ones the model declared, but those already nested.

Return type:

tuple[OnCycle[N], ...]

class Monolithic[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Architecture[N, V], Generic[N, V]

Under a top: its interior is the scope, every requirement the design reaches is combined into it first, and every cycle then off the top’s is resolved by an analysis.

top: N

nothing searches for an optimiser.

Type:

The problem the design lives in. Required

analysis: Optional[Analysis[N, V]] = None

What resolves every cycle off the top’s; None is an MDA with this rule and closing.

checks_graph: PerLevel[tuple[Callable, ...]] = (<function check_top_bound>, <function check_top_is_problem>, <function check_top_combinable>)

(op, graph) -> Iterator[Violation], collected by refusals and raised by apply.

Type:

What the op needs of the graph before it can compute anything

property design: tuple[N, ...]

abstract to ABC until a subclass binds the name, and absent on a class that declares it as a field.

Type:

What the level binds in place of the annotation

scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

outside(graph: NestingGraph[N, V])[source]

The analysis over the graph with the top’s cycle taken out, its ops applied to the whole: a cycle off the top’s is a component of its own.

Return type:

tuple[GraphOp[N, V], ...]

absorbing(graph: NestingGraph[N, V])[source]

Every requirement whose conditions the design of top reaches, combined into top: one Combine, or nothing.

Return type:

tuple[GraphOp[N, V], ...]

class Coupled[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Architecture[N, V], Generic[N, V]

No top: the whole graph is the scope and nothing is absorbed. A requirement is left where it is, for the proof to refuse.

design: AbstractVar[tuple[N, ...]] = ()

the top, or none.

Type:

The problems that are the level’s own and not models

scope(graph: NestingGraph[N, V])[source]

The graph the cutting sees, and whose cycles are placed.

Return type:

NestingGraph[N, V]

outside(graph: NestingGraph[N, V])[source]

What resolves the cycles the scope leaves out, once absorbed.

Return type:

tuple[GraphOp[N, V], ...]

absorbing(graph: NestingGraph[N, V])[source]

What is combined before anything is cut.

Return type:

tuple[GraphOp[N, V], ...]

class MultidisciplinaryFeasible[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

Per cycle, the closures folded into one MDA nested in top, and each declared problem nested in that MDA – or in top, on a cycle nothing was bound on.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class IndividualFeasible[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

top owns the coupling copies and drives the gaps to zero; each declared problem is a solve of its own inside its iteration.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class Simultaneous[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Monolithic[N, V], Generic[N, V]

top absorbs every problem under it.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class Analysis[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Coupled[N, V], Generic[N, V]

Per cycle, the closures folded into one, and each declared problem nested in it. A cycle nothing was bound on is left as it is: its one problem closes it.

combines_declared: ClassVar[bool] = False

Whether the final may Combine a declared problem into another, so each must combine as the top does; a level that only nests them says False, and then takes a problem combining as nothing.

combining(opened, closures)[source]

The ops placing what lies in the scope, read off opened, the graph the cutting leaves; closures is the problems it bound.

class MDF[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: MultidisciplinaryFeasible[N, V], Generic[N, V]

Multidisciplinary feasible over the disciplines.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class IDF[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: IndividualFeasible[N, V], Generic[N, V]

Individual discipline feasible over the disciplines.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class SAND[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V], top: N, *, analysis: Optional[Analysis[N, V]] = None)[source]

Bases: Simultaneous[N, V], Generic[N, V]

Simultaneous analysis and design over the bodies: the states are the optimiser’s outright, so a solve’s own loop needs no cut.

boxes: AbstractVar[Boxes[N, V]] = bodies

Which solves in the scope the rule sees as one function each.

class MDA[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: Analysis[N, V], Generic[N, V]

A multidisciplinary analysis over the disciplines: each implicit model keeps its own solver, and one closure per cycle iterates the states between them.

boxes: AbstractVar[Boxes[N, V]] = disciplines

Which solves in the scope the rule sees as one function each.

class Boxes[N: Label, V: Place][source]

Bases: Frozen, Generic[N, V]

Which problems of the graph handed are seen as one function each.

abstractmethod folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Bodies[N: Label, V: Place][source]

Bases: Boxes[N, V], Generic[N, V]

None: the function nodes alone are seen.

folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Disciplines[N: Label, V: Place][source]

Bases: Boxes[N, V], Generic[N, V]

Every problem of the graph handed – a discipline under check_implicit_models, and under an architecture every implicit model in its scope.

folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class Solves[N: Label, V: Place](names: tuple[N, ...])[source]

Bases: Boxes[N, V], Generic[N, V]

These, by name.

names: tuple[N, ...]
folded(graph: NestingGraph[N, V])[source]

The problems to fold, in binding order.

Return type:

tuple[N, ...]

class OnCycle[N: Label](closures: tuple[N, ...], declared: tuple[N, ...])[source]

Bases: Frozen, Generic[N]

The problems on one cycle of the scope, as a final reads them.

closures: tuple[N, ...]

The ones the cutting bound, in binding order.

declared: tuple[N, ...]

The ones the model declared, but those nested inside another’s body, in binding order.

class Resolution[N: Label, V: Place](absorbed: tuple[GraphOp[N, V], ...], outside: tuple[GraphOp[N, V], ...], closures: tuple[GraphOp[N, V], ...], opened: NestingGraph[N, V], combining: tuple[GraphOp[N, V], ...], graph: NestingGraph[N, V])[source]

Bases: Frozen, Generic[N, V]

Architecture applied to a graph in terms of GraphOps and the intermediate graphs. Useful for extracting which closures were inserted.

absorbed: tuple[GraphOp[N, V], ...]

one Combine, or none.

Type:

The requirements the design reaches, combined into the top

outside: tuple[GraphOp[N, V], ...]

the analysis’s closures and placing.

Type:

What resolved the cycles off the scope’s

closures: tuple[GraphOp[N, V], ...]

what the Closing returned.

Type:

What the cutting bound, one closure per group

opened: NestingGraph[N, V]

The graph after those two and before any problem is placed.

combining: tuple[GraphOp[N, V], ...]

each lying inside another’s body nested there, then the final’s own, placing the closures and the declared problems.

Type:

The ops placing the problems

graph: NestingGraph[N, V]

The result.

class AtFirstMember[N: Label, V: Place](closure_of: LabelToLabel[N])[source]

Bases: At[N, V], Generic[N, V]

At the cycle’s first member in binding order, whatever the rule cut: one closure per cycle, so two groups on one cycle collide, which closed refuses by name.

closure_of: LabelToLabel[N]
closed[N: Label, V: Place](opened: Iterable[Opened[N, V]], closing: Closing[N, V])[source]

Every group on every cycle closed, each bound at a name of its own.

Return type:

tuple[GraphOp[N, V], ...]

class CloseFunctionalCycles[N: Label, V: Place](rule: CutRule[N, V], closing: Closing[N, V])[source]

Bases: ComposedOp[N, V], Generic[N, V]

Every cycle of the function nodes closed by the rule, over the graph this op is applied to. Records the rule, where a closure records a decision.

rule: CutRule[N, V]
closing: Closing[N, V]
composed(graph: NestingGraph[N, V])[source]

The ops this one is. Takes a graph, so an expansion may depend on what it meets.

Return type:

Sequence[GraphOp[N, V]]

class Architecting(locator: Locator[V, N])[source]

Bases: Part

The architectures a study applies, each named after the op it builds, every group of cuts closed by closing; which variables to cut is the rule, per call.

closing: AbstractVar[Closing]

another closing is another surface, or the op written in full.

Type:

How a group of cuts is closed

mdf(top: Label, rule: CutRule = GaussSeidel())[source]

Multidisciplinary feasible under top: one MDA per cycle, nested in it.

Return type:

MDF

idf(top: Label, rule: CutRule = GaussSeidel())[source]

Individual discipline feasible under top: the closures combined into it.

Return type:

IDF

sand(top: Label, rule: CutRule = GaussSeidel())[source]

Simultaneous analysis and design under top: the bodies’ states are its own.

Return type:

SAND

mda(rule: CutRule = GaussSeidel())[source]

A multidisciplinary analysis: one closure per cycle, and no design.

Return type:

MDA

Submodules