#include"fvm_gks2d.h" #include"output.h" int gausspoint = 0; //initilization double* gauss_loc = new double[gausspoint]; //initilization double* gauss_weight = new double[gausspoint]; //initilization GKS2d_type gks2dsolver = kfvs1st_2d; //initilization Reconstruction_within_Cell_2D_normal cellreconstruction_2D_normal = Vanleer_normal; //initilization Reconstruction_within_Cell_2D_tangent cellreconstruction_2D_tangent = Vanleer_tangent; //initilization Reconstruction_forG0_2D_normal g0reconstruction_2D_normal = Center_do_nothing_normal; //initilization Reconstruction_forG0_2D_tangent g0reconstruction_2D_tangent = Center_all_collision_multi; //initilization Flux_function_2d flux_function_2d = GKS2D_smooth; //initilization TimeMarchingCoefficient_2d timecoe_list_2d = S1O1_2D; //initilization void SetGuassPoint() { if (gausspoint == 0) { cout << "no gausspoint specify" << endl; exit(0); } if (gausspoint == 1) { gauss_loc = new double[1]; gauss_loc[0] = 0.0; gauss_weight = new double[1]; gauss_weight[0] = 1.0; } if (gausspoint == 2) { gauss_loc = new double[2]; gauss_loc[0] = -sqrt(1.0 / 3.0); gauss_loc[1] = -gauss_loc[0]; gauss_weight = new double[2]; gauss_weight[0] = 0.5; gauss_weight[1] = 0.5; } if (gausspoint == 3) { cout << "the usage of 3 gausspoint may be imcompatiable for some reconstructions" << endl; //exit(0); gauss_loc = new double[3]; gauss_loc[0] = 0.0; gauss_loc[1] = sqrt(3.0 / 5.0); gauss_loc[2] = -gauss_loc[1]; gauss_weight = new double[3]; gauss_weight[0] = 4.0 / 9.0; gauss_weight[1] = 0.5 - 0.5 * gauss_weight[0]; gauss_weight[2] = gauss_weight[1]; } if (gausspoint == 4) { cout << "the usage of 4 gausspoint may be imcompatiable for some reconstructions" << endl; gauss_loc = new double[4]; gauss_weight = new double[4]; gauss_loc[0] = -1.0; gauss_loc[1] = -gauss_loc[0]; gauss_loc[2] = -sqrt(5) / 5.0; gauss_loc[3] = -gauss_loc[2]; gauss_weight[0] = 1.0 / 12.0; gauss_weight[1] = 1.0 / 12.0; gauss_weight[2] = 5.0 / 12.0; gauss_weight[3] = 5.0 / 12.0; } cout << gausspoint << " gausspoint(s) specify" << endl; } double Get_CFL(Block2d& block, Fluid2d* fluids, double tstop) { double dt = fluids[block.ghost * block.ny + block.ghost].dx; for (int i = block.ghost; i < block.nx - block.ghost; i++) { for (int j = block.ghost; j < block.ny - block.ghost; j++) { dt = Dtx(dt, fluids[i * block.ny + j].dx, block.CFL, fluids[i * block.ny + j].primvar[0], fluids[i * block.ny + j].primvar[1], fluids[i * block.ny + j].primvar[2], fluids[i * block.ny + j].primvar[3]); dt = Dtx(dt, fluids[i * block.ny + j].dy, block.CFL, fluids[i * block.ny + j].primvar[0], fluids[i * block.ny + j].primvar[1], fluids[i * block.ny + j].primvar[2], fluids[i * block.ny + j].primvar[3]); } } if (block.t + dt > tstop) { dt = tstop - block.t + 1e-16; cout << "last step here" << endl; } //print time step information if (block.step % 100 == 0) { cout << "step= " << block.step << "time size is " << dt << " time= " << block.t << endl; } return dt; } void A_point(double* a, double* der, double* prim) { double R4, R3, R2; double overden = 1.0 / prim[0]; R4 = der[3] * overden - 0.5 * (prim[1] * prim[1] + prim[2] * prim[2] + 0.5 * (K + 2) / prim[3]) * der[0] * overden; R3 = (der[2] - prim[2] * der[0]) * overden; R2 = (der[1] - prim[1] * der[0]) * overden; a[3] = (4.0 / (K + 2)) * prim[3] * prim[3] * (2 * R4 - 2 * prim[1] * R2 - 2 * prim[2] * R3); a[2] = 2 * prim[3] * R3 - prim[2] * a[3]; a[1] = 2 * prim[3] * R2 - prim[1] * a[3]; a[0] = der[0] * overden - prim[1] * a[1] - prim[2] * a[2] - 0.5 * a[3] * (prim[1] * prim[1] + prim[2] * prim[2] + 0.5 * (K + 2) / prim[3]); } void G_address(int no_u, int no_v, int no_xi, double* psi, double a[4], MMDF& m) { psi[0] = a[0] * m.uvxi[no_u][no_v][no_xi] + a[1] * m.uvxi[no_u + 1][no_v][no_xi] + a[2] * m.uvxi[no_u][no_v + 1][no_xi] + a[3] * 0.5 * (m.uvxi[no_u + 2][no_v][no_xi] + m.uvxi[no_u][no_v + 2][no_xi] + m.uvxi[no_u][no_v][no_xi + 1]); psi[1] = a[0] * m.uvxi[no_u + 1][no_v][no_xi] + a[1] * m.uvxi[no_u + 2][no_v][no_xi] + a[2] * m.uvxi[no_u + 1][no_v + 1][no_xi] + a[3] * 0.5 * (m.uvxi[no_u + 3][no_v][no_xi] + m.uvxi[no_u + 1][no_v + 2][no_xi] + m.uvxi[no_u + 1][no_v][no_xi + 1]); psi[2] = a[0] * m.uvxi[no_u][no_v + 1][no_xi] + a[1] * m.uvxi[no_u + 1][no_v + 1][no_xi] + a[2] * m.uvxi[no_u][no_v + 2][no_xi] + a[3] * 0.5 * (m.uvxi[no_u + 2][no_v + 1][no_xi] + m.uvxi[no_u][no_v + 3][no_xi] + m.uvxi[no_u][no_v + 1][no_xi + 1]); psi[3] = 0.5 * (a[0] * (m.uvxi[no_u + 2][no_v][no_xi] + m.uvxi[no_u][no_v + 2][no_xi] + m.uvxi[no_u][no_v][no_xi + 1]) + a[1] * (m.uvxi[no_u + 3][no_v][no_xi] + m.uvxi[no_u + 1][no_v + 2][no_xi] + m.uvxi[no_u + 1][no_v][no_xi + 1]) + a[2] * (m.uvxi[no_u + 2][no_v + 1][no_xi] + m.uvxi[no_u][no_v + 3][no_xi] + m.uvxi[no_u][no_v + 1][no_xi + 1]) + a[3] * 0.5 * (m.uvxi[no_u + 4][no_v][no_xi] + m.uvxi[no_u][no_v + 4][no_xi] + m.uvxi[no_u][no_v][no_xi + 2] + 2 * m.uvxi[no_u + 2][no_v + 2][no_xi] + 2 * m.uvxi[no_u + 2][no_v][no_xi + 1] + 2 * m.uvxi[no_u][no_v + 2][no_xi + 1])); } void GL_address(int no_u, int no_v, int no_xi, double* psi, double a[4], MMDF& m) { psi[0] = a[0] * m.upvxi[no_u][no_v][no_xi] + a[1] * m.upvxi[no_u + 1][no_v][no_xi] + a[2] * m.upvxi[no_u][no_v + 1][no_xi] + a[3] * 0.5 * (m.upvxi[no_u + 2][no_v][no_xi] + m.upvxi[no_u][no_v + 2][no_xi] + m.upvxi[no_u][no_v][no_xi + 1]); psi[1] = a[0] * m.upvxi[no_u + 1][no_v][no_xi] + a[1] * m.upvxi[no_u + 2][no_v][no_xi] + a[2] * m.upvxi[no_u + 1][no_v + 1][no_xi] + a[3] * 0.5 * (m.upvxi[no_u + 3][no_v][no_xi] + m.upvxi[no_u + 1][no_v + 2][no_xi] + m.upvxi[no_u + 1][no_v][no_xi + 1]); psi[2] = a[0] * m.upvxi[no_u][no_v + 1][no_xi] + a[1] * m.upvxi[no_u + 1][no_v + 1][no_xi] + a[2] * m.upvxi[no_u][no_v + 2][no_xi] + a[3] * 0.5 * (m.upvxi[no_u + 2][no_v + 1][no_xi] + m.upvxi[no_u][no_v + 3][no_xi] + m.upvxi[no_u][no_v + 1][no_xi + 1]); psi[3] = 0.5 * (a[0] * (m.upvxi[no_u + 2][no_v][no_xi] + m.upvxi[no_u][no_v + 2][no_xi] + m.upvxi[no_u][no_v][no_xi + 1]) + a[1] * (m.upvxi[no_u + 3][no_v][no_xi] + m.upvxi[no_u + 1][no_v + 2][no_xi] + m.upvxi[no_u + 1][no_v][no_xi + 1]) + a[2] * (m.upvxi[no_u + 2][no_v + 1][no_xi] + m.upvxi[no_u][no_v + 3][no_xi] + m.upvxi[no_u][no_v + 1][no_xi + 1]) + a[3] * 0.5 * (m.upvxi[no_u + 4][no_v][no_xi] + m.upvxi[no_u][no_v + 4][no_xi] + m.upvxi[no_u][no_v][no_xi + 2] + 2 * m.upvxi[no_u + 2][no_v + 2][no_xi] + 2 * m.upvxi[no_u + 2][no_v][no_xi + 1] + 2 * m.upvxi[no_u][no_v + 2][no_xi + 1])); } void GR_address(int no_u, int no_v, int no_xi, double* psi, double a[4], MMDF& m) { // Similar to the GL_address psi[0] = a[0] * m.unvxi[no_u][no_v][no_xi] + a[1] * m.unvxi[no_u + 1][no_v][no_xi] + a[2] * m.unvxi[no_u][no_v + 1][no_xi] + a[3] * 0.5 * (m.unvxi[no_u + 2][no_v][no_xi] + m.unvxi[no_u][no_v + 2][no_xi] + m.unvxi[no_u][no_v][no_xi + 1]); psi[1] = a[0] * m.unvxi[no_u + 1][no_v][no_xi] + a[1] * m.unvxi[no_u + 2][no_v][no_xi] + a[2] * m.unvxi[no_u + 1][no_v + 1][no_xi] + a[3] * 0.5 * (m.unvxi[no_u + 3][no_v][no_xi] + m.unvxi[no_u + 1][no_v + 2][no_xi] + m.unvxi[no_u + 1][no_v][no_xi + 1]); psi[2] = a[0] * m.unvxi[no_u][no_v + 1][no_xi] + a[1] * m.unvxi[no_u + 1][no_v + 1][no_xi] + a[2] * m.unvxi[no_u][no_v + 2][no_xi] + a[3] * 0.5 * (m.unvxi[no_u + 2][no_v + 1][no_xi] + m.unvxi[no_u][no_v + 3][no_xi] + m.unvxi[no_u][no_v + 1][no_xi + 1]); psi[3] = 0.5 * (a[0] * (m.unvxi[no_u + 2][no_v][no_xi] + m.unvxi[no_u][no_v + 2][no_xi] + m.unvxi[no_u][no_v][no_xi + 1]) + a[1] * (m.unvxi[no_u + 3][no_v][no_xi] + m.unvxi[no_u + 1][no_v + 2][no_xi] + m.unvxi[no_u + 1][no_v][no_xi + 1]) + a[2] * (m.unvxi[no_u + 2][no_v + 1][no_xi] + m.unvxi[no_u][no_v + 3][no_xi] + m.unvxi[no_u][no_v + 1][no_xi + 1]) + a[3] * 0.5 * (m.unvxi[no_u + 4][no_v][no_xi] + m.unvxi[no_u][no_v + 4][no_xi] + m.unvxi[no_u][no_v][no_xi + 2] + 2 * m.unvxi[no_u + 2][no_v + 2][no_xi] + 2 * m.unvxi[no_u + 2][no_v][no_xi + 1] + 2 * m.unvxi[no_u][no_v + 2][no_xi + 1])); } void free_boundary_left(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.ghost - 1; i >= 0; i--) { for (int j = 0; j < block.ny; j++) { fluids[i * block.ny + j].convar[0] = fluids[(i + 1) * block.ny + j].convar[0]; fluids[i * block.ny + j].convar[1] = fluids[(i + 1) * block.ny + j].convar[1]; fluids[i * block.ny + j].convar[2] = fluids[(i + 1) * block.ny + j].convar[2]; fluids[i * block.ny + j].convar[3] = fluids[(i + 1) * block.ny + j].convar[3]; } } } void free_boundary_right(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.nx - block.ghost; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { fluids[i * block.ny + j].convar[0] = fluids[(i - 1) * block.ny + j].convar[0]; fluids[i * block.ny + j].convar[1] = fluids[(i - 1) * block.ny + j].convar[1]; fluids[i * block.ny + j].convar[2] = fluids[(i - 1) * block.ny + j].convar[2]; fluids[i * block.ny + j].convar[3] = fluids[(i - 1) * block.ny + j].convar[3]; } } } void free_boundary_down(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int j = block.ghost - 1; j >= 0; j--) { for (int i = 0; i < block.nx; i++) { fluids[i * block.ny + j].convar[0] = fluids[i * block.ny + j + 1].convar[0]; fluids[i * block.ny + j].convar[1] = fluids[i * block.ny + j + 1].convar[1]; fluids[i * block.ny + j].convar[2] = fluids[i * block.ny + j + 1].convar[2]; fluids[i * block.ny + j].convar[3] = fluids[i * block.ny + j + 1].convar[3]; } } } void free_boundary_up(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int j = block.ny - block.ghost; j < block.ny; j++) { for (int i = 0; i < block.nx; i++) { fluids[i * block.ny + j].convar[0] = fluids[i * block.ny + j - 1].convar[0]; fluids[i * block.ny + j].convar[1] = fluids[i * block.ny + j - 1].convar[1]; fluids[i * block.ny + j].convar[2] = fluids[i * block.ny + j - 1].convar[2]; fluids[i * block.ny + j].convar[3] = fluids[i * block.ny + j - 1].convar[3]; } } } void periodic_boundary_left(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.ghost - 1; i >= 0; i--) { int tar = i + block.nodex; for (int j = 0; j < block.ny; j++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].convar[var] = fluids[tar * block.ny + j].convar[var]; } } } } void periodic_boundary_right(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.nx - block.ghost; i < block.nx; i++) { int tar = i - block.nodex; for (int j = 0; j < block.ny; j++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].convar[var] = fluids[tar * block.ny + j].convar[var]; } } } } void periodic_boundary_down(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int j = block.ghost - 1; j >= 0; j--) { int tar = j + block.nodey; for (int i = 0; i < block.nx; i++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].convar[var] = fluids[i * block.ny + tar].convar[var]; } } } } void periodic_boundary_up(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int j = block.ny - block.ghost; j < block.ny; j++) { int tar = j - block.nodey; for (int i = 0; i < block.nx; i++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].convar[var] = fluids[i * block.ny + tar].convar[var]; } } } } void noslip_adiabatic_boundary_left(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int i = order - 1; i >= 0; i--) { for (int j = 0; j < block.ny; j++) { int index = i * block.ny + j; int ref = (2 * order - 1 - i) * block.ny + j; fluids[index].convar[0] = fluids[ref].convar[0]; fluids[index].convar[1] = 2 * fluids[index].convar[0] * bcvalue.primvar[1] - fluids[ref].convar[1]; fluids[index].convar[2] = 2 * fluids[index].convar[0] * bcvalue.primvar[2] - fluids[ref].convar[2]; fluids[index].convar[3] = fluids[ref].convar[3]; } } } void noslip_adiabatic_boundary_right(Fluid2d* fluids, Interface2d* face, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int i = block.nx - order; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { int index = i * block.ny + j; int ref = (2 * block.nx - 2 * order - 1 - i) * block.ny + j; int face_index = (2 * block.nx - 2 * order - 1 - i) * (block.ny + 1) + j; noslip_adiabatic_boundary(fluids[index].convar, fluids[ref].convar, face[face_index].normal, &bcvalue.primvar[1]); } } } void noslip_adiabatic_boundary(double* w_ghost, double* w_inner, double* normal, double* local_wall_velocity) { double inner[4]; Copy_Array(inner, w_inner, 4); Global_to_Local(inner, normal); inner[1] = 2 * local_wall_velocity[0] - inner[1]; inner[2] = 2 * local_wall_velocity[1] - inner[2]; Local_to_Global(inner, normal); Copy_Array(w_ghost, inner, 4); } void noslip_adiabatic_boundary_down(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int j = order - 1; j >= 0; j--) { for (int i = 0; i < block.nx; i++) { int index = i * block.ny + j; int ref = (i)*block.ny + 2 * order - 1 - j; fluids[index].convar[0] = fluids[ref].convar[0]; fluids[index].convar[1] = 2 * fluids[index].convar[0] * bcvalue.primvar[1] - fluids[ref].convar[1]; fluids[index].convar[2] = 2 * fluids[index].convar[0] * bcvalue.primvar[2] - fluids[ref].convar[2]; fluids[index].convar[3] = fluids[ref].convar[3]; } } } void noslip_adiabatic_boundary_up(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int j = block.ny - order; j < block.ny; j++) { for (int i = 0; i < block.nx; i++) { int index = i * block.ny + j; int ref = (i)*block.ny + 2 * block.ny - 2 * order - 1 - j; fluids[index].convar[0] = fluids[ref].convar[0]; fluids[index].convar[1] = 2 * fluids[index].convar[0] * bcvalue.primvar[1] - fluids[ref].convar[1]; fluids[index].convar[2] = 2 * fluids[index].convar[0] * bcvalue.primvar[2] - fluids[ref].convar[2]; fluids[index].convar[3] = fluids[ref].convar[3]; } } } void reflection_boundary_up(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int j = block.ny - order; j < block.ny; j++) { for (int i = 0; i < block.nx; i++) { int index = i * block.ny + j; int ref = (i)*block.ny + 2 * block.ny - 2 * order - 1 - j; fluids[index].convar[0] = fluids[ref].convar[0]; fluids[index].convar[1] = fluids[ref].convar[1]; fluids[index].convar[2] = -fluids[ref].convar[2]; fluids[index].convar[3] = fluids[ref].convar[3]; } } } void reflection_boundary_down(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int j = order - 1; j >= 0; j--) { for (int i = 0; i < block.nx; i++) { int index = i * block.ny + j; int ref = (i)*block.ny + 2 * order - 1 - j; fluids[index].convar[0] = fluids[ref].convar[0]; fluids[index].convar[1] = fluids[ref].convar[1]; fluids[index].convar[2] = -fluids[ref].convar[2]; fluids[index].convar[3] = fluids[ref].convar[3]; } } } void reflection_boundary_right(Fluid2d* fluids, Interface2d* face, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int i = block.nx - order; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { int index = i * block.ny + j; int ref = (2 * block.nx - 2 * order - 1 - i) * block.ny + j; int face_index = (2 * block.nx - 2 * order - 1 - i) * (block.ny + 1) + j; reflection_boundary(fluids[index].convar, fluids[ref].convar, face[face_index].normal); } } } void reflection_boundary_left(Fluid2d* fluids, Interface2d* face, Block2d block, Fluid2d bcvalue) { int order = block.ghost; for (int i = order - 1; i >= 0; i--) { for (int j = 0; j < block.ny; j++) { int index = i * block.ny + j; int ref = (2 * order - 1 - i) * block.ny + j; int face_index = order * (block.ny + 1) + j; reflection_boundary(fluids[index].convar, fluids[ref].convar, face[face_index].normal); } } } void reflection_boundary(double* w_ghost, double* w_inner, double* normal) { double inner[4]; Copy_Array(inner, w_inner, 4); Global_to_Local(inner, normal); inner[1] = -inner[1]; Local_to_Global(inner, normal); Copy_Array(w_ghost, inner, 4); } void inflow_boundary_left(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.ghost - 1; i >= 0; i--) { for (int j = 0; j < block.ny; j++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].primvar[var] = bcvalue.primvar[var]; } Primvar_to_convar_2D(fluids[i * block.ny + j].convar, fluids[i * block.ny + j].primvar); } } } void inflow_boundary_right(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int i = block.nx - block.ghost; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].primvar[var] = bcvalue.primvar[var]; } Primvar_to_convar_2D(fluids[i * block.ny + j].convar, fluids[i * block.ny + j].primvar); } } } void inflow_boundary_up(Fluid2d* fluids, Block2d block, Fluid2d bcvalue) { for (int j = block.ny - block.ghost; j < block.ny; j++) { for (int i = 0; i < block.nx; i++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].primvar[var] = bcvalue.primvar[var]; } Primvar_to_convar_2D(fluids[i * block.ny + j].convar, fluids[i * block.ny + j].primvar); } } } void ICfor_uniform_2d(Fluid2d* fluid, double* prim, Block2d block) { for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { fluid[i * block.ny + j].primvar[0] = prim[0]; fluid[i * block.ny + j].primvar[1] = prim[1]; fluid[i * block.ny + j].primvar[2] = prim[2]; fluid[i * block.ny + j].primvar[3] = prim[3]; } } for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { Primvar_to_convar_2D(fluid[i * block.ny + j].convar, fluid[i * block.ny + j].primvar); } } } bool negative_density_or_pressure(double* primvar) { //detect whether density or pressure is negative if (primvar[0] < 0 || primvar[3] < 0 || isnan(primvar[0]) || isnan(primvar[3])) { return true; } else { return false; } } void Convar_to_Primvar(Fluid2d* fluids, Block2d block) { bool all_positive = true; #pragma omp parallel for for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { Convar_to_primvar_2D(fluids[i * block.ny + j].primvar, fluids[i * block.ny + j].convar); if (negative_density_or_pressure(fluids[i * block.ny + j].primvar)) { all_positive = false; } } } if (all_positive == false) { cout << "the program blows up at t=" << block.t << "!" << endl; output2d_blow_up(fluids, block); exit(0); } } void Convar_to_primvar(Fluid2d* fluid, Block2d block) { #pragma omp parallel for for (int i = 0; i < block.nx * block.ny; i++) { Convar_to_primvar_2D(fluid[i].primvar, fluid[i].convar); } } void YchangetoX(double* fluidtmp, double* fluid) { fluidtmp[0] = fluid[0]; fluidtmp[1] = fluid[2]; fluidtmp[2] = -fluid[1]; fluidtmp[3] = fluid[3]; } void XchangetoY(double* fluidtmp, double* fluid) { fluidtmp[0] = fluid[0]; fluidtmp[1] = -fluid[2]; fluidtmp[2] = fluid[1]; fluidtmp[3] = fluid[3]; } void CopyFluid_new_to_old(Fluid2d* fluids, Block2d block) { #pragma omp parallel for for (int i = block.ghost; i < block.ghost + block.nodex; i++) { for (int j = block.ghost; j < block.ghost + block.nodey; j++) { for (int var = 0; var < 4; var++) { fluids[i * block.ny + j].convar_old[var] = fluids[i * block.ny + j].convar[var]; } } } } void Reconstruction_within_cell(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { #pragma omp parallel for for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { cellreconstruction_2D_normal (xinterfaces[i * (block.ny + 1) + j], xinterfaces[(i + 1) * (block.ny + 1) + j], yinterfaces[i * (block.ny + 1) + j], yinterfaces[i * (block.ny + 1) + j + 1], &fluids[i * block.ny + j], block); } } #pragma omp parallel for for (int i = block.ghost - 1; i < block.nx - block.ghost + 1; i++) { for (int j = block.ghost - 1; j < block.ny - block.ghost + 1; j++) { cellreconstruction_2D_tangent (&xinterfaces[i * (block.ny + 1) + j], &xinterfaces[(i + 1) * (block.ny + 1) + j], &yinterfaces[i * (block.ny + 1) + j], &yinterfaces[i * (block.ny + 1) + j + 1], &fluids[i * block.ny + j], block); } } } void First_order_normal(Interface2d& left, Interface2d& right, Interface2d& down, Interface2d& up, Fluid2d* fluids, Block2d block) { first_order(left.line.right, right.line.left, left.normal, right.normal, fluids[0].convar); first_order(down.line.right, up.line.left, down.normal, up.normal, fluids[0].convar); } void first_order(Point2d& left, Point2d& right, double* normal_l, double* normal_r, double* w) { double splus[4], sminus[4]; double w_l[4]; Global_to_Local(w_l, w, normal_l); Copy_Array(left.convar, w_l, 4); Array_zero(left.der1x, 4); double w_r[4]; Global_to_Local(w_r, w, normal_r); Copy_Array(right.convar, w_r, 4); Array_zero(right.der1x, 4); } void Vanleer_normal(Interface2d& left, Interface2d& right, Interface2d& down, Interface2d& up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Vanleer(left.line.right, right.line.left, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, block.dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double wn1tmp[4], wtmp[4], wp1tmp[4]; YchangetoX(wn1tmp, fluids[-1].convar); YchangetoX(wtmp, fluids[0].convar); YchangetoX(wp1tmp, fluids[1].convar); Vanleer(down.line.right, up.line.left, wn1tmp, wtmp, wp1tmp, block.dy); } } else { double h = fluids[0].dx; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Vanleer_non_uniform(left.line.right, right.line.left, left.normal, right.normal, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, h); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { h = fluids[0].dy; Vanleer_non_uniform(down.line.right, up.line.left, down.normal, up.normal, fluids[-1].convar, fluids[0].convar, fluids[1].convar, h); } } } void Vanleer(Point2d& left, Point2d& right, double* wn1, double* w, double* wp1, double h) { double splus[4], sminus[4]; for (int i = 0; i < 4; i++) { splus[i] = (wp1[i] - w[i]) / h; sminus[i] = (w[i] - wn1[i]) / h; } for (int i = 0; i < 4; i++) { if ((splus[i] * sminus[i]) > 0) { left.der1x[i] = 2 * splus[i] * sminus[i] / (splus[i] + sminus[i]); right.der1x[i] = left.der1x[i]; } else { left.der1x[i] = 0.0; right.der1x[i] = 0.0; } left.convar[i] = w[i] - 0.5 * h * left.der1x[i]; right.convar[i] = w[i] + 0.5 * h * right.der1x[i]; } //if lambda <0, then reduce to the first order Check_Order_Reduce_by_Lambda_2D(left.is_reduce_order, left.convar); Check_Order_Reduce_by_Lambda_2D(right.is_reduce_order, right.convar); if (left.is_reduce_order == true) { if (is_reduce_order_warning == true) { cout << "order reduce on left interface x= " << left.x << " y= " << left.y << endl; } for (int m = 0; m < 4; m++) { left.convar[m] = wn1[m]; } left.is_reduce_order = true; } if (right.is_reduce_order == true) { if (is_reduce_order_warning == true) { cout << "order reduce on right interface x= " << right.x << " y= " << right.y << endl; } for (int m = 0; m < 4; m++) { right.convar[m] = wp1[m]; } right.is_reduce_order = true; } } void WENO3_normal(Interface2d& left, Interface2d& right, Interface2d& down, Interface2d& up, Fluid2d* fluids, Block2d block) { //for non-uniform mesh. Point2d voidpoint; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = fluids[0].dx; double normal[2]; double wn1tmp[4], wtmp[4], wp1tmp[4]; //cell left reconstruction Copy_Array(normal, left.normal, 2); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); WENO3(left.line.right, voidpoint, wn1tmp, wtmp, wp1tmp, dx); //cell right reconstruction Copy_Array(normal, right.normal, 2); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); WENO3(voidpoint, right.line.left, wn1tmp, wtmp, wp1tmp, dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = fluids[0].dy; double normal[2]; double wn1tmp[4], wtmp[4], wp1tmp[4]; //down interface reconstruction Copy_Array(normal, down.normal, 2); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); WENO3(down.line.right, voidpoint, wn1tmp, wtmp, wp1tmp, dy); //up interface reconstruction Copy_Array(normal, up.normal, 2); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); WENO3(voidpoint, up.line.left, wn1tmp, wtmp, wp1tmp, dy); } } void WENO3(Point2d& left, Point2d& right, double* wn1, double* w, double* wp1, double h) { //we denote that |left...cell-center...right| double ren1[4], re0[4], rep1[4]; double var[4], der1[4], der2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(wn1_primvar, wn1); Convar_to_primvar_2D(w_primvar, w); Convar_to_primvar_2D(wp1_primvar, wp1); for (int i = 0; i < 4; i++) { base_left[i] = 0.5 * (wn1_primvar[i] + w_primvar[i]); base_right[i] = 0.5 * (wp1_primvar[i] + w_primvar[i]); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; } } else if (reconstruction_variable == characteristic) { Convar_to_char(ren1, base_left, wn1); Convar_to_char(re0, base_left, w); Convar_to_char(rep1, base_left, wp1); } for (int i = 0; i < 4; i++) { weno_3rd_left(var[i], der1[i], der2[i], ren1[i], re0[i], rep1[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { left.convar[i] = var[i]; left.der1x[i] = der1[i]; } } else { Char_to_convar(left.convar, base_left, var); Char_to_convar(left.der1x, base_left, der1); } // cell right if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; } } else { Convar_to_char(ren1, base_right, wn1); Convar_to_char(re0, base_right, w); Convar_to_char(rep1, base_right, wp1); } for (int i = 0; i < 4; i++) { weno_3rd_right(var[i], der1[i], der2[i], ren1[i], re0[i], rep1[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { right.convar[i] = var[i]; right.der1x[i] = der1[i]; } } else { Char_to_convar(right.convar, base_right, var); Char_to_convar(right.der1x, base_right, der1); } Check_Order_Reduce_by_Lambda_2D(right.is_reduce_order, right.convar); Check_Order_Reduce_by_Lambda_2D(left.is_reduce_order, left.convar); if (left.is_reduce_order == true || right.is_reduce_order == true) { if (is_reduce_order_warning == true) cout << " WENO5-cell-splitting order reduce" << endl; for (int m = 0; m < 4; m++) { right.convar[m] = w[m]; left.convar[m] = w[m]; right.der1x[m] = 0.0; left.der1x[m] = 0.0; } } } void Vanleer_non_uniform(Point2d& left, Point2d& right, double* normal_l, double* normal_r, double* wn1, double* w, double* wp1, double h) { double splus[4], sminus[4]; double wn1_l[4], w_l[4], wp1_l[4]; Global_to_Local(wn1_l, wn1, normal_l); Global_to_Local(w_l, w, normal_l); Global_to_Local(wp1_l, wp1, normal_l); for (int i = 0; i < 4; i++) { splus[i] = (wp1_l[i] - w_l[i]) / h; sminus[i] = (w_l[i] - wn1_l[i]) / h; } for (int i = 0; i < 4; i++) { if ((splus[i] * sminus[i]) > 0) { left.der1x[i] = 2 * splus[i] * sminus[i] / (splus[i] + sminus[i]); } else { left.der1x[i] = 0.0; } left.convar[i] = w_l[i] - 0.5 * h * left.der1x[i]; } double wn1_r[4], w_r[4], wp1_r[4]; Global_to_Local(wn1_r, wn1, normal_r); Global_to_Local(w_r, w, normal_r); Global_to_Local(wp1_r, wp1, normal_r); for (int i = 0; i < 4; i++) { splus[i] = (wp1_r[i] - w_r[i]) / h; sminus[i] = (w_r[i] - wn1_r[i]) / h; } for (int i = 0; i < 4; i++) { if ((splus[i] * sminus[i]) > 0) { right.der1x[i] = 2 * splus[i] * sminus[i] / (splus[i] + sminus[i]); } else { right.der1x[i] = 0.0; } right.convar[i] = w_r[i] + 0.5 * h * right.der1x[i]; } //if lambda <0, then reduce to the first order Check_Order_Reduce_by_Lambda_2D(left.is_reduce_order, left.convar); Check_Order_Reduce_by_Lambda_2D(right.is_reduce_order, right.convar); if (left.is_reduce_order == true) { if (is_reduce_order_warning == true) { cout << "order reduce on left interface x= " << left.x << " y= " << left.y << endl; } for (int m = 0; m < 4; m++) { left.convar[m] = w_l[m]; } left.is_reduce_order = true; } if (right.is_reduce_order == true) { if (is_reduce_order_warning == true) { cout << "order reduce on right interface x= " << right.x << " y= " << right.y << endl; } for (int m = 0; m < 4; m++) { right.convar[m] = w_r[m]; } right.is_reduce_order = true; } } void WENO5_normal(Interface2d& left, Interface2d& right, Interface2d& down, Interface2d& up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { WENO(left.line.right, right.line.left, fluids[-2 * block.ny].convar, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, fluids[2 * block.ny].convar , fluids[0].dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; YchangetoX(wn1tmp, fluids[-1].convar); YchangetoX(wtmp, fluids[0].convar); YchangetoX(wp1tmp, fluids[1].convar); YchangetoX(wn2tmp, fluids[-2].convar); YchangetoX(wp2tmp, fluids[2].convar); WENO(down.line.right, up.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, fluids[0].dy); } } else { //for non-uniform mesh. Point2d voidpoint; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = fluids[0].dx; double normal[2]; double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; //cell left reconstruction Copy_Array(normal, left.normal, 2); Global_to_Local(wn2tmp, fluids[-2 * block.ny].convar, normal); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); Global_to_Local(wp2tmp, fluids[2 * block.ny].convar, normal); WENO(left.line.right, voidpoint, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dx); //cell right reconstruction Copy_Array(normal, right.normal, 2); Global_to_Local(wn2tmp, fluids[-2 * block.ny].convar, normal); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); Global_to_Local(wp2tmp, fluids[2 * block.ny].convar, normal); WENO(voidpoint, right.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = fluids[0].dy; double normal[2]; double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; //down interface reconstruction Copy_Array(normal, down.normal, 2); Global_to_Local(wn2tmp, fluids[-2].convar, normal); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); Global_to_Local(wp2tmp, fluids[2].convar, normal); WENO(down.line.right, voidpoint, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dy); //up interface reconstruction Copy_Array(normal, up.normal, 2); Global_to_Local(wn2tmp, fluids[-2].convar, normal); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); Global_to_Local(wp2tmp, fluids[2].convar, normal); WENO(voidpoint, up.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dy); } } } void WENO(Point2d& left, Point2d& right, double* wn2, double* wn1, double* w, double* wp1, double* wp2, double h) { //we denote that |left...cell-center...right| double ren2[4], ren1[4], re0[4], rep1[4], rep2[4]; double var[4], der1[4], der2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(wn1_primvar, wn1); Convar_to_primvar_2D(w_primvar, w); Convar_to_primvar_2D(wp1_primvar, wp1); for (int i = 0; i < 4; i++) { base_left[i] = 0.5 * (wn1_primvar[i] + w_primvar[i]); base_right[i] = 0.5 * (wp1_primvar[i] + w_primvar[i]); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_left, wn2); Convar_to_char(ren1, base_left, wn1); Convar_to_char(re0, base_left, w); Convar_to_char(rep1, base_left, wp1); Convar_to_char(rep2, base_left, wp2); } for (int i = 0; i < 4; i++) { WENO5_left(var[i], der1[i], der2[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { left.convar[i] = var[i]; left.der1x[i] = der1[i]; } } else { Char_to_convar(left.convar, base_left, var); Char_to_convar(left.der1x, base_left, der1); } // cell right if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_right, wn2); Convar_to_char(ren1, base_right, wn1); Convar_to_char(re0, base_right, w); Convar_to_char(rep1, base_right, wp1); Convar_to_char(rep2, base_right, wp2); } for (int i = 0; i < 4; i++) { WENO5_right(var[i], der1[i], der2[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { right.convar[i] = var[i]; right.der1x[i] = der1[i]; } } else { Char_to_convar(right.convar, base_right, var); Char_to_convar(right.der1x, base_right, der1); } Check_Order_Reduce_by_Lambda_2D(right.is_reduce_order, right.convar); Check_Order_Reduce_by_Lambda_2D(left.is_reduce_order, left.convar); if (left.is_reduce_order == true || right.is_reduce_order == true) { if (is_reduce_order_warning == true) cout << " WENO5-cell-splitting order reduce" << endl; for (int m = 0; m < 4; m++) { right.convar[m] = w[m]; left.convar[m] = w[m]; right.der1x[m] = 0.0; left.der1x[m] = 0.0; } } } void WENO5_left(double& var, double& der1, double& der2, double wn2, double wn1, double w, double wp1, double wp2, double h) { double qleft[3]; double qright[3]; double dleft[3]; double dright[3]; qleft[0] = 11.0 / 6.0 * w - 7.0 / 6.0 * wp1 + 1.0 / 3.0 * wp2; qleft[1] = 1.0 / 3.0 * wn1 + 5.0 / 6.0 * w - 1.0 / 6.0 * wp1; qleft[2] = -1.0 / 6.0 * wn2 + 5.0 / 6.0 * wn1 + 1.0 / 3.0 * w; dleft[0] = 0.1; dleft[1] = 0.6; dleft[2] = 0.3; qright[0] = 1.0 / 3.0 * w + 5.0 / 6.0 * wp1 - 1.0 / 6.0 * wp2; qright[1] = -1.0 / 6.0 * wn1 + 5.0 / 6.0 * w + 1.0 / 3.0 * wp1; qright[2] = 1.0 / 3.0 * wn2 - 7.0 / 6.0 * wn1 + 11.0 / 6.0 * w; dright[0] = 0.3; dright[1] = 0.6; dright[2] = 0.1; double beta[3]; beta[0] = 13.0 / 12.0 * pow((w - 2 * wp1 + wp2), 2) + 0.25 * pow((3 * w - 4 * wp1 + wp2), 2); beta[1] = 13.0 / 12.0 * pow((wn1 - 2 * w + wp1), 2) + 0.25 * pow((wn1 - wp1), 2); beta[2] = 13.0 / 12.0 * pow((wn2 - 2 * wn1 + w), 2) + 0.25 * pow((wn2 - 4 * wn1 + 3 * w), 2); double epsilon = 1e-8; double alphaleft[3]; double alpharight[3]; if (wenotype == wenojs) { for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); alpharight[i] = dright[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); } } if (wenotype == wenoz) { double tau5 = abs(beta[0] - beta[2]); for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] * (1 + tau5 / (beta[i] + epsilon)); alpharight[i] = dright[i] * (1 + tau5 / (beta[i] + epsilon)); } } if (wenotype == linear) { for (int k = 0; k < 3; k++) { alphaleft[k] = dleft[k]; alpharight[k] = dright[k]; } } double alphal = alphaleft[0] + alphaleft[1] + alphaleft[2]; double omegaleft[3]; omegaleft[0] = alphaleft[0] / alphal; omegaleft[1] = alphaleft[1] / alphal; omegaleft[2] = alphaleft[2] / alphal; double left = omegaleft[0] * qleft[0] + omegaleft[1] * qleft[1] + omegaleft[2] * qleft[2]; double alphar = alpharight[0] + alpharight[1] + alpharight[2]; double omegaright[3]; omegaright[0] = alpharight[0] / alphar; omegaright[1] = alpharight[1] / alphar; omegaright[2] = alpharight[2] / alphar; double right = omegaright[0] * qright[0] + omegaright[1] * qright[1] + omegaright[2] * qright[2]; var = left; der2 = 6 * (left + right - 2 * w) / (h * h); der1 = (right - left) / h - 0.5 * h * der2; } void WENO5_right(double& var, double& der1, double& der2, double wn2, double wn1, double w, double wp1, double wp2, double h) { double qleft[3]; double qright[3]; double dleft[3]; double dright[3]; qleft[0] = 11.0 / 6.0 * w - 7.0 / 6.0 * wp1 + 1.0 / 3.0 * wp2; qleft[1] = 1.0 / 3.0 * wn1 + 5.0 / 6.0 * w - 1.0 / 6.0 * wp1; qleft[2] = -1.0 / 6.0 * wn2 + 5.0 / 6.0 * wn1 + 1.0 / 3.0 * w; dleft[0] = 0.1; dleft[1] = 0.6; dleft[2] = 0.3; qright[0] = 1.0 / 3.0 * w + 5.0 / 6.0 * wp1 - 1.0 / 6.0 * wp2; qright[1] = -1.0 / 6.0 * wn1 + 5.0 / 6.0 * w + 1.0 / 3.0 * wp1; qright[2] = 1.0 / 3.0 * wn2 - 7.0 / 6.0 * wn1 + 11.0 / 6.0 * w; dright[0] = 0.3; dright[1] = 0.6; dright[2] = 0.1; double beta[3]; beta[0] = 13.0 / 12.0 * pow((w - 2 * wp1 + wp2), 2) + 0.25 * pow((3 * w - 4 * wp1 + wp2), 2); beta[1] = 13.0 / 12.0 * pow((wn1 - 2 * w + wp1), 2) + 0.25 * pow((wn1 - wp1), 2); beta[2] = 13.0 / 12.0 * pow((wn2 - 2 * wn1 + w), 2) + 0.25 * pow((wn2 - 4 * wn1 + 3 * w), 2); double epsilon = 1e-8; double alphaleft[3]; double alpharight[3]; if (wenotype == wenojs) { for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); alpharight[i] = dright[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); } } if (wenotype == wenoz) { double tau5 = abs(beta[0] - beta[2]); for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] * (1 + tau5 / (beta[i] + epsilon)); alpharight[i] = dright[i] * (1 + tau5 / (beta[i] + epsilon)); } } if (wenotype == linear) { for (int k = 0; k < 3; k++) { alphaleft[k] = dleft[k]; alpharight[k] = dright[k]; } } double alphal = alphaleft[0] + alphaleft[1] + alphaleft[2]; double omegaleft[3]; omegaleft[0] = alphaleft[0] / alphal; omegaleft[1] = alphaleft[1] / alphal; omegaleft[2] = alphaleft[2] / alphal; double left = omegaleft[0] * qleft[0] + omegaleft[1] * qleft[1] + omegaleft[2] * qleft[2]; double alphar = alpharight[0] + alpharight[1] + alpharight[2]; double omegaright[3]; omegaright[0] = alpharight[0] / alphar; omegaright[1] = alpharight[1] / alphar; omegaright[2] = alpharight[2] / alphar; double right = omegaright[0] * qright[0] + omegaright[1] * qright[1] + omegaright[2] * qright[2]; var = right; der2 = 6 * (left + right - 2 * w) / (h * h); der1 = (right - left) / h + 0.5 * h * der2; } void WENO5_AO_normal(Interface2d& left, Interface2d& right, Interface2d& down, Interface2d& up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { WENO5_AO(left.line.right, right.line.left, fluids[-2 * block.ny].convar, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, fluids[2 * block.ny].convar, fluids[0].dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; YchangetoX(wn1tmp, fluids[-1].convar); YchangetoX(wtmp, fluids[0].convar); YchangetoX(wp1tmp, fluids[1].convar); YchangetoX(wn2tmp, fluids[-2].convar); YchangetoX(wp2tmp, fluids[2].convar); WENO5_AO(down.line.right, up.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, fluids[0].dy); } } else { //for non-uniform mesh. Point2d voidpoint; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = fluids[0].dx; double normal[2]; double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; //cell left reconstruction Copy_Array(normal, left.normal, 2); Global_to_Local(wn2tmp, fluids[-2 * block.ny].convar, normal); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); Global_to_Local(wp2tmp, fluids[2 * block.ny].convar, normal); WENO5_AO(left.line.right, voidpoint, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dx); //cell right reconstruction Copy_Array(normal, right.normal, 2); Global_to_Local(wn2tmp, fluids[-2 * block.ny].convar, normal); Global_to_Local(wn1tmp, fluids[-block.ny].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[block.ny].convar, normal); Global_to_Local(wp2tmp, fluids[2 * block.ny].convar, normal); WENO5_AO(voidpoint, right.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = fluids[0].dy; double normal[2]; double wn2tmp[4], wn1tmp[4], wtmp[4], wp1tmp[4], wp2tmp[4]; //down interface reconstruction Copy_Array(normal, down.normal, 2); Global_to_Local(wn2tmp, fluids[-2].convar, normal); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); Global_to_Local(wp2tmp, fluids[2].convar, normal); WENO5_AO(down.line.right, voidpoint, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dy); //up interface reconstruction Copy_Array(normal, up.normal, 2); Global_to_Local(wn2tmp, fluids[-2].convar, normal); Global_to_Local(wn1tmp, fluids[-1].convar, normal); Global_to_Local(wtmp, fluids[0].convar, normal); Global_to_Local(wp1tmp, fluids[1].convar, normal); Global_to_Local(wp2tmp, fluids[2].convar, normal); WENO5_AO(voidpoint, up.line.left, wn2tmp, wn1tmp, wtmp, wp1tmp, wp2tmp, dy); } } } void WENO5_AO(Point2d& left, Point2d& right, double* wn2, double* wn1, double* w, double* wp1, double* wp2, double h) { //we denote that |left...cell-center...right| double ren2[4], ren1[4], re0[4], rep1[4], rep2[4]; double var[4], der1[4], der2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(wn1_primvar, wn1); Convar_to_primvar_2D(w_primvar, w); Convar_to_primvar_2D(wp1_primvar, wp1); for (int i = 0; i < 4; i++) { base_left[i] = 0.5 * (wn1_primvar[i] + w_primvar[i]); base_right[i] = 0.5 * (wp1_primvar[i] + w_primvar[i]); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_left, wn2); Convar_to_char(ren1, base_left, wn1); Convar_to_char(re0, base_left, w); Convar_to_char(rep1, base_left, wp1); Convar_to_char(rep2, base_left, wp2); } for (int i = 0; i < 4; i++) { weno_5th_ao_left(var[i], der1[i], der2[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { left.convar[i] = var[i]; left.der1x[i] = der1[i]; } } else { Char_to_convar(left.convar, base_left, var); Char_to_convar(left.der1x, base_left, der1); } // cell right if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_right, wn2); Convar_to_char(ren1, base_right, wn1); Convar_to_char(re0, base_right, w); Convar_to_char(rep1, base_right, wp1); Convar_to_char(rep2, base_right, wp2); } for (int i = 0; i < 4; i++) { weno_5th_ao_right(var[i], der1[i], der2[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { right.convar[i] = var[i]; right.der1x[i] = der1[i]; } } else { Char_to_convar(right.convar, base_right, var); Char_to_convar(right.der1x, base_right, der1); } Check_Order_Reduce_by_Lambda_2D(right.is_reduce_order, right.convar); Check_Order_Reduce_by_Lambda_2D(left.is_reduce_order, left.convar); if (left.is_reduce_order == true || right.is_reduce_order == true) { if (is_reduce_order_warning == true) cout << " WENO5-cell-splitting order reduce" << endl; for (int m = 0; m < 4; m++) { right.convar[m] = w[m]; left.convar[m] = w[m]; right.der1x[m] = 0.0; left.der1x[m] = 0.0; } } } void First_order_tangent(Interface2d* left, Interface2d* right, Interface2d* down, Interface2d* up, Fluid2d* fluids, Block2d block) { for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { first_order_tangent(left[0].gauss[num_gauss].right, left[0].line.right); first_order_tangent(right[0].gauss[num_gauss].left, right[0].line.left); first_order_tangent(down[0].gauss[num_gauss].right, down[0].line.right); first_order_tangent(up[0].gauss[num_gauss].left, up[0].line.left); } } void first_order_tangent(Point2d& gauss, Point2d& w0) { //tangential Copy_Array(gauss.convar, w0.convar, 4); Copy_Array(gauss.der1x, w0.der1x, 4); Array_zero(gauss.der1y, 4); } void Vanleer_tangent(Interface2d* left, Interface2d* right, Interface2d* down, Interface2d* up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { // along x direction tangitial recontruction, for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Vanleer(left[0].gauss[num_gauss].right, left[-1].line.right, left[0].line.right, left[1].line.right, left[0].length); Vanleer(right[0].gauss[num_gauss].left, right[-1].line.left, right[0].line.left, right[1].line.left, right[0].length); } //since we already do the coordinate transform, along y, no transform needed. for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Vanleer(down[0].gauss[num_gauss].right, down[block.ny + 1].line.right, down[0].line.right, down[-block.ny - 1].line.right, down[0].length); Vanleer(up[0].gauss[num_gauss].left, up[block.ny + 1].line.left, up[0].line.left, up[-block.ny - 1].line.left, up[0].length); } } else { Interface2d re[2]; int index[2]; index[0] = -1; index[1] = 1; for (int iface = 0; iface < 2; ++iface) { Local_to_Global(re[iface].line.left.convar, right[index[iface]].line.left.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, right[0].normal); Local_to_Global(re[iface].line.left.der1x, right[index[iface]].line.left.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, right[0].normal); Local_to_Global(re[iface].line.right.convar, right[index[iface]].line.right.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, right[0].normal); Local_to_Global(re[iface].line.right.der1x, right[index[iface]].line.right.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, right[0].normal); } for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { Vanleer(right[0].gauss[num_gauss].left, re[0].line.left, right[0].line.left, re[1].line.left, right[0].length); Vanleer(right[0].gauss[num_gauss].right, re[0].line.right, right[0].line.right, re[1].line.right, right[0].length); } index[0] = (block.ny + 1); index[1] = -(block.ny + 1); for (int iface = 0; iface < 2; ++iface) { Local_to_Global(re[iface].line.left.convar, up[index[iface]].line.left.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, up[0].normal); Local_to_Global(re[iface].line.left.der1x, up[index[iface]].line.left.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, up[0].normal); Local_to_Global(re[iface].line.right.convar, up[index[iface]].line.right.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, up[0].normal); Local_to_Global(re[iface].line.right.der1x, up[index[iface]].line.right.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, up[0].normal); } for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { Vanleer(up[0].gauss[num_gauss].left, re[0].line.left, up[0].line.left, re[1].line.left, up[0].length); Vanleer(up[0].gauss[num_gauss].right, re[0].line.right, up[0].line.right, re[1].line.right, up[0].length); } } } void Vanleer(Point2d& gauss, Point2d& wn1, Point2d& w0, Point2d& wp1, double h) { //tangential for (int var = 0; var < 4; var++) { double coe[2]; Vanleer_tangential(coe, wn1.convar[var], w0.convar[var], wp1.convar[var], h); gauss.convar[var] = coe[0] + gauss.x * coe[1]; gauss.der1y[var] = coe[1]; Vanleer_tangential(coe, wn1.der1x[var], w0.der1x[var], wp1.der1x[var], h); gauss.der1x[var] = coe[0] + gauss.x * coe[1]; } Check_Order_Reduce_by_Lambda_2D(gauss.is_reduce_order, gauss.convar); //if lambda <0, then reduce to the first order if (gauss.is_reduce_order == true) { for (int m = 0; m < 4; ++m) { gauss.convar[m] = w0.convar[m]; gauss.der1x[m] = w0.der1x[m]; gauss.der1y[m] = 0.0; } } } void Vanleer_tangential(double* coe, double wn1, double w0, double wp1, double h) { if ((w0 - wn1) * (wp1 - w0) > 0) { double slope_left = (w0 - wn1) / h; double slope_right = (wp1 - w0) / h; coe[1] = 2 * slope_left * slope_right / (slope_left + slope_right); coe[0] = w0; } else { coe[0] = w0; coe[1] = 0.0; } } void WENO5_tangent(Interface2d* left, Interface2d* right, Interface2d* down, Interface2d* up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { // along x direction tangitial recontruction, WENO5_tangential(right[0].gauss, right[-2].line, right[-1].line, right[0].line, right[1].line, right[2].line, right[0].length); //since we already do the coordinate transform, along y, no transform needed. WENO5_tangential(up[0].gauss, up[2 * (block.ny + 1)].line, up[block.ny + 1].line, up[0].line, up[-(block.ny + 1)].line, up[-2 * (block.ny + 1)].line, up[0].length); } else { Interface2d re[4]; int index[4]; index[0] = -2; index[1] = -1; index[2] = 1; index[3] = 2; for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, right[index[iface]].line.left.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, right[0].normal); Local_to_Global(re[iface].line.left.der1x, right[index[iface]].line.left.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, right[0].normal); Local_to_Global(re[iface].line.right.convar, right[index[iface]].line.right.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, right[0].normal); Local_to_Global(re[iface].line.right.der1x, right[index[iface]].line.right.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, right[0].normal); } WENO5_tangential(right[0].gauss, re[0].line, re[1].line, right[0].line, re[2].line, re[3].line, right[0].length); index[0] = 2 * (block.ny + 1); index[1] = (block.ny + 1); index[2] = -(block.ny + 1); index[3] = -2 * (block.ny + 1); for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, up[index[iface]].line.left.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, up[0].normal); Local_to_Global(re[iface].line.left.der1x, up[index[iface]].line.left.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, up[0].normal); Local_to_Global(re[iface].line.right.convar, up[index[iface]].line.right.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, up[0].normal); Local_to_Global(re[iface].line.right.der1x, up[index[iface]].line.right.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, up[0].normal); } WENO5_tangential(up[0].gauss, re[0].line, re[1].line, up[0].line, re[2].line, re[3].line, up[0].length); } } void WENO5_tangential(double* left, double* right, double* wn2, double* wn1, double* w, double* wp1, double* wp2, double h) { //we denote that |left...cell-center...right| double ren2[4], ren1[4], re0[4], rep1[4], rep2[4]; double var[4], der1[4], der2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(wn1_primvar, wn1); Convar_to_primvar_2D(w_primvar, w); Convar_to_primvar_2D(wp1_primvar, wp1); for (int i = 0; i < 4; i++) { base_left[i] = 0.5 * (wn1_primvar[i] + w_primvar[i]); base_right[i] = 0.5 * (wp1_primvar[i] + w_primvar[i]); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_left, wn2); Convar_to_char(ren1, base_left, wn1); Convar_to_char(re0, base_left, w); Convar_to_char(rep1, base_left, wp1); Convar_to_char(rep2, base_left, wp2); } for (int i = 0; i < 4; i++) { WENO5_left(var[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { left[i] = var[i]; } } else { Char_to_convar(left, base_left, var); } // cell right if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren2[i] = wn2[i]; ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; rep2[i] = wp2[i]; } } else { Convar_to_char(ren2, base_right, wn2); Convar_to_char(ren1, base_right, wn1); Convar_to_char(re0, base_right, w); Convar_to_char(rep1, base_right, wp1); Convar_to_char(rep2, base_right, wp2); } for (int i = 0; i < 4; i++) { WENO5_right(var[i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { right[i] = var[i]; } } else { Char_to_convar(right, base_right, var); } } void WENO5_tangential_for_slope(double* left, double* right, double* wn2, double* wn1, double* w, double* wp1, double* wp2, double h) { //we denote that |left...cell-center...right| for (int i = 0; i < 4; i++) { WENO5_left(left[i], wn2[i], wn1[i], w[i], wp1[i], wp2[i], h); } for (int i = 0; i < 4; i++) { WENO5_right(right[i], wn2[i], wn1[i], w[i], wp1[i], wp2[i], h); } } void Polynomial_3rd(double* coefficent, double pn1, double w0, double pp1, double h) { coefficent[0] = (1.0 / 4.0) * (-pn1 - pp1 + 6.0 * w0); coefficent[1] = -(pn1 - pp1) / h; coefficent[2] = (3 * (pn1 + pp1 - 2 * w0)) / (h * h); } void Polynomial_5th(double* coefficent, double wn2, double wn1, double w0, double wp1, double wp2, double h) { coefficent[0] = 1.0 / 1920.0 * (2134 * w0 - 116 * (wn1 + wp1) + 9 * (wn2 + wp2)); coefficent[1] = 1.0 / h * (-5.0 / 48.0 * (wp2 - wn2) + 17.0 / 24.0 * (wp1 - wn1)); coefficent[2] = 1.0 / 16.0 / h / h * (12 * (wp1 + wn1) - (wp2 + wn2) - 22 * w0); coefficent[3] = 1.0 / 12.0 / h / h / h * ((wp2 - wn2) - 2 * (wp1 - wn1)); coefficent[4] = 1.0 / 24.0 / h / h / h / h * ((wp2 + wn2) - 4 * (wp1 + wn1) + 6 * w0); } double Value_Polynomial(int order, double x0, double* coefficient) { if (order <= 0) { cout << "wrong input for the order of polynomial" << endl; return 0; } if (order == 1) { return coefficient[0]; } if (order == 2) { return coefficient[0] + coefficient[1] * x0; }; if (order == 3) { return coefficient[0] + x0 * (coefficient[1] + coefficient[2] * x0); }; if (order == 4) { return coefficient[0] + x0 * (coefficient[1] + x0 * (coefficient[2] + coefficient[3] * x0)); }; if (order == 5) { return coefficient[0] + x0 * (coefficient[1] + x0 * (coefficient[2] + x0 * (coefficient[3] + coefficient[4] * x0))); }; if (order == 6) { return coefficient[0] + x0 * (coefficient[1] + x0 * (coefficient[2] + x0 * (coefficient[3] + x0 * (coefficient[4] + coefficient[5] * x0)))); }; if (order == 7) { return coefficient[0] + x0 * (coefficient[1] + x0 * (coefficient[2] + x0 * (coefficient[3] + x0 * (coefficient[4] + x0 * (coefficient[5] + coefficient[6] * x0))))); }; } double Der1_Polynomial(int order, double x0, double* coefficient) { if (order <= 0) { cout << "wrong input for the order of polynomial" << endl; return 0; } if (order == 1) { return 0.0; } if (order == 2) { return coefficient[1]; }; if (order == 3) { return coefficient[1] + 2 * coefficient[2] * x0; }; if (order == 4) { return coefficient[1] + x0 * (2.0 * coefficient[2] + 3.0 * coefficient[3] * x0); }; if (order == 5) { return coefficient[1] + x0 * (2.0 * coefficient[2] + x0 * (3.0 * coefficient[3] + 4.0 * coefficient[4] * x0)); }; if (order == 6) { return coefficient[1] + x0 * (2.0 * coefficient[2] + x0 * (3.0 * coefficient[3] + x0 * (4.0 * coefficient[4] + 5.0 * coefficient[5] * x0))); }; if (order == 7) { return coefficient[1] + x0 * (2.0 * coefficient[2] + x0 * (3.0 * coefficient[3] + x0 * (4.0 * coefficient[4] + x0 * (5.0 * coefficient[5] + 6.0 * coefficient[6] * x0)))); }; } void Polynomial_3rd_avg(double* coefficent, double wn1, double w0, double wp1, double h) { coefficent[0] = w0; coefficent[1] = 1.0 / 2.0 / h * (wp1 - wn1); coefficent[2] = 1.0 / 2.0 / h / h * ((wp1 + wn1) - 2 * w0); } double Value_Polynomial_3rd(double x, double coefficient[3]) { return coefficient[0] + coefficient[1] * x + coefficient[2] * x * x; } double Der1_Polynomial_3rd(double x, double coefficient[3]) { return coefficient[1] + 2 * coefficient[2] * x; } void WENO5_left(double& var, double wn2, double wn1, double w, double wp1, double wp2, double h) { double qleft[3]; double dleft[3]; qleft[0] = 11.0 / 6.0 * w - 7.0 / 6.0 * wp1 + 1.0 / 3.0 * wp2; qleft[1] = 1.0 / 3.0 * wn1 + 5.0 / 6.0 * w - 1.0 / 6.0 * wp1; qleft[2] = -1.0 / 6.0 * wn2 + 5.0 / 6.0 * wn1 + 1.0 / 3.0 * w; dleft[0] = 0.1; dleft[1] = 0.6; dleft[2] = 0.3; double omegaleft[3]; if (wenotype == linear) { omegaleft[0] = dleft[0]; omegaleft[1] = dleft[1]; omegaleft[2] = dleft[2]; } else { double beta[3]; beta[0] = 13.0 / 12.0 * pow((w - 2.0 * wp1 + wp2), 2) + 0.25 * pow((3.0 * w - 4.0 * wp1 + wp2), 2); beta[1] = 13.0 / 12.0 * pow((wn1 - 2.0 * w + wp1), 2) + 0.25 * pow((wn1 - wp1), 2); beta[2] = 13.0 / 12.0 * pow((wn2 - 2.0 * wn1 + w), 2) + 0.25 * pow((wn2 - 4.0 * wn1 + 3.0 * w), 2); double epsilon = 1e-6; double alphaleft[3]; if (wenotype == wenojs) { for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); } } if (wenotype == wenoz) { double tau5 = abs(beta[0] - beta[2]); for (int i = 0; i < 3; i++) { alphaleft[i] = dleft[i] * (1 + tau5 / (beta[i] + epsilon)); } } double alphal = alphaleft[0] + alphaleft[1] + alphaleft[2]; omegaleft[0] = alphaleft[0] / alphal; omegaleft[1] = alphaleft[1] / alphal; omegaleft[2] = alphaleft[2] / alphal; } double left = omegaleft[0] * qleft[0] + omegaleft[1] * qleft[1] + omegaleft[2] * qleft[2]; var = left; } void WENO5_right(double& var, double wn2, double wn1, double w, double wp1, double wp2, double h) { double qright[3]; double dright[3]; qright[0] = 1.0 / 3.0 * w + 5.0 / 6.0 * wp1 - 1.0 / 6.0 * wp2; qright[1] = -1.0 / 6.0 * wn1 + 5.0 / 6.0 * w + 1.0 / 3.0 * wp1; qright[2] = 1.0 / 3.0 * wn2 - 7.0 / 6.0 * wn1 + 11.0 / 6.0 * w; dright[0] = 0.3; dright[1] = 0.6; dright[2] = 0.1; double omegaright[3]; if (wenotype == linear) { omegaright[0] = dright[0]; omegaright[1] = dright[1]; omegaright[2] = dright[2]; } else { double beta[3]; beta[0] = 13.0 / 12.0 * pow((w - 2.0 * wp1 + wp2), 2) + 0.25 * pow((3.0 * w - 4.0 * wp1 + wp2), 2); beta[1] = 13.0 / 12.0 * pow((wn1 - 2.0 * w + wp1), 2) + 0.25 * pow((wn1 - wp1), 2); beta[2] = 13.0 / 12.0 * pow((wn2 - 2.0 * wn1 + w), 2) + 0.25 * pow((wn2 - 4.0 * wn1 + 3.0 * w), 2); double epsilon = 1e-6; double alphaleft[3]; double alpharight[3]; if (wenotype == wenojs) { for (int i = 0; i < 3; i++) { alpharight[i] = dright[i] / ((beta[i] + epsilon) * (beta[i] + epsilon)); } } if (wenotype == wenoz) { double tau5 = abs(beta[0] - beta[2]); for (int i = 0; i < 3; i++) { alpharight[i] = dright[i] * (1 + tau5 / (beta[i] + epsilon)); } } double alphar = alpharight[0] + alpharight[1] + alpharight[2]; omegaright[0] = alpharight[0] / alphar; omegaright[1] = alpharight[1] / alphar; omegaright[2] = alpharight[2] / alphar; } double right = omegaright[0] * qright[0] + omegaright[1] * qright[1] + omegaright[2] * qright[2]; var = right; } void WENO5_tangential(Recon2d* re, Recon2d& wn2, Recon2d& wn1, Recon2d& w0, Recon2d& wp1, Recon2d& wp2, double h) { double left[4], right[4]; double coe[3]; // let's reconstruct the left first WENO5_tangential(left, right, wn2.left.convar, wn1.left.convar, w0.left.convar, wp1.left.convar, wp2.left.convar, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.left.convar[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].left.convar[var] = Value_Polynomial_3rd(re[num_gauss].left.x, coe); re[num_gauss].left.der1y[var] = Der1_Polynomial_3rd(re[num_gauss].left.x, coe); } } WENO5_tangential_for_slope(left, right, wn2.left.der1x, wn1.left.der1x, w0.left.der1x, wp1.left.der1x, wp2.left.der1x, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.left.der1x[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].left.der1x[var] = Value_Polynomial_3rd(re[num_gauss].left.x, coe); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].left.is_reduce_order, re[num_gauss].left.convar); if (re[num_gauss].left.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].left.convar[var] = w0.left.convar[var]; re[num_gauss].left.der1x[var] = w0.left.der1x[var]; re[num_gauss].left.der1y[var] = 0.0; } } } // then is the right part WENO5_tangential(left, right, wn2.right.convar, wn1.right.convar, w0.right.convar, wp1.right.convar, wp2.right.convar, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.right.convar[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].right.convar[var] = Value_Polynomial_3rd(re[num_gauss].right.x, coe); re[num_gauss].right.der1y[var] = Der1_Polynomial_3rd(re[num_gauss].right.x, coe); } } WENO5_tangential_for_slope(left, right, wn2.right.der1x, wn1.right.der1x, w0.right.der1x, wp1.right.der1x, wp2.right.der1x, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.right.der1x[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].right.der1x[var] = Value_Polynomial_3rd(re[num_gauss].right.x, coe); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].right.is_reduce_order, re[num_gauss].right.convar); if (re[num_gauss].right.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].right.convar[var] = w0.right.convar[var]; re[num_gauss].right.der1x[var] = w0.right.der1x[var]; re[num_gauss].right.der1y[var] = 0.0; } } } //right part compelete } void WENO5_AO_tangent(Interface2d* left, Interface2d* right, Interface2d* down, Interface2d* up, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { // along x direction tangitial recontruction, WENO5_AO_tangential(right[0].gauss, right[-2].line, right[-1].line, right[0].line, right[1].line, right[2].line, right[0].length); //since we already do the coordinate transform, along y, no transform needed. WENO5_AO_tangential(up[0].gauss, up[2 * (block.ny + 1)].line, up[block.ny + 1].line, up[0].line, up[-(block.ny + 1)].line, up[-2 * (block.ny + 1)].line, up[0].length); } else { Interface2d re[4]; int index[4]; index[0] = -2; index[1] = -1; index[2] = 1; index[3] = 2; for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, right[index[iface]].line.left.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, right[0].normal); Local_to_Global(re[iface].line.left.der1x, right[index[iface]].line.left.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, right[0].normal); Local_to_Global(re[iface].line.right.convar, right[index[iface]].line.right.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, right[0].normal); Local_to_Global(re[iface].line.right.der1x, right[index[iface]].line.right.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, right[0].normal); } WENO5_AO_tangential(right[0].gauss, re[0].line, re[1].line, right[0].line, re[2].line, re[3].line, right[0].length); index[0] = 2 * (block.ny + 1); index[1] = (block.ny + 1); index[2] = -(block.ny + 1); index[3] = -2 * (block.ny + 1); for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, up[index[iface]].line.left.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, up[0].normal); Local_to_Global(re[iface].line.left.der1x, up[index[iface]].line.left.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, up[0].normal); Local_to_Global(re[iface].line.right.convar, up[index[iface]].line.right.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, up[0].normal); Local_to_Global(re[iface].line.right.der1x, up[index[iface]].line.right.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, up[0].normal); } WENO5_AO_tangential(up[0].gauss, re[0].line, re[1].line, up[0].line, re[2].line, re[3].line, up[0].length); } } void WENO5_AO_tangential(Recon2d* re, Recon2d& wn2, Recon2d& wn1, Recon2d& w0, Recon2d& wp1, Recon2d& wp2, double h) { //lets first reconstruction the left value double ren2[4], ren1[4], re0[4], rep1[4], rep2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(w_primvar, w0.left.convar); for (int i = 0; i < 4; i++) { base_left[i] = (w_primvar[i]); } if (reconstruction_variable == conservative) { double tmp[2]; for (int i = 0; i < 4; i++) { if (gausspoint == 2) { weno_5th_ao_2gauss(re[0].left.convar[i], re[0].left.der1y[i], tmp[0], re[1].left.convar[i], re[1].left.der1y[i], tmp[1], wn2.left.convar[i], wn1.left.convar[i], w0.left.convar[i], wp1.left.convar[i], wp2.left.convar[i], h, 2); } } } else { Convar_to_char(ren2, base_left, wn2.left.convar); Convar_to_char(ren1, base_left, wn1.left.convar); Convar_to_char(re0, base_left, w0.left.convar); Convar_to_char(rep1, base_left, wp1.left.convar); Convar_to_char(rep2, base_left, wp2.left.convar); if (gausspoint == 2) { double var[2][4], der1[2][4], der2[2][4]; for (int i = 0; i < 4; i++) { weno_5th_ao_2gauss(var[0][i], der1[0][i], der2[0][i], var[1][i], der1[1][i], der2[1][i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h, 2); } for (int igauss = 0; igauss < gausspoint; igauss++) { Char_to_convar(re[igauss].left.convar, base_left, var[igauss]); Char_to_convar(re[igauss].left.der1y, base_left, der1[igauss]); } } } for (int i = 0; i < 4; i++) { double tmp[4]; if (gausspoint == 2) { weno_5th_ao_2gauss(re[0].left.der1x[i], tmp[0], tmp[1], re[1].left.der1x[i], tmp[2], tmp[3], wn2.left.der1x[i], wn1.left.der1x[i], w0.left.der1x[i], wp1.left.der1x[i], wp2.left.der1x[i], h, 1); } } //then let's construct the right part.... Convar_to_primvar_2D(w_primvar, w0.right.convar); for (int i = 0; i < 4; i++) { base_right[i] = (w_primvar[i]); } if (reconstruction_variable == conservative) { double tmp[2]; for (int i = 0; i < 4; i++) { if (gausspoint == 2) { weno_5th_ao_2gauss(re[0].right.convar[i], re[0].right.der1y[i], tmp[0], re[1].right.convar[i], re[1].right.der1y[i], tmp[1], wn2.right.convar[i], wn1.right.convar[i], w0.right.convar[i], wp1.right.convar[i], wp2.right.convar[i], h, 2); } } } else { Convar_to_char(ren2, base_right, wn2.right.convar); Convar_to_char(ren1, base_right, wn1.right.convar); Convar_to_char(re0, base_right, w0.right.convar); Convar_to_char(rep1, base_right, wp1.right.convar); Convar_to_char(rep2, base_right, wp2.right.convar); if (gausspoint == 2) { double var[2][4], der1[2][4], der2[2][4]; for (int i = 0; i < 4; i++) { weno_5th_ao_2gauss(var[0][i], der1[0][i], der2[0][i], var[1][i], der1[1][i], der2[1][i], ren2[i], ren1[i], re0[i], rep1[i], rep2[i], h, 2); } for (int igauss = 0; igauss < gausspoint; igauss++) { Char_to_convar(re[igauss].right.convar, base_right, var[igauss]); Char_to_convar(re[igauss].right.der1y, base_right, der1[igauss]); } } } for (int i = 0; i < 4; i++) { double tmp[4]; if (gausspoint == 2) { weno_5th_ao_2gauss(re[0].right.der1x[i], tmp[0], tmp[1], re[1].right.der1x[i], tmp[2], tmp[3], wn2.right.der1x[i], wn1.right.der1x[i], w0.right.der1x[i], wp1.right.der1x[i], wp2.right.der1x[i], h, 1); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].left.is_reduce_order, re[num_gauss].left.convar); if (re[num_gauss].left.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].left.convar[var] = w0.left.convar[var]; re[num_gauss].left.der1x[var] = w0.left.der1x[var]; re[num_gauss].left.der1y[var] = 0.0; } } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].right.is_reduce_order, re[num_gauss].right.convar); if (re[num_gauss].right.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].right.convar[var] = w0.right.convar[var]; re[num_gauss].right.der1x[var] = w0.right.der1x[var]; re[num_gauss].right.der1y[var] = 0.0; } } } } void weno_5th_ao_2gauss(double& g1, double& g1x, double& g1xx, double& g2, double& g2x, double& g2xx, double wn2, double wn1, double w0, double wp1, double wp2, double h, int order) { //the parameter order constrols up to which order you want construct // order from 0, 1, 2 if (order > 2 || order < 0) { cout << "invalid order input for the function " << __FUNCTION__ << endl; exit(0); } double dhi = 0.85; double dlo = 0.85; //-- - parameter of WENO-- - double beta[4], d[4], ww[4], alpha[4]; double epsilonW = 1e-8; //-- - intermediate parameter-- - double p[4], px[4], pxx[4], tempvar; double sum_alpha; //three small stencil d[0] = (1 - dhi) * (1 - dlo) * 0.5; d[1] = (1 - dhi) * dlo; d[2] = (1 - dhi) * (1 - dlo) * 0.5; //one big stencil d[3] = dhi; if (wenotype == linear) { for (int k = 0; k < 4; k++) { ww[k] = d[k]; } } else { //cout << "here" << endl; beta[0] = 13.0 / 12.0 * pow((wn2 - 2 * wn1 + w0), 2) + 0.25 * pow((wn2 - 4 * wn1 + 3 * w0), 2); beta[1] = 13.0 / 12.0 * pow((wn1 - 2 * w0 + wp1), 2) + 0.25 * pow((wn1 - wp1), 2); beta[2] = 13.0 / 12.0 * pow((w0 - 2 * wp1 + wp2), 2) + 0.25 * pow((3 * w0 - 4 * wp1 + wp2), 2); beta[3] = (1.0 / 5040.0) * (231153 * w0 * w0 + 104963 * wn1 * wn1 + 6908 * wn2 * wn2 - 38947 * wn2 * wp1 + 104963 * wp1 * wp1 + wn1 * (-51001 * wn2 + 179098 * wp1 - 38947 * wp2) - 3 * w0 * (99692 * wn1 - 22641 * wn2 + 99692 * wp1 - 22641 * wp2) + 8209 * wn2 * wp2 - 51001 * wp1 * wp2 + 6908 * wp2 * wp2); double tau5 = 1.0 / 3.0 * (abs(beta[3] - beta[0]) + abs(beta[3] - beta[1]) + abs(beta[3] - beta[2])); if (wenotype == wenojs) { sum_alpha = 0.0; for (int k = 0; k < 4; k++) { alpha[k] = d[k] / ((epsilonW + beta[k]) * (epsilonW + beta[k])); sum_alpha += alpha[k]; } } else if (wenotype == wenoz) { sum_alpha = 0.0; for (int i = 0; i < 4; i++) { double global_div = tau5 / (beta[i] + epsilonW); alpha[i] = d[i] * (1 + global_div * global_div); sum_alpha += alpha[i]; } } for (int k = 0; k < 4; k++) { ww[k] = alpha[k] / sum_alpha; } } ////-- - combination-- - double final_weight[4]; final_weight[3] = ww[3] / d[3]; for (int k = 0; k < 3; k++) { final_weight[k] = ww[k] - ww[3] / d[3] * d[k]; } g1 = 0; g1x = 0; g1xx = 0; g2 = 0; g2x = 0; g2xx = 0; double sqrt3 = sqrt(3); //-- - candidate polynomial-- for gauss 1 point p[0] = w0 - (sqrt3 * w0) / 4 + (4 * wn1 - wn2) / (4 * sqrt3); p[1] = w0 + (wn1 - wp1) / (4 * sqrt3); p[2] = (1.0 / 12.0) * (3 * (4 + sqrt3) * w0 + sqrt3 * (-4 * wp1 + wp2)); p[3] = (4314 * w0 + (4 + 500 * sqrt3) * wn1 - wn2 - 70 * sqrt3 * wn2 + 4 * wp1 - 500 * sqrt3 * wp1 - wp2 + 70 * sqrt3 * wp2) / 4320; for (int k = 0; k < 4; k++) { g1 += final_weight[k] * p[k]; } if (order > 0) { px[0] = -((-9 + sqrt3) * w0 - 2 * (-6 + sqrt3) * wn1 + (-3 + sqrt3) * wn2) / (6 * h); px[1] = -(-2 * sqrt3 * w0 + (3 + sqrt3) * wn1 + (-3 + sqrt3) * wp1) / (6 * h); px[2] = -((9 + sqrt3) * w0 - 2 * (6 + sqrt3) * wp1 + (3 + sqrt3) * wp2) / (6 * h); px[3] = (48 * sqrt3 * w0 - 72 * wn1 - 26 * sqrt3 * wn1 + 9 * wn2 + 2 * sqrt3 * wn2 + 72 * wp1 - 26 * sqrt3 * wp1 - 9 * wp2 + 2 * sqrt3 * wp2) / (108 * h); for (int k = 0; k < 4; k++) { g1x += final_weight[k] * px[k]; } if (order == 2) { pxx[0] = (w0 - 2 * wn1 + wn2) / h / h; pxx[1] = (-2 * w0 + wn1 + wp1) / h / h; pxx[2] = (w0 - 2 * wp1 + wp2) / h / h; pxx[3] = -((30 * w0 + 2 * (-8 + sqrt3) * wn1 + wn2 - sqrt3 * wn2 - 16 * wp1 - 2 * sqrt3 * wp1 + wp2 + sqrt3 * wp2) / (12 * h * h)); for (int k = 0; k < 4; k++) { g1xx += final_weight[k] * pxx[k]; } } } //-- - candidate polynomial-- for gauss 2 point p[0] = (1.0 / 12.0) * (3 * (4 + sqrt3) * w0 + sqrt3 * (-4 * wn1 + wn2)); p[1] = w0 + (-wn1 + wp1) / (4 * sqrt3); p[2] = w0 - (sqrt3 * w0) / 4 + (4 * wp1 - wp2) / (4 * sqrt3); p[3] = (4314 * w0 + (4 - 500 * sqrt3) * wn1 - wn2 + 70 * sqrt3 * wn2 + 4 * wp1 + 500 * sqrt3 * wp1 - wp2 - 70 * sqrt3 * wp2) / 4320; for (int k = 0; k < 4; k++) { g2 += final_weight[k] * p[k]; } if (order > 0) { px[0] = ((9 + sqrt3) * w0 - 2 * (6 + sqrt3) * wn1 + (3 + sqrt3) * wn2) / (6 * h); px[1] = (-2 * sqrt3 * w0 + (-3 + sqrt3) * wn1 + (3 + sqrt3) * wp1) / (6 * h); px[2] = ((-9 + sqrt3) * w0 - 2 * (-6 + sqrt3) * wp1 + (-3 + sqrt3) * wp2) / (6 * h); px[3] = -((48 * sqrt3 * w0 + 72 * wn1 - 26 * sqrt3 * wn1 - 9 * wn2 + 2 * sqrt3 * wn2 - 72 * wp1 - 26 * sqrt3 * wp1 + 9 * wp2 + 2 * sqrt3 * wp2) / (108 * h)); for (int k = 0; k < 4; k++) { g2x += final_weight[k] * px[k]; } if (order == 2) { pxx[0] = (w0 - 2 * wn1 + wn2) / h / h; pxx[1] = (-2 * w0 + wn1 + wp1) / h / h; pxx[2] = (w0 - 2 * wp1 + wp2) / h / h; pxx[3] = -((30 * w0 - 2 * (8 + sqrt3) * wn1 + wn2 + sqrt3 * wn2 - 16 * wp1 + 2 * sqrt3 * wp1 + wp2 - sqrt3 * wp2) / (12 * h * h)); } for (int k = 0; k < 4; k++) { g2xx += final_weight[k] * pxx[k]; } } } void WENO3_tangent(Interface2d* left, Interface2d* right, Interface2d* down, Interface2d* up, Fluid2d* fluids, Block2d block) { Interface2d re[4]; int index[4]; index[0] = -2; index[1] = -1; index[2] = 1; index[3] = 2; for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, right[index[iface]].line.left.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, right[0].normal); Local_to_Global(re[iface].line.left.der1x, right[index[iface]].line.left.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, right[0].normal); Local_to_Global(re[iface].line.right.convar, right[index[iface]].line.right.convar, right[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, right[0].normal); Local_to_Global(re[iface].line.right.der1x, right[index[iface]].line.right.der1x, right[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, right[0].normal); } WENO3_tangential(right[0].gauss, re[1].line, right[0].line, re[2].line, right[0].length); index[0] = 2 * (block.ny + 1); index[1] = (block.ny + 1); index[2] = -(block.ny + 1); index[3] = -2 * (block.ny + 1); for (int iface = 0; iface < 4; iface++) { Local_to_Global(re[iface].line.left.convar, up[index[iface]].line.left.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.left.convar, up[0].normal); Local_to_Global(re[iface].line.left.der1x, up[index[iface]].line.left.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.left.der1x, up[0].normal); Local_to_Global(re[iface].line.right.convar, up[index[iface]].line.right.convar, up[index[iface]].normal); Global_to_Local(re[iface].line.right.convar, up[0].normal); Local_to_Global(re[iface].line.right.der1x, up[index[iface]].line.right.der1x, up[index[iface]].normal); Global_to_Local(re[iface].line.right.der1x, up[0].normal); } WENO3_tangential(up[0].gauss, re[1].line, up[0].line, re[2].line, up[0].length); } void WENO3_tangential(Recon2d* re, Recon2d& wn1, Recon2d& w0, Recon2d& wp1, double h) { double left[4], right[4]; double coe[3]; // let's reconstruct the left first WENO3_tangential(left, right, wn1.left.convar, w0.left.convar, wp1.left.convar, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.left.convar[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].left.convar[var] = Value_Polynomial_3rd(re[num_gauss].left.x, coe); re[num_gauss].left.der1y[var] = Der1_Polynomial_3rd(re[num_gauss].left.x, coe); } } WENO3_tangential_for_slope(left, right, wn1.left.der1x, w0.left.der1x, wp1.left.der1x, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.left.der1x[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].left.der1x[var] = Value_Polynomial_3rd(re[num_gauss].left.x, coe); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].left.is_reduce_order, re[num_gauss].left.convar); if (re[num_gauss].left.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].left.convar[var] = w0.left.convar[var]; re[num_gauss].left.der1x[var] = w0.left.der1x[var]; re[num_gauss].left.der1y[var] = 0.0; } } } // then is the right part WENO3_tangential(left, right, wn1.right.convar, w0.right.convar, wp1.right.convar, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.right.convar[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].right.convar[var] = Value_Polynomial_3rd(re[num_gauss].right.x, coe); re[num_gauss].right.der1y[var] = Der1_Polynomial_3rd(re[num_gauss].right.x, coe); } } WENO3_tangential_for_slope(left, right, wn1.right.der1x, w0.right.der1x, wp1.right.der1x, h); for (int var = 0; var < 4; var++) { Polynomial_3rd(coe, left[var], w0.right.der1x[var], right[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].right.der1x[var] = Value_Polynomial_3rd(re[num_gauss].right.x, coe); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].right.is_reduce_order, re[num_gauss].right.convar); if (re[num_gauss].right.is_reduce_order == true) { for (int var = 0; var < 4; var++) { re[num_gauss].right.convar[var] = w0.right.convar[var]; re[num_gauss].right.der1x[var] = w0.right.der1x[var]; re[num_gauss].right.der1y[var] = 0.0; } } } //right part compelete } void WENO3_tangential(double* left, double* right, double* wn1, double* w, double* wp1, double h) { //we denote that |left...cell-center...right| double ren1[4], re0[4], rep1[4]; double var[4], der1[4], der2[4]; double base_left[4]; double base_right[4]; double wn1_primvar[4], w_primvar[4], wp1_primvar[4]; Convar_to_primvar_2D(wn1_primvar, wn1); Convar_to_primvar_2D(w_primvar, w); Convar_to_primvar_2D(wp1_primvar, wp1); for (int i = 0; i < 4; i++) { base_left[i] = 0.5 * (wn1_primvar[i] + w_primvar[i]); base_right[i] = 0.5 * (wp1_primvar[i] + w_primvar[i]); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; } } else { Convar_to_char(ren1, base_left, wn1); Convar_to_char(re0, base_left, w); Convar_to_char(rep1, base_left, wp1); } for (int i = 0; i < 4; i++) { WENO3_left(var[i], ren1[i], re0[i], rep1[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { left[i] = var[i]; } } else { Char_to_convar(left, base_left, var); } // cell right if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { ren1[i] = wn1[i]; re0[i] = w[i]; rep1[i] = wp1[i]; } } else { Convar_to_char(ren1, base_right, wn1); Convar_to_char(re0, base_right, w); Convar_to_char(rep1, base_right, wp1); } for (int i = 0; i < 4; i++) { WENO3_right(var[i], ren1[i], re0[i], rep1[i], h); } if (reconstruction_variable == conservative) { for (int i = 0; i < 4; i++) { right[i] = var[i]; } } else { Char_to_convar(right, base_right, var); } } void WENO3_tangential_for_slope(double* left, double* right, double* wn1, double* w, double* wp1, double h) { //we denote that |left...cell-center...right| for (int i = 0; i < 4; i++) { WENO3_left(left[i], wn1[i], w[i], wp1[i], h); } for (int i = 0; i < 4; i++) { WENO3_right(right[i], wn1[i], w[i], wp1[i], h); } } void Reconstruction_forg0(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { #pragma omp parallel for for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { g0reconstruction_2D_normal(&xinterfaces[i * (block.ny + 1) + j], &yinterfaces[i * (block.ny + 1) + j], &fluids[i * (block.ny) + j], block); } } // then get the guass point value. That is, so called multi-dimensional property #pragma omp parallel for for (int i = block.ghost; i < block.nx - block.ghost + 1; i++) { for (int j = block.ghost; j < block.ny - block.ghost + 1; j++) { g0reconstruction_2D_tangent(&xinterfaces[i * (block.ny + 1) + j], &yinterfaces[i * (block.ny + 1) + j], &fluids[i * (block.ny) + j], block); } } } void Center_collision_normal(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Center_all_collision_2d_multi(xinterfaces[0].line); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { Center_all_collision_2d_multi(yinterfaces[0].line); } } void Center_3rd_normal(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { //assume this is uniform mesh, if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Center_3rd_Splitting(xinterfaces[0], fluids[-block.ny].convar, fluids[0].convar, block.dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double tmp_w[4], tmp_wp1[4]; YchangetoX(tmp_wp1, fluids[0].convar); YchangetoX(tmp_w, fluids[-1].convar); Center_3rd_Splitting(yinterfaces[0], tmp_w, tmp_wp1, block.dy); } } else { double tmp_w[4], tmp_wp1[4]; double normal[2]; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = 0.5 * (fluids[-block.ny].dx + fluids[0].dx); Copy_Array(normal, xinterfaces[0].normal, 2); Global_to_Local(tmp_w, fluids[-block.ny].convar, normal); Global_to_Local(tmp_wp1, fluids[0].convar, normal); double over_cos = -dx / ((fluids[-block.ny].coordx - fluids[0].coordx) * normal[0] + (fluids[-block.ny].coordy - fluids[0].coordy) * normal[1]); Center_3rd_Splitting(xinterfaces[0], tmp_w, tmp_wp1, over_cos * dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = 0.5 * (fluids[-1].dy + fluids[0].dy); Copy_Array(normal, yinterfaces[0].normal, 2); Global_to_Local(tmp_w, fluids[-1].convar, normal); Global_to_Local(tmp_wp1, fluids[0].convar, normal); double over_cos = -dy / ((fluids[-1].coordx - fluids[0].coordx) * normal[0] + (fluids[-1].coordy - fluids[0].coordy) * normal[1]); Center_3rd_Splitting(yinterfaces[0], tmp_w, tmp_wp1, over_cos * dy); } } } void Center_3rd_Splitting(Interface2d& interface, double* w, double* wp1, double h) { double prim_left[4], prim_right[4]; Convar_to_ULambda_2d(prim_left, interface.line.left.convar); Convar_to_ULambda_2d(prim_right, interface.line.right.convar); MMDF1st ml(prim_left[1], prim_left[2], prim_left[3]); MMDF1st mr(prim_right[1], prim_right[2], prim_right[3]); Collision(interface.line.center.convar, prim_left[0], prim_right[0], ml, mr); for (int var = 0; var < 4; var++) { interface.line.center.der1x[var] = (wp1[var] - w[var]) / h; } } void Center_do_nothing_normal(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { // do nothing; } void Center_4th_normal(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Center_4th_normal(xinterfaces[0], fluids[-2 * block.ny].convar, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, fluids[0].dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double tmp_wn1[4], tmp_w[4], tmp_wp1[4], tmp_wp2[4]; YchangetoX(tmp_wn1, fluids[-2].convar); YchangetoX(tmp_w, fluids[-1].convar); YchangetoX(tmp_wp1, fluids[0].convar); YchangetoX(tmp_wp2, fluids[1].convar); Center_4th_normal(yinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, fluids[0].dy); } } else { double tmp_wn1[4], tmp_w[4], tmp_wp1[4], tmp_wp2[4]; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = 0.5 * (fluids[-block.ny].dx + fluids[0].dx); Global_to_Local(tmp_wn1, fluids[-2 * block.ny].convar, xinterfaces[0].normal); Global_to_Local(tmp_w, fluids[-1 * block.ny].convar, xinterfaces[0].normal); Global_to_Local(tmp_wp1, fluids[0].convar, xinterfaces[0].normal); Global_to_Local(tmp_wp2, fluids[block.ny].convar, xinterfaces[0].normal); Center_4th_normal(xinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = 0.5 * (fluids[-1].dy + fluids[0].dy); Global_to_Local(tmp_wn1, fluids[-2].convar, yinterfaces[0].normal); Global_to_Local(tmp_w, fluids[-1].convar, yinterfaces[0].normal); Global_to_Local(tmp_wp1, fluids[0].convar, yinterfaces[0].normal); Global_to_Local(tmp_wp2, fluids[1].convar, yinterfaces[0].normal); Center_4th_normal(yinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, dy); } } } void Center_4th_normal(Interface2d& interface, double* wn1, double* w, double* wp1, double* wp2, double h) { for (int var = 0; var < 4; var++) { interface.line.center.convar[var] = (-1.0 / 12.0 * (wp2[var] + wn1[var]) + 7.0 / 12.0 * (wp1[var] + w[var])); interface.line.center.der1x[var] = (-1.0 / 12.0 * (wp2[var] - wn1[var]) + 1.25 * (wp1[var] - w[var])) / h; } } void Center_5th_normal(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { Center_5th_normal(xinterfaces[0], fluids[-2 * block.ny].convar, fluids[-block.ny].convar, fluids[0].convar, fluids[block.ny].convar, fluids[0].dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double tmp_wn1[4], tmp_w[4], tmp_wp1[4], tmp_wp2[4]; YchangetoX(tmp_wn1, fluids[-2].convar); YchangetoX(tmp_w, fluids[-1].convar); YchangetoX(tmp_wp1, fluids[0].convar); YchangetoX(tmp_wp2, fluids[1].convar); Center_5th_normal(yinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, fluids[0].dy); } } else { double tmp_wn1[4], tmp_w[4], tmp_wp1[4], tmp_wp2[4]; if ((fluids[0].xindex > block.ghost - 2) && (fluids[0].xindex < block.nx - block.ghost + 1)) { double dx = 0.5 * (fluids[-block.ny].dx + fluids[0].dx); Global_to_Local(tmp_wn1, fluids[-2 * block.ny].convar, xinterfaces[0].normal); Global_to_Local(tmp_w, fluids[-1 * block.ny].convar, xinterfaces[0].normal); Global_to_Local(tmp_wp1, fluids[0].convar, xinterfaces[0].normal); Global_to_Local(tmp_wp2, fluids[block.ny].convar, xinterfaces[0].normal); Center_5th_normal(xinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, dx); } if ((fluids[0].yindex > block.ghost - 2) && (fluids[0].yindex < block.ny - block.ghost + 1)) { double dy = 0.5 * (fluids[-1].dy + fluids[0].dy); Global_to_Local(tmp_wn1, fluids[-2].convar, yinterfaces[0].normal); Global_to_Local(tmp_w, fluids[-1].convar, yinterfaces[0].normal); Global_to_Local(tmp_wp1, fluids[0].convar, yinterfaces[0].normal); Global_to_Local(tmp_wp2, fluids[1].convar, yinterfaces[0].normal); Center_5th_normal(yinterfaces[0], tmp_wn1, tmp_w, tmp_wp1, tmp_wp2, dy); } } } void Center_5th_normal(Interface2d& interface, double* wn1, double* w, double* wp1, double* wp2, double h) { double prim_left[4], prim_right[4]; Convar_to_ULambda_2d(prim_left, interface.line.left.convar); Convar_to_ULambda_2d(prim_right, interface.line.right.convar); MMDF1st ml(prim_left[1], prim_left[2], prim_left[3]); MMDF1st mr(prim_right[1], prim_right[2], prim_right[3]); Collision(interface.line.center.convar, prim_left[0], prim_right[0], ml, mr); for (int var = 0; var < 4; var++) { interface.line.center.der1x[var] = (-1.0 / 12.0 * (wp2[var] - wn1[var]) + 1.25 * (wp1[var] - w[var])) / h; } bool order_reduce = false; if (interface.line.left.is_reduce_order == true || interface.line.right.is_reduce_order == true) { order_reduce = true; } if (order_reduce == true) { for (int var = 0; var < 4; var++) { interface.line.center.der1x[var] = (wp1[var] - w[var]) / h; } } } void Center_all_collision_multi(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if (flux_function_2d == GKS2D_smooth) { for (int m = 0; m < gausspoint; m++) { Center_all_collision_2d_multi(xinterfaces[0].gauss[m]); Center_all_collision_2d_multi(yinterfaces[0].gauss[m]); } } } void Center_all_collision_2d_multi(Recon2d& gauss) { double prim_left[4], prim_right[4]; Convar_to_ULambda_2d(prim_left, gauss.left.convar); Convar_to_ULambda_2d(prim_right, gauss.right.convar); MMDF ml(prim_left[1], prim_left[2], prim_left[3]); MMDF mr(prim_right[1], prim_right[2], prim_right[3]); Collision(gauss.center.convar, prim_left[0], prim_right[0], ml, mr); double a0[4] = { 1.0, 0.0, 0.0, 0.0 }; double alx[4], arx[4]; //w_x A_point(alx, gauss.left.der1x, prim_left); A_point(arx, gauss.right.der1x, prim_right); double al0x[4]; double ar0x[4]; GL_address(0, 0, 0, al0x, alx, ml); GR_address(0, 0, 0, ar0x, arx, mr); double aly[4], ary[4]; //w_y A_point(aly, gauss.left.der1y, prim_left); A_point(ary, gauss.right.der1y, prim_right); double al0y[4]; double ar0y[4]; GL_address(0, 0, 0, al0y, aly, ml); GR_address(0, 0, 0, ar0y, ary, mr); for (int var = 0; var < 4; var++) { gauss.center.der1x[var] = prim_left[0] * al0x[var] + prim_right[0] * ar0x[var]; gauss.center.der1y[var] = prim_left[0] * al0y[var] + prim_right[0] * ar0y[var]; } } void Center_first_order_tangent(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { first_order_tangent(xinterfaces[0].gauss[num_gauss].center, xinterfaces[0].line.center); first_order_tangent(yinterfaces[0].gauss[num_gauss].center, yinterfaces[0].line.center); } } void Center_3rd_tangent(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { //assume this is uniform mesh, // along x direction tangitial recontruction, Center_3rd_Multi(xinterfaces[0].gauss[num_gauss].center, xinterfaces[-1].line.center, xinterfaces[0].line.center, xinterfaces[1].line.center, xinterfaces[0].length); //since we already do the coordinate transform, along y, no transform needed. Center_3rd_Multi(yinterfaces[0].gauss[num_gauss].center, yinterfaces[block.ny + 1].line.center, yinterfaces[0].line.center, yinterfaces[-block.ny - 1].line.center, yinterfaces[0].length); } } else { Interface2d re[2]; int index[2]; index[0] = -1; index[1] = 1; for (int iface = 0; iface < 2; iface++) { Local_to_Global(re[iface].line.center.convar, xinterfaces[index[iface]].line.center.convar, xinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.convar, xinterfaces[0].normal); Local_to_Global(re[iface].line.center.der1x, xinterfaces[index[iface]].line.center.der1x, xinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.der1x, xinterfaces[0].normal); } for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { //assume this is uniform mesh, Center_3rd_Multi(xinterfaces[0].gauss[num_gauss].center, re[0].line.center, xinterfaces[0].line.center, re[1].line.center, xinterfaces[0].length); } index[0] = (block.ny + 1); index[1] = -(block.ny + 1); for (int iface = 0; iface < 2; iface++) { Local_to_Global(re[iface].line.center.convar, yinterfaces[index[iface]].line.center.convar, yinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.convar, yinterfaces[0].normal); Local_to_Global(re[iface].line.center.der1x, yinterfaces[index[iface]].line.center.der1x, yinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.der1x, yinterfaces[0].normal); } for (int num_gauss = 0; num_gauss < gausspoint; ++num_gauss) { //assume this is uniform mesh, Center_3rd_Multi(yinterfaces[0].gauss[num_gauss].center, re[0].line.center, yinterfaces[0].line.center, re[1].line.center, yinterfaces[0].length); } } } void Center_5th_tangent(Interface2d* xinterfaces, Interface2d* yinterfaces, Fluid2d* fluids, Block2d block) { if (block.uniform == true) { Center_5th_Multi(xinterfaces[0].gauss, xinterfaces[-2].line, xinterfaces[-1].line, xinterfaces[0].line, xinterfaces[1].line, xinterfaces[2].line, xinterfaces[0].length); Center_5th_Multi(yinterfaces[0].gauss, yinterfaces[2 * (block.ny + 1)].line, yinterfaces[block.ny + 1].line, yinterfaces[0].line, yinterfaces[-block.ny - 1].line, yinterfaces[-2 * (block.ny + 1)].line, yinterfaces[0].length); // x direction bool order_reduce = false; for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { if (xinterfaces[0].gauss[num_gauss].center.is_reduce_order == true) { order_reduce = true; } } if (order_reduce == true) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Center_3rd_Multi(xinterfaces[0].gauss[num_gauss].center, xinterfaces[-1].line.center, xinterfaces[0].line.center, xinterfaces[1].line.center, xinterfaces[0].length); } } // y direction order_reduce = false; for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { if (yinterfaces[0].gauss[num_gauss].center.is_reduce_order == true) { order_reduce = true; } } if (order_reduce == true) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Center_3rd_Multi(yinterfaces[0].gauss[num_gauss].center, yinterfaces[block.ny + 1].line.center, yinterfaces[0].line.center, yinterfaces[-block.ny - 1].line.center, yinterfaces[0].length); } } } else { Interface2d re[4]; int index[4]; index[0] = -2; index[1] = -1; index[2] = 1; index[3] = 2; for (int iface = 0; iface < 4; ++iface) { Local_to_Global(re[iface].line.center.convar, xinterfaces[index[iface]].line.center.convar, xinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.convar, xinterfaces[0].normal); Local_to_Global(re[iface].line.center.der1x, xinterfaces[index[iface]].line.center.der1x, xinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.der1x, xinterfaces[0].normal); } //assume this is uniform mesh, Center_5th_Multi(xinterfaces[0].gauss, re[0].line, re[1].line, xinterfaces[0].line, re[2].line, re[3].line, xinterfaces[0].length); index[0] = 2 * (block.ny + 1); index[1] = (block.ny + 1); index[2] = -(block.ny + 1); index[3] = -2 * (block.ny + 1); for (int iface = 0; iface < 4; ++iface) { Local_to_Global(re[iface].line.center.convar, yinterfaces[index[iface]].line.center.convar, yinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.convar, yinterfaces[0].normal); Local_to_Global(re[iface].line.center.der1x, yinterfaces[index[iface]].line.center.der1x, yinterfaces[index[iface]].normal); Global_to_Local(re[iface].line.center.der1x, yinterfaces[0].normal); } Center_5th_Multi(yinterfaces[0].gauss, re[0].line, re[1].line, yinterfaces[0].line, re[2].line, re[3].line, yinterfaces[0].length); } } void Center_5th_Multi(Recon2d* re, Recon2d& wn2, Recon2d& wn1, Recon2d& w0, Recon2d& wp1, Recon2d& wp2, double h) { for (int var = 0; var < 4; var++) { double coe[5]; Polynomial_5th(coe, wn2.center.convar[var], wn1.center.convar[var], w0.center.convar[var], wp1.center.convar[var], wp2.center.convar[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].center.convar[var] = Value_Polynomial(5, re[num_gauss].center.x, coe); re[num_gauss].center.der1y[var] = Der1_Polynomial(5, re[num_gauss].center.x, coe); } Polynomial_5th(coe, wn2.center.der1x[var], wn1.center.der1x[var], w0.center.der1x[var], wp1.center.der1x[var], wp2.center.der1x[var], h); for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { re[num_gauss].center.der1x[var] = Value_Polynomial(5, re[num_gauss].center.x, coe); } } for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Check_Order_Reduce_by_Lambda_2D(re[num_gauss].center.is_reduce_order, re[num_gauss].center.convar); if (re[num_gauss].center.is_reduce_order == true) { for (int m = 0; m < 4; m++) { re[num_gauss].center.convar[m] = w0.center.convar[m]; re[num_gauss].center.der1x[m] = w0.center.der1x[m]; re[num_gauss].center.der1y[m] = 0.0; } } } } void Center_3rd_Multi(Point2d& gauss, Point2d& wn1, Point2d& w0, Point2d& wp1, double h) { for (int var = 0; var < 4; var++) { double coe[3]; Polynomial_3rd_avg(coe, wn1.convar[var], w0.convar[var], wp1.convar[var], h); gauss.convar[var] = Value_Polynomial_3rd(gauss.x, coe); gauss.der1y[var] = Der1_Polynomial_3rd(gauss.x, coe); Polynomial_3rd_avg(coe, wn1.der1x[var], w0.der1x[var], wp1.der1x[var], h); gauss.der1x[var] = Value_Polynomial_3rd(gauss.x, coe); } Check_Order_Reduce_by_Lambda_2D(gauss.is_reduce_order, gauss.convar); //if lambda <0, then reduce to the first order if (gauss.is_reduce_order == true) { for (int m = 0; m < 4; m++) { gauss.convar[m] = w0.convar[m]; gauss.der1x[m] = w0.der1x[m]; gauss.der1y[m] = 0.0; } } } void Calculate_flux(Flux2d_gauss** xfluxes, Flux2d_gauss** yfluxes, Interface2d* xinterfaces, Interface2d* yinterfaces, Block2d block, int stage) { // Note : calculate the final flux of gauss points, in xfluxes, by the reconstructed variables in xinterfaces; the same for y #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost + 1; i++) { for (int j = block.ghost; j < block.nodey + block.ghost; j++) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { flux_function_2d(xfluxes[i * (block.ny + 1) + j][stage].gauss[num_gauss], xinterfaces[i * (block.ny + 1) + j].gauss[num_gauss], block.dt); // calculate the final flux in xfluxes, by the reconstructed variables in xinterfaces; the same for y } } } #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost; i++) { for (int j = block.ghost; j < block.nodey + block.ghost + 1; j++) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { flux_function_2d(yfluxes[i * (block.ny + 1) + j][stage].gauss[num_gauss], yinterfaces[i * (block.ny + 1) + j].gauss[num_gauss], block.dt); } } } } void GKS2D_smooth(Flux2d& flux, Recon2d& interface, double dt) { if (gks2dsolver == nothing_2d) { cout << "no gks solver specify" << endl; exit(0); } double Flux[2][4]; //change conservative variables to rho u lambda double convar0[4]; for (int i = 0; i < 4; i++) { convar0[i] = interface.center.convar[i]; } //cout << endl; double prim0[4]; Convar_to_ULambda_2d(prim0, convar0); //then lets get the coefficient of time intergation factors double tau; double tau_num; tau = Get_Tau_NS(prim0[0], prim0[3]); tau_num = tau; double eta = 0.0; double t[10]; // non equ part time coefficient for gks_2nd algorithm t[0] = tau_num * (1 - eta); // this refers glu, gru part t[1] = tau_num * (eta * (dt + tau_num) - tau_num) + tau * tau_num * (eta - 1); //this refers aluu, aruu part t[2] = tau * tau_num * (eta - 1); //this refers Alu, Aru part // then, equ part time coefficient for gks 2nd t[3] = dt; //this refers g0u part t[4] = -dt * tau; //this refers a0uu part t[5] = 0.5 * dt * dt - tau * dt; //this refers A0u part double unit[4] = { 1, 0.0, 0.0, 0.0 }; //only one part, the kfvs1st part for (int i = 0; i < 4; i++) { Flux[0][i] = 0.0; } //now the equ part added, m0 term added, gks1st part begin MMDF m0(prim0[1], prim0[2], prim0[3]); double g0u[4]; G_address(1, 0, 0, g0u, unit, m0); //the equ g0u part, the gks1st part for (int i = 0; i < 4; i++) { Flux[0][i] = Flux[0][i] + prim0[0] * t[3] * g0u[i]; } // then we still need t[2], t[4] t[5] part for gks 2nd // for t[4] a0xuu part double a0x[4]; double der1[4]; for (int i = 0; i < 4; i++) { der1[i] = interface.center.der1x[i]; } //solve the microslope A(a0x, der1, prim0); //a0x moment double a0xu[4]; G_address(1, 0, 0, a0xu, a0x, m0); //a0x moment double a0xuu[4]; G_address(2, 0, 0, a0xuu, a0x, m0); double a0y[4]; double dery[4]; for (int i = 0; i < 4; i++) { dery[i] = interface.center.der1y[i]; } A(a0y, dery, prim0); double a0yv[4]; G_address(0, 1, 0, a0yv, a0y, m0); //a0x moment double a0yuv[4]; G_address(1, 1, 0, a0yuv, a0y, m0); for (int i = 0; i < 4; i++) { // t4 part Flux[0][i] = Flux[0][i] + prim0[0] * t[4] * (a0xuu[i] + a0yuv[i]); } // for t[5] A0u part double derA0[4]; for (int i = 0; i < 4; i++) { derA0[i] = -prim0[0] * (a0xu[i] + a0yv[i]); } double A0[4]; A(A0, derA0, prim0); double A0u[4]; G_address(1, 0, 0, A0u, A0, m0); for (int i = 0; i < 4; ++i) { // t5 part Flux[0][i] = Flux[0][i] + prim0[0] * t[5] * (A0u[i]); } if (gks2dsolver == gks2nd_2d && timecoe_list_2d == S1O1_2D) { for (int i = 0; i < 4; i++) { flux.f[i] = Flux[0][i]; flux.derf[i] = 0.0; } return; } if (gks2dsolver == gks2nd_2d && (timecoe_list_2d != S1O1_2D)) { double dt2 = 0.5 * dt; t[3] = dt2; //this refers g0u part t[4] = dt2 * tau; //this refers a0uu part t[5] = 0.5 * dt2 * dt2 - tau * dt2; //this refers A0u part for (int i = 0; i < 4; i++) { // t0 part Flux[1][i] = 0.0; // t3 part Flux[1][i] = Flux[1][i] + prim0[0] * t[3] * g0u[i]; // t4 part Flux[1][i] = Flux[1][i] + prim0[0] * t[4] * (a0xuu[i] + a0yuv[i]); // t5 part Flux[1][i] = Flux[1][i] + prim0[0] * t[5] * (A0u[i]); } for (int i = 0; i < 4; i++) { flux.f[i] = (4.0 * Flux[1][i] - Flux[0][i]); flux.derf[i] = 4.0 * (Flux[0][i] - 2.0 * Flux[1][i]); } return; } else { cout << "no valid solver specify" << endl; exit(0); } } void GKS2D(Flux2d& flux, Recon2d& interface, double dt) { // Note : // calculate the final flux in flux, by the reconstructed variables in interface if (gks2dsolver == nothing_2d) { cout << "no gks solver specify" << endl; exit(0); } double Flux[2][4]; double convar_left[4], convar_right[4], convar0[4]; for (int i = 0; i < 4; ++i) { convar_left[i] = interface.left.convar[i]; convar_right[i] = interface.right.convar[i]; } //cout << endl; //change conservative variables to rho u lambda double prim_left[4], prim_right[4], prim0[4]; Convar_to_ULambda_2d(prim_left, convar_left); Convar_to_ULambda_2d(prim_right, convar_right); //prim_left[1], prim_left[2], prim_left[3], means U, V, Lambda MMDF ml(prim_left[1], prim_left[2], prim_left[3]); MMDF mr(prim_right[1], prim_right[2], prim_right[3]); if (g0reconstruction_2D_tangent == Center_all_collision_multi) { Collision(interface.center.convar, prim_left[0], prim_right[0], ml, mr); // ml, mr, pass the whole class into the function double a0[4] = { 1.0, 0.0, 0.0, 0.0 }; double alx_t[4], arx_t[4]; //w_x A_point(alx_t, interface.left.der1x, prim_left); // input the slope of macroscopic variables, output the a coefficient A_point(arx_t, interface.right.der1x, prim_right); double al0x_t[4]; double ar0x_t[4]; GL_address(0, 0, 0, al0x_t, alx_t, ml); // ml, mr, pass the whole class into the function GR_address(0, 0, 0, ar0x_t, arx_t, mr); // ml, mr, pass the whole class into the function //GL_address, GR_address, G_address, are calculating the macroscopic variables by the microscopic variables based on moment calculation //Note: when the input of moment calculation is a coefficient, the result is the derivative of W; when the input is (0 0 0 0), the result is W //when the input is (1 0 0 0), the result is the relative flux, without considering the integral of time //w_y double aly_t[4], ary_t[4]; A_point(aly_t, interface.left.der1y, prim_left); A_point(ary_t, interface.right.der1y, prim_right); //The difference of A_point with A is just the input form, matrix or pointer //The content, input variables, output variables are the same double al0y_t[4]; double ar0y_t[4]; GL_address(0, 0, 0, al0y_t, aly_t, ml); GR_address(0, 0, 0, ar0y_t, ary_t, mr); for (int var = 0; var < 4; ++var) { interface.center.der1x[var] = prim_left[0] * al0x_t[var] + prim_right[0] * ar0x_t[var]; interface.center.der1y[var] = prim_left[0] * al0y_t[var] + prim_right[0] * ar0y_t[var]; } } for (int i = 0; i < 4; ++i) { convar0[i] = interface.center.convar[i]; } Convar_to_ULambda_2d(prim0, convar0); //then lets get the coefficient of time intergation factors double tau; double tau_num; tau = Get_Tau_NS(prim0[0], prim0[3]); tau_num = Get_Tau(prim_left[0], prim_right[0], prim0[0], prim_left[3], prim_right[3], prim0[3], dt); double eta = exp(-dt / tau_num); double t[10]; // non equ part time coefficient for gks_2nd algorithm t[0] = tau_num * (1 - eta); // this refers glu, gru part t[1] = tau_num * (eta * (dt + tau_num) - tau_num) + tau * tau_num * (eta - 1); //this refers aluu, aruu part t[2] = tau * tau_num * (eta - 1); //this refers Alu, Aru part // then, equ part time coefficient for gks 2nd t[3] = tau_num * eta + dt - tau_num; //this refers g0u part t[4] = tau_num * (tau_num - eta * (dt + tau_num) - tau * (eta - 1)) - dt * tau; //this refers a0uu part t[5] = 0.5 * dt * dt - tau * tau_num * (eta - 1) - tau * dt; //this refers A0u part //reset the t[0~5], used ONLY for kfvs method //in kfvs, only use time step deltat, but NOT collision time if (gks2dsolver == kfvs1st_2d) { t[0] = dt; for (int i = 1; i < 6; i++) { t[i] = 0.0; } //do nothing, kfvs1st only use t[0]=dt part; } else if (gks2dsolver == kfvs2nd_2d) { t[0] = dt; t[1] = -0.5 * dt * dt; for (int i = 2; i < 6; i++) { t[i] = 0.0; } } double unit[4] = { 1, 0.0, 0.0, 0.0 }; // alx_t = a(0)*1 + a(1)*u + a(2)*v + a(3)*e; arx_t, aly_t, ary_t are the same // the slope of the (macroscopic) conservative variables value (/density) can be obtained by (in al0x_t), GL_address(0, 0, 0, al0x_t, alx_t, ml); // thus, when replace a by unit (=[1 0 0 0]), GL_address can get the relative (macroscopic) conservative variables (/density); but pay attention to the (1 0 0) but not (0 0 0) // G_address, GR_address, are the same with GL_address double glu[4], gru[4]; GL_address(1, 0, 0, glu, unit, ml); // (1 0 0) get GLu GR_address(1, 0, 0, gru, unit, mr); // (1 0 0) get GRu //only one part, the kfvs1st part for (int i = 0; i < 4; i++) { Flux[0][i] = prim_left[0] * t[0] * glu[i] + prim_right[0] * t[0] * gru[i]; } //cout<< endl; if (gks2dsolver == kfvs1st_2d) { for (int i = 0; i < 4; i++) { flux.f[i] = Flux[0][i]; } return; } // kfvs1st part ended //now the equ part added, m0 term added, gks1st part begin MMDF m0(prim0[1], prim0[2], prim0[3]); double g0u[4]; G_address(1, 0, 0, g0u, unit, m0); if (gks2dsolver != kfvs2nd_2d) { //the equ g0u part, the gks1st part for (int i = 0; i < 4; i++) { Flux[0][i] = Flux[0][i] + prim0[0] * t[3] * g0u[i]; } } if (gks2dsolver == gks1st_2d) { for (int i = 0; i < 4; i++) { flux.f[i] = Flux[0][i]; } return; } // gks1d solver ended //for kfvs2nd part double der1xleft[4], der1xright[4]; double der1yleft[4], der1yright[4]; for (int i = 0; i < 4; i++) { der1xleft[i] = interface.left.der1x[i]; der1xright[i] = interface.right.der1x[i]; der1yleft[i] = interface.left.der1y[i]; der1yright[i] = interface.right.der1y[i]; } double alx[4]; A(alx, der1xleft, prim_left); double alxuul[4]; GL_address(2, 0, 0, alxuul, alx, ml); double arx[4]; A(arx, der1xright, prim_right); double arxuur[4]; GR_address(2, 0, 0, arxuur, arx, mr); double aly[4]; A(aly, der1yleft, prim_left); double alyuvl[4]; GL_address(1, 1, 0, alyuvl, aly, ml); double ary[4]; A(ary, der1yright, prim_right); double aryuvr[4]; GR_address(1, 1, 0, aryuvr, ary, mr); for (int i = 0; i < 4; i++) { // t1 part Flux[0][i] = Flux[0][i] + t[1] * (prim_left[0] * (alxuul[i] + alyuvl[i]) + prim_right[0] * (arxuur[i] + aryuvr[i])); } if (gks2dsolver == kfvs2nd_2d) { for (int i = 0; i < 4; i++) { flux.f[i] = Flux[0][i]; } return; } // the kfvs2nd part ended // then we still need t[2], t[4] t[5] part for gks 2nd //for t[2] Aru,Alu part double alxu[4]; double alyv[4]; double arxu[4]; double aryv[4]; //take moment for al, ar G_address(1, 0, 0, alxu, alx, ml); G_address(1, 0, 0, arxu, arx, mr); G_address(0, 1, 0, alyv, aly, ml); G_address(0, 1, 0, aryv, ary, mr); double Al[4], Ar[4]; double der_AL[4], der_AR[4]; //using compatability condition to get the time derivative for (int i = 0; i < 4; i++) { der_AL[i] = -prim_left[0] * (alxu[i] + alyv[i]); der_AR[i] = -prim_right[0] * (arxu[i] + aryv[i]); } // solve the coefficient martix b=ma A(Al, der_AL, prim_left); A(Ar, der_AR, prim_right); //to obtain the Alu and Aru double Alul[4]; double Arur[4]; GL_address(1, 0, 0, Alul, Al, ml); GR_address(1, 0, 0, Arur, Ar, mr); for (int i = 0; i < 4; i++) { // t2 part Flux[0][i] = Flux[0][i] + t[2] * (prim_left[0] * Alul[i] + prim_right[0] * Arur[i]); } // for t[4] a0xuu part double a0x[4]; double der1[4]; for (int i = 0; i < 4; i++) { der1[i] = interface.center.der1x[i]; //Only the averaged value for g0 } //solve the microslope A(a0x, der1, prim0); //a0x moment double a0xu[4]; G_address(1, 0, 0, a0xu, a0x, m0); //get a0xu, used for the following determination of derA0, and then A0 //a0x moment double a0xuu[4]; G_address(2, 0, 0, a0xuu, a0x, m0); double a0y[4]; double dery[4]; for (int i = 0; i < 4; i++) { dery[i] = interface.center.der1y[i]; } A(a0y, dery, prim0); double a0yv[4]; G_address(0, 1, 0, a0yv, a0y, m0); //get a0yv, used for the following determination of derA0, and then A0 //a0x moment double a0yuv[4]; G_address(1, 1, 0, a0yuv, a0y, m0); for (int i = 0; i < 4; i++) { // t4 part Flux[0][i] = Flux[0][i] + prim0[0] * t[4] * (a0xuu[i] + a0yuv[i]); } // for t[5] A0u part double derA0[4]; for (int i = 0; i < 4; i++) { derA0[i] = -prim0[0] * (a0xu[i] + a0yv[i]); } double A0[4]; A(A0, derA0, prim0); double A0u[4]; G_address(1, 0, 0, A0u, A0, m0); for (int i = 0; i < 4; i++) { // t5 part Flux[0][i] = Flux[0][i] + prim0[0] * t[5] * (A0u[i]); } if (is_Prandtl_fix == true) { double qs; qs = a0xuu[3] + A0u[3] - prim0[1] * (a0xuu[1] + A0u[1]) - prim0[2] * (a0xuu[2] + A0u[2]); qs *= -prim0[0] * tau * dt; Flux[0][3] += (1.0 / Pr - 1.0) * qs; } if (gks2dsolver == gks2nd_2d && timecoe_list_2d == S1O1_2D) { for (int i = 0; i < 4; i++) { flux.f[i] = Flux[0][i]; flux.derf[i] = 0.0; } return; } if (gks2dsolver == gks2nd_2d && timecoe_list_2d != S1O1_2D) { double dt2 = 0.5 * dt; // the following is dt2 tau_num = Get_Tau(prim_left[0], prim_right[0], prim0[0], prim_left[3], prim_right[3], prim0[3], dt2); eta = exp(-dt2 / tau_num); // non equ part time coefficient for gks_2nd algorithm t[0] = tau_num * (1 - eta); // this refers glu, gru part t[1] = tau_num * (eta * (dt2 + tau_num) - tau_num) + tau * tau_num * (eta - 1); //this refers aluu, aruu part t[2] = tau * tau_num * (eta - 1); //this refers Alu, Aru part // then, equ part time coefficient for gks 2nd t[3] = tau_num * eta + dt2 - tau_num; //this refers g0u part t[4] = tau_num * (tau_num - eta * (dt2 + tau_num) - tau * (eta - 1)) - dt2 * tau; //this refers a0uu part t[5] = 0.5 * dt2 * dt2 - tau * tau_num * (eta - 1) - tau * dt2; //this refers A0u part for (int i = 0; i < 4; i++) { // t0 part Flux[1][i] = t[0] * (prim_left[0] * glu[i] + prim_right[0] * gru[i]); // t1 part Flux[1][i] = Flux[1][i] + t[1] * (prim_left[0] * (alxuul[i] + alyuvl[i]) + prim_right[0] * (arxuur[i] + aryuvr[i])); // t2 part Flux[1][i] = Flux[1][i] + t[2] * (prim_left[0] * Alul[i] + prim_right[0] * Arur[i]); // t3 part Flux[1][i] = Flux[1][i] + prim0[0] * t[3] * g0u[i]; // t4 part Flux[1][i] = Flux[1][i] + prim0[0] * t[4] * (a0xuu[i] + a0yuv[i]); // t5 part Flux[1][i] = Flux[1][i] + prim0[0] * t[5] * (A0u[i]); } if (is_Prandtl_fix == true) { double qs; qs = a0xuu[3] + A0u[3] - prim0[1] * (a0xuu[1] + A0u[1]) - prim0[2] * (a0xuu[2] + A0u[2]); qs *= -prim0[0] * tau * 0.5 * dt; Flux[1][3] += (1.0 / Pr - 1.0) * qs; } for (int i = 0; i < 4; i++) { flux.f[i] = (4.0 * Flux[1][i] - Flux[0][i]); flux.derf[i] = 4.0 * (Flux[0][i] - 2.0 * Flux[1][i]); } return; } else { cout << "no valid solver specify" << endl; exit(0); } } void LF2D(Flux2d& flux, Recon2d& interface, double dt) { double pl[4], pr[4]; Convar_to_primvar_2D(pl, interface.left.convar); Convar_to_primvar_2D(pr, interface.right.convar); double k[2]; k[0] = abs(pl[1]) + sqrt(Gamma * pl[3] / pl[0]); k[1] = abs(pr[1]) + sqrt(Gamma * pr[3] / pr[0]); double beta = k[0]; if (k[1] > k[0]) { beta = k[1]; } double flux_l[4], flux_r[4]; get_flux(pl, flux_l); get_flux(pr, flux_r); for (int m = 0; m < 4; m++) { flux.f[m] = 0.5 * ((flux_l[m] + flux_r[m]) - beta * (interface.right.convar[m] - interface.left.convar[m])); flux.f[m] *= dt; } if (tau_type == NS) { NS_by_central_difference_prim_2D(flux, interface, dt); } } void HLLC2D(Flux2d& flux, Recon2d& interface, double dt) { double pl[4], pr[4]; Convar_to_primvar_2D(pl, interface.left.convar); Convar_to_primvar_2D(pr, interface.right.convar); double al, ar, pvars, pstar, tmp1, tmp2, tmp3, qk, sl, sr, star; al = sqrt(Gamma * pl[3] / pl[0]); //sound speed ar = sqrt(Gamma * pr[3] / pr[0]); tmp1 = 0.5 * (al + ar); //avg of sound and density tmp2 = 0.5 * (pl[0] + pr[0]); pvars = 0.5 * (pl[3] + pr[3]) - 0.5 * (pr[1] - pl[1]) * tmp1 * tmp2; pstar = fmax(0.0, pvars); double flxtmp[4], qstar[4]; ESTIME(sl, star, sr, pl[0], pl[1], pl[3], al, pr[0], pr[1], pr[3], ar); tmp1 = pr[3] - pl[3] + pl[0] * pl[1] * (sl - pl[1]) - pr[0] * pr[1] * (sr - pr[1]); tmp2 = pl[0] * (sl - pl[1]) - pr[0] * (sr - pr[1]); star = tmp1 / tmp2; if (sl >= 0.0) { get_flux(pl, flux.f); } else if (sr <= 0.0) { get_flux(pr, flux.f); } else if ((star >= 0.0) && (sl <= 0.0)) { get_flux(pl, flxtmp); ustarforHLLC(pl[0], pl[1], pl[2], pl[3], sl, star, qstar); for (int m = 0; m < 4; m++) { flux.f[m] = flxtmp[m] + sl * (qstar[m] - interface.left.convar[m]); } } else if ((star <= 0.0) && (sr >= 0.0)) { get_flux(pr, flxtmp); ustarforHLLC(pr[0], pr[1], pr[2], pr[3], sr, star, qstar); for (int m = 0; m < 4; m++) { flux.f[m] = flxtmp[m] + sr * (qstar[m] - interface.right.convar[m]); } } else { cout << "couldnt be possible that hllc cannot give any result" << endl; } for (int m = 0; m < 4; m++) { flux.f[m] *= dt; } if (tau_type == NS) { NS_by_central_difference_convar_2D(flux, interface, dt); } } void NS_by_central_difference_prim_2D(Flux2d& flux, Recon2d& interface, double dt) { // Note : Sixth-order centrial differential scheme for viscous term // here convar[i] represents density, u, v, and temperature double mu = Mu; if (Nu > 0) { mu = Nu * interface.center.convar[0]; } double u = interface.center.convar[1]; double v = interface.center.convar[2]; double ux, uy, vx, vy; ux = interface.center.der1x[1]; vx = interface.center.der1x[2]; uy = interface.center.der1y[1]; vy = interface.center.der1y[2]; double tau_xx = 2 * mu * ux - 2.0 / 3.0 * mu * (ux + vy); double tau_xy = mu * (uy + vx); double q = u * tau_xx + v * tau_xy + (K + 4) / (2 * Pr) * mu * interface.center.der1x[3]; flux.f[1] += tau_xx * dt; flux.f[2] += tau_xy * dt; flux.f[3] += q * dt; } void NS_by_central_difference_convar_2D(Flux2d& flux, Recon2d& interface, double dt) { // Note: Write a function calculating the flux of viscous term in NS, used for HLLC Riemann solver // If g0type = collisionnless, means the conservative variables used for viscous flux are those of Gauss points, which were interpolated by the line-averaged variables in the tangential direction // If g0type = collisionn, means, the conservative variables used for viscous flux are averaged by the left and right variables (line-ageraged) // This is because of the first method might cause negative variables for density or pressure, which is not allowed. double convar[4]; for (int m = 0; m < 4; m++) { convar[m] = 0.5 * (interface.left.convar[m] + interface.right.convar[m]); } // here convar[i] represents the conservative variables double den = convar[0]; double mu = Mu; if (Nu > 0) { mu = Nu * den; } double u = convar[1] / den; double v = convar[2] / den; double ux, uy, vx, vy; ux = (interface.center.der1x[1] - interface.center.der1x[0] * u) / den; vx = (interface.center.der1x[2] - interface.center.der1x[0] * v) / den; uy = (interface.center.der1y[1] - interface.center.der1y[0] * u) / den; vy = (interface.center.der1y[2] - interface.center.der1y[0] * v) / den; double tau_xx = 2 * mu * ux - 2.0 / 3.0 * mu * (ux + vy); double tau_xy = mu * (uy + vx); double Tx = interface.center.der1x[3] / den - u * ux - u * vx - convar[3] * interface.center.der1x[0] / den / den; double q = u * tau_xx + v * tau_xy + (K + 4) / (2.0 * Pr) * mu * Tx; flux.f[1] -= tau_xx * dt; flux.f[2] -= tau_xy * dt; flux.f[3] -= q * dt; } //forward_euler void S1O1_2D(Block2d& block) { block.stages = 1; block.timecoefficient[0][0][0] = 1.0; block.timecoefficient[0][0][1] = 0.0; } void S1O2_2D(Block2d& block) { block.stages = 1; block.timecoefficient[0][0][0] = 1.0; block.timecoefficient[0][0][1] = 0.5; } void RK2_2D(Block2d& block) { block.stages = 2; block.timecoefficient[0][0][0] = 1.0; block.timecoefficient[1][0][0] = 0.5; block.timecoefficient[1][1][0] = 0.5; } void S2O4_2D(Block2d& block) { block.stages = 2; block.timecoefficient[0][0][0] = 0.5; block.timecoefficient[0][0][1] = 1.0 / 8.0; block.timecoefficient[1][0][0] = 1.0; block.timecoefficient[1][1][0] = 0.0; block.timecoefficient[1][0][1] = 1.0 / 6.0; block.timecoefficient[1][1][1] = 1.0 / 3.0; } void RK4_2D(Block2d& block) { block.stages = 4; block.timecoefficient[0][0][0] = 0.5; block.timecoefficient[1][1][0] = 0.5; block.timecoefficient[2][2][0] = 1.0; block.timecoefficient[3][0][0] = 1.0 / 6.0; block.timecoefficient[3][1][0] = 1.0 / 3.0; block.timecoefficient[3][2][0] = 1.0 / 3.0; block.timecoefficient[3][3][0] = 1.0 / 6.0; } void Initial_stages(Block2d& block) { for (int i = 0; i < 5; i++) //refers the n stage { for (int j = 0; j < 5; j++) //refers the nth coefficient at n stage { for (int k = 0; k < 3; k++) //refers f, derf, der2f { block.timecoefficient[i][j][k] = 0.0; } } } timecoe_list_2d(block); } Fluid2d* Setfluid(Block2d& block) { Fluid2d* var = new Fluid2d[block.nx * block.ny]; // dynamic variable (since block.nx is not determined) if (var == 0) { cout << "fluid variable allocate fail..."; return NULL; } for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { var[i * block.ny + j].xindex = i; var[i * block.ny + j].yindex = j; } } cout << "fluid variable allocate done..." << endl; return var; } Interface2d* Setinterface_array(Block2d block) { Interface2d* var = new Interface2d[(block.nx + 1) * (block.ny + 1)]; // dynamic variable (since block.nx is not determined) if (var == 0) { cout << "fluid variable allocate fail..."; return NULL; } for (int i = 0; i < block.nx + 1; i++) { for (int j = 0; j < block.ny + 1; j++) { for (int k = 0; k < 4; k++) { var[i * (block.ny + 1) + j].line.left.der1x[k] = 0.0; var[i * (block.ny + 1) + j].line.left.der1y[k] = 0.0; var[i * (block.ny + 1) + j].line.right.der1x[k] = 0.0; var[i * (block.ny + 1) + j].line.right.der1y[k] = 0.0; var[i * (block.ny + 1) + j].line.center.der1x[k] = 0.0; var[i * (block.ny + 1) + j].line.center.der1y[k] = 0.0; } } } cout << "interface variable allocate done..." << endl; return var; } Flux2d_gauss** Setflux_gauss_array(Block2d block) { Flux2d_gauss** var = new Flux2d_gauss * [(block.nx + 1) * (block.ny + 1)]; // dynamic variable (since block.nx is not determined) for (int i = 0; i < block.nx + 1; i++) { for (int j = 0; j < block.ny + 1; j++) { // for m th step time marching schemes, m subflux needed var[i * (block.ny + 1) + j] = new Flux2d_gauss[block.stages]; } } for (int i = 0; i < block.nx + 1; i++) { for (int j = 0; j < block.ny + 1; j++) { for (int k = 0; k < block.stages; k++) { if (gausspoint == 0) { var[i * (block.ny + 1) + j][k].gauss = new Flux2d[1]; for (int m = 0; m < 4; m++) { var[i * (block.ny + 1) + j][k].gauss[0].f[m] = 0.0; var[i * (block.ny + 1) + j][k].gauss[0].derf[m] = 0.0; } } else { var[i * (block.ny + 1) + j][k].gauss = new Flux2d[gausspoint]; for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { for (int m = 0; m < 4; m++) { var[i * (block.ny + 1) + j][k].gauss[num_gauss].f[m] = 0.0; var[i * (block.ny + 1) + j][k].gauss[num_gauss].derf[m] = 0.0; } } } } } } if (var == 0) { cout << "fluid variable allocate fail..."; return NULL; } cout << "flux with gausspoint variable allocate done..." << endl; return var; } void SetUniformMesh(Block2d& block, Fluid2d* fluids, Interface2d* xinterfaces, Interface2d* yinterfaces, Flux2d_gauss** xfluxes, Flux2d_gauss** yfluxes) { //nodex, nodey are the real node //interface number = cell number + 1 block.dx = (block.right - block.left) / block.nodex; block.dy = (block.up - block.down) / block.nodey; block.overdx = 1 / block.dx; block.overdy = 1 / block.dy; block.xcell_begin = block.ghost; block.xcell_end = block.ghost + block.nodex - 1; block.ycell_begin = block.ghost; block.ycell_end = block.ghost + block.nodey - 1; block.xinterface_begin_n = block.ghost; block.xinterface_end_n = block.ghost + block.nodex; block.xinterface_begin_t = block.ghost; block.xinterface_end_t = block.ghost + block.nodex - 1; block.yinterface_begin_n = block.ghost; block.yinterface_end_n = block.ghost + block.nodey; block.yinterface_begin_t = block.ghost; block.yinterface_end_t = block.ghost + block.nodey - 1; //cell avg information for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { //two dimension geometry to one dimension store matrix, y direciton first and x direction second fluids[i * block.ny + j].dx = block.dx; //cell size fluids[i * block.ny + j].dy = block.dy; //cell size fluids[i * block.ny + j].coordx = block.left + (i + 0.5 - block.ghost) * block.dx; //cell center location fluids[i * block.ny + j].coordy = block.down + (j + 0.5 - block.ghost) * block.dy; //cell center location fluids[i * block.ny + j].area = block.dx * block.dy; fluids[i * block.ny + j].node[0] = block.left + (i - block.ghost) * block.dx; fluids[i * block.ny + j].node[1] = block.down + (j - block.ghost) * block.dy; fluids[i * block.ny + j].node[2] = block.left + (i + 1 - block.ghost) * block.dx; fluids[i * block.ny + j].node[3] = block.down + (j - block.ghost) * block.dy; fluids[i * block.ny + j].node[4] = block.left + (i + 1 - block.ghost) * block.dx; fluids[i * block.ny + j].node[5] = block.down + (j + 1 - block.ghost) * block.dy; fluids[i * block.ny + j].node[6] = block.left + (i - block.ghost) * block.dx; fluids[i * block.ny + j].node[7] = block.down + (j + 1 - block.ghost) * block.dy; } } // interface information for (int i = 0; i <= block.nx; i++) { for (int j = 0; j <= block.ny; j++) { xinterfaces[i * (block.ny + 1) + j].x = block.left + (i - block.ghost) * block.dx; xinterfaces[i * (block.ny + 1) + j].y = block.down + (j - block.ghost + 0.5) * block.dy; xinterfaces[i * (block.ny + 1) + j].length = block.dy; xinterfaces[i * (block.ny + 1) + j].normal[0] = 1.0; xinterfaces[i * (block.ny + 1) + j].normal[1] = 0.0; Copy_geo_from_interface_to_line(xinterfaces[i * (block.ny + 1) + j]); xinterfaces[i * (block.ny + 1) + j].gauss = new Recon2d[gausspoint]; Copy_geo_from_interface_to_flux (xinterfaces[i * (block.ny + 1) + j], xfluxes[i * (block.ny + 1) + j], block.stages); yinterfaces[i * (block.ny + 1) + j].y = block.down + (j - block.ghost) * block.dy; yinterfaces[i * (block.ny + 1) + j].x = block.left + (i - block.ghost + 0.5) * block.dx; yinterfaces[i * (block.ny + 1) + j].length = block.dx; yinterfaces[i * (block.ny + 1) + j].normal[0] = 0.0; yinterfaces[i * (block.ny + 1) + j].normal[1] = 1.0; Copy_geo_from_interface_to_line(yinterfaces[i * (block.ny + 1) + j]); yinterfaces[i * (block.ny + 1) + j].gauss = new Recon2d[gausspoint]; Copy_geo_from_interface_to_flux (yinterfaces[i * (block.ny + 1) + j], yfluxes[i * (block.ny + 1) + j], block.stages); Set_Gauss_Coordinate(xinterfaces[i * (block.ny + 1) + j], yinterfaces[i * (block.ny + 1) + j]); } } cout << "set uniform information done..." << endl; } void Copy_geo_from_interface_to_line(Interface2d& interface) { interface.line.x = interface.x; interface.line.y = interface.y; interface.line.normal[0] = interface.normal[0]; interface.line.normal[1] = interface.normal[1]; } void Copy_geo_from_interface_to_flux(Interface2d& interface, Flux2d_gauss* flux, int stages) { for (int istage = 0; istage < stages; istage++) { if (gausspoint == 0) { int igauss = 0; flux[istage].gauss[igauss].normal[0] = interface.normal[0]; flux[istage].gauss[igauss].normal[1] = interface.normal[1]; flux[istage].gauss[igauss].length = interface.length; } else { for (int igauss = 0; igauss < gausspoint; igauss++) { flux[istage].gauss[igauss].normal[0] = interface.normal[0]; flux[istage].gauss[igauss].normal[1] = interface.normal[1]; flux[istage].gauss[igauss].length = interface.length; } } } } void Set_Gauss_Coordinate(Interface2d& xinterface, Interface2d& yinterface) { for (int num_guass = 0; num_guass < gausspoint; num_guass++) { // first is gauss parameter xinterface.gauss[num_guass].x = xinterface.x; xinterface.gauss[num_guass].y = xinterface.y + gauss_loc[num_guass] * 0.5 * xinterface.length; xinterface.gauss[num_guass].normal[0] = xinterface.normal[0]; xinterface.gauss[num_guass].normal[1] = xinterface.normal[1]; // each gauss point contain left center right point Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].left, num_guass, xinterface.length); Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].right, num_guass, xinterface.length); Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].center, num_guass, xinterface.length); yinterface.gauss[num_guass].x = yinterface.x + gauss_loc[num_guass] * 0.5 * yinterface.length; yinterface.gauss[num_guass].y = yinterface.y; yinterface.gauss[num_guass].normal[0] = yinterface.normal[0]; yinterface.gauss[num_guass].normal[1] = yinterface.normal[1]; // each gauss point contain left center right point Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].left, num_guass, yinterface.length); Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].right, num_guass, yinterface.length); Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].center, num_guass, yinterface.length); } } void Set_Gauss_Intergation_Location_x(Point2d& xgauss, int index, double h) { xgauss.x = gauss_loc[index] * h / 2.0; } void Set_Gauss_Intergation_Location_y(Point2d& ygauss, int index, double h) { ygauss.x = gauss_loc[index] * h / 2.0; } void Update(Fluid2d* fluids, Flux2d_gauss** xfluxes, Flux2d_gauss** yfluxes, Block2d block, int stage) { // Note : write the function to update the conservative variables of each cell if (stage > block.stages) { cout << "wrong middle stage,pls check the time marching setting" << endl; exit(0); } double dt = block.dt; #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost + 1; i++) { for (int j = block.ghost; j < block.nodey + block.ghost; j++) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { for (int var = 0; var < 4; var++) { double Flux = 0.0; for (int k = 0; k < stage + 1; k++) { Flux = Flux + gauss_weight[num_gauss] * (block.timecoefficient[stage][k][0] * xfluxes[i * (block.ny + 1) + j][k].gauss[num_gauss].f[var] + block.timecoefficient[stage][k][1] * xfluxes[i * (block.ny + 1) + j][k].gauss[num_gauss].derf[var]); } xfluxes[i * (block.ny + 1) + j][stage].gauss[num_gauss].x[var] = Flux; // calculate the final flux of the interface, in x in xfluxes, by the obtained the flux and its derivative (f, def, der2f) at guass points, in xfluxes, and the corresponding weight factors // calculate by several stages according to the time marching method. same for yfluxes } } } } #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost; i++) { for (int j = block.ghost; j < block.nodey + block.ghost + 1; j++) { for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { for (int var = 0; var < 4; var++) { double Flux = 0.0; for (int k = 0; k < stage + 1; k++) { Flux = Flux + gauss_weight[num_gauss] * (block.timecoefficient[stage][k][0] * yfluxes[i * (block.ny + 1) + j][k].gauss[num_gauss].f[var] + block.timecoefficient[stage][k][1] * yfluxes[i * (block.ny + 1) + j][k].gauss[num_gauss].derf[var]); } yfluxes[i * (block.ny + 1) + j][stage].gauss[num_gauss].x[var] = Flux; } } } } Update_with_gauss(fluids, xfluxes, yfluxes, block, stage); } void Update_with_gauss(Fluid2d* fluids, Flux2d_gauss** xfluxes, Flux2d_gauss** yfluxes, Block2d block, int stage) { //Note : calculate the final flux of the cell, in fluids, by the obtained final flux of interface, in xfluxes and yfluxes #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost + 1; i++) { for (int j = block.ghost; j < block.nodey + block.ghost + 1; j++) { int face = i * (block.ny + 1) + j; for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { Local_to_Global(yfluxes[face][stage].gauss[num_gauss].x, yfluxes[face][stage].gauss[num_gauss].normal); Local_to_Global(xfluxes[face][stage].gauss[num_gauss].x, xfluxes[face][stage].gauss[num_gauss].normal); } } } #pragma omp parallel for for (int i = block.ghost; i < block.nodex + block.ghost; i++) { for (int j = block.ghost; j < block.nodey + block.ghost; j++) { int cell = i * (block.ny) + j; int face = i * (block.ny + 1) + j; for (int var = 0; var < 4; var++) { fluids[cell].convar[var] = fluids[cell].convar_old[var]; //get the Wn from convar_old double total_flux = 0.0; for (int num_gauss = 0; num_gauss < gausspoint; num_gauss++) { total_flux += yfluxes[face][stage].gauss[num_gauss].length * yfluxes[face][stage].gauss[num_gauss].x[var]; total_flux += -yfluxes[face + 1][stage].gauss[num_gauss].length * yfluxes[face + 1][stage].gauss[num_gauss].x[var]; total_flux += xfluxes[face][stage].gauss[num_gauss].length * xfluxes[face][stage].gauss[num_gauss].x[var]; total_flux += -xfluxes[face + block.ny + 1][stage].gauss[num_gauss].length * xfluxes[face + block.ny + 1][stage].gauss[num_gauss].x[var]; } fluids[cell].convar[var] += total_flux / fluids[cell].area; // calculate the final flux of the cell, in fluids, by the obtained final flux of interface, in xfluxes and yfluxes // in 2d, the total flux be updated by the line-averaged flux of four interface } } } } void Check_Order_Reduce_by_Lambda_2D(bool& order_reduce, double* convar) { order_reduce = false; double lambda; lambda = Lambda(convar[0], convar[1] / convar[0], convar[2] / convar[0], convar[3]); //if lambda <0, then reduce to the first order if (lambda <= 0.0 || (lambda == lambda) == false) { order_reduce = true; } } void Recompute_KFVS_1st(Fluid2d& fluid, double* center, double* left, double* right, double* down, double* up, Block2d& block) { double flux_left[4]; double flux_right[4]; double flux_down[4]; double flux_up[4]; KFVS_1st(flux_left, left, center, block.dt); KFVS_1st(flux_right, center, right, block.dt); double center_tmp[4], up_tmp[4], down_tmp[4]; YchangetoX(center_tmp, center); YchangetoX(up_tmp, up); YchangetoX(down_tmp, down); KFVS_1st(flux_down, down_tmp, center_tmp, block.dt); KFVS_1st(flux_up, center_tmp, up_tmp, block.dt); fluid.convar[0] = fluid.convar_old[0] + 1.0 / block.dy * (flux_down[0] - flux_up[0]); fluid.convar[1] = fluid.convar_old[1] + 1.0 / block.dy * (-flux_down[2] + flux_up[2]); fluid.convar[2] = fluid.convar_old[2] + 1.0 / block.dy * (flux_down[1] - flux_up[1]); fluid.convar[3] = fluid.convar_old[3] + 1.0 / block.dy * (flux_down[3] - flux_up[3]); fluid.convar[0] = fluid.convar[0] + 1.0 / block.dx * (flux_left[0] - flux_right[0]); fluid.convar[1] = fluid.convar[1] + 1.0 / block.dx * (flux_left[1] - flux_right[1]); fluid.convar[2] = fluid.convar[2] + 1.0 / block.dx * (flux_left[2] - flux_right[2]); fluid.convar[3] = fluid.convar[3] + 1.0 / block.dx * (flux_left[3] - flux_right[3]); } void KFVS_1st(double* flux, double* left, double* right, double dt) { double density_left, density_right; double u_left, u_right, v_left, v_right; //λ double lambda_left, lambda_right; density_left = left[0]; density_right = right[0]; u_left = U(density_left, left[1]); v_left = V(density_left, left[2]); lambda_left = Lambda(density_left, u_left, v_left, left[3]); u_right = U(density_right, right[1]); v_right = V(density_right, right[2]); lambda_right = Lambda(density_right, u_right, v_right, right[3]); MMDF1st m2(u_left, v_left, lambda_left); MMDF1st m3(u_right, v_right, lambda_right); //t4part flux[0] = density_left * dt * m2.uplus[1] + density_right * dt * m3.uminus[1]; flux[1] = density_left * dt * m2.uplus[2] + density_right * dt * m3.uminus[2]; flux[2] = density_left * dt * m2.uplus[1] * m2.vwhole[1] + density_right * dt * m3.uminus[1] * m3.vwhole[1]; flux[3] = density_left * 0.5 * dt * (m2.uplus[3] + m2.uplus[1] * m2.vwhole[2] + m2.uplus[1] * m2.xi2) + density_right * 0.5 * dt * (m3.uminus[3] + m3.uminus[1] * m3.vwhole[2] + m3.uminus[1] * m3.xi2); } void SetNonUniformMesh(Block2d& block, Fluid2d* fluids, Interface2d* xinterfaces, Interface2d* yinterfaces, Flux2d_gauss** xfluxes, Flux2d_gauss** yfluxes, double** node2d) { block.xcell_begin = block.ghost; block.xcell_end = block.ghost + block.nodex - 1; block.ycell_begin = block.ghost; block.ycell_end = block.ghost + block.nodey - 1; block.xinterface_begin_n = block.ghost; block.xinterface_end_n = block.ghost + block.nodex; block.xinterface_begin_t = block.ghost; block.xinterface_end_t = block.ghost + block.nodex - 1; block.yinterface_begin_n = block.ghost; block.yinterface_end_n = block.ghost + block.nodey; block.yinterface_begin_t = block.ghost; block.yinterface_end_t = block.ghost + block.nodey - 1; #pragma omp parallel for for (int i = 0; i < block.nx; i++) { for (int j = 0; j < block.ny; j++) { int cindex = i * block.ny + j; int node_index[4]; node_index[0] = i * (block.ny + 1) + j; node_index[1] = (i + 1) * (block.ny + 1) + j; node_index[2] = (i + 1) * (block.ny + 1) + j + 1; node_index[3] = (i) * (block.ny + 1) + j + 1; Set_cell_geo_from_quad_node(fluids[cindex], node2d[node_index[0]], node2d[node_index[1]], node2d[node_index[2]], node2d[node_index[3]]); } } #pragma omp parallel for for (int i = 0; i < block.nx + 1; i++) { for (int j = 0; j < block.ny + 1; j++) { int interface_index = i * (block.ny + 1) + j; int node_index[3]; node_index[0] = i * (block.ny + 1) + j; node_index[1] = (i + 1) * (block.ny + 1) + j; node_index[2] = (i) * (block.ny + 1) + j + 1; if (j < block.ny) { Set_interface_geo_from_two_node (xinterfaces[interface_index], node2d[node_index[0]], node2d[node_index[2]], 0); } if (i < block.nx) { Set_interface_geo_from_two_node (yinterfaces[interface_index], node2d[node_index[0]], node2d[node_index[1]], 1); } Copy_geo_from_interface_to_line(xinterfaces[interface_index]); Copy_geo_from_interface_to_line(yinterfaces[interface_index]); xinterfaces[interface_index].gauss = new Recon2d[gausspoint]; yinterfaces[interface_index].gauss = new Recon2d[gausspoint]; if (j < block.ny) { Set_Gauss_Coordinate_general_mesh_x(xinterfaces[interface_index], node2d[node_index[0]], node2d[node_index[2]]); } if (i < block.nx) { Set_Gauss_Coordinate_general_mesh_y(yinterfaces[interface_index], node2d[node_index[0]], node2d[node_index[1]]); } Copy_geo_from_interface_to_flux (xinterfaces[interface_index], xfluxes[interface_index], block.stages); Copy_geo_from_interface_to_flux (yinterfaces[interface_index], yfluxes[interface_index], block.stages); } } } void Set_cell_geo_from_quad_node (Fluid2d& fluid, double* n1, double* n2, double* n3, double* n4) { //4 //3 ///////////////// // // // // // // // // // // ///////////////// //1 //2 Copy_Array(&fluid.node[0], n1, 2); Copy_Array(&fluid.node[2], n2, 2); Copy_Array(&fluid.node[4], n3, 2); Copy_Array(&fluid.node[6], n4, 2); fluid.coordx = (n1[0] + n2[0] + n4[0] + n3[0]) / 4.0; fluid.coordy = (n1[1] + n2[1] + n4[1] + n3[1]) / 4.0; fluid.area = 0.5 * sqrt((pow((n2[0] - n1[0]), 2) + pow((n2[1] - n1[1]), 2)) * (pow((n4[0] - n1[0]), 2) + pow((n4[1] - n1[1]), 2)) - pow(((n2[0] - n1[0]) * (n4[0] - n1[0]) + (n2[1] - n1[1]) * (n4[1] - n1[1])), 2)) + 0.5 * sqrt((pow((n2[0] - n3[0]), 2) + pow((n2[1] - n3[1]), 2)) * (pow((n4[0] - n3[0]), 2) + pow((n4[1] - n3[1]), 2)) - pow(((n2[0] - n3[0]) * (n4[0] - n3[0]) + (n2[1] - n3[1]) * (n4[1] - n3[1])), 2)); fluid.dx = sqrt(pow((0.5 * (n2[0] + n3[0]) - 0.5 * (n1[0] + n4[0])), 2) + pow((0.5 * (n3[1] - n4[1]) + 0.5 * (n2[1] - n1[1])), 2)); fluid.dy = sqrt(pow((0.5 * (n4[0] + n3[0]) - 0.5 * (n1[0] + n2[0])), 2) + pow((0.5 * (n4[1] + n3[1]) - 0.5 * (n1[1] + n2[1])), 2)); } void Set_interface_geo_from_two_node (Interface2d& interface, double* n1, double* n2, int direction) { interface.x = (n1[0] + n2[0]) / 2.0; interface.y = (n1[1] + n2[1]) / 2.0; interface.length = sqrt(pow((n2[0] - n1[0]), 2) + pow((n2[1] - n1[1]), 2)); if (direction == 0) //we see it as x direction { interface.normal[0] = (n2[1] - n1[1]) / interface.length; interface.normal[1] = -(n2[0] - n1[0]) / interface.length; } else { interface.normal[0] = -(n2[1] - n1[1]) / interface.length; interface.normal[1] = (n2[0] - n1[0]) / interface.length; } } void Set_Gauss_Coordinate_general_mesh_x (Interface2d& xinterface, double* node0, double* nodex1) { double xoff[2]; xoff[0] = nodex1[0] - node0[0]; xoff[1] = nodex1[1] - node0[1]; for (int num_guass = 0; num_guass < gausspoint; num_guass++) { // first is gauss parameter xinterface.gauss[num_guass].x = xinterface.x + gauss_loc[num_guass] * 0.5 * xoff[0]; xinterface.gauss[num_guass].y = xinterface.y + gauss_loc[num_guass] * 0.5 * xoff[1]; xinterface.gauss[num_guass].normal[0] = xinterface.normal[0]; xinterface.gauss[num_guass].normal[1] = xinterface.normal[1]; // each gauss point contain left center right point Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].left, num_guass, xinterface.length); Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].right, num_guass, xinterface.length); Set_Gauss_Intergation_Location_x(xinterface.gauss[num_guass].center, num_guass, xinterface.length); } } void Set_Gauss_Coordinate_general_mesh_y (Interface2d& yinterface, double* node0, double* nodey1) { double yoff[2]; yoff[0] = nodey1[0] - node0[0]; yoff[1] = nodey1[1] - node0[1]; for (int num_guass = 0; num_guass < gausspoint; num_guass++) { yinterface.gauss[num_guass].x = yinterface.x + gauss_loc[num_guass] * 0.5 * yoff[0]; yinterface.gauss[num_guass].y = yinterface.y + gauss_loc[num_guass] * 0.5 * yoff[1]; yinterface.gauss[num_guass].normal[0] = yinterface.normal[0]; yinterface.gauss[num_guass].normal[1] = yinterface.normal[1]; // each gauss point contain left center right point Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].left, num_guass, yinterface.length); Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].right, num_guass, yinterface.length); Set_Gauss_Intergation_Location_y(yinterface.gauss[num_guass].center, num_guass, yinterface.length); } } void Residual2d(Fluid2d* fluids, Block2d block, int outputstep) { if (block.step % outputstep == 0) { int order = block.ghost; double residual[4]; double sum_old[4]; for (int k = 0; k < 4; k++) { residual[k] = 0.0; sum_old[k] = 0.0; } for (int i = order; i < block.nx - order; i++) { for (int j = order; j < block.ny - order; j++) { int index = i * block.ny + j; for (int k = 0; k < 4; k++) { residual[k] = residual[k] + abs(fluids[index].convar[k] - fluids[index].convar_old[k]); sum_old[k] = sum_old[k] + abs(fluids[index].convar_old[k]); } } } for (int k = 0; k < 4; k++) { residual[k] = residual[k] / (sum_old[k] + 1e-15) / block.dt; } cout << "step= " << block.step << " density " << residual[0] << " u " << residual[1] << " v " << residual[2] << " densityE " << residual[3] << endl; ofstream out; if (block.step == outputstep) { out.open("result/residual-2D.plt", ios::out); } else { out.open("result/residual-2D.plt", ios::ate | ios::out | ios::in); } if (!out.is_open()) { cout << "cannot find residual-2D.plt" << endl; cout << "a new case will start" << endl; } if (block.step == outputstep) { out << "# CFL number is " << block.CFL << endl; out << "# tau type (0 refer euler, 1 refer NS) is " << tau_type << endl; out << "# time marching strategy is " << block.stages << " stage method" << endl; out << "variables = step,density_residual,m_residual,n_residual,E_residual" << endl; } //output the data out << block.step << " " << log10(residual[0]) << " " << log10(residual[1]) << " " << log10(residual[2]) << " " << log10(residual[3]) << endl; out.close(); } }