public IEnumerable <Tetrahedral> MakeTetrahedra(Voxel voxel) { var c = voxel.GetCorners().ToArray(); var t = new[, ] { { c[0], c[1], c[2], c[4] }, { c[3], c[1], c[2], c[7] }, { c[1], c[2], c[4], c[7] }, { c[4], c[5], c[7], c[1] }, { c[4], c[7], c[6], c[2] } }; for (int i = 0; i < 5; i++) { var tetra = new Tetrahedral() { E = 210e9, Nu = 0.33 }; for (int j = 0; j < 4; j++) { tetra.Nodes[j] = (t[i, j] as FeaCorner).Node; } yield return(tetra); } }
/// <summary> /// Gets the global equivalent nodal loads for <see cref="Tetrahedral"/> element. /// </summary> /// <param name="elm">The elm.</param> /// <returns>global equivalent nodal loads for <see cref="Tetrahedral"/> element</returns> private Force[] GetGlobalEquivalentNodalLoads(Tetrahedral elm) { //p.263 of Structural Analysis with the Finite Element Method Linear Statics, ISBN: 978-1-4020-8733-2 //formula (8.37c) : the total body force is distributed in equal parts between the four nodes, as expected! elm.UpdateGeoMatrix(); var v = elm.det / 6; var f = new Force(); f.Fx = v / 4 * _vx; f.Fy = v / 4 * _vy; f.Fz = v / 4 * _vz; return(new[] { f, f, f, f }); }
private void AddTetrahedronElement(MeshBuilder bldr, Tetrahedral elm) { PolygonYz section = null; var r = ElementVisualThickness / 2; var p1 = elm.Nodes[0].Location; var p2 = elm.Nodes[1].Location; var p3 = elm.Nodes[2].Location; var p4 = elm.Nodes[3].Location; bldr.AddTriangle(p1, p3, p4); bldr.AddTriangle(p3, p2, p4); bldr.AddTriangle(p1, p2, p4); bldr.AddTriangle(p1, p2, p3); }
/// <summary> /// Gets the global equivalent nodal loads for <see cref="Tetrahedral"/> element. /// </summary> /// <param name="element">The element.</param> /// <returns></returns> public Force[] GetGlobalEquivalentNodalLoads(Tetrahedral element) { //p.264 of Structural Analysis with the Finite Element Method Linear Statics, ISBN: 978-1-4020-8733-2 //formula (8.39) - (8.42) : Uniform surface tractions are distributed in equal parts between the three nodes of the linear tetrahedron face affected by the loading. //area of triangle in 3D: S = | AB x AC |/2 //using cross product of two lines of three lines of triangle var p1 = _surfaceNodes[0].Location; var p2 = _surfaceNodes[1].Location; var p3 = _surfaceNodes[2].Location; var v1 = p2 - p1; var v2 = p3 - p1; var s = v1.Cross(v2).Length / 2; var f = new Force { Fx = this.Sx * s / 3, Fy = this.Sy * s / 3, Fz = this.Sz * s / 3 }; return(new[] { f, f, f }); }
public static Model Generate3DTet4Grid(int m, int n, int l) { var buf = new Model(); var dx = 1.0; var dy = 1.0; var dz = 1.0; var nodes = new Node[m, n, l]; for (int k = 0; k < l; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { var pos = new Point(i * dx, j * dy, k * dz); var nde = new Node() { Location = pos }; buf.Nodes.Add(nde); nde.Constraints = Constraint.RotationFixed; nodes[j, i, k] = nde; } } } var elm = new Func <Node, Node, Node, Node, Tetrahedral>((n1, n2, n3, n4) => { var buff = new Tetrahedral(); buff.Nodes[0] = n1; buff.Nodes[1] = n2; buff.Nodes[2] = n3; buff.Nodes[3] = n4; buff.E = 210e9; buff.Nu = 0.33; return(buff); }); var elms = new List <Element>(); for (int i = 0; i < m - 1; i++) { for (int j = 0; j < n - 1; j++) { for (int k = 0; k < l - 1; k++) { var ns = new Node[] { nodes[i, j, k], nodes[i + 1, j, k], nodes[i + 1, j + 1, k], nodes[i, j + 1, k], nodes[i, j, k + 1], nodes[i + 1, j, k + 1], nodes[i + 1, j + 1, k + 1], nodes[i, j + 1, k + 1], }; elms.Add(elm(ns[0], ns[1], ns[3], ns[4])); elms.Add(elm(ns[2], ns[1], ns[3], ns[6])); elms.Add(elm(ns[1], ns[3], ns[4], ns[6])); elms.Add(elm(ns[4], ns[5], ns[6], ns[1])); elms.Add(elm(ns[4], ns[6], ns[7], ns[3])); } } } buf.Elements.Add(elms.ToArray()); for (int i = 0; i < n * m; i++) { buf.Nodes[i].Constraints = Constraint.Fixed; } return(buf); }
public static void Test3() { var model = new BriefFiniteElementNet.Model(); var p = new Point[20]; var ns = new Node[20]; p[0] = new Point(x: 0, y: 1, z: 0); p[1] = new Point(x: 0, y: 0, z: 0); p[2] = new Point(x: 0.20, y: 0, z: 0); p[3] = new Point(x: 0.20, y: 0, z: 0.20); p[4] = new Point(x: 0.20, y: 1, z: 0); p[5] = new Point(x: 0.20, y: 1, z: 0.20); p[6] = new Point(x: 0, y: 1, z: 0.20); p[7] = new Point(x: 0, y: 0, z: 0.20); p[8] = new Point(x: 0, y: 0.50, z: 0); p[9] = new Point(x: 0.20, y: 0.50, z: 0); p[10] = new Point(x: 0, y: 0.50, z: 0.20); p[11] = new Point(x: 0.20, y: 0.50, z: 0.20); p[12] = new Point(x: 0.20, y: 0.25, z: 0.20); p[13] = new Point(x: 0, y: 0.25, z: 0.20); p[14] = new Point(x: 0, y: 0.25, z: 0); p[15] = new Point(x: 0.20, y: 0.25, z: 0); p[16] = new Point(x: 0.20, y: 0.75, z: 0.20); p[17] = new Point(x: 0.20, y: 0.75, z: 0); p[18] = new Point(x: 0, y: 0.75, z: 0); p[19] = new Point(x: 0, y: 0.75, z: 0.20); for (var i = 0; i < 20; i++) { model.Nodes.Add(ns[i] = new Node(p[i])); ns[i].Label = "n" + i.ToString(CultureInfo.CurrentCulture); ns[i].Constraints = Constraints.RotationFixed; } var mesh = new int[24][]; mesh[0] = new int[] { 0, 4, 16, 17 }; mesh[1] = new int[] { 8, 15, 12, 14 }; mesh[2] = new int[] { 8, 16, 17, 18 }; mesh[3] = new int[] { 10, 8, 11, 12 }; mesh[4] = new int[] { 5, 19, 0, 16 }; mesh[5] = new int[] { 1, 15, 14, 12 }; mesh[6] = new int[] { 8, 10, 11, 16 }; mesh[7] = new int[] { 3, 13, 1, 7 }; mesh[8] = new int[] { 3, 13, 12, 1 }; mesh[9] = new int[] { 8, 12, 13, 14 }; mesh[10] = new int[] { 1, 15, 12, 2 }; mesh[11] = new int[] { 9, 8, 11, 16 }; mesh[12] = new int[] { 10, 8, 12, 13 }; mesh[13] = new int[] { 5, 0, 4, 16 }; mesh[14] = new int[] { 5, 19, 6, 0 }; mesh[15] = new int[] { 8, 19, 16, 18 }; mesh[16] = new int[] { 8, 19, 10, 16 }; mesh[17] = new int[] { 0, 19, 18, 16 }; mesh[18] = new int[] { 1, 3, 2, 12 }; mesh[19] = new int[] { 8, 15, 9, 12 }; mesh[20] = new int[] { 13, 12, 1, 14 }; mesh[21] = new int[] { 8, 9, 11, 12 }; mesh[22] = new int[] { 9, 8, 16, 17 }; mesh[23] = new int[] { 16, 0, 17, 18 }; foreach (var elm in mesh) { var felm = new Tetrahedral(); felm.Nodes[0] = ns[elm[0]]; felm.Nodes[1] = ns[elm[1]]; felm.Nodes[2] = ns[elm[2]]; felm.Nodes[3] = ns[elm[3]]; felm.E = 210e9; felm.Nu = 0.33; model.Elements.Add(felm); } var relm = new BriefFiniteElementNet.MpcElements.RigidElement_MPC(); relm.Nodes = new NodeList() { ns[0], ns[4], ns[5], ns[6] }; relm.UseForAllLoads = true; //model.MpcElements.Add(relm); ns[1].Constraints = ns[2].Constraints = ns[3].Constraints = ns[7].Constraints = Constraints.Fixed; var load = new BriefFiniteElementNet.NodalLoad(); var frc = new Force(); frc.Fz = 1000;// 1kN force in Z direction load.Force = frc; ns[5].Loads.Add(load); ns[6].Loads.Add(load); model.Solve_MPC(); var d5 = ns[5].GetNodalDisplacement(); var d6 = ns[6].GetNodalDisplacement(); Console.WriteLine("Nodal displacement in Z direction is {0} meters (thus {1} mm)", d5.DZ, d5.DZ * 1000); Console.WriteLine("Nodal displacement in Z direction is {0} meters (thus {1} mm)", d6.DZ, d6.DZ * 1000); var tetra = model.Elements[0] as Tetrahedral; var stress = tetra.GetInternalForce(LoadCombination.DefaultLoadCombination); }