コード例 #1
0
        public void SetReferences(FeModel modell)
        {
            for (int i = 0; i < NodesPerElement; i++)
            {
                if (modell.Knoten.TryGetValue(NodeIds[i], out Node node))
                {
                    Nodes[i] = node;
                }

                if (node != null)
                {
                    continue;
                }
                var message = "Element mit ID = " + NodeIds[i] + " ist nicht im Modell enthalten";
                _ = MessageBox.Show(message, "AbstractElement");
            }
            if (modell.Material.TryGetValue(ElementMaterialId, out AbstractMaterial material))
            {
                ElementMaterial = material;
            }
            if (material == null)
            {
                var message = "Material mit ID=" + ElementMaterialId + " ist nicht im Modell enthalten";
                _ = MessageBox.Show(message, "AbstractElement");
            }
        }
コード例 #2
0
        public SurfaceGeometry(FeModel f)
        {
            SurfaceGeometry.fem = f;
            listFaces           = new List <int[]>();
            listEdges           = new List <int[]>();
            listSurfaceElement  = new List <int>();
            listSharedFaces     = new List <int[]>();

            sNodes = new int[fem.nNod];

            // Create element faces located at the surface
            createFaces();
            nFaces    = listFaces.Count;
            nElements = listSurfaceElement.Count;
            // Create element edges located at the surface
            createEdges();
            nEdges = listEdges.Count();


            // Create nodes located at the surface
            createNodes();

            //if (VisData.drawContours)
            {
                //fun = new double[fem.nNod];
                //ResultAtNodes ran = new ResultAtNodes(this, fem);
                //ran.setParmAtNodes(VisData.parm, VisData.displ);
            }

            //modifyNodeCoordinates();
        }
コード例 #3
0
        public static Solver newSolver(FeModel fem)
        {
            Solver.fem = fem;
            neq        = fem.nEq;

            return(create());
        }
コード例 #4
0
 public void Create2(ID id, FeModel item)
 {
     using (StreamWriter sw = new StreamWriter($"{id}.stl"))
     {
         Save2(sw, id, item);
     }
 }
コード例 #5
0
        private FeModel copyMesh()
        {
            FeModel mB = new FeModel(CSMGEN.RD, CSMGEN.PR);

            mB.nDim = mA.nDim;

            mB.nNod = mA.nNod;
            mB.newCoordArray();
            for (int i = 0; i < mB.nNod; i++)
            {
                for (int j = 0; j < mB.nDim; j++)
                {
                    mB.setNodeCoords(i, mA.getNodeCoords(i));
                }
            }

            mB.nEl   = mA.nEl;
            mB.elems = new Element[mB.nEl];
            for (int el = 0; el < mB.nEl; el++)
            {
                mB.elems[el] = Element.newElement(mA.elems[el].name);
                mB.elems[el].setElemConnectivities(mA.elems[el].ind);
                mB.elems[el].matName = mA.elems[el].matName;
            }

            return(mB);
        }
コード例 #6
0
ファイル: FEParser.cs プロジェクト: KarlBeucke/FE
        // parsing a new model to be read from file
        public void ParseModel(string[] lines)
        {
            for (var i = 0; i < lines.Length; i++)
            {
                InputFound = "";
                if (lines[i] != "ModellName")
                {
                    continue;
                }
                ModelId    = lines[i + 1];
                InputFound = "ModellName = " + ModelId;
                break;
            }

            for (var i = 0; i < lines.Length; i++)
            {
                if (lines[i] != "Raumdimension")
                {
                    continue;
                }
                InputFound      += "\nRaumdimension";
                substrings       = lines[i + 1].Split(delimiters);
                SpatialDimension = int.Parse(substrings[0]);
                numberNodalDof   = int.Parse(substrings[1]);
                break;
            }
            FeModell = new FeModel(SpatialDimension);
        }
