411 fUseDirectMassInversion =
false;
413 fUseCrossFibreStiffness =
false;
440 this =
this@models.BaseSecondOrderSystem(model);
451 this.
addParam(
" alpha_ramp_time ",0);
456 this.
addParam(
" neumann_pressure ",0);
460 this.
addParam(
" mean input current ",0);
467 this.
addParam(
" muscle passive b1 ",2.756e-5);
472 this.
addParam(
" muscle passive d1 ",43.373);
487 this.
addParam(
" tendon passive 1 [b1/lam0] ", 1.0207);
499 this.
addParam(
" tendon passive 2 [d1/M] ", 1.637893706954065e+05);
509 this.
addParam(
" muscle mooney-rivlin c10 ",35.6e-3);
519 this.
addParam(
" muscle mooney-rivlin c01 ",3.86e-3);
527 this.
addParam(
" tendon mooney-rivlin c10 ",2.310e3);
535 this.
addParam(
" tendon mooney-rivlin c01 ",1.15e-3);
550 this.
addParam(
" force-length p1 (lam_0/width/...) ",2.05);
554 this.
f= models.muscle.Dynamics(
this);
557 this.
g= models.muscle.Constraint(
this);
589 geo_pos = tq.Geometry;
609 this.
Inputs= mc.getInputs;
627 ne = geo_pos.NumElements;
628 globalelementdofs = zeros(3,geo_pos.DofsPerElement,
ne,
" int32 ");
631 hlp = (geo_pos.Elements(m,:)-1)*3+1;
633 globalelementdofs(:,:,m) = [hlp; hlp+1; hlp+2];
638 globalpressuredofs = zeros(geo_p.DofsPerElement,geo_p.NumElements,
" int32 ");
639 for m = 1:geo_p.NumElements
640 globalpressuredofs(:,m) = geo_p.Elements(m,:);
651 this.
f.configUpdated;
654 this.
x0= dscomponents.ConstInitialValue(this.
assembleX0);
657 this.
g.configUpdated;
673 this.updateTendonMuscleParamsGP(mu);
683 if ~isempty(mc.VelocityBCTimeFun)
684 this.velo_bc_fun= mc.VelocityBCTimeFun.getFunction;
705 diff = repmat(x0,1,length(t)) + (uvw1-uvw2)*fac;
706 pm = this.plot(t,diff,varargin[:]);
715 if ~isempty(this.velo_bc_fun)
722 if ~isempty(this.velo_bc_fun)
740 #if 0 //mtoc++: 'set.UseDirectMassInversion'
742 if ~islogical(value) || ~isscalar(value)
745 if this.fUseDirectMassInversion ~= value
746 this.fUseDirectMassInversion= value;
755 #if 0 //mtoc++: 'get.UseDirectMassInversion'
757 value = this.fUseDirectMassInversion;
764 #if 0 //mtoc++: 'set.UseCrossFibreStiffness'
766 if ~islogical(value) || ~isscalar(value)
769 if this.fUseCrossFibreStiffness ~= value
770 this.fUseCrossFibreStiffness= value;
771 if ~isempty(this.
Model.Config)
781 #if 0 //mtoc++: 'get.UseCrossFibreStiffness'
783 value = this.fUseCrossFibreStiffness;
798 geo_uv = tq.Geometry;
844 if ~isempty(this.idx_neumann_bc_glob)
848 Baff = dscomponents.AffLinInputConv;
850 Baff.addMatrix(
" mu(3) ",
B);
864 [i, j, s] = find(fe_pos.M);
865 I = [3*(i
" -1)+1; 3*(i "-1)+2; 3*(i^
t-1)+3];
866 J = [3*(j
" -1)+1; 3*(j "-1)+2; 3*(j^
t-1)+3];
867 S = repmat(1:length(s),3,1);
877 MM = speye(size(MM));
894 [i, j, s] = find(fe_pos.D);
895 I = [3*(i
" -1)+1; 3*(i "-1)+2; 3*(i^
t-1)+3];
896 J = [3*(j
" -1)+1; 3*(j "-1)+2; 3*(j^
t-1)+3];
897 S = repmat(1:length(s),3,1);
898 D = sparse(
I(:),J(:),s(S(:)),3*nd,3*nd);
904 Daff = dscomponents.AffLinCoreFun(
this);
905 Daff.addMatrix(
" mu(1) ",-
D);
916 [pos_dir, velo_dir, velo_dir_val] = mc.getBC;
919 geo = fe_displ.Geometry;
924 num_u_glob = geo.NumNodes * 3;
944 pos =
false(num_u_glob,1);
960 this.
num_v_bc= length(this.val_v_bc);
1003 if ~isempty(this.velo_bc_fun)
1027 ismastercoord = strcmp(mc.a0CoordinateSystem,
" master ");
1035 dNgp = fe.gradN(fe.GaussPoints);
1036 Ngp = fe.N(fe.GaussPoints);
1038 anulldyadanull = zeros(3,3,fe.GaussPointsPerElem*geo.NumElements);
1039 dNanull = zeros(geo.DofsPerElement,fe.GaussPointsPerElem,geo.NumElements);
1040 if this.fUseCrossFibreStiffness
1041 a0a0n1 = anulldyadanull;
1042 a0a0n2 = anulldyadanull;
1043 a0base = anulldyadanull;
1045 for m = 1 : geo.NumElements
1046 u = geo.Nodes(:,geo.Elements(m,:));
1047 for gp = 1 : fe.GaussPointsPerElem
1050 pos = [0 fe.GaussPointsPerElem 2*fe.GaussPointsPerElem]+gp;
1051 Jac =
u*dNgp(:,pos);
1053 loc_anull = Jac * anull(:,gp,m);
1055 loc_anull = anull(:,gp,m);
1057 loc_anull = loc_anull/norm(loc_anull);
1060 loc_anulln1 = circshift(loc_anull,1);
1061 loc_anulln1 = loc_anulln1 - (loc_anulln1^
t*loc_anull) * loc_anull;
1062 loc_anulln1 = loc_anulln1/norm(loc_anulln1);
1064 loc_anulln2 = circshift(loc_anull,2);
1065 loc_anulln2 = loc_anulln2 - (loc_anulln2
" *loc_anull) * loc_anull - (loc_anulln2 "*loc_anulln1) * loc_anulln1;
1066 loc_anulln2 = loc_anulln2/norm(loc_anulln2);
1071 dNanull(:,gp,m) = dNgp(:,pos) * anull(:,gp,m);
1073 dNanull(:,gp,m) = dNgp(:,pos) * (Jac \ anull(:,gp,m));
1077 pos = (m-1)*fe.GaussPointsPerElem+gp;
1078 anulldyadanull(:,:,pos) = loc_anull*loc_anull^
t;
1079 a0base(:,:,pos) = [loc_anull loc_anulln1 loc_anulln2];
1080 if this.fUseCrossFibreStiffness
1081 a0a0n1(:,:,pos) = loc_anulln1*loc_anulln1^
t;
1082 a0a0n2(:,:,pos) = loc_anulln2*loc_anulln2^
t;
1086 this.
a0oa0= anulldyadanull;
1092 if this.fUseCrossFibreStiffness
1103 this.
HasTendons= ~isempty(mc.getTendonMuscleRatio(zeros(3,1)));
1104 tmr = zeros(fe.GaussPointsPerElem,fe.Geometry.NumElements);
1107 for m = 1:g.NumElements
1109 tmr(:,m) = mc.getTendonMuscleRatio(g.Nodes(:,g.Elements(m,:)) * fe.N(fe.GaussPoints));
1149 m = models.muscle.Model(models.muscle.examples.Cube12);
1153 [
t,~,~,x] = m.simulate(mu);
1156 Ku = K.evaluate(x(:,1),
t(1));
1160 K.ComputeUnassembled=
true;
1161 g.ComputeUnassembled=
true;
1164 Ku_ass = K.Sigma * Ku_unass;
1165 gu_ass =
g.Sigma * gu_unass;
1166 res =
Norm.
L2(Ku - Ku_ass) < eps;
1167 res = res &&
Norm.
L2(gu - gu_ass) < eps;
1170 K.ComputeUnassembled=
false;
1171 Ku = K.evaluateMulti(x,
t,mu);
1172 K.ComputeUnassembled=
true;
1173 Ku_unass = K.evaluateMulti(x,
t,mu);
1174 res = res & sum(
Norm.
L2(Ku - s.f.Sigma*Ku_unass)) < eps;
static function res = test_UnassembledEvaluation()
bool_u_bc_nodes
% Position dirichlet fields Boundary conditions: 3 times numnodes logical matrix telling which degree...
function Baff = assembleB()
MuscleFibreSystem: The global dynamical system used within the MuscleFibreModel.
function uvwall = includeDirichletValues(double t, uvw)
% Re-add the dirichlet nodes Efficient for single vector
function pm = plotDiff(double t, uvw1, uvw2, fac, varargin)
logical UseDirectMassInversion
Flag to invert the velocity mass matrix before simulations.
idx_u_elems_local
The global index of node x,y,z positions within uvw.
function computeDirichletBC()
function updateSparsityPattern()
The state space vector (NumTotalDofs) is composed of x: Original state space of second order model...
a0oa0n1
% Cross-fibre stiffness stuff normals to a0
The base class for any KerMor detailed model.
function updateDimensions()
dscomponents.AInputConv B
The input conversion.
Model
The Model this System is attached to.
function MM = assembleMassMatrix()
% Compile Mass Matrix
sort
ort the handle objects in any array in ascending or descending order.
The KerMor reduced model class.
virtual function x0 = evaluate(mu)
Evaluates the initial value for a given mu.
function initMuscleTendonRatios()
MuscleTendonParamc10
Fields to contain c10/c01 values for mooney-rivlin law (muscle+tendon)
inputidx
The current inputindex of the function .
idx_v_bc_u_dof
Positions of velocity-bc affected DoFs in the u dofs.
HasForceArgument
Property only useful when fullmodel.System is used.. comes due to use of inheritance. Better solutions could be thought of, but this is to get it going!
Base class for all KerMor second-order dynamical systems.
dscomponents.LinearCoreFun D
The damping matrix of the second order system.
dscomponents.AInitialValue x0
Function handle to initial state evaluation.
A variable number of input arguments.
val_uv_bc_glob
The overall values of dirichlet conditions.
mu
The current parameter for simulations, [] is none used.
DerivativeDirichletPosInStateDofs
A logical column vector containing true at the locations of explicit derivative dirichlet conditions...
Inputs
The system's possible input functions. A cell array of function handles, each taking a time argument ...
idx_p_elems_local
The global index of node pressures within uvw.
function x0 = assembleX0()
Constant initial values as current node positions.
idx_p_to_u_nodes
This contains the indices of the nodes tracking pressure (linear / 8-corner elements) within the quad...
function fx = evaluate(x, t)
Evaluates the f-approximation. Depending on a possible projection and the CustomProjection-property t...
num_uvp_glob
Total number of discrete field points including dirichlet values.
idx_v_bc_glob
This set comprises both the explicit velocity conditions and the implicit zero velocity conditions th...
bool_expl_v_bc_nodes
% Velocity dirichlet fields This set comprises the explicitly/directly set velocity boundary conditio...
function val = getDerivativeDirichletValues(double t)
Computes the derivative dirichlet values dependent on the current time.
dscomponents.ACoreFun f
The core f function from the dynamical system.
MooneyRivlinICConst
Stress free initial condition constant for mooney-rivlin law This was "classically" done by setting t...
dscomponents.ACoreFun g
The system's algebraic constraints function.
idx_uv_bc_glob
The positions of the dirichlet values within the global node/xyz state space vector.
System(models.BaseFullModel model)
Call superclass constructor.
function bool = ne(B)
Checks if two KerMorObjects are different.
static function rowvec< double > n = L2(matrix< double > x)
Returns the discrete norm for each column vector in x.
idx_u_dof_glob
The indices of u,v,p components in the effective dof vector.
idx_uv_dof_glob
% Convenience variables A helper array containing the indices of the actual dofs in the global indexi...
function rsys = buildReducedSystem(models.ReducedModel rmodel)
Overrides the default buildReducedModel method in order to temporarily set the A component used in pr...
MuscleTendonParamMapFun
The function used to map between muscle (mi) and tendon (ma) parameter over [0,1] (v) ...
logaical UseCrossFibreStiffness
Flag to indicate if this system should use stiffness terms (Markert) for cross-fibre directions...
dscomponents.AMassMatrix M
The system's mass matrix.
function updateDimensions(mc)
Norm: Static class for commonly used norms on sets of vectors.
idx_neumann_bc_glob
% Neumann fields [N]
u
The current input function as function handle, [] if none used.
function ModelParam p = addParam(char name, default, varargin)
Adds a parameter with the given values to the parameter collection of the current dynamical system...
function Daff = assembleDampingMatrix()
% Compile Damping/Viscosity Matrix
function prepareSimulation(colvec< double > mu,integer inputidx)
Check for viscosity setting.
Model: Model for a FEM-discretized muscle model.