public override void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke) { int Ip, Iq; int NNPE = ElementNodes.Length; for (int p = 0; p < NNPE; p++) { Node_ND_Unknowns_VectorField Unknown_p = (Node_ND_Unknowns_VectorField)ElementNodes[p].Unknowns; int NDFp = Unknown_p.UnknownDoFs.Length; for (int i = 0; i < NDFp; i++) { Ip = Unknown_p.UnknownDoFs[i]; for (int q = 0; q < NNPE; q++) { Node_ND_Unknowns_VectorField Unknown_q = (Node_ND_Unknowns_VectorField)ElementNodes[q].Unknowns; int NDFq = Unknown_q.UnknownDoFs.Length; for (int j = 0; j < NDFq; j++) { Iq = Unknown_q.UnknownDoFs[j]; K.AddToMatrixElement(Ip, Iq, Ke.Values[NNPE * p + i][NNPE * q + j]); } } } } }
/// <summary> /// Get rotation matrix for a rotation of given ange around given axis (only for 3D vectors) /// </summary> /// <param name="AxisOfRotation"></param> /// <param name="AngleRad"></param> /// <returns></returns> public static Matrix_Jagged RotationMatrixForRotationAboutAxis_Jagged(Vector AxisOfRotation, double AngleOfRotation_Rad) { Matrix_Jagged NewMatrix = new Matrix_Jagged(); NewMatrix.Values = ArrayTools.RotationMatrixAboutAxis_Jagged(AngleOfRotation_Rad, AxisOfRotation.Values); return(NewMatrix); }
public virtual Matrix_Jagged IntegralArgument_Ce(Vector Xi) { //Override with argument of Ce as a matrix Matrix_Jagged Ce = new Matrix_Jagged(); return(Ce); }
public override void SolveFEMSystem_Parallel() { //Set up the load vector and stiffness matrix int NDF = Unknowns_NDoF; //Get the size of the unknowns temperature (one per node) Vector F = new Vector(NDF); //Make global load vector Matrix_Jagged K = new Matrix_Jagged(NDF, NDF); // Make global stiffness matrix //Assemble F and K int NE = Elements.Length; //Get the number of elements ParallelOptions op = new ParallelOptions(); op.MaxDegreeOfParallelism = Environment.ProcessorCount; Parallel.For(0, NE, op, i => { Vector Fe = Elements[i].Calculate_Fe(); Matrix_Jagged Ke = Elements[i].Calculate_Ke(); lock (this_K_Lock) { Elements[i].Assemble(ref K, Ke); } lock (this_F_Lock) { Elements[i].Assemble(ref F, Fe); } }); //Adjust for boundary conditions int NBE = BoundaryElements.Length; for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustFAndK(ref F, ref K); } //Solve system U = K.SolveLinearSystem(F); }
public static Matrix_Jagged RotationMatrixForRotationAboutAxis_Jagged(double[] AxisOfRotation, double AngleOfRotation_Rad) { Matrix_Jagged Q = new Matrix_Jagged(); Q.Values = ArrayTools.RotationMatrixAboutAxis_Jagged(AngleOfRotation_Rad, AxisOfRotation); return(Q); }
public override void Assemble(ref Matrix_Jagged K, Matrix_Jagged Ke) { int Ip, Iq; int NNPE = ElementNodes.Length; for (int p = 0; p < NNPE; p++) { Node_ND_Unknowns_VectorField Unknown_p = (Node_ND_Unknowns_VectorField)ElementNodes[p].Unknowns; int NDFp = Unknown_p.UnknownDoFs.Length; for (int i = 0; i < NDFp; i++) { Ip = Unknown_p.UnknownDoFs[i]; for (int q = 0; q < NNPE; q++) { Node_ND_Unknowns_VectorField Unknown_q = (Node_ND_Unknowns_VectorField)ElementNodes[q].Unknowns; int NDFq = Unknown_q.UnknownDoFs.Length; for (int j = 0; j < NDFq; j++) { Iq = Unknown_q.UnknownDoFs[j]; K.Values[Ip][Iq] += Ke.Values[NDFp * p + i][NDFq * q + j]; } } } } }
public override void SolveFEMSystem() { //Set up the load vector and stiffness matrix int NDF = Unknowns_NDoF; //Get the size of the unknowns temperature (one per node) Vector F = new Vector(NDF); //Make global load vector Matrix_Jagged K = new Matrix_Jagged(NDF, NDF); // Make global stiffness matrix //Assemble F and K int NE = Elements.Length; //Get the number of elements for (int i = 0; i < NE; i++) { Elements[i].CalculateAndAssemble_FeAndKe(ref F, ref K); } //Adjust for boundary conditions int NBE = BoundaryElements.Length; for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustFAndK(ref F, ref K); } //Solve system U = K.SolveLinearSystem(F); }
public virtual Matrix_Jagged IntegralArgument_Me(Vector Xi) { //Override with argument of Ce as a matrix (Do not include Le/L_Xi factor) Matrix_Jagged Me = new Matrix_Jagged(); return(Me); }
public virtual Matrix_Jagged Calculate_DerivativesOfShapeFunctions_WRTXi_Matrix_Jagged(Vector Xi) { //Override with method to calculate derivative of shape functions with respect to Xi Vector[] dNdXi = Calculate_DerivativesOfShapeFunctions_WRTXi(Xi); Matrix_Jagged DNDXi = new Matrix_Jagged(dNdXi); return(DNDXi.Transpose()); }
public virtual Matrix_Jagged IntegralArgument_Ke(Vector Xi) { //Override with argument of Ke as a matrix Matrix_Jagged Ke = new Matrix_Jagged(); return(Ke); }
public static void Calculate_YGradient(Vector[] X, double[] Y, out Vector Center_X, out Vector[] DX, out double Center_Y, out Vector Gradient) { int N = X.Length; Vector X_c = Vector.Average(X); Vector Sum_DX = new Vector(2); double Sum_Y = 0.0D; Vector Sum_YDX = new Vector(2); DX = new Vector[N]; for (int i = 0; i < N; i++) { DX[i] = new Vector(2); DX[i] = X[i] - X_c; Sum_DX += DX[i]; } OOPTools_Math.Matrix_Jagged M = new OOPTools_Math.Matrix_Jagged(2, 2); for (int i = 0; i < N; i++) { M += OOPTools_Math.Matrix_Jagged.TensorProduct(DX[i], DX[i]); } Matrix_Jagged A = new Matrix_Jagged(3, 3); A.Values[0][0] = Convert.ToDouble(N); A.Values[0][1] = Sum_DX.Values[0]; A.Values[0][2] = Sum_DX.Values[1]; A.Values[1][0] = Sum_DX.Values[0]; A.Values[1][1] = M.Values[0][0]; A.Values[1][2] = M.Values[0][1]; A.Values[2][0] = Sum_DX.Values[1]; A.Values[2][1] = M.Values[1][0]; A.Values[2][2] = M.Values[1][1]; double DetA; A.SolveLinearSystem_LUDecomp(out DetA); Gradient = new Vector(2); if (DetA < 1.0E-20) { Center_Y = ArrayTools.Average(Y); } else { for (int i = 0; i < N; i++) { Sum_Y += Y[i]; Sum_YDX += Y[i] * DX[i]; } Vector b = new Vector(3); b.Values[0] = Sum_Y; b.Values[1] = Sum_YDX.Values[0]; b.Values[2] = Sum_YDX.Values[1]; Vector x = A.SolveLinearSystem_BackSub(b); Center_Y = x.Values[0]; Gradient.Values[0] = x.Values[1]; Gradient.Values[1] = x.Values[2]; } Center_X = X_c; }
public virtual Matrix_Jagged IntegrateFunction(Function_Matrix_Jagged Func) { Matrix_Jagged integral = QRule.wi[0] * Func(QRule.Xi[0]); for (int i = 1; i < QRule.NIP; i++) { integral += QRule.wi[i] * Func(QRule.Xi[i]); } return(integral); }
public virtual Matrix_Jagged Interpolate_DerivativeOfVariable_WRTXi(Vector[] Variable_NodalValues, Vector[] dNdXi) { int nnpe = dNdXi.Length; Matrix_Jagged Value = Matrix_Jagged.TensorProduct(Variable_NodalValues[0], dNdXi[0]); for (int p = 1; p < nnpe; p++) { Value += Matrix_Jagged.TensorProduct(Variable_NodalValues[p], dNdXi[p]); } return(Value); }
public virtual Matrix_Jagged Calculate_DerivativesOfShapeFunctions_WRTX(Vector Xi, Node_ND[] ElementNodes, out Matrix_Jagged DXDXi, out double Det_Jacobian) { Vector[] dNdXi; Matrix_Jagged DXiDX; Calculate_dNdXi_DXDXi_DXiDX_DetJac(Xi, ElementNodes, out dNdXi, out DXDXi, out DXiDX, out Det_Jacobian); Matrix_Jagged DNDXi = new Matrix_Jagged(dNdXi).Transpose(); return(DNDXi * DXiDX); }
public virtual void Calculate_X_N_DetJacobian(Vector Xi, Node_ND[] ElementNodes, out Vector X, out Vector N, out double Det_Jac) { Vector[] Xp = Get_ElementNodal_X(ElementNodes); Vector[] dNdXi = Calculate_DerivativesOfShapeFunctions_WRTXi(Xi, out N); X = Interpolate_Variable(Xp, N); Matrix_Jagged DXDXi = Interpolate_DerivativeOfVariable_WRTXi(Xp, dNdXi); Det_Jac = DXDXi.Det(); }
public virtual Matrix_Jagged Interpolate_DerivativeOfVariable_WRTX(Vector Xi, Vector[] Variable_NodalValues, Node_ND[] ElementNodes) { Vector[] dNdXi; Matrix_Jagged DXDXi, DXiDX; Calculate_dNdXi_DXDXi_DXiDX(Xi, ElementNodes, out dNdXi, out DXDXi, out DXiDX); Matrix_Jagged DValueDXi = Interpolate_DerivativeOfVariable_WRTXi(Variable_NodalValues, dNdXi); return(DValueDXi * DXiDX); }
public Matrix_Jagged[] Calculate_ElementNodal_DUDX() { int NNPE = ElementNodes.Length; Matrix_Jagged[] DuDX = new Matrix_Jagged[NNPE]; Vector[] Ue = Get_ElementNodal_U(Element_ND.U); Vector[] Xip = Interpolator.NodeXi; for (int p = 0; p < NNPE; p++) { DuDX[p] = Interpolator.Interpolate_DerivativeOfVariable_WRTX(Xip[p], Ue, ElementNodes); } return(DuDX); }
public Matrix_Jagged Displacements; //Nodal values of Displacements public override void AdjustFAndK(ref Vector F, ref Matrix_Jagged K) { int NNPE = ElementNodes.Length; for (int i = 0; i < NNPE; i++) { Node_ND_Unknowns_VectorField Unknowns_i = (Node_ND_Unknowns_VectorField)ElementNodes[i].Unknowns; int[] Ip = Unknowns_i.UnknownDoFs; //position of unkonw in globle matrix F.Values[Ip[0]] = 1.0E20 * Displacements.Values[i][0]; //penalty for Uix K.Values[Ip[0]][Ip[0]] = 1.0E20; F.Values[Ip[1]] = 1.0E20 * Displacements.Values[i][1]; //penalty for Uiy K.Values[Ip[1]][Ip[1]] = 1.0E20; } }
public void Calculate_X_DNDX_DetJacobian(Vector Xi, Node_ND[] ElementNodes, out Vector X, out Matrix_Jagged DNDX, out double Det_Jac) { Vector[] Xp = Get_ElementNodal_X(ElementNodes); Vector N; Vector[] dNdXi = Calculate_DerivativesOfShapeFunctions_WRTXi(Xi, out N); X = Interpolate_Variable(Xp, N); Matrix_Jagged DNDXi = new Matrix_Jagged(dNdXi).Transpose(); Matrix_Jagged DXDXi = Interpolate_DerivativeOfVariable_WRTXi(Xp, dNdXi); Matrix_Jagged DXiDX = DXDXi.Invert(out Det_Jac); DNDX = DNDXi * DXiDX; }
public override void Assemble(ref Matrix_Jagged K, Matrix_Jagged Ke) { int Ip, Iq; int NNPE = ElementNodes.Length; for (int p = 0; p < NNPE; p++) { Node_ND_Unknowns_ScalarField TheUnknowns_p = (Node_ND_Unknowns_ScalarField)ElementNodes[p].Unknowns; Ip = TheUnknowns_p.UnknownDoF; for (int q = 0; q < NNPE; q++) { Node_ND_Unknowns_ScalarField TheUnknowns_q = (Node_ND_Unknowns_ScalarField)ElementNodes[q].Unknowns; Iq = TheUnknowns_q.UnknownDoF; K.Values[Ip][Iq] += Ke.Values[p][q]; } } }
public override void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke) { int Ip, Iq; int NNPE = ElementNodes.Length; for (int p = 0; p < NNPE; p++) { Node_ND_Unknowns_ScalarField TheUnknowns_p = (Node_ND_Unknowns_ScalarField)ElementNodes[p].Unknowns; Ip = TheUnknowns_p.UnknownDoF; for (int q = 0; q < NNPE; q++) { Node_ND_Unknowns_ScalarField TheUnknowns_q = (Node_ND_Unknowns_ScalarField)ElementNodes[q].Unknowns; Iq = TheUnknowns_q.UnknownDoF; K.AddToMatrixElement(Ip, Iq, Ke.Values[p][q]); } } }
public static void Assemble_Parallel(int NE, Element_ND[] Elements, out Vector[] Fes, out Matrix_Jagged[] Kes) { Vector[] Fe = new Vector[NE]; Matrix_Jagged[] Ke = new Matrix_Jagged[NE]; ParallelOptions op = new ParallelOptions(); op.MaxDegreeOfParallelism = Environment.ProcessorCount - 1; Parallel.For(0, NE, op, i => { Fe[i] = Elements[i].Calculate_Fe(); Ke[i] = Elements[i].Calculate_Ke(); }); Fes = Fe; Kes = Ke; }
public override Matrix_Jagged Calculate_DerivativesOfShapeFunctions_WRTXi_Matrix_Jagged(Vector Xi) { Matrix_Jagged DNDXi = new Matrix_Jagged(NNPE, 2); Vector N_1D_M = ParametricInterpolation_1D_M.CalculateShapeFunctions(Xi.Values[0]); Vector N_1D_N = ParametricInterpolation_1D_N.CalculateShapeFunctions(Xi.Values[1]); Vector DNDXi_1D_M = ParametricInterpolation_1D_M.CalculateDerivativesOfShapeFunctions_WRTXi(Xi.Values[0]); Vector DNDXi_1D_N = ParametricInterpolation_1D_N.CalculateDerivativesOfShapeFunctions_WRTXi(Xi.Values[1]); int Index = 0; for (int j = 0; j < NNPE_n; j++) { for (int i = 0; i < NNPE_m; i++) { DNDXi.Values[Index][0] = DNDXi_1D_M.Values[i] * N_1D_N.Values[j]; DNDXi.Values[Index][1] = N_1D_M.Values[i] * DNDXi_1D_N.Values[j]; Index++; } } return(DNDXi); }
public override void Assemble(ref Matrix_Jagged K, Matrix_Jagged Ke) { int Ip, Iq, I1p, I1pi, I1, I2q, I2qk, I2; int NNPE = ElementNodes.Length; int NumberOFPhysics, TotalDoFPerNode; int[] DofPerPhysics; int[] StartIndexPerPhysics = Get_StartIndexForEachPhysics(out NumberOFPhysics, out TotalDoFPerNode, out DofPerPhysics); for (int p = 0; p < NNPE; p++) { Node_ND_Unknowns_MultiPhysics Unknowns_p = (Node_ND_Unknowns_MultiPhysics)ElementNodes[p].Unknowns; I1p = TotalDoFPerNode * p; for (int i = 0; i < NumberOFPhysics; i++) { I1pi = I1p + StartIndexPerPhysics[i]; for (int j = 0; j < DofPerPhysics[i]; j++) { I1 = I1pi + j; Ip = Unknowns_p.UnknownDoFs[PhysicsUsed[i]][j]; for (int q = 0; q < NNPE; q++) { Node_ND_Unknowns_MultiPhysics Unknowns_q = (Node_ND_Unknowns_MultiPhysics)ElementNodes[q].Unknowns; I2q = TotalDoFPerNode * q; for (int k = 0; k < NumberOFPhysics; k++) { I2qk = I2q + StartIndexPerPhysics[k]; for (int l = 0; l < DofPerPhysics[k]; l++) { I2 = I2qk + l; Iq = Unknowns_q.UnknownDoFs[PhysicsUsed[k]][l]; K.Values[Ip][Iq] += Ke.Values[I1][I2]; } } } } } } }
public override Matrix_Jagged IntegralArgument_Ke(Vector Xi) { int NNPE = ElementNodes.Length; double Det_Jac; Vector X; Matrix_Jagged DNDX; Matrix_Jagged Ke_Arg = new Matrix_Jagged(NNPE * 2, NNPE * 2); Interpolator.Calculate_X_DNDX_DetJacobian(Xi, ElementNodes, out X, out DNDX, out Det_Jac); for (int p = 0; p < NNPE; p++)//p defines node number { Node_ND_Unknowns_VectorField Unknown_p = (Node_ND_Unknowns_VectorField)ElementNodes[p].Unknowns; int NDFp = Unknown_p.UnknownDoFs.Length; for (int i = 0; i < NDFp; i++) //loop at x direction { for (int q = 0; q < NNPE; q++) // { Node_ND_Unknowns_VectorField Unknown_q = (Node_ND_Unknowns_VectorField)ElementNodes[q].Unknowns; int NDFq = Unknown_q.UnknownDoFs.Length; for (int j = 0; j < NDFq; j++)//loop at y direction { double temp = 0; for (int m = 0; m < 2; m++) //loop at x direction { for (int n = 0; n < 2; n++) //loop at y direction { double Eimjn = 0; Eimjn = GetE(i, m, j, n);//obtain constitutive matrix temp += DNDX.Values[p][m] * Eimjn * DNDX.Values[q][n]; } } Ke_Arg.Values[NDFp * p + i][NDFq * q + j] = temp * Det_Jac; //store Ke } } } } return(Ke_Arg); }
public virtual void AdjustK(double Time, ref Matrix_Jagged K) { }
public virtual void AdjustC(double Time, ref Matrix_Jagged C) { }
public Vector ForceY; //Force at Y-axis public override void AdjustFAndK(ref Vector F, ref Matrix_Jagged K) { CalculateAndAssemble_Fe(ref F); }
public virtual void AdjustM(double Time, ref Matrix_Jagged M) { }
public override void SolveFEMSystem() { double beta = Newmark_beta; double gamma = Newmark_gamma; //Set up the load vector and stiffness matrix int NDF = Unknowns_NDoF; //Get the size of the unknowns temperature (one per node) Vector F = new Vector(NDF); //Make global load vector (old) Vector F_new = new Vector(NDF); //Make global load vector (new) Matrix_Jagged K = new Matrix_Jagged(NDF, NDF); // Make global stiffness matrix Matrix_Jagged M = new Matrix_Jagged(NDF, NDF); // Make global thermal mass matrix //Assemble F, K, C int NE = Elements.Length; //Get the number of elements for (int i = 0; i < NE; i++) { Elements[i].CalculateAndAssemble_FeAndKeAndMe(ref F, ref K, ref M); } Matrix_Jagged CDamping = ArtificialDamping_Factor_M * M + ArtificialDamping_Factor_K * K; Matrix_Jagged Mhat = M + (gamma * DTime) * CDamping + (beta * DTime * DTime) * K; Mhat.SolveLinearSystem_LUDecomp(); //Adjust for boundary conditions int NBE = BoundaryElements.Length; for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustF(Times.Values[StartIndex], ref F); BoundaryElements[i].AdjustK(Times.Values[StartIndex], ref K); } //Initial conditions Vector u_old = new Vector(Ut[StartIndex]); Vector v_old = new Vector(Vt[StartIndex]); //Initial acceleration Vector a_old = M.SolveLinearSystem(F - K * u_old); Node_ND.Set_UnknownForNode(Nodes, u_old); StoreSensors(StartIndex); double RTime = 0.0D; for (int i = StartIndex; i < NumberOfStepsToStore; i++) { for (int j = 0; j < NumberOfStepsToSkipOutput; j++) { RTime += DTime; //Increment to new time Element_ND.Time = RTime; //Give new time to all elements F_new = new Vector(NDF); for (int k = 0; k < NE; k++) { Elements[k].CalculateAndAssemble_Fe(ref F_new); //Calculate new F } //Adjust new F for BC for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustF(RTime, ref F_new); } //solve for new values u_old += DTime * v_old + (0.5D * DTime * DTime * (1.0D - 2.0D * beta)) * a_old; for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustU(RTime, ref u_old); } v_old += ((1.0D - gamma) * DTime) * a_old; for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustV(RTime, ref v_old); } a_old = Mhat.SolveLinearSystem_BackSub(F_new - CDamping * v_old - K * u_old); u_old += (beta * DTime * DTime) * a_old; for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustU(RTime, ref u_old); } v_old += (gamma * DTime) * a_old; for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustV(RTime, ref v_old); } } Times.Values[i + 1] = RTime; //Store time Ut[i + 1] = new Vector(u_old); //Store vector of node displacements Vt[i + 1] = new Vector(v_old); //Store vector of node velocity Solver_Output_Info.StoreAStep(i + 1, Times.Values[i + 1], Ut[i + 1], Vt[i + 1], DTime, NumberOfStepsToSkipOutput); Solver_Output_Info.SaveToFile(Solver_Output_Info.Make_OuptutAddress()); Node_ND.Set_UnknownForNode(Nodes, u_old); StoreSensors(i + 1); } }