コード例 #7
0
ファイル: FeResultLocation.cs プロジェクト: scudelari/EMASA
        public static FeResultLocation CreateSectionNodeLocation([NotNull] FeModel inModel, [NotNull] FeMeshBeamElement inBeam, [NotNull] FeMeshNode inNode, [NotNull] FeMeshNode_SectionNode inSectionNode)
        {
            if (inModel == null)
            {
                throw new ArgumentNullException(nameof(inModel));
            }
            if (inNode == null)
            {
                throw new ArgumentNullException(nameof(inNode));
            }
            if (inBeam == null)
            {
                throw new ArgumentNullException(nameof(inBeam));
            }
            if (inSectionNode == null)
            {
                throw new ArgumentNullException(nameof(inSectionNode));
            }

            return(new FeResultLocation()
            {
                Model = inModel,
                MeshNode = inNode,
                MeshBeam = inBeam,
                SectionNode = inSectionNode
            });
        }
コード例 #8
0
        public sweep20()
        {
            String modelName2 = CSMGEN.RD.next();
            String modelName3 = CSMGEN.RD.next();

            CSMGEN.PR.Write("Sweep20: {0} {1}\n", modelName2, modelName3);
            readData();
            printData();

            if (CSMGEN.blocks.ContainsKey(modelName2))
            {
                m2 = (FeModel)CSMGEN.blocks[modelName2];
            }
            else
            {
                UTIL.errorMsg("No such mesh block: " + modelName2);
            }


            m3      = new FeModel(CSMGEN.RD, CSMGEN.PR);
            m3.nDim = 3;
            m3.nEl  = m2.nEl * nlayers;
            m3.nNod = nodeTypesNumbers2D();
            elementConnectivities3D();
            nodeCoordinates3D();

            CSMGEN.blocks.Add(modelName3, m3);
            CSMGEN.PR.Write("Mesh " + modelName3 + ": nEl = {0}  nNod = {1}\n", m3.nEl, m3.nNod);
        }
コード例 #9
0
 public StaticMechanicSparseSolution(ISolve <SparseMatrix> solver, FeModel model)
 {
     this.solver  = solver;
     globalMatrix = solver.GlobalMatrix;
     length       = model.Nodes.Count * DEGREES_OF_FREEDOM;
     loads        = new double[length];
     results      = new double[length];
 }
コード例 #10
0
        /// <summary>
        /// Generation finite element model
        /// </summary>
        /// <param name="path">Path to directory with DICOM data</param>
        /// <param name="step">Step of the mesh</param>
        public ModelGeneration(string path, int step = 10)
        {
            this.step = step;
            this.path = path;
            //repository = new ObjRepository<string>();
            repository = new XyzRepository <string>();

            Model = Generation();
        }
コード例 #11
0
        public writemesh()
        {
            String modelName = CSMGEN.RD.next();
            String fileName  = CSMGEN.RD.next();

            CSMGEN.PR.Write("WriteMesh: {0}    {1}\n", modelName, fileName);

            StreamWriter WR = new FePrintWriter().getPrinter(fileName);

            if (CSMGEN.blocks.ContainsKey(modelName))
            {
                m = (FeModel)CSMGEN.blocks[modelName];
            }
            else
            {
                UTIL.errorMsg("No such mesh block: " + modelName);
            }

            WR.Write("# Model name: {0}\n", modelName);
            WR.Write("nNod = {0,5}\n", m.nNod);
            WR.Write("nEl = {0,5}\n", m.nEl);
            WR.Write("nDim = {0,5}\n", m.nDim);

            WR.Write("nodCoord\n");
            for (int i = 0; i < m.nNod; i++)
            {
                for (int j = 0; j < m.nDim; j++)
                {
                    WR.Write("{0,20:0.000000000}", m.getNodeCoord(i, j));
                }
                WR.WriteLine("");
            }

            WR.Write("\nelCon");
            for (int iel = 0; iel < m.nEl; iel++)
            {
                WR.Write("\n{0} {1,6}", m.elems[iel].name, m.elems[iel].matName);
                if (m.elems[iel].name.Equals("quad4") || m.elems[iel].name.Equals("quad8r")) //|| m.elems[iel].name.Equals("genquad4") || m.elems[iel].name.Equals("genquad8"))
                {
                    WR.Write("{0,6}", m.elems[iel].t);
                }
                if (m.elems[iel].name.Equals("truss22") || m.elems[iel].name.Equals("truss32"))//|| m.elems[iel].name.Equals("genquad4") || m.elems[iel].name.Equals("genquad8"))
                {
                    WR.Write("{0,12}", m.elems[iel].A);
                }
                int nind = m.elems[iel].ind.Length;
                for (int i = 0; i < nind; i++)
                {
                    WR.Write("{0,12}", m.elems[iel].ind[i]);
                }
            }
            WR.Write("\n\nend\n");
            WR.Close();
            CSMGEN.PR.Write("Mesh " + modelName + ": nEl = {0}  nNod = {1}\n", m.nEl, m.nNod);
        }
