// See slides p.44 public void GetLocalNodeCoordinates(out Matrix xel, out Matrix Tg) { Vector3D v1 = Nodes[1].Pos - Nodes[0].Pos; Vector3D _v2 = Nodes[2].Pos - Nodes[0].Pos; Vector3D v3 = Vector3D.CrossProduct(v1, _v2); Vector3D v2 = Vector3D.CrossProduct(v3, v1); if (v1.IsZeroVector() || v2.IsZeroVector() || v3.IsZeroVector()) { throw new Exception("Bad element, ID: " + this.Id.ToString()); } Vector3D e1 = v1.Normalize(false); Vector3D e2 = v2.Normalize(false); Vector3D e3 = v3.Normalize(false); Matrix xeg = new Matrix(3, 3); xeg.SetRow(v1.ToMatrix().Transpose(), 1); xeg.SetRow(_v2.ToMatrix().Transpose(), 2); Matrix T = new Matrix(3, 3); T.SetCol(e1.ToMatrix(), 0); T.SetCol(e2.ToMatrix(), 1); T.SetCol(e3.ToMatrix(), 2); xel = xeg * T; Tg = new Matrix(18, 18); int[] pos1 = SF.intSrs(0, 2); int[] pos2 = SF.intSrs(3, 5); int[] pos3 = SF.intSrs(6, 8); int[] pos4 = SF.intSrs(9, 11); int[] pos5 = SF.intSrs(12, 14); int[] pos6 = SF.intSrs(15, 17); Tg[pos1, pos1] = T; Tg[pos2, pos2] = T; Tg[pos3, pos3] = T; Tg[pos4, pos4] = T; Tg[pos5, pos5] = T; Tg[pos6, pos6] = T; }
//Calculate principal tresses for all the elements public void CalcStresses() { //Folllowing plants in MATlab, each element 15 dofs //the 15 active dofs used in each element (with 18 dofs in total) int[] activeDofs = new int[] { 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16 }; PrincipalStresses = new List <Vector3D>(); stresses = new List <Matrix>(); PrincipalAngles = new List <double>(); vonMises = new List <double>(); for (int i = 0; i < elements.Count; i++) { //Get all the 18 element dofs from the global int[] dofsFull = elements[i].GetElementDofs(); //Take the deformations from the element dofs Matrix aTrans = new Matrix(18, 1); for (int j = 0; j < dofsFull.Count(); j++) { aTrans[j] = a[dofsFull[j]]; } //Transform the local coordinates to global aTrans = elements[i].Te.Invert() * aTrans; //Take the 15 active dofs that should be used from the transformed defrormations Matrix ed = new Matrix(1, 15); for (int j = 0; j < activeDofs.Count(); j++) { ed[0, j] = aTrans[activeDofs[j]]; } //Stresses (D*B*a) // Matrix ss = elements[i].DBe * ed[0, SF.intSrs(0, 14)].Transpose(); // stresses.Add(ss); double theta = 0; Vector3D vMax = new Vector3D(); //for every layer for (int j = 0; j < elements[i].DBe.Count; j++) { Matrix ss = new Matrix(6, 1); ed[3] *= elements[i].zs[j]; ed[4] *= elements[i].zs[j]; ed[8] *= elements[i].zs[j]; ed[9] *= elements[i].zs[j]; ed[13] *= elements[i].zs[j]; ed[14] *= elements[i].zs[j]; ss = elements[i].DBe[j] * ed[0, SF.intSrs(0, 14)].Transpose(); //Make sure there is no errors when this is changed // theta = 0.5 * Math.Atan(2 * ss[2] / (ss[0] - ss[1])); // if (ss[0] < ss[1]) theta = theta + Math.PI / 2; //PrincipalAngles.Add(theta); //Principle stresses double p1 = (ss[0] + ss[1]) / 2.0 + Math.Sqrt(Math.Pow((ss[0] - ss[1]) / 2, 2) + Math.Pow(ss[2], 2)); double p2 = (ss[0] + ss[1]) / 2.0 - Math.Sqrt(Math.Pow((ss[0] - ss[1]) / 2, 2) + Math.Pow(ss[2], 2)); Vector3D v = new Vector3D(p1, p2, 0); if (v.Length > vMax.Length) { vMax = v; theta = 0.5 * Math.Atan(2 * ss[2] / (ss[0] - ss[1])); if (ss[0] < ss[1]) { theta = theta + Math.PI / 2; } } } // PrincipalStresses.Add(new Vector3D(p1, p2, 0)); PrincipalStresses.Add(vMax); // vonMises.Add(Math.Sqrt(p1 * p1 - p1 * p2 + p2 * p2)); vonMises.Add(Math.Sqrt(vMax.X * vMax.X - vMax.X * vMax.Y + vMax.Y * vMax.Y)); PrincipalAngles.Add(theta); } }