@@ -146,22 +146,33 @@ def assemble_LO(mesh : tools.Discretization, coeff : tools.Grey_coeff):
146146def 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():
200211def 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"\r Step { 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+
269303def 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
282338def 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