コード例 #12
0
ファイル: FeResultLocation.cs プロジェクト: scudelari/EMASA
        public static FeResultLocation CreateModelLocation([NotNull] FeModel inModel)
        {
            if (inModel == null)
            {
                throw new ArgumentNullException(nameof(inModel));
            }

            return(new FeResultLocation()
            {
                Model = inModel,
            });
        }
コード例 #13
0
        public genquad8()
        {
            String modelName = CSMGEN.RD.next();

            CSMGEN.PR.WriteLine("GenQuad8: {0}", modelName);
            readData();
            printData();
            m = new FeModel(CSMGEN.RD, CSMGEN.PR);
            generateMesh();
            //CSMGEN.blocks.put(modelName, m);
            CSMGEN.blocks.Add(modelName, m);
            CSMGEN.PR.WriteLine("Mesh " + modelName + ": nEl = {0}  nNod = {1}", m.nEl, m.nNod);
        }
コード例 #14
0
        public readmesh()
        {
            String modelName = CSMGEN.RD.next();
            String fileName  = CSMGEN.RD.next();

            CSMGEN.PR.WriteLine("ReadMesh:  {0}    {1}\n", modelName, fileName);
            FeScanner RD = new FeScanner(fileName);
            FeModel   m  = new FeModel(RD, CSMGEN.PR);

            m.readData();
            CSMGEN.blocks.Add(modelName, m);
            CSMGEN.PR.WriteLine("Mesh " + modelName + ": nEl = {0,9}  nNod = {1,9}\n", m.nEl, m.nNod);
        }
コード例 #15
0
        // Paste two meshes.
        // Nodes and elements of the first mesh
        // are first in the resulting mesh.
        // returns   resulting mesh after pasting.
        private FeModel pasteModels()
        {
            FeModel mC = new FeModel(CSMGEN.RD, CSMGEN.PR);

            mC.nDim = mA.nDim;

            // nodal coordinates of model mC
            mC.nNod = mA.nNod + mB.nNod - nConnected;
            mC.newCoordArray();
            // Copy nodes of model mA
            for (int i = 0; i < mA.nNod; i++)
            {
                mC.setNodeCoords(i, mA.getNodeCoords(i));
            }
            // Add nodes of model mB
            for (int i = 0; i < mB.nNod; i++)
            {
                mC.setNodeCoords(
                    newNodesB[i], mB.getNodeCoords(i));
            }

            // Element connectivities of model mC
            mC.nEl   = mA.nEl + mB.nEl;
            mC.elems = new Element[mC.nEl];
            // Copy elements of model mA
            for (int el = 0; el < mA.nEl; el++)
            {
                mC.elems[el] = Element.newElement(mA.elems[el].name);
                mC.elems[el].setElemConnectivities(mA.elems[el].ind);
                mC.elems[el].matName = mA.elems[el].matName;
                mC.elems[el].A       = mA.elems[el].A;
                mC.elems[el].t       = mA.elems[el].t;
                mC.elems[el].I       = mA.elems[el].I;
            }
            // Add elements of mB with renumbered connectivities
            for (int el = 0; el < mB.nEl; el++)
            {
                mC.elems[mA.nEl + el] = Element.newElement(mB.elems[el].name);
                int[] indel = new int[mB.elems[el].ind.Length];
                for (int i = 0; i < mB.elems[el].ind.Length; i++)
                {
                    indel[i] = newNodesB[mB.elems[el].ind[i] - 1] + 1;
                }
                mC.elems[mA.nEl + el].setElemConnectivities(indel);
                mC.elems[mA.nEl + el].matName = mB.elems[el].matName;
                mC.elems[mA.nEl + el].A       = mB.elems[el].A;
                mC.elems[mA.nEl + el].t       = mB.elems[el].t;
                mC.elems[mA.nEl + el].I       = mB.elems[el].I;
            }
            return(mC);
        }
