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
MuscleTendonMix.m
Go to the documentation of this file.
1 namespace models{
2 namespace muscle{
3 namespace examples{
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 
53  public:
54 
56 
57 
58  public:
59 
61 
62 
63  public:
64 
66  this = this@models.muscle.AMuscleConfig(varargin[:]);
67  this.addOption(" Variant ",1);
68  this.init;
69 
70  /* this.NeumannCoordinateSystem = 'global'; */
71  }
72 
73 
74  function configureModel(m) {
75  configureModel@models.muscle.AMuscleConfig(this, m);
76  m.T= 4;
77  m.dt= .01;
78  m.DefaultInput= 1;
79 
80  os = m.ODESolver;
81  os.RelTol= .0001;
82  os.AbsTol= .05;
83 
84  mu = m.DefaultMu;
85  switch this.Options.Variant
86  case [1 2]
87  mu(3) = 4;
88  case 3
89  mu(3) = 4;
90  m.ODESolver.AbsTol= .1;
91  case 4
92  mu(2) = m.T;
93  mu(3) = 0;
94  m.ODESolver.RelTol= .1;
95  m.ODESolver.AbsTol= .1;
96  case 5
97  mu(2) = m.T;
98  m.ODESolver.RelTol= .1;
99  m.ODESolver.AbsTol= .1;
100  case 6
101  mu(3) = 10;
102  case 7
103  m.T= 30;
104  m.dt= .05;
105  mu(2) = m.T*2/3; /* activate 2/3rds of the time */
106 
107  mu(3) = 0;
108  end
109  mu(13) = .250; /* Pmax [MPa] */
110 
111  m.DefaultMu= mu;
112  }
113 
114 
115  function u = getInputs() {
116  u[1] = this.getAlphaRamp(1,1);
117  }
125  function tmr = getTendonMuscleRatio(points) {
126  tmr = zeros(1,size(points,2));
127  switch this.Options.Variant
128  case 1
129  ratios = linspace(0,1,4);
130  for k=1:4
131  tmr(points(2,:) >= k-1 .* points(2,:) < k) = ratios(k);
132  end
133  case [2 5]
134  tmr(points(3,:) > .66) = 1;
135  case [3 4]
136  tmr = this.TMRFun(points(2,:),points(3,:));
137  /* Take only half - too stiff otherwise */
138  tmr = tmr/2;
139  case [6 7]
140  /* Set the middle 20% percent to 100% muscle */
141  zeroperc = .2;
142 
143  y = points(2,:);
144  cent = this.ylen/2;
145  left = y <= cent*(1-zeroperc/2);
146  tmr(left) = 1-y(left)/(cent*(1-zeroperc/2));
147  right = y > cent + this.ylen*zeroperc/2;
148  tmr(right) = (y(right)-(this.ylen*(.5+zeroperc/2)))/...
149  (this.ylen*(.5-zeroperc/2));
150  end
151  /* Use max .2 tendon - works but needs to be checked for higher
152  * tendon parts (and current default parameter mu!!!!) */
153  if this.Options.Variant == 4
154  tmr = 2*tmr/5;
155  end
156  }
168  function tmr = TMRFun(z,matrix<double> y) {
169  f = @(z,y)min(1,max(0,-.5+.5./((z/2+.1).*(1.5*y+.08*z+.1))));
170  tmr = f(z,y) + f(6-z,2-y);
171  }
172 
173 
174  function plotTMRFun() {
175  [Y,Z] = meshgrid(0:.01:2.1,0:.01:6.1);
176  tmr = this.TMRFun(Z,Y);
177  pm = PlotManager;
178  pm.LeaveOpen= true;
179  ax = pm.nextPlot(" tmr_func "," Muscle/Tendon ratio function ");
180  surfc(Z,Y,tmr," Parent ",ax);
181  axis(ax," equal ");
182  }
183 
184 
185  function P = getBoundaryPressure(elemidx,faceidx) {
186  P = [];
187  switch this.Options.Variant
188  /* Pull on front face */
189  case [1 2 3]
190  if any(elemidx == [1 2 7 8]) && faceidx == 3
191  P = 1;
192  end
193  case 6
194  if any(elemidx == 1:4) && faceidx == 3
195  P = 1;
196  end
197  end
198  }
212  protected:
213 
214 
215  function geo = getGeometry() {
216  switch this.Options.Variant
217  case 1
218  /* Four cubes in a row */
219  geo = fem.geometry.RegularHex8Grid(0:1,0:4,0:1);
220  case [2 5]
221  /* Single cube with same config as reference element */
222  geo = fem.geometry.RegularHex8Grid(0:1,0:1,0:1);
223  case [3 4]
224  /* 2x4x2 geometry */
225  geo = fem.geometry.RegularHex8Grid(0:2,0:2:6,0:2);
226  end
227  if any(this.Options.Variant == [6 7])
228  yl = 10;
229  this.ylen= yl;
230  geo = fem.geometry.Belly(6,yl," Radius ",1," InnerRadius ",.2," Gamma ",2);
231  else
232  geo = geo.toCube27Node;
233  end
234  }
235 
236 
237  function displ_dir = setPositionDirichletBC(displ_dir) {
238  geo = this.FEM.Geometry;
239 
240  switch this.Options.Variant
241  case [1 2 5]
242  /* Fix all on left and only the y,z directions of the back right
243  * nodes */
244  displ_dir(2,geo.Elements(geo.NumElements,geo.MasterFaces(4,:))) = true;
245  case 3
246  displ_dir(2,geo.Elements([5 6 11 12],geo.MasterFaces(4,:))) = true;
247  displ_dir(:,geo.Elements(5,geo.MasterFaces(4,9))) = true;
248  case 4
249  /* displ_dir(2,geo.Elements([5 6 11 12],geo.MasterFaces(4,:))) = true;
250  *displ_dir(2,geo.Elements([1 2 7 8],geo.MasterFaces(3,:))) = true; */
251  displ_dir(:,geo.Elements([5 6 11 12],geo.MasterFaces(4,:))) = true;
252  displ_dir(:,geo.Elements([1 2 7 8],geo.MasterFaces(3,:))) = true;
253  case 6
254  displ_dir(:,geo.Elements(13:16,geo.MasterFaces(4,:))) = true;
255  case 7
256  displ_dir(:,geo.Elements(1:4,geo.MasterFaces(3,:))) = true;
257  last = size(geo.Elements,1)-3:size(geo.Elements,1);
258  displ_dir(:,geo.Elements(last,geo.MasterFaces(4,:))) = true;
259  end
260  }
269  function anull = seta0(anull) {
270  switch this.Options.Variant
271  case [1 2 5 6 7]
272  /* Direction is y */
273  anull(2,:,:) = 1;
274  case [3 4]
275  /* anull(2,:,:) = 1; */
276  anull([2 3],:,:) = -1;
277  end
278  }
279 
280 
281  public: /* ( Static ) */
282 
283  static function test_MuscleTendonMix(variant) {
284  if nargin < 1
285  variant = 1:7;
286  end
287  for k = variant
288  fprintf(" Testing MuscleTendonMix Variant %d\n ",k);
289  m = models.muscle.Model(models.muscle.examples.MuscleTendonMix(" Variant ",k));
290  m.simulateAndPlot;
291  end
292  }
293 
294 
295 
296 };
297 }
298 }
299 }
300 
301 
302 
function geo = getGeometry()
Returns the intended geometry for this model config.
function addOption(name, default, varargin)
Definition: AFEMConfig.m:219
function alpha = getAlphaRamp(ramptime,double alphamax,double starttime)
Creates a linearly increasing scalar function starting at starttime milliseconds ranging from zero to...
function u = getInputs()
Ramp up the external pressure.
PlotManager: Small class that allows the same plots generated by some script to be either organized a...
Definition: PlotManager.m:17
function P = getBoundaryPressure(elemidx, faceidx)
Determines the neumann forces on the boundary.
static function test_MuscleTendonMix(variant)
function tmr = TMRFun(z,matrix< double > y)
logical LeaveOpen
Flag indicating if the plots should be left open once the PlotManager is deleted (as variable) ...
Definition: PlotManager.m:213
A variable number of input arguments.
function tmr = getTendonMuscleRatio(points)
Returns the [0,1] ratio between tendon and muscle at all specified points.
#define Y(i, j)
function displ_dir = setPositionDirichletBC(displ_dir)
% Dirichlet conditions: Position (fix one side)
Muscle - Tendon mixed geometries.