/// <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); }
/// <summary> /// Tetrahedrons generation /// </summary> /// <param name="trianglesLayers"> Layers of triangles</param> /// <param name="volume">Volume generation settings</param> /// <param name="areas">List of areas by layers</param> /// <returns></returns> List <Tetrahedron> GenerateTetrahedrons(ref Dictionary <int, List <List <Triangle> > > trianglesLayers, VolumeGeneration volume, ref Dictionary <int, List <Area> > areas) { List <Tetrahedron> tetrahedrons = new List <Tetrahedron>(); for (int i = 1; i < trianglesLayers.Count; i++) { if (trianglesLayers[i - 1].Count > 0 && trianglesLayers[i].Count > 0) { if (trianglesLayers[i - 1].Count < trianglesLayers[i].Count) { tetrahedrons.AddRange(volume.GenerateTetrahedrons(trianglesLayers[i - 1], trianglesLayers[i])); } else { tetrahedrons.AddRange(volume.GenerateTetrahedrons(trianglesLayers[i], trianglesLayers[i - 1])); } } else { if (trianglesLayers[i - 1].Count < trianglesLayers[i].Count) { List <Triangle> tmp = new List <Triangle>(); trianglesLayers[i].ForEach(x => tmp.AddRange(x)); tetrahedrons.AddRange(volume.GenerateTetrahedrons(areas[i - 1][0].Nodes[0], tmp)); } else { List <Triangle> tmp = new List <Triangle>(); trianglesLayers[i - 1].ForEach(x => tmp.AddRange(x)); tetrahedrons.AddRange(volume.GenerateTetrahedrons(areas[i][0].Nodes[0], tmp)); } } } return(tetrahedrons); }