コード例 #16
0
ファイル: Logic.cs プロジェクト: Desm0nt/AppMag_POZV_DESM0nt
        private FeModel GetGeneralModelFromScene(FeModel scene, List <List <Triangle> > vertebras)
        {
            FeModel            feModel      = null;
            List <Node>        nodes        = new List <Node>();
            List <Tetrahedron> tetrahedrons = new List <Tetrahedron>();

            scene.Tetrahedrons.AsParallel().ForAll(tetrahedron =>
            {
                if (IsInsideStlArea(vertebras, tetrahedron))
                {
                    tetrahedrons.Add(tetrahedron);
                }
            });
            scene.Nodes.ForEach(node =>
            {
                bool isHave = false;
                for (int i = 0; i < tetrahedrons.Count; i++)
                {
                    tetrahedrons[i].Nodes.ForEach(nd =>
                    {
                        if (nd.GlobalIndex == node.GlobalIndex)
                        {
                            nodes.Add(nd);
                            isHave = true;
                        }
                    });
                    if (isHave)
                    {
                        break;
                    }
                }
            });

            tetrahedrons.AsParallel().ForAll(tn =>
            {
                for (int i = 0; i < tn.Nodes.Count; i++)
                {
                    tn.Nodes[i] = nodes.FirstOrDefault(nd => nd.GlobalIndex == tn.Nodes[i].GlobalIndex);
                }
            });

            Parallel.For(0, nodes.Count, counter =>
            {
                nodes[counter].GlobalIndex = counter;
            });

            feModel = new FeModel(nodes, tetrahedrons);

            return(feModel);
        }
コード例 #17
0
        //public bool[] Restrained { get; set; }
        //public double[] Reactions { get; set; }

        public void SetReferences(FeModel modell)
        {
            if (modell.Knoten.TryGetValue(NodeId, out Node node))
            {
            }

            if (node != null)
            {
                return;
            }
            var message = "Knoten mit ID=" + NodeId + " ist nicht im Modell enthalten";

            _ = MessageBox.Show(message, "AbstractNodeLoad");
        }
コード例 #18
0
 // Constructor for results at nodes.
 // sg - geometry of model surface.
 public ResultAtNodes(FeModel fem)
 {
     //this.sg = sg;
     this.fem  = fem;
     multNod   = new int[fem.nNod];
     stressNod = new double[fem.nNod][];// 2*fem.nDim];
     for (int i = 0; i < fem.nNod; i++)
     {
         stressNod[i] = new double[2 * fem.nDim];
     }
     sgsNodes = new int[fem.nNod];
     sgfun    = new double[fem.nNod];
     feStressAtNodes();
 }
