6 Finite Element Models

6.8 Varying and augmenting material behaviors

The default material used by all elements of an FEM model is supplied by the model’s material property. However, it is often the case that one wishes to specify different material behaviors for different sets of elements within an FEM model. This may be particularly true when combining volumetric and shell elements.

There are several ways to vary material behavior within a model. These include:

  • Setting an explicit material for specific elements, using their material property. An element’s material is null by default, but if set to a material, it will override the default material supplied by the FEM model. While this method is quite straightforward, it does have one disadvantage: because material settings are copied by each element, subsequent interactive or online changes to the material require resetting the material in all the affected elements.

  • Binding one or more material parameters to a field. Sometimes certain material parameters, such as stiffness quantities or direction information, may need to vary across the FEM domain. While sometimes this can be handled by setting material properties for specific elements, it may be more convenient to bind the varying properties to a field, which can specify varying values over a domain composed of either a regular grid or an FEM mesh. Only one material needs to be used, and any properties which are not bound can be adjusted interactively or online. Fields and their bindings are described in detail in Chapter 7.

  • Adding augmenting material behaviors using MaterialBundles. A material bundle may be specified either for all elements, or for a subset of them, and each provides one material (via its own material property) whose behavior is added to that of the indicated elements. This also provides an easy way to combine the behaviors of two of more materials in the same element. One also has the option of setting the material property of the certain elements to NullMaterial, so that only the augmenting material(s) are applied.

  • Adding muscle behaviors using MuscleBundles. This is analogous to using MaterialBundles, except that MuscleBundles are restricted to using an instance of a MuscleMaterial, and include support for handling the excitation value, as well as the activation directions (which usually vary across the FEM domain). MuscleBundles are only present in the FemMuscleModels subclass of FemModel3d, and are described in detail in Section 6.9.

The remainder of this section will discuss MaterialBundles.

Adding a MaterialBundle to an FEM model is illustrated by the following code fragment:

  FemMaterial extraMat;   // material to be added
  FemModel3d fem;         // FEM model
  ...
  MaterialBundle bun = new MaterialBundle ("mybundle", extraMat);
  // add volumetric elements to the bundle
  for (FemElement3d e : fem.getElements()) {
     if (/* e should be added to the bundle */) {
        bun.addElement (e);
     }
  }
  fem.addMaterialBundle (bun);

Once added, the stress computed by the bundle’s material will be added to the stress computed by any other materials which are active for the bundle’s elements.

When deciding what elements to add to a bundle, one is free to choose any means necessary. The example above inspects all the volumetric elements in the FEM. To instead inspect all the shell elements, or all volumetric and shell elements, one could use the code fragments such as the following:

  // add shell elements to the bundle
  for (ShellElement3d e : fem.getShellElements()) {
     if (/* e should be added to the bundle */) {
        bun.addElement (e);
     }
  }
  // add volumetric or shell elements to the bundle
  for (FemElement3dBase e : fem.getAllElements()) {
     if (/* e should be added to the bundle */) {
        bun.addElement (e);
     }
  }

Of course, if the elements are known through other means, then they can be added directly.

The element composition of a bundle can be controlled by the methods

  void addElement (FemElement3dBase e)        // adds an element
  boolean removeElement (FemElement3dBase e)  // removes an element
  void clearElements()                        // removes all elements
  int numElements()                           // gets the number of elements
  FemElment3dBase getElement (int idx)        // gets the idx-th element

It is also possible to create a MaterialBundle whose material is added to all the FEM elements. This can done either by using one of the following constructors

  MaterialBundle (String name, boolean useAllElements)
  MaterialBundle (String name, FemMaterial mat, boolean useAllElements)

with useAllElements set to true, or by calling the method

  void setUseAllElements (boolean enable)

When a bundle is set to use all the FEM elements, it clears its own element list, and one is not permitted to add elements using addElement(elem).

After a bundle has been created, it is possible to get or set its material property using the methods

  FemMateral getMaterial()                  // get the material
  FemMateral setMaterial (FemMaterial mat)  // set the material

Again, because materials are copied internally, any modification to a material after it has been used as an input to setMaterial() will not be noticed by the bundle. Instead, one should modify the material before calling setMaterial(), or modify the copied material which can be obtained by calling getMaterial() or by storing the value returned by setMaterial().

