Program: 70883
Project: 70883
Buggy source:
/** 
 * Creates a combined hex/wedge fem model by extruding triangles into wedges and quads into hexes. If the mesh is the surface mesh of an underlying FemModel, then each triangle is examined to see if it is associated with an underlying hex element, and if it is, then a hex element is extruded from both the surface triangles connected to that element.
 * @param model Empty FEM model to which elements are added. If <code>null</code>,then a new FEM model will be created and returned. Note that <code>model</code> must be different from <code>surfaceFem</code>
 * @param n number of layers 
 * @param d layer thickness
 * @param surface surface mesh to extrude
 * @param surfaceFem FEM associated with the surface mesh, or <code>null</code> if there is associated FEM.
 * @return extruded FEM model, which will be <code>model</code> ifthat argument is not <code>null</code>.
 */
public static FemModel3d createHexWedgeExtrusion(FemModel3d model,int n,double d,PolygonalMesh surface,FemModel3d surfaceFem){
  if (model == null) {
    model=new FemModel3d();
  }
 else   if (model == surfaceFem) {
    throw new IllegalArgumentException("String_Node_Str");
  }
 else {
    model.clear();
  }
  for (  Vertex3d v : surface.getVertices()) {
    FemNode3d node=new FemNode3d(v.pnt);
    model.addNode(node);
  }
  boolean[] marked=new boolean[surface.numFaces()];
  Point3d newpnt=new Point3d();
  Vector3d nrm=new Vector3d();
  for (int l=0; l < n; l++) {
    for (    Vertex3d v : surface.getVertices()) {
      v.computeAngleWeightedNormal(nrm);
      newpnt.scaledAdd((l + 1) * d,nrm,v.pnt);
      model.addNode(new FemNode3d(newpnt));
    }
    int numSurfVtxs=surface.numVertices();
    for (int i=0; i < surface.numFaces(); i++) {
      if (!marked[i]) {
        Face f=surface.getFaces().get(i);
        int numv=f.numVertices();
        if (numv != 3 && numv != 4) {
          throw new IllegalArgumentException("String_Node_Str");
        }
        int[] vertexIndices=null;
        FemNode3d quadNode=null;
        if (surfaceFem != null) {
          FemElement3d elem=surfaceFem.getSurfaceElement(f);
          if (elem != null && numv == 3) {
            quadNode=getQuadFaceNode(f,elem,surfaceFem);
          }
        }
        if (quadNode != null) {
          vertexIndices=new int[4];
          HalfEdge he=f.firstHalfEdge();
          int k=0;
          for (int j=0; j < 3; j++) {
            vertexIndices[k++]=he.tail.getIndex();
            Vertex3d vop=he.opposite.getNext().head;
            if (surfaceFem.getSurfaceNode(vop) == quadNode) {
              vertexIndices[k++]=vop.getIndex();
              marked[he.opposite.getFace().getIndex()]=true;
            }
            he=he.getNext();
          }
        }
 else {
          vertexIndices=f.getVertexIndices();
        }
        FemElement3d e;
        if (vertexIndices.length == 3) {
          FemNode3d[] nodes=new FemNode3d[6];
          for (int j=0; j < 3; j++) {
            int idx=vertexIndices[j];
            nodes[j]=model.getNode(idx + l * numSurfVtxs);
            nodes[j + 3]=model.getNode(idx + (l + 1) * numSurfVtxs);
          }
          e=new WedgeElement(nodes);
        }
 else {
          FemNode3d[] nodes=new FemNode3d[8];
          for (int j=0; j < 4; j++) {
            int idx=vertexIndices[j];
            nodes[j]=model.getNode(idx + (l + 1) * numSurfVtxs);
            nodes[j + 4]=model.getNode(idx + l * numSurfVtxs);
          }
          e=new HexElement(nodes);
        }
        model.addElement(e);
        marked[f.getIndex()]=true;
      }
    }
  }
  return model;
}