コード例 #19
0
ファイル: FeResultLocation.cs プロジェクト: scudelari/EMASA
        public static FeResultLocation CreateMeshNodeLocation([NotNull] FeModel inModel, [NotNull] FeMeshNode inNode)
        {
            if (inModel == null)
            {
                throw new ArgumentNullException(nameof(inModel));
            }
            if (inNode == null)
            {
                throw new ArgumentNullException(nameof(inNode));
            }

            return(new FeResultLocation()
            {
                Model = inModel,
                MeshNode = inNode
            });
        }
コード例 #20
0
ファイル: FeResultLocation.cs プロジェクト: scudelari/EMASA
        public static FeResultLocation CreateElementLocation([NotNull] FeModel inModel, [NotNull] FeMeshBeamElement inBeam)
        {
            if (inModel == null)
            {
                throw new ArgumentNullException(nameof(inModel));
            }
            if (inBeam == null)
            {
                throw new ArgumentNullException(nameof(inBeam));
            }

            return(new FeResultLocation()
            {
                Model = inModel,
                MeshBeam = inBeam,
            });
        }
コード例 #21
0
 public void SetCrossSectionReferences(FeModel modell)
 {
     // Elementquerschnitt für 2D Elemente
     if (ElementCrossSectionId == null)
     {
         return;
     }
     if (modell.Querschnitt.TryGetValue(ElementCrossSectionId, out var crossSection))
     {
         ElementCrossSection = crossSection;
     }
     else
     {
         var querschnitt = MessageBox.Show("Querschnitt " + ElementCrossSectionId + " ist nicht im Modell enthalten.", "Abstract2D");
         _ = querschnitt;
     }
 }
コード例 #22
0
ファイル: Logic.cs プロジェクト: Desm0nt/AppMag_POZV_DESM0nt
        private FeModel GenerateTetrahedralModel(double width, double height, double stepWidth, double stepHeight, int materialId)
        {
            IScene scene = new TetrahedralScene(width, height, stepWidth, stepHeight);

            scene.Initialize();

            FeModel feModel = new FeModel(scene.Nodes, new List <Triangle>(), scene.Tetrahedrons);

            foreach (var node in feModel.Nodes)
            {
                node.IdMaterial = materialId;
            }
            feModel.Tetrahedrons.AsParallel().ForAll(tn =>
            {
                tn.Nodes.ForEach(node => node.IdMaterial = materialId);
            });
            return(feModel);
        }
コード例 #23
0
        //public double[] Reactions { get; set; }

        public void SetReferences(FeModel modell)
        {
            if (NodeId != null)
            {
                if (modell.Knoten.TryGetValue(NodeId, out Node node))
                {
                    Node = node;
                }

                if (node == null)
                {
                    throw new ModelException("Knoten mit ID = " + NodeId + " ist nicht im Modell enthalten");
                }
            }
            else
            {
                throw new ModelException("Knotenidentifikator für Randbedingung " + SupportId +
                                         " ist nicht definiert");
            }
        }
コード例 #24
0
 void Save2(StreamWriter sw, ID id, FeModel item)
 {
     sw.WriteLine($"solid {id.ToString()}");
     foreach (var tetrahedron in item.Tetrahedrons)
     {
         List <Triangle> triangles = TrianglesFromTetrahedrons(tetrahedron);
         foreach (var triangle in triangles)
         {
             Tuple <double, double, double> normal = Normal(triangle);
             sw.WriteLine($"  facet normal {normal.Item1} {normal.Item2} {normal.Item3}");
             sw.WriteLine("    outer loop");
             foreach (var node in triangle.Nodes)
             {
                 sw.WriteLine($"      vertex {node.PX+700} {node.PY} {node.PZ}");
             }
             sw.WriteLine("    endloop");
             sw.WriteLine("  endfacet");
         }
     }
     sw.WriteLine($"endsolid {id.ToString()}");
 }
