Search in sources :

Example 6 with FemNode3d

use of artisynth.core.femmodels.FemNode3d in project artisynth_core by artisynth.

the class MFreeElement3d method computeCentroid.

public void computeCentroid(Vector3d centroid) {
    if (myBoundaryMesh != null) {
        myBoundaryMesh.computeCentroid(centroid);
    } else {
        // based on integration points
        if (myIntegrationPoints.size() > 0) {
            centroid.setZero();
            for (MFreeIntegrationPoint3d ipnt : myIntegrationPoints) {
                centroid.add(ipnt.getPosition());
            }
            centroid.scale(1.0 / myIntegrationPoints.size());
        } else {
            centroid.setZero();
            for (FemNode3d node : myNodes) {
                centroid.add(((MFreeNode3d) node).getTruePosition());
            }
            centroid.scale(1.0 / myNodes.length);
        }
    }
}
Also used : FemNode3d(artisynth.core.femmodels.FemNode3d)

Example 7 with FemNode3d

use of artisynth.core.femmodels.FemNode3d in project artisynth_core by artisynth.

the class MFreeFactory method cloneFem.

public static MFreeModel3d cloneFem(MFreeModel3d model, FemModel3d fem) {
    if (model == null) {
        model = new MFreeModel3d();
    }
    HashMap<FemNode3d, MFreeNode3d> nodeMap = new HashMap<FemNode3d, MFreeNode3d>();
    HashMap<MFreeNode3d, FemNode3d> nodeMapInv = new HashMap<MFreeNode3d, FemNode3d>();
    ArrayList<MFreeNode3d> nodeList = new ArrayList<MFreeNode3d>();
    // duplicate nodes
    for (FemNode3d node : fem.getNodes()) {
        MFreeNode3d mnode = new MFreeNode3d(node.getRestPosition());
        // explicit node masses
        mnode.setMassExplicit(true);
        mnode.setMass(node.getMass());
        MFreeNode3d[] deps = new MFreeNode3d[1];
        deps[0] = mnode;
        VectorNd coords = new VectorNd(new double[] { 1 });
        mnode.setDependentNodes(deps, coords);
        nodeMap.put(node, mnode);
        nodeMapInv.put(mnode, node);
        nodeList.add(mnode);
    }
    // convert surface mesh
    FemMeshComp surfaceFem = fem.getSurfaceMeshComp();
    PolygonalMesh mesh = (PolygonalMesh) surfaceFem.getMesh();
    // build mesh
    PolygonalMesh mesh2 = mesh.copy();
    // index vertices
    int idx = 0;
    for (Vertex3d vtx : mesh.getVertices()) {
        vtx.setIndex(idx++);
    }
    idx = 0;
    for (Vertex3d vtx : mesh2.getVertices()) {
        vtx.setIndex(idx++);
    }
    MFreeMeshComp surfaceMFree = new MFreeMeshComp(model, "surface");
    surfaceMFree.setMesh(mesh2);
    // manually build surface attachments
    for (Vertex3d vtx : mesh.getVertices()) {
        PointAttachment pa = surfaceFem.getAttachment(vtx.getIndex());
        if (pa instanceof PointFem3dAttachment) {
            PointFem3dAttachment pfa = (PointFem3dAttachment) pa;
            FemNode[] masters = pfa.getNodes();
            MFreeNode3d[] deps = new MFreeNode3d[masters.length];
            VectorNd coords = new VectorNd(masters.length);
            for (int j = 0; j < masters.length; j++) {
                // mlist.add (new ContactMaster (masters[j], pfa.getCoordinate(j)));
                deps[j] = nodeMap.get(masters[j]);
                coords.set(j, pfa.getCoordinate(j));
            }
            surfaceMFree.setVertexAttachment(vtx.getIndex(), coords.getBuffer(), deps);
        } else {
            PointParticleAttachment ppa = (PointParticleAttachment) pa;
            DynamicComponent[] masters = ppa.getMasters();
            MFreeNode3d[] deps = new MFreeNode3d[1];
            deps[0] = nodeMap.get(masters[0]);
            VectorNd coords = new VectorNd(new double[] { 1 });
            surfaceMFree.setVertexAttachment(vtx.getIndex(), coords.getBuffer(), deps);
        }
    }
    // integration regions by copying elements
    ArrayList<MFreeElement3d> elemList = new ArrayList<MFreeElement3d>(fem.numElements());
    HashMap<FemElement3d, MFreeElement3d> elemMap = new HashMap<FemElement3d, MFreeElement3d>(fem.numElements());
    for (FemElement3d elem : fem.getElements()) {
        MFreeNode3d[] elemNodes = new MFreeNode3d[elem.numNodes()];
        FemNode3d[] fnodes = elem.getNodes();
        for (int i = 0; i < elem.numNodes(); i++) {
            elemNodes[i] = nodeMap.get(fnodes[i]);
        }
        MFreeElement3d region = new MFreeElement3d(null, elemNodes);
        // region.setAllTermsActive(true);
        MFreeIntegrationPoint3d[] mpnts = new MFreeIntegrationPoint3d[elem.numIntegrationPoints()];
        IntegrationData3d[] mdata = new IntegrationData3d[elem.numIntegrationPoints()];
        IntegrationPoint3d[] ipnts = elem.getIntegrationPoints();
        IntegrationData3d[] idata = elem.getIntegrationData();
        for (int i = 0; i < ipnts.length; i++) {
            Point3d pos = new Point3d();
            ipnts[i].computePosition(pos, elem.getNodes());
            Vector3d[] gradU = ipnts[i].getGNs();
            ArrayList<Vector3d> grads = new ArrayList<Vector3d>();
            for (Vector3d g : gradU) {
                grads.add(g);
            }
            MFreeIntegrationPoint3d mpnt = MFreeIntegrationPoint3d.create(elemNodes, ipnts[i].getShapeWeights(), grads, ipnts[i].getWeight());
            IntegrationData3d mdat = new IntegrationData3d();
            mdat.setRestInverseJacobian(idata[i].getInvJ0(), idata[i].getDetJ0());
            mpnts[i] = mpnt;
            mdata[i] = mdat;
        }
        // set warping point
        if (region.getWarpingPoint() == null) {
            IntegrationPoint3d wpnt = elem.getWarpingPoint();
            IntegrationData3d wdat = elem.getWarpingData();
            Point3d pos = new Point3d();
            wpnt.computePosition(pos, elem.getNodes());
            // Vector3d [] gradU = wpnt.updateShapeGradient(wdat.getInvJ0());
            Vector3d[] gradU = wpnt.getGNs();
            ArrayList<Vector3d> grads = new ArrayList<Vector3d>();
            for (Vector3d g : gradU) {
                grads.add(g);
            }
            // MFreeIntegrationPoint3d mpnt =
            // MFreeIntegrationPoint3d.create(pos, deps,
            // wpnt.getShapeWeights(), grads, wpnt.getWeight()*wdat.getDetJ0());
            MFreeIntegrationPoint3d mpnt = MFreeIntegrationPoint3d.create(elemNodes, wpnt.getShapeWeights(), grads, wpnt.getWeight());
            region.setWarpingPoint(mpnt);
            IntegrationData3d wdata = new IntegrationData3d();
            wdata.setRestInverseJacobian(wdat.getInvJ0(), wdat.getDetJ0());
            region.setWarpingPoint(mpnt, wdata);
        }
        region.setIntegrationPoints(mpnts, mdata);
        elemList.add(region);
        elemMap.put(elem, region);
    }
    // add everything to model
    model.addNodes(nodeList);
    model.addElements(elemList);
    model.setSurfaceMeshComp(surfaceMFree);
    // copy properties
    model.setDensity(fem.getDensity());
    model.setParticleDamping(fem.getParticleDamping());
    model.setStiffnessDamping(fem.getStiffnessDamping());
    // copy over all masses
    for (FemNode3d node : fem.getNodes()) {
        nodeMap.get(node).setMass(node.getMass());
    }
    for (FemElement3d elem : fem.getElements()) {
        elemMap.get(elem).setMass(elem.getMass());
    }
    model.setMaterial(fem.getMaterial());
    return model;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) PointAttachment(artisynth.core.mechmodels.PointAttachment) IntegrationData3d(artisynth.core.femmodels.IntegrationData3d) PolygonalMesh(maspack.geometry.PolygonalMesh) Point3d(maspack.matrix.Point3d) IntegrationPoint3d(artisynth.core.femmodels.IntegrationPoint3d) FemNode3d(artisynth.core.femmodels.FemNode3d) DynamicComponent(artisynth.core.mechmodels.DynamicComponent) FemNode(artisynth.core.femmodels.FemNode) FemElement3d(artisynth.core.femmodels.FemElement3d) FemMeshComp(artisynth.core.femmodels.FemMeshComp) IntegrationPoint3d(artisynth.core.femmodels.IntegrationPoint3d) Vector3d(maspack.matrix.Vector3d) VectorNd(maspack.matrix.VectorNd) PointFem3dAttachment(artisynth.core.femmodels.PointFem3dAttachment) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment)

