Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNES Poisson solver [WIP] #37

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e3ada3f
1) Added option to get ksp to read command line arguments. Needed to …
Sep 26, 2017
3a7d353
* Using SNES to solve Poisson equation
Sep 27, 2017
e18df04
Got residual assembly for f(x) = x^2 - 2. over [N_q1, N_q2] working w…
Sep 28, 2017
1a2961e
Poisson solver now works with SNES.
Oct 6, 2017
d84a745
First iteration of 3D poisson solver + 2D charge density. Code in tests/
Oct 9, 2017
cf85dc4
backup commit
Oct 10, 2017
5cbe201
3D poisson solver + 2D density in tests/
Nov 3, 2017
6564b68
Backup commit.
Nov 4, 2017
0cdae72
Merge remote-tracking branch 'origin' into poisson_testing
Nov 4, 2017
156cb55
Backup commit. Self-consistent Poisson-Boltzmann solution now does no…
Nov 28, 2017
48748ea
(1) Changed units: length scale = 1 um, time scale = 1 ps
Dec 4, 2017
f5df972
Merge branch 'master' into poisson_testing
Dec 5, 2017
91e53ad
Deleted file timestepper_source.py that crept in during merge
Dec 5, 2017
35ff5f4
Added graphene example problem
Dec 5, 2017
c8ec414
First working version with FVM
Dec 9, 2017
414feaf
(1) Clean implementation of boundaries
Dec 21, 2017
43d9a73
(1) Cleaned up Poisson solver (somewhat). Works in parallel for nproc…
Dec 21, 2017
cc2f441
Fixed merge mistakes
Dec 21, 2017
8b89d7c
Added job script for aimp.mat.rpi.edu
Dec 22, 2017
8341f68
(1) Fixed bug in parallel SNES solver due to wrong shape of q1_2D, q2_2D
Dec 22, 2017
412212a
Added EM fields output
Dec 24, 2017
9a725c7
1) Added eqbm solver
Jan 19, 2018
f1fc67a
ee operator modified to work with current data layout
Feb 5, 2018
be12f7f
(1) Added dump routines for Lagrange multipliers.
Feb 6, 2018
4eacc7d
Refined post-processing script
Feb 7, 2018
086f7b3
Fixed bug in RTA
Feb 10, 2018
0425535
Added AC source. Refined post-processing script.
Feb 11, 2018
c6e0c7a
Changed Lorentz force to use band velocities.
May 7, 2018
4664bac
Commented out selection of inflow chars at the boundaries; not needed.
May 7, 2018
ed9cf57
Code backup; Need to clean up post.py
May 7, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
405 changes: 405 additions & 0 deletions bolt/lib/nonlinear_solver/EM_fields_solver/electrostatic.py

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions bolt/lib/nonlinear_solver/EM_fields_solver/fields_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import arrayfire as af

from .electrostatic import fft_poisson
from .electrostatic import fft_poisson, compute_electrostatic_fields
from .fdtd_explicit import fdtd, fdtd_grid_to_ck_grid
from .. import interpolation_routines

Expand All @@ -12,12 +12,17 @@ def fields_step(self, dt):
if(self.performance_test_flag == True):
tic = af.time()

if (self.physical_system.params.fields_solver == 'fft'):
fft_poisson(self)
if (self.physical_system.params.fields_type == 'electrostatic'):
if (self.physical_system.params.fields_solver == 'fft'):
fft_poisson(self)
elif (self.physical_system.params.fields_solver == 'SNES'):
#compute_electrostatic_fields(self)
pass

self._communicate_fields()
self._apply_bcs_fields()

elif (self.physical_system.params.fields_solver == 'fdtd'):
elif (self.physical_system.params.fields_type == 'electrodynamic'):
# Will return a flattened array containing the values of
# J1,2,3 in 2D space:
self.J1 = self.physical_system.params.charge_electron \
Expand Down
135 changes: 83 additions & 52 deletions bolt/lib/nonlinear_solver/FVM_solver/df_dt_fvm.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import arrayfire as af

from bolt.lib.nonlinear_solver.EM_fields_solver.electrostatic import fft_poisson
from bolt.lib.nonlinear_solver.EM_fields_solver.electrostatic import compute_electrostatic_fields
# Importing Riemann solver used in calculating fluxes:
from .riemann_solver import riemann_solver
from .riemann_solver import riemann_solver, upwind_flux
from .reconstruct import reconstruct
import params

