Skip to content

Commit f90f661

Browse files
authored
Merge pull request #1 from hankyleh/nonlinear_dbdt
Nonlinear dbdt
2 parents 89c63a1 + a9daf45 commit f90f661

37 files changed

Lines changed: 488 additions & 367 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ tpls/
1313
*.xdv
1414
*.out
1515
*.snm
16+
_minted/
1617

1718
__pycache__/
1819
venv/

method.py

Lines changed: 186 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -146,22 +146,33 @@ def assemble_LO(mesh : tools.Discretization, coeff : tools.Grey_coeff):
146146
def unaccelerated_loop(mesh : tools.Discretization,
147147
sol_prev : tools.Transport_solution,
148148
coeff : tools.MG_coefficients,
149-
flags : dict):
149+
flags : dict,
150+
guess = None):
150151

151-
last_iteration = copy.deepcopy(sol_prev)
152+
if guess is None:
153+
last_iteration = copy.deepcopy(sol_prev)
154+
else:
155+
last_iteration = guess
152156
updated_solution = copy.deepcopy(sol_prev)
153157

154158
change = [1]
155159

160+
if flags["coarse"] is True:
161+
gmtol = mesh.eps
162+
tol = mesh.eps_c
163+
else:
164+
gmtol = mesh.eps_f
165+
tol = mesh.eps
166+
156167
iter = 0
157-
while (numpy.max(change) > mesh.eps) :
168+
while (numpy.max(change) > tol) :
158169
iter += 1
159170
for k in range(0, mesh.ng):
160171
sys = assemble_HO(mesh, coeff, last_iteration.intensity, k)
161172
if flags["mat_method"] == "lu":
162173
updated_solution.vec[k, :] = sparse.linalg.spsolve(sys.mat, sys.src)
163174
elif flags["mat_method"] == "gmres":
164-
updated_solution.vec[k, :], b = sparse.linalg.gmres(sys.mat, sys.src, x0=last_iteration.vec[k], rtol = 0.01*mesh.eps)
175+
updated_solution.vec[k, :], b = sparse.linalg.gmres(sys.mat, sys.src, x0=last_iteration.vec[k], rtol = gmtol)
165176
elif flags["mat_method"] == "inv":
166177
updated_solution.vec[k, :] = numpy.matmul(scipy.linalg.inv(sys.mat.todense()), sys.src)
167178
else:
@@ -200,41 +211,50 @@ def print_update():
200211
def accelerated_loop(mesh : tools.Discretization,
201212
sol_prev : tools.Transport_solution,
202213
coeff : tools.MG_coefficients,
203-
flags : dict):
214+
flags : dict,
215+
guess = None):
204216

205217
I_prev = sol_prev.intensity[:]
206-
last_iteration = copy.deepcopy(sol_prev)
218+
if guess is None:
219+
last_iteration = copy.deepcopy(sol_prev)
220+
else:
221+
last_iteration = guess
207222
updated_solution = copy.deepcopy(sol_prev)
208223
error_soln = copy.deepcopy(sol_prev)
209224

210225
grey_constants = tools.Grey_coeff(mesh)
211226

212227
change = [1]
213228

229+
if flags["coarse"] is True:
230+
gmtol = mesh.eps
231+
tol = mesh.eps_c
232+
else:
233+
gmtol = mesh.eps_f
234+
tol = mesh.eps
235+
214236
iter = 0
215-
while (numpy.max(change) > mesh.eps) :
237+
while (numpy.max(change) > tol):
216238
iter += 1
217239

218240
for k in range(0, mesh.ng):
219241
sys = assemble_HO(mesh, coeff, last_iteration.intensity, k)
220242
if flags["mat_method"] == "lu":
221243
updated_solution.vec[k, :] = sparse.linalg.spsolve(sys.mat, sys.src)
222244
elif flags["mat_method"] == "gmres":
223-
updated_solution.vec[k, :], b = sparse.linalg.gmres(sys.mat, sys.src, x0=last_iteration.vec[k], rtol = 0.01*mesh.eps)
245+
updated_solution.vec[k, :], b = sparse.linalg.gmres(sys.mat, sys.src, x0=last_iteration.vec[k], rtol = gmtol)
224246
elif flags["mat_method"] == "inv":
225247
updated_solution.vec[k, :] = numpy.matmul(scipy.linalg.inv(sys.mat.todense()), sys.src)
226248
else:
227249
raise ValueError("Invalid solution method provided")
228250

