Finite Element Analysis - element connectivities


#1

Hi there,
I would like to build a small finite element code for linear elasticity problems into Rhino interface. In usual formulation of FEM, the finite elements (poly/lines, mesh faces) are connected in nodes and form so called connectivity matrix. This matrix tells us which element is connected to which node.

Every mesh or line objects in Rhino have their own ID and their own numbering system and therefore they are not consistent and do not fit to usual finite element procedures.

I am looking for an idea how to build a “numbering system”, which will join all mesh vertices and all poly/line points in one global numbering system and extract a global connectivity information.

Any suggestions ? :slight_smile:

Thanks !


#2

Only that you might consider implementing something like Math.Net Numerics for all the matrix operations and such: https://numerics.mathdotnet.com/


#3

Thanks for your suggestion. But first, I would like to collect the information about the connectivity of all the elements in workspace into one unified system…


#4

Peter,

in Concha we did something similar like the following using RhinoCommon (C#):

public static double[] GetCoordinates( Rhino.Geometry.Mesh mesh )
{
   const int dimWorld = 3;
   var vertices = mesh.Vertices;
   Rhino.Geometry.Point3d[] nodes = vertices.ToPoint3dArray();
   var coords = new double[ nodes.Length * dimWorld ];

   int ctr = 0;
   foreach( var node in nodes )
   {
       coords[ ctr++ ] = node.X;
       coords[ ctr++ ] = node.Y;
       coords[ ctr++ ] = node.Z;
   }
   return coords;
}

The element connectivity you can get by iterating over the faces:

public static int[] GetIncidencies( Rhino.Geometry.Mesh mesh )
{
 var elements = mesh.Faces;
 // count incidencies
 int numIncidencies = 0;
 foreach( var element in elements )
 {
   if( element.IsTria )
     numIncidencies += 3;
   else
     numIncidencies += 4;
 }

 // parse connectivity / incidencies
 int[] incidencies = new int[ numIncidencies ];
 int ctr = 0;
 foreach( var element in elements )
 {
   incidencies[ ctr++ ] = element.A;
   incidencies[ ctr++ ] = element.B;
   incidencies[ ctr++ ] = element.C;
   if( element.IsQuad )
     incidencies[ ctr++ ] = element.D;
 }

 return incidencies;
}

With element.A, element.B and so on you get the zero-based index of the node in the vertex list mesh.Vertices .

Does that help?
Juergen


#5

Dear Juergen,

thank you for your detailed description. It gave me an idea.
But, if I read your code correctly, when you read multiple meshes
(connected to each other at least in one node), and loop over all faces in
those meshes - it will return duplicate nodes, doesnt it ?
How do you prevent that ?


#6

I mean, in the first part of your code. The loop over all mesh vertices of two individual meshes connected in at least one node (vertex) will give you twice the same node. Am I right ?


#7

Hi Peter,

No. The meshes do not know anything about each other. What you could do, is join them:

      wholeMesh.Append( mesh1 );
      wholeMesh.Append( mesh2 );
      wholeMesh.Compact();

      // just to get sure to get an analysis-suitable mesh we use:
      wholeMesh.Faces.CullDegenerateFaces();

Juergen


#8

Thanks Juergen,

does Concha offer also connected beam elements or shell stiffeners ?


#9

No, sorry. We had that in mind, but dismissed that feature.


#10

That´s OK. Anyway, thank you for discussion, you have helped me move forward !