# Equation to solve:
# df/dt + d(C_q1 * f)/dq1 + d(C_q2 * f)/dq2 = C[f]
Expand Down Expand Up @@ -75,11 +77,25 @@ def df_dt_fvm(f, self, at_n = True):
if( self.physical_system.params.solver_method_in_p == 'FVM'
and self.physical_system.params.charge_electron != 0
):
if(self.physical_system.params.fields_solver == 'fft'):
if(self.physical_system.params.fields_type == 'electrostatic'):

fft_poisson(self, f)
self._communicate_fields()
self._apply_bcs_fields()
if (params.time_step%params.electrostatic_solver_every_nth_step==0):

if(self.physical_system.params.fields_solver == 'fft'):

fft_poisson(self, f)

elif(self.physical_system.params.fields_solver == 'SNES'):
compute_electrostatic_fields(self)
pass

E1 = self.cell_centered_EM_fields[0]
E2 = self.cell_centered_EM_fields[1]
E3 = self.cell_centered_EM_fields[2]

B1 = self.cell_centered_EM_fields[3]
B2 = self.cell_centered_EM_fields[4]
B3 = self.cell_centered_EM_fields[5]

# This is taken care of by the timestepper that is utilized
# when FDTD is to be used with FVM in p-space
Expand All @@ -91,39 +107,39 @@ def df_dt_fvm(f, self, at_n = True):
invalid/not-implemented'
)

if( self.physical_system.params.fields_solver == 'fdtd'
and at_n == True
):

E1 = self.cell_centered_EM_fields_at_n[0]
E2 = self.cell_centered_EM_fields_at_n[1]
E3 = self.cell_centered_EM_fields_at_n[2]

B1 = self.cell_centered_EM_fields_at_n[3]
B2 = self.cell_centered_EM_fields_at_n[4]
B3 = self.cell_centered_EM_fields_at_n[5]

elif( self.physical_system.params.fields_solver == 'fdtd'
and at_n != False
):

E1 = self.cell_centered_EM_fields_at_n_plus_half[0]
E2 = self.cell_centered_EM_fields_at_n_plus_half[1]
E3 = self.cell_centered_EM_fields_at_n_plus_half[2]

B1 = self.cell_centered_EM_fields_at_n_plus_half[3]
B2 = self.cell_centered_EM_fields_at_n_plus_half[4]
B3 = self.cell_centered_EM_fields_at_n_plus_half[5]

else:

E1 = self.cell_centered_EM_fields[0]
E2 = self.cell_centered_EM_fields[1]
E3 = self.cell_centered_EM_fields[2]

B1 = self.cell_centered_EM_fields[3]
B2 = self.cell_centered_EM_fields[4]
B3 = self.cell_centered_EM_fields[5]
# if( self.physical_system.params.fields_solver == 'fdtd'
# and at_n == True
# ):
#
# E1 = self.cell_centered_EM_fields_at_n[0]
# E2 = self.cell_centered_EM_fields_at_n[1]
# E3 = self.cell_centered_EM_fields_at_n[2]
#
# B1 = self.cell_centered_EM_fields_at_n[3]
# B2 = self.cell_centered_EM_fields_at_n[4]
# B3 = self.cell_centered_EM_fields_at_n[5]
#
# elif( self.physical_system.params.fields_solver == 'fdtd'
# and at_n != False
# ):
#
# E1 = self.cell_centered_EM_fields_at_n_plus_half[0]
# E2 = self.cell_centered_EM_fields_at_n_plus_half[1]
# E3 = self.cell_centered_EM_fields_at_n_plus_half[2]
#
# B1 = self.cell_centered_EM_fields_at_n_plus_half[3]
# B2 = self.cell_centered_EM_fields_at_n_plus_half[4]
# B3 = self.cell_centered_EM_fields_at_n_plus_half[5]
#
# else:
#
# E1 = self.cell_centered_EM_fields[0]
# E2 = self.cell_centered_EM_fields[1]
# E3 = self.cell_centered_EM_fields[2]
#
# B1 = self.cell_centered_EM_fields[3]
# B2 = self.cell_centered_EM_fields[4]
# B3 = self.cell_centered_EM_fields[5]