コード例 #25
0
ファイル: BestArchProblem.cs プロジェクト: scudelari/EMASA
        protected override double Function_Override()
        {
            Rhino_SendInputAndGetOutput();

            // Gets the grasshopper vars in the right cast
            List <double> bowLength = CurrentSolution.GetIntermediateValueByName <List <double> >("BowLength");

            List <Point3d> fixedSupport_1 = FeModel.AddJoints_IntermediateParameter("FixedSupportJoint_1");
            List <Point3d> fixedSupport_2 = FeModel.AddJoints_IntermediateParameter("FixedSupportJoint_2");

            List <Line> archLines_1 = FeModel.AddFrames_IntermediateParameter("ArchLines_1"); // The section is defined in the interface
            List <Line> archLines_2 = FeModel.AddFrames_IntermediateParameter("ArchLines_2"); // The section is defined in the interface

            // Loading of the model is set in the Problem object by the interface

            // The chosen result output given is only valid for the model runs that are *not* for section analysis
            FeModel.RunAnalysisAndGetResults(new List <ResultOutput>()
            {
                ResultOutput.Element_StrainEnergy,
                ResultOutput.SectionNode_Stress,
            });

            CurrentSolution.FillScreenShotData();

            double averageStrainEnergy = (from a in FeModel.MeshBeamElements select a.Value.ElementStrainEnergy.StrainEnergy).Average();
            double maxStrainEnergy     = (from a in FeModel.MeshBeamElements select a.Value.ElementStrainEnergy.StrainEnergy).Max();
            double StDevStrainEnergy   = (from a in FeModel.MeshBeamElements select a.Value.ElementStrainEnergy.StrainEnergy).StandardDeviation();

            CurrentSolution.SetFinalValueByName("MaximumStrainEnergy", maxStrainEnergy);

            CurrentSolution.Eval = CurrentSolution.GetSquareSumOfList(new[]
            {
                // Stores the solution result values

                CurrentSolution.SetFinalValueByName("AverageStrainEnergy", averageStrainEnergy),
                CurrentSolution.SetFinalValueByName("StDevStrainEnergy", StDevStrainEnergy),
            });

            return(CurrentSolution.Eval);
        }
コード例 #26
0
        public static void readData(FeScanner RD)
        {
            readDataFile(RD);

            FeScanner fes = new FeScanner(meshFile);

            fem         = new FeModel(fes, null);
            Element.fem = fem;
            fem.readData();

            if (resultFile != null)
            {
                displ = new double[fem.nNod * fem.nDf];
                FeStress stress = new FeStress(fem);
                stress.readResults(resultFile, displ);
                if (deformScale > 0)
                {
                    showDeformShape = true;
                }
                drawContours = VisData.parm != VisData.parms.none;
            }
        }
コード例 #27
0
        public connect()
        {
            String modelNameA = CSMGEN.RD.next();
            String modelNameB = CSMGEN.RD.next();
            String modelNameC = CSMGEN.RD.next();

            CSMGEN.PR.WriteLine("Connect: {0} + {1} -> {2}", modelNameA, modelNameB, modelNameC);

            readData();

            if (CSMGEN.blocks.ContainsKey(modelNameA))
            {
                mA = (FeModel)CSMGEN.blocks[modelNameA];
            }
            else
            {
                UTIL.errorMsg("No such mesh block: " + modelNameA);
            }
            if (CSMGEN.blocks.ContainsKey(modelNameB))
            {
                mB = (FeModel)CSMGEN.blocks[modelNameB];
            }
            else
            {
                UTIL.errorMsg("No such mesh block: " + modelNameB);
            }
            if (mA.nDim != mB.nDim)
            {
                UTIL.errorMsg("Models with different nDim");
            }

            findCoincidentNodes();
            FeModel mC = pasteModels();

            CSMGEN.blocks.Add(modelNameC, mC);
            CSMGEN.PR.Write(" {0} node pairs connected\n", nConnected);
            CSMGEN.PR.Write("Mesh " + modelNameC + ": nEl = {0}  nNod = {1}\n", mC.nEl, mC.nNod);
        }