Example 8 with FemNode3d

use of artisynth.core.femmodels.FemNode3d in project artisynth_core by artisynth.

the class MFreeMeshComp method createEmbedded.

/**
 * Assumes the mesh is in "rest" coordinates, not current coordinates
 * @param surf mfree surface to populate (or null to create one)
 * @param mesh mesh to embed
 * @param mfree model to embed mesh in
 * @return populated or created mesh
 */
public static MFreeMeshComp createEmbedded(MFreeMeshComp surf, MeshBase mesh, MFreeModel3d mfree) {
    double reduceTol = 1e-8;
    ArrayList<MFreeNode3d> nodes = new ArrayList<MFreeNode3d>();
    VectorNd weights = new VectorNd();
    if (surf == null) {
        surf = new MFreeMeshComp(mfree);
    }
    surf.setMesh(mesh);
    ArrayList<Vertex3d> verts = mesh.getVertices();
    Point3d coords = new Point3d();
    ArrayList<FemNode3d> deps = new ArrayList<>();
    MLSShapeFunction sfunc = new MLSShapeFunction();
    surf.myVertexAttachments.clear();
    for (int i = 0; i < verts.size(); i++) {
        // this could works very similarly to the code that adds
        // marker points into a mesh
        Vertex3d vtx = verts.get(i);
        deps.clear();
        mfree.findDependentNodesAtRest(vtx.pnt, deps);
        // compute shape function
        VectorNd N = new VectorNd(deps.size());
        MFreeNode3d[] dnodes = deps.toArray(new MFreeNode3d[deps.size()]);
        sfunc.update(vtx.pnt, dnodes);
        sfunc.eval(N);
        // first see if there's a node within reduceTol of the point,
        // and if so just use that
        double maxDist = Double.NEGATIVE_INFINITY;
        double minDist = Double.POSITIVE_INFINITY;
        MFreeNode3d nearestNode = null;
        for (int k = 0; k < dnodes.length; k++) {
            double d = vtx.pnt.distance(dnodes[k].getRestPosition());
            if (d > maxDist) {
                maxDist = d;
            }
            if (d < minDist) {
                minDist = d;
                nearestNode = dnodes[k];
            }
        }
        if (minDist / maxDist <= reduceTol) {
            // weight everything to the nearest node
            nodes.clear();
            nodes.add(nearestNode);
            weights.setSize(0);
            weights.append(1.0);
        } else {
            nodes.clear();
            weights.setSize(0);
            for (int k = 0; k < N.size(); k++) {
                if (Math.abs(N.get(k)) >= reduceTol) {
                    nodes.add(dnodes[k]);
                    weights.append(N.get(k));
                }
            }
        }
        if (weights.size() > 1) {
            PointFem3dAttachment attacher = new PointFem3dAttachment();
            attacher.setFromNodes(nodes, weights);
            surf.myVertexAttachments.add(attacher);
        } else if (weights.size() == 1) {
            PointParticleAttachment attacher = new PointParticleAttachment(nodes.get(0), null);
            surf.myVertexAttachments.add(attacher);
        }
    }
    surf.buildNodeVertexMap();
    return surf;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) ArrayList(java.util.ArrayList) ContactPoint(artisynth.core.mechmodels.ContactPoint) Point(artisynth.core.mechmodels.Point) Point3d(maspack.matrix.Point3d) VectorNd(maspack.matrix.VectorNd) FemNode3d(artisynth.core.femmodels.FemNode3d) PointFem3dAttachment(artisynth.core.femmodels.PointFem3dAttachment) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment)