(A_p1, A_p2, A_p3) = af.broadcast(self._A_p, self.q1_center, self.q2_center,
self.p1, self.p2, self.p3,
Expand All @@ -133,40 +149,55 @@ def df_dt_fvm(f, self, at_n = True):

# Variation of p1 is along axis 0:
left_plus_eps_flux_p1, right_minus_eps_flux_p1 = \
reconstruct(self, self._convert_to_p_expanded(af.broadcast(multiply, A_p1, f)), 0, method_in_p)
reconstruct(self,
self._convert_to_p_expanded(af.broadcast(multiply, A_p1, f)),
0, method_in_p
)
# Variation of p2 is along axis 1:
bot_plus_eps_flux_p2, top_minus_eps_flux_p2 = \
reconstruct(self, self._convert_to_p_expanded(af.broadcast(multiply, A_p2, f)), 1, method_in_p)
# Variation of p3 is along axis 2:
back_plus_eps_flux_p3, front_minus_eps_flux_p3 = \
reconstruct(self, self._convert_to_p_expanded(af.broadcast(multiply, A_p3, f)), 2, method_in_p)
reconstruct(self,
self._convert_to_p_expanded(af.broadcast(multiply, A_p2, f)),
1, method_in_p
)
# # Variation of p3 is along axis 2:
# back_plus_eps_flux_p3, front_minus_eps_flux_p3 = \
# reconstruct(self, self._convert_to_p_expanded(af.broadcast(multiply, A_p3, f)), 2, method_in_p)

left_minus_eps_flux_p1 = af.shift(right_minus_eps_flux_p1, 1)
bot_minus_eps_flux_p2 = af.shift(top_minus_eps_flux_p2, 0, 1)
back_minus_eps_flux_p3 = af.shift(front_minus_eps_flux_p3, 0, 0, 1)
# back_minus_eps_flux_p3 = af.shift(front_minus_eps_flux_p3, 0, 0, 1)

# Obtaining the fluxes by face-averaging:
left_flux_p1 = 0.5 * (left_minus_eps_flux_p1 + left_plus_eps_flux_p1)
bot_flux_p2 = 0.5 * (bot_minus_eps_flux_p2 + bot_plus_eps_flux_p2)
back_flux_p3 = 0.5 * (back_minus_eps_flux_p3 + back_plus_eps_flux_p3)
# left_flux_p1 = 0.5 * (left_minus_eps_flux_p1 + left_plus_eps_flux_p1)
# bot_flux_p2 = 0.5 * (bot_minus_eps_flux_p2 + bot_plus_eps_flux_p2)
# back_flux_p3 = 0.5 * (back_minus_eps_flux_p3 + back_plus_eps_flux_p3)

left_flux_p1 = upwind_flux(left_minus_eps_flux_p1, \
left_plus_eps_flux_p1, \
self._convert_to_p_expanded(A_p1)
)

bot_flux_p2 = upwind_flux(bot_minus_eps_flux_p2, \
bot_plus_eps_flux_p2, \
self._convert_to_p_expanded(A_p2)
)

right_flux_p1 = af.shift(left_flux_p1, -1)
top_flux_p2 = af.shift(bot_flux_p2, 0, -1)
front_flux_p3 = af.shift(back_flux_p3, 0, 0, -1)
# front_flux_p3 = af.shift(back_flux_p3, 0, 0, -1)

left_flux_p1 = self._convert_to_q_expanded(left_flux_p1)
right_flux_p1 = self._convert_to_q_expanded(right_flux_p1)

bot_flux_p2 = self._convert_to_q_expanded(bot_flux_p2)
top_flux_p2 = self._convert_to_q_expanded(top_flux_p2)

back_flux_p3 = self._convert_to_q_expanded(back_flux_p3)
front_flux_p3 = self._convert_to_q_expanded(front_flux_p3)
# back_flux_p3 = self._convert_to_q_expanded(back_flux_p3)
# front_flux_p3 = self._convert_to_q_expanded(front_flux_p3)

df_dt += - (right_flux_p1 - left_flux_p1)/self.dp1 \
- (top_flux_p2 - bot_flux_p2 )/self.dp2 \
- (front_flux_p3 - back_flux_p3)/self.dp3

#- (front_flux_p3 - back_flux_p3)/self.dp3

af.eval(df_dt)
return(df_dt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,6 @@ def reconstruct_weno5(input_array, axis):
# Reconstruction:
left_value = (w1l * u1l + w2l * u2l + w3l * u3l) / denl;
right_value = (w1r * u1r + w2r * u2r + w3r * u3r) / denr;


af.eval(left_value, right_value)
return(left_value, right_value)
97 changes: 50 additions & 47 deletions bolt/lib/nonlinear_solver/FVM_solver/timestep_df_dt.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,59 +11,62 @@

def fvm_timestep_RK2(self, dt):

self._communicate_f()
self._apply_bcs_f()

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]
)
# 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

Expand Down
Loading