import%20marimo%0A%0A__generated_with%20%3D%20%220.15.2%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22!%5BMOSEK%20ApS%5D(https%3A%2F%2Fwww.mosek.com%2Fstatic%2Fimages%2Fbranding%2Fwebgraphmoseklogocolor.png%20)%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%23%20Truss%20Topology%20Design%20with%20Multiple%20Load%20Scenarios%0A%0A%20%20%20%20This%20notebook%20demonstrates%20how%20to%20model%20and%20solve%20a%20**truss%20topology%20optimization%20problem**%20using%20the%20MOSEK%20Fusion%20API%20inspired%20by%20%5BLectures%20on%20Modern%20Convex%20Optimization%5D(https%3A%2F%2Fwww2.isye.gatech.edu%2F~nemirovs%2FLMCOBookSIAM.pdf)%20by%20Ben-Tal%20and%20Nemirovski.%20%0A%0A%20%20%20%20Truss%20topology%20design%20is%20a%20classical%20structural%20optimization%20problem%20that%20arises%20in%20civil%2C%20mechanical%2C%20and%20aerospace%20engineering.%20The%20task%20is%20to%20determine%20the%20optimal%20configuration%20of%20a%20truss%2C%20a%20structure%20formed%20by%20straight%20bars%20connected%20at%20nodes%2C%20that%20is%20both%20lightweight%20and%20stiff%20under%20a%20given%20set%20of%20external%20loads.%20The%20problem%20is%20based%20on%20equilibrium%20constraints%20and%20second-order%20cone%20reformulations.%0A%0A%0A%0A%20%20%20%20---%0A%0A%0A%20%20%20%20%23%23%20Problem%20Definition%0A%0A%0A%20%20%20%20We%20consider%20a%20truss%20consisting%20of%3A%0A%0A%20%20%20%20-%20A%20set%20of%20**bars**%20%5C(i%20%5Cin%20I%20%3D%20%5C%7B1%2C%5Cdots%2Cn%5C%7D%5C)%0A%20%20%20%20-%20A%20set%20of%20**nodes**%20%5C(j%20%5Cin%20J%20%3D%20%5C%7B1%2C%5Cdots%2Cm%5C%7D%5C)%0A%20%20%20%20-%20A%20set%20of%20**load%20scenarios**%20%5C(k%20%5Cin%20K%20%3D%20%5C%7B1%2C%5Cdots%2CK%5C%7D%5C)%0A%0A%0A%20%20%20%20%23%23%23%20Parameters%0A%0A%20%20%20%20-%20%5C(%20f(j%2Ck)%20%5C)%3A%20External%20force%20applied%20at%20node%20%5C(j%5C)%20in%20scenario%20%5C(k%5C).%0A%20%20%20%20-%20%5C(%20b(j%2Ci)%20%5C)%3A%20Stiffness%20contribution%20of%20bar%20%5C(i%5C)%20at%20node%20%5C(j%5C).%0A%20%20%20%20-%20%5C(%20V_%7B%5Cmax%7D%20%5C)%3A%20Maximum%20allowed%20total%20volume%20of%20the%20truss.%0A%0A%0A%20%20%20%20%23%23%23%20Decision%20Variables%0A%0A%20%20%20%20-%20%5C(%20t(i)%20%5Cgeq%200%20%5C)%3A%20Volume%20of%20bar%20%5C(i%5C).%0A%20%20%20%20-%20%5C(%20s(i%2Ck)%20%5C)%3A%20Stress%2Felongation%20of%20bar%20%5C(i%5C)%20under%20load%20scenario%20%5C(k%5C).%0A%20%20%20%20-%20%5C(%20%5Csigma(i%2Ck)%20%5Cgeq%200%20%5C)%3A%20Required%20cross-sectional%20area%20of%20bar%20%5C(i%5C)%20under%20load%20%5C(k%5C).%0A%20%20%20%20-%20%5C(%20%5Ctau%20%5Cgeq%200%20%5C)%3A%20Upper%20bound%20on%20compliance%2C%20which%20is%20minimized.%0A%0A%0A%20%20%20%20---%0A%0A%0A%20%20%20%20%23%23%20Constraints%0A%0A%0A%20%20%20%20The%20optimization%20model%20can%20be%20written%20as%3A%0A%0A%0A%20%20%20%201.%20**Rotated%20Cone%20Constraints%20(Stress-Volume%20Relation)%3A**%0A%0A%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20s(i%2Ck)%5E2%20%5Cleq%202%20%5C%2C%20t(i)%20%5C%2C%20%5Csigma(i%2Ck)%2C%20%5Cquad%20%5Cforall%20i%20%5Cin%20I%2C%20%5C%2C%20k%20%5Cin%20K%0A%20%20%20%20%5C%5D%0A%0A%20%20%20%20This%20enforces%20the%20geometric%20relation%20between%20stress%2C%20bar%20volume%2C%20and%20cross-sectional%20area.%20It%20is%20expressed%20as%20a%20**rotated%20second-order%20cone**.%0A%0A%0A%20%20%20%202.%20**Resource%20Constraints%20(Scenario-wise%20Compliance)%3A**%0A%0A%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20%5Csum_%7Bi%20%5Cin%20I%7D%20%5Csigma(i%2Ck)%20%5Cleq%20%5Ctau%2C%20%5Cquad%20%5Cforall%20k%20%5Cin%20K%0A%20%20%20%20%5C%5D%0A%0A%20%20%20%20Ensures%20that%20under%20each%20load%20scenario%2C%20the%20required%20cross-sections%20do%20not%20exceed%20%5C(%5Ctau%5C).%0A%0A%0A%20%20%20%203.%20**Total%20Volume%20Constraint%3A**%0A%0A%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20%5Csum_%7Bi%20%5Cin%20I%7D%20t(i)%20%5Cleq%20V_%7B%5Cmax%7D%0A%20%20%20%20%5C%5D%0A%0A%20%20%20%20Limits%20the%20total%20material%20used%20in%20the%20truss.%0A%0A%20%20%20%204.%20**Stiffness%20Equilibrium%20Constraints%3A**%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20%5Csum_%7Bi%20%5Cin%20I%7D%20b(j%2Ci)%20%5C%2C%20s(i%2Ck)%20%3D%20f(j%2Ck)%2C%20%5Cquad%20%5Cforall%20j%20%5Cin%20J%2C%20%5C%2C%20k%20%5Cin%20K%0A%20%20%20%20%5C%5D%0A%0A%20%20%20%20Ensures%20that%20stresses%20balance%20the%20external%20nodal%20forces%20for%20each%20scenario.%0A%0A%0A%20%20%20%20---%0A%0A%0A%20%20%20%20%23%23%20Objective%0A%0A%0A%20%20%20%20We%20minimize%20the%20upper%20bound%20on%20compliance%20%5C(%5Ctau%5C)%3A%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20%5Cmin%20%5Ctau%0A%20%20%20%20%5C%5D%0A%0A%0A%20%20%20%20This%20ensures%20the%20stiffest%20possible%20truss%20design%20under%20all%20load%20scenarios.%0A%0A%0A%20%20%20%20---%0A%0A%0A%20%20%20%20%23%23%20Cone%20Reformulation%0A%0A%0A%20%20%20%20Constraint%20(1)%20is%20written%20in%20conic%20form%20using%20the%20**rotated%20quadratic%20cone**%3A%0A%0A%0A%20%20%20%20%5C%5B%0A%20%20%20%20(s(i%2Ck)%2C%20%5C%2C%20t(i)%2C%20%5C%2C%20%5Csigma(i%2Ck))%20%5Cin%20%5Cmathcal%7BQ%7D%5Er%20%3D%20%5C%7B%20(u%2Cv%2Cw)%20%3A%202uv%20%5Cgeq%20w%5E2%2C%20u%2Cv%20%5Cgeq%200%20%5C%7D%0A%20%20%20%20%5C%5D%0A%0A%0A%20%20%20%20This%20makes%20the%20problem%20a%20**Second%20Order%20Cone%20Program%20(SOCP)**%2C%20which%20can%20be%20solved%20efficiently%20with%20MOSEK.%0A%0A%0A%20%20%20%20---%0A%0A%20%20%20%20The%20data%20is%20taken%20from%20the%20example%20provided%20in%20%5Bthis%20implementation%20by%20GAMS%5D(https%3A%2F%2Fwww.gams.com%2Flatest%2Fgamslib_ml%2Flibhtml%2Fgamslib_trussm.html)%20and%20is%20provided%20below%0A%20%20%20%20.%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20%23%20Index%20sets%0A%20%20%20%20bars%20%3D%20%5B%22i1%22%2C%22i2%22%2C%22i3%22%2C%22i4%22%2C%22i5%22%5D%0A%20%20%20%20nodes%20%3D%20%5B%22j1%22%2C%22j2%22%2C%22j3%22%2C%22j4%22%5D%0A%20%20%20%20scen%20%3D%20%5B%22k1%22%2C%22k2%22%2C%22k3%22%5D%0A%0A%20%20%20%20n%20%3D%205%0A%20%20%20%20m%20%3D%204%0A%20%20%20%20K%20%3D%203%0A%0A%20%20%20%20%23%20External%20Force%20Matrix%0A%20%20%20%20f%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B%200.0008%2C%20%201.0668%2C%20%200.2944%5D%2C%20%20%20%23%20j1%0A%20%20%20%20%20%20%20%20%5B%200.0003%2C%20%200.0593%2C%20-1.3362%5D%2C%20%20%20%23%20j2%0A%20%20%20%20%20%20%20%20%5B-0.0006%2C%20-0.0956%2C%20%200.7143%5D%2C%20%20%20%23%20j3%0A%20%20%20%20%20%20%20%20%5B-1.0003%2C%20-0.8323%2C%20%201.6236%5D%2C%20%20%20%23%20j4%0A%20%20%20%20%5D)%20%20%23%20shape%20(m%2C%20K)%0A%0A%20%20%20%20%23%20b(j%2Ci)%20stiffness%20matrix%20(rows%20%3D%20nodes%2C%20cols%20%3D%20bars)%0A%20%20%20%20b%20%3D%20np.array(%5B%0A%20%20%20%20%20%20%20%20%5B%201.0%2C%20%200.0%2C%20%200.5%2C%20%200.0%2C%20%200.0%5D%2C%20%20%20%23%20j1%0A%20%20%20%20%20%20%20%20%5B%200.0%2C%20%200.0%2C%20-0.5%2C%20-1.0%2C%20%200.0%5D%2C%20%20%20%23%20j2%0A%20%20%20%20%20%20%20%20%5B%200.0%2C%20%200.5%2C%20%200.0%2C%20%200.0%2C%20%201.0%5D%2C%20%20%20%23%20j3%0A%20%20%20%20%20%20%20%20%5B%200.0%2C%20%200.5%2C%20%200.0%2C%20%201.0%2C%20%200.0%5D%2C%20%20%20%23%20j4%0A%20%20%20%20%5D)%20%20%23%20shape%20(m%2C%20n)%0A%0A%20%20%20%20maxvolume%20%3D%2010.0%0A%20%20%20%20return%20K%2C%20b%2C%20f%2C%20m%2C%20maxvolume%2C%20n%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Now%2C%20we%20can%20implement%20this%20model%20using%20MOSEK%20Fusion%20in%20Python.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(K%2C%20b%2C%20f%2C%20m%2C%20maxvolume%2C%20n)%3A%0A%20%20%20%20from%20mosek.fusion%20import%20Model%2C%20Domain%2C%20Expr%2C%20ObjectiveSense%2C%20Matrix%2C%20Var%0A%20%20%20%20import%20mosek.fusion.pythonic%0A%0A%20%20%20%20%23%20Build%20Fusion%20model%0A%20%20%20%20M%20%3D%20Model(%22truss%22)%0A%0A%20%20%20%20%23%20Variables%0A%20%20%20%20tau%20%20%20%3D%20M.variable(%22tau%22%2C%201%2C%20Domain.greaterThan(0.0))%0A%20%20%20%20t%20%20%20%20%20%3D%20M.variable(%22t%22%2C%20n%2C%20Domain.greaterThan(0.0))%20%20%20%20%20%20%20%23%20bar%20volumes%0A%20%20%20%20sigma%20%3D%20M.variable(%22sigma%22%2C%20%5Bn%2C%20K%5D%2C%20Domain.greaterThan(0.0))%0A%20%20%20%20s%20%20%20%20%20%3D%20M.variable(%22s%22%2C%20%5Bn%2C%20K%5D%2C%20Domain.unbounded())%20%20%20%20%20%20%20%23%20stresses%0A%0A%20%20%20%20%23%20Rotated%20cone%20constraints%3A%20(t%5Bi%5D%2C%20sigma%5Bi%2Ck%5D%2C%20s%5Bi%2Ck%5D)%20in%20RQCone%0A%20%20%20%20for%20k%20in%20range(K)%3A%0A%20%20%20%20%20%20%20%20M.constraint(Expr.hstack(t%2Csigma%5B%3A%2Ck%5D%2Cs%5B%3A%2Ck%5D)%2C%20Domain.inRotatedQCone())%0A%0A%20%20%20%20%23%20Resource%20constraints%3A%20sum_i%20sigma%5Bi%2Ck%5D%20%3C%3D%20tau%0A%20%20%20%20for%20k%20in%20range(K)%3A%0A%20%20%20%20%20%20%20%20M.constraint(%0A%20%20%20%20%20%20%20%20%20%20%20%20Expr.sum(sigma%5B%3A%2Ck%5D)%20%3C%3D%20(tau)%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%23%20Volume%20constraint%3A%20sum_i%20t%5Bi%5D%20%3C%3D%20maxvolume%0A%20%20%20%20M.constraint(Expr.sum(t)%2C%20Domain.lessThan(maxvolume))%0A%0A%20%20%20%20%23%20Stiffness%20equations%3A%20sum_i%20s%5Bi%2Ck%5D%20*%20b%5Bj%2Ci%5D%20%3D%20f%5Bj%2Ck%5D%0A%20%20%20%20for%20j%20in%20range(m)%3A%0A%20%20%20%20%20%20%20%20for%20k%20in%20range(K)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lhs%20%3D%20Expr.dot(b%5Bj%2C%20%3A%5D%2C%20s.slice(%5B0%2C%20k%5D%2C%20%5Bn%2C%20k%2B1%5D))%0A%20%20%20%20%20%20%20%20%20%20%20%20M.constraint(lhs%2C%20Domain.equalsTo(f%5Bj%2C%20k%5D))%0A%0A%20%20%20%20%23%20Objective%3A%20minimize%20tau%0A%20%20%20%20M.objective(ObjectiveSense.Minimize%2C%20tau)%0A%0A%20%20%20%20%23%20Solve%0A%20%20%20%20M.solve()%0A%0A%20%20%20%20%23%20Print%20results%0A%20%20%20%20print(%22Problem%20Status%3A%22%2C%20M.getProblemStatus())%0A%20%20%20%20print(%22tau%20(objective)%3A%22%2C%20f%22%7Btau.level()%5B0%5D%3A.4f%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%3Ca%20rel%3D%22license%22%20href%3D%22http%3A%2F%2Fcreativecommons.org%2Flicenses%2Fby%2F4.0%2F%22%3E%3Cimg%20alt%3D%22Creative%20Commons%20License%22%20style%3D%22border-width%3A0%22%20src%3D%22https%3A%2F%2Fi.creativecommons.org%2Fl%2Fby%2F4.0%2F80x15.png%22%20%2F%3E%3C%2Fa%3E%3Cbr%20%2F%3EThis%20work%20is%20licensed%20under%20a%20%3Ca%20rel%3D%22license%22%20href%3D%22http%3A%2F%2Fcreativecommons.org%2Flicenses%2Fby%2F4.0%2F%22%3ECreative%20Commons%20Attribution%204.0%20International%20License%3C%2Fa%3E.%20The%20**MOSEK**%20logo%20and%20name%20are%20trademarks%20of%20%3Ca%20href%3D%22http%3A%2F%2Fmosek.com%22%3EMosek%20ApS%3C%2Fa%3E.%20The%20code%20is%20provided%20as-is.%20Compatibility%20with%20future%20release%20of%20**MOSEK**%20or%20the%20%60Fusion%20API%60%20are%20not%20guaranteed.%20For%20more%20information%20contact%20our%20%5Bsupport%5D(mailto%3Asupport%40mosek.com).%20%0A%0A%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
b0e67e518ebb906152834cdca0b84f4c740c8d6f6015018752b5308ff931a6fa