Design Space Modeling: Python API¶
This notebook demonstrates how to model an architecture design space using the Python API. Refer to the API reference if needed.
The modeling process is managed by the GraphApiManager:
this object ensures that everything in the design space model is correct and consistent,
applies external element linking rules, creates the underlying Architecture Design Space Graph (ADSG),
derives architectural choices, and checks if there are any issues with the design space.
import adore as ad
# Create a manager for an empty project
manager = ad.GraphApiManager()
project = manager.project
factory = manager.factory # Factory should be created by the manager!
project.name = 'Python API Demo Project'
# The project has an empty context and system
print(project)
# Set to `False` to interactively view the ADORE model within an
# interactive Jupyter notebook
externalize_js = True
Project: Python API Demo Project
design_space: DesignSpace
context: SystemContext "System Context" (id=1)
system: System "System" (id=2)
n_inst: [1]
# Get a reference to the top-level system
system = project.design_space.system
# Create a function and add it to the system
gen_thrust = factory.function(name='Generate Thrust')
system.functions.append(gen_thrust)
# Create a component that fulfills the function
turbofan = factory.component(
name='Turbofan',
fulfilled_function_ids=[gen_thrust.id],
)
system.components.append(turbofan)
# Anytime you modify the project, run manager.sync()
manager.sync()
print(project)
# Show the project interactively in a notebook
manager.show_project(height=300, externalize_js=externalize_js)
Project: Python API Demo Project
design_space: DesignSpace
context: SystemContext "System Context" (id=1)
is_conditional: False
system: System "System" (id=2)
is_conditional: False
n_inst: [1]
functions:
- Function "Generate Thrust" (id=3; ref=generate-thrust)
is_conditional: False
components:
- Component "Turbofan" (id=4; ref=turbofan)
is_conditional: False
n_inst: [1]
fulfilled_function_ids: Function(Generate Thrust; id=3)
# Create another component that fulfills the same function
propeller = factory.component(
name='Propeller',
fulfilled_function_ids=[gen_thrust.id],
n_inst=[1, 2], # There can be 1 or 2 instances of the propeller
)
system.components.append(propeller)
# Observe that now two architectural choices ("decision") are added
manager.sync()
with ad.pretty_printing_context(project):
for choice in project.design_space.decisions:
print(choice)
Decision (id=6); OPTION; FUNCTION_FULFILL n_opts: 2 source_ref_element_ids: Function(Generate Thrust; id=3) target_ref_element_ids: Component(Propeller; id=5), Component(Turbofan; id=4) Decision (id=7); OPTION; COMPONENT_INSTANTIATION n_opts: 2 source_ref_element_ids: Component(Propeller; id=5) target_ref_element_ids: Component(Propeller; id=5)
# We can also calculate design space statistics
# (be careful as this can take a long time if there are
# complicated port connection choices that need to be encoded)
manager.sync_decision_stats(encoding_timeout=10.)
print(project.design_space.stats)
# As can be seen, there are now 3 valid architectures
Statistics n_valid: 3 n_declared: 4 information_index: 1.0 imputation_ratio: 1.3333333333333333 imputation_ratio_comb: 1.3333333333333333 imputation_ratio_cont: 1.0 distance_correlation: 0.0 encoder: complete n_discrete: 2 n_existence: 1 n_dim_cont: 0 n_dim_cont_mean: 0.0
manager.show_project(height=300, externalize_js=externalize_js)
# We also show the underlying ADSG
manager.adore_graph.render()
Quantities of Interest (QOIs)¶
Quantities of Interest represent input and output parameters, associated to systems, functions or component (instances).
It is recommended to always explicitly specify the QOI type to prevent confusion.
# Define a system-level objective
system.qois.append(
factory.qoi(name='System Mass', units='kg', type_=ad.QOIType.OBJECTIVE),
)
# Define QOIs on the function
gen_thrust.qois += [
# Constraint
factory.qoi(name='Rated Thrust', units='kN', ref_value=400,
pos_better=True, type_=ad.QOIType.CONSTRAINT),
# Static input
factory.qoi(name='Cruise Altitude', units='ft', value=35000,
type_=ad.QOIType.INPUT_PARAM),
]
# Define QOIs on the components
turbofan.qois += [
# Continuous design variable
factory.qoi(name='Bypass Ratio', bounds=(5., 15.),
type_=ad.QOIType.DESIGN_VAR),
# Output metric
factory.qoi(name='Inlet Pressure', units='Pa', type_=ad.QOIType.METRIC),
]
# Independent QOIs for each instance of the propeller
propeller.instance_qois += [
# Discrete design variable
factory.qoi(name='Blades', options=["2", "3", "4", "6", "8"],
type_=ad.QOIType.DESIGN_VAR),
]
# Update
manager.sync()
manager.sync_decision_stats()
print(project.design_space.stats)
manager.show_project(externalize_js=externalize_js)
Statistics n_valid: 31 n_declared: 100 information_index: 0.5315514604066738 imputation_ratio: 9.677419354838708 imputation_ratio_comb: 3.225806451612903 imputation_ratio_cont: 3.0 distance_correlation: 0.0 encoder: complete n_discrete: 4 n_existence: 1 n_dim_cont: 1 n_dim_cont_mean: 0.3333333333333333
# Create some new functions to work with
provide_shaft_power = factory.function(name='Provide Shaft Power')
reverse_thrust = factory.function(name='Reverse Thrust')
provide_power = factory.function(name='Provide Power')
provide_elec_power = factory.function(name='Provide Electrical Power')
provide_dc_power = factory.function(name='Provide DC Power')
convert_dc_to_ac = factory.function(name='Convert DC to AC')
system.functions += [
provide_shaft_power, reverse_thrust, provide_power,
provide_elec_power, provide_dc_power, convert_dc_to_ac,
]
# The propeller needs "Provide Shaft Power", which can be fulfilled by:
# - An electric motor
# - A turboshaft
# - Or both (hybrid)
propeller.needed_function_ids = [provide_shaft_power.id]
hybrid = factory.multi_fulfillment(
name='Hybrid',
function_ids=[provide_shaft_power.id],
)
system.multi_fulfillments.append(hybrid)
electric_motor = factory.component(
name='Electric Motor',
fulfilled_function_ids=[hybrid.id, provide_shaft_power.id],
# Electric motor additionally needs the provide power function
needed_function_ids=[provide_power.id],
)
turboshaft = factory.component(
name='Turboshaft',
fulfilled_function_ids=[hybrid.id, provide_shaft_power.id],
)
system.components += [
# The components either fulfill the function directly
# or through the multi-fulfillment element
electric_motor,
turboshaft,
]
# Synchronizing shows that the "provide power" function is not fulfilled
manager.sync()
with ad.pretty_printing_context(project):
print(system.multi_fulfillments[0])
print(electric_motor)
for issue in (project.design_space.issues or []):
print(issue)
MultiFulfillment "Hybrid" (id=23; ref=hybrid) function_ids: Function(Provide Shaft Power; id=17) Component "Electric Motor" (id=24; ref=electric-motor) n_inst: [1] fulfilled_function_ids: MultiFulfillment(Hybrid; id=23), Function(Provide Shaft Power; id=17) needed_function_ids: Function(Provide Power; id=19) Issue type: Function must be fulfilled by at least one component, decomposition, concept or multi/non-fulfillment. (FUNCTION_NOT_FULFILLED) element_ids: Function(Provide Power; id=19)
Non-fulfillment¶
# Reverse thrust can either be fulfilled by a reverser system or not
turbofan.needed_function_ids = [reverse_thrust.id]
system.components.append(
factory.component(
name='Reverser System', fulfilled_function_ids=[reverse_thrust.id]),
)
system.non_fulfillments.append(
factory.non_fulfillment(name='N/A', function_ids=[reverse_thrust.id]),
)
manager.sync()
with ad.pretty_printing_context(project):
print(system.non_fulfillments[0])
NonFulfillment "N/A" (id=28; ref=n-a) function_ids: Function(Reverse Thrust; id=18)
Concept¶
# A concept maps a neutral to a specific function
# Here shown as a demonstration
system.concepts.append(
factory.concept(
name='Electrical',
neutral_function_id=provide_power.id,
specific_function_id=provide_elec_power.id,
)
)
# Synchronizing shows that "provide electric power" is not fulfilled
manager.sync()
with ad.pretty_printing_context(project):
print(system.concepts[0])
for issue in (project.design_space.issues or []):
print(issue)
Concept "Electrical" (id=30; ref=electrical) neutral_function_id: Function(Provide Power; id=19) specific_function_id: Function(Provide Electrical Power; id=20) Issue type: Function must be fulfilled by at least one component, decomposition, concept or multi/non-fulfillment. (FUNCTION_NOT_FULFILLED) element_ids: Function(Provide Electrical Power; id=20)
Decomposition¶
# Provide electric power is decomposed into two functions
system.decompositions.append(
factory.decomposition(
name='AC Power',
emerged_function_id=provide_elec_power.id,
zoomed_function_ids=[
provide_dc_power.id,
convert_dc_to_ac.id,
],
),
)
# Add components to fulfill the zoomed (decomposed) functions
system.components += [
factory.component(
name='DC Bus', fulfilled_function_ids=[provide_dc_power.id]),
factory.component(
name='Inverter', fulfilled_function_ids=[convert_dc_to_ac.id]),
]
# Now there are no more issues
manager.sync()
with ad.pretty_printing_context(project):
print(system.decompositions[0])
manager.show_project(externalize_js=externalize_js)
Decomposition "AC Power" (id=31; ref=ac-power) emerged_function_id: Function(Provide Electrical Power; id=20) zoomed_function_ids: Function(Provide DC Power; id=21), Function(Convert DC to AC; id=22)
Subsystem¶
Systems can recursively contain (sub)systems, and the number of (sub)system instances can be an architectural choice.
# Systems cannot just exist by themselves, they should at least fulfill
# something in a higher-level system
provide_hyd_power = factory.function(name='Provide Hydraulic Power')
system.functions.append(provide_hyd_power)
# Create a hydraulic system that can be instantiated 1, 2 or 3 times
generate_pressure = factory.function(name='Generate Pressure')
engine_driven_pumps = factory.component(
name='Engine-driven Pumps',
fulfilled_function_ids=[generate_pressure.id],
)
hyd_system = factory.system(
name='Hydraulic System',
n_inst=[1, 2, 3],
functions=[generate_pressure],
components=[
factory.component(
name='Hydraulic Lines',
fulfilled_function_ids=[provide_hyd_power.id],
needed_function_ids=[generate_pressure.id],
),
factory.component(
name='Electric Pumps',
fulfilled_function_ids=[generate_pressure.id],
),
engine_driven_pumps,
],
)
system.systems.append(hyd_system)
manager.sync()
with ad.pretty_printing_context(project):
print(hyd_system)
manager.show_project(externalize_js=externalize_js)
System "Hydraulic System" (id=39; ref=hydraulic-system)
is_conditional: False
n_inst: [1, 2, 3]
functions:
- Function "Generate Pressure" (id=35; ref=generate-pressure)
components:
- Component "Hydraulic Lines" (id=37; ref=hydraulic-lines)
n_inst: [1]
fulfilled_function_ids: Function(Provide Hydraulic Power; id=34)
needed_function_ids: Function(Generate Pressure; id=35)
- Component "Electric Pumps" (id=38; ref=electric-pumps)
n_inst: [1]
fulfilled_function_ids: Function(Generate Pressure; id=35)
- Component "Engine-driven Pumps" (id=36; ref=engine-driven-pumps)
n_inst: [1]
fulfilled_function_ids: Function(Generate Pressure; id=35)
Ports¶
Ports connect components to components and are subject to port connector constraints.
# Define the port
port = factory.port(name='Connection')
system.ports.append(port)
# Define that we can either have 1 or 2 turboshafts
turboshaft.n_inst = [1, 2]
# Connect the port from the turboshafts to the engine-driven pumps
turboshaft.output_ports.append(
factory.port_connection(
port_id=port.id,
# The actual connection constraints are specified in the ConnSpec
# For the turboshaft: 0 or more connections (no repetitions)
conn=factory.conn_spec(
n_range_min=0,
repeat_allowed=False,
),
)
)
engine_driven_pumps.input_ports.append(
factory.port_connection(
port_id=port.id,
# Each engine-driven pump needs 1 connection
conn=factory.conn_spec(
n_specific=[1],
),
)
)
manager.sync()
manager.sync_decision_stats()
with ad.pretty_printing_context(project):
print(port)
print(turboshaft)
manager.show_project(externalize_js=externalize_js)
# Print the connection choice statistics: there are 36 possible connection sets
connection_choice = project.design_space.decisions[9]
assert connection_choice.operation == ad.DecisionOperation.PORT_CONNECTION
print(f'Statistics for: {connection_choice!s}')
print(connection_choice.stats)
Port "Connection" (id=44; ref=connection)
Component "Turboshaft" (id=25; ref=turboshaft)
n_inst: [1, 2]
fulfilled_function_ids: MultiFulfillment(Hybrid; id=23), Function(Provide Shaft Power; id=17)
output_ports:
- PortConnection "Port" (id=45)
port_id: Port(Connection; id=44)
n_inst: [1]
conn: ConnSpec
n_range_min: 0
repeat_allowed: False
grouping: BY_COMPONENT_INSTANCE
self_connect_allowed: True
Statistics for: Decision (id=48); PERMUTATION; PORT_CONNECTION source_ref_element_ids: [45, 44, 25] target_ref_element_ids: [46, 44, 36] Statistics n_valid: 36 n_declared: 8 information_index: 1.0 imputation_ratio: 5.333333333333333 imputation_ratio_comb: 5.333333333333333 imputation_ratio_cont: 1.0 distance_correlation: 0.9999999999999999 encoder: Group By Element Norm Grp + Auto Mod Imp n_discrete: 3 n_existence: 24 n_dim_cont: 0 n_dim_cont_mean: 0.0
Incompatibility Constraints¶
Incompatibility constraints are a type of structural constraint, and declare that two elements may never exist together in an architecture instance.
# Add an incompatibility constraint between the
# engine-driven pumps and the electric motor
project.design_space.structural_constraints.append(
factory.structural_constraint(
type_=ad.StructuralConstraintType.INCOMPATIBILITY,
element_ids=[electric_motor.id, engine_driven_pumps.id],
)
)
manager.sync()
manager.show_project(externalize_js=externalize_js)
Choice Constraints¶
manager.sync()
manager.sync_decision_stats()
n_valid_before = project.design_space.stats.n_valid
print(f'Possible architecture before adding the constraint: {n_valid_before}')
# Get all "generate pressure" fulfillment choices
# (one for each hydraulic system instance)
gen_pressure_fulfillment_choices = [
choice for choice in project.design_space.decisions
if choice.operation == ad.DecisionOperation.FUNCTION_FULFILL and
choice.source_ref_element_ids[0] == generate_pressure.id]
assert len(gen_pressure_fulfillment_choices) == 3
# Add a choice constraint to ensure that all hydraulic systems either use
# electric pumps or engine-driven pumps
project.design_space.structural_constraints.append(
factory.structural_constraint(
type_=ad.StructuralConstraintType.LINKED_DECISIONS,
element_ids=[choice.id for choice in gen_pressure_fulfillment_choices],
)
)
# Show that there are now less possible architectures due to the constraint
manager.sync()
manager.sync_decision_stats()
n_valid_after = project.design_space.stats.n_valid
print(f'Possible architecture after adding the constraint: {n_valid_after} '
f'({100*((n_valid_before-n_valid_after)/n_valid_before):.0f}% less)')
Possible architecture before adding the constraint: 1866 Possible architecture after adding the constraint: 966 (48% less)
Generating Architectures¶
To generate architectures, we first formalize the design space as a design problem, and then create architectures by passing design vectors.
# Formalize the design space as a design problem
translator = manager.get_design_problem_translator()
print(project.design_problems[0])
DesignProblem "Design Problem #1" (id=52)
encoder: complete
design_vars [n=13]:
- DiscreteDesignVar (id=53)
decision_id: 40
options: ['1 time', '2 times', '3 times']
- DiscreteDesignVar (id=54)
decision_id: 6
options: ['Propeller', 'Turbofan']
- DiscreteDesignVar (id=55)
decision_id: 29
options: ['N/A', 'Reverser System']
- DiscreteDesignVar (id=56)
decision_id: 26
options: ['Electric Motor', 'Hybrid', 'Turboshaft']
- DiscreteDesignVar (id=57) @ sys 0
decision_id: 41
options: ['Electric Pumps', 'Engine-driven Pumps']
- DiscreteDesignVar (id=58)
decision_id: 7
options: ['1 time', '2 times']
- DiscreteDesignVar (id=59)
decision_id: 47
options: ['1 time', '2 times']
- DiscreteDesignVar (id=60)
decision_id: 48
options: ['0', '1']
- DiscreteDesignVar (id=61)
decision_id: 48
options: ['0', '1']
- DiscreteDesignVar (id=62)
decision_id: 48
options: ['0', '1']
- DiscreteDesignVar (id=63) @ comp 0
decision_id: 14
qoi_id: 13
options: ['2', '3', '4', '6', '8']
- DiscreteDesignVar (id=64) @ comp 1
decision_id: 15
qoi_id: 13
options: ['2', '3', '4', '6', '8']
- ContinuousDesignVar (id=65)
decision_id: 16
qoi_id: 11
bounds: [5.0, 15.0]
objectives:
- Objective (id=66)
qoi_id: 8
maximize: False
constraints:
- Constraint (id=67)
qoi_id: 9
pos_feasible: True
ref_value: 400.0
metrics:
- Metric (id=68)
qoi_id: 12
always_exists: False
# Generate several random architectures
for i in range(5):
architecture, design_vector, activeness_vector = translator.get_architecture(
translator.get_random_design_vector(), append=True)
print(f'Generated architecture #{i+1}: {design_vector}')
if i == 0:
with ad.pretty_printing_context(project):
print(architecture)
manager.show_project(show_architecture_id=architecture.id, externalize_js=externalize_js)
Generated architecture #1: [2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 4, 10.0]
Architecture "Architecture #1" (id=69)
final: True
feasible: True
perf_evaluated: False
design_vars [n=13]:
- ArchDiscreteDesignVar (id=113)
design_var_id: 53
active: True
options: ['1 time', '2 times', '3 times']
option_index: 2
- ArchDiscreteDesignVar (id=114)
design_var_id: 54
active: True
options: ['Propeller', 'Turbofan']
option_index: 0
- ArchDiscreteDesignVar (id=115)
design_var_id: 55
active: False
options: ['N/A', 'Reverser System']
option_index: 0
- ArchDiscreteDesignVar (id=116)
design_var_id: 56
active: True
options: ['Electric Motor', 'Hybrid', 'Turboshaft']
option_index: 0
- ArchDiscreteDesignVar (id=117)
design_var_id: 57
active: True
options: ['Electric Pumps', 'Engine-driven Pumps']
option_index: 0
- ArchDiscreteDesignVar (id=118)
design_var_id: 58
active: True
options: ['1 time', '2 times']
option_index: 1
- ArchDiscreteDesignVar (id=119)
design_var_id: 59
active: False
options: ['1 time', '2 times']
option_index: 0
- ArchDiscreteDesignVar (id=120)
design_var_id: 60
active: False
options: ['0', '1']
option_index: 0
- ArchDiscreteDesignVar (id=121)
design_var_id: 61
active: False
options: ['0', '1']
option_index: 0
- ArchDiscreteDesignVar (id=122)
design_var_id: 62
active: False
options: ['0', '1']
option_index: 0
- ArchDiscreteDesignVar (id=123)
design_var_id: 63
arch_qoi_id: 89
active: True
options: ['2', '3', '4', '6', '8']
option_index: 4
- ArchDiscreteDesignVar (id=124)
design_var_id: 64
arch_qoi_id: 91
active: True
options: ['2', '3', '4', '6', '8']
option_index: 4
- ArchContinuousDesignVar (id=125)
design_var_id: 65
active: False
bounds: [5.0, 15.0]
value: 10.0
objectives:
- ArchObjective (id=126)
objective_id: 66
arch_qoi_id: 100
maximize: False
constraints:
- ArchConstraint (id=127)
constraint_id: 67
arch_qoi_id: 73
pos_feasible: True
ref_value: 400.0
context: ArchSystemContext "System Context" (id=70)
element_id: SystemContext(System Context; id=1)
system: ArchSystem "System" (id=71)
element_id: System(System; id=2)
index: 0
functions [n=7]:
- ArchFunction "Generate Thrust" (id=72; ref=generate-thrust)
element_id: Function(Generate Thrust; id=3)
boundary_function: True
qois:
- ArchQOI "Rated Thrust" (id=73; ref=rated-thrust)
element_id: Qoi(Rated Thrust; id=9)
type: CONSTRAINT
evaluated: False
units: kN
- ArchQOI "Cruise Altitude" (id=74; ref=cruise-altitude)
element_id: Qoi(Cruise Altitude; id=10)
type: INPUT_PARAM
evaluated: False
value: 35000.0
units: ft
- ArchFunction "Provide Shaft Power" (id=75; ref=provide-shaft-power)
element_id: Function(Provide Shaft Power; id=17)
boundary_function: False
- ArchFunction "Provide Power" (id=76; ref=provide-power)
element_id: Function(Provide Power; id=19)
boundary_function: False
- ArchFunction "Provide Electrical Power" (id=77; ref=provide-electrical-power)
element_id: Function(Provide Electrical Power; id=20)
boundary_function: False
- ArchFunction "Provide DC Power" (id=78; ref=provide-dc-power)
element_id: Function(Provide DC Power; id=21)
boundary_function: False
- ArchFunction "Convert DC to AC" (id=79; ref=convert-dc-to-ac)
element_id: Function(Convert DC to AC; id=22)
boundary_function: False
- ArchFunction "Provide Hydraulic Power" (id=80; ref=provide-hydraulic-power)
element_id: Function(Provide Hydraulic Power; id=34)
boundary_function: True
components:
- ArchComponent "Propeller" (id=87; ref=propeller)
element_id: Component(Propeller; id=5)
fulfilled_arch_function_ids: [72]
needed_arch_function_ids: [75]
instances:
- ArchComponentInstance #0
qois:
- ArchQOI "Blades" (id=89; ref=blades)
element_id: Qoi(Blades; id=13)
type: DESIGN_VAR
evaluated: False
value_str: 8
option_index: 4
- ArchComponentInstance #1
qois:
- ArchQOI "Blades" (id=91; ref=blades)
element_id: Qoi(Blades; id=13)
type: DESIGN_VAR
evaluated: False
value_str: 8
option_index: 4
- ArchComponent "Electric Motor" (id=92; ref=electric-motor)
element_id: Component(Electric Motor; id=24)
fulfilled_arch_function_ids: [75]
needed_arch_function_ids: [76]
instances:
- ArchComponentInstance #0
- ArchComponent "DC Bus" (id=94; ref=dc-bus)
element_id: Component(DC Bus; id=32)
fulfilled_arch_function_ids: [78]
instances:
- ArchComponentInstance #0
- ArchComponent "Inverter" (id=96; ref=inverter)
element_id: Component(Inverter; id=33)
fulfilled_arch_function_ids: [79]
instances:
- ArchComponentInstance #0
decompositions:
- ArchDecomposition "AC Power" (id=99; ref=ac-power)
element_id: Decomposition(AC Power; id=31)
emerged_arch_function_id: 77
zoomed_arch_function_ids: [78, 79]
concepts:
- ArchConcept "Electrical" (id=98; ref=electrical)
element_id: Concept(Electrical; id=30)
neutral_arch_function_id: 76
specific_arch_function_id: 77
qois:
- ArchQOI "System Mass" (id=100; ref=system-mass)
element_id: Qoi(System Mass; id=8)
type: OBJECTIVE
evaluated: False
units: kg
systems:
- ArchSystem "Hydraulic System" (id=81; ref=hydraulic-system)
element_id: System(Hydraulic System; id=39)
index: 0
functions:
- ArchFunction "Generate Pressure" (id=82; ref=generate-pressure)
element_id: Function(Generate Pressure; id=35)
boundary_function: False
components:
- ArchComponent "Hydraulic Lines" (id=101; ref=hydraulic-lines)
element_id: Component(Hydraulic Lines; id=37)
fulfilled_arch_function_ids: [80]
needed_arch_function_ids: [82]
instances:
- ArchComponentInstance #0
- ArchComponent "Electric Pumps" (id=103; ref=electric-pumps)
element_id: Component(Electric Pumps; id=38)
fulfilled_arch_function_ids: [82]
instances:
- ArchComponentInstance #0
- ArchSystem "Hydraulic System" (id=83; ref=hydraulic-system)
element_id: System(Hydraulic System; id=39)
index: 1
functions:
- ArchFunction "Generate Pressure" (id=84; ref=generate-pressure)
element_id: Function(Generate Pressure; id=35)
boundary_function: False
components:
- ArchComponent "Hydraulic Lines" (id=105; ref=hydraulic-lines)
element_id: Component(Hydraulic Lines; id=37)
fulfilled_arch_function_ids: [80]
needed_arch_function_ids: [84]
instances:
- ArchComponentInstance #0
- ArchComponent "Electric Pumps" (id=107; ref=electric-pumps)
element_id: Component(Electric Pumps; id=38)
fulfilled_arch_function_ids: [84]
instances:
- ArchComponentInstance #0
- ArchSystem "Hydraulic System" (id=85; ref=hydraulic-system)
element_id: System(Hydraulic System; id=39)
index: 2
functions:
- ArchFunction "Generate Pressure" (id=86; ref=generate-pressure)
element_id: Function(Generate Pressure; id=35)
boundary_function: False
components:
- ArchComponent "Hydraulic Lines" (id=109; ref=hydraulic-lines)
element_id: Component(Hydraulic Lines; id=37)
fulfilled_arch_function_ids: [80]
needed_arch_function_ids: [86]
instances:
- ArchComponentInstance #0
- ArchComponent "Electric Pumps" (id=111; ref=electric-pumps)
element_id: Component(Electric Pumps; id=38)
fulfilled_arch_function_ids: [86]
instances:
- ArchComponentInstance #0
Generated architecture #2: [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10.3535525668946]
Generated architecture #3: [2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 10.0]
Generated architecture #4: [1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 2, 2, 10.0]
Generated architecture #5: [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 4, 0, 10.0]
Loading and Saving Projects¶
# Write to and read from a file
manager.to_file('project.adore')
manager2 = manager.from_file('project.adore')
print(manager2.project.name)
# Serialize to/from bytes
data = manager.to_file_contents()
manager3 = manager.from_file_content(data)
print(manager3.project.name)
Python API Demo Project Python API Demo Project