KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
evaluate.m
Go to the documentation of this file.
1 #include "Dynamics.m"
2 namespace models{
3 namespace muscle{
4 
5 
6 /* (Autoinserted by mtoc++)
7  * This source code has been filtered by the mtoc++ executable,
8  * which generates code that can be processed by the doxygen documentation tool.
9  *
10  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
11  * Except for the comments, the function bodies of your M-file functions are untouched.
12  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
13  * attached source files that are highly readable by humans.
14  *
15  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
16  * the correct locations in the source code browser.
17  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
18  */
19 
20 function Kuvw = models.muscle.Dynamics.evaluate(uvwdof,double t,fibreforces) {
21 
22  this.nfevals= this.nfevals+1;
23 
24  sys = this.fsys;
25  isproj = ~isempty(this.V);
26  /* If we evaluate inside a projected (reduced) model, reconstruct */
27  if isproj
28  uvwdof = this.V*uvwdof;
29  end
30 
31  /* This should be more correct
32  * unassembled = ~isproj && this.ComputeUnassembled; */
33  unassembled = this.ComputeUnassembled;
34 
35  /* % Include dirichlet values to state vector */
36  uvwcomplete = sys.includeDirichletValues(t, uvwdof);
37 
38  /* % Evaluate K(u,v,w)
39  * This is the main FEM-loop, which evaluates K(u,v,w) */
40  sys = this.fsys;
41  mc = sys.Model.Config;
42  fe_pos = mc.FEM;
43  geo = fe_pos.Geometry;
44  fe_press = mc.PressureFEM;
45 
46  num_u_glob = geo.NumNodes*3;
47 
48  /* Cache variables instead of accessing them via this. in loops */
49  Pmax = this.mu(13);
50  flfun = this.ForceLengthFun;
51 
52  havefibres = sys.HasFibres;
53  havefibretypes = sys.HasFibreTypes;
54  usecrossfibres = this.crossfibres;
55  if usecrossfibres
56  b1cf = this.b1cf;
57  d1cf = this.d1cf;
58  end
59  ldotpos = this.lambda_dot_pos;
60 
61  c10 = sys.MuscleTendonParamc10;
62  c01 = sys.MuscleTendonParamc01;
63  mooneyrivlin_ic_const = sys.MooneyRivlinICConst;
64 
65  if havefibres
66  /* Muscle/tendon material inits. Assume muscle only. */
67  musclepart = 1;
68  anisomusclefun = this.AnisoPassiveMuscle;
69  hastendons = sys.HasTendons;
70  if hastendons
71  tmrgp = sys.MuscleTendonRatioGP;
72  anisotendonfun = this.AnisoPassiveTendon;
73  end
74  if havefibretypes
75  alphaconst = [];
76  fibretypeweights = mc.FibreTypeWeights;
77  if sys.HasMotoPool
78  FibreForces = mc.Pool.getActivation(t);
79  elseif sys.HasForceArgument
80  FibreForces = fibreforces;
81  else
82  FibreForces = ones(size(fibretypeweights,2),1)*this.alpha(t);
83  end
84  /* FibreForces = this.APExp.evaluate(forceargs)'; */
85  else
86  alphaconst = this.alpha(t);
87  end
88  end
89 
90  dofsperelem_u = geo.DofsPerElement;
91  num_gp = fe_pos.GaussPointsPerElem;
92  num_elements = geo.NumElements;
93 
94  /* Init result vector dvw */
95  if unassembled
96  Kuvw = zeros(this.fDim_unass,1);
97  else
98  Kuvw = zeros(num_u_glob,1);
99  end
100 
101  idx_u_elems_local = sys.idx_u_elems_local;
102  /* Transfer to global position within complete uvw vector */
103  idx_p_elems_global = sys.idx_p_elems_local+2*num_u_glob;
104  for m = 1:num_elements
105  /* 1:num_u_glob is all u */
106  elemidx_u = idx_u_elems_local(:,:,m);
107  /* num_u_glob next ones are all v */
108  elemidx_v = num_u_glob + elemidx_u;
109 
110  u = uvwcomplete(elemidx_u);
111  w = uvwcomplete(idx_p_elems_global(:,m));
112 
113  if havefibretypes
114  ftwelem = fibretypeweights(:,:,m)*FibreForces;
115  end
116 
117  integrand_u = zeros(3,dofsperelem_u);
118  for gp = 1:num_gp
119 
120  /* Evaluate the pressure at gauss points */
121  p = w^t * fe_press.Ngp(:,gp,m);
122 
123  pos = 3*(gp-1)+1:3*gp;
124  dtn = fe_pos.transgrad(:,pos,m);
125 
126  if any(isnan(u(:)))
127  fprintf(" NaNs in models.muscle.Dynamics#evaluateCoreFun! Have a look.\n ");
128  keyboard;
129  end
130  /* Deformation gradient */
131  F = u * dtn;
132  C = F^t*F;
133 
134  /* % Isotropic part (Invariant I1 related)
135  * I1 = sum(sum((u'*u) .* (dtn*dtn'))); */
136  I1 = C(1,1) + C(2,2) + C(3,3);
137 
138  /* % Compile tensor */
139  P = mooneyrivlin_ic_const(gp,m)*eye(3) + p*inv(F)^t + 2*(c10(gp,m) + I1*c01(gp,m))*F ...
140  - 2*c01(gp,m)*F*C;
141 
142  /* % Anisotropic part (Invariant I4 related) */
143  if havefibres
144  fibrenr = (m-1)*num_gp + gp;
145  fibres = sys.a0Base(:,:,fibrenr);
146  lambdaf = norm(F*fibres(:,1));
147 
148  /* Get weights for tendon/muscle part at current gauss point */
149  if hastendons
150  tendonpart = tmrgp(gp,m);
151  musclepart = 1-tendonpart;
152  end
153  if havefibretypes
154  alpha = musclepart*ftwelem(gp);
155  else
156  alpha = musclepart*alphaconst;
157  /* [t sys.MuscleTendonRatiosGP(gp,m) alpha] */
158  end
159  passive_aniso_stress = 0;
160  /* Using > 1 is deadly. All lambdas are equal to one at t=0
161  * (reference config, analytical), but numerically this is
162  * dependent on how precise F and hence lambda is computed.
163  * It is very very close to one, but sometimes 1e-7 smaller
164  * or bigger.. and that makes all the difference! */
165  if lambdaf > 1.0001
166  passive_aniso_stress = musclepart*anisomusclefun(lambdaf);
167  if hastendons
168  passive_aniso_stress = passive_aniso_stress + tendonpart*anisotendonfun(lambdaf);
169  end
170  end
171 
172  /* Using a class-subfunction is 20% slower!
173  * So: function handle */
174  fl = flfun(lambdaf);
175  gval = passive_aniso_stress + (Pmax/lambdaf)*fl*alpha;
176  P = P + gval*F*sys.a0oa0(:,:,fibrenr);
177 
178  /* % Cross-fibre stiffness part */
179  if usecrossfibres
180  lambdaf = norm(F*fibres(:,2));
181  if lambdaf > .999
182  g1 = (b1cf/lambdaf^2)*(lambdaf^d1cf-1);
183  P = P + g1*F*sys.a0oa0n1(:,:,fibrenr);
184  end
185  lambdaf = norm(F*fibres(:,3));
186  if lambdaf > .999
187  g2 = (b1cf/lambdaf^2)*(lambdaf^d1cf-1);
188  P = P + g2*F*sys.a0oa0n2(:,:,fibrenr);
189  end
190  end
191 
192  /* % Check if change rate of lambda at a certain gauss point should be tracked
193  * (corresponds to a spindle location in fullmodels.muscle.Model) */
194  if ~isempty(ldotpos)
195  k = find(ldotpos(1,:) == m & ldotpos(2,:) == gp);
196  if ~isempty(k)
197  Fdot = uvwcomplete(elemidx_v) * dtn;
198  this.lambda_dot(k) = (F*fibres(:,1))^t*(Fdot*fibres(:,1))/lambdaf;
199  end
200  end
201  end
202 
203  /* % Viscosity - currently modeled as extra A linear system
204  * if visc > 0
205  * v = uvw_full(elemidx_v);
206  * P = P + visc * v * dtn;
207  * end */
208 
209  /* % Assembly part I - sum up contributions from gauss points */
210  weight = fe_pos.GaussWeights(gp) * fe_pos.elem_detjac(m,gp);
211 
212  integrand_u = integrand_u + weight * P * dtn^t;
213  end /* end of gauss point loop */
214 
215 
216  /* % Assembly part II - sum up contributions of elements
217  * Unassembled or assembled? */
218  if unassembled
219  pos = (1:3*dofsperelem_u) + (m-1) * 3 * dofsperelem_u;
220  Kuvw(pos) = -integrand_u(:);
221  else
222  /* This operator does only give the change of v and the
223  * algebraic side constraints. Hence, the resulting dvw vector
224  * does not contain the change of u in the first num_u_glob
225  * entries. */
226  elemidx_v_out = elemidx_v - num_u_glob;
227 
228  /* We have v' + K(u) = 0, so the values of K(u) must be
229  * written at the according locations of v', i.e. elemidx_velo
230  *
231  * Have MINUS here as the equation satisfies Mu'' + K(u,w) =
232  * 0, but KerMor implements Mu'' = -K(u,w) */
233  Kuvw(elemidx_v_out) = Kuvw(elemidx_v_out) - integrand_u;
234  end
235  /* % end of element loop */
236  end
237 
238  if unassembled
239  Kuvw(this.idx_uv_bc_glob_unass) = [];
240  else
241  /* Extract boundary condition residuals for later use */
242  this.LastBCResiduals= Kuvw(sys.idx_v_bc_local);
243 
244  /* Remove BC entries */
245  Kuvw(sys.idx_v_bc_local) = [];
246 
247  /* Reconstruct if suitable */
248  if isproj
249  Kuvw = this.W^t*Kuvw;
250  end
251  end
252 end
253 }
262 };
263 };
* fl(l)
#define F(x, y, z)
Definition: CalcMD5.c:168
function fx = evaluate(x, t)
Evaluates the f-approximation. Depending on a possible projection and the CustomProjection-property t...
Definition: ACoreFun.m:296