%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.11%22%0A%23%20dependencies%20%3D%20%5B%22marimo%3E%3D0.23.9%22%2C%20%22numpy%3E%3D2.0%22%2C%20%22matplotlib%3E%3D3.9%22%2C%20%22urllib3%3E%3D2.2%22%5D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.25.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%0A%20%20%20%20%23%20Muscle%20simulation%0A%0A%20%20%20%20%3E%20Marcos%20Duarte%2C%20Renato%20Watanabe%3Cbr%3E%0A%20%20%20%20%3E%20%5BLaboratory%20of%20Biomechanics%20and%20Motor%20Control%5D(https%3A%2F%2Fbmclab.pesquisa.ufabc.edu.br%2F)%3Cbr%3E%0A%20%20%20%20%3E%20Federal%20University%20of%20ABC%2C%20Brazil%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20How%20to%20use%20this%20tutorial%0A%0A%20%20%20%20This%20notebook%20is%20a%20guided%20study%20session.%20It%20puts%20the%20Hill-type%20muscle%20model%20from%20the%20companion%20notebook%20%5BMuscle%20modeling%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fmuscle_modeling.py)%20into%20motion%3A%20given%20an%20excitation%20signal%20and%20a%20muscle%E2%80%93tendon%20length%2C%20we%20integrate%20the%20muscle%20dynamics%20and%20watch%20the%20forces%20and%20lengths%20evolve%20in%20time.%0A%0A%20%20%20%20Read%20a%20short%20explanation%2C%20predict%20what%20the%20muscle%20should%20do%2C%20run%20the%20cell%2C%20and%20then%20use%20the%20plot%20to%20answer%20the%20challenge%20questions.%20Keep%20a%20scratchpad%20nearby%20and%20write%20your%20prediction%20*before*%20you%20reveal%20each%20plot.%0A%0A%20%20%20%20You%20do%20not%20need%20to%20finish%20every%20challenge%20on%20the%20first%20pass.%20Run%20the%20cells%20in%20order%20first%3B%20then%20come%20back%20and%20change%20one%20parameter%20at%20a%20time.%20The%20goal%20is%20not%20to%20make%20the%20code%20run%20%E2%80%94%20it%20already%20runs.%20The%20goal%20is%20to%20connect%20three%20things%3A%20the%20equations%20of%20the%20model%2C%20the%20step-by-step%20numerical%20integration%2C%20and%20the%20muscle%20behavior%20you%20see%20in%20the%20plots.%0A%0A%20%20%20%20**Challenge%200.**%20Before%20you%20begin%2C%20picture%20an%20*isometric*%20contraction%3A%20the%20whole%20muscle%E2%80%93tendon%20unit%20is%20held%20at%20a%20fixed%20length%20while%20the%20muscle%20activates.%20Predict%20what%20happens%20to%20the%20muscle%20fiber%20length%20%24L_M%24%20and%20to%20the%20tendon%20length%20%24L_T%24%20as%20activation%20rises.%20Can%20either%20one%20change%20even%20though%20their%20sum%20%24L_%7BMT%7D%24%20is%20fixed%3F%20Write%20your%20answer%20down%3B%20you%20will%20test%20it%20in%20the%20first%20simulation.%0A%0A%20%20%20%20Follow%20the%20existing%20pennation%20and%20equilibrium%20examples%20into%20the%20isometric%20and%20prescribed-length%20simulations.%20The%20total%20musculotendon%20length%20is%20an%20input%20here%3B%20fiber%20length%20is%20a%20state.%20Check%20force%20balance%20and%20step-size%20sensitivity%20before%20interpreting%20differences%20between%20parameter%20choices.%0A%0A%20%20%20%20Try%20the%20distributed%20**Exercises**%20before%20opening%20their%20collapsed%20worked%20solutions.%20Then%20use%20the%20**Checkpoint%20questions**%20and%20attempt%20the%20**Problems**%20independently%3B%20their%20panels%20contain%20final%20answers%20only.%20Predict%20the%20effect%20of%20a%20parameter%20change%20before%20running%20it%2C%20and%20check%20units%20and%20limiting%20cases.%0A%0A%20%20%20%20**Opening%20challenge.**%20Clamp%20the%20total%20musculotendon%20length%20and%20increase%20excitation.%20Can%20the%20muscle%20fibers%20still%20shorten%2C%20and%20where%20would%20that%20shortening%20go%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Python%20setup%0A%0A%20%20%20%20The%20dependency%20declaration%20at%20the%20top%20of%20this%20file%20lists%20the%20packages%20used%20by%20this%20guide.%20Marimo%20runs%20cells%20in%20dependency%20order.%20Run%20the%20notebook%20in%20an%20editor%20to%20use%20its%20displays%20and%20controls%3B%20the%20computational%20examples%20below%20explain%20their%20inputs%20before%20using%20them.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20Let's%20simulate%20the%203-component%20Hill-type%20muscle%20model%20we%20described%20in%20%5BMuscle%20modeling%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fmuscle_modeling.py)%20and%20illustrated%20below%3A%0A%20%20%20%20%3Cp%3E%3C%2Fp%3E%0A%20%20%20%20%3Cimg%20src%3D%22https%3A%2F%2Fraw.githubusercontent.com%2FBMClab%2FBMC%2Fmaster%2Fimages%2Fmuscle_hill.png%22%20width%3D%22400%22%20alt%3D%22Hill-type%20muscle%20model.%22%2F%3E%0A%0A%20%20%20%20*Figure.%20A%20Hill-type%20muscle%20model%20with%20three%20components%3A%20two%20for%20the%20muscle%2C%20an%20active%20contractile%20element%2C%20%24%5Cmathsf%7BCE%7D%24%2C%20and%20a%20passive%20elastic%20element%20in%20parallel%2C%20%24%5Cmathsf%7BPE%7D%24%2C%20with%20the%20%24%5Cmathsf%7BCE%7D%24%2C%20and%20one%20component%20for%20the%20tendon%2C%20an%20elastic%20element%20in%20series%2C%20%24%5Cmathsf%7BSE%7D%24%2C%20with%20the%20muscle.%20%24%5Cmathsf%7BL_%7BMT%7D%7D%24%3A%20muscle%E2%80%93tendon%20length%2C%20%24%5Cmathsf%7BL_T%7D%24%3A%20tendon%20length%2C%20%24%5Cmathsf%7BL_M%7D%24%3A%20muscle%20fiber%20length%2C%20%24%5Cmathsf%7BF_T%7D%24%3A%20tendon%20force%2C%20%24%5Cmathsf%7BF_M%7D%24%3A%20muscle%20force%2C%20and%20%24%5Calpha%24%3A%20pennation%20angle.*%0A%0A%20%20%20%20The%20following%20relationships%20are%20true%20for%20the%20model%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cbegin%7Barray%7D%7Bl%7D%0A%20%20%20%20L_%7BMT%7D%20%3D%20L_%7BT%7D%20%2B%20L_M%5Ccos%5Calpha%20%20%5C%5C%0A%20%20%20%20%5C%5C%0A%20%20%20%20L_M%20%3D%20L_%7BCE%7D%20%3D%20L_%7BPE%7D%20%5C%5C%0A%20%20%20%20%5C%5C%0A%20%20%20%20%5Cdot%7BL%7D_M%20%3D%20%5Cdot%7BL%7D_%7BCE%7D%20%3D%20%5Cdot%7BL%7D_%7BPE%7D%20%5C%5C%0A%20%20%20%20%5C%5C%0A%20%20%20%20F_%7BM%7D%20%3D%20F_%7BCE%7D%20%2B%20F_%7BPE%7D%0A%20%20%20%20%5Cend%7Barray%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20If%20we%20assume%20that%20the%20muscle%E2%80%93tendon%20system%20is%20at%20equilibrium%2C%20that%20is%2C%20muscle%2C%20%24F_%7BM%7D%24%2C%20and%20tendon%2C%20%24F_%7BT%7D%24%2C%20forces%20are%20in%20equilibrium%20at%20all%20times%2C%20the%20following%20equation%20holds%20(and%20that%20a%20muscle%20can%20only%20pull)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20F_%7BT%7D%20%3D%20F_%7BSE%7D%20%3D%20F_%7BM%7D%5Ccos%5Calpha%0A%20%20%20%20%24%24%0A%0A%20%20%20%20**Guiding%20questions%201.**%0A%0A%20%20%20%201.%20In%20the%20relationship%20%24L_%7BMT%7D%20%3D%20L_T%20%2B%20L_M%5Ccos%5Calpha%24%2C%20which%20lengths%20change%20over%20the%20course%20of%20a%20simulation%2C%20and%20which%20one%20do%20*we*%20prescribe%20as%20an%20input%3F%0A%20%20%20%202.%20The%20equilibrium%20assumption%20sets%20%24F_T%20%3D%20F_M%5Ccos%5Calpha%24%20at%20every%20instant.%20What%20property%20of%20the%20tendon%20makes%20treating%20it%20as%20always%20in%20equilibrium%20with%20the%20muscle%20a%20reasonable%20simplification%3F%0A%20%20%20%203.%20If%20the%20tendon%20stretches%20while%20%24L_%7BMT%7D%24%20is%20held%20fixed%2C%20what%20must%20happen%20to%20the%20fiber%20length%20%24L_M%24%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Pennation%20angle%0A%0A%20%20%20%20The%20pennation%20angle%20will%20vary%20during%20muscle%20activation%3B%20for%20instance%2C%20Kawakami%20et%20al.%20(1998)%20showed%20that%20the%20pennation%20angle%20of%20the%20medial%20gastrocnemius%20muscle%20can%20vary%20from%2022%24%5Eo%24%20to%2067%24%5Eo%24%20during%20activation.%20The%20most%20used%20approach%20is%20to%20assume%20that%20the%20muscle%20width%20(defined%20as%20the%20length%20of%20the%20perpendicular%20line%20between%20the%20lines%20of%20the%20muscle%20origin%20and%20insertion)%20remains%20constant%20(Scott%20%26%20Winter%2C%201991)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20w%20%3D%20L_%7BM%2C0%7D%20%5Csin%5Calpha_0%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20pennation%20angle%20as%20a%20function%20of%20time%20will%20be%20given%20by%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Calpha%20%3D%20%5Csin%5E%7B-1%7D%20%5Cleft(%5Cdfrac%7Bw%7D%7BL_M%7D%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20cosine%20of%20the%20pennation%20angle%20can%20be%20given%20by%20(if%20%24L_M%24%20is%20known)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ccos%20%5Calpha%20%3D%20%5Cdfrac%7B%5Csqrt%7BL_M%5E2-w%5E2%7D%7D%7BL_M%7D%20%3D%20%5Csqrt%7B1-%5Cleft(%5Cdfrac%7Bw%7D%7BL_M%7D%5Cright)%5E2%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20or%20(if%20%24L_M%24%20is%20not%20known)%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ccos%20%5Calpha%20%3D%20%5Cdfrac%7BL_%7BMT%7D-L_T%7D%7BL_M%7D%20%3D%20%5Cdfrac%7B1%7D%7B%5Csqrt%7B1%20%2B%20%5Cleft(%5Cdfrac%7Bw%7D%7BL_%7BMT%7D-L_T%7D%5Cright)%5E2%7D%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20**Guiding%20questions%202.**%0A%0A%20%20%20%201.%20The%20tendon%20feels%20the%20force%20%24F_T%20%3D%20F_M%5Ccos%5Calpha%24.%20As%20the%20pennation%20angle%20%24%5Calpha%24%20grows%20during%20a%20contraction%2C%20does%20the%20tendon%20receive%20a%20larger%20or%20smaller%20fraction%20of%20the%20muscle%20fiber%20force%3F%0A%20%20%20%202.%20The%20constant-width%20assumption%20(%24w%20%3D%20L_%7BM%2C0%7D%5Csin%5Calpha_0%24)%20forces%20%24%5Calpha%24%20to%20change%20as%20the%20fiber%20shortens.%20Using%20%24%5Calpha%20%3D%20%5Csin%5E%7B-1%7D(w%2FL_M)%24%2C%20explain%20whether%20the%20angle%20grows%20or%20shrinks%20when%20%24L_M%24%20decreases.%0A%0A%20%20%20%20**Challenge%201.**%20A%20fusiform%20muscle%20has%20%24%5Calpha_0%20%3D%200%24.%20Show%20from%20%24w%20%3D%20L_%7BM%2C0%7D%5Csin%5Calpha_0%24%20that%20its%20width%20%24w%24%20is%20zero%2C%20so%20%24%5Calpha%20%3D%200%24%20and%20%24%5Ccos%5Calpha%20%3D%201%24%20for%20any%20fiber%20length.%20We%20will%20use%20%24%5Calpha_0%20%3D%200%24%20for%20most%20simulations%20and%20revisit%20a%20pennated%20(%2430%5Eo%24)%20case%20later.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20**Exercise%201%20%E2%80%94%20Project%20fiber%20length.**%20A%20fiber%20is%200.10%20m%20long%20at%2030%C2%B0%20pennation.%20Find%20its%20projection%20along%20the%20tendon.%20If%20fiber%20height%20is%20constant%2C%20what%20happens%20to%20pennation%20as%20fiber%20length%20decreases%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%2F%2F%2F%20details%20%7C%20Solution%20to%20Exercise%201%0A%0A%20%20%20%20The%20projection%20is%20%24L_M%5Ccos%5Calpha%3D0.0866%24%20m.%20Constant%20height%20means%20%24L_M%5Csin%5Calpha%24%20is%20fixed%2C%20so%20shortening%20increases%20%24%5Calpha%24.%20The%20geometry%20must%20be%20updated%20during%20a%20simulation.%0A%20%20%20%20%2F%2F%2F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Muscle%20force%0A%0A%20%20%20%20In%20general%2C%20the%20dependence%20of%20the%20force%20of%20the%20contractile%20element%20with%20its%20length%20and%20velocity%20and%20with%20the%20activation%20level%20are%20assumed%20independent%20of%20each%20other%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20F_%7BCE%7D(a%2C%20L_%7BCE%7D%2C%20%5Cdot%7BL%7D_%7BCE%7D)%20%3D%20a%20%5C%3A%20f_l(L_%7BCE%7D)%20%5C%3A%20f_v(%5Cdot%7BL%7D_%7BCE%7D)%20%5C%3A%20F_%7BM0%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%20%24f_l(L_M)%24%20and%20%24f_v(%5Cdot%7BL%7D_M)%24%20are%20mathematical%20functions%20describing%20the%20force-length%20and%20force-velocity%20relationships%20of%20the%20contractile%20element%20(typically%20these%20functions%20are%20normalized%20by%20%24F_%7BM0%7D%24%2C%20the%20maximum%20isometric%20(at%20zero%20velocity)%20muscle%20force%2C%20so%20we%20have%20to%20multiply%20the%20right%20side%20of%20the%20equation%20by%20%24F_%7BM0%7D%24).%0A%0A%20%20%20%20And%20for%20the%20muscle%20force%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20F_%7BM%7D(a%2C%20L_M%2C%20%5Cdot%7BL%7D_M)%20%3D%20%5Cleft%5Ba%20%5C%3A%20f_l(L_M)f_v(%5Cdot%7BL%7D_M)%20%2B%20F_%7BPE%7D(L_M)%5Cright%5DF_%7BM0%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20This%20equation%20for%20the%20muscle%20force%2C%20with%20%24a%24%2C%20%24L_%7BM%7D%24%2C%20and%20%24%5Cdot%7BL%7D_%7BM%7D%24%20as%20state%20variables%2C%20can%20be%20used%20to%20simulate%20the%20dynamics%20of%20a%20muscle%20given%20an%20excitation%20and%20determine%20the%20muscle%20force%20and%20length.%20We%20can%20rearrange%20the%20equation%2C%20invert%20the%20expression%20for%20%24f_v%24%2C%20and%20integrate%20the%20resulting%20first-order%20ordinary%20differential%20equation%20(ODE)%20to%20obatin%20%24L_M%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cdot%7BL%7D_M%20%3D%20f_v%5E%7B-1%7D%5Cleft(%5Cdfrac%7BF_%7BSE%7D(L_%7BMT%7D-L_M%5Ccos%5Calpha)%2F%5Ccos%5Calpha%20-%20F_%7BPE%7D(L_M)%7D%7Ba%20f_l(L_M)%7D%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20This%20approach%20is%20the%20most%20commonly%20employed%20in%20the%20literature%20(see%20for%20example%2C%20%5BOpenSim%5D(http%3A%2F%2Fsimtk-confluence.stanford.edu%3A8080%2Fdisplay%2FOpenSim%2FMuscle%2BModel%2BTheory%2Band%2BPublications)%3B%20McLean%2C%20Su%2C%20van%20den%20Bogert%2C%202003%3B%20Thelen%2C%202003%3B%20Nigg%20and%20Herzog%2C%202007).%0A%0A%20%20%20%20Although%20the%20equation%20for%20the%20muscle%20force%20doesn't%20have%20numerical%20singularities%2C%20the%20differential%20equation%20for%20muscle%20velocity%20has%20four%20(%5BOpenSim%20Millard%202012%20Muscle%20Models%5D(http%3A%2F%2Fsimtk-confluence.stanford.edu%3A8080%2Fdisplay%2FOpenSim%2FMillard%2B2012%2BMuscle%2BModels))%3A%3Cbr%3E%0A%20%20%20%20When%20%24a%20%5Crightarrow%200%24%3B%20when%20%24f_l(L_M)%20%5Crightarrow%200%24%3B%20when%20%24%5Calpha%20%5Crightarrow%20%5Cpi%2F2%24%3B%20and%20when%20%24%5Cpartial%20f_v%2F%5Cpartial%20v%20%5Crightarrow%200%24.%3Cbr%3E%0A%20%20%20%20The%20following%20solutions%20can%20be%20employed%20to%20avoid%20the%20numerical%20singularities%20(%5BOpenSim%20Millard%202012%20Muscle%20Models%5D(http%3A%2F%2Fsimtk-confluence.stanford.edu%3A8080%2Fdisplay%2FOpenSim%2FMillard%2B2012%2BMuscle%2BModels))%3A%3Cbr%3E%0A%20%20%20%20-%20A%20minimum%20value%20for%20%24a%24%3B%20e.g.%2C%20%24a_%7Bmin%7D%3D0.01%24%3B%3Cbr%3E%0A%20%20%20%20-%20A%20minimum%20value%20for%20%24f_l(L_M)%24%3B%20e.g.%2C%20%24f_l(0.1)%24%3B%3Cbr%3E%0A%20%20%20%20-%20A%20maximum%20value%20for%20pennation%20angle%3B%20e.g.%2C%20constrain%20%24%5Calpha%24%20to%20%24%5Ccos%5Calpha%20%3E%200.1%3B%20(%5Calpha%20%3C%2084.26%5Eo)%24%3B%3Cbr%3E%0A%20%20%20%20-%20Make%20the%20slope%20of%20%24f_V%24%20at%20and%20beyond%20maximum%20velocity%20different%20than%20zero%20(for%20both%20concentric%20and%20eccentric%20activations).%0A%0A%20%20%20%20We%20will%20adopt%20these%20solutions%20to%20avoid%20singularities%20in%20the%20simulation%20of%20muscle%20mechanics.%20A%20problem%20of%20imposing%20values%20to%20variables%20as%20described%20above%20is%20that%20we%20can%20make%20the%20ordinary%20differential%20equation%20numerically%20stiff%2C%20which%20will%20increase%20the%20computational%20cost%20of%20the%20numerical%20integration.%20A%20better%20solution%20would%20be%20to%20modify%20the%20model%20to%20not%20have%20these%20singularities%20(see%20%5BOpenSim%20Millard%202012%20Muscle%20Models%5D(http%3A%2F%2Fsimtk-confluence.stanford.edu%3A8080%2Fdisplay%2FOpenSim%2FMillard%2B2012%2BMuscle%2BModels)).%0A%0A%20%20%20%20**Guiding%20questions%203.**%0A%0A%20%20%20%201.%20The%20muscle%20force%20%24F_%7BM%7D%20%3D%20%5Cleft%5Ba%20%5C%3A%20f_l(L_M)f_v(%5Cdot%7BL%7D_M)%20%2B%20F_%7BPE%7D(L_M)%5Cright%5DF_%7BM0%7D%24%20has%20three%20factors%20that%20scale%20the%20*active*%20force.%20Which%20factor%20carries%20the%20neural%20command%2C%20which%20the%20length%20dependence%2C%20and%20which%20the%20velocity%20dependence%3F%0A%20%20%20%202.%20The%20velocity%20equation%20is%20obtained%20by%20inverting%20%24f_v%24%2C%20which%20divides%20by%20%24a%5C%2Cf_l(L_M)%24.%20Why%20does%20this%20create%20a%20numerical%20singularity%20when%20the%20muscle%20is%20nearly%20inactive%20(%24a%5Cto%200%24)%20or%20far%20from%20its%20optimal%20length%20(%24f_l%5Cto%200%24)%3F%0A%0A%20%20%20%20**Challenge%202.**%20For%20each%20of%20the%20four%20singularities%20listed%20above%20(%24a%5Cto%200%24%2C%20%24f_l%5Cto%200%24%2C%20%24%5Calpha%5Cto%5Cpi%2F2%24%2C%20%24%5Cpartial%20f_v%2F%5Cpartial%20v%5Cto%200%24)%2C%20find%20the%20matching%20clamp%20in%20the%20code%20when%20you%20reach%20the%20module%20at%20the%20end%20of%20the%20notebook.%20(Hint%3A%20look%20for%20%600.1%20*%20lmopt%60%20in%20%60vm_eq%60%20and%20the%20pennation-angle%20cap%20in%20%60penn_ang%60.)%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20**Exercise%202%20%E2%80%94%20Separate%20active%20and%20tendon%20forces.**%20A%20fiber%20has%20300%20N%20active%20and%20100%20N%20passive%20force%20at%2020%C2%B0%20pennation.%20What%20tendon%20force%20is%20consistent%20with%20equilibrium%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%2F%2F%2F%20details%20%7C%20Solution%20to%20Exercise%202%0A%0A%20%20%20%20Total%20fiber%20force%20is%20400%20N%3B%20its%20tendon-direction%20component%20is%20%24400%5Ccos20%5E%5Ccirc%3D375.9%24%20N.%20Equating%20tendon%20force%20to%20active%20force%20alone%20would%20neglect%20both%20passive%20tension%20and%20pennation.%0A%20%20%20%20%2F%2F%2F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Simulation%0A%0A%20%20%20%20Let's%20simulate%20muscle%20dynamics%20using%20the%20Thelen2003Muscle%20model%20we%20defined%20in%20%5BMuscle%20modeling%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fmuscle_modeling.py).%20For%20the%20simulation%20of%20the%20Thelen2003Muscle%2C%20we%20simply%20have%20to%20integrate%20the%20equation%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20V_M%20%3D%20(0.25%2B0.75a)%5C%2CV_%7BMmax%7D%5Cfrac%7B%5Cbar%7BF%7D_M-a%5Cbar%7Bf%7D_%7Bl%2CCE%7D%7D%7Bb%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%0A%0A%20%20%20%20%24%24%0A%20%20%20%20b%20%3D%20%5Cleft%5C%7B%0A%20%20%20%20%20%20%5Cbegin%7Barray%7D%7Bl%20l%20l%7D%0A%20%20%20%20%20%20%20%20a%5Cbar%7Bf%7D_%7Bl%2CCE%7D%20%2B%20%5Cbar%7BF%7D_M%2FA_f%20%5Cquad%20%26%20%5Ctext%7Bif%7D%20%5Cquad%20%5Cbar%7BF%7D_M%20%5Cleq%20a%5Cbar%7Bf%7D_%7Bl%2CCE%7D%20%26%20%5Ctext%7B(shortening)%7D%20%5C%5C%0A%20%20%20%20%20%20%20%20%5C%5C%0A%20%20%20%20%20%20%20%20%5Cdfrac%7B(2%2B2%2FA_f)(a%5Cbar%7Bf%7D_%7Bl%2CCE%7D%5Cbar%7Bf%7D_%7BCEmax%7D%20-%20%5Cbar%7BF%7D_M)%7D%7B%5Cbar%7Bf%7D_%7BCEmax%7D-1%7D%20%5Cquad%20%26%20%5Ctext%7Bif%7D%20%5Cquad%20%5Cbar%7BF%7D_M%20%3E%20a%5Cbar%7Bf%7D_%7Bl%2CCE%7D%20%26%20%5Ctext%7B(lengthening)%7D%0A%20%20%20%20%5Cend%7Barray%7D%20%5Cright.%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20equation%20above%20already%20contains%20the%20terms%20for%20actvation%2C%20%24a%24%2C%20and%20force-length%20dependence%2C%20%24%5Cbar%7Bf%7D_%7Bl%2CCE%7D%24.%20The%20equation%20is%20too%20complicated%20for%20solving%20analytically%2C%20we%20will%20solve%20it%20by%20numerical%20integration%20with%20a%20simple%20fixed-step%20forward%20%5BEuler%20method%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FEuler_method).%20We%20could%20run%20a%20simulation%20using%20%5BOpenSim%5D(https%3A%2F%2Fsimtk.org%2Fhome%2Fopensim)%3B%20it%20would%20be%20faster%2C%20but%20for%20fun%2C%20let's%20program%20in%20Python.%20All%20the%20necessary%20functions%20for%20the%20Thelen2003Muscle%20model%20described%20in%20%5BMuscle%20modeling%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fmuscle_modeling.py)%20were%20grouped%20in%20one%20file%20(module)%2C%20%60muscles.py%60.%20Besides%20these%20functions%2C%20the%20module%20%60muscles.py%60%20contains%20a%20function%20for%20the%20muscle%20velocity%2C%20%60vm_eq%60%2C%20which%20is%20evaluated%20at%20each%20integration%20step%20by%20the%20solver%20%60lm_sol%60%3A%0A%0A%20%20%20%20%60%60%60python%3Cbr%3E%0A%20%20%20%20def%20vm_eq(self%2C%20t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20lmopt%2C%20ltslack%2C%20alpha0%2C%20vmmax%2C%20fm0)%3A%0A%20%20%20%20%20%20%20%20%22%5C%22%5C%22Equation%20for%20muscle%20velocity.%22%5C%22%5C%22%0A%20%20%20%20%20%20%20%20if%20lm%20%3C%200.1*lmopt%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%200.1*lmopt%3Cbr%3E%0A%20%20%20%20%20%20%20%20a%20%20%20%20%20%3D%20self.activation(t)%0A%20%20%20%20%20%20%20%20lmt%20%20%20%3D%20self.lmt_eq(t%2C%20lmt0)%0A%20%20%20%20%20%20%20%20alpha%20%3D%20self.penn_ang(lmt%3Dlmt%2C%20lm%3Dlm%2C%20lm0%3Dlm0%2C%20alpha0%3Dalpha0)%0A%20%20%20%20%20%20%20%20lt%20%20%20%20%3D%20lmt%20-%20lm*np.cos(alpha)%0A%20%20%20%20%20%20%20%20fse%20%20%20%3D%20self.force_se(lt%3Dlt%2C%20ltslack%3Dltslack)%0A%20%20%20%20%20%20%20%20fpe%20%20%20%3D%20self.force_pe(lm%3Dlm%2Flmopt)%0A%20%20%20%20%20%20%20%20fl%20%20%20%20%3D%20self.force_l(lm%3Dlm%2Flmopt)%0A%20%20%20%20%20%20%20%20fce_t%20%3D%20fse%2Fnp.cos(alpha)%20-%20fpe%0A%20%20%20%20%20%20%20%20vm%20%20%20%20%3D%20self.velo_fm(fm%3Dfce_t%2C%20a%3Da%2C%20fl%3Dfl)%0A%20%20%20%20%20%20%20%20return%20vm%0A%0A%20%20%20%20def%20lm_sol(self%2C%20fun%2C%20t0%2C%20t1%2C%20dt%2C%20lm0%2C%20lmt0%2C%20ltslack%2C%20lmopt%2C%20alpha0%2C%20vmmax%2C%20fm0%2C%20show%2C%20axs)%3A%0A%20%20%20%20%20%20%20%20%22%5C%22%5C%22Forward%20Euler%20ODE%20solver%20for%20muscle%20length.%22%5C%22%5C%22%0A%20%20%20%20%20%20%20%20if%20fun%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20fun%20%3D%20self.vm_eq%0A%20%20%20%20%20%20%20%20nsteps%20%3D%20int(round((t1%20-%20t0)%20%2F%20dt))%0A%20%20%20%20%20%20%20%20lm%20%3D%20lm0%0A%20%20%20%20%20%20%20%20data%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(nsteps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20t0%20%2B%20i*dt%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20max(lm%2C%200.1*lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20data.append(self.calc_data(t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20ltslack%2C%20lmopt%2C%20alpha0%2C%20fm0))%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20fun(t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20lmopt%2C%20ltslack%2C%20alpha0%2C%20vmmax%2C%20fm0)%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20lm%20%2B%20dt*vm%0A%20%20%20%20%20%20%20%20data%20%3D%20np.array(data)%0A%20%20%20%20%20%20%20%20self.lm_data%20%3D%20data%0A%20%20%20%20%20%20%20%20if%20show%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.lm_plot(data%2C%20axs)%0A%20%20%20%20%20%20%20%20return%20data%0A%20%20%20%20%60%60%60%0A%0A%20%20%20%20**Challenge%203.**%20Read%20the%20%60lm_sol%60%20loop%20above.%20It%20is%20the%20same%20forward%20Euler%20update%20you%20met%20for%20a%20first-order%20ODE%3A%20%60lm%20%3D%20lm%20%2B%20dt*vm%60.%20Identify%20the%20three%20ingredients%20of%20one%20Euler%20step%20here%20%E2%80%94%20the%20current%20state%2C%20the%20rate%20of%20change%2C%20and%20the%20time%20step.%20Why%20does%20the%20solver%20take%20many%20small%20steps%20of%20size%20%60dt%60%20instead%20of%20one%20big%20jump%3F%0A%0A%20%20%20%20%60muscles.py%60%20also%20contains%20some%20auxiliary%20functions%20for%20entering%20data%20and%20for%20plotting%20the%20results.%20Let's%20import%20the%20necessary%20Python%20libraries%20and%20customize%20the%20environment%20in%20order%20to%20run%20some%20simulations%20using%20%60muscles.py%60%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20matplotlib%0A%0A%20%20%20%20matplotlib.rcParams%5B%22lines.linewidth%22%5D%20%3D%202%0A%20%20%20%20matplotlib.rcParams%5B%22font.size%22%5D%20%3D%2012%0A%20%20%20%20matplotlib.rcParams%5B%22lines.markersize%22%5D%20%3D%204%0A%20%20%20%20matplotlib.rc(%22axes%22%2C%20grid%3DTrue%2C%20labelsize%3D12%2C%20titlesize%3D13%2C%20ymargin%3D0.01)%0A%20%20%20%20matplotlib.rc(%22legend%22%2C%20numpoints%3D1%2C%20fontsize%3D10)%0A%20%20%20%20return%20np%2C%20plt%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20The%20%60muscles.py%60%20module%20contains%20the%20class%20%60Thelen2003()%60%20which%20has%20the%20functions%20we%20want%20to%20use.%20To%20run%20a%20simulation%2C%20this%20class%20needs%20a%20set%20of%20muscle%20parameters%20and%20initial%20states.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20Instead%20of%20reading%20them%20from%20external%20files%2C%20we%20define%20the%20parameters%20and%20states%20directly%20in%20the%20notebook%20as%20Python%20dictionaries%2C%20so%20the%20notebook%20is%20self-contained%20and%20runs%20anywhere%2C%20including%20in%20the%20browser%20at%20%5Bmarimo.app%5D(https%3A%2F%2Fmarimo.app%2F).%20Let's%20use%20the%20parameters%20and%20states%20from%20an%20exercise%20of%20the%20chapter%204%20of%20Nigg%20and%20Herzog%20(2006)%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20parameters%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22id%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22u_max%22%3A%201.0%2C%20%20%23%20maximum%20value%20for%20muscle%20excitation%0A%20%20%20%20%20%20%20%20%22u_min%22%3A%200.01%2C%20%20%23%20minimum%20value%20for%20muscle%20excitation%0A%20%20%20%20%20%20%20%20%22t_act%22%3A%200.015%2C%20%20%23%20activation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%22t_deact%22%3A%200.050%2C%20%20%23%20deactivation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%22lmopt%22%3A%200.093%2C%20%20%23%20optimal%20CE%20length%0A%20%20%20%20%20%20%20%20%22alpha0%22%3A%200.0%2C%20%20%23%20pennation%20angle%20at%20rest%0A%20%20%20%20%20%20%20%20%22fm0%22%3A%207400.0%2C%20%20%23%20maximum%20isometric%20muscle%20force%0A%20%20%20%20%20%20%20%20%22gammal%22%3A%200.45%2C%20%20%23%20CE%20force-length%20shape%20factor%0A%20%20%20%20%20%20%20%20%22kpe%22%3A%205.0%2C%20%20%23%20PE%20exponential%20shape%20factor%0A%20%20%20%20%20%20%20%20%22epsm0%22%3A%200.6%2C%20%20%23%20PE%20passive%20muscle%20strain%20due%20to%20maximum%20isometric%20force%0A%20%20%20%20%20%20%20%20%22vmmax%22%3A%2010.0%2C%20%20%23%20CE%20force-velocity%20maximum%20velocity%20(concentric)%0A%20%20%20%20%20%20%20%20%22fmlen%22%3A%201.4%2C%20%20%23%20CE%20force-velocity%20maximum%20force%20(lengthening)%0A%20%20%20%20%20%20%20%20%22af%22%3A%200.25%2C%20%20%23%20CE%20force-velocity%20shape%20factor%0A%20%20%20%20%20%20%20%20%22ltslack%22%3A%200.223%2C%20%20%23%20tendon%20slack%20length%0A%20%20%20%20%20%20%20%20%22epst0%22%3A%200.04%2C%20%20%23%20tendon%20strain%20at%20the%20maximal%20isometric%20muscle%20force%0A%20%20%20%20%20%20%20%20%22kttoe%22%3A%203.0%2C%20%20%23%20tendon%20linear%20scale%20factor%0A%20%20%20%20%7D%0A%20%20%20%20return%20(parameters%2C)%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20states%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22id%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22lmt0%22%3A%200.313%2C%20%20%23%20initial%20muscle-tendon%20length%0A%20%20%20%20%20%20%20%20%22lm0%22%3A%200.09%2C%20%20%23%20initial%20muscle%20length%0A%20%20%20%20%20%20%20%20%22lt0%22%3A%20np.nan%2C%20%20%23%20initial%20tendon%20length%20(computed%20from%20the%20others%20if%20NaN)%0A%20%20%20%20%7D%0A%20%20%20%20return%20(states%2C)%0A%0A%0A%40app.cell%0Adef%20_(Thelen2003%2C%20parameters%2C%20states)%3A%0A%20%20%20%20ms%20%3D%20Thelen2003(parameters.copy()%2C%20states.copy())%0A%20%20%20%20return%20(ms%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20We%20can%20see%20the%20parameters%20and%20states%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20print(%22Parameters%3A%5Cn%22%2C%20ms.P)%0A%20%20%20%20print(%22States%3A%5Cn%22%2C%20ms.S)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20We%20can%20plot%20the%20muscle-tendon%20forces%20considering%20these%20parameters%20and%20initial%20states.%20**Before%20you%20run%20the%20next%20cell**%2C%20predict%20the%20shape%20of%20each%20curve%3A%20where%20along%20the%20fiber%20length%20is%20the%20active%20force%E2%80%93length%20curve%20maximal%2C%20and%20does%20the%20passive%20(PE)%20force%20appear%20before%20or%20after%20the%20optimal%20length%3F%20Where%20does%20the%20tendon%20(SE)%20force%20become%20non-zero%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20ms.muscle_plot()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Let's%20simulate%20an%20isometric%20activation.%20Since%20we%20have%20not%20run%20the%20activation%20dynamics%20yet%2C%20the%20solver%20uses%20%24a%3D1%24%20(full%20activation)%20throughout.%0A%0A%20%20%20%20**Before%20you%20run%20the%20next%20cell**%2C%20return%20to%20your%20answer%20for%20**Challenge%200**.%20The%20muscle%E2%80%93tendon%20length%20is%20held%20fixed%2C%20but%20the%20muscle%20is%20fully%20active.%20Predict%20whether%20the%20fiber%20length%20%24L_M%24%20stays%20constant%20or%20changes%2C%20and%20what%20the%20tendon%20does.%20Then%20read%20the%20%24L_M%24%20and%20%24L_T%24%20panels%20of%20the%20plot%20to%20check.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20def%20lmt_eq(t%2C%20lmt0)%3A%0A%20%20%20%20%20%20%20%20%23%20isometric%20activation%0A%0A%20%20%20%20%20%20%20%20lmt%20%3D%20lmt0%0A%0A%20%20%20%20%20%20%20%20return%20lmt%0A%0A%20%20%20%20ms.lmt_eq%20%3D%20lmt_eq%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20data%20%3D%20ms.lm_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20**Challenge%204.**%20In%20the%20isometric%20run%20above%2C%20the%20muscle%E2%80%93tendon%20length%20never%20changed%2C%20yet%20the%20fiber%20shortened%20a%20little%20while%20the%20tendon%20stretched.%20Explain%20this%20using%20tendon%20elasticity%20and%20the%20equilibrium%20condition%20%24F_T%20%3D%20F_M%5Ccos%5Calpha%24.%20(This%20is%20the%20effect%20you%20predicted%20in%20Challenge%200.)%0A%0A%20%20%20%20Now%20let's%20prescribe%20a%20*changing*%20muscle%E2%80%93tendon%20length.%20The%20next%20cell%20redefines%20the%20length%20function%20%60ms.lmt_eq%60%3A%20it%20holds%20the%20length%20constant%2C%20ramps%20it%20down%20by%204%20cm%20between%20%24t%3D1%24%20and%20%24t%3D2%24%20s%20(a%20shortening)%2C%20then%20holds%20it%20again.%20**Before%20you%20run%20it**%2C%20predict%20what%20the%20muscle%20fiber%20velocity%20%24V_%7BCE%7D%24%20will%20do%20during%20the%20ramp.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20def%20lmt_eq_1(t%2C%20lmt0)%3A%0A%20%20%20%20%20%20%20%20if%20t%20%3C%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20lmt0%0A%20%20%20%20%20%20%20%20if%201%20%3C%3D%20t%20%3C%202%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20lmt0%20-%200.04%20*%20(t%20-%201)%0A%20%20%20%20%20%20%20%20if%20t%20%3E%3D%202%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20lmt0%20-%200.04%0A%20%20%20%20%20%20%20%20return%20lmt%0A%0A%20%20%20%20ms.lmt_eq%20%3D%20lmt_eq_1%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20data_1%20%3D%20ms.lm_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Let's%20simulate%20a%20pennated%20muscle%20with%20an%20angle%20of%2430%5Eo%24.%20We%20don't%20need%20to%20enter%20all%20parameters%20again%2C%20we%20can%20change%20only%20the%20parameter%20%60alpha0%60.%0A%0A%20%20%20%20**Before%20you%20run**%2C%20recall%20Guiding%20questions%202%3A%20with%20%24%5Calpha_0%20%3D%2030%5Eo%24%2C%20only%20%24%5Ccos(30%5Eo)%5Capprox%200.87%24%20of%20the%20fiber%20force%20reaches%20the%20tendon.%20Predict%20whether%20the%20tendon%20force%20will%20be%20higher%20or%20lower%20than%20in%20the%20fusiform%20(%24%5Calpha_0%3D0%24)%20case.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms%2C%20np)%3A%0A%20%20%20%20ms.P%5B%22alpha0%22%5D%20%3D%2030%20*%20np.pi%20%2F%20180%0A%20%20%20%20print(%22New%20initial%20pennation%20angle%3A%22%2C%20ms.P%5B%22alpha0%22%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Because%20the%20muscle%20length%20is%20now%20shortened%20by%20%24%5Ccos(30%5Eo)%24%2C%20we%20will%20also%20have%20to%20change%20the%20initial%20muscle-tendon%20length%20if%20we%20want%20to%20start%20with%20the%20tendon%20at%20its%20slack%20length%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms%2C%20np)%3A%0A%20%20%20%20ms.S%5B%22lmt0%22%5D%20%3D%20ms.S%5B%22lmt0%22%5D%20-%20ms.S%5B%22lm0%22%5D%20%2B%20ms.S%5B%22lm0%22%5D%20*%20np.cos(ms.P%5B%22alpha0%22%5D)%0A%20%20%20%20print(%22New%20initial%20muscle-tendon%20length%3A%22%2C%20ms.S%5B%22lmt0%22%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20data_2%20%3D%20ms.lm_sol()%0A%20%20%20%20return%20(data_2%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Here%20is%20a%20plot%20of%20the%20simulated%20pennation%20angle%3A%0A%0A%20%20%20%20**Challenge%205.**%20The%20pennation%20angle%20is%20*not*%20constant%20during%20the%20contraction.%20From%20the%20constant-width%20assumption%2C%20does%20the%20angle%20grow%20or%20shrink%20as%20the%20fiber%20shortens%3F%20Confirm%20the%20direction%20of%20change%20against%20the%20plot.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(data_2%2C%20np%2C%20plt)%3A%0A%20%20%20%20plt.figure(figsize%3D(7%2C%204))%0A%20%20%20%20plt.plot(data_2%5B%3A%2C%200%5D%2C%20data_2%5B%3A%2C%209%5D%20*%20180%20%2F%20np.pi)%0A%20%20%20%20plt.xlabel(%22Time%20(s)%22)%0A%20%20%20%20plt.ylabel(%22Pennation%20angle%24(%5Eo)%24%22)%0A%20%20%20%20plt.show()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Change%20back%20to%20the%20old%20values%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20ms.P%5B%22alpha0%22%5D%20%3D%200%0A%20%20%20%20ms.S%5B%22lmt0%22%5D%20%3D%200.313%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20We%20can%20change%20the%20initial%20states%20to%20show%20the%20role%20of%20the%20passive%20parallel%20element.%20The%20next%20cell%20sets%20a%20*longer*%20initial%20fiber%20length%20(%24L_M%20%3D%200.10%24%20m%2C%20above%20the%20optimal%20%240.093%24%20m)%20so%20the%20passive%20element%20is%20engaged.%0A%0A%20%20%20%20**Before%20you%20run**%20the%20plot%2C%20predict%3A%20at%20a%20fiber%20length%20beyond%20the%20optimum%2C%20does%20the%20total%20muscle%20force%20come%20only%20from%20the%20active%20element%2C%20only%20from%20the%20passive%20(PE)%20element%2C%20or%20from%20both%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms%2C%20np)%3A%0A%20%20%20%20ms.S%20%3D%20%7B%22id%22%3A%20%22%22%2C%20%22lt0%22%3A%20np.nan%2C%20%22lmt0%22%3A%200.323%2C%20%22lm0%22%3A%200.10%2C%20%22name%22%3A%20%22%22%7D%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20ms.muscle_plot()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20So%20far%20the%20activation%20was%20fixed%20at%20%24a%3D1%24.%20Now%20let's%20drive%20the%20muscle%20with%20a%20time-varying%20*excitation*%20and%20let%20the%20activation%20dynamics%20respond.%20The%20next%20cell%20defines%20a%20%22hat%22%20excitation%3A%20%24u%3D1%24%20between%20%24t%3D1%24%20and%20%24t%3D2%24%20s%2C%20and%20%24u%3D0.01%24%20otherwise.%0A%0A%20%20%20%20**Before%20you%20run**%20the%20activation%20plot%2C%20predict%3A%20will%20the%20activation%20%24a(t)%24%20follow%20the%20excitation%20instantly%2C%20or%20will%20it%20lag%20on%20the%20way%20up%20and%20on%20the%20way%20down%3F%20Which%20should%20be%20slower%20%E2%80%94%20activation%20or%20deactivation%20%E2%80%94%20given%20%24t_%7Bact%7D%3D0.015%24%20s%20and%20%24t_%7Bdeact%7D%3D0.05%24%20s%3F%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20def%20excitation(t%2C%20u_max%3D1%2C%20u_min%3D0.01%2C%20t0%3D1%2C%20t1%3D2)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Excitation%20signal%2C%20a%20hat%20signal.%22%22%22%0A%20%20%20%20%20%20%20%20u%20%3D%20u_min%0A%20%20%20%20%20%20%20%20if%20t%20%3E%3D%20t0%20and%20t%20%3C%3D%20t1%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20return%20u%0A%0A%20%20%20%20ms.excitation%20%3D%20excitation%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20act%20%3D%20ms.activation_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20And%20let's%20simulate%20an%20isometric%20contraction%3A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20def%20lmt_eq_2(t%2C%20lmt0)%3A%0A%20%20%20%20%20%20%20%20lmt%20%3D%20lmt0%0A%20%20%20%20%20%20%20%20return%20lmt%0A%0A%20%20%20%20ms.lmt_eq%20%3D%20lmt_eq_2%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20data_3%20%3D%20ms.lm_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Let's%20use%20as%20excitation%20a%20train%20of%20short%20pulses%20(a%20crude%20model%20of%20repetitive%20motor-unit%20firing).%0A%0A%20%20%20%20**Before%20you%20run**%20the%20activation%20and%20force%20plots%2C%20predict%20what%20happens%20between%20pulses%3A%20does%20activation%20drop%20all%20the%20way%20back%20to%20rest%2C%20or%20does%20it%20stay%20partly%20elevated%20so%20that%20successive%20pulses%20*summate*%20into%20a%20smoother%2C%20sustained%20force%3F%0A%0A%20%20%20%20**Challenge%206.**%20Compare%20the%20muscle%20force%20from%20this%20pulse%20train%20with%20the%20single%20%22hat%22%20excitation%20before%20it.%20If%20you%20wanted%20a%20smoother%20force%2C%20would%20you%20increase%20the%20pulse%20*rate*%20or%20the%20pulse%20*amplitude*%3F%20Change%20the%20%600.1%60%20spacing%20in%20%60np.arange(1%2C%202.0%2C%200.1)%60%20and%20re-run%20to%20test%20your%20answer.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms%2C%20np)%3A%0A%20%20%20%20def%20excitation_1(t%2C%20u_max%3D0.5%2C%20u_min%3D0.01%2C%20t0%3D0.2%2C%20t1%3D2)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Excitation%20signal%2C%20a%20train%20of%20square%20pulses.%22%22%22%0A%20%20%20%20%20%20%20%20u%20%3D%20u_min%0A%20%20%20%20%20%20%20%20ts%20%3D%20np.arange(1%2C%202.0%2C%200.1)%0A%20%20%20%20%20%20%20%20if%20t%20%3E%3D%20ts%5B0%5D%20and%20t%20%3C%3D%20ts%5B1%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20elif%20t%20%3E%3D%20ts%5B2%5D%20and%20t%20%3C%3D%20ts%5B3%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20elif%20t%20%3E%3D%20ts%5B4%5D%20and%20t%20%3C%3D%20ts%5B5%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20elif%20t%20%3E%3D%20ts%5B6%5D%20and%20t%20%3C%3D%20ts%5B7%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20elif%20t%20%3E%3D%20ts%5B8%5D%20and%20t%20%3C%3D%20ts%5B9%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%20%20%20%20%20%20%20%20return%20u%0A%0A%20%20%20%20ms.excitation%20%3D%20excitation_1%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20act_1%20%3D%20ms.activation_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ms)%3A%0A%20%20%20%20data_4%20%3D%20ms.lm_sol()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20**Exercise%203%20%E2%80%94%20Inspect%20isometric%20shortening.**%20At%20fixed%20musculotendon%20length%20and%20zero%20pennation%2C%20tendon%20extension%20increases%20by%204%20mm%20after%20activation.%20What%20happens%20to%20fiber%20length%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%2F%2F%2F%20details%20%7C%20Solution%20to%20Exercise%203%0A%0A%20%20%20%20From%20%24L_%7BMT%7D%3DL_M%2BL_T%24%2C%20fiber%20length%20decreases%20by%204%20mm.%20%E2%80%9CIsometric%E2%80%9D%20at%20the%20musculotendon%20level%20does%20not%20require%20an%20isometric%20fiber.%20With%20pennation%2C%20use%20the%20changing%20projected%20fiber%20length%20instead.%0A%20%20%20%20%2F%2F%2F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Module%20muscles.py%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20from%20notebook_resources%20import%20repo_file%0A%20%20%20%20except%20ModuleNotFoundError%20as%20_error%3A%0A%20%20%20%20%20%20%20%20if%20_error.name%20!%3D%20%22notebook_resources%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20raise%0A%20%20%20%20%20%20%20%20raise%20ModuleNotFoundError(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22This%20notebook%20needs%20notebook_resources.py.%20Download%20it%20from%3A%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22https%3A%2F%2Fraw.githubusercontent.com%2FBMClab%2FBMC%2Fmaster%2Ffunctions%2Fnotebook_resources.py%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Save%20it%20in%20the%20same%20folder%20as%20this%20notebook%2C%20then%20rerun%20this%20cell.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22notebook_resources%22%2C%0A%20%20%20%20%20%20%20%20)%20from%20None%0A%20%20%20%20return%20(repo_file%2C)%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20repo_file)%3A%0A%20%20%20%20%22%22%22Muscle%20modeling%20and%20simulation.%22%22%22%0A%0A%20%20%20%20import%20configparser%0A%0A%20%20%20%20__author__%20%3D%20%22Marcos%20Duarte%2C%20https%3A%2F%2Fgithub.com%2FBMClab%2FBMC%22%0A%20%20%20%20__version__%20%3D%20%22muscles.py%20v.1.03%202026%2F07%2F07%22%0A%0A%20%20%20%20class%20Thelen2003%3A%0A%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20muscle%20model.%22%22%22%0A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20parameters%3DNone%2C%20states%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20parameters%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.set_parameters(parameters)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20states%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.set_states(states)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.lm_data%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20self.act_data%20%3D%20%5B%5D%0A%0A%20%20%20%20%20%20%20%20def%20set_parameters(self%2C%20var%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Load%20and%20set%20parameters%20for%20the%20muscle%20model.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20var%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20%3D%20str(repo_file(%22data%2Fmuscle_parameter.txt%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(var%2C%20str)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.P%20%3D%20self.config_parser(var%2C%20%22parameters%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20isinstance(var%2C%20dict)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.P%20%3D%20var%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20ValueError(%22Wrong%20parameters!%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22The%20parameters%20were%20successfully%20loaded%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%22and%20are%20stored%20in%20the%20variable%20P.%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20def%20set_states(self%2C%20var%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Load%20and%20set%20states%20for%20the%20muscle%20model.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20var%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var%20%3D%20str(repo_file(%22data%2Fmuscle_state.txt%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(var%2C%20str)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.S%20%3D%20self.config_parser(var%2C%20%22states%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20isinstance(var%2C%20dict)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.S%20%3D%20var%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20ValueError(%22Wrong%20states!%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22The%20states%20were%20successfully%20loaded%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%22and%20are%20stored%20in%20the%20variable%20S.%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20def%20config_parser(self%2C%20filename%2C%20var)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20parser%20%3D%20configparser.ConfigParser()%0A%20%20%20%20%20%20%20%20%20%20%20%20parser.optionxform%20%3D%20str%20%20%23%20make%20option%20names%20case%20sensitive%0A%20%20%20%20%20%20%20%20%20%20%20%20read_files%20%3D%20parser.read(filename)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20not%20read_files%20or%20not%20parser.sections()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20ValueError(f%22Could%20not%20read%20%7Bvar%7D%20from%20'%7Bfilename%7D'.%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20key%2C%20value%20in%20parser.items(parser.sections()%5B0%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20key.lower()%20in%20%5B%22name%22%2C%20%22id%22%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var.update(%7Bkey%3A%20value%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20%3D%20float(value)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20except%20ValueError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(f%22%7Bkey%7D%20value%20%7Bvalue%7D%20was%20replaced%20by%20NaN.%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20value%20%3D%20np.nan%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20var.update(%7Bkey%3A%20value%7D)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20var%0A%0A%20%20%20%20%20%20%20%20def%20force_l(self%2C%20lm%2C%20gammal%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20force%20of%20the%20contractile%20element%20vs.%20muscle%20length.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20gammal%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shape%20factor%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20force%20of%20the%20muscle%20contractile%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20gammal%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gammal%20%3D%20self.P%5B%22gammal%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3D%20np.exp(-((lm%20-%201)%20**%202)%20%2F%20gammal)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fl%0A%0A%20%20%20%20%20%20%20%20def%20force_pe(self%2C%20lm%2C%20kpe%3DNone%2C%20epsm0%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20force%20of%20the%20muscle%20parallel%20element%20vs.%20muscle%20length.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20kpe%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20exponential%20shape%20factor%0A%20%20%20%20%20%20%20%20%20%20%20%20epsm0%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20passive%20muscle%20strain%20due%20to%20maximum%20isometric%20force%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20force%20of%20the%20muscle%20parallel%20(passive)%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20kpe%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kpe%20%3D%20self.P%5B%22kpe%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20epsm0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20epsm0%20%3D%20self.P%5B%22epsm0%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lm%20%3C%3D%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3D%200%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3D%20(np.exp(kpe%20*%20(lm%20-%201)%20%2F%20epsm0)%20-%201)%20%2F%20(np.exp(kpe)%20-%201)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fpe%0A%0A%20%20%20%20%20%20%20%20def%20force_se(self%2C%20lt%2C%20ltslack%3DNone%2C%20epst0%3DNone%2C%20kttoe%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20force-length%20relationship%20of%20tendon%20vs.%20tendon%20length.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tendon%20length%20(normalized%20or%20not)%0A%20%20%20%20%20%20%20%20%20%20%20%20ltslack%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tendon%20slack%20length%20(normalized%20or%20not)%0A%20%20%20%20%20%20%20%20%20%20%20%20epst0%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tendon%20strain%20at%20the%20maximal%20isometric%20muscle%20force%0A%20%20%20%20%20%20%20%20%20%20%20%20kttoe%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linear%20scale%20factor%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20force%20of%20the%20tendon%20series%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20ltslack%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ltslack%20%3D%20self.P%5B%22ltslack%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20epst0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20epst0%20%3D%20self.P%5B%22epst0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20kttoe%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kttoe%20%3D%20self.P%5B%22kttoe%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20epst%20%3D%20(lt%20-%20ltslack)%20%2F%20ltslack%0A%20%20%20%20%20%20%20%20%20%20%20%20fttoe%20%3D%200.33%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20values%20from%20OpenSim%20Thelen2003Muscle%0A%20%20%20%20%20%20%20%20%20%20%20%20epsttoe%20%3D%200.99%20*%20epst0%20*%20np.e**3%20%2F%20(1.66%20*%20np.e**3%20-%200.67)%0A%20%20%20%20%20%20%20%20%20%20%20%20ktlin%20%3D%200.67%20%2F%20(epst0%20-%20epsttoe)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20epst%20%3C%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%200%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20epst%20%3C%3D%20epsttoe%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20fttoe%20%2F%20(np.exp(kttoe)%20-%201)%20*%20(np.exp(kttoe%20*%20epst%20%2F%20epsttoe)%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20ktlin%20*%20(epst%20-%20epsttoe)%20%2B%20fttoe%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fse%0A%0A%20%20%20%20%20%20%20%20def%20velo_fm(self%2C%20fm%2C%20a%2C%20fl%2C%20lmopt%3DNone%2C%20vmmax%3DNone%2C%20fmlen%3DNone%2C%20af%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20velocity%20of%20the%20force-velocity%20relationship%20vs.%20CE%20force.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20fm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20muscle%20force%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle%20activation%20level%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20muscle%20force%20due%20to%20the%20force-length%20relationship%0A%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20optimal%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20maximum%20muscle%20velocity%20for%20concentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20fmlen%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20maximum%20force%20generated%20at%20the%20lengthening%20phase%0A%20%20%20%20%20%20%20%20%20%20%20%20af%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shape%20factor%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20velocity%20of%20the%20muscle%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lmopt%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3D%20self.P%5B%22lmopt%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20vmmax%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3D%20self.P%5B%22vmmax%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fmlen%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fmlen%20%3D%20self.P%5B%22fmlen%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20af%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20af%20%3D%20self.P%5B%22af%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fm%20%3C%3D%20a%20*%20fl%3A%20%20%23%20isometric%20and%20concentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20fm%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20%3D%20a%20*%20fl%20%2B%20fm%20%2F%20af%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20%3D%20a%20*%20fl%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%20%20%23%20eccentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20asyE_thresh%20%3D%200.95%20%20%23%20from%20OpenSim%20Thelen2003Muscle%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20fm%20%3C%20a%20*%20fl%20*%20fmlen%20*%20asyE_thresh%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20%3D%20(2%20%2B%202%20%2F%20af)%20*%20(a%20*%20fl%20*%20fmlen%20-%20fm)%20%2F%20(fmlen%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fm_thresh%20%3D%20a%20*%20fl%20*%20fmlen%20*%20asyE_thresh%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20b%20%3D%20(2%20%2B%202%20%2F%20af)%20*%20(a%20*%20fl%20*%20fmlen%20-%20fm_thresh)%20%2F%20(fmlen%20-%201)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20(0.25%20%2B%200.75%20*%20a)%20*%20(fm%20-%20a%20*%20fl)%20%2F%20b%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20vm%20*%20vmmax%20*%20lmopt%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20vm%0A%0A%20%20%20%20%20%20%20%20def%20force_vm(self%2C%20vm%2C%20a%2C%20fl%2C%20lmopt%3DNone%2C%20vmmax%3DNone%2C%20fmlen%3DNone%2C%20af%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20force%20of%20the%20contractile%20element%20vs.%20muscle%20velocity.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle%20velocity%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle%20activation%20level%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20muscle%20force%20due%20to%20the%20force-length%20relationship%0A%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20optimal%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20maximum%20muscle%20velocity%20for%20concentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20fmlen%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20normalized%20maximum%20force%20generated%20at%20the%20lengthening%20phase%0A%20%20%20%20%20%20%20%20%20%20%20%20af%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shape%20factor%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20fvm%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20normalized%20force%20of%20the%20muscle%20contractile%20element%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lmopt%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3D%20self.P%5B%22lmopt%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20vmmax%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3D%20self.P%5B%22vmmax%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fmlen%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fmlen%20%3D%20self.P%5B%22fmlen%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20af%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20af%20%3D%20self.P%5B%22af%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3D%20vmmax%20*%20lmopt%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20vm%20%3C%3D%200%3A%20%20%23%20isometric%20and%20concentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fvm%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20af%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20a%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20fl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(4%20*%20vm%20%2B%20vmmax%20*%20(3%20*%20a%20%2B%201))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%20(-4%20*%20vm%20%2B%20vmmax%20*%20af%20*%20(3%20*%20a%20%2B%201))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%20%20%23%20eccentric%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fvm%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20fl%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20af%20*%20vmmax%20*%20(3%20*%20a%20*%20fmlen%20-%203%20*%20a%20%2B%20fmlen%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%208%20*%20vm%20*%20fmlen%20*%20(af%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20af%20*%20vmmax%20*%20(3%20*%20a%20*%20fmlen%20-%203%20*%20a%20%2B%20fmlen%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%208%20*%20vm%20*%20(af%20%2B%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20fvm%0A%0A%20%20%20%20%20%20%20%20def%20lmt_eq(self%2C%20t%2C%20lmt0%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Equation%20for%20muscle-tendon%20length.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lmt0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmt0%20%3D%20self.S%5B%22lmt0%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20lmt0%0A%0A%20%20%20%20%20%20%20%20def%20vm_eq(self%2C%20t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20lmopt%2C%20ltslack%2C%20alpha0%2C%20vmmax%2C%20fm0)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Equation%20for%20muscle%20velocity.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lm%20%3C%200.1%20*%20lmopt%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%200.1%20*%20lmopt%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20lt0%20%3D%20lmt0%20-%20lm0*np.cos(alpha0)%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20self.activation(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20self.lmt_eq(t%2C%20lmt0)%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3D%20self.penn_ang(lmt%3Dlmt%2C%20lm%3Dlm%2C%20lm0%3Dlm0%2C%20alpha0%3Dalpha0)%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3D%20lmt%20-%20lm%20*%20np.cos(alpha)%0A%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20self.force_se(lt%3Dlt%2C%20ltslack%3Dltslack)%0A%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3D%20self.force_pe(lm%3Dlm%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3D%20self.force_l(lm%3Dlm%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fce_t%20%3D%20fse%20%2F%20np.cos(alpha)%20-%20fpe%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20if%20fce_t%20%3C%200%3A%20fce_t%3D0%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20self.velo_fm(fm%3Dfce_t%2C%20a%3Da%2C%20fl%3Dfl)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20vm%0A%0A%20%20%20%20%20%20%20%20def%20lm_sol(%0A%20%20%20%20%20%20%20%20%20%20%20%20self%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fun%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t0%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t1%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20dt%3D0.001%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lm0%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt0%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ltslack%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lmopt%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha0%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20vmmax%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fm0%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20show%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%3DNone%2C%0A%20%20%20%20%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Forward%20Euler%20ODE%20solver%20for%20muscle%20length.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lm0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm0%20%3D%20self.S%5B%22lm0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lmt0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmt0%20%3D%20self.S%5B%22lmt0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20ltslack%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ltslack%20%3D%20self.P%5B%22ltslack%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20alpha0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha0%20%3D%20self.P%5B%22alpha0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lmopt%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3D%20self.P%5B%22lmopt%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20vmmax%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3D%20self.P%5B%22vmmax%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fm0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fm0%20%3D%20self.P%5B%22fm0%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fun%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fun%20%3D%20self.vm_eq%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20nsteps%20%3D%20int(round((t1%20-%20t0)%20%2F%20dt))%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20lm0%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(nsteps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20t0%20%2B%20i%20*%20dt%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20max(lm%2C%200.1%20*%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.calc_data(t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20ltslack%2C%20lmopt%2C%20alpha0%2C%20fm0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20fun(t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20lmopt%2C%20ltslack%2C%20alpha0%2C%20vmmax%2C%20fm0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20lm%20%2B%20dt%20*%20vm%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20np.array(data)%0A%20%20%20%20%20%20%20%20%20%20%20%20self.lm_data%20%3D%20data%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20show%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.lm_plot(data%2C%20axs)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data%0A%0A%20%20%20%20%20%20%20%20def%20calc_data(self%2C%20t%2C%20lm%2C%20lm0%2C%20lmt0%2C%20ltslack%2C%20lmopt%2C%20alpha0%2C%20fm0)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Calculus%20of%20muscle-tendon%20variables.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20self.activation(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20self.lmt_eq(t%2C%20lmt0%3Dlmt0)%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3D%20self.penn_ang(lmt%3Dlmt%2C%20lm%3Dlm%2C%20lm0%3Dlm0%2C%20alpha0%3Dalpha0)%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3D%20lmt%20-%20lm%20*%20np.cos(alpha)%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3D%20self.force_l(lm%3Dlm%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3D%20self.force_pe(lm%3Dlm%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20self.force_se(lt%3Dlt%2C%20ltslack%3Dltslack)%0A%20%20%20%20%20%20%20%20%20%20%20%20fce_t%20%3D%20fse%20%2F%20np.cos(alpha)%20-%20fpe%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20self.velo_fm(fm%3Dfce_t%2C%20a%3Da%2C%20fl%3Dfl%2C%20lmopt%3Dlmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fm%20%3D%20self.force_vm(vm%3Dvm%2C%20fl%3Dfl%2C%20lmopt%3Dlmopt%2C%20a%3Da)%20%2B%20fpe%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lmt%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lt%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20vm%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fm%20*%20fm0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fse%20*%20fm0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20*%20fl%20*%20fm0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fpe%20*%20fm0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data%0A%0A%20%20%20%20%20%20%20%20def%20muscle_plot(self%2C%20a%3D1%2C%20axs%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Plot%20muscle-tendon%20relationships%20with%20length%20and%20velocity.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20ImportError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22matplotlib%20is%20not%20available.%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20axs%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fig%2C%20axs%20%3D%20plt.subplots(nrows%3D1%2C%20ncols%3D3%2C%20figsize%3D(9%2C%204))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20lmopt%20%3D%20self.P%5B%22lmopt%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20ltslack%20%3D%20self.P%5B%22ltslack%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20vmmax%20%3D%20self.P%5B%22vmmax%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha0%20%3D%20self.P%5B%22alpha0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20fm0%20%3D%20self.P%5B%22fm0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20lm0%20%3D%20self.S%5B%22lm0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt0%20%3D%20self.S%5B%22lmt0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20lt0%20%3D%20self.S%5B%22lt0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20np.isnan(lt0)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lt0%20%3D%20lmt0%20-%20lm0%20*%20np.cos(alpha0)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20np.linspace(0%2C%202%2C%20101)%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3D%20np.linspace(0%2C%201%2C%20101)%20*%200.05%20%2B%201%0A%20%20%20%20%20%20%20%20%20%20%20%20vm%20%3D%20np.linspace(-1%2C%201%2C%20101)%20*%20vmmax%20*%20lmopt%0A%20%20%20%20%20%20%20%20%20%20%20%20fl%20%3D%20np.zeros(lm.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20fpe%20%3D%20np.zeros(lm.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20np.zeros(lt.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20fvm%20%3D%20np.zeros(vm.size)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20fl_lm0%20%3D%20self.force_l(lm0%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fpe_lm0%20%3D%20self.force_pe(lm0%20%2F%20lmopt)%0A%20%20%20%20%20%20%20%20%20%20%20%20fm_lm0%20%3D%20fl_lm0%20%2B%20fpe_lm0%0A%20%20%20%20%20%20%20%20%20%20%20%20ft_lt0%20%3D%20self.force_se(lt0%2C%20ltslack)%20*%20fm0%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(101)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fl%5Bi%5D%20%3D%20self.force_l(lm%5Bi%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fpe%5Bi%5D%20%3D%20self.force_pe(lm%5Bi%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fse%5Bi%5D%20%3D%20self.force_se(lt%5Bi%5D%2C%20ltslack%3D1)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fvm%5Bi%5D%20%3D%20self.force_vm(vm%5Bi%5D%2C%20a%3Da%2C%20fl%3Dfl_lm0)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3D%20lm%20*%20lmopt%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3D%20lt%20*%20ltslack%0A%20%20%20%20%20%20%20%20%20%20%20%20fse%20%3D%20fse%20*%20fm0%0A%20%20%20%20%20%20%20%20%20%20%20%20fvm%20%3D%20fvm%20*%20fm0%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20xlim%20%3D%20self.margins(lm%2C%20margin%3D0.05%2C%20minmargin%3DFalse)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.set_xlim(xlim)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(%5B0%2C%202%5D%2C%20margin%3D0.05)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(lm%2C%20fl%2C%20%22b%22%2C%20label%3D%22Active%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(lm%2C%20fpe%2C%20%22b--%22%2C%20label%3D%22Passive%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(lm%2C%20fl%20%2B%20fpe%2C%20%22b%3A%22%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(%5Blm0%2C%20lm0%5D%2C%20%5Bylim%5B0%5D%2C%20fm_lm0%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(%5Bxlim%5B0%5D%2C%20lm0%5D%2C%20%5Bfm_lm0%2C%20fm_lm0%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.plot(lm0%2C%20fm_lm0%2C%20%22o%22%2C%20ms%3D6%2C%20mfc%3D%22r%22%2C%20mec%3D%22r%22%2C%20mew%3D2%2C%20label%3D%22fl(LM0)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.legend(loc%3D%22best%22%2C%20frameon%3DTrue%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.set_xlabel(%22Length%20%5Bm%5D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.set_ylabel(%22Scale%20factor%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.xaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.yaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%5D.set_title(%22Muscle%20F-L%20(a%3D1)%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20xlim%20%3D%20self.margins(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B0%2C%20np.min(vm)%2C%20np.max(vm)%5D%2C%20margin%3D0.05%2C%20minmargin%3DFalse%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.set_xlim(xlim)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(%5B0%2C%20fm0%20*%201.2%2C%20np.max(fvm)%20*%201.5%5D%2C%20margin%3D0.025)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.plot(vm%2C%20fvm%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.set_xlabel(r%22%24%5Cmathbf%7B%5E%7BCON%7D%7D%5C%3B%24%20Velocity%20%5Bm%2Fs%5D%20%24%5C%3B%5Cmathbf%7B%5E%7BEXC%7D%7D%24%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.plot(%5B0%2C%200%5D%2C%20%5Bylim%5B0%5D%2C%20fvm%5B50%5D%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.plot(%5Bxlim%5B0%5D%2C%200%5D%2C%20%5Bfvm%5B50%5D%2C%20fvm%5B50%5D%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.plot(0%2C%20fvm%5B50%5D%2C%20%22o%22%2C%20ms%3D6%2C%20mfc%3D%22r%22%2C%20mec%3D%22r%22%2C%20mew%3D2%2C%20label%3D%22FM0(LM0)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.plot(xlim%5B0%5D%2C%20fm0%2C%20%22%2B%22%2C%20ms%3D10%2C%20mfc%3D%22r%22%2C%20mec%3D%22r%22%2C%20mew%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.text(vm%5B0%5D%2C%20fm0%2C%20%22FM0%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.legend(loc%3D%22upper%20right%22%2C%20frameon%3DTrue%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.set_ylabel(%22Force%20%5BN%5D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.xaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.yaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%5D.set_title(%22Muscle%20F-V%20(a%3D1)%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20xlim%20%3D%20self.margins(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Blt0%2C%20ltslack%2C%20np.min(lt)%2C%20np.max(lt)%5D%2C%20margin%3D0.05%2C%20minmargin%3DFalse%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.set_xlim(xlim)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(%5Bft_lt0%2C%200%2C%20np.max(fse)%5D%2C%20margin%3D0.05)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.plot(lt%2C%20fse%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.set_xlabel(%22Length%20%5Bm%5D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.plot(%5Blt0%2C%20lt0%5D%2C%20%5Bylim%5B0%5D%2C%20ft_lt0%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.plot(%5Bxlim%5B0%5D%2C%20lt0%5D%2C%20%5Bft_lt0%2C%20ft_lt0%5D%2C%20%22k%3A%22%2C%20lw%3D2%2C%20label%3D%22%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.plot(lt0%2C%20ft_lt0%2C%20%22o%22%2C%20ms%3D6%2C%20mfc%3D%22r%22%2C%20mec%3D%22r%22%2C%20mew%3D2%2C%20label%3D%22FT(LT0)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.legend(loc%3D%22upper%20left%22%2C%20frameon%3DTrue%2C%20framealpha%3D0.5)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.set_ylabel(%22Force%20%5BN%5D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.xaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.yaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%5D.set_title(%22Tendon%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.suptitle(%22Muscle-tendon%20mechanics%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.tight_layout(w_pad%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.show()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20axs%0A%0A%20%20%20%20%20%20%20%20def%20lm_plot(self%2C%20x%2C%20axs%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Plot%20the%20muscle-tendon%20simulation%20results.%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20%5Bt%2C%20lmt%2C%20lm%2C%20lt%2C%20vm%2C%20fm*fm0%2C%20fse*fm0%2C%20fl*fm0%2C%20fpe*fm0%2C%20alpha%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20ImportError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22matplotlib%20is%20not%20available.%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20axs%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fig%2C%20axs%20%3D%20plt.subplots(nrows%3D3%2C%20ncols%3D2%2C%20sharex%3DTrue%2C%20figsize%3D(9%2C%206))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%201%5D%2C%20%22b%22%2C%20label%3D%22LMT%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3D%20x%5B%3A%2C%202%5D%20*%20np.cos(x%5B%3A%2C%209%5D)%20%2B%20x%5B%3A%2C%203%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20np.sum(x%5B%3A%2C%209%5D)%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20lmt%2C%20%22g--%22%2C%20label%3Dr%22%24LM%20%5Ccos%20%5Calpha%20%2B%20LT%24%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20lmt%2C%20%22g--%22%2C%20label%3Dr%22LM%2BLT%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%201%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%200%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%200%5D.legend(framealpha%3D0.5%2C%20loc%3D%22best%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%201%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%203%5D%2C%20%22b%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20axs%5B0%2C%201%5D.plot(x%5B%3A%2C%200%5D%2C%20lt0*np.ones(len(x))%2C%20'r')%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%203%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B0%2C%201%5D.set_ylim(ylim)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%202%5D%2C%20%22b%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20axs%5B1%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20lmopt*np.ones(len(x))%2C%20'r')%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%202%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%2C%200%5D.set_ylim(ylim)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%2C%201%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%204%5D%2C%20%22b%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%204%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B1%2C%201%5D.set_ylim(ylim)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%205%5D%2C%20%22b%22%2C%20label%3D%22Muscle%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%200%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%206%5D%2C%20%22g--%22%2C%20label%3D%22Tendon%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%20%5B5%2C%206%5D%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%200%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%200%5D.set_xlabel(%22Time%20(s)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%200%5D.legend(framealpha%3D0.5%2C%20loc%3D%22best%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%201%5D.plot(x%5B%3A%2C%200%5D%2C%20x%5B%3A%2C%208%5D%2C%20%22b%22%2C%20label%3D%22PE%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20ylim%20%3D%20self.margins(x%5B%3A%2C%208%5D%2C%20margin%3D0.1)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%201%5D.set_ylim(ylim)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%201%5D.set_xlabel(%22Time%20(s)%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%5B2%2C%201%5D.legend(framealpha%3D0.5%2C%20loc%3D%22best%22)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20ylabel%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24L_%7BMT%7D%5C%2C(m)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24L_%7BT%7D%5C%2C(m)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24L_%7BM%7D%5C%2C(m)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24V_%7BCE%7D%5C%2C(m%2Fs)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24Force%5C%2C(N)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24Force%5C%2C(N)%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%2C%20axi%20in%20enumerate(axs.flat)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20axi.set_ylabel(ylabel%5Bi%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20axi.yaxis.set_major_locator(plt.MaxNLocator(4))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fig.align_ylabels(axs)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20axi.yaxis.set_label_coords(-.2%2C%200.5)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.suptitle(%22Simulation%20of%20muscle-tendon%20mechanics%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.show()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20axs%0A%0A%20%20%20%20%20%20%20%20def%20penn_ang(self%2C%20lmt%2C%20lm%2C%20lt%3DNone%2C%20lm0%3DNone%2C%20alpha0%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Pennation%20angle.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20lmt%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle-tendon%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20lt%20%3A%20float%2C%20optional%20(default%3DNone)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tendon%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20lm%20%3A%20float%2C%20optional%20(default%3DNone)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20lm0%20%3A%20float%2C%20optional%20(default%20from%20states%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial%20muscle%20fiber%20length%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha0%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial%20pennation%20angle%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pennation%20angle%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lm0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lm0%20%3D%20self.S%5B%22lm0%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20alpha0%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha0%20%3D%20self.P%5B%22alpha0%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3D%20alpha0%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20alpha0%20!%3D%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20w%20%3D%20lm0%20*%20np.sin(alpha0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20lm%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cosalpha%20%3D%20np.sqrt(1%20-%20(w%20%2F%20lm)%20**%202)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20lmt%20is%20not%20None%20and%20lt%20is%20not%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cosalpha%20%3D%201%20%2F%20(np.sqrt(1%20%2B%20(w%20%2F%20(lmt%20-%20lt))%20**%202))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3D%20np.arccos(cosalpha)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20alpha%20%3E%201.4706289%3A%20%20%23%20np.arccos(0.1)%2C%2084.2608%20degrees%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%20%3D%201.4706289%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20alpha%0A%0A%20%20%20%20%20%20%20%20def%20excitation(self%2C%20t%2C%20u_max%3DNone%2C%20u_min%3DNone%2C%20t0%3D0%2C%20t1%3D5)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Excitation%20signal%2C%20a%20square%20wave.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20t%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20time%20instant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20u_max%20%3A%20float%20(0%20%3C%20u_max%20%3C%3D%201)%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maximum%20value%20for%20muscle%20excitation%0A%20%20%20%20%20%20%20%20%20%20%20%20u_min%20%3A%20float%20(0%20%3C%20u_min%20%3C%201)%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20minimum%20value%20for%20muscle%20excitation%0A%20%20%20%20%20%20%20%20%20%20%20%20t0%20%3A%20float%2C%20optional%20(default%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial%20time%20instant%20for%20muscle%20excitation%20equals%20to%20u_max%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20t1%20%3A%20float%2C%20optional%20(default%3D5)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20time%20instant%20for%20muscle%20excitation%20equals%20to%20u_max%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3A%20float%20(0%20%3C%20u%20%3C%3D%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20excitation%20signal%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20u_max%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20u_max%20%3D%20self.P%5B%22u_max%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20u_min%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20u_min%20%3D%20self.P%5B%22u_min%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_min%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t%20%3E%3D%20t0%20and%20t%20%3C%3D%20t1%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20u_max%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20u%0A%0A%20%20%20%20%20%20%20%20def%20activation_dyn(self%2C%20t%2C%20a%2C%20t_act%3DNone%2C%20t_deact%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Thelen%20(2003)%20activation%20dynamics%2C%20the%20derivative%20of%20%60a%60%20at%20%60t%60.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20t%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20time%20instant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3A%20float%20(0%20%3C%3D%20a%20%3C%3D%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20muscle%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20t_act%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20t_deact%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20deactivation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20adot%20%3A%20float%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20derivative%20of%20%60a%60%20at%20%60t%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t_act%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t_act%20%3D%20self.P%5B%22t_act%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t_deact%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t_deact%20%3D%20self.P%5B%22t_deact%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20u%20%3D%20self.excitation(t)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20u%20%3E%20a%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20adot%20%3D%20(u%20-%20a)%20%2F%20(t_act%20*%20(0.5%20%2B%201.5%20*%20a))%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20adot%20%3D%20(u%20-%20a)%20%2F%20(t_deact%20%2F%20(0.5%20%2B%201.5%20*%20a))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20adot%0A%0A%20%20%20%20%20%20%20%20def%20activation_sol(%0A%20%20%20%20%20%20%20%20%20%20%20%20self%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fun%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t0%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t1%3D3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20dt%3D0.001%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20a0%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20u_min%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_act%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20t_deact%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20show%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%3DNone%2C%0A%20%20%20%20%20%20%20%20)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Forward%20Euler%20ODE%20solver%20for%20activation%20dynamics.%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Parameters%0A%20%20%20%20%20%20%20%20%20%20%20%20----------%0A%20%20%20%20%20%20%20%20%20%20%20%20fun%20%3A%20function%20object%2C%20optional%20(default%20is%20None%20and%20%60activation_dyn%60%20is%20used)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20function%20with%20ODE%20to%20be%20solved%0A%20%20%20%20%20%20%20%20%20%20%20%20t0%20%3A%20float%2C%20optional%20(default%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial%20time%20instant%20for%20the%20simulation%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20t1%20%3A%20float%2C%20optional%20(default%3D3)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20time%20instant%20for%20the%20simulation%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20dt%20%3A%20float%2C%20optional%20(default%3D0.001)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fixed%20integration%20time%20step%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20a0%20%3A%20float%2C%20optional%20(default%3D0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20initial%20muscle%20activation%0A%20%20%20%20%20%20%20%20%20%20%20%20u_min%20%3A%20float%20(0%20%3C%20u_min%20%3C%201)%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20minimum%20value%20for%20muscle%20excitation%0A%20%20%20%20%20%20%20%20%20%20%20%20t_act%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20activation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20t_deact%20%3A%20float%2C%20optional%20(default%20from%20parameter%20file)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20deactivation%20time%20constant%20%5Bs%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20show%20%3A%20bool%2C%20optional%20(default%20%3D%20True)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20True%20(1)%2C%20plot%20data%20in%20matplotlib%20figure%0A%20%20%20%20%20%20%20%20%20%20%20%20axs%20%3A%20a%20matplotlib.axes.Axes%20instance%2C%20optional%20(default%20%3D%20None)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20Returns%0A%20%20%20%20%20%20%20%20%20%20%20%20-------%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3A%202-d%20array%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20array%20with%20columns%20%5Btime%2C%20excitation%2C%20activation%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20u_min%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20u_min%20%3D%20self.P%5B%22u_min%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t_act%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t_act%20%3D%20self.P%5B%22t_act%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t_deact%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t_deact%20%3D%20self.P%5B%22t_deact%22%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20fun%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fun%20%3D%20self.activation_dyn%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20nsteps%20%3D%20int(round((t1%20-%20t0)%20%2F%20dt))%0A%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20a0%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(nsteps)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20t%20%3D%20t0%20%2B%20i%20*%20dt%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data.append(%5Bt%2C%20self.excitation(t)%2C%20max(a%2C%20u_min)%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20adot%20%3D%20fun(t%2C%20a%2C%20t_act%2C%20t_deact)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20a%20%2B%20dt%20*%20adot%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20np.array(data)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20show%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.activation_plot(data%2C%20axs)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.act_data%20%3D%20data%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20data%0A%0A%20%20%20%20%20%20%20%20def%20activation(self%2C%20t%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Activation%20signal.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20self.act_data%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t%20is%20not%20None%20and%20len(data)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20t%20%3C%3D%20self.act_data%5B0%2C%200%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20self.act_data%5B0%2C%202%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20t%20%3E%3D%20self.act_data%5B-1%2C%200%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20self.act_data%5B-1%2C%202%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%20np.interp(t%2C%20self.act_data%5B%3A%2C%200%5D%2C%20self.act_data%5B%3A%2C%202%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20a%20%3D%201%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20a%0A%0A%20%20%20%20%20%20%20%20def%20activation_plot(self%2C%20data%2C%20axs%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Plot%20the%20activation%20dynamics%20results.%22%22%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20%20%20%20%20%20%20%20%20except%20ImportError%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22matplotlib%20is%20not%20available.%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20axs%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20_%2C%20axs%20%3D%20plt.subplots(nrows%3D1%2C%20ncols%3D1%2C%20figsize%3D(6%2C%204))%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20axs.plot(data%5B%3A%2C%200%5D%2C%20data%5B%3A%2C%201%5D%2C%20color%3D%5B1%2C%200%2C%200%2C%200.6%5D%2C%20label%3D%22Excitation%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs.plot(data%5B%3A%2C%200%5D%2C%20data%5B%3A%2C%202%5D%2C%20color%3D%5B0%2C%200%2C%201%2C%200.6%5D%2C%20label%3D%22Activation%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs.set_xlabel(%22Time%20%5Bs%5D%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs.set_ylabel(%22Level%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20axs.legend()%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.title(%22Activation%20dynamics%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.tight_layout()%0A%20%20%20%20%20%20%20%20%20%20%20%20plt.show()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20axs%0A%0A%20%20%20%20%20%20%20%20def%20margins(self%2C%20x%2C%20margin%3D0.01%2C%20minmargin%3DTrue)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22Calculate%20plot%20limits%20with%20extra%20margins.%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20rang%20%3D%20np.nanmax(x)%20-%20np.nanmin(x)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20rang%20%3C%200.001%20and%20minmargin%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rang%20%3D%200.001%20*%20np.nanmean(x)%20%2F%20margin%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20rang%20%3C%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rang%20%3D%201%0A%20%20%20%20%20%20%20%20%20%20%20%20lim%20%3D%20%5Bnp.nanmin(x)%20-%20rang%20*%20margin%2C%20np.nanmax(x)%20%2B%20rang%20*%20margin%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20lim%0A%0A%20%20%20%20return%20(Thelen2003%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%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(r%22%22%22%0A%20%20%20%20%23%23%20Checkpoint%20questions%0A%0A%20%20%20%20Pause%20here%20and%20answer%20these%20before%20moving%20on.%20They%20tie%20together%20the%20pieces%20you%20have%20simulated.%0A%0A%20%20%20%201.%20In%20a%20fixed-length%20(isometric)%20muscle%E2%80%93tendon%20unit%2C%20why%20can%20the%20muscle%20fiber%20length%20still%20change%20after%20activation%20changes%3F%0A%20%20%20%202.%20Which%20two%20force%E2%80%93length%20curves%20add%20together%20to%20give%20the%20total%20muscle%20force%2C%20and%20which%20one%20dominates%20at%20long%20fiber%20lengths%3F%0A%20%20%20%203.%20Why%20does%20the%20tendon%20force%20equal%20%24F_M%5Ccos%5Calpha%24%20rather%20than%20%24F_M%24%3F%0A%20%20%20%204.%20Activation%20lags%20behind%20excitation.%20Which%20state%20variable%20stores%20this%20%22memory%22%2C%20and%20which%20two%20parameters%20set%20how%20fast%20it%20rises%20and%20falls%3F%0A%20%20%20%205.%20The%20solver%20clamps%20the%20fiber%20length%20at%20%240.1%5C%2CL_%7BM%2Copt%7D%24%20and%20the%20pennation%20angle%20below%20%24%5Csim%2084%5Eo%24.%20What%20numerical%20problem%20is%20each%20clamp%20preventing%3F%0A%20%20%20%206.%20When%20would%20a%20coarse%20forward-Euler%20solution%20be%20good%20enough%20for%20teaching%2C%20and%20when%20would%20you%20switch%20to%20an%20adaptive%20solver%20such%20as%20%60solve_ivp%60%3F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%2F%2F%2F%20details%20%7C%20Checkpoint%20answers%0A%0A%20%20%20%201.%20Tendon%20stretch%20and%20changing%20pennation%20allow%20fiber%20shortening%20at%20fixed%20total%20length.%202.%20Active%20and%20passive%20fiber%20curves%20add%3B%20the%20passive%20curve%20dominates%20sufficiently%20long%20lengths.%203.%20Only%20the%20fiber-force%20component%20along%20the%20tendon%20is%20transmitted%20in%20this%20geometry.%204.%20Activation%20a%20stores%20the%20history%3B%20%60t_act%60%20and%20%60t_deact%60%20set%20its%20rise%2Fdecay%20rates.%205.%20The%20length%20floor%20avoids%20extreme%2Fundefined%20force%E2%80%93velocity%20calculations%3B%20the%20angle%20limit%20avoids%20division%20by%20nearly%20zero%20cosine.%20These%20safeguards%20do%20not%20validate%20impossible%20geometry.%206.%20Euler%20is%20useful%20for%20a%20converged%20short%20teaching%20demonstration%3B%20use%20an%20adaptive%20solver%20for%20fast%20transients%2C%20tighter%20accuracy%20or%20sensitive%20comparisons.%0A%20%20%20%20%2F%2F%2F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Problems%0A%0A%20%20%20%20Use%20these%20as%20independent%20investigations.%20State%20the%20parameter%20choices%20and%20numerical%20tolerances%20with%20each%20result.%0A%0A%20%20%20%201.%20**Activation%20level.**%20Run%20the%20activation%20dynamics%20with%20a%20constant%20excitation%20of%20%24u%3D1%24%2C%20%24u%3D0.5%24%2C%20and%20%24u%3D0.1%24.%20How%20does%20the%20steady-state%20muscle%20force%20scale%20with%20activation%3F%20Is%20it%20linear%3F%0A%20%20%20%202.%20**Tendon%20compliance.**%20Change%20the%20tendon%20slack%20length%20%60ltslack%60%20and%2For%20%60epst0%60%20to%20make%20the%20tendon%20stiffer%2C%20then%20softer.%20In%20the%20isometric%20contraction%2C%20how%20does%20tendon%20compliance%20change%20how%20much%20the%20muscle%20fiber%20shortens%3F%0A%20%20%20%203.%20**Optimal%20length.**%20Set%20the%20initial%20fiber%20length%20%60lm0%60%20below%2C%20at%2C%20and%20above%20the%20optimal%20length%20%60lmopt%60.%20Predict%20from%20the%20force%E2%80%93length%20curve%20where%20the%20active%20force%20is%20largest%2C%20then%20confirm%20with%20%60muscle_plot%60.%0A%20%20%20%204.%20**Pennation%20sweep.**%20Sweep%20%60alpha0%60%20over%20%240%5Eo%24%2C%20%2415%5Eo%24%2C%20%2430%5Eo%24%2C%20and%20%2445%5Eo%24%20(remember%20to%20adjust%20%60lmt0%60%20as%20done%20above).%20Report%20the%20tendon%20force%20at%20each%20and%20explain%20the%20trend%20using%20%24F_T%20%3D%20F_M%5Ccos%5Calpha%24.%0A%20%20%20%205.%20**Step%20size.**%20Re-run%20a%20simulation%20with%20%60ms.lm_sol(dt%3D0.01)%60%20and%20%60ms.lm_sol(dt%3D0.0001)%60.%20Where%20do%20the%20two%20solutions%20differ%2C%20and%20where%20do%20they%20agree%3F%20What%20does%20this%20tell%20you%20about%20choosing%20a%20step%20size%3F%0A%20%20%20%206.%20**Force%E2%80%93velocity.**%20During%20the%20prescribed%20shortening%20ramp%2C%20read%20the%20muscle%20force%20while%20the%20fiber%20is%20shortening%20and%20compare%20it%20with%20the%20isometric%20force%20at%20the%20same%20length.%20Does%20shortening%20raise%20or%20lower%20the%20active%20force%2C%20and%20why%3F%0A%20%20%20%207.%20**Your%20own%20contraction.**%20Design%20an%20excitation%20signal%20for%20a%20movement%20you%20care%20about%20(a%20quick%20tap%2C%20a%20sustained%20hold%2C%20a%20ramp).%20Predict%20the%20force%2C%20then%20simulate%20it%20by%20replacing%20%60ms.excitation%60.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%2F%2F%2F%20details%20%7C%20Final%20answers%20to%20original%20Problems%0A%0A%20%20%20%201.%20Steady%20activation%20tends%20to%20the%20excitation%20level.%20Active%20force%20is%20linear%20in%20activation%20only%20at%20fixed%20normalized%20fiber%20length%20and%20velocity%3B%20the%20compliant%20equilibrium%20can%20make%20the%20total%20isometric%20response%20nonlinear.%0A%0A%20%20%20%202.%20Lower%20tendon%20strain%20parameter%20%60epst0%60%20makes%20its%20force%E2%80%93strain%20curve%20stiffer%3B%20the%20fiber%20then%20shortens%20less%20while%20the%20tendon%20stretches.%20Slack%20length%20primarily%20changes%20geometry%20and%20operating%20point%20and%20should%20not%20be%20treated%20as%20a%20pure%20stiffness%20parameter.%0A%0A%20%20%20%203.%20The%20active%20force%E2%80%93length%20multiplier%20peaks%20at%20%60lmopt%60%3B%20passive%20force%20can%20make%20total%20force%20largest%20at%20longer%20lengths.%0A%0A%20%20%20%204.%20At%20fixed%20fiber%20force%20and%20fixed%20current%20pennation%2C%20tendon%2Ffiber%20force%20ratios%20are%201%2C%200.9659%2C%200.8660%20and%200.7071%20at%200%C2%B0%2C%2015%C2%B0%2C%2030%C2%B0%20and%2045%C2%B0.%20A%20full%20equilibrium%20sweep%20also%20changes%20fiber%20length%20and%20therefore%20need%20not%20scale%20by%20these%20factors%20alone.%0A%0A%20%20%20%205.%20The%200.0001%20s%20solution%20should%20resolve%20rapid%20activation%20and%20tendon%20transients%20better.%20Quantitative%20differences%20depend%20on%20the%20selected%20parameters%3B%20convergence%20of%20force%20and%20fiber-length%20histories%20is%20the%20acceptance%20criterion.%0A%0A%20%20%20%206.%20Shortening%20lowers%20active%20force%20relative%20to%20isometric%20force%20at%20the%20same%20length%20and%20activation%20in%20this%20model.%0A%0A%20%20%20%207.%20No%20unique%20trace%20is%20expected.%20A%20brief%20excitation%20pulse%20produces%20delayed%20activation%20and%20force%2C%20followed%20by%20decay%3B%20a%20sustained%20input%20approaches%20the%20coupled%20equilibrium%20for%20the%20imposed%20length.%0A%20%20%20%20%2F%2F%2F%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20Go%20deeper%0A%0A%20%20%20%20-%20%5BMuscle%20modeling%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fmuscle_modeling.py)%20%E2%80%94%20the%20companion%20notebook%20that%20derives%20the%20force%E2%80%93length%2C%20force%E2%80%93velocity%2C%20and%20activation%20functions%20used%20here.%0A%20%20%20%20-%20%5BIntroduction%20to%20numerical%20solution%20of%20Ordinary%20Differential%20Equations%5D(https%3A%2F%2Fmolab.marimo.io%2Fgithub%2FBMClab%2FBMC%2Fblob%2Fmaster%2Fnotebooks%2Fordinary_differential_equation.py)%20%E2%80%94%20the%20forward%20Euler%20method%20and%20alternatives%20such%20as%20%60solve_ivp%60.%0A%20%20%20%20-%20%5BOpenSim%20Millard%202012%20Muscle%20Models%5D(http%3A%2F%2Fsimtk-confluence.stanford.edu%3A8080%2Fdisplay%2FOpenSim%2FMillard%2B2012%2BMuscle%2BModels)%20%E2%80%94%20how%20modern%20implementations%20remove%20the%20numerical%20singularities%20discussed%20above.%0A%20%20%20%20-%20%5BThelen%20(2003)%5D(http%3A%2F%2Fhomepages.cae.wisc.edu%2F~thelen%2Fpubs%2Fjbme03.pdf)%20%E2%80%94%20the%20muscle%20model%20formulation%20simulated%20in%20this%20notebook.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%23%20Video%20lectures%20on%20the%20Internet%0A%0A%20%20%20%20%5BMIT%20OpenCourseWare%5D(https%3A%2F%2Focw.mit.edu%2Fcourses%2F2-003sc-engineering-dynamics-fall-2011%2F)%20%E2%80%94%20Mechanical%20vibration%20lectures%3A%20review%20spring%2C%20damping%20and%20coupled-system%20responses%20before%20interpreting%20passive%20muscle-model%20elements.%0A%20%20%20%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(r%22%22%22%0A%20%20%20%20%23%23%20References%0A%0A%20%20%20%20-%20Kawakami%20Y%2C%20Ichinose%20Y%2C%20Fukunaga%20T%20(1998)%20%5BArchitectural%20and%20functional%20features%20of%20human%20triceps%20surae%20muscles%20during%20contraction%5D(https%3A%2F%2Fpubmed.ncbi.nlm.nih.gov%2F9688711).%20Journal%20of%20Applied%20Physiology%2C%2085%2C%20398%E2%80%93404.%0A%0A%20%20%20%20-%20McLean%20SG%2C%20Su%20A%2C%20van%20den%20Bogert%20AJ%20(2003)%20%5BDevelopment%20and%20validation%20of%20a%203-D%20model%20to%20predict%20knee%20joint%20loading%20during%20dynamic%20movement%5D(https%3A%2F%2Fpubmed.ncbi.nlm.nih.gov%2F14986412).%20Journal%20of%20Biomechanical%20Engineering%2C%20125%2C%20864-74.%0A%0A%20%20%20%20-%20Nigg%20BM%20and%20Herzog%20W%20(2006)%20%5BBiomechanics%20of%20the%20Musculo-skeletal%20System%5D(https%3A%2F%2Fbooks.google.com.br%2Fbooks%3Fid%3DhOIeAQAAIAAJ%26dq%3Deditions%3AISBN0470017678).%203rd%20Edition.%20Wiley.%0A%0A%20%20%20%20-%20Scott%20SH%2C%20Winter%20DA%20(1991)%20%5BA%20comparison%20of%20three%20muscle%20pennation%20assumptions%20and%20their%20effect%20on%20isometric%20and%20isotonic%20force%5D(https%3A%2F%2Fpubmed.ncbi.nlm.nih.gov%2F2037616).%20Journal%20of%20Biomechanics%2C%2024%2C%20163%E2%80%93167.%0A%0A%20%20%20%20-%20Thelen%20DG%20(2003)%20%5BAdjustment%20of%20muscle%20mechanics%20model%20parameters%20to%20simulate%20dynamic%20contractions%20in%20older%20adults%5D(http%3A%2F%2Fhomepages.cae.wisc.edu%2F~thelen%2Fpubs%2Fjbme03.pdf).%20Journal%20of%20Biomechanical%20Engineering%2C%20125(1)%3A70%E2%80%9377.%0A%20%20%20%20%22%22%22)%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
92290337bfd3b3b480ea20b93ec792b8