Fixed version (ground truth):
/** 
 * Creates a combined hex/wedge fem model by extruding triangles into wedges and quads into hexes. If the mesh is the surface mesh of an underlying FemModel, then each triangle is examined to see if it is associated with an underlying hex element, and if it is, then a hex element is extruded from both the surface triangles connected to that element.
 * @param model Empty FEM model to which elements are added. If <code>null</code>,then a new FEM model will be created and returned. Note that <code>model</code> must be different from <code>surfaceFem</code>
 * @param n number of layers 
 * @param d layer thickness
 * @param surface surface mesh to extrude
 * @param surfaceFem FEM associated with the surface mesh, or <code>null</code> if there is associated FEM.
 * @return extruded FEM model, which will be <code>model</code> ifthat argument is not <code>null</code>.
 */
public static FemModel3d createHexWedgeExtrusion(FemModel3d model,int n,double d,PolygonalMesh surface,FemModel3d surfaceFem){
  if (model == null) {
    model=new FemModel3d();
  }
 else   if (model == surfaceFem) {
    throw new IllegalArgumentException("String_Node_Str");
  }
 else {
    model.clear();
  }
  for (  Vertex3d v : surface.getVertices()) {
    FemNode3d node=new FemNode3d(v.pnt);
    model.addNode(node);
  }
  Point3d newpnt=new Point3d();
  Vector3d nrm=new Vector3d();
  for (int l=0; l < n; l++) {
    boolean[] marked=new boolean[surface.numFaces()];
    for (    Vertex3d v : surface.getVertices()) {
      v.computeAngleWeightedNormal(nrm);
      newpnt.scaledAdd((l + 1) * d,nrm,v.pnt);
      model.addNode(new FemNode3d(newpnt));
    }
    int numSurfVtxs=surface.numVertices();
    for (int i=0; i < surface.numFaces(); i++) {
      if (!marked[i]) {
        Face f=surface.getFaces().get(i);
        int numv=f.numVertices();
        if (numv != 3 && numv != 4) {
          throw new IllegalArgumentException("String_Node_Str");
        }
        int[] vertexIndices=null;
        FemNode3d quadNode=null;
        if (surfaceFem != null) {
          FemElement3d elem=surfaceFem.getSurfaceElement(f);
          if (elem != null && numv == 3) {
            quadNode=getQuadFaceNode(f,elem,surfaceFem);
          }
        }
        if (quadNode != null) {
          vertexIndices=new int[4];
          HalfEdge he=f.firstHalfEdge();
          int k=0;
          for (int j=0; j < 3; j++) {
            vertexIndices[k++]=he.tail.getIndex();
            Vertex3d vop=he.opposite.getNext().head;
            if (surfaceFem.getSurfaceNode(vop) == quadNode) {
              vertexIndices[k++]=vop.getIndex();
              marked[he.opposite.getFace().getIndex()]=true;
            }
            he=he.getNext();
          }
        }
 else {
          vertexIndices=f.getVertexIndices();
        }
        FemElement3d e;
        if (vertexIndices.length == 3) {
          FemNode3d[] nodes=new FemNode3d[6];
          for (int j=0; j < 3; j++) {
            int idx=vertexIndices[j];
            nodes[j]=model.getNode(idx + l * numSurfVtxs);
            nodes[j + 3]=model.getNode(idx + (l + 1) * numSurfVtxs);
          }
          e=new WedgeElement(nodes);
        }
 else {
          FemNode3d[] nodes=new FemNode3d[8];
          for (int j=0; j < 4; j++) {
            int idx=vertexIndices[j];
            nodes[j]=model.getNode(idx + (l + 1) * numSurfVtxs);
            nodes[j + 4]=model.getNode(idx + l * numSurfVtxs);
          }
          e=new HexElement(nodes);
        }
        model.addElement(e);
        marked[f.getIndex()]=true;
      }
    }
  }
  return model;
}