def fvm_timestep_RK2(self, dt): f_initial = self.f self.f = self.f + df_dt_fvm(self.f, self, True) * (dt / 2) self._communicate_f() self._apply_bcs_f() if (self.physical_system.params.charge_electron != 0 and self.physical_system.params.fields_solver == 'fdtd'): # Will return a flattened array containing the values of # J1,2,3 in 2D space: self.J1 = self.physical_system.params.charge_electron \ * self.compute_moments('mom_p1_bulk') # (i + 1/2, j + 1/2) self.J2 = self.physical_system.params.charge_electron \ * self.compute_moments('mom_p2_bulk') # (i + 1/2, j + 1/2) self.J3 = self.physical_system.params.charge_electron \ * self.compute_moments('mom_p3_bulk') # (i + 1/2, j + 1/2) # Obtaining the values for current density on the Yee-Grid: self.J1 = 0.5 * (self.J1 + af.shift(self.J1, 0, 0, 1)) # (i + 1/2, j) self.J2 = 0.5 * (self.J2 + af.shift(self.J2, 0, 1, 0)) # (i, j + 1/2) self.J3 = 0.25 * ( self.J3 + af.shift(self.J3, 0, 1, 0) + +af.shift(self.J3, 0, 0, 1) + af.shift(self.J3, 0, 1, 1)) # (i, j) # Here: # cell_centered_EM_fields[:3] is at n # cell_centered_EM_fields[3:] is at n+1/2 # cell_centered_EM_fields_at_n_plus_half[3:] is at n-1/2 self.cell_centered_EM_fields_at_n[:3] = self.cell_centered_EM_fields[: 3] self.cell_centered_EM_fields_at_n[3:] = \ 0.5 * ( self.cell_centered_EM_fields_at_n_plus_half[3:] + self.cell_centered_EM_fields[3:] ) self.cell_centered_EM_fields_at_n_plus_half[ 3:] = self.cell_centered_EM_fields[3:] fdtd(self, dt) fdtd_grid_to_ck_grid(self) # Here # cell_centered_EM_fields[:3] is at n+1 # cell_centered_EM_fields[3:] is at n+3/2 self.cell_centered_EM_fields_at_n_plus_half[:3] = \ 0.5 * ( self.cell_centered_EM_fields_at_n_plus_half[:3] + self.cell_centered_EM_fields[:3] ) self.f = f_initial + df_dt_fvm(self.f, self, False) * dt af.eval(self.f) return
def test_fdtd_mode1(): error_B1 = np.zeros(3) error_B2 = np.zeros(3) error_E3 = np.zeros(3) N = 2**np.arange(5, 8) for i in range(N.size): obj = test(N[i]) N_g = obj.N_ghost B1_fdtd = gauss1D(obj.q2[:, N_g:-N_g, N_g:-N_g], 0.1) B2_fdtd = gauss1D(obj.q1[:, N_g:-N_g, N_g:-N_g], 0.1) obj.yee_grid_EM_fields[3, N_g:-N_g, N_g:-N_g] = B1_fdtd obj.yee_grid_EM_fields[4, N_g:-N_g, N_g:-N_g] = B2_fdtd dt = obj.dq1 / 2 time = np.arange(dt, 1 + dt, dt) E3_initial = obj.yee_grid_EM_fields[2].copy() B1_initial = obj.yee_grid_EM_fields[3].copy() B2_initial = obj.yee_grid_EM_fields[4].copy() obj.J1, obj.J2, obj.J3 = 0, 0, 0 for time_index, t0 in enumerate(time): fdtd(obj, dt) error_B1[i] = af.sum( af.abs(obj.yee_grid_EM_fields[3, N_g:-N_g, N_g:-N_g] - B1_initial[0, N_g:-N_g, N_g:-N_g])) / ( B1_initial.elements()) error_B2[i] = af.sum( af.abs(obj.yee_grid_EM_fields[4, N_g:-N_g, N_g:-N_g] - B2_initial[0, N_g:-N_g, N_g:-N_g])) / ( B2_initial.elements()) error_E3[i] = af.sum( af.abs(obj.yee_grid_EM_fields[2, N_g:-N_g, N_g:-N_g] - E3_initial[0, N_g:-N_g, N_g:-N_g])) / ( E3_initial.elements()) poly_B1 = np.polyfit(np.log10(N), np.log10(error_B1), 1) poly_B2 = np.polyfit(np.log10(N), np.log10(error_B2), 1) poly_E3 = np.polyfit(np.log10(N), np.log10(error_E3), 1) assert (abs(poly_B1[0] + 3) < 0.6) assert (abs(poly_B2[0] + 3) < 0.6) assert (abs(poly_E3[0] + 2) < 0.6)
def test_fdtd_mode2(): error_E1 = np.zeros(3) error_E2 = np.zeros(3) error_B3 = np.zeros(3) N = 2**np.arange(5, 8) for i in range(N.size): obj = test(N[i]) N_g = obj.N_ghost obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] = gauss1D( obj.q2[:, N_g:-N_g, N_g:-N_g], 0.1) obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] = gauss1D( obj.q1[:, N_g:-N_g, N_g:-N_g], 0.1) dt = obj.dq1 / 2 time = np.arange(dt, 1 + dt, dt) B3_initial = obj.yee_grid_EM_fields[5].copy() E1_initial = obj.yee_grid_EM_fields[0].copy() E2_initial = obj.yee_grid_EM_fields[1].copy() obj.J1, obj.J2, obj.J3 = 0, 0, 0 for time_index, t0 in enumerate(time): fdtd(obj, dt) error_E1[i] = af.sum( af.abs(obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] - E1_initial[:, N_g:-N_g, N_g:-N_g])) / ( E1_initial.elements()) error_E2[i] = af.sum( af.abs(obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] - E2_initial[:, N_g:-N_g, N_g:-N_g])) / ( E2_initial.elements()) error_B3[i] = af.sum( af.abs(obj.yee_grid_EM_fields[5, N_g:-N_g, N_g:-N_g] - B3_initial[:, N_g:-N_g, N_g:-N_g])) / ( B3_initial.elements()) poly_E1 = np.polyfit(np.log10(N), np.log10(error_E1), 1) poly_E2 = np.polyfit(np.log10(N), np.log10(error_E2), 1) poly_B3 = np.polyfit(np.log10(N), np.log10(error_B3), 1) assert (abs(poly_E1[0] + 3) < 0.4) assert (abs(poly_E2[0] + 3) < 0.4) assert (abs(poly_B3[0] + 2) < 0.4)
def test_fdtd_modeTE(): error_E1 = np.zeros(3) error_E2 = np.zeros(3) error_B3 = np.zeros(3) N = 2**np.arange(5, 8) for i in range(N.size): obj = test(N[i]) dt = obj.dq1 / 2 time = np.arange(dt, 1 + dt, dt) N_g = obj.N_ghost E1_fdtd = 8 * np.pi * af.cos(4 * np.pi * obj.q2_center_bot) E2_fdtd = 4 * np.pi * af.cos(2 * np.pi * obj.q1_left_center) B3_fdtd = 2 * np.pi * af.cos(2 * np.pi * (obj.q1_left_center - dt)) \ - 4 * np.pi * af.cos(4 * np.pi * (obj.q2_center_bot - dt)) obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] = E1_fdtd[:, N_g:-N_g, N_g:-N_g] obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] = E2_fdtd[:, N_g:-N_g, N_g:-N_g] obj.yee_grid_EM_fields[5, N_g:-N_g, N_g:-N_g] = B3_fdtd[:, N_g:-N_g, N_g:-N_g] B3_initial = obj.yee_grid_EM_fields[5].copy() E1_initial = obj.yee_grid_EM_fields[0].copy() E2_initial = obj.yee_grid_EM_fields[1].copy() obj.J1, obj.J2, obj.J3 = 0, 0, 0 for time_index, t0 in enumerate(time): obj.J1 = 48 * np.pi**2 * af.sin(4 * np.pi * (obj.q2_center_bot - 2 * t0)) obj.J2 = 12 * np.pi**2 * af.sin(2 * np.pi * (obj.q1_left_center - 2 * t0)) fdtd(obj, dt) error_E1[i] = af.sum( af.abs(obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] - E1_initial[:, N_g:-N_g, N_g:-N_g])) / ( E1_initial.elements()) error_E2[i] = af.sum( af.abs(obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] - E2_initial[:, N_g:-N_g, N_g:-N_g])) / ( E2_initial.elements()) error_B3[i] = af.sum( af.abs(obj.yee_grid_EM_fields[5, N_g:-N_g, N_g:-N_g] - B3_initial[:, N_g:-N_g, N_g:-N_g])) / ( B3_initial.elements()) poly_E1 = np.polyfit(np.log10(N), np.log10(error_E1), 1) poly_E2 = np.polyfit(np.log10(N), np.log10(error_E2), 1) poly_B3 = np.polyfit(np.log10(N), np.log10(error_B3), 1) assert (abs(poly_E1[0] + 2) < 0.25) assert (abs(poly_E2[0] + 2) < 0.25) assert (abs(poly_B3[0] + 2) < 0.25)
def test_fdtd_modeTM(): error_B1 = np.zeros(3) error_B2 = np.zeros(3) error_E3 = np.zeros(3) N = 2**np.arange(5, 8) for i in range(N.size): obj = test(N[i]) dt = obj.dq1 / 2 time = np.arange(dt, 1 + dt, dt) N_g = obj.N_ghost A3 = af.sin(2 * np.pi * (obj.q1_left_bot - 0.5 * dt) + 4 * np.pi * (obj.q2_left_bot - 0.5 * dt)) B1_fdtd = (af.shift(A3, 0, 0, -1) - A3) / obj.dq2 B2_fdtd = -(af.shift(A3, 0, -1) - A3) / obj.dq1 E3_fdtd = 6 * np.pi * af.cos(2 * np.pi * obj.q1_left_bot + 4 * np.pi * obj.q2_left_bot) obj.yee_grid_EM_fields[2] = E3_fdtd obj.yee_grid_EM_fields[3] = B1_fdtd obj.yee_grid_EM_fields[4] = B2_fdtd E3_initial = obj.yee_grid_EM_fields[2].copy() B1_initial = obj.yee_grid_EM_fields[3].copy() B2_initial = obj.yee_grid_EM_fields[4].copy() obj.J1, obj.J2, obj.J3 = 0, 0, 0 for time_index, t0 in enumerate(time): obj.J3 = -16 * np.pi**2 * af.sin( 2 * np.pi * (obj.q1_left_bot - t0 + 0.5 * dt) + 4 * np.pi * (obj.q2_left_bot - t0 + 0.5 * dt)) fdtd(obj, dt) error_B1[i] = af.sum( af.abs(obj.yee_grid_EM_fields[3, N_g:-N_g, N_g:-N_g] - B1_initial[0, N_g:-N_g, N_g:-N_g])) / ( B1_initial.elements()) error_B2[i] = af.sum( af.abs(obj.yee_grid_EM_fields[4, N_g:-N_g, N_g:-N_g] - B2_initial[0, N_g:-N_g, N_g:-N_g])) / ( B2_initial.elements()) error_E3[i] = af.sum( af.abs(obj.yee_grid_EM_fields[2, N_g:-N_g, N_g:-N_g] - E3_initial[0, N_g:-N_g, N_g:-N_g])) / ( E3_initial.elements()) poly_B1 = np.polyfit(np.log10(N), np.log10(error_B1), 1) poly_B2 = np.polyfit(np.log10(N), np.log10(error_B2), 1) poly_E3 = np.polyfit(np.log10(N), np.log10(error_E3), 1) assert (abs(poly_B1[0] + 2) < 0.25) assert (abs(poly_B2[0] + 2) < 0.25) assert (abs(poly_E3[0] + 2) < 0.25)
def test_fdtd_mode2(): error_E1 = np.zeros(5) error_E2 = np.zeros(5) error_B3 = np.zeros(5) N = 2**np.arange(5, 10) for i in range(N.size): obj = test(N[i]) dt = obj.dq1 * np.sqrt(9 / 5) / 2 time = np.arange(dt, np.sqrt(9 / 5) + dt, dt) N_g = obj.N_ghost E1_fdtd = 6 * np.pi * np.sqrt( 5 / 9) * af.cos(2 * np.pi * obj.q1_left_bot + 4 * np.pi * obj.q2_left_bot) E2_fdtd = -3 * np.pi * np.sqrt( 5 / 9) * af.cos(2 * np.pi * obj.q1_left_bot + 4 * np.pi * obj.q2_left_bot) B3_fdtd = -5 * np.pi * af.cos( 2 * np.pi * (obj.q1_left_bot - 0.5 * np.sqrt(5 / 9) * dt) + 4 * np.pi * (obj.q2_left_bot - 0.5 * np.sqrt(5 / 9) * dt)) obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] = E1_fdtd[:, N_g:-N_g, N_g:-N_g] obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] = E2_fdtd[:, N_g:-N_g, N_g:-N_g] obj.yee_grid_EM_fields[5, N_g:-N_g, N_g:-N_g] = B3_fdtd[:, N_g:-N_g, N_g:-N_g] B3_initial = obj.yee_grid_EM_fields[5].copy() E1_initial = obj.yee_grid_EM_fields[0].copy() E2_initial = obj.yee_grid_EM_fields[1].copy() obj.J1, obj.J2, obj.J3 = 0, 0, 0 for time_index, t0 in enumerate(time): fdtd(obj, dt) error_E1[i] = af.sum( af.abs(obj.yee_grid_EM_fields[0, N_g:-N_g, N_g:-N_g] - E1_initial[:, N_g:-N_g, N_g:-N_g])) / ( E1_initial.elements()) error_E2[i] = af.sum( af.abs(obj.yee_grid_EM_fields[1, N_g:-N_g, N_g:-N_g] - E2_initial[:, N_g:-N_g, N_g:-N_g])) / ( E2_initial.elements()) error_B3[i] = af.sum( af.abs(obj.yee_grid_EM_fields[5, N_g:-N_g, N_g:-N_g] - B3_initial[:, N_g:-N_g, N_g:-N_g])) / ( B3_initial.elements()) poly_E1 = np.polyfit(np.log10(N), np.log10(error_E1), 1) poly_E2 = np.polyfit(np.log10(N), np.log10(error_E2), 1) poly_B3 = np.polyfit(np.log10(N), np.log10(error_B3), 1) assert (abs(poly_E1[0] + 2) < 0.2) assert (abs(poly_E2[0] + 2) < 0.2) assert (abs(poly_B3[0] + 2) < 0.2)