コード例 #28
0
        public copy()
        {
            String modelNameA = CSMGEN.RD.next();
            String modelNameB = CSMGEN.RD.next();

            CSMGEN.PR.WriteLine("Copy: {0} -> {1}\n", modelNameA, modelNameB);
            if (modelNameA.Equals(modelNameB))
            {
                return;
            }
            if (CSMGEN.blocks.ContainsKey(modelNameA))
            {
                mA = (FeModel)CSMGEN.blocks[modelNameA];
            }
            else
            {
                UTIL.errorMsg("No such mesh block: " + modelNameA);
            }
            FeModel mB = copyMesh();

            CSMGEN.blocks.Add(modelNameB, mB);
            CSMGEN.PR.WriteLine("Mesh " + modelNameB + ": nEl = {0,9}  nNod = {1,9}\n", mB.nEl, mB.nNod);
        }
コード例 #29
0
 /// <summary>
 /// The problem of stress-strain state on the model data
 /// </summary>
 public DynamicStressStrainSparse(FeModel model) : base(model)
 {
     GenerateGlobalMatrix();
 }
コード例 #30
0
        /// <summary>
        /// Gneration of the finite element model
        /// </summary>
        /// <returns></returns>
        FeModel Generation()
        {
            FeModel result = null;

            Dictionary <int, List <Area> >             items           = new Dictionary <int, List <Area> >();
            Dictionary <int, List <List <Triangle> > > trianglesLayers = new Dictionary <int, List <List <Triangle> > >();
            List <Tetrahedron> tetrahedrons = new List <Tetrahedron>();
            List <Node>        nodes        = new List <Node>();

            Triangulating    triangulate = new Triangulating(step);
            VolumeGeneration volume      = new VolumeGeneration(step);

            List <List <Node> > boundLayers = InitLayers(repository.Read(path));

            int difference = step / Math.Abs(boundLayers[1][0].PZ - boundLayers[0][0].PZ);

            for (int i = 0; i < boundLayers.Count - difference; i++)
            {
                boundLayers.RemoveRange(i + 1, difference - 1);
            }

            int processCount = boundLayers.Count;
            int counter      = 0;

            using (ManualResetEvent resetEvent = new ManualResetEvent(false))
            {
                foreach (var item in boundLayers)
                {
                    ThreadPool.SetMaxThreads(4, 8); // 8 because 4 core and 4 virtual
                    ThreadPool.QueueUserWorkItem(thrLayer =>
                    {
                        var layer = (((object[])thrLayer)[0]) as List <Node>;
                        int index = (int)((object[])thrLayer)[1];
                        LayerSettings settings = new LayerSettings(layer, step);
                        List <Area> areas      = settings.Areas;

                        items.Add(index, areas);
                        List <List <Triangle> > triangles = new List <List <Triangle> >();
                        areas.ForEach(area =>
                        {
                            List <Triangle> tmp = triangulate.GenerateTriangles(area.Nodes).Values.ToList();
                            if (tmp.Count > 0)
                            {
                                triangles.Add(tmp);
                            }
                        });
                        trianglesLayers.Add(index, triangles);

                        if (Interlocked.Decrement(ref processCount) == 0)
                        {
                            resetEvent.Set();
                        }
                    }, new object[] { item, counter++ });
                }
                resetEvent.WaitOne();
            }
            for (int i = 0; i < items.Count; i++)
            {
                items[i].ForEach(ar => nodes.AddRange(ar.Nodes));
            }
            //nodes.Sort((first, second) =>
            //{
            //    return (first.Z > second.Z) ? 1
            //    : (first.Z < second.Z) ? -1
            //    : 0;
            //});
            // set global indexes by getting from current area id plus count elements in previous areas
            // after generate triangles and tetrahedrons (try with thread pool)
            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].GlobalIndex = i;
            }

            //tetrahedron generation
            tetrahedrons = GenerateTetrahedrons(ref trianglesLayers, volume, ref items);

            result = new FeModel(nodes, tetrahedrons);
            return(result);
        }