21 this.nJevals= this.nJevals+1;
27 mc = sys.Model.Config;
29 geo = fe_pos.Geometry;
30 fe_press = mc.PressureFEM;
31 pgeo = fe_press.Geometry;
35 dofsperelem_pos = geo.DofsPerElement;
36 dofsperelem_press = pgeo.DofsPerElement;
37 num_gausspoints = fe_pos.GaussPointsPerElem;
38 num_elements = geo.NumElements;
42 c10 = sys.MuscleTendonParamc10;
43 c01 = sys.MuscleTendonParamc01;
45 flfun = this.ForceLengthFun;
46 dflfun = this.ForceLengthFunDeriv;
48 havefibres = sys.HasFibres;
49 havefibretypes = sys.HasFibreTypes;
50 usecrossfibres = this.crossfibres;
51 hasforceargument = sys.HasForceArgument;
56 ldotpos = this.lambda_dot_pos;
57 haveldotpos = ~isempty(ldotpos);
65 numXYZDofs_pos = 3*dofsperelem_pos;
66 relidx_pos = 1:numXYZDofs_pos;
68 numparts = (3+1)*numXYZDofs_pos;
72 totalsize = num_elements*num_gausspoints*numparts;
73 i = zeros(totalsize,1);
74 j = zeros(totalsize,1);
75 s = zeros(totalsize,1);
82 anisomusclefun = this.AnisoPassiveMuscle;
83 anisomuscledfun = this.AnisoPassiveMuscleDeriv;
84 hastendons = sys.HasTendons;
86 tmrgp = sys.MuscleTendonRatioGP;
87 anisotendonfun = this.AnisoPassiveTendon;
88 anisotendondfun = this.AnisoPassiveTendonDeriv;
93 fibretypeweights = mc.FibreTypeWeights;
94 nfibres = size(fibretypeweights,2);
96 FibreForces = mc.Pool.getActivation(t);
97 elseif hasforceargument
98 FibreForces = uvwdof(sys.NumTotalDofs+1:end) * min(1,t);
99 totalsizeS = num_elements*num_gausspoints*nfibres;
100 iS = zeros(totalsizeS,1);
101 jS = zeros(totalsizeS,1);
102 sS = zeros(totalsizeS,1);
104 columns_sarco_link = 53:56:56*nfibres;
106 error(
" No implemented ");
110 alphaconst = this.alpha(t);
116 globidx_pos = sys.idx_u_elems_local;
117 idx_p_elems_global = sys.idx_p_elems_local + 2*size_pos_vec;
120 uvwcomplete = sys.includeDirichletValues(t, uvwdof);
122 for m = 1:num_elements
123 elemidx_u_glob = globidx_pos(:,:,m);
124 elemidx_v_glob = elemidx_u_glob + size_pos_vec;
129 elemidx_v_out_linear = elemidx_u_glob(:);
130 elemidx_v_out_linear3 = [elemidx_v_out_linear
132 elemidx_v_out_linear];
133 elemidx_p_global = idx_p_elems_global(:,m);
136 ftwelem = fibretypeweights(:,:,m)*FibreForces;
139 for gp = 1:num_gausspoints
140 pos = 3*(gp-1)+1:3*gp;
141 dtn = fe_pos.transgrad(:,pos,m);
142 u = uvwcomplete(elemidx_u_glob);
151 w = uvwcomplete(elemidx_p_global);
152 p = w^t * fe_press.Ngp(:,gp,m);
155 I1 = C(1,1) + C(2,2) + C(3,3);
159 fibrenr = (m-1)*num_gausspoints + gp;
160 fibres = sys.a0Base(:,:,fibrenr);
166 tendonpart = tmrgp(gp,m);
167 musclepart = 1-tendonpart;
170 alpha = musclepart*alphaconst;
172 alpha = musclepart*ftwelem(gp);
175 alpha_prefactor = (Pmax/lambdaf)*fl;
176 g_value = alpha_prefactor*alpha;
177 dg_dlam = (Pmax/lambdaf^2)*alpha*(dflfun(lambdaf) -
fl);
184 g_value = g_value + musclepart*anisomusclefun(lambdaf);
185 dg_dlam = dg_dlam + musclepart*anisomuscledfun(lambdaf);
187 g_value = g_value + tendonpart*anisotendonfun(lambdaf);
188 dg_dlam = dg_dlam + tendonpart*anisotendondfun(lambdaf);
191 a0 = sys.a0oa0(:,:,fibrenr);
195 Fcrossf1 = F*fibres(:,2);
196 lambdaa0_n1 = norm(Fcrossf1);
197 if lambdaa0_n1 > .999
198 xfibre1 = (b1cf/lambdaa0_n1^2)*(lambdaa0_n1^d1cf-1);
199 dxfibre1_dlam = (b1cf/lambdaa0_n1^3)*((d1cf-2)*lambdaa0_n1^d1cf + 2);
201 Fcrossf2 = F*fibres(:,3);
202 lambdaa0_n2 = norm(Fcrossf2);
203 if lambdaa0_n2 > .999
204 xfibre2 = (b1cf/lambdaa0_n2^2)*(lambdaa0_n2^d1cf-1);
205 dxfibre2_dlam = (b1cf/lambdaa0_n2^3)*((d1cf-2)*lambdaa0_n2^d1cf + 2);
207 a0oa0_2 = sys.a0oa0n1(:,:,fibrenr);
208 a0oa0_3 = sys.a0oa0n2(:,:,fibrenr);
213 k = find(ldotpos(1,:) == m & ldotpos(2,:) == gp);
215 Fdot = uvwcomplete(elemidx_v_glob) * dtn;
216 Fdota0 = Fdot*fibres(:,1);
220 this.lambda_dot(k) = Fa0^t*Fdota0/lambdaf;
223 JLamDot = zeros(2*numXYZDofs_pos,1);
224 for eldof = 1:dofsperelem_pos
226 U1k = [dtn(eldof,:); 0 0 0; 0 0 0];
227 U2k = [0 0 0; dtn(eldof,:); 0 0 0];
228 U3k = [0 0 0; 0 0 0; dtn(eldof,:)];
229 idx = (eldof-1)*3 + (1:3);
230 idxv = idx + 3*dofsperelem_pos;
232 Ua0 = U1k*fibres(:,1);
234 JLamDot(idx(1)) = JLamDot(idx(1)) + Ua0^t*Fdota0;
238 JLamDot(idxv(1)) = JLamDot(idxv(1)) + Fa0^t*Ua0;
241 Ua0 = U2k*fibres(:,1);
243 JLamDot(idx(2)) = JLamDot(idx(2)) + Ua0^t*Fdota0;
247 JLamDot(idxv(2)) = JLamDot(idxv(2)) + Fa0^t*Ua0;
250 Ua0 = U3k*fibres(:,1);
252 JLamDot(idx(3)) = JLamDot(idx(3)) + Ua0^t*Fdota0;
256 JLamDot(idxv(3)) = JLamDot(idxv(3)) + Fa0^t*Ua0;
258 ildot = [ildot; k*ones(2*numXYZDofs_pos,1)];
260 jldot = [jldot; elemidx_u_glob(:); elemidx_v_glob(:)];
262 sldot = [sldot; JLamDot];
270 weight = fe_pos.GaussWeights(gp) * fe_pos.elem_detjac(m, gp);
272 for k = 1:dofsperelem_pos
274 U1k = [dtn(k,:); 0 0 0; 0 0 0];
275 U2k = [0 0 0; dtn(k,:); 0 0 0];
276 U3k = [0 0 0; 0 0 0; dtn(k,:)];
278 dI1duk = 2*sum([1; 1; 1] * (dtn(k,:) * dtn^t) .* u, 2);
279 fac1 = 2*dI1duk*c01(gp,m);
280 fac2 = 2*(c10(gp,m) + I1*c01(gp,m));
288 i(cur_off + (1:3*numXYZDofs_pos)) = elemidx_v_out_linear3;
291 dFtF1 = U1k" *F + F "*U1k;
292 dPx = -p * (Finv * U1k * Finv)^t...
293 + fac1(1)*F + fac2*U1k...
294 -2*c01(gp,m) * (U1k * C + F*dFtF1);
297 dlambda_dux = Fa0^t*U1k*fibres(:,1)/lambdaf;
298 dPx = dPx + (dg_dlam*dlambda_dux*F + g_value*U1k)*a0;
300 if lambdaa0_n1 > .999
301 dlambda_dux = Fcrossf1^t*U1k*fibres(:,2)/lambdaa0_n1;
302 dPx = dPx + (dxfibre1_dlam*dlambda_dux*F + xfibre1*U1k)*a0oa0_2;
304 if lambdaa0_n2 > .999
305 dlambda_dux = Fcrossf2^t*U1k*fibres(:,3)/lambdaa0_n2;
306 dPx = dPx + (dxfibre2_dlam*dlambda_dux*F + xfibre2*U1k)*a0oa0_3;
310 j(cur_off + relidx_pos) = elemidx_u_glob(1,k);
311 snew = -weight * dPx * dtn^t;
312 s(cur_off + relidx_pos) = snew(:);
313 cur_off = cur_off + numXYZDofs_pos;
316 dFtF2 = U2k" *F + F "*U2k;
317 dPy = -p * (Finv * U2k * Finv)^t...
318 +fac1(2)*F + fac2*U2k...
319 -2*c01(gp,m) * (U2k * C + F*dFtF2);
321 dlambda_duy = Fa0^t*U2k*fibres(:,1)/lambdaf;
322 dPy = dPy + (dg_dlam*dlambda_duy*F + g_value*U2k)*a0;
324 if lambdaa0_n1 > .999
325 dlambda_duy = Fcrossf1^t*U2k*fibres(:,2)/lambdaa0_n1;
326 dPy = dPy + (dxfibre1_dlam*dlambda_duy*F + xfibre1*U2k)*a0oa0_2;
328 if lambdaa0_n2 > .999
329 dlambda_duy = Fcrossf2^t*U2k*fibres(:,3)/lambdaa0_n2;
330 dPy = dPy + (dxfibre2_dlam*dlambda_duy*F + xfibre2*U2k)*a0oa0_3;
334 j(cur_off + relidx_pos) = elemidx_u_glob(2,k);
335 snew = -weight * dPy * dtn^t;
336 s(cur_off + relidx_pos) = snew(:);
337 cur_off = cur_off + numXYZDofs_pos;
340 dFtF3 = U3k" *F + F "*U3k;
341 dPz = -p * (Finv * U3k * Finv)^t...
342 +fac1(3)*F + fac2*U3k ...
343 - 2*c01(gp,m) * (U3k * C + F*dFtF3);
345 dlambda_duz = Fa0^t*U3k*fibres(:,1)/lambdaf;
346 dPz = dPz + (dg_dlam*dlambda_duz*F + g_value*U3k)*a0;
348 if lambdaa0_n1 > .999
349 dlambda_duz = Fcrossf1^t*U3k*fibres(:,2)/lambdaa0_n1;
350 dPz = dPz + (dxfibre1_dlam*dlambda_duz*F + xfibre1*U3k)*a0oa0_2;
352 if lambdaa0_n2 > .999
353 dlambda_duz = Fcrossf2^t*U3k*fibres(:,3)/lambdaa0_n2;
354 dPz = dPz + (dxfibre2_dlam*dlambda_duz*F + xfibre2*U3k)*a0oa0_3;
358 j(cur_off + relidx_pos) = elemidx_u_glob(3,k);
359 snew = -weight * dPz * dtn^t;
360 s(cur_off + relidx_pos) = snew(:);
361 cur_off = cur_off + numXYZDofs_pos;
389 for k = 1:dofsperelem_press
390 i(cur_off + relidx_pos) = elemidx_v_out_linear;
391 j(cur_off + relidx_pos) = elemidx_p_global(k);
392 snew = -weight * fe_press.Ngp(k,gp,m) * Finv" * dtn ";
393 s(cur_off + relidx_pos) = snew(:);
394 cur_off = cur_off + numXYZDofs_pos;
400 dPsk = alpha_prefactor * fibretypeweights(gp,k,m) * F * a0;
401 iS(cur_offS + relidx_pos) = elemidx_v_out_linear-size_pos_vec;
402 jS(cur_offS + relidx_pos) = columns_sarco_link(k);
403 snew = -weight * dPsk * dtn^t;
404 sS(cur_offS + relidx_pos) = snew(:);
405 cur_offS = cur_offS + numXYZDofs_pos;
411 JK = sparse(i,j,s,3*N,6*N+pgeo.NumNodes);
413 JK(:,sys.idx_uv_bc_glob) = [];
414 JK(sys.idx_v_bc_local,:) = [];
423 Jalpha = sparse(iS,jS,sS,3*N,nfibres*56);
425 Jalpha([sys.idx_u_bc_glob; sys.idx_v_bc_glob],:) = [];
430 JLamDot = sparse(ildot,
double(jldot),sldot,this.nfibres,6*N);
431 JLamDot(:,sys.idx_uv_bc_glob) = [];
function J = getStateJacobianImpl(colvec< double > x,double t)
Default implementation of state jacobians. uses finite differences.