private void Get_Side_Nodes(Node_ND[] ElementNodes, out int[][] NNPE_Side, out Node_ND[][] Side_Nodes) { NNPE_Side = new int[3][]; NNPE_Side[0] = new int[2]; NNPE_Side[0][0] = NNPE_l; NNPE_Side[0][1] = NNPE_m; NNPE_Side[1] = new int[2]; NNPE_Side[1][0] = NNPE_m; NNPE_Side[1][1] = NNPE_n; NNPE_Side[2] = new int[2]; NNPE_Side[2][0] = NNPE_l; NNPE_Side[2][1] = NNPE_n; int[] NNPS = new int[3]; NNPS[0] = NNPE_l * NNPE_m; NNPS[1] = NNPE_m * NNPE_n; NNPS[2] = NNPE_n * NNPE_l; Side_Nodes = new Node_ND[6][]; for (int i = 0; i < 3; i++) { Side_Nodes[i] = new Node_ND[NNPS[i]]; Side_Nodes[i + 3] = new Node_ND[NNPS[i]]; } int index = 0; for (int j = 0; j < NNPE_m; j++) { for (int i = 0; i < NNPE_l; i++) { Side_Nodes[0][index] = ElementNodes[index]; Side_Nodes[3][index] = ElementNodes[NNPS[0] * (NNPE_n - 1) + index]; index++; } } index = 0; for (int j = 0; j < NNPE_n; j++) { for (int i = 0; i < NNPE_m; i++) { Side_Nodes[1][index] = ElementNodes[j * NNPS[0] + NNPE_l * i]; Side_Nodes[4][index] = ElementNodes[j * NNPS[0] + (NNPE_l - 1) * i]; index++;; } } index = 0; for (int j = 0; j < NNPE_n; j++) { for (int i = 0; i < NNPE_l; i++) { Side_Nodes[2][index] = ElementNodes[j * NNPS[0] + i]; Side_Nodes[5][index] = ElementNodes[j * NNPS[0] + (NNPE_l - 1) + NNPE_l * (NNPE_m - 1) + i]; index++;; } } }
public Element_ND_VectorField(int NNPE) { ElementNodes = new Node_ND[NNPE]; }
/// <summary> /// Developed by: Mehrdad Negahban /// Date: 12/26/2012 /// /// Purpose: CrankNicholson solver using sparse matrix for first order transient problem (C dU/dt + K U = F) /// Comments: /// /// Date modified: /// Modified by: /// Comments: /// </summary> 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) MatrixSparseLinkedList K = new MatrixSparseLinkedList(NDF); // Make global stiffness matrix MatrixSparseLinkedList C = new MatrixSparseLinkedList(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; MatrixSparseLinkedList 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.LUDecomposition_Parallel();//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]); Node_ND.Set_UnknownForNode(Nodes, U_old); StoreSensors(StartIndex); Vector Fhat; 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.Values = C.SolveLinearSystemForwardEliminationAndBackSubstitution(Fhat.Values); //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); } }
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 Element_ND_ScalarField(int NNPE) { ElementNodes = new Node_ND[NNPE]; }
public Element_ND_MultiPhysics(int NNPE, int[] physicsUsed) { ElementNodes = new Node_ND[NNPE]; PhysicsUsed = physicsUsed; }
private void Get_Side_NodesAndNodeLocations(Node_ND[] ElementNodes, out Node_ND[][] Side_Nodes, out Vector[][] Side_NodeLocations_X, out Vector[][] Side_NodeLocations_Xi) { int NNPS = NNPE_m * (NNPE_m - 1) / 2 + NNPE_m; Side_Nodes = new Node_ND[4][]; Side_NodeLocations_X = new Vector[4][]; Side_NodeLocations_Xi = new Vector[4][]; for (int i = 0; i < 4; i++) { Side_Nodes[i] = new Node_ND[NNPS]; Side_NodeLocations_X[i] = new Vector[NNPS]; Side_NodeLocations_Xi[i] = new Vector[NNPS]; } int index = 0; for (int j = 0; j < NNPE_m; j++) { for (int i = 0; i < NNPE_m - j; i++) { Side_Nodes[0][index] = ElementNodes[index]; Side_NodeLocations_X[0][index] = ElementNodes[index].X; Side_NodeLocations_Xi[0][index] = NodeXi[index]; index++; } } index = 0; for (int j = 0; j < NNPE_m; j++) { for (int i = 0; i < NNPE_m - j; i++) { Side_Nodes[1][index] = ElementNodes[index]; Side_NodeLocations_X[1][index] = ElementNodes[index].X; Side_NodeLocations_Xi[1][index] = NodeXi[index]; index += NNPE_m - j - i; } } index = 0; int index_2 = 0; for (int j = 0; j < NNPE_m; j++) { index = index_2; for (int i = 0; i < NNPE_m - j; i++) { Side_Nodes[2][index] = ElementNodes[index]; Side_NodeLocations_X[2][index] = ElementNodes[index].X; Side_NodeLocations_Xi[2][index] = NodeXi[index]; index++; } index_2 += (NNPE_m - j) * (NNPE_m - j - 1) / 2 + NNPE_m - j; } index = 0; index_2 = 0; for (int j = 0; j < NNPE_m; j++) { index = index_2; for (int i = 0; i < NNPE_m - j; i++) { index += NNPE_m - j - i; Side_Nodes[3][index] = ElementNodes[index]; Side_NodeLocations_X[3][index] = ElementNodes[index].X; Side_NodeLocations_Xi[3][index] = NodeXi[index]; } index_2 += (NNPE_m - j) * (NNPE_m - j - 1) / 2 + NNPE_m - j; } }