Note
Go to the end to download the full example code.
Custom Model TemplateΒΆ
CustomMetaprogrammedType.__prepare__ with new_kwarg=None
CustomMetaprogrammedType.__new__ with new_kwarg=None
CustomMetaprogrammedType.processs_placeholders for <CustomMetaprogrammed: MyModel0> is a good place for manipulating substitutions
CustomMetaprogrammedType.__prepare__ with new_kwarg=handle a string
CustomMetaprogrammedType.__new__ with new_kwarg=handle a string
CustomMetaprogrammedType.processs_placeholders for <CustomMetaprogrammed: MyModel1> is a good place for manipulating substitutions
Use for something like ReferenceFrame, it's also possible to modify the kwargs
<ModelsCouldAlwaysTakeNonCondorInputs: x=1.2>
import condor as co
class CustomMetaprogrammedType(co.ModelType):
@classmethod
def process_placeholders(cls, new_cls, attrs):
print(
f"CustomMetaprogrammedType.processs_placeholders for {new_cls} is a good "
"place for manipulating substitutions"
)
@classmethod
def __prepare__(cls, *args, new_kwarg=None, **kwargs):
"""
custom processing behavior use cases:
- condor-flight cross-substitution of vehicle state to environment models
(atmosphere/wind/gravity/etc)
- lincov generation of augmented covariance state, propagation/correction/update
equations, etc.
catching custom metaclass arguments use cases:
big gascon: component inputs and sub-assembly declaration (like a primary model)
then singleton submodels for "outputs", but these are not condor built-in
submodels, gascon will define a template for each:
- weight with "subtotal" placheolder
- aero with lift-curve slope, equivalent wetted area, etc, placeholder +
potentially dynamic inputs?
- propulsion with dynamic inputs (maybe base aircraft provides all the core
state plus flight conditions, etc.) and placeholder for thrust, incidence
angle, and state field for adding new state
so primary component model metaclass will have to have a slot for these gascon
output submodels
so the gascon output submodel will at least bind to the primary model template
its when the primary is inserted into a parent assembly that the output
submodels really get processed, and then combined into the parents as needed?
will the assembly user model
class Component(ComponentTemplate):
input = field()
class Weight(GasconComponentOutput):
subtotal = placeholder()
class Aero(GasconComponentOutput):
lift_curve_slope = placeholder()
flat_plate_equivalent_area = placeholder()
class Propulsion(GasconComponentOutput):
state = field()
thrust_lbf = placeholder()
incidence_angle = placeholder()
# this is a bad example since we will use a custom metaclass for lots of the
# propulsion models for the engine decks...
class Turbofan(Component):
fan_diameter_ft = input()
sls_airflow = input()
# require location?
class Performance(Turbofan):
thrust = ...
class EngineOutDrag(Turbofan):
drag_lbf = ...
# I kinda like this syntax, use the name of the "subclass" to figure out which
# template to use?
"""
print(f"CustomMetaprogrammedType.__prepare__ with new_kwarg={new_kwarg}")
return super().__prepare__(*args, **kwargs)
def __new__(cls, *args, new_kwarg=None, **kwargs):
print(f"CustomMetaprogrammedType.__new__ with new_kwarg={new_kwarg}")
new_cls = super().__new__(cls, *args, **kwargs)
return new_cls
class CustomMetaprogrammed(co.ModelTemplate, model_metaclass=CustomMetaprogrammedType):
pass
class MyModel0(CustomMetaprogrammed):
pass
class MyModel1(CustomMetaprogrammed, new_kwarg="handle a string"):
pass
class ModelsCouldAlwaysTakeNonCondorInputs(co.ExplicitSystem):
x = input()
output.y = x**2
def __init__(self, *args, my_kwarg=None, **kwargs):
print(
"Use for something like ReferenceFrame, it's also possible to modify the "
"kwargs"
)
# store frame state as condor elements, then can use normal python type logic to
# compose bigger expressions like finding path from arbitrary frames -- but
# would need to do something to make sure that the extra kwargs were saved and
# re-bound as needed... or maybe it's okay if they're not? the final expression
# which will get used with the bound thing will be right? not sure.
# it's also possible to manipulate the (k)wargs that get passed to super based
# on my_kwarg -- is that a way this could work?
super().__init__(*args, **kwargs)
ModelsCouldAlwaysTakeNonCondorInputs(1.2)
Total running time of the script: (0 minutes 0.004 seconds)