Reference
Constants
Muscade.noFB — Constant
noFBA constant, used by elements' residual or lagrangian as their 3rd output if they do provide any feedback to the solver (for example, on the reduction of the barrier parameter in interior point method).
Example: return L,noFB
See also: noFB
Types
Muscade.AbstractElement — Type
AbstractElementAn abstract data type. An element type MyElement must be declared as a subtype of AbstractElement.
MyELementmust provide a constructor with interface
`eleobj = MyElement(nod::Vector{Node}; kwargs...)`See also: coord, Node, lagrangian
Muscade.Acost — Type
Acost{Na,ainod,afield,Tcost,Tcostargs} <: AbstractElementAn element to apply a once-off cost on a combination of A-dofs. For costs per unit of time on A-dofs (not recommended), see DofCost.
Named arguments to the constructor
inod::NTuple{Na,𝕫}=()For each A-dof to entercost, its element-node number.field::NTuple{Na,Symbol}=()For each A-dof to entercost, its field.cost::Functorcost(A,costargs...)→ℝcostargs::NTuple=()orNamedTupleof additional arguments passed tocost`
Requestable internal variables
cost, the value of the cost.
Example
@functor with() acost(A;A0)=(A[1]-A0)^2
ele1 = addelement!(model,Acost,[nod1],inod=(1,),field=(:EI,),
cost=acost,costargs=(;A0=0.27)See also: SingleAcost, DofCost, SingleDofCost, ElementCost, addelement!
Muscade.DirectXUA — Type
DirectXUA{OX,OU,IA}A non-linear direct solver for optimisation FEM.
An analysis is carried out by a call with the following syntax:
initialstate = initialize!(model)The solver does not yet support interior point methods.
Parameters
OX0 for static analysis 1 for first order problems in time (viscosity, friction, measurement of velocity) 2 for second order problems in time (inertia, measurement of acceleration)OU0 for white noise prior to the unknown load process 2 otherwiseIA0 for XU problems (variables of class A will be unchanged) 1 for XUA problems
Named arguments
dbg=(;)a named tuple to trace the call tree (for debugging).verbose=trueset to false to suppress printed output (for testing).silenterror=falseset to true to suppress print out of error (for testing) .initialstateanAbstractVectorofState: one initial state for each experimenttimeanAbstractVector(of same length asinitialstate) ofAbstractRangeof times at which to compute the steps. Example: 0:0.1:5.maxiter=50maximum number of Newton-Raphson iterations.maxΔλ=1e-5convergence criteria: a norm of the scaledΛincrement.maxΔx=1e-5convergence criteria: a norm of the scaledXincrement.maxΔu=1e-5convergence criteria: a norm of the scaledUincrement.maxΔa=1e-5convergence criteria: a norm of the scaledAincrement.saveiter=falseset to true so that the outputstatecontains the states at each Newton-Raphson iteration (for debugging non-convergence).
Setting the following flags to true will improve the sparsity of the system. But setting a flag to true when the condition isn't met causes the Hessian to be wrong, which is detrimental for convergence.
Xwhite=falsetrueif response measurement error is a white noise process.XUindep=falsetrueif response measurement error is independant ofUUAindep=falsetrueifUis independant ofAXAindep=falsetrueif response measurement error is independant ofA
Output
state, wherestate[iexp][itime]contains the state of the optimized model at each of these steps, or ifsaveiter=truethenstate[iiter][iexp][itime]is a state.
See also: solve, initialize!, SweepX, FreqXU
Muscade.DofConstraint — Type
DofConstraint{λclass,Nx,Nu,Na,xinod,xfield,uinod,ufield,ainod,
afield,λinod,λfield,Tg,Tmode} <: AbstractElementAn element to apply physical/optimisation equality/inequality constraints on dofs.
The constraints are holonomic, i.e. they apply to the values, not the time derivatives, of the involved dofs. This element is very general but not very user-friendly to construct, factory functions are provided for better useability. The sign convention is that the gap g≥0 and the Lagrange multiplier λ≥0.
This element can generate three classes of constraints, depending on the input argument λclass.
λclass=:XPhysical constraint. In mechanics, the Lagrange multiplier dof is a generalized force, dual of the gap. The gapFunctormust be of the formgap(x,t,gargs...).λclass=:UTime varying optimisation constraint. For example: findA-parameters so that at all times, the response does not exceed a given criteria. The gapFunctormust be of the formgap(x,u,a,t,gargs...).λclass=:ATime invariant optimisation constraint. For example: findA-parameters such thatA[1]+A[2]=gargs.somevalue. The gapFunctormust be of the formgap(a,gargs...).
Named arguments to the constructor
xinod::NTuple{Nx,𝕫}=()For each X-dof to be constrained, its element-node number.xfield::NTuple{Nx,Symbol}=()For each X-dof to be constrained, its field.uinod::NTuple{Nu,𝕫}=()For each U-dof to be constrained, its element-node number.ufield::NTuple{Nu,Symbol}=()For each U-dof to be constrained, its field.ainod::NTuple{Na,𝕫}=()For each A-dof to be constrained, its element-node number.afield::NTuple{Na,Symbol}=()For each A-dof to be constrained, its field.λinod::𝕫The element-node number of the Lagrange multiplier.λclass::SymbolThe class (:X,:Uor:A) of the Lagrange multiplier. See the explanation above for classes of constraintsλfield::SymbolThe field of the Lagrange multiplier.gap::FunctorThe gap function.gargs::NTupleAdditional inputs to the gap function.mode::Functorwheremode(t::ℝ) -> Symbol, with value:equal,:positiveor:offat any time. An:offconstraint will set the Lagrange multiplier to zero.
Example
using Muscade
model = Model(:TestModel)
n1 = addnode!(model,𝕣[0])
@functor with() gap(x,t)=x[1]+.1
@functor with() res(x,u,a,t)=0.4x.+.08+.5x.^2)
e1 = addelement!(model,DofConstraint,[n1],xinod=(1,),xfield=(:t1,),
λinod=1, λclass=:X, λfield=:λ1,gap=gap,
mode=positive)
e2 = addelement!(model,QuickFix ,[n1],inod=(1,),field=(:t1,),
res=res
initialstate = initialize!(model)
setdof!(initialstate,1.;field=:λ1)
state = solve(SweepX{0};initialstate,time=[0.],verbose=false)
X = state[1].X[1]See also: Hold, ElementConstraint, off, equal, positive
Muscade.DofCost — Type
DofCost{Class,Nx,Nu,Na,xinod,xfield,uinod,ufield,ainod,
afield,Tcost,Tcostargs} <: AbstractElementAn element to apply costs on combinations of dofs. The cost is "per unit of time". For once-off costs on A-dofs, see Acost.
Named arguments to the constructor
xinod::NTuple{Nx,𝕫}=()For each X-dof to entercost, its element-node number.xfield::NTuple{Nx,Symbol}=()For each X-dof to entercost, its field.uinod::NTuple{Nu,𝕫}=()For each U-dof to entercost, its element-node number.ufield::NTuple{Nu,Symbol}=()For each U-dof to entercost, its field.ainod::NTuple{Na,𝕫}=()For each A-dof to entercost, its element-node number.afield::NTuple{Na,Symbol}=()For each A-dof to entercost, its field.cost::Functorcost(X,U,A,t,costargs...)→ℝXandUare tuples (derivates of dofs...), and∂0(X),∂1(X),∂2(X)must be used bycostto access the value and derivatives ofX(resp.U)costargs::NTuple=()orNamedTupleof additional arguments passed tocost`
Requestable internal variables
cost, the value of the cost.
Example
@functor with() xcost(X,U,A,t;X0) = (X[1]-X0)^2
ele1 = addelement!(model,DofCost,[nod1],xinod=(1,),xfield=(:tx1,),
cost=xcost,costargs=(;X0=0.27)See also: Acost, SingleDofCost, ElementCost, addelement!
Muscade.DofLoad — Type
DofLoad{Tvalue,Field} <: AbstractElementAn element to apply a loading term to a single X-dof.
Named arguments to the constructor
field::Symbol.value::Functor, wherevalue(t::ℝ) → ℝ.
Requestable internal variables
F, the value of the load.
Examples
using Muscade
model = Model(:TestModel)
node = addnode!(model,𝕣[0,0])
@functor with(a=3,b=-1) load(t)=a*t+b
e = addelement!(model,DofLoad,[node];field=:tx,value=load)Muscade.EigX — Type
eiginc = solve(EigX{ℝ};state=initialstate,nmod)
eiginc = solve(EigX{ℂ};state=initialstate,nmod)Given an initial (typicaly static) state initialstate, computes the lowest nmod eigenmodes of a system. EigX{ℝ} computes real eigenmodes not accounting for damping. EigX{ℝ} computes complex eigenmodes accounting for damping. The data structure eiginc can be passed to increment to obtain dynamic states superimposing mode shapes.
Input
initialstate- aStatenmod=5- the number of eigenmodes to identifydroptol=1e-9- in the stiffness and mass matrix, the magnitude of a term relative to the largest term in the matrix under which the term is set to zero.- Further named arguments: see the optional keyword arguments to
geneig.
Output
- an object of type
EigXℝincrementorEigXℂincrement, for use withincrementto create a snapshot of the oscillating system.
See also: solve, initialize!, increment, geneig
Muscade.EigXU — Type
EigXU{OX,OU}Study the combinations of load and response that are least detected by sensor systems.
An analysis is carried out by a call with the following syntax:
initialstate = initialize!(model)
eiginc = solve(EigXU{OX,OU};Δω, p, nmod,initialstate)The solver linearises the problem (computes the Hessian of the Lagrangian) at initialstate and solves the ΛXU-eigenvalue problem at frequencies ωᵢ = Δω*i with i∈{0,...,2ᵖ-1}.
Parameters
OX0 for static analysis 1 for first OX problems in time (viscosity, friction, measurement of velocity) 2 for second OX problems in time (inertia, measurement of acceleration)OU0 for white noise prior to the unknown load process 2 otherwise
Named arguments
dbg=(;)a named tuple to trace the call tree (for debugging).verbose=trueset to false to suppress printed output (for testing).initialstateaState.nmodthe number of eigen-modes to identusyΔωfrequency stepp2^psteps will be analysed.droptol=1e-10set to zero terms in the incremental matrices that are smaller thandroptolin absolute value.
Output
- an object of type
EigXUincrementfor use withincrementto create a snapshot of the oscillating system.
See also: increment,EigXU, solve, initialize!, study_singular, SweepX, DirectXUA
Muscade.ElementConstraint — Type
ElementConstraint{Teleobj,λinod,λfield,Nu,Treq,Tg,Tgargs,Tmode} <: AbstractElementAn element to apply optimisation equality/inequality constraints on the element-results of another "target" element. The target element must not be added separately to the model. Instead, the ElementType, and the named arguments to the target element are provided as input to the ElementConstraint constructor.
This element generates a time varying optimisation constraint. For example: find A-parameters so that at all times, the element-result von-Mises stress does not exceed a given value.
The Lagrangian multiplier introduced by this optimisation constraint is of class :U.
Named arguments to the constructor
λinod::𝕫The element-node number of the Lagrange multiplier.λfield::SymbolThe field of the Lagrange multiplier.reqA request for element-results to be extracted from the target element, see@request. The request is formulated as if adressed directly to the target element.gₛ::𝕣=1.A scale for the gap.λₛ::𝕣=1.A scale for the Lagrange multiplier.gapA gap functiongap(eleres,t,gargs...)→ℝ.eleresis the output of the above-mentionned request to the target element.gargs::NTupleAdditional inputs to the gap function.mode::Functorwheremode(t::ℝ) -> Symbol, with value:equal,:positiveor:offat any time. An:offconstraint will set the Lagrange multiplier to zero.ElementTypeThe named of the constructor for the relevant elementelementkwargsA named tuple containing the named arguments of theElementTypeconstructor.
Requestable internal variables
Not to be confused with the req provided as input to addelement! when adding an ElementConstraint, one can, after the analysis, request results from ElementConstraint
λThe constraints Lagrange multipliergapThe constraints gapFunctoreleres(...)where...is the list of requestables wanted from the target element. The "prefix"eleresis there to prevent possible confusion with variables requestable fromElementConstraint. For example@request gapwould extract the value of theElementConstraint's functiongap, while@request eleres(gap)refers to the value of a variable calledgapin the target element.
Example
@functor with() gap(eleres,t) = eleres.Fh^2
ele1 = addelement!(model,ElementCoonstraint,[nod1];req=@request(Fh),
gap,λinod=1,λfield=:λ,mode=equal,
ElementType=AnchorLine,
elementkwargs=(Δxₘtop=[5.,0,0], xₘbot=[250.,0],L=290., buoyancy=-5e3))See also: Hold, DofConstraint, off, equal, positive, @request, @functor
Muscade.ElementCost — Type
ElementCost{Teleobj,Treq,Tcost,Tcostargs} <: AbstractElementAn element to apply costs on another "target" element's dofs and element-results. The target element must not be added separately to the model. Instead, the ElementType, and the named arguments to the target element are provided as input to the ElementCost constructor.
Named arguments to the constructor
reqA request for element-results to be extracted from the target element, see@request. The request is formulated as if adressed directly to the target element.costA costFunctorcost(eleres,t,costargs...)→ℝ.eleresis the output of the above-mentionned request to the target element.costargs::NTuple=()orNamedTupleof additional arguments passed tocost.ElementTypeThe named of the constructor for the relevant element.elementkwargsA named tuple containing the named arguments of theElementTypeconstructor.
Example
@functor with() cost(eleres,X,U,A,t;Fh0) = (eleres.Fh-Fh0)^2
ele1 = addelement!(model,ElementCost,[nod1];req=@request(Fh),
cost=cost,
costargs = (;Fh0=0.27),
ElementType=AnchorLine,
elementkwargs=(Λₘtop=[5.,0,0], xₘbot=[250.,0], L=290., buoyancy=-5e3))See also: SingleDofCost, DofCost, @request, @functor
Muscade.FreqXU — Type
FreqXU{OX,OU}A linear frequency domain solver for optimisation FEM.
An analysis is carried out by a call with the following syntax:
initialstate = initialize!(model)
stateXU = solve(FreqXU{OX,OU};Δt, p, t₀,tᵣ,initialstate)The solver linearises the problem (computes the Hessian of the Lagrangian) at initialstate with time tᵣ, and solves it at times t=range(start=t₀,step=Δt,length=2^p). The return
Parameters
OX0 for static analysis 1 for first order problems in time (viscosity, friction, measurement of velocity) 2 for second order problems in time (inertia, measurement of acceleration)OU0 for white noise prior to the unknown load process 2 otherwise
Named arguments
dbg=(;)a named tuple to trace the call tree (for debugging).verbose=trueset to false to suppress printed output (for testing).silenterror=falseset to true to suppress print out of error (for testing) .initialstateaState.t₀=0.time of first step.Δttime step.p2^psteps will be analysed.tᵣ=t₀reference time for linearisation.droptol=1e-10set to zero terms in the incremental matrices that are smaller thandroptolin absolute value.
Output
A vector of length 2^p containing the state of the model at each of these steps.
See also: solve, initialize!, study_singular, SweepX, DirectXUA
Muscade.FunctionFromVector — Type
f = FunctionFromVector(xs::AbstractRange,ys::AbstractVector)
y = f(x)
Linear interpolation. Fails if `x` is outside the range `xs`Muscade.Hold — Type
Hold <: AbstractElementAn element to set a single X-dof to zero.
Named arguments to the constructor
field::Symbol. The field of the X-dof to constraint.λfield::Symbol=Symbol(:λ,field). The field of the Lagrange multiplier.
Example
using Muscade
model = Model(:TestModel)
node = addnode!(model,𝕣[0,0])
e = addelement!(model,Hold,[node];field=:tx)See also: DofConstraint, DofLoad, DofCost
Muscade.IdVec — Type
An "identity vector"
id = IdVec i = 9834987 id[i] == i # true for any i
See also Julia's identity function.
Muscade.Model — Type
model = Model([ID=:my_model])Construct a blank model, which will be mutated to create a finite element [optimization] problem.
See also: addnode!, addelement!, describe, solve
Muscade.Monitor — Type
Muscade.Monitor <: AbstractElementAn element for for monitoring inputs to and outputs from another element, during an analysis.
Instead of adding the element to be monitored directly into the model, add this element with the element to be monitored as argument.
Inputs and outputs are @show'n.
Named arguments to the constructor
ElementTypeThe the type of element to be monitored-triggerA function that takesdbgas an input and returns a boolean (true) to printout.elementkwargsaNamedTuplecontaining the named arguments of theElementTypeconstructor.
Muscade.Node — Type
NodeThe eltype of vectors handed by Muscade as first argument to element constructors.
Example: function SingleDofCost(nod::Vector{Node};class::Symbol, ... )
See also: coord
Muscade.OffsetVector — Type
A simple offset vector that only implements "setindex!" and "getindex". Based on Memory, so cannot be extended.
Muscade.QuickFix — Type
QuickFix <: AbstractElementAn element for creating simple elements with "one line" of code. Elements thus created have several limitations:
- physical elements with only X-dofs.
- only
Rcan be espied.
The element is intended for testing. Muscade-based applications should not include this in their API.
Named arguments to the constructor
inod::NTuple{Nx,𝕫}. The element-node numbers of the X-dofs.field::NTuple{Nx,Symbol}. The fields of the X-dofs.res::Functor, whereres(X::ℝ1,X′::ℝ1,X″::ℝ1,t::ℝ) → ℝ1, the residual.
Examples
A one-dimensional linear elastic spring with stiffness 2.
using Muscade
model = Model(:TestModel)
node1 = addnode!(model,𝕣[0])
node2 = addnode!(model,𝕣[1])
@functor with() res(x,u,a,t)=0.4x.+.08+.5x.^2)
e = addelement!(model,QuickFix,[node1,node2];inod=(1,2),field=(:tx1,:tx1),res=res)Muscade.SingleAcost — Type
SingleAcost <: AbstractElementAn element with a single node, for adding a once-off cost to a single A-dof.
Named arguments to the constructor
field::Symbol.cost::Functor, wherecost(a::ℝ,[,costargs...]) → ℝ
costargs::NTuple=()orNamedTupleof additional arguments passed tocost
Requestable internal variables
cost, the value of the cost.
Example
using Muscade
model = Model(:TestModel)
node = addnode!(model,𝕣[0,0])
@functor with() acost(a,three)=(a/three)^2
e = addelement!(model,SingleAcost,[node];field=:EI,
costargs=(3.,),cost=acost)See also: DofCost, SingleDofCost, Acost, ElementCost
Muscade.SingleDofCost — Type
SingleDofCost{Derivative,Class,Field,Tcost} <: AbstractElementAn element with a single node, for adding a cost to a given dof.
Named arguments to the constructor
class::Symbol, either:Xor:U.field::Symbol.cost::Functor, wherecost(x::ℝ,t::ℝ[,costargs...]) → ℝifclassis:Xor:U, andcost(x::ℝ, [,costargs...]) → ℝifclassis:A.
[costargs::NTuple=() or NamedTuple] of additional arguments passed tocost``derivative::Int=00, 1 or 2 - which time derivative of the dof enters the cost.
Requestable internal variables
cost, the value of the cost.
Example
using Muscade
model = Model(:TestModel)
node = addnode!(model,𝕣[0,0])
@functor with() xcost(x,t,three)=(x/three)^2
e = addelement!(model,SingleDofCost,[node];class=:X,field=:tx,
costargs=(3.,),cost=xcost)See also: DofCost, ElementCost
Muscade.SingleUdof — Type
SingleUdof{XField,Ufield,Tcost} <: AbstractElementAn element that creates a Udof, and associates a cost to its value. The value of the Udof is applied as a load to a Xdof on the same node.
Named arguments to the constructor
Xfield::Symbol.Ufield::Symbol.cost::Functor, wherecost(u::ℝ,t::ℝ[,costargs...]) → ℝ[costargs::NTuple=() or NamedTuple] of additional arguments passed tocost``
Requestable internal variables
cost, the value of the cost.
Example
using Muscade
model = Model(:TestModel)
node = addnode!(model,𝕣[0,0])
@functor with() ucost(u,t,three)->(u/three)^2
e = addelement!(model,SingleUdof,[node];Xfield=:tx,Ufield=:utx,
costargs=(3.,),cost=ucost)See also: DofCost, ElementCost
Muscade.SpyAxis — Type
axis = Muscade.SpyAxis()Spoof a GLMakie.jl Axis/Axis3 object so that calls like
lines!( axis,args...;kwargs...)result in args and kwargs being stored in axis, allowing to test functions that generate plots. Results are accessed by for example
axis.call[3].fun
axis.call[3].args[2]To get the name of the 3rd GLMakie.jl function that was called, and the 2nd input argument of this call.
Only lines!, scatter! and mesh! logging functions are implemented for now, but more functions can easily be added.
Muscade.SweepX — Type
SweepX{OX}A non-linear, time domain solver, that solves the problem time-step by time-step. Only the X-dofs of the model are solved for, while U-dofs and A-dofs are unchanged.
SweepX{0}is Newton-Raphson.SweepX{1}is a first order variant of Newmark-β with Newton-Raphson iterations.SweepX{2}is Newmark-β, with Newton-Raphson iterations.
IMPORTANT NOTE: Muscade does not allow elements to have state variables, for example, plastic strain, or shear-free position for dry friction. Where the element implements such physics, this is implemented by introducing the state as a degree of freedom of the element, and solving for its evolution, even in a quasi-static problem, requires the use of OX≥1.
An analysis is carried out by a call with the following syntax:
initialstate = initialize!(model)
setdof!(initialstate,1.;class=:U,field=:λcsr)
states = solve(SweepX{2};initialstate=initialstate,time=0:10)Named arguments to solve:
dbg=(;)a named tuple to trace the call tree (for debugging)verbose=trueset to false to suppress printed output (for testing)silenterror=falseset to true to suppress print out of error (for testing)initialstateaState, obtain fromìnitialize!orSweepX.timemaximum number of Newton-Raphson iterationsβ=1/4,γ=1/2parameters to the Newmark-β algorithm.βis dummy ifOX<2.γis dummy ifOX<1.maxiter=50maximum number of equilibrium iterations at each step.maxΔx=1e-5convergence criteria: norm ofX.maxLλ=∞convergence criteria: norm of the residual.saveiter=falseset to true so that outputstatescontains the state at the iteration of the last step analysed. Useful to study a step that fails to converge.
Output
A vector of length equal to that of the named input argument time containing the states at the time steps.
See also: solve, initialize!, findlastassigned, study_singular, DirectXUA, FreqXU
Muscade.SweepXA — Type
SweepXA{OX}A non-linear, time domain solver, that solves the problem time-step by time-step. Only the X-dofs of the model are solved for, while U-dofs and A-dofs are unchangeδ
SweepXA{0}is Newton-Raphson, with feasibility line-search, to handle inequality constraints.SweepXA{1}is implicit Euler, with feasibility line-search.SweepXA{2}is Newmark-β, with Newton-Raphson iterations and feasibility line search
IMPORTANT NOTE: Muscade does not allow elements to have state variables, for example, plastic strain, or shear-free position for dry friction. Where the element implements such physics, this is implemented by introducing the state as a degree of freedom of the element, and solving for its evolution, even in a quasi-static problem, requires the use of ORDER≥1.
An analysis is carried out by a call with the following syntax:
initialstate = initialize!(model)
setdof!(initialstate,1.;class=:U,field=:λcsr)
states = solve(SweepXA{2};initialstate=initialstate,time=0:10)Named arguments to solve:
dbg=(;)a named tuple to trace the call tree (for debugging)verbose=trueset to false to suppress printed output (for testing)silenterror=falseset to true to suppress print out of error (for testing)initialstateaState, obtain fromìnitialize!orSweepXA.timemaximum number of Newton-Raphson iterationsβ=1/4,γ=1/2parameters to the Newmark-β algorithm. Dummy ifOX<2maxXiter=50maximum number of equilibrium iterations at each step.maxΔx=1e-5convergence criteria: norm ofX.maxLλ=∞convergence criteria: norm of the residual.maxLineIter=50Maximum number of iteration in the feasibility line search. set to 0 to skip the line search (not recommended for models with inequality constraints).sfac=0.5Parameter in the line search for a feasible point. If a tentative result is not feasible, backtrack by a factorsfac. If still not feasible, backtrack what is left by a factorsfac, and so forth, up tomaxLineItertimes.γfac=0.5Parameter for feasibility. For an inequality constraintg(X)with reaction forceλ, requireg(X)*λ==γ, and multiplyγ *= γfacat each iteration.
Output
A vector of length equal to that of the named input argument time containing the states at the time steps.
See also: solve, initialize!, findlastassigned, study_singular, DirectXUA, FreqXU
Muscade.addin! — Method
addin!(asm,global,block,ibr,ibc,factor=1.)Add a sparse block into a large out sparse matrix, at block-row and -column ibr and ibc. Use prepare to allocate memory for global and build the assembler asm.
Muscade.addin! — Method
addin!(asm,outvec,blockvec,ibr)Add a full block vector into a large outvec full vector. at block-row ibr. Use prepare to create asm.
See also: prepare
Muscade.composeJacobian — Type
composeJacobian{P}(Ty,X_)Given Ty obtained using revariate, and X_, obtained using motion{P}(X) where X is a tuple of SVectors and P=constants(X), compute y, a tuple of length ND of AbstractArrays of same eltype as vectors in X, andy∂X₀, the Jacobian of∂0(y)with respect to∂0(X)`.
See also revariate, motion, motion⁻¹, composevalue
Muscade.composevalue — Type
composevalue{P,ND}(Ty,X_)Given Ty obtained using revariate, and X_, obtained using motion{P}(X) where X is a tuple of length ND and P=constants(X), compute y, a tuple of length ND of AbstractArrays of same eltype as vectors in `X.
See also revariate, motion, motion⁻¹, composeJacobian
Muscade.default — Type
value = default{:fieldname}(namedtuple,defaultvalue)
namedtuple = default(inputnamedtuple,defaultnamedtuple)The first syntax attempts to access field fieldname from namedtuple. If namedtuple does not have such a field - or is not a NamedTuple, return defaultvalue.
The second syntax creates namedtuple from inputnamedtuple, supplementing with fields and values from defaultnamedtuple where there is no corresponding field in inputnamedtuple. This a thin wrapper of Julia's Base.merge.
Muscade.diffed_lagrangian — Type
Muscade.diffed_lagrangian{P}(eleobj;Λ,X,U,A,t=0.,SP=nothing)Compute the Lagrangian, its gradients and Hessian, and the memory of an element. For element debugging and testing.
P, the order of differentiation must be 1 or 2.
The output is a NamedTuple with fields Λ, X, U, A, t, SP echoing the inputs and fields
∇Lof format∇L[iclass][ider]so that for example∇L[2][3]contains the gradient of the Lagrangian wrt to the acceleration.iclassis 1,2,3 and 4 forΛ,X,UandArespectively.- if
P==2:HLof formatHL[iclass,jclass][ider,jder]so that for exampleHL[1,2][1,3]contains the mass matrix. FBas returned bylagrangian
See also: diffed_residual, print_element_array
Muscade.geneig — Type
λ,v,ncv = geneig{ALGO}(A,B,neig=5)Solves (A-λ*B)*v=0, finding the neig lowest eigenvalues λ (in absolute value) and the corresponding eigenvectors v (a Vector{Vector})
Input
ALGO can be
- :SDP if
Ais symmetric definite positive andBis symmetric. Will return realλandv. - :Hermitian if
Ais symmetric indefinite andBis symmetric. Will return realλandv. - :Complex otherwise, will return complex
λandv.
Optional keyword arguments:
maxiter = 300verbosity = 0 ∈ {0,1,2,3}krylovdim = 2neig+6
Uses KrylovKit.jl. Freely based on VibrationGEPHelpers.jl and input from PetrKryslUCSD and stevengj. See GIThub-blame for bug-credits.
Muscade.increment — Type
state = increment{OX}(initialstate,eiginc,imod,A)Starting from initalstate for which an EigX analysis has been carried out, and using the output eiginc of that analysis, construct new States representing the instantaneous state of the vibrating structure
Input
OXthe number of time derivatives to be computed.increment(initialstate,eiginc,imod,A)defaults toOX=2initialstatethe same initialStateprovided toEigXto computeeiginceigincobtained fromEigXimod, anAbstractVectorof integer mode numbersA, anAbstractVectorof same length asimod, containing real or complex amplitudes associated to the modes
Output
statea snapshot of the vibrating system
See also: EigX
Muscade.increment — Method
state = increment{OX}(initialstate,eiginc,iω,imod,A)Starting from initalstate for which an EigX analysis has been carried out, and using the output eiginc of that analysis, construct new States representing the instantaneous state of the vibrating structure
Input
OXthe number of time derivatives to be computed.increment(initialstate,eiginc,imod,A)defaults toOX=2initialstatethe same initialStateprovided toEigXUto computeeiginceigincobtained fromEigXUiω, the number of the frequency to consider.ω=iω*ΔωwhereΔωis an input toEigXU.imod, anAbstractVectorof integer mode numbersA, anAbstractVectorof same length asimod, containing real or complex amplitudes associated to the modes
Output
statea snapshot of the vibrating system
See also: EigXU
Muscade.motion — Method
P = constant(X)
X_ = motion{P}(X)Transform a NTuple of SVectors, for example the vector X provided as an input to residual or Lagrangian into a SVector of ∂ℝ. This can be used by an element to compute time derivatives, for example Euler, Coriolis and centrifugal accelerations, or strain rates.
Some principles of safe automatic differentiation must be adhered to:
- the function that uses
motionmust also 'unpack' : no variable that is touched by the output ofmotionmust be returned by the function without having been unpacked bymotion⁻¹. Touched variables can for example be marked with an underscore. - The precendence
Pmust be calculated usingconstantswith all variables that are input to the function and may be differentiated. - If other levels of automatic differentiation are introduced within the function, unpack in reverse order of packing.
See motion⁻¹
Muscade.motion⁻¹ — Method
P = constants(X,U,A,t)
ND = length(X)
X_ = motion{P,ND}(X)
Y_ = f(Y_)
Y₀ = motion⁻¹{P,ND,0}(Y_)
Y₁ = motion⁻¹{P,ND,1}(Y_)
Y₂ = motion⁻¹{P,ND,2}(Y_)
Y = motion⁻¹{P,ND }(Y)Extract the value and time derivatives from a variable that is a function of the output of motion. In the above Y is a tuple of length ND. One can use ∂0,∂1 and ∂2 to unpack Y.
See also motion
Muscade.revariate — Type
TX = revariate{P}(V)The variable V is a nested structure NamedTuples, Tuples and SArrays of Reals (possibly: ∂ℝs).
V is stripped of its partials, an revariated to order P.
TV = revariate(VX)revariates to the order precedence(V).
revariate, in conjunction with chainrule can be used to improve performance when the length of V is smaller than the length of its partials.
Be extremely careful never to mix any variable that is a function of V with any other variables containing ∂ℝs but not produced by the same revariate.
A special version of revariate
V = (;X,U,A)
S = (X=scale.X,U=scale.U,A=scale.A)
TV = revariate{P}(V,S)allows to introduce scaling in automatic differentiation. For this method, S and V have the same structure, with the important exception that Tuples in V must be ntuples (have elements of identical type T), and, to a Tuple in V corresponds a variable of type T in V. Put simply: the same scale scale.X will be applied to ∂0[X], ∂1[X] and ∂2[X].
See also: chainrule
Muscade.to_order — Type
to_order{P}(V)Decrease (lossy) or increase (pad partials with zeros) the order of differentiation of V. V is a nested structure of NamedTuple, Tuple, SArray, and the components of V must be of type ∂ℝ (otherwise, the number of partials would be undefined).
Muscade.∂ — Method
yₓ = ∂{P,N}(Y)Extract the gradient of an automatic differentiation object. If Y is a SArray, the index of the partial derivative is appended to the indices of Y.
y′ = ∂{P}(Y)Extract the derivative of an automatic differentiation object (or SArray of such), where the variation was created by the syntax variate{P}.
Functions
Muscade.:∘₁ — Method
c = a∘₁bCompute the single-dot product of two arrays, so that cᵢⱼ=Σₖ aᵢₖ bₖⱼ where i and j can be multiple indices.
Muscade.:∘₂ — Method
c = a∘₂bCompute the double-dot product of two arrays, so that cᵢⱼ=Σₖₗ aᵢₖₗ bₖₗⱼ where i and j can be multiple indices.
Muscade.:⊗ — Method
c = a⊗bCompute the exterior product of two arrays, so that cᵢⱼ=aᵢ bⱼ where i and j can be multiple indices.
Muscade.GUI — Method
GUI(eiginc,initialstate;[draw_shadow=true],[shadow=...],[model=...])Taking the output eiginc obtained from an EigXU, and the state initstate provided to EigXU, provide a GUI to explore the results.
Optional keyword arguements are
draw_shadowwhether to superimpose a drawing ofinitstateshadowaNamedTuplewith any arguments to be passed todraw!initstatemodelaNamedTuplewith any arguments to be passed todraw!theEigXUmodes.
See also EigXU
Muscade.GUI — Method
GUI(state,refstate=state[1];dim=3,kwargs...)Taking state, a Vector of States output by various solvers, provide a GUI to explore the results.
This assumes that elements' drawing methods are writen for GLMakie.
The GUI allows to intereactively amplify responses (Λ,X,U and A-dofs) to make then easier to visualise. For X-dofs, it is the difference from the refstate (by default: state[1]) that is amplified.
Optional keyword arguements are
dim, 2 or 3 depending on whether elements assumeAxisorAxis3kwargskeywords argument, that will be passed todraw!
See also EigXU
Muscade.McLaurin — Method
McLaurin(Ty,x)Ty::∂ℝ has partials to arbitrary order with respect to a variable x. These partials define a McLaurin expansion, which McLaurin evaluates at value x, as if Ty had been computed at 0.
McLaurin handles nested structures of Tuples and SVectors of ∂ℝ, applying the expansion to each element.
Muscade.Taylor — Method
Taylor(Ty,x₀,x)Ty::∂ℝ has partials to arbitrary order evaluated at x₀. These partials define a Taylor expansion, which Taylor evaluates at value x
Taylor handles nested structures of Tuples and SVectors of ∂ℝ, applying the expansion to each element.
Muscade.addelement! — Method
eleid = addelement!(model,ElType,nodid;kwargs...)Add one or several elements to model, connecting them to the nodes specified by nodid.
If nodid is an AbstractVector: add a single element to the model. eleid is then a single element identifier.
If nodid is an AbstractMatrix: add multiple elements to the model. Each row of nodid identifies the node of a single element. eleid is then a vector of element identifiers.
For each element, addelement! will call eleobj = ElType(nodes;kwargs...) where nodes is a vector of nodes of the element.
Muscade.addnode! — Method
nodid = addnode!(model,coord)If coord is an AbstractVector of Real: add a single node to the model. Muscade does not prescribe what coordinate system to use. Muscade will handle to each element the coord of the nodes of the element, and the element constructor must be able to make sense of it. nodid is a node identifier, that is used as input to addelement!.
If coord is an AbstractMatrix, its rows are treated as vectors of coordinates. nodid is then a vector of node identifiers.
See also: addelement!, coord , describe
Muscade.allocate_drawing — Method
mut,opt = Muscade.allocate_drawing(axis,eleobjs;kwargs...)Elements that are to be displayed in graphical output must implement a method for Muscade.allocate_drawing.
The method is to allocate opt, a NamedTuple of data that will not be mutated from frame to frame, but are usefull in Muscade.update_drawing or Muscade.display_drawing!.
The method is also to allocate mut, a NamedTuple of data that will be mutated from frame to frame. When implementing graphics with GLMakie.jl, the fields of mut must be exactly the updatable inputs provided to GLMakie.jl's drawing primitives: in Muscade.display_drawing!
lines!(axis,mut.x,mut.y)is acceptable, but
lines!(axis,mut.x[:,s],mut.y[:,s])
lines!(axis,mut.a.x,mut.a.y)are not.
The content of Arrays in opt and mut can be undef-ined.
Inputs are:
axisthe "canvas" to draw on, typicaly aGLMakie.jlAxis.eleobjsanAbstractVectorof element objects, of lengthnel.kwargsaNamedTuplecontaining the keyword arguments provided by the user. Seedefault.
See also: Muscade.update_drawing, Muscade.display_drawing!
Muscade.chainrule — Method
chainrule(Ty,x)Apply a chain rule in automatic differentiation. For example Tx = revariate(x) Ty = f(Tx) y = chainrule(Ty,x) is faster than y = f(x) if the length of x is smaller than the length of its partials.
Muscade.colnormalize — Method
colnormalize(a)Euclidian-normalize the columns of an SMatrix
Muscade.columnmatrix — Method
columnmatrix(v)Reshape a vector into a matrix of size (length(v),1)
Muscade.coord — Method
c = coord(node)Used by element constructors to obtain the coordinates of a vector of Nodes handed by Muscade to the constructor. c is accessed as
c[inod][icoord]where inod is the element-node number and icoord an index into a vector of coordinates.
Note that c[inod] points at the same memory as nod[inod].coord: do not mutate c[inod]!
See also: addnode!, addelement!, describe, solve
Muscade.describe — Method
describe(model,spec)Print out information about model. spec can be
an
EleIDto describe an element,a
DofIDto describe a dof.a
NodIDto describe a node,:doftypto obtain a list of doftypes,:dofto obtain a list of dofs or:eletypfor a list of element types.describe(state,[class=:all])
Provide a description of the dofs stored in state. class can be either :all, :Λ, :ΛX, :X, :U, :A or :scale.
See also: addelement!, addnode!
Muscade.diffed_residual — Method
Muscade.diffed_residual(eleobj;X,U,A,t=0.,SP=nothing)Compute the residual, its gradients, and the memory of an element. For element debugging and testing.
The output is a NamedTuple with fields X, U, A, t, SP echoing the inputs and fields
Rcontaining the residual∇Rof format∇R[iclass][ider]so that for example∇R[2][3]contains the mass matrix.iclassis 2,3 and 4 forX,UandArespectively.FBas returned byresidual
See also: diffed_lagrangian, print_element_array
Muscade.display_drawing! — Method
Muscade.display_drawing!(axis,MyElement,mut,opt)Elements that are to be displayed in graphical output must implement a method for Muscade.display_drawing!.
Inputs are:
axisthe "canvas" to draw on, typicaly aGLMakie.jlAxis.MyElementused for dispatching to the right method.mutis aNamedTuple, as output byMuscade.update_drawing. More specificaly, if implementing graphics withGLMakie.jl,muthas beenoptis as returned byMuscade.allocate_drawing
When implementing graphics with GLMakie.jl, the fields of mut must be exactly the updatable inputs provided to GLMakie.jl's drawing primitives: in Muscade.display_drawing!
lines!(axis,mut.x,mut.y)is acceptable, but
lines!(axis,mut.x[:,s],mut.y[:,s])is not. The reason is that when doing graphics with GLMakie.jl, Muscade will recursively wrap each field of mut into an Observable before calling the elements' methods display_drawing!. This allows Muscade to update the graphics by just calling Muscade.update_drawing for each element.
See also: Muscade.allocate_drawing, Muscade.update_drawing
Muscade.doflist — Method
Muscade.doflist(::Type{E<:AbstractElement})Elements must provide a method for Muscade.doflist.
The method must take the element type as only input, and return a NamedTuple with fieldnames inod,class and field. The tuple-fields are NTuples of the same length. For example
Muscade.doflist( ::Type{<:Turbine}) = (inod =(1 ,1 ,2 ,2 ),
class=(:X ,:X ,:A ,:A ),
field=(:tx1,:tx2,:Δseadrag,:Δskydrag))In Λ, X, U and A handed by Muscade to residual or lagrangian, the dofs in the vectors will follow the order in the doflist. Element developers are free to number their dofs by node, by field, or in any other way.
See also: Muscade.lagrangian, Muscade.residual, Muscade.no_second_order
Muscade.draw! — Method
graphic = draw!(axis ,state[,els];kwargs...)
draw!(graphic,state[,els];kwargs...)Plot all or part of a Model.
Currently, only GLMakie.jl is supported and tested, but Muscade is designed to allow application developers to chose other graphic system, including exporting data to Paraview. GLMakie.jl is thus not a dependency of Muscade, and must be installed and invoked (using) separately to run demos provided with Muscade.
Application developers can implement methods Muscade.allocate_drawing, Muscade.update_drawing and Muscade.display_drawing! to make their element "drawable".
axis a GLMakie.jl Axis, a Muscade.SpyAxis (for automated testing of graphic generation), and in the future a HDF5/VTK file handle for export of data to Paraview. state a single State. els specifies which elements to draw and can be either
- a vector of
EleIDs (obtained fromaddelement!`), all corresponding to the same concrete element type - a concrete element type (see
eletyp). - omitted: all the element of the model are drawn.
kwargs... is any additional key words arguments that will be passed to the draw method of each element, for example to specify colors, etc. See the elements' documentation.
When a plot of the Model is first generated, axis must be provided, and draw! returns graphic. graphic can then be provided for further calls to draw! to update the graphic.
See also: getdof, @request, @espy, addelement!, solve
Muscade.eletyp — Method
et = eletyp(model)Return a vector of the concrete types of elements in the model.
Muscade.equal — Function
equal(t) → :equalA function which for any value t returns the symbol equal. Useful for specifying the keyword argument mode=equal in adding an element of type `DofConstraint to a Model.
See also: DofConstraint, ElementConstraint, off, positive
Muscade.fast — Method
y,... = fast(f,x)In the context of forward automatic differentiation using ∂ℝ, accelerate the evaluation of y,...= f(x) if the length of x is smaller than the length of its partials.
Also work where x is a nested structure of Tuples and NamedTuples where the leaves are ℝ or SArray{S,R} where {S,R<:ℝ}.
Be extremely careful with closures, making sure that f does not capture variables of type ∂ℝ.
Muscade.findlastassigned — Method
ilast = findlastassigned(state)Find the index ilast of the element before the first non assigment element in a vector state.
In multistep analyses, solve returns a vector state of length equal to the number of steps requested by the user. If the analysis is aborted, solve still returns any available results at the begining of state, and the vector state[1:ilast] is fully assigned.
See also: solve
Muscade.getdof — Method
dofres = getdof(state;[class=:X],field=:somefield,nodID=[nodids...],[order=0])Obtain the value of dofs of the same class and field, at various nodes and for various states.
If state is a vector, the output dofres has size (ndof,nstate). If state is a scalar, the output dofres has size (ndof,).
Muscade.getndof — Method
getndof(model|Element)
getndof(model|Element,class)
getndof(model|Element,(class1,class2,[,...]))where class can be any of :X, :U, :A: get the number of dofs of each specified dof-classes for the variable model or the type Element. If no class is specified getndof return the asum of the number of dofs of all classes.
See also: describe
Muscade.getresult — Method
eleres = getresult(state,req,els)Obtain an array of nested NamedTuples and NTuples of element results. req is a request defined using @request. state a vector of States or a single State. els can be either
- a vector of
EleIDs (obtained fromaddelement!) all corresponding to the same concrete element type - a concrete element type (see
eletyp).
If state is a vector, the output dofres has size (nele,nstate). If state is a scalar, the output dofres has size (nele).
See also: getdof, @request, @espy, addelement!, solve, eletyp
Muscade.getsomedofs — Method
rotations = getsomedofs(X,[3,6])Used by elements' residual or lagrangian to some degrees of freedom, and their time derivatives, from the variables X and U.
Muscade.getδt — Method
getδt(n,δω) = 2π/(n*δω)
`n` is the length of the time seriesMuscade.getδω — Method
δω=getδω(n,δt) = 2π/(n*δt)
`n` is the length of the time seriesMuscade.initialize! — Method
initialstate = initialize!(model)Return an initial State for the model with all dofs set to zero
Modifying a model (invoquing addnode! and addelement! after initialize! will result in an error)
Optional keyword arguments: nΛder=1, nXder=1, nUder=1 to specify the number of "derivatives" to store in the State. note that "n⋅der==order+1", that is, for a dynamic problem (with accelerations), nXder=3 so that order==2. Setting n⋅der is only required if setdof! will be used. A dynamic solver handles a "static" initial state perfectly well. time=-∞ the time associated to the initial state. Note that for example setting time=0., and then calling a solver with a first time step also at 0. causes an error.
See also: setdof!, Model, addnode!, addelement!, solve
Muscade.lagrangian — Method
@espy function Muscade.lagrangian(eleobj::MyElement,Λ,X,U,A,t,SP,dbg)
...
return L,FB
endElements must implement a method for Muscade.lagrangian or Muscade.residual.
Inputs
eleobjan element objectΛaSVector{nXdof,R} where{R<:Real}, Lagrange multipliers (akaδXvirtual displacements).XaNTupleofSVector{nXdof,R} where{R<:Real}, containing the Xdofs and, depending on the solver, their time derivatives. Usex=∂0(X),v=∂1(X)anda=∂2(X)to safely obtain vectors of zeros where the solver leaves time derivatives undefined.UaNTupleofSVector{nUdof,R} where{R<:Real}, containing the Udofs and, depending on the solver, their time derivatives. Useu=∂0(U),̇u=∂1(U)and̈u=∂2(U)to safely obtain vectors of zeros where the solver leaves time derivatives undefined.AaSVector{nAdof,R} where{R<:Real}.ta `Realcontaining the time.SPsolver parameters (for example: the barrier parameterγfor interior point methods).dbgaNamedTupleto be used only for debugging purposes.
Outputs
Lthe lagrangianFBfeedback from the element to the solver (for example: canγbe reduced?). ReturnnoFBof the element has no feedback to provide.
See also: Muscade.residual, Muscade.doflist, @espy, ∂0, ∂1, ∂2, noFB,
Muscade.mergerequest — Method
req = mergerequest(o.req)"Outer" elements like ElementCost and ElementConstraint use requests to apply a cost or a constraint to requestables from another "target" element. These outer elements must be coded carefully so that getresult can be used to extracted both requestable internal results from the outer and from the target element.
mergerequest is used to merge the requests for the request needed to enforce a cost or constraint, and the user's request for element to be obtained from the analysis. The call to mergerequest, to be inserted in the code of lagrange for the outer element will be modified by @espy to something like req = mergerequest(o.req,req), to merge o.req of the outer element to any requests req transmitted by the user to extract results (or by an outer element to the outer element).
See the code of ElementCost's constructor and lagrange method for an example.
See also: ElementCost, @request, getresult
Muscade.mod_onebased — Method
mod_onebased(i,n) = mod(i-1,n)+1For i::ℤ, returns a value in {1,...n}. This differs from mod which return a value in [0,n[
Muscade.muscadeerror — Method
muscadeerror([[dbg,]msg])Throw a MuscadeException, where
dbgis aNamedTuplethat contains "location information"
(for example: solver, step, iteration, element, quadrature point) that will be displayed with the error message.
msgis aStringdescribing the problem.
Muscade.no_second_order — Method
no_second_order(::Type{E<:AbstractElement})Elements that define residual are normaly mostly differentiated only to the first order, to avoid excessive compilation and/or execution time. To allow differentiation to the second order (for elements with few dofs), implement a method after the below pattern:
Muscade.no_second_order( ::Type{<:MyElementType}) = Val(false)Muscade.off — Function
off(t) → :offA function which for any value t returns the symbol off. Useful for specifying the keyword argument mode=off in adding an element of type `DofConstraint to a Model.
See also: DofConstraint, ElementConstraint, equal, positive
Muscade.plot_block_matrix_sparsity — Method
Muscade.plot_block_matrix_sparsity(M)Specialised tool to visualise the sparsity pattern of a matrix produced by DirectXUA. M is either a Matrix or a SparseMatrixCSC (the block structure), whose entries are themselve SparseMatrixCSC (the structure of each block).
Optional inputs:
size=500Size in pizel of the figure window.markersize=3Size of dots for non-zero elements.
Muscade.plot_matrix_sparsity — Method
Muscade.plot_matrix_sparsity(M)Opens a GLMakie figure and plots the sparsity pattern of M::SparseMatrixCSC.
Actual non zero-elements are plotted in green. Remaining structuraly non-zero elements are plotted in red.
Optional inputs:
size=500Size in pizel of the figure window.title=nothingTitle of the figure window.markersize=3Size of dots for non-zero elements.atol=1e-9Tolerance for actual non-zero elements.
Muscade.positive — Function
positive(t) → :positiveA function which for any value t returns the symbol positive. Useful for specifying the keyword argument mode=positive in adding an element of type `DofConstraint to a Model.
See also: DofConstraint, ElementConstraint, off, equal
Muscade.prepare — Method
bigmat,bigmatasm,bigvecasm,bigvecdis = prepare(pattern)Prepare for the assembly of sparse blocks into a large sparse matrix. bigmat is allocated, with the correct sparsity structure, but its nzval undef'ed. Where some blocks share the same sparsity structure, blocks in pattern can have === elements.
pattern is a SparseMatrixCSC{<:SparseMatrixCSC}, where empty blocks are structuraly zero
See also: addin!
Muscade.print_element_array — Method
Muscade.print_element_array(eleobj,class,V)Show a vector (or a matrix) V, the rows of V being described as corresponding to eleobj dof of class class (:X, :U or :A). This can be used to print degrees of freedom, residuals, their derivatives, or gradients and Hessian of the Lagrangian.
See also: diffed_residual, diffed_lagrangian
Muscade.print_nz — Method
print_nz(S::SparseMatrixCSC)List the structuraly non-zero entries of the sparse matrix.
Muscade.residual — Method
@espy function Muscade.residual(eleobj::MyElement,X,U,A,t,SP,dbg) ... return R,FB end
Elements must implement a method for Muscade.residual or Muscade.lagrangian.
Inputs
eleobjan element objectXaNTupleofSVector{nXdof,R} where{R<:Real}, containing the Xdofs and, depending on the solver, their time derivatives. Usex=∂0(X),v=∂1(X)anda=∂2(X)to safely obtain vectors of zeros where the solver leaves time derivatives undefined.UaNTupleofSVector{nUdof,R} where{R<:Real}, containing the Udofs and, depending on the solver, their time derivatives. Useu=∂0(U),̇u=∂1(U)and̈u=∂2(U)to safely obtain vectors of zeros where the solver leaves time derivatives undefined.AaSVector{nAdof,R} where{R<:Real}.ta `Realcontaining the time.SPsolver parameters (for example: the barrier parameterγfor interior point methods).dbgaNamedTupleto be used only for debugging purposes.
Outputs
Rthe residualFBfeedback from the element to the solver (for example: canγbe reduced?). ReturnnoFBof the element has no feedback to provide.
See also: Muscade.lagrangian, Muscade.no_second_order, Muscade.doflist, @espy, ∂0, ∂1, ∂2, noFB
Muscade.rowmatrix — Method
rowmatrix(v)Reshape a vector into a matrix of size (1,length(v))
Muscade.setdof! — Method
state = setdof!(state,value ;[class=:X],field=:somefield, [order=0])
state = setdof!(state,value::Vector;[class=:X],field=:somefield,nodID=[nodids...],[order=0])Set the value of dofs of the same class and field, at various nodes and for various states. There are two methods:
- A single
valueis applied to all relevant nodes in the model valueandnodIDare vectors of the same lengths, and each element invalueis applied to the corresponding node.
setdof! is peculiar in that it modifies its input state variable, but must be used as a function. A call like stateout = setdof!(statein,value;class=:X,field=:somefield,order=1) can turn out in two ways: If the state already stores derivatives in X to order 1, then statein is mutated and statein===stateout. Otherwise, statein is unchanged, stateout is a new object, sharing as much memory as possible with statein. To avoid confusion, always use the syntax shown above.
Muscade.setscale! — Method
setscale!(model;scale=nothing,Λscale=nothing)Provide scale value for each type (class and field) of dof in the model. This is usued to improve the conditioning of the incremental problems and for convergence criteria. scale is a NamedTuple with fieldnames within X, U and A. Each field is itself a NamedTuple with fieldnames being dof fields, and value being the expected order of magnitude.
For example scale = (X=(tx=10,rx=1),A=(drag=3.)) should be read as: X-dofs of field :tx are expected to be of the order of magnitude of 10m in the solution, :rx to be of the order of 1 radian, and A-dofs of field drag of the order of 3. All other degrees of freedom are of the order of 1.
Determining scaling coefficients that improve the condition number of incremental matrices is a hard problem.
Λscale is a scalar. The scale of a Λ-dof will be deemed to be the scale of the corresponding X-dof, times Λscale.
See also: addnode!, describe, coord, Muscade.study_scale
Muscade.solve — Method
solve(Solver;dbg=(;),verbose=true,silenterror=false,kwargs...)Execute an analysis using solver Solver (e.g. SweepX, DirectXUA...), and safeguard partial results in the case of error.
Named arguments
dbg=(;)a named tuple to trace the call tree (for debugging)verbose=trueset to false to suppress printed output (for testing)silenterror=falseset to true to suppress print out of error (for testing)kwargs...Further arguments passed on to the methodsolveprovided by the solver
See also: SweepX, DirectXUA, initialize!
Muscade.sparser! — Method
sparser!(S::SparseMatrixCSC,keep::Function)Eliminate terms that do not satisfy a criteria from the storage of a sparse matrix. S will be mutated, and the size of its internal storage modified. keep is a Function which to an index into S.nzval associate true if storage is to be kept for this term and false otherwise. Alternatively, keep can be a Vector{Bool}
Examples
sparser!([T],S,i->abs(S.nzval[i])>tol)
sparser!([T],S,keep::Vector{Boolean})If T is provided (initialised as T = copy(S)), then result is set in T, S is unchanged, other wise S is mutated in place. The input keep::Vector{Boolean} must be of length nnz(S).
sparser!([S1,S2,...],rtol=1e-9)Operates in place, reducing the sparses S1, S2 etc... to a common sparsity pattern.
In the first example, the keep function accesses S.nzval[i], and the term is then mutated by sparser!. Any criteria requiring multiple access to nzval must build a Vector before calling sparser!.
Note that assemble! computes the nzval of a sparse, assumning that its sparsity structure colptr and rowval is unchanged since sparse storage was allocated by asmmat in prepare. In other words, if applying sparser! directly to a sparse returned by assemble!, assemble! can no longer be called for this matrix.
Muscade.study_scale — Method
scale = Muscade.study_scale(state;[SP=nothing],[verbose=false],[dbg=(;)])Returns a named tuple of named tuples for scaling the model, accessed as scaled.myclass.myfield, for example scale.X.tx1.
If verbose=true, prints out a report of the analysis underlying the proposed scale. The proposed scaling depends on the state passed as input - as it is computed for a given incremental matrix.
See also: setscale!
Muscade.study_singular — Method
matrix = Muscade.study_singular(state;SP,[iclasses=(Λ,:X,:U,:A)],[jclasses=iclasses],[verbose::𝕓=true],[dbg=(;)])Generates an incremental matrix for state (no time derivatives) corresponding to the classes required, and report on the null space of the matrix.
In teh present implementation, the incremental matrix is converted to full format, limiting the applicability to small models.
The function returns the incremental matrix.
Muscade.toggle — Method
toggle(condition,a,b)Typestable equivalent of condition ? a : b. Returns a value converted to promote_type(typeof(a),typeof(b))
Muscade.update_drawing — Method
mut = Muscade.update_drawing( axis,::AbstractVector{E},oldmut,opt, Λ,X,U,A,t,SP,dbg)Elements that are to be displayed in graphical output must implement a method for Muscade.allocate_drawing.
For parametric element types
Muscade.update_drawing(axis,o::AbstractVector{Teleobj}, Λ,X,U,A,t,SP,dbg;kwargs...)
where{Teleobj<:MyElement}For non-parametric element types, one can simplify the above to:
Muscade.update_drawing(axis,o::AbstractVector{MyElement}, Λ,X,U,A,t,SP,dbg;kwargs...)Inputs are:
axisthe "canvas" to draw on, typicaly aGLMakie.jlAxis.eleobjsanAbstractVectorof element objects, of lengthnel.oldmutthe outputmutofMuscade.allocate_drawingor of a previous call toMuscade.update_drawing.optthe outputoptofMuscade.allocate_drawingΛa matrix of size(nXdof,nel)XaNTuple(over the derivatives) of matrices of size(nXdof,nel)UaNTuple(over the derivatives) of matrices of size(nUdof,nel)Aa matrix of size(nAdof,nel)ttimeSPsolver parametersdbgdebuging informationkwargsaNamedTuplecontaining the keyword arguments provided by the user. Seedefault.
See also: Muscade.allocate_drawing, Muscade.display_drawing!
Muscade.zero! — Method
zero!(a)Set to zero all elements of an arrays. If a is sparse, the vector nzval of values is set to zero and the sparsity structure is unchanged.
Muscade.∂0 — Method
position = ∂0(X)Used by elements' residual or lagrangian to extract the zero-th order time derivative from the variables X and U.
See also: ∂1,∂2,getsomedofs
Muscade.∂1 — Method
velocity = ∂1(X)Used by elements' residual or lagrangian to extract the first order time derivative from the variables X and U. Where the solver does not provide this derivative (e.g. a static solver), the output is a vector of zeros.
See also: ∂0,∂2,getsomedofs
Muscade.∂2 — Method
position = ∂2(X)Used by elements' residual or lagrangian to extract the zero-th order time derivative from the variables X and U. Where the solver does not provide this derivative (e.g. a static solver), the output is a vector of zeros.
See also: ∂0,∂1,getsomedofs
Muscade.𝔉 — Method
X = 𝔉(x,δt) # typeset with \mfrakF\BbbrFourrier transform of a real time series x stored at time steps δt and length 2N = 2*2^p into a complex spectre X stored at frequency intervals δω=getδω(2N,δt)=2π/(2N*δt). The length of the spectre is N: only positive frequencies are stored (the Fourrier transform of real functions are Hermitian).
This provides a discretization of the unitary Fourrier transform,
G(ω) = 𝔉(g)(ω) = 1/√(2π) ∫exp(-𝑖ωt) g(t) dt𝔉 is unitary, in the sense that
sum(abs2.(x))*δt ≈ 2*(sum(abs2.(X)) - abs2.(X[1])/2)*δω(since the discrete spectre is provided for ω≥0, it contains only half the energy)
Arguments
xa vector of real numbers representing a time series. Its length must be a power of two.δtthe time step of the time series
Example
X = 𝔉(x,δt)
δω = getδω(length(x),δt)
x′ = 𝔉⁻¹(X,δω) # ≈ xMuscade.𝔉⁻¹ — Method
x = 𝔉⁻¹(X,δω) # typeset with \mfrakF\^-\^1See 𝔉
Arguments
Xa vector of complex numbers representing one side of a spectra. Its length must be a power of two.δω, the angular frequency step of spectra
Example
X = 𝔉(x,δt)
δω = getδω(length(x),δt)
x′ = 𝔉⁻¹(X,δω) # ≈ xMuscade.𝕫log2 — Method
𝕫log2(i::𝕫)Compute the integer log2 of an integer, fast. Fails if i is not a power of two.
Macros
Muscade.@espy — Macro
@espy function ... endFrom an anotated function code, generate - "clean" code, in which the anotations have been deleted, and with the call syntax argout... = foo(argin...) - "espying" code, with added input and ouput arguments argout...,res = foo(argin...,req) where req has been generated using @request and res is a nested structure of NamedTuples and NTuples containing the requested data.
The macro is not general: it is designed for residual and lagrangian, which for performance have to be programmed in "immutable" style: they must never mutate variables (this implies in particular, no adding into an array in a loop over Gauss points). So @espy only supports the specific programming constructs needed in this style.
The following is an example of anotated code:
@espy function residual(x::Vector{R},y) where{R<:Real}
ngp=2
accum = ntuple(ngp) do igp
☼z = x[igp]+y[igp]
☼s,☼t = ☼material(z)
♢square = s^2
@named(s)
end
r = sum(i->accum[i].s,ngp)
return r,nothing,nothing
end- The keyword
functionis preceded by the macro-call@espy. - The name of requestable variables is preceded by
☼(\sun). Such anotation must always appear on the left of an assigment. - If the name of a variable is preceded by
♢(\diamond), then the variable is evaluated only if requested. Such a notation can only be used if there is only one variable left of the assignement. - The name of a function being called must be preceded by
☼if the definition of the function is itself preceeded by the macro-call@espy. for-loops are not supported.do-loops must be used: to be efficient,residualandlagrangianmust not allocate and thus use immutables.- The keyword
returnmust be explicitly used, and if must be followed the a comma separated list of output variables. Syntaxes likereturn if...are not supported.
Muscade.@espydbg — Macro
@espydbg function ... endGenerate the same code as @espy and print it (for debug purposes).
Muscade.@functor — Macro
a = 3
@functor with(a,e=2) function f(x::Real)
return a*x^e
endor
a = 3
@functor with(a,e=2) f(x::Real)=a*x^e
e = 1
@functor with(a,e) f(x::Real)=a*x^e
@functor with() f(x::Real)=x^2This is roughly equivalent to a closure defined as
f(x::Real)=a*x^eFunctors are meant to facilitate the definition of "functions" in a Muscade input script, while avoiding several of the issues associated with defining a function (and in particular a closure) in a script:
- A closure captures a variable "by reference", while
@functorcaptures it by value, which might be more intuitive. - To ensure type stability, the variables captured by a closure would have to be declared
const- forbidding to update the input value in a script without restarting Julia. - If the code of the function is not changed, the function is not parsed and compiled again, accelerating the re-analysis.
It is not possible to associate multiple methods to a functor.
Functor is a subtype of the abstract type Function: functions that accept a arg::Function as an input will accept arg to be a Functor. Functions that require arg:Functor will not accept a classical Function, thus enforcing capture by value etc.
Muscade.@request — Macro
req = @request exprCreate a request of internal results wanted from a function. Considering the function presented as example for @espy, examples of possible syntax include
req = @request gp(s,z,material(a,b))
req = @request gp(s)
req = @request gp(material(a))The first expression can be read as follows: "In the function, there is a do loop over variable igp, and within this loop a call to a function material. Results s and z are wanted from within the loop, and results a and b from within material.
The corresponding datastructure containing the results for each element is a nesting of NTuples and NamedTuples, and can be accessed as out.gp[igp].material.a and so forth.
Muscade.@typeof — Macro
inftyp,rettyp = Muscade.@typeof(foo(args...[;kwargs...]))
Determine the inferred type and the returned type of the output[s] returned by the relevant method-instance of foo.
Useful to study type-stability in `lagrangian`, `residual` and more.
This does not work on all operating systems, and should thus only be used for debugging.
In tests, use `Test.@inferred`.Toolbox
Muscade.Toolbox.AxisymmetricBarCrossSection — Type
AxisymmetricBarCrossSectionData structure containing the cross section material properties, for example to a Bar3D
Arguments to the constructor
EA :: 𝕣is the axial stiffness [N]μ :: 𝕣is the mass per unit length [kg/m]
Optional argument to the constructor (all set to zero by default)
Caₜ :: 𝕣is the tangential added mass per unit length [kg/m]Clₜ :: 𝕣is the tangential linear damping coefficient per unit length [N/m/(m/s)]Cqₜ :: 𝕣is the tangential quadratic damping coefficient per unit length [N/m/(m/s)^2], for example from dragCaₙ :: 𝕣is the normal added mass per unit length [kg/m]Clₙ :: 𝕣is the normal linear damping coefficient per unit length [N/m/(m/s)]Cqₙ :: 𝕣is the normal quadratic damping coefficient per unit length [N/m/(m/s)^2]
Example
EA = 10.
L₀ = 2.
μ = 1.
model = Model(:TestModel)
node1 = addnode!(model,𝕣[0,0,0])
node2 = addnode!(model,𝕣[L₀,0,0])
elnod = [model.nod[n.inod] for n∈[node1,node2]]
mat = AxisymmetricBarCrossSection(EA=EA,μ=μ)
bar = Bar3D(elnod;mat)See also: Bar3D, EulerBeam3D
Muscade.Toolbox.Bar3D — Type
Bar3D <: AbstractElementA three-dimensional bar element, with two nodes, six X-dofs and three U-dofs
Arguments to the constructor
nod :: Vector{Node}contains the element's nodesmat :: Matcontains the material properties (AxisymmetricBarCrossSection, for example)
Optional argument to the constructor
ϵₛ ::𝕣is such that the stress-free length of the element is (1-ϵₛ) times the as-meshed length of the element.
Providing ϵₛ is optional and set to machine precision by default. A non-zero ϵₛ means that the bar element exhibits some strain in the as-meshed configuration, and hence has some transverse stiffness, which facilitates convergence in static analyses.
Example
EA = 10.
L₀ = 2.
μ = 1.
model = Model(:TestModel)
node1 = addnode!(model,𝕣[0,0,0])
node2 = addnode!(model,𝕣[L₀,0,0])
elnod = [model.nod[n.inod] for n∈[node1,node2]]
mat = AxisymmetricBarCrossSection(EA=EA,μ=μ)
bar = Bar3D(elnod;mat)See also: AxisymmetricBarCrossSection, EulerBeam3D
Muscade.Toolbox.EulerBeam3D — Type
EulerBeam3DAn Euler beam element
Muscade.Toolbox.Position3D — Method
Position3DAn 3D single-node element, to be connected to a node with both translation and rotation dofs. The element makes zero contribution to residual or Lagrangian. It only provides requestables allowing to model accelerometers and optical position measurements. For an inverse analysis, this is done by including the element in an ElementCost.
Keyword arguments when adding elements:
PSMatrix{3,Nsensor,𝕣}, giving the offset between the nodal position and the point(s) at which position(s) and/or accelerations will be measured.DSMatrix{3,Nsensor,𝕣}, the orientation of an accelerometer. If no accelerometer is present at a given postionP, use NaNs. If multiple accelerometers are present at the same position, one can repeat the columns ofP.
Requestables:
aa[isensor]is thexx[oder+1][:,isensor]contains the position, velocity and acceleration (oder=0,1,2) of the sensor which position was described in theisensor-th column ofP.rᵢrₑ[oder+1]is a vector containing a zero vector, the intrinsic rotation rate vector and its time derivative (oder=0,1,2), for the element's node.rₑrₑ[oder+1]is a vector containing the rotation vector, the extrinsic rotation rate vector and its time derivative (oder=0,1,2), for the element's node.RR[oder+1]is a matrix containing the rotation matrix, spin matrix and its time derivative (oder=0,1,2), for the element's node.xₙx[oder+1]is a vector containing the position, velocity and acceleration (oder=0,1,2) of the element's node.
#Keyword arguments when drawing elements:
When calling draw!, instruction to Position3D elements are given as in this example:
draw!(axis,state>;Position3D=(L= @SVector [0.1,0,0],point_size=10,accelerometer_color=:orange))`The opional keword arguments and their default values are
L = 0.(thus if not given, directions of accelerometers are not shown)point_size = 6point_color = :blackstalk_color = :greystalk_width = 1accelerometer_color = :tealaccelerometer_width = 2
Muscade.Toolbox.StrainGaugeOnEulerBeam3D — Type
StrainGaugeOnEulerBeam3DAn element designed to wrap around an EulerBeam3D. The element makes no contribution to residual or Lagrangian besides the contribution made by the element it wraps. StrainGaugeOnEulerBeam3D provides requestables allowing to model strain gauges. The strain gauges are placed halfway along the EulerBeam3D. In an inverse analysis, the StrainGaugeOnEulerBeam3D is itself wraped by an ElementCost element.
Keyword arguments when adding elements:
PSMatrix{3,Nsensor,𝕣}, giving the offset between the point on the axis of the element halfway along its length.P[1,:]must be zero.DSMatrix{3,Nsensor,𝕣}, the orientation of a strain gauge. If multiple strain gauges are present at the same position, one can repeat the columns ofP.ElementType=EulerBeam3Dthe constructor to the wrapped element. This is typicaly anEulerBeam3Dbut could be another element wrapping anEulerBeam3D.elementkwargsaNamedTuplewith the keyword arguments to the wrapped element. SeeEulerBeam3D
Requestables:
εₐₓ(scalar), the axial strain at the middle of the elementκa vector with elements:κ[1]the torsion at the middle of the element.κ[2]the component of te curvature inEulerBeam3D's direction 2.κ[3]the component of te curvature inEulerBeam3D's direction 3. Although a tri-vector that includes torsion may erroneously suggest a rotation rate vector, theκ[2:3]points to the inside of the curvature and the unit is in1/L(notrad/L) whereLis the unit of length of the model.εa vector of lengthNsensorcontaining the strain values defined byPandD.
#Keyword arguments when drawing elements:
When calling draw!, instruction to StrainGaugeOnEulerBeam3D elements are given as in this example:
draw!(axis,state>;StrainGaugeOnEulerBeam3D=(L= @SVector [0.1,0,0],point_size=10,accelerometer_color=:orange))`The optional keword arguments and their default values are
gauge_color = :blueexpand = 1.02a multiplicative factor applied toPin the drawing only (not in strain calculation) to ensure the gauge is not hidden by a patch-drawing of the beam itself.L = SVector{Nsensor,𝕣}(norm(P)/5 for i=1:Nsensor)the length of the strain gauge in the drawing TODO
Muscade.Toolbox.Rodrigues — Method
Rodrigues(v::SVector{3})Transform a rotation vector v into the rotation matrix M.
See also Toolbox.spin, Toolbox.spin⁻¹, Toolbox.Rodrigues⁻¹, Toolbox.adjust.
Muscade.Toolbox.Rodrigues⁻¹ — Method
Rodrigues⁻¹(v::SVector{3})Transform a rotation matrix M into the rotation vector v, such that |v| < π. Undefined for rotations of angle π
See also Toolbox.spin, Toolbox.spin⁻¹, Toolbox.Rodrigues, Toolbox.adjust.
Muscade.Toolbox.adjust — Method
adjust(u::SVector{3},v::SVector{3})Compute the matrix of the rotation with smallest angle that transforms u into a vector colinear with v. Fails if |u|=0, |v|=0 or if the angle of the rotation is π.
See also Toolbox.spin, Toolbox.spin⁻¹, Toolbox.Rodrigues, Toolbox.Rodrigues⁻¹.
Muscade.Toolbox.intrinsicrotationrates — Method
intrinsicrotationrates(rₑ::NTuple{ND,SMatrix{3,3}}) where{ND}Transform a NTuple containing a rotation matrix and its extrinsic time derivatives, into a NTuple containing a (zero) rotation vector and its intrinsic time derivatives.
See also Toolbox.spin, Toolbox.spin⁻¹, Toolbox.Rodrigues, Toolbox.Rodrigues⁻¹.
Muscade.Toolbox.scac — Method
scac(x)scac(x) = sinc1(acos(x)), The function can be differentiated to the fourth order over ]-1,1] .
See also Toolbox.sinc1
Muscade.Toolbox.sinc1 — Method
sinc1(x)sinc1(x) = sin(x)/x - but sinc1(0.) = 1.. The function can be differentiated to the fourth order.
This differs from Julia's sinc(x) = sin(π*x)/(π*x).
See also Toolbox.scac
Muscade.Toolbox.spin — Method
spin(v::SVector{3})Transform a rotation vector v into the cross product matrix M, such that M ∘₁ a = v × a.
See also Toolbox.spin⁻¹, Toolbox.Rodrigues, Toolbox.Rodrigues⁻¹.
Muscade.Toolbox.spin⁻¹ — Method
spin⁻¹(M::SMatrix{3,3})Transform a cross product matrix M into the rotation vector v, such that v × a = M ∘₁ a.
See also Toolbox.spin, Toolbox.Rodrigues, Toolbox.Rodrigues⁻¹.
Muscade.Toolbox.trace — Method
trace(v::SMatrix{3,3})Computes the trace of a matrix.
Muscade.allocate_drawing — Method
Drawing a Bar3D.
draw!(axis,state)Optional arguments (and their default values) are
line_color = :blackcolor of the lineUdof(trueiff element has Udofs) wether to draw U-forces.Uscale = 1.How many meter is a Newton per meter?
Muscade.allocate_drawing — Method
Drawing a EulerBeam3D.
draw!(axis,state)
draw!(axis,state;EulerBeam3D=(;style=:shape))
α = 2π*(0:19)/20
circle = 0.1*[cos.(α) sin.(α)]'
draw!(axis,state;EulerBeam3D=(;style=:solid,section = circle))style=:shape shows the deformed neutral axis of the element. It has optional arguments frame=true (draws the element's corotated frame of reference) and nseg=10 (number of points to show the deflected shape of each element).
style=:solid shows the deformed shape of the element. It requires the input section=... to be given a matrix of size (2,nsec) describing nsec points around the cross section of the element (no need to close the circumference by repeating the first point at the end). It has optional arguments nseg=10 as above, marking=true to draw a longitudinal marking and solid_color=:yellow.
Other optional arguments (and their default values) are
Udof(trueiff element has Udofs) wether to draw U-forces.draw_frame = falsewether to draw the local reference frame of each elementdraw_marking = truewether to draw "longitudinal marking" along the element. Will only draw if style=:solid.nseg = 1number of segments to display the shape of a deformed elementsolid_color = :yellowcolor of the surface ifstyle=:solidline_color = :blackcolor of the line ifstyle=:sshapeUscale = 1.How many meter is a Newton per meter?
Index
Muscade.noFBMuscade.ϵMuscade.∞Muscade.AbstractElementMuscade.AcostMuscade.DirectXUAMuscade.DofConstraintMuscade.DofCostMuscade.DofLoadMuscade.EigXMuscade.EigXUMuscade.ElementConstraintMuscade.ElementCostMuscade.FreqXUMuscade.FunctionFromVectorMuscade.HoldMuscade.IdVecMuscade.ModelMuscade.MonitorMuscade.NodeMuscade.OffsetVectorMuscade.QuickFixMuscade.SingleAcostMuscade.SingleDofCostMuscade.SingleUdofMuscade.SpyAxisMuscade.SweepXMuscade.SweepXAMuscade.Toolbox.AxisymmetricBarCrossSectionMuscade.Toolbox.Bar3DMuscade.Toolbox.EulerBeam3DMuscade.Toolbox.Position3DMuscade.Toolbox.StrainGaugeOnEulerBeam3DMuscade.addin!Muscade.addin!Muscade.composeJacobianMuscade.composevalueMuscade.defaultMuscade.diffed_lagrangianMuscade.geneigMuscade.incrementMuscade.incrementMuscade.motionMuscade.motion⁻¹Muscade.revariateMuscade.to_orderMuscade.valueMuscade.value_∂Muscade.variateMuscade.δMuscade.ℂMuscade.ℕMuscade.ℝMuscade.ℤMuscade.∂Muscade.𝔹Muscade.𝕓Muscade.𝕔Muscade.𝕟Muscade.𝕣Muscade.𝕫Muscade.:∘₁Muscade.:∘₂Muscade.:⊗Muscade.GUIMuscade.GUIMuscade.McLaurinMuscade.TaylorMuscade.Toolbox.RodriguesMuscade.Toolbox.Rodrigues⁻¹Muscade.Toolbox.adjustMuscade.Toolbox.intrinsicrotationratesMuscade.Toolbox.scacMuscade.Toolbox.sinc1Muscade.Toolbox.spinMuscade.Toolbox.spin⁻¹Muscade.Toolbox.traceMuscade.VALUEMuscade.addelement!Muscade.addnode!Muscade.allocate_drawingMuscade.allocate_drawingMuscade.allocate_drawingMuscade.chainruleMuscade.colnormalizeMuscade.columnmatrixMuscade.constantsMuscade.coordMuscade.describeMuscade.diffed_residualMuscade.display_drawing!Muscade.doflistMuscade.draw!Muscade.eletypMuscade.equalMuscade.fastMuscade.findlastassignedMuscade.getdofMuscade.getndofMuscade.getresultMuscade.getsomedofsMuscade.getδtMuscade.getδωMuscade.initialize!Muscade.lagrangianMuscade.mergerequestMuscade.mod_onebasedMuscade.muscadeerrorMuscade.no_second_orderMuscade.offMuscade.plot_block_matrix_sparsityMuscade.plot_matrix_sparsityMuscade.positiveMuscade.prepareMuscade.print_element_arrayMuscade.print_nzMuscade.residualMuscade.rowmatrixMuscade.setdof!Muscade.setscale!Muscade.solveMuscade.sparser!Muscade.study_scaleMuscade.study_singularMuscade.toggleMuscade.update_drawingMuscade.zero!Muscade.∂0Muscade.∂1Muscade.∂2Muscade.𝔉Muscade.𝔉⁻¹Muscade.𝕫log2Muscade.@espyMuscade.@espydbgMuscade.@functorMuscade.@requestMuscade.@typeof