def test_connect(self): x = XDSM(use_sfmath=False) x.add_system("D1", FUNC, "D_1", label_width=2) x.add_system("D2", FUNC, "D_2", stack=False) try: x.connect("D1", "D2", r"\mathcal{R}(y_1)", "foobar") except ValueError as err: self.assertEquals(str(err), "label_width argument must be an integer") else: self.fail("Expected ValueError")
def test_connect(self): x = XDSM(use_sfmath=False) x.add_system('D1', 'Function', 'D_1', label_width=2) x.add_system('D2', 'Function', 'D_2', stack=False) try: x.connect('D1', 'D2', r'\mathcal{R}(y_1)', 'foobar') except ValueError as err: self.assertEquals(str(err), 'label_width argument must be an integer') else: self.fail('Expected ValueError')
def test_stacked_system(self): x = XDSM() x.add_system("test", OPT, r"\text{test}", stack=True) file_name = "stacked_test" x.write(file_name) tikz_file = file_name + ".tikz" with open(tikz_file, "r") as f: tikz = f.read() self.assertIn(r"\node [Optimization,stack]", tikz)
def test_write_outdir(self): fname = "test" for abspath in [True, False]: subdir = tempfile.mkdtemp(dir=self.tempdir) outdir = subdir if abspath else os.path.basename(subdir) x = XDSM() x.add_system("x", FUNC, "x") x.write(fname, outdir=outdir) for ext in [".tex", ".tikz", ".pdf"]: self.assertTrue( os.path.isfile(os.path.join(subdir, fname + ext))) # no files outside the subdirs self.assertFalse( any(os.path.isfile(fp) for fp in os.listdir(self.tempdir)))
def test_tikz_content(self): # Check if TiKZ file was created. # Compare the content of the sample below and the newly created TiKZ file. sample_txt = r""" %%% Preamble Requirements %%% % \usepackage{geometry} % \usepackage{amsfonts} % \usepackage{amsmath} % \usepackage{amssymb} % \usepackage{tikz} % Optional packages such as sfmath set through python interface % \usepackage{sfmath} % \usetikzlibrary{arrows,chains,positioning,scopes,shapes.geometric,shapes.misc,shadows} %%% End Preamble Requirements %%% \input{"path/to/diagram_styles"} \begin{tikzpicture} \matrix[MatrixSetup]{ %Row 0 \node [DataIO] (left_output_opt) {$x^*, z^*$};& \node [Optimization] (opt) {$\text{Optimizer}$};& & \node [DataInter] (opt-D1) {$x, z$};& \node [DataInter] (opt-D2) {$z$};& \node [DataInter] (opt-F) {$x, z$};& \\ %Row 1 & & \node [MDA] (solver) {$\text{Newton}$};& \node [DataInter] (solver-D1) {$y_2$};& \node [DataInter] (solver-D2) {$y_1$};& \node [DataInter] (solver-F) {$y_1, y_2$};& \node [DataInter] (solver-G) {$y_1, y_2$};\\ %Row 2 \node [DataIO] (left_output_D1) {$y_1^*$};& & \node [DataInter] (D1-solver) {$\mathcal{R}(y_1)$};& \node [Function] (D1) {$D_1$};& & & \\ %Row 3 \node [DataIO] (left_output_D2) {$y_2^*$};& & \node [DataInter] (D2-solver) {$\mathcal{R}(y_2)$};& & \node [Function] (D2) {$D_2$};& & \\ %Row 4 \node [DataIO] (left_output_F) {$f^*$};& \node [DataInter] (F-opt) {$f$};& & & & \node [Function] (F) {$F$};& \\ %Row 5 \node [DataIO] (left_output_G) {$g^*$};& \node [DataInter] (G-opt) {$g$};& & & & & \node [Function] (G) {$G$};\\ %Row 6 & & & & & & \\ }; % XDSM process chains \begin{pgfonlayer}{data} \path % Horizontal edges (opt) edge [DataLine] (opt-D1) (opt) edge [DataLine] (opt-D2) (opt) edge [DataLine] (opt-F) (solver) edge [DataLine] (solver-D1) (solver) edge [DataLine] (solver-D2) (D1) edge [DataLine] (D1-solver) (solver) edge [DataLine] (solver-F) (D2) edge [DataLine] (D2-solver) (solver) edge [DataLine] (solver-G) (F) edge [DataLine] (F-opt) (G) edge [DataLine] (G-opt) (opt) edge [DataLine] (left_output_opt) (D1) edge [DataLine] (left_output_D1) (D2) edge [DataLine] (left_output_D2) (F) edge [DataLine] (left_output_F) (G) edge [DataLine] (left_output_G) % Vertical edges (opt-D1) edge [DataLine] (D1) (opt-D2) edge [DataLine] (D2) (opt-F) edge [DataLine] (F) (solver-D1) edge [DataLine] (D1) (solver-D2) edge [DataLine] (D2) (D1-solver) edge [DataLine] (solver) (solver-F) edge [DataLine] (F) (D2-solver) edge [DataLine] (solver) (solver-G) edge [DataLine] (G) (F-opt) edge [DataLine] (opt) (G-opt) edge [DataLine] (opt); \end{pgfonlayer} \end{tikzpicture}""" filename = "xdsm_test_tikz" x = XDSM(use_sfmath=True) x.add_system("opt", OPT, r"\text{Optimizer}") x.add_system("solver", SOLVER, r"\text{Newton}") x.add_system("D1", FUNC, "D_1") x.add_system("D2", FUNC, "D_2") x.add_system("F", FUNC, "F") x.add_system("G", FUNC, "G") x.connect("opt", "D1", "x, z") x.connect("opt", "D2", "z") x.connect("opt", "F", "x, z") x.connect("solver", "D1", "y_2") x.connect("solver", "D2", "y_1") x.connect("D1", "solver", r"\mathcal{R}(y_1)") x.connect("solver", "F", "y_1, y_2") x.connect("D2", "solver", r"\mathcal{R}(y_2)") x.connect("solver", "G", "y_1, y_2") x.connect("F", "opt", "f") x.connect("G", "opt", "g") x.add_output("opt", "x^*, z^*", side="left") x.add_output("D1", "y_1^*", side="left") x.add_output("D2", "y_2^*", side="left") x.add_output("F", "f^*", side="left") x.add_output("G", "g^*", side="left") x.write(filename) # Check if file was created tikz_file = filename + ".tikz" self.assertTrue(os.path.isfile(tikz_file)) sample_lines = sample_txt.split("\n") sample_lines = filter_lines(sample_lines) with open(tikz_file, "r") as f: new_lines = filter_lines(f.readlines()) sample_no_match = [] # Sample text new_no_match = [] # New text for new_line, sample_line in zip(new_lines, sample_lines): if new_line.startswith(r"\input{"): continue if new_line != sample_line: # else everything is okay # This can be because of the different ordering of lines or because of an error. sample_no_match.append(new_line) new_no_match.append(sample_line) # Sort both sets of suspicious lines sample_no_match.sort() new_no_match.sort() for sample_line, new_line in zip(sample_no_match, new_no_match): # Now the lines should match, if only the ordering was different self.assertEqual(new_line, sample_line) # To be sure, check the length, otherwise a missing last line could get unnoticed because of using zip self.assertEqual(len(new_lines), len(sample_lines))
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' ecomp = 'Analysis' icomp = 'ImplicitAnalysis' group = 'Metamodel' func = 'Function' x = XDSM() #x.add_system('const', comp, r'\text{Constants}') x.add_system('DYMOS', opt, [r'\text{DYMOS}']) x.add_system('ambient', ecomp, [r'\text{Ambient}']) # x.add_system('USATM', comp, [r'\text{US Atm 1976}']) # x.add_system('mach_comp', comp, [r'\text{MACH}']) x.add_system('prop_comp', icomp, [r'\text{Propeller}', r'\text{(OpenBEMT)}']) x.add_system('e_comp', icomp, [r'\text{Electrical}', r'\text{(Zappy)}']) x.add_system('engine_comp', icomp, [r'\text{Turboshaft}', r'\text{(pyCycle)}']) # x.add_system('cool_comp', comp, [r'\text{Thermal}']) x.add_system('solver', solver, [r'\text{Solver}']) x.add_system('aero_comp', icomp, [r'\text{Wing Aerodynamics}', r'\text{(OpenAeroStruct)}']) x.add_system('flight_dynamics', ecomp, [r'\text{Flight Dynamics}']) # AKA prebalance x.add_system('balance', icomp, [r'\text{Balance}']) # x.add_system('drag_comp', comp, [r'\text{Aero Drag}']) x.add_system('EOM_comp', ecomp, [r'\text{State Rates}']) # x.add_system('', comp, r'\text{}')
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' comp = 'Analysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('opt', opt, r'\text{Optimizer}') x.add_system('solver', solver, r'\text{Newton}') x.add_system('D1', comp, r'D_1') x.add_system('D2', comp, r'D_2') x.add_system('F', func, r'F') x.add_system('G', func, r'G') x.connect('opt', 'D1', r'x, z') x.connect('opt', 'D2', r'z') x.connect('opt', 'F', r'x, z') x.connect('solver', 'D1', r'y_2') x.connect('solver', 'D2', r'y_1') x.connect('D1', 'solver', r'\mathcal{R}(y_1)') x.connect('solver', 'F', r'y_1, y_2') x.connect('D2', 'solver', r'\mathcal{R}(y_2)') x.connect('solver', 'G', r'y_1, y_2') x.connect('F', 'opt', r'f') x.connect('G', 'opt', r'g')
from pyxdsm.XDSM import XDSM # styling names for the boxes opt = 'Optimization' solver = 'MDA' ecomp = 'Analysis' icomp = 'ImplicitAnalysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('opt', opt, r'\text{Optimizer}') x.add_system('D1', ecomp, r'D_1') # can fade out blocks to allow for emphasis on sub-sections of XDSM x.add_system('D2', icomp, r'D_2', faded=True) # can fade out blocks to allow for emphasis on sub-sections of XDSM x.add_system('D3', icomp, r'D_3') # if you give the label as a list or tuple, it splits it onto multiple lines x.add_system('F', func, (r'F', r'\text{Functional}')) # stacked can be used to represent multiple instances that can be run in parallel x.add_system('G', func, r'G', stack=True) x.add_process(['opt', 'D1', 'D2', 'F', 'G', 'opt'], arrow=True) x.connect('opt', 'D1', r'x, z, y_2') x.connect('opt', 'D2', r'z, y_1')
from pyxdsm.XDSM import XDSM, OPT, SOLVER, FUNC, GROUP x = XDSM() x.add_system("top_opt", OPT, "Optimizer") x.add_system("sub_opt", OPT, "Sub\_Optimizer") x.add_system("comp_pitch_angles", FUNC, "ComputePitchAngle", stack=True) x.connect('top_opt', 'comp_pitch_angles', 'drag\_modifier') x.connect('comp_pitch_angles', 'top_opt', 'total\_power') x.connect("sub_opt", "comp_pitch_angles", "pitch\_angle", stack=True) x.connect("comp_pitch_angles", "sub_opt", "powers", stack=True) x.add_input("comp_pitch_angles", "wind\_speeds", stack=True) x.write("run_comp_pitch_angles_sub_opt")
def test_options(self): filename = 'xdsm_test_options' spec_dir = filename + '_specs' # Change `use_sfmath` to False to use computer modern x = XDSM(use_sfmath=False) x.add_system('opt', 'Optimization', r'\text{Optimizer}') x.add_system('solver', 'MDA', r'\text{Newton}') x.add_system('D1', 'Function', 'D_1', text_width=2.0) x.add_system('D2', 'Function', 'D_2', stack=False) x.add_system('F', 'Function', 'F', faded=True) x.add_system('G', 'Function', 'G', spec_name="G_spec") x.connect('opt', 'D1', 'x, z') x.connect('opt', 'D2', 'z') x.connect('opt', 'F', 'x, z') x.connect('solver', 'D1', 'y_2') x.connect('solver', 'D2', 'y_1') x.connect('D1', 'solver', r'\mathcal{R}(y_1)') x.connect('solver', 'F', 'y_1, y_2') x.connect('D2', 'solver', r'\mathcal{R}(y_2)') x.connect('solver', 'G', 'y_1, y_2') x.connect('F', 'opt', 'f') x.connect('G', 'opt', 'g') x.add_output('opt', 'x^*, z^*', side='right') x.add_output('D1', 'y_1^*', side='left', stack=True) x.add_output('D2', 'y_2^*', side='left') x.add_output('F', 'f^*', side='left') x.add_output('G', 'g^*') x.write(filename) x.write_sys_specs(spec_dir) # Test if files where created self.assertTrue(os.path.isfile(filename + '.tikz')) self.assertTrue(os.path.isfile(filename + '.tex')) self.assertTrue(os.path.isdir(spec_dir)) self.assertTrue(os.path.isfile(os.path.join(spec_dir, 'F.json'))) self.assertTrue(os.path.isfile(os.path.join(spec_dir, 'G_spec.json')))
Created on Wed Oct 10 10:22:59 2018 @author: xx """ from pyxdsm.XDSM import XDSM # opt = 'Optimization' comp = 'Analysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('opt', opt, r'\text{Optimizer}') x.add_system('A', comp, r'\text{Aerodynamics}') x.add_system('L', comp, r'\text{Loads}') x.add_system('S', comp, r'\text{Structures}') x.add_system('P', comp, r'\text{Performance}') x.add_system('O', func, r'\text{Objective}') x.add_system('I', func, r'\text{Inequality Constraints}') x.add_system('C', func, r'\text{Consistency Constraints}') x.connect( 'opt', 'A', r'S_{e},b_{e},\lambda_{e},\Lambda_{LE},\\CST_{root},CST_{tip},\phi_{e},\hat{MTOW},\hat{W_{f}}' ) x.connect( 'opt', 'L', r'S_{e},b_{e},\lambda_{e},\Lambda_{LE},\\CST_{root},CST_{tip},\phi_{e},\hat{MTOW},\hat{W_{f}}'
from pyxdsm.XDSM import XDSM, OPT, SOLVER, FUNC x = XDSM() # Instantiate on-diagonal blocks # order of args goes: object name, type of object, string for block on XDSM x.add_system('opt', OPT, r'\text{Optimizer}') x.add_system('rotor', FUNC, r'\text{RotorSE}') x.add_system('drive', FUNC, r'\text{DrivetrainSE}') x.add_system('tower', FUNC, r'\text{TowerSE}') x.add_system('CSM', FUNC, r'\text{NREL CSM}') x.add_system('BOS', FUNC, r'\text{LandBOSSE}') x.add_system('costs', FUNC, r'\text{Plant\_FinanceSE}') # Feed-forward connections; from, to, name for connections x.connect('opt', 'rotor', r'\text{Blade design variables}') x.connect('rotor', 'drive', r'\text{Performance, loads}') x.connect('rotor', 'BOS', r'\text{Rotor and blade mass}') x.connect('drive', 'tower', (r'\text{Forces, moments,}', r'\text{mass properties}')) x.connect('tower', 'CSM', r'\text{Tower mass}') x.connect('drive', 'CSM', r'\text{Drivetrain mass}') x.connect('rotor', 'CSM', r'\text{Rotor mass}') x.connect('CSM', 'BOS', r'\text{Turbine mass and costs}') x.connect('BOS', 'costs', r'\text{BOS costs}') # Feed-backward connections x.connect('drive', 'rotor', r'\text{Efficiency}') x.connect('costs', 'opt', r'\text{Cost and profit values}') x.connect('tower', 'opt', (r'\text{Tower stress and}', r'\text{buckling values}')) x.connect('rotor', 'opt', (r'\text{Blade tip deflection,}', r'\text{blade strains}'))
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' comp = 'Analysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('d1', comp, r'\TwolineComponent{10em}{Discipline 1}{$y_1 = z_1^2 + z_2 + x_1 - 0.2y_2$}') x.add_system('d2', comp, r'\TwolineComponent{8em}{Discipline 2}{$y_2 = \sqrt{y_1} + z_1 + z_2$}') x.add_system('f', func, r'\TwolineComponent{10em}{Objective}{$f = x^2 + z_1 + y_1 + e^{-y_2}$}') x.add_system('g1', func, r'\TwolineComponent{7em}{Constraint 1}{$g1 = 3.16-y_1 $}') x.add_system('g2', func, r'\TwolineComponent{7em}{Constraint 2}{$g_2 = y_2 - 24.0$}') x.connect('d1', 'd2', r'$y_1$') x.connect('d1', 'f', r'$y_1$') x.connect('d1', 'g1', r'$y_1$') x.connect('d2', 'd1', r'$y_2$') x.connect('d2', 'f', r'$y_2$') x.connect('d2', 'g2', r'$y_2$') x.add_input('d1', r'$x, z_1, z_2$') x.add_input('d2', r'$z_1, z_2$') x.add_input('f', r'$x, z_1$') x.add_output('f', r'$f$', side='right')
x = XDSM() # Define styles OPT = "Optimization" SUBOPT = "SubOptimization" SOLVER = "MDA" DOE = "DOE" IFUNC = "ImplicitFunction" FUNC = "Function" GROUP = "Group" IGROUP = "ImplicitGroup" METAMODEL = "Metamodel" DataIO = "DataIO" DataInter = "DataInter" x.add_system("D1", FUNC, ["Discipline1", "y_1=z_1^2+z_2+x_1-0.2y_2"]) x.add_system("D2", FUNC, ["Discipline2", "y_2=sqrt(y_1)+z_1+z_2"]) x.add_system("OBJ", FUNC, ["Objective", "f=x^2+z_2+y_1+exp(-y_2)"]) x.add_system("G1", FUNC, ["Constraint1", "g_1=3.16-y_1"]) x.add_system("G2", FUNC, ["Constraint2", "g_2=y_2-24"]) x.add_input("D1", "x,z_1,z_2") x.add_input("D2", "z_1,z_2") x.add_input("OBJ", "x,z_2") x.connect("D1", "D2", "y_1") x.connect("D1", "OBJ", "y_1") x.connect("D1", "G1", "y_1") x.connect("D2", "OBJ", "y_2") x.connect("D2", "G2", "y_2")
from pyxdsm.XDSM import XDSM, OPT, SOLVER, FUNC, GROUP x = XDSM() x.add_system("prob1_opt", OPT, "Optimize\_Prob1") x.add_system("d_airfoil", FUNC, "DesignAirfoil", stack=True) x.add_system("comp_mod_power", FUNC, "ComputeModifiedPower") x.connect("prob1_opt", "d_airfoil", "airfoil\_design") x.connect("comp_mod_power", "prob1_opt", "modified\_power") x.connect("d_airfoil", "comp_mod_power", "aerodynamic\_eff", stack=True) x.connect("d_airfoil", "comp_mod_power2", "aerodynamic\_eff*", stack=True) x.add_input("d_airfoil", "wind\_speeds", stack=True) x.add_system("prob2_opt", OPT, "Optimize\_Prob2") x.add_system("comp_pitch_angles", GROUP, "ComputeOptPitchAngle", stack=True) x.add_system("comp_mod_power2", FUNC, "ComputeModifiedPower") x.connect("prob2_opt", "comp_pitch_angles", "drag\_modifier") x.connect("comp_mod_power2", "prob2_opt", "powers, modified\_power") x.connect("comp_pitch_angles", "comp_mod_power2", "powers*", stack=True) x.connect("comp_pitch_angles", "comp_mod_power", "powers**", stack=True) x.add_input("comp_pitch_angles", "wind\_speeds", stack=True) x.write("run_sequential_top_level")
from pyxdsm.XDSM import XDSM x = XDSM() OPT = "Optimization" SUBOPT = "SubOptimization" SOLVER = "MDA" DOE = "DOE" IFUNC = "ImplicitFunction" FUNC = "Function" GROUP = "Group" IGROUP = "ImplicitGroup" METAMODEL = "Metamodel" x.add_system("opt", OPT, r"\text{Optimizer}") x.add_system("solver", SOLVER, r"\text{Newton}") x.add_system("D1", FUNC, "D_1") x.add_system("D2", FUNC, "D_2") x.add_system("F", FUNC, "F") x.add_system("G", FUNC, "G") x.connect("opt", "D1", "x, z") x.connect("opt", "D2", "z") x.connect("opt", "F", "x, z") x.connect("solver", "D1", "y_2") x.connect("solver", "D2", "y_1") x.connect("D1", "solver", r"\mathcal{R}(y_1)") x.connect("solver", "F", "y_1, y_2") x.connect("D2", "solver", r"\mathcal{R}(y_2)") x.connect("solver", "G", "y_1, y_2") x.connect("F", "opt", "f")
IFUNC, FUNC, GROUP, IGROUP, METAMODEL) # styling names for the boxes opt = 'Optimization' subopt = 'SubOptimization' solver = 'MDA' doe = 'DOE' ifunc = 'ImplicitFunction' func = 'Function' group = 'Group' igroup = 'ImplicitGroup' metamodel = 'Metamodel' x = XDSM() x.add_system('opt', opt, r'\text{Optimizer}') x.add_system('DOE', doe, r'\text{DOE}') x.add_system('MDA', solver, r'\text{Newton}') x.add_system('D1', func, 'D_1') # can fade out blocks to allow for emphasis on sub-sections of XDSM x.add_system('D2', ifunc, 'D_2', faded=True) x.add_system('D3', ifunc, 'D_3') x.add_system('subopt', subopt, 'SubOpt') x.add_system('G1', group, 'G_1') x.add_system('G2', igroup, 'G_2') x.add_system('MM', metamodel, 'MM') # if you give the label as a list or tuple, it splits it onto multiple lines x.add_system('F', func, ('F', r'\text{Functional}'))
from pyxdsm.XDSM import XDSM # Part-1 : Generate XDSM class object x = XDSM() # Part-2 : Define shape styles used in XDSM DataIO = 'DataIO' comp2 = 'ImplicitFunction' group = 'Metamodel' func = 'Function' OPT = "Optimization" # Part-3 : create system x.add_system('opt', OPT, r'\text{Optimizer}') x.add_system('D1', func, (r'Discipline1', r'y_1 = y_2^2')) x.add_system('D2', comp2, (r'Discipline2', r'exp(-y_1y_2)-xy_2 = 0 ')) x.add_system('F', func, (r'\text{Model Output}', r'f= y_1^2 - y_2 +3')) # Part-4 : Connect systems with variables x.connect('opt', 'D2', 'x') x.connect('D1', 'D2', r'y_1') x.connect('D1', 'F', r'y_1') x.connect('D2', 'F', r'y_2') x.connect('D2', 'D1', r'y_2') x.connect('F', 'opt', r'f') x.add_output('opt', 'x^*', side='left') # Part-5 : write Sellar.tex, Sellar.tikz, Sellar.pdf files x.write('Sellar')
from pyxdsm.XDSM import XDSM x = XDSM() OPT = "Optimization" SUBOPT = "SubOptimization" SOLVER = "MDA" DOE = "DOE" IFUNC = "ImplicitFunction" FUNC = "Function" GROUP = "Group" IGROUP = "ImplicitGroup" METAMODEL = "Metamodel" x.add_system("opt", OPT, r"\text{Optimizer}") x.add_system("DOE", DOE, r"\text{DOE}") x.add_system("MDA", SOLVER, r"\text{Newton}") x.add_system("D1", FUNC, "D_1") # can fade out blocks to allow for emphasis on sub-sections of XDSM x.add_system("D2", IFUNC, "D_2", faded=True) x.add_system("D3", IFUNC, "D_3") x.add_system("subopt", SUBOPT, "SubOpt") x.add_system("G1", GROUP, "G_1") x.add_system("G2", IGROUP, "G_2") x.add_system("MM", METAMODEL, "MM") # if you give the label as a list or tuple, it splits it onto multiple lines x.add_system("F", FUNC, ("F", r"\text{Functional}")) # stacked can be used to represent multiple instances that can be run in parallel
def test_tikz_content(self): # Check if TiKZ file was created. # Compare the content of the sample below and the newly created TiKZ file. tikz_txt = r""" %%% Preamble Requirements %%% % \usepackage{geometry} % \usepackage{amsfonts} % \usepackage{amsmath} % \usepackage{amssymb} % \usepackage{tikz} % Optional packages such as sfmath set through python interface % \usepackage{sfmath} % \usetikzlibrary{arrows,chains,positioning,scopes,shapes.geometric,shapes.misc,shadows} %%% End Preamble Requirements %%% \input{"D:/Documents/GitHub/mypyXDSM/pyXDSM/pyxdsm/diagram_styles"} \begin{tikzpicture} \matrix[MatrixSetup]{ %Row 0 \node [DataIO] (left_output_opt) {$x^*, z^*$};& \node [Optimization] (opt) {$\text{Optimizer}$};& & \node [DataInter] (opt-D1) {$x, z$};& \node [DataInter] (opt-D2) {$z$};& \node [DataInter] (opt-F) {$x, z$};& \\ %Row 1 & & \node [MDA] (solver) {$\text{Newton}$};& \node [DataInter] (solver-D1) {$y_2$};& \node [DataInter] (solver-D2) {$y_1$};& \node [DataInter] (solver-F) {$y_1, y_2$};& \node [DataInter] (solver-G) {$y_1, y_2$};\\ %Row 2 \node [DataIO] (left_output_D1) {$y_1^*$};& & \node [DataInter] (D1-solver) {$\mathcal{R}(y_1)$};& \node [Function] (D1) {$D_1$};& & & \\ %Row 3 \node [DataIO] (left_output_D2) {$y_2^*$};& & \node [DataInter] (D2-solver) {$\mathcal{R}(y_2)$};& & \node [Function] (D2) {$D_2$};& & \\ %Row 4 \node [DataIO] (left_output_F) {$f^*$};& \node [DataInter] (F-opt) {$f$};& & & & \node [Function] (F) {$F$};& \\ %Row 5 \node [DataIO] (left_output_G) {$g^*$};& \node [DataInter] (G-opt) {$g$};& & & & & \node [Function] (G) {$G$};\\ %Row 6 & & & & & & \\ }; % XDSM process chains \begin{pgfonlayer}{data} \path % Horizontal edges (opt) edge [DataLine] (opt-D1) (opt) edge [DataLine] (opt-D2) (opt) edge [DataLine] (opt-F) (solver) edge [DataLine] (solver-D1) (solver) edge [DataLine] (solver-D2) (D1) edge [DataLine] (D1-solver) (solver) edge [DataLine] (solver-F) (D2) edge [DataLine] (D2-solver) (solver) edge [DataLine] (solver-G) (F) edge [DataLine] (F-opt) (G) edge [DataLine] (G-opt) (opt) edge [DataLine] (left_output_opt) (D1) edge [DataLine] (left_output_D1) (D2) edge [DataLine] (left_output_D2) (F) edge [DataLine] (left_output_F) (G) edge [DataLine] (left_output_G) % Vertical edges (opt-D1) edge [DataLine] (D1) (opt-D2) edge [DataLine] (D2) (opt-F) edge [DataLine] (F) (solver-D1) edge [DataLine] (D1) (solver-D2) edge [DataLine] (D2) (D1-solver) edge [DataLine] (solver) (solver-F) edge [DataLine] (F) (D2-solver) edge [DataLine] (solver) (solver-G) edge [DataLine] (G) (F-opt) edge [DataLine] (opt) (G-opt) edge [DataLine] (opt); \end{pgfonlayer} \end{tikzpicture}""" def filter_lines(lns): # Empty lines are excluded. # Leading and trailing whitespaces are removed # Comments are removed. return [ ln.strip() for ln in lns if ln.strip() and not ln.strip().startswith('%') ] filename = 'xdsm_test_tikz' x = XDSM(use_sfmath=True) x.add_system('opt', 'Optimization', r'\text{Optimizer}') x.add_system('solver', 'MDA', r'\text{Newton}') x.add_system('D1', 'Function', 'D_1') x.add_system('D2', 'Function', 'D_2') x.add_system('F', 'Function', 'F') x.add_system('G', 'Function', 'G') x.connect('opt', 'D1', 'x, z') x.connect('opt', 'D2', 'z') x.connect('opt', 'F', 'x, z') x.connect('solver', 'D1', 'y_2') x.connect('solver', 'D2', 'y_1') x.connect('D1', 'solver', r'\mathcal{R}(y_1)') x.connect('solver', 'F', 'y_1, y_2') x.connect('D2', 'solver', r'\mathcal{R}(y_2)') x.connect('solver', 'G', 'y_1, y_2') x.connect('F', 'opt', 'f') x.connect('G', 'opt', 'g') x.add_output('opt', 'x^*, z^*', side='left') x.add_output('D1', 'y_1^*', side='left') x.add_output('D2', 'y_2^*', side='left') x.add_output('F', 'f^*', side='left') x.add_output('G', 'g^*', side='left') x.write(filename) # Check if file was created tikz_file = filename + '.tikz' self.assertTrue(os.path.isfile(tikz_file)) tikz_lines = tikz_txt.split('\n') tikz_lines = filter_lines(tikz_lines) with open(tikz_file, "r") as f: lines = filter_lines(f.readlines()) sample_no_match = [] # Sample text new_no_match = [] # New text for line1, line2 in zip(lines, tikz_lines): if line1 != line2: # else everything is okay # This can be because of the different ordering of lines or because of an error. sample_no_match.append(line1) new_no_match.append(line2) # Sort both sets of suspicious lines sample_no_match.sort() new_no_match.sort() for line1, line2 in zip(sample_no_match, new_no_match): # Now the lines should match, if only the ordering was different self.assertEqual(line1, line2) # To be sure, check the length, otherwise a missing last line could get unnoticed because of using zip self.assertEqual(len(lines), len(tikz_lines))
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' ecomp = 'Analysis' icomp = 'ImplicitAnalysis' x = XDSM() x.add_system('moi', ecomp, [r'\text{1) moment of inertia}', r'I_i = \frac{1}{4} b * h_i^3']) x.add_system('local_K', ecomp, [r'\text{2) local stiffness:}', r'\left[K_\text{local}\right]_i']) x.add_system('global_K', icomp, [r'\text{3) FEM:}', r'\left[K_\text{global}\right] u = f', r'u = [d, \theta]']) x.add_system('compliance', ecomp, [r'\text{4) compliance:}', r'c = f \cdot d']) x.add_system('volume', ecomp, [r'\text{5) volume:}', r'\sum h_i b L_i']) x.connect('moi', 'local_K', 'I') x.connect('local_K', 'global_K', r'K_\text{local}') x.connect('global_K', 'compliance', r'd')
from pyxdsm.XDSM import XDSM # styling names for the boxes opt = 'Optimization' solver = 'MDA' comp = 'Analysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('opt', opt, 'Optimizer') x.add_system('D1', comp, r'$D_1$') # can fade out blocks to allow for emphasis on sub-sections of XDSM x.add_system('D2', comp, r'$D_2$', faded=True) x.add_system('F', func, r'$F$') # stacked can be used to represent multiple instances that can be run in parallel x.add_system('G', func, r'$G$', stack=True) x.add_process(['opt', 'D1', 'D2', 'F', 'G', 'opt'], arrow=True) x.connect('opt', 'D1', r'$x, z, y_2$') x.connect('opt', 'D2', r'$z, y_1$') x.connect('opt', 'F', r'$x, z$') x.connect('opt', 'F', r'$y_1, y_2$') # you can also stack variables x.connect('opt', 'G', r'$y_1, y_2$', stack=True) x.connect('D1', 'opt', r'$\mathcal{R}(y_1)$') x.connect('D2', 'opt', r'$\mathcal{R}(y_2)$')
from pyxdsm.XDSM import XDSM opt = 'Optimization' solver = 'MDA' func = 'Function' ifunc = 'ImplicitFunction' x = XDSM() x.add_system('opt', opt, (r'0, 7 \rightarrow 1:', r'\text{Optimizer}')) x.add_system('solver', solver, (r'1, 5 \rightarrow 2:', r'\text{Solver}')) x.add_system('Qext', func, (r'2:', r'\text{HeatFlux}')) x.add_system('Power', func, (r'3:', r'\text{Power}')) x.add_system('Temp', ifunc, (r'4:', r'\text{Temperature}')) x.add_system('Fun', func, (r'6:', r'\text{Functions}'), stack=True) x.connect('opt', 'solver', r'T^{t,(0)}') x.connect('opt', 'Qext', r'\Phi, \Psi, \Omega, \alpha') x.connect('opt', 'Power', r'P_{out}') x.connect('opt', 'Temp', r'\epsilon, k') x.connect('opt', 'Fun', r'P_{out}') x.connect('solver', 'Qext', 'T^t') x.connect('solver', 'Power', 'T^t') x.connect('Qext', 'Power', r'Q_{sun}') x.connect('Qext', 'Temp', r'Q_{sun}, Q_{planet}, Q_{alb}') x.connect('Qext', 'Temp', r'Q_{sun}, Q_{planet}, Q_{alb}') x.connect('Power', 'Temp', r'Q_{dis}') x.connect('Power', 'Fun', r'Q_{dis}, P_{el}') x.connect('Temp', 'solver', r'\mathcal{R}(T)') x.connect('Temp', 'Fun', 'T')
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' ecomp = 'Analysis' icomp = 'ImplicitAnalysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('solver', solver, [r'\text{Solver}']) x.add_system('thrust_comp', ecomp, [r'\text{Thrust}', r'\text{Required}']) x.add_system('eng_ambient', ecomp, [r'\text{Propulsion}', r'\text{Ambient}']) x.add_system('prop_comp', icomp, [r'\text{Propeller}', r'\text{(OpenBEMT)}']) x.add_system('e_comp', icomp, [r'\text{Electrical}', r'\text{(Zappy)}']) x.add_system('engine_comp', icomp, [r'\text{Turboshaft}', r'\text{(pyCycle)}']) x.add_system('wing_ambient', ecomp, [r'\text{Wing}', r'\text{Ambient}']) x.add_system('aero_comp', icomp, [ r'\text{Wing Aerodynamics/}', r'\text{Structures}', r'\text{(OpenAeroStruct)}' ]) x.add_system('aircraft_mass', ecomp, [r'\text{Aircraft Mass}']) # AKA prebalance x.add_system('balance', icomp, [r'\text{Balance}']) x.add_input('prop_comp', r'\bar{X}_{propeller}') x.add_input('e_comp', r'\bar{X}_{electrical}') x.add_input('engine_comp', r'\bar{X}_{turboshaft}') x.add_input('aero_comp', r'\bar{X}_{wing}')
from pyxdsm.XDSM import XDSM, OPT, SOLVER, FUNC, GROUP x = XDSM() # Systems x.add_system("top_opt", OPT, "Optimizer") x.add_system("comp_pitch_angles", GROUP, "ComputeOptPitchAngle", stack=True) x.add_system("d_airfoil", FUNC, "DesignAirfoil", stack=True) x.add_system("comp_mod_power", FUNC, "ComputeModifiedPower") x.connect("d_airfoil", "comp_mod_power", "aerodynamic\_eff", stack=True) x.connect("comp_pitch_angles", "comp_mod_power", "powers*", stack=True) x.connect("top_opt", "d_airfoil", "airfoil\_design") x.connect("top_opt", "comp_pitch_angles", "drag\_modifier") x.connect("comp_mod_power", "top_opt", "modified\_power") x.add_input("d_airfoil", "wind\_speeds", stack=True) x.add_input("comp_pitch_angles", "wind\_speeds", stack=True) x.write("run_MDF_top_level")
x = XDSM() # Define styles OPT = "Optimization" SUBOPT = "SubOptimization" SOLVER = "MDA" DOE = "DOE" IFUNC = "ImplicitFunction" FUNC = "Function" GROUP = "Group" IGROUP = "ImplicitGroup" METAMODEL = "Metamodel" DataIO = "DataIO" DataInter = "DataInter" x.add_system("opt", OPT, [r"\text{Optimizer}"]) x.add_system("solver", SOLVER, [r"\text{MDA}"]) x.add_system("D1", IFUNC, ["Aerodynamic", "F=CA_fv^2"]) x.add_system("D2", IFUNC, ["Structural", "k\\theta=\\frac{1}{2}\\rho C_D"]) x.add_system("G", FUNC, ["Constraint1", "g=F-F_{max}"]) x.add_system("H", FUNC, ["Constraint2", "h=lw-A"]) x.add_system("OBJ", FUNC, ["Objective", "f=(\\theta-{\\hat \\theta})^2"]) x.add_input("opt", "l^{(0)},w^{(0)}") x.connect("opt", "D1", "l,w") x.connect("opt", "D2", "l") x.connect("opt", "H", "l,w") x.connect("solver", "G", "F") x.connect("solver", "OBJ", "\\theta")
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' ecomp = 'Analysis' icomp = 'ImplicitAnalysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('opt', opt, [r'\text{Manual Iteration}', r'\text{or Optimizer}']) x.add_system('NPSS_opt', opt, [r'\text{Manual Iteration}', r'\text{or Optimizer}']) x.add_system('NPSS', icomp, [r'\text{Engine Design and}',r'\text{Performance}',r'\text{Model (NPSS)}']) # x.add_system('NPSS_des', icomp, [r'\text{Engine Design}',r'\text{Model (NPSS)}']) # x.add_system('NPSS_od', icomp, [r'\text{Engine Performance}',r'\text{Model (NPSS)}']) x.add_system('CAMRAD_opt', opt, [r'\text{Manual Iteration}', r'\text{or Optimizer}']) x.add_system('CAMRAD', icomp, [r'\text{Rotor Design and}',r'\text{Performance}',r'\text{Model (CAMRAD II)}']) # x.add_system('CAMRAD_des', icomp, [r'\text{Rotor Design}',r'\text{Model (CAMRAD II)}']) # x.add_system('CAMRAD_od', icomp, [r'\text{Rotor Performance}',r'\text{Model (CAMRAD II)}']) x.add_system('NDARC_opt', opt, [r'\text{Manual Iteration}', r'\text{or Optimizer}']) x.add_system('NDARC', icomp, [r'\text{Aircraft Sizing and}',r'\text{Mission Performance}',r'\text{Model (NDARC)}']) # x.add_system('NDARC_des', icomp, [r'\text{Aircraft Design}',r'\text{Model (NDARC)}']) # x.add_system('NDARC_od', icomp, [r'\text{Mission Performance}',r'\text{Model (NDARC)}'])
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' comp = 'Analysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('EOM', comp, r'EOM') x.add_system('nav', comp, r'nav') x.add_system('threat', func, r'threat') # x.connect('opt', 'EOM', r'x, z') # x.connect('opt', 'nav', r'z') # x.connect('opt', 'F', r'x, z') # x.connect('solver', 'EOM', r'y_2') # x.connect('solver', 'nav', r'y_1') x.connect('nav', 'threat', r'r_{ship}') # x.connect('solver', 'F', r'y_1, y_2') # x.connect('solver', 'G', r'y_1, y_2') x.add_input('EOM', r'v, \phi') x.add_input('nav', r'x, y') x.add_input('threat', r'time') # x.add_output('opt', r'x^*, z^*', side='left') x.add_output('EOM', r'\dot{x}, \dot{y}', side='right') x.add_output('threat', r'range_{sub}', side='right')
opt = 'Optimization' # blue pill subopt = 'SubOptimization' solver = 'MDA' # orange pill doe = 'DOE' ifunc = 'ImplicitFunction' func = 'Function' # green box group = 'Group' igroup = 'ImplicitGroup' metamodel = 'Metamodel' x = XDSM() # Create subsystem components # spec_name = False (don't write a spec) # spec_name = 'xyz' (changes the spec name from defalt 'e_comp' to 'xyz') x.add_system('Sweep', solver, ['Sweep'], spec_name=False) x.add_system('Optimizer', opt, ['Optimizer'], spec_name=False) x.add_system('Geometry', func, ['Geometry']) x.add_system('Thermal', func, ['Thermal']) x.add_system('Structural', func, ['Structural']) # Optimizer x.add_input('Optimizer', 'constraints_{temp,stress}') x.connect('Optimizer', 'Geometry', ['extra', 'ratio', 'cell_d']) # Geometry # x.add_input('pack_design', ['L_{pack}', 'W_{pack}','L_{cell}', 'W_{cell}', 'H_{cell}', # 'mass_{cell}','voltage_{low,cell}','voltage_{nom,cell}','dischargeRate_{cell}','Q_{max}','V_{batt}']) x.connect('Geometry', 'Thermal', ['dimensions']) x.connect('Geometry', 'Structural', 'dimensions') x.connect('Geometry', 'Optimizer', 'mass')
def test_options(self): filename = "xdsm_test_options" spec_dir = filename + "_specs" # Change `use_sfmath` to False to use computer modern x = XDSM(use_sfmath=False) x.add_system("opt", OPT, r"\text{Optimizer}") x.add_system("solver", SOLVER, r"\text{Newton}") x.add_system("D1", FUNC, "D_1", label_width=2) x.add_system("D2", FUNC, "D_2", stack=False) x.add_system("F", FUNC, "F", faded=True) x.add_system("G", FUNC, "G", spec_name="G_spec") x.connect("opt", "D1", "x, z") x.connect("opt", "D2", "z") x.connect("opt", "F", "x, z") x.connect("solver", "D1", "y_2") x.connect("solver", "D2", "y_1") x.connect("D1", "solver", r"\mathcal{R}(y_1)") x.connect("solver", "F", "y_1, y_2") x.connect("D2", "solver", r"\mathcal{R}(y_2)") x.connect("solver", "G", "y_1, y_2") x.connect("F", "opt", "f") x.connect("G", "opt", "g") x.add_output("opt", "x^*, z^*", side="right") x.add_output("D1", "y_1^*", side="left", stack=True) x.add_output("D2", "y_2^*", side="left") x.add_output("F", "f^*", side="left") x.add_output("G", "g^*") x.write(filename) x.write_sys_specs(spec_dir) # Test if files where created self.assertTrue(os.path.isfile(filename + ".tikz")) self.assertTrue(os.path.isfile(filename + ".tex")) self.assertTrue(os.path.isdir(spec_dir)) self.assertTrue(os.path.isfile(os.path.join(spec_dir, "F.json"))) self.assertTrue(os.path.isfile(os.path.join(spec_dir, "G_spec.json")))
from pyxdsm.XDSM import XDSM # opt = 'Optimization' solver = 'MDA' comp = 'ImplicitAnalysis' group = 'Metamodel' func = 'Function' x = XDSM() x.add_system('dv', func, (r'x=1', r'\text{Design Variable}')) x.add_system('d1', func, (r'y_1=y_2^2', r'\text{Discipline 1}')) x.add_system('d2', comp, (r'\exp(-y_1 y_2) - x y_2', r'\text{Discipline 2}')) x.add_system('f', func, (r'y_1^2 - y_2 + 3', r'\text{Objective}')) x.connect('dv', 'd2', 'x') x.connect('d1', 'd2', 'y_1') x.connect('d2', 'd1', 'y_1') x.connect('d1', 'f', 'y_1') x.connect('d2', 'f', 'y_2') x.write('simple_example_xdsm')