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 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); } }
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_old = 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 C = 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_FeAndKeAndCe(ref F_old, ref K, ref C); } //Adjust for boundary conditions int NBE = BoundaryElements.Length; for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustK(Times.Values[StartIndex], ref K); } K = 0.5 * K; C = C / DTime; Matrix_Jagged C1 = C - K; C = C + K; // Calculate Chat and store in C //Adjust C for boundary condition for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustChat(Times.Values[StartIndex], ref C); } C.SolveLinearSystem_LUDecomp();//Run LU decomposition on C //Adjust F for BC for (int i = 0; i < NBE; i++) { BoundaryElements[i].AdjustF(Times.Values[StartIndex], ref F_old); } F_old = 0.5D * F_old; //Store initial time and temperature Vector U_old = new Vector(Ut[StartIndex]); Vector Fhat; Node_ND.Set_UnknownForNode(Nodes, U_old); StoreSensors(StartIndex); double RTime = Times.Values[StartIndex]; 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); } F_new = 0.5 * F_new; Fhat = F_old + F_new + C1 * U_old; //Get Fhat //Adust Fhat for BC for (int k = 0; k < NBE; k++) { BoundaryElements[k].AdjustFhat(RTime, ref F_new); } U_old = C.SolveLinearSystem_BackSub(Fhat); //Solve for new temperatures F_old = F_new; //Move new F to old F for next step } Times.Values[i + 1] = RTime; //Store time Ut[i + 1] = new Vector(U_old); //Store vector of node temperatures Solver_Output_Info.StoreAStep(i + 1, Times.Values[i + 1], Ut[i + 1], DTime, NumberOfStepsToSkipOutput); Solver_Output_Info.SaveToFile(Solver_Output_Info.Make_OuptutAddress()); Node_ND.Set_UnknownForNode(Nodes, U_old); StoreSensors(i + 1); } }