229251
grey_constants.assign(mesh, coeff, updated_solution, last_iteration)
230-
231-
232252
sys_grey = assemble_LO(mesh, grey_constants)
233253

234254
if flags["mat_method"] == "lu":
235255
error_soln.vec[:] = sparse.linalg.spsolve(sys_grey.mat, sys_grey.src)
236256
elif flags["mat_method"] == "gmres":
237-
error_soln.vec[:], b = sparse.linalg.gmres(sys_grey.mat, sys_grey.src, x0=last_iteration.vec[k], rtol = 0.01*mesh.eps)
257+
error_soln.vec[:], b = sparse.linalg.gmres(sys_grey.mat, sys_grey.src, x0=last_iteration.vec[k], rtol = gmtol)
238258
elif flags["mat_method"] == "inv":
239259
error_soln.vec[:] = numpy.matmul(scipy.linalg.inv(sys_grey.mat.todense()), sys_grey.src)
240260
else:
@@ -251,13 +271,13 @@ def accelerated_loop(mesh : tools.Discretization,
251271
last_iteration = copy.deepcopy(updated_solution)
252272

253273
def print_update():
254-
print(f"Step {flags["time_frac"]:<8}"+
274+
print(f"\rStep {flags["time_frac"]:<8}"+
255275
f"Iteration {iter:<6}"+
256276
f"Max. rel. change {numpy.max(change):.4e} "+
257277
f"{"MANUALLY ASSIGNED OPACITY" * (flags["manual_kappa"] is not False)}"+
258278
f"'{flags["mat_method"]}' LD solution method "+
259-
f"{"Using Accelerated Algorithm"*(flags["accelerated"] is not False)}",
260-
end="\r", flush=True)
279+
f"{"Using Accelerated Algorithm"*(flags["accelerated"] is not False)}",
280+
end = "", flush=True)
261281

262282
if iter % flags["printing_interval"] == 0:
263283
print_update()
@@ -266,6 +286,20 @@ def print_update():
266286
return updated_solution.vec, iter
267287

268288

289+
def loop(mesh : tools.Discretization,
290+
sol_prev : tools.Transport_solution,
291+
coeff : tools.MG_coefficients,
292+
flags : dict,
293+
guess = None):
294+
295+
if flags["accelerated"] == True:
296+
transport_sol, inners = accelerated_loop(mesh, sol_prev, coeff, flags, guess)
297+
else:
298+
transport_sol, inners = unaccelerated_loop(mesh, sol_prev, coeff, flags, guess)
299+
300+
return transport_sol, inners
301+
302+
269303
def update_temperature(mesh : tools.Discretization,
270304
coeff : tools.MG_coefficients,
271305
soln : tools.Transport_solution,
@@ -277,6 +311,28 @@ def update_temperature(mesh : tools.Discretization,
277311
)/(
278312
(Cv/mesh.dt) + numpy.sum(coeff.kappa * coeff.db_dt, axis=0)
279313
)
314+
315+
# if (sum(math.isnan(temp_change[j]) for j in range(0, mesh.nx)) > 0):
316+
# print(temp_change[:])
317+
# print("temp change")
318+
# print(coeff.kappa[:, 0:3])
319+
# print("kappa sample")
320+
# # print(soln.cell_center_i[0:6, 0:6])
321+
# # print("cell center i sample")
322+
# # print(coeff.beta[0:6, 0:6])
323+
# # print("beta sample")
324+
# print((Cv/mesh.dt) + numpy.sum(coeff.kappa * coeff.db_dt, axis=0))
325+
# print("denominator")
326+
# print( numpy.sum(coeff.kappa * (soln.cell_center_i - coeff.beta), axis=0) + Q)
327+
# print("numerator")
328+
# print(numpy.sum(coeff.kappa * coeff.db_dt, axis=0))
329+
# print("sum term")
330+
# print(coeff.db_dt[:, 0:3])
331+
# print("dbdt")
332+
333+
# raise ValueError("NaN dT encountered")
334+
335+
280336
return temp_change
281337

282338
def solve_diffusion(mesh : tools.Discretization,
@@ -294,7 +350,9 @@ def solve_diffusion(mesh : tools.Discretization,
294350
mat_method = "lu",
295351
printing_interval = 5,
296352
print_coeff = False,
297-
print_iter_change = False):
353+
print_iter_change = False,
354+
coarse = False,
355+
Newton = True):
298356
print("Beginning unaccelerated iteration")
299357

300358
flags = {
@@ -306,7 +364,8 @@ def solve_diffusion(mesh : tools.Discretization,
306364
"mat_method" : mat_method,
307365
"printing_interval" : printing_interval,
308366
"print_coeff" : print_coeff,
309-
"print_iter_change" : print_iter_change
367+
"print_iter_change" : print_iter_change,
368+
"coarse" : coarse
310369
}
311370

312371
dt = mesh.dt
@@ -321,31 +380,31 @@ def solve_diffusion(mesh : tools.Discretization,
321380
transport_iters = copy.deepcopy(IC)
322381
sol_prev = copy.deepcopy(IC)
323382

324-
T_iter = copy.deepcopy(T_init)
383+
T_n = copy.deepcopy(T_init)
325384

326385
kappa = numpy.zeros((mesh.ng, mesh.nx))
327-
change = numpy.zeros(mesh.nx)
386+
dT = numpy.zeros(mesh.nx)
387+
beta = copy.deepcopy(dT)
328388

329-
330-
print("unaccelerated method")
331389
for stop in range(0, (first_step_only == False)*len(nt)
332390
+ (first_step_only == True)):
333391

334392
print(f"Starting steps towards {mesh.t_stops[stop]}")
335393

336394
for step in range(0, nt[stop]):
395+
inners = 0
337396
flags["time_frac"] = f"{(step + numpy.sum(mesh.nt[0:stop])) + 1}/{numpy.sum(mesh.nt)}"
338397

339398
if manual_kappa is False:
340-
kappa[:] = opacity(mesh, T_iter, k_star)
399+
kappa[:] = opacity(mesh, T_n, k_star)
341400
else:
342401
kappa[:] = manual_kappa
343402
if print_kappa is True:
344403
print(kappa[:, 0])
345404
print("Group opacity in first cell")
346405

347406
coeff = tools.MG_coefficients(mesh)
348-
coeff.assign(mesh, kappa, sol_prev, T_iter, Cv, Q)
407+
coeff.assign(mesh, kappa, sol_prev, T_n, Cv, Q)
349408

350409
if print_coeff is True:
351410
print()
@@ -361,40 +420,123 @@ def solve_diffusion(mesh : tools.Discretization,
361420
print(coeff.sig_f[:, -1])
362421
print("sig_f, first cell; last cell")
363422

364-
if accelerated == True:
365-
transport_iters.vec[:,:], inners = accelerated_loop(mesh, sol_prev, coeff, flags)
366-
else:
367-
transport_iters.vec[:,:], inners = unaccelerated_loop(mesh, sol_prev, coeff, flags)
423+
424+
def check_nan(mesh : tools.Discretization, soln : tools.Transport_solution, prev = None):
425+
if (sum(math.isnan(soln.intensity[i, j]) for i in range (0, mesh.ng) for j in range(0, 2*mesh.nx)) > 0):
426+
print(soln.intensity)
427+
print("Cell-edge flux")
428+
print(soln.vec[0:6, 0:6])
429+
print("Sample of transport solution")
430+
print(soln.cell_center_i)
431+
print("Cell-centered flux")
432+
print(kappa[:, 0:6])
433+
print("opacity sample")
434+
print(T_n[:])
435+
print("Temperature")
436+
print(dT[:])
437+
print("most recent temperature change")
438+
439+
plt.figure()
440+
ax = plt.gca()
441+
lines = tools.LD_plottable(mesh, (1/mesh.C)*physics.ev_to_erg*soln.vec)
442+
tools.plot_LD_groups(ax, mesh, lines.intensity, range(0, mesh.ng))
443+
plt.title(f"Energy density")
444+
plt.xlabel("x [cm]")
445+
plt.autoscale()
446+
447+
448+
plt.figure()
449+
plt.plot(mesh.cell_centers, mesh.K*T_n)
450+
plt.xlabel("x [cm]")
451+
plt.ylabel("T [eV]")
452+
plt.title("Temperature")
453+
454+
if prev is not None:
455+
print(prev.vec[0:6, 0:6])
456+
print("previous solution sample")
457+
print()
458+
plt.figure()
459+
ax = plt.gca()
460+
lines = tools.LD_plottable(mesh, (1/mesh.C)*physics.ev_to_erg*prev.vec)
461+
tools.plot_LD_groups(ax, mesh, lines.intensity, range(0, mesh.ng))
462+
plt.title(f"Previous iteration Energy density")
463+
plt.xlabel("x [cm]")
464+
plt.autoscale()
465+
466+
plt.show()
467+
raise ValueError("NaN intensity encountered")
468+
return 0
469+
470+
if Newton is True:
471+
alpha = 0.05
472+
dbdt = coeff.db_dt
473+
slope = numpy.zeros((mesh.ng, mesh.nx))
474+
475+
slope_change = 1
476+
slope_iters = 0
477+
# iterate until slope is good
478+
479+
# check dT first
480+
transport_iters.vec[:,:], new_inners = loop(mesh, sol_prev, coeff, flags, guess = transport_iters)
481+
inners += new_inners
482+
dT[:] = update_temperature(mesh, coeff, transport_iters, Cv)
483+
if numpy.linalg.norm(dT/T_n, 2) > alpha:
484+
while (slope_change > mesh.eps_c):
485+
slope_iters += 1
486+
flags["coarse"] = True
487+
temporary_transport = copy.deepcopy(transport_iters)
488+
transport_iters.vec[:,:], new_inners = loop(mesh, sol_prev, coeff,
489+
flags, guess = transport_iters)
490+
check_nan(mesh, transport_iters, prev=temporary_transport)
491+
inners += new_inners
492+
dT[:] = update_temperature(mesh, coeff, transport_iters, Cv)
493+
dBeta = physics.group_planck(mesh, (T_n + dT)) - coeff.beta
494+
slope = dBeta / dT
495+
change_vec = numpy.sum(numpy.abs( (slope / coeff.db_dt)-1 ),axis=0)
496+
change_vec = numpy.nan_to_num(change_vec)
497+
slope_change = numpy.max(change_vec)
498+
if slope_iters > 40:
499+
# TODO : temporary fix for no convergence.
500+
# FIND OUT WHY THIS IS OCCURING
501+
print("No Newton convergence")
502+
coeff.db_dt[:, :] = dbdt
503+
break
504+
505+
print()
506+
print(slope_change)
507+
print("slope change")
508+
coeff.db_dt[:, :] = slope
509+
else:
510+
pass
511+
# dT was small; use dB/dT|_n
512+
# finish iterations using new slope
513+
flags["coarse"] = coarse
514+
515+
516+
# calculate flux and intensity, record iterations
517+
temporary_transport = copy.deepcopy(transport_iters)
518+
transport_iters.vec[:,:], new_inners = loop(mesh, sol_prev, coeff,
519+
flags, guess = transport_iters)
520+
check_nan(mesh, transport_iters, prev = temporary_transport)
521+
inners += new_inners
368522
sol_prev.vec[:] = transport_iters.vec[:].copy()
369523

370-
if (sum(math.isnan(transport_iters.cell_center_i[i, j]) for i in range (0, mesh.ng) for j in range(0, mesh.nx)) > 0):
371-
print(transport_iters.intensity)
372-
print("Cell-edge flux")
373-
print(transport_iters.vec[0:6, 0:6])
374-
print("Sample of transport solution")
375-
print(transport_iters.cell_center_i)
376-
print("Cell-centered flux")
377-
print(kappa[:, 0:6])
378-
print("opacity sample")
379-
raise ValueError("NaN intensity encountered")
524+
380525

381526
if accelerated == True:
382527
iters_log[:,step + numpy.sum(mesh.nt[0:stop])] = inners * numpy.array([1, mesh.ng + 1]).transpose()
383528
else:
384529
iters_log[:,step + numpy.sum(mesh.nt[0:stop])] = inners * numpy.array([1, mesh.ng]).transpose()
385530

386-
# print("")
387-
# print(iters_log)
388531

389-
change[:] = update_temperature(mesh, coeff, transport_iters, Cv)
532+
dT[:] = update_temperature(mesh, coeff, transport_iters, Cv)
390533
if print_T_change == True:
391-
print(change)
534+
print(dT)
392535
print("Temperature delta")
393-
T_iter += copy.deepcopy(change[:])
394-
coeff.assign(mesh, kappa, transport_iters, T_iter, Cv, Q)
536+
T_n += copy.deepcopy(dT[:])
537+
coeff.assign(mesh, kappa, transport_iters, T_n, Cv, Q)
395538
print("")
396539
transport_output.append(copy.deepcopy(transport_iters))
397-
temp_output.append(copy.deepcopy(T_iter[:]))
540+
temp_output.append(copy.deepcopy(T_n[:]))
398541

399542
return temp_output, transport_output, iters_log
400-

0 commit comments

Comments
 (0)