Example 9 with FemNode3d

use of artisynth.core.femmodels.FemNode3d in project artisynth_core by artisynth.

the class MFreeModel3d method updateNodeMasses.

public void updateNodeMasses(double totalMass, VectorNd massMatrixDiag) {
    if (totalMass <= 0) {
        totalMass = integrateMass();
    }
    if (massMatrixDiag == null) {
        SparseMatrixNd massMatrix = computeConsistentMassMatrix();
        massMatrixDiag = new VectorNd(massMatrix.rowSize());
        for (int i = 0; i < massMatrix.rowSize(); i++) {
            double rowSum = 0;
            for (int j = 0; j < massMatrix.colSize(); j++) {
                rowSum += massMatrix.get(i, j);
            }
            // rowSum += massMatrix.get(i, i);
            massMatrixDiag.set(i, rowSum);
        }
    }
    double mTrace = massMatrixDiag.sum();
    for (FemNode3d node : myNodes) {
        int i = node.getNumber();
        double m = totalMass / mTrace * massMatrixDiag.get(i);
        node.setMass(m);
        node.setMassExplicit(true);
    }
}
Also used : SparseMatrixNd(maspack.matrix.SparseMatrixNd) VectorNd(maspack.matrix.VectorNd) FemNode3d(artisynth.core.femmodels.FemNode3d) Point(artisynth.core.mechmodels.Point)