Finally, a MuscleBundle is a renderable component. Setting its elementWidgetSize property to a value greater than zero will cause the rendering of all its elements, using a solid widget representation of each at a scale controlled by elementWidgetSize: 0.5 for half size, 1.0 for full size, etc. The color of the widgets is controlled by the faceColor property of the bundle’s renderProps. Being able to render the elements makes it easy to select the bundle and visualize which elements it contains.

6.8.1 Example: FEM sheet with a stiff spine

Figure 6.14: MaterialBundleDemo model after being run in ArtiSynth.

A simple model demonstrating the use of material bundles is defined in

  artisynth.demos.tutorial.MaterialBundleDemo

It consists of a simple thin hexahedral sheet in which a material bundle is used to stiffen elements close to the x-axis, creating a stiff “spine”. While the same effect could be achieved by simply setting a different material property for the “spine” elements, it does provide a good example of muscle bundle usage. The model’s build method is given below:

1    public void build (String[] args) {
2       MechModel mech = new MechModel ("mech");
3       addModel (mech);
4
5       // create a fem model consisting of a thin sheet of hexes
6       FemModel3d fem = FemFactory.createHexGrid (null, 1.0, 1.0, 0.1, 10, 10, 1);
7       fem.setDensity (1000);
8       fem.setMaterial (new LinearMaterial (10000, 0.45));
9       mech.add (fem);
10       // fix the left-most nodes:
11       double EPS = 1e-8;
12       for (FemNode3d n : fem.getNodes()) {
13          if (n.getPosition().x <= -0.5+EPS) {
14             n.setDynamic (false);
15          }
16       }
17       // create a "spine" of stiffer elements using a MaterialBundle with a
18       // stiffer material
19       MaterialBundle bun =
20          new MaterialBundle ("spine", new NeoHookeanMaterial (5e6, 0.45), false);
21       for (FemElement3d e : fem.getElements()) {
22          // use element centroid to determine which elements are on the "spine"
23          Point3d pos = new Point3d();
24          e.computeCentroid (pos);
25          if (Math.abs(pos.y) <= 0.1+EPS) {
26             bun.addElement (e);
27          }
28       }
29       fem.addMaterialBundle (bun);
30
31       // add a control panel to control both the fem and bundle materials,
32       // as well as the fem and bundle widget sizes
33       ControlPanel panel = new ControlPanel();
34       panel.addWidget ("fem material", fem, "material");
35       panel.addWidget ("fem widget size", fem, "elementWidgetSize");
36       panel.addWidget ("bundle material", bun, "material");
37       panel.addWidget ("bundle widget size", bun, "elementWidgetSize");
38       addControlPanel (panel);
39
40       // set rendering properties, using element widgets
41       RenderProps.setFaceColor (fem, new Color (0.7f, 0.7f, 1.0f));
42       RenderProps.setFaceColor (bun, new Color (0.7f, 1.0f, 0.7f));
43       bun.setElementWidgetSize (0.9);

Lines 6-9 create a thin FEM hex sheet, centered on the origin, with size 1\times 1\times 0.1 and 10\times 10\times 1 elements along each axis. Its material is set to a linear material with a Young’s modulus of 10000. The leftmost nodes are then fixed (lines 11-16).

Next, a MuscleBundle is added and used to apply an additional material to the elements near the x axis (lines 19-29). It is given a neo-hookean material with a much higher stiffness, and the “spine” elements for it are selected by finding those whose centroids have a y value within 0.1 of the x axis.

After the bundle is added, a control panel is created allowing interactive control of the materials for both the FEM model and the bundle, along with their elementWidgetSize properties.

Finally, some render properties are set (lines 41-44). The idea is to render the elements of both the FEM model and the bundle using element widgets (both of which will be visible since there is no surface rendering and the element widget sizes for both are greater than 0). The widget size for the bundle is made larger than that of the FEM model to ensure its widgets will cover those of the latter. Widget colors are controlled by the FEM and bundle face colors, set in lines 41-42.

The example can be run in ArtiSynth by selecting All demos > tutorial > MaterialBundleDemo from the Models menu. When it is run, the sheet will fall under gravity but be much stiffer along the spine (Figure 6.14). The control panel can be used to interactively adjust the material parameters for both the FEM and the bundle. This is one advantage of using bundles: the same material can be used to control multiple elements. The panel also allows interactive adjustment of the widget sizes, to illustrate what they look like and how they are rendered.