Example 10 with FemNode3d

use of artisynth.core.femmodels.FemNode3d in project artisynth_core by artisynth.

the class MFreeModel3d method buildRestNodeTree.

private static AABBTree buildRestNodeTree(Collection<FemNode3d> nodes) {
    AABBTree nodeTree = new AABBTree();
    RestNode[] rnodes = new RestNode[nodes.size()];
    int idx = 0;
    for (FemNode3d node : nodes) {
        rnodes[idx] = new RestNode(node, ((MFreeNode3d) node).getInfluenceRadius());
        ++idx;
    }
    nodeTree.build(rnodes, rnodes.length);
    return nodeTree;
}
Also used : AABBTree(maspack.geometry.AABBTree) FemNode3d(artisynth.core.femmodels.FemNode3d) Point(artisynth.core.mechmodels.Point)

Aggregations

FemNode3d (artisynth.core.femmodels.FemNode3d)38 FemModel3d (artisynth.core.femmodels.FemModel3d)12 Point3d (maspack.matrix.Point3d)12 RigidTransform3d (maspack.matrix.RigidTransform3d)9 FemElement3d (artisynth.core.femmodels.FemElement3d)8 MechModel (artisynth.core.mechmodels.MechModel)8 Point (artisynth.core.mechmodels.Point)7 RigidBody (artisynth.core.mechmodels.RigidBody)7 Vector3d (maspack.matrix.Vector3d)6 ArrayList (java.util.ArrayList)5 FemMarker (artisynth.core.femmodels.FemMarker)4 IntegrationPoint3d (artisynth.core.femmodels.IntegrationPoint3d)4 VectorNd (maspack.matrix.VectorNd)4 TetElement (artisynth.core.femmodels.TetElement)3 RevoluteJoint (artisynth.core.mechmodels.RevoluteJoint)3 LinkedList (java.util.LinkedList)3 FemNode (artisynth.core.femmodels.FemNode)2 HexElement (artisynth.core.femmodels.HexElement)2 PointFem3dAttachment (artisynth.core.femmodels.PointFem3dAttachment)2 PyramidElement (artisynth.core.femmodels.PyramidElement)2