def test_sets3(self): xs1 = CrossSection() xs1.set([[1.0, 2.0, 3.0, 1.0], [11.0, 12.0, 13.0, 0.0]]) xs1.set_smat([[1.0, 2.0], [3.0, 4.0]]) xs1_ref = CrossSection() xs1_ref.set(xs1) self.assertEqual(xs1, xs1_ref)
def test_operation_mul(self): xs1 = CrossSection() xs1.set([[1.0, 2.0, 3.0, 1.0], [11.0, 12.0, 13.0, 0.0]]) xs1.set_smat([[1.0, 2.0], [3.0, 4.0]]) xs2 = xs1 * 2.0 xs2_ref = CrossSection() xs2_ref.set([[2.0, 4.0, 6.0, 2.0], [22.0, 24.0, 26.0, 0.0]]) xs2_ref.set_smat([[2.0, 4.0], [6.0, 8.0]]) self.assertEqual(xs2, xs2_ref) xs3 = 2.0 * xs1 xs3_ref = xs2_ref self.assertEqual(xs3, xs3_ref) xs4 = 2.0 * xs1 * 3.0 xs4_ref = CrossSection() xs4_ref.set([[6.0, 12.0, 18.0, 6.0], [66.0, 72.0, 78.0, 0.0]]) xs4_ref.set_smat([[6.0, 12.0], [18.0, 24.0]]) xs4.debug() xs4_ref.debug() self.assertEqual(xs4, xs4_ref)
def test_operation_mul(self): xs1 = CrossSection([1.0, 2.0, 3.0]) xs2 = xs1 * 2.0 xs2_ref = CrossSection([2.0, 4.0, 6.0]) self.assertEqual(xs2, xs2_ref) xs3 = 2.0 * xs1 xs3_ref = CrossSection([2.0, 4.0, 6.0]) self.assertEqual(xs3, xs3_ref) xs4 = 2.0 * xs1 * 3.0 xs4_ref = CrossSection([6.0, 12.0, 18.0]) self.assertEqual(xs4, xs4_ref)
def test_calculation_manager(self): xs = CrossSection() xs.set([[1.58, 0.02, 0.0, 1.0], [0.271, 0.0930, 0.168, 0.0]]) xs.set_smat([[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() delta = 1.0 albedo = -1.0 geom = [{'xs': xs, 'width': 100}] config = {'geometry': geom, 'mesh_width': delta, "albedo": albedo} calc_man = CalculationManager(config) count, flag = calc_man.run() keff = calc_man.get_keff() b2 = (math.pi / geom[0]['width'])**2 kana_nume = (xs.sigr(1) + xs.dif(1) * b2) * xs.nusigf(0) + xs.sigs( 0, 1) * xs.nusigf(1) kana_deno = (xs.dif(0) * b2 + xs.sigr(0)) * (xs.dif(1) * b2 + xs.sigr(1)) kana = kana_nume / kana_deno print("kana=", kana) self.assertAlmostEqual(keff, kana, places=4)
def test_container_controller(self): xs = CrossSection() xs.set([[1.58, 0.02, 0.0, 1.0], [0.271, 0.0930, 0.168, 0.0]]) xs.set_smat([[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() delta = 1.0 albedo = -1.0 geom = [{'xs': xs, 'width': 100}] container = Container(geom, delta, albedo) #cont.debug() controller = ContainerController(container) count, flag = controller.calc() print("outer iterations: ", count) keff = controller.get_keff() b2 = (math.pi / geom[0]['width'])**2 kana_nume = (xs.sigr(1) + xs.dif(1) * b2) * xs.nusigf(0) + xs.sigs( 0, 1) * xs.nusigf(1) kana_deno = (xs.dif(0) * b2 + xs.sigr(0)) * (xs.dif(1) * b2 + xs.sigr(1)) kana = kana_nume / kana_deno print("kana=", kana) self.assertAlmostEqual(keff, kana, places=4)
def test_sets(self): xs = CrossSection() xs.set_d(0, 1.0) xs.set_siga(0, 2.0) xs.set_nusigf(0, 3.0) xs.set_xi(0, 1.0) xs.set_d(1, 11.0) xs.set_siga(1, 12.0) xs.set_nusigf(1, 13.0) xs.set_xi(1, 0.0) xs.set_smat([[1.0, 2.0], [3.0, 4.0]]) # sm(kg, kkg) # # kkg # 0 1 # kg 0 1.0 2.0 # 1 3.0 4.0 self.assertEqual(xs.dif(0), 1.0) self.assertEqual(xs.siga(0), 2.0) self.assertEqual(xs.nusigf(0), 3.0) self.assertEqual(xs.xi(0), 1.0) self.assertEqual(xs.dif(1), 11.0) self.assertEqual(xs.siga(1), 12.0) self.assertEqual(xs.nusigf(1), 13.0) self.assertEqual(xs.xi(1), 0.0) self.assertEqual(xs.sigs(0, 0), 1.0) self.assertEqual(xs.sigs(0, 1), 2.0) self.assertEqual(xs.sigs(1, 0), 3.0) self.assertEqual(xs.sigs(1, 1), 4.0)
def test_operation_sub(self): xs1 = CrossSection() xs1.set([[1.0, 2.0, 3.0, 1.0], [11.0, 12.0, 13.0, 0.0]]) xs1.set_smat([[1.0, 2.0], [3.0, 4.0]]) xs2 = CrossSection() xs2.set([[2.0, 4.0, 6.0, 2.0], [22.0, 24.0, 26.0, 0.0]]) xs2.set_smat([[2.0, 4.0], [6.0, 8.0]]) xs3 = xs2 - xs1 xs3_ref = CrossSection() xs3_ref.set([[1.0, 2.0, 3.0, 1.0], [11.0, 12.0, 13.0, 0.0]]) xs3_ref.set_smat([[1.0, 2.0], [3.0, 4.0]]) self.assertEqual(xs3, xs3_ref)
def test_sets(self): xs = CrossSection() xs.set_d(1.0) xs.set_siga(2.0) xs.set_nusigf(3.0) self.assertEqual(xs.dif(), 1.0) self.assertEqual(xs.siga(), 2.0) self.assertEqual(xs.nusigf(), 3.0)
def test_container(self): xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) delta = 1.0 albedo = -1.0 geom = [{'xs':xs_fuel, 'width':100}] cont = Container(geom, delta, albedo) #cont.debug() keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-7 for idx_outer in range(100): total_fis_src = cont.get_total_fis_src() norm_factor = 1.0 / (total_fis_src/keff) cont.normalize_fis_src(norm_factor) for idx_inner in range(4): for color in range(2): cont.calc(color) cont.calc_fis_src() total_fis_src = cont.get_total_fis_src() keff = total_fis_src / (total_fis_src_old/keff_old) diff = abs((keff - keff_old)/keff) #print( keff, diff) if(diff < conv): break keff_old = keff total_fis_src_old = total_fis_src cont.set_keff(keff) kana = xs_fuel.nusigf() / (xs_fuel.dif() * math.pi ** 2 / 100**2 + xs_fuel.siga()) #print( 'kana = ', kana) self.assertAlmostEqual(keff, kana, places=4) flux = cont.get_flux_dist() self.assertEqual(len(flux), 2) # x, y self.assertEqual(len(flux[0]), int(geom[0]['width']/delta)) self.assertEqual(flux[0][0], delta/2.0) self.assertEqual(flux[0][-1], geom[0]['width']-delta/2.0) self.assertEqual(len(flux[1]), int(geom[0]['width']/delta))
def test_calculation_manager(self): xs_fuel = CrossSection() xs_fuel.set([[1.58, 0.0032, 0.0, 1.0], [0.271, 0.0930, 0.168, 0.0]]) xs_fuel.set_smat([[0.0, 0.0178], [0.0, 0.0]]) xs_fuel.calc_sigr() xs_ref = CrossSection() xs_ref.set([[1.41, 0.0, 0.0, 1.0], [0.117, 0.0191, 0.0, 0.0]]) xs_ref.set_smat([[0.0, 0.0476], [0.0, 0.0]]) xs_ref.calc_sigr() geom = [{ 'xs': xs_ref, 'width': 30 }, { 'xs': xs_fuel, 'width': 60 }, { 'xs': xs_ref, 'width': 30 }] delta = 1.0 albedo = -1.0 config = { 'geometry':geom, 'mesh_width':delta, 'albedo': albedo, 'max_iteration': 1000, \ 'omega': 0.5, 'asymptotic_criteria': 0.05} calc_man = CalculationManager(config) count, flag = calc_man.run() print("outer iterations:", count) keff = calc_man.get_keff() self.assertAlmostEqual(keff, 1.35826, places=5) # keff with strict condition
def test_calculation_manager(self): xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) delta = 1.0 albedo = -1.0 geom = [{'xs': xs_fuel, 'width': 100}] config = {'geometry': geom, 'mesh_width': delta, "albedo": albedo} calc_man = CalculationManager(config) calc_man.run() keff = calc_man.get_keff() kana = xs_fuel.nusigf() / (xs_fuel.dif() * math.pi**2 / 100**2 + xs_fuel.siga()) #print( 'kana = ', kana) self.assertAlmostEqual(keff, kana, places=4)
def test_onenode(self): node = Node() xs = CrossSection([1.36, 0.0181, 0.0279]) #xs.debug() node.set_xs(xs) node.set_keff( xs.nusigf() / xs.siga() ) node.calc() for k in range(1000): jout_xm = node.get_jout(XM) jout_xp = node.get_jout(XP) node.set_jin(XM, jout_xm) node.set_jin(XP, jout_xp) node.calc() self.assertEqual(node.get_jout(XM), node.get_jout(XP)) self.assertEqual(node.get_jin(XM), node.get_jout(XM)) self.assertEqual(node.get_jin(XP), node.get_jout(XP)) self.assertEqual(node.get_jout(XM)+node.get_jin(XM), node.get_flux() / 2.0)
def test_container_controller(self): xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) delta = 1.0 albedo = -1.0 geom = [{'xs': xs_fuel, 'width': 100}] container = Container(geom, delta, albedo) #cont.debug() controller = ContainerController(container) controller.calc() keff = controller.get_keff() kana = xs_fuel.nusigf() / (xs_fuel.dif() * math.pi**2 / 100**2 + xs_fuel.siga()) #print( 'kana = ', kana) self.assertAlmostEqual(keff, kana, places=4)
def test_uniform_zeroflux_bc(self): xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) delta = 1.0 geom = [{'xs': xs_fuel, 'width': 100}] nodes = [] for r in geom: for k in range(int(r['width'] / delta)): the_node = Node(r['xs']) the_node.set_width(delta) nodes.append(the_node) keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-7 for idx_outer in range(2000): # outer iteration # calculation of total fission source total_fis_src = 0.0 for the_node in nodes: total_fis_src += the_node.get_fis_src() # normalize fis src to make total fis src unity norm_factor = 1.0 / (total_fis_src / keff) for the_node in nodes: the_node.normalize_fis_src(norm_factor) # inner iteration with fixed fis src for istart in range(2): # start color (0: red, 1:black) for ix in range(istart, len(nodes), 2): if (ix == 0): # left boundary jin_xm = -nodes[ix].get_jout(XM) else: jin_xm = nodes[ix - 1].get_jout(XP) if (ix == len(nodes) - 1): # right boundary jin_xp = -nodes[ix].get_jout(XP) else: jin_xp = nodes[ix + 1].get_jout(XM) nodes[ix].set_jin(XM, jin_xm) nodes[ix].set_jin(XP, jin_xp) nodes[ix].calc() # calculation of new fission source for the_node in nodes: the_node.calc_fis_src() # calculation of total fission source total_fis_src = 0.0 for the_node in nodes: total_fis_src += the_node.get_fis_src() # estimation of eigen value as a ratio of generations keff = total_fis_src / (total_fis_src_old / keff_old) diff = abs((keff - keff_old) / keff) #print( idx_outer, keff, diff) if (diff < conv): break keff_old = keff total_fis_src_old = total_fis_src # set new eigen value to all the nodes for the_node in nodes: the_node.set_keff(keff) # reference as analytical solution: Eq.(6) on p.107 of the textbook kana = xs_fuel.nusigf() / (xs_fuel.dif() * math.pi**2 / 100**2 + xs_fuel.siga()) #print( 'kana = ', kana) self.assertAlmostEqual(keff, kana, places=5)
import sys sys.path.append('lib') from calculation_manager import CalculationManager from cross_section import CrossSection xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) delta = 1.0 albedo = -1.0 geom = [{'xs': xs_fuel, 'width': 100}] config = {'geometry': geom, 'mesh_width': delta, "albedo": albedo} calc_man = CalculationManager(config) calc_man.run() keff = calc_man.get_keff() print("keff = ", keff)
def test_sets3(self): xs1 = CrossSection() xs1.set([1.0, 2.0, 3.0]) xs1_ref = CrossSection() xs1_ref.set(xs1) self.assertEqual(xs1, xs1_ref)
def test_container(self): xs = CrossSection() xs.set([[1.58, 0.02, 0.0, 1.0],[0.271, 0.0930, 0.168, 0.0]]) xs.set_smat( [[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() delta = 1.0 albedo = -1.0 geom = [{'xs':xs, 'width':100}] cont = Container(geom, delta, albedo) #cont.debug() keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-7 for idx_outer in range(100): total_fis_src = cont.get_total_fis_src() norm_factor = 1.0 / (total_fis_src/keff) cont.normalize_fis_src(norm_factor) for kg in range(2): cont.calc_scat_src(kg) for idx_inner in range(4): for color in range(2): cont.calc(kg, color) cont.calc_fis_src(kg) total_fis_src = cont.get_total_fis_src() keff = total_fis_src / (total_fis_src_old/keff_old) diff = abs((keff - keff_old)/keff) #print( keff, diff) if(diff < conv): break keff_old = keff total_fis_src_old = total_fis_src cont.set_keff(keff) b2 = (math.pi / geom[0]['width'])**2 kana_nume = (xs.sigr(1) + xs.dif(1)*b2)*xs.nusigf(0) + xs.sigs(0,1)*xs.nusigf(1) kana_deno = (xs.dif(0)*b2 + xs.sigr(0) ) * (xs.dif(1)*b2 + xs.sigr(1)) kana = kana_nume / kana_deno print("kana=", kana) self.assertAlmostEqual(keff, kana, places=4) flux = cont.get_flux_dist(0) # first energy self.assertEqual(len(flux), 2) # x, y self.assertEqual(len(flux[0]), int(geom[0]['width']/delta)) self.assertEqual(flux[0][0], delta/2.0) self.assertEqual(flux[0][-1], geom[0]['width']-delta/2.0) self.assertEqual(len(flux[1]), int(geom[0]['width']/delta))
import sys sys.path.append('lib') from calculation_manager import CalculationManager from cross_section import CrossSection xs = CrossSection() xs.set([[1.58, 0.02, 0.0, 1.0],[0.271, 0.0930, 0.168, 0.0]]) xs.set_smat( [[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() delta = 1.0 albedo = -1.0 geom = [{'xs':xs, 'width':100}] config = { 'geometry':geom, 'mesh_width':delta, "albedo": albedo} calc_man = CalculationManager(config) calc_man.run() keff = calc_man.get_keff() print ("keff = ", keff)
def test_two_regions_zeroflux_bc(self): xs_fuel = CrossSection([1.36, 0.0181, 0.0279]) xs_ref = CrossSection([0.55, 0.0127, 0.0]) delta = 1.0 geom = [{ 'xs': xs_ref, 'width': 60 }, { 'xs': xs_fuel, 'width': 60 }, { 'xs': xs_ref, 'width': 60 }] nodes = [] for r in geom: for k in range(int(r['width'] / delta)): the_node = Node(r['xs']) the_node.set_width(delta) nodes.append(the_node) keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-7 for ik in range(2000): # outer iteration # calculation of total fission source total_fis_src = 0.0 for the_node in nodes: total_fis_src += the_node.get_fis_src() # normalize fis src to make total fis src unity norm_factor = 1.0 / (total_fis_src / keff) for the_node in nodes: the_node.normalize_fis_src(norm_factor) # inner iteration with fixed fis src for istart in range(2): # start color (0: red, 1:black) for ix in range(istart, len(nodes), 2): if (ix == 0): # left boundary jin_xm = -nodes[ix].get_jout(XM) else: jin_xm = nodes[ix - 1].get_jout(XP) if (ix == len(nodes) - 1): # right boundary jin_xp = -nodes[ix].get_jout(XP) else: jin_xp = nodes[ix + 1].get_jout(XM) nodes[ix].set_jin(XM, jin_xm) nodes[ix].set_jin(XP, jin_xp) nodes[ix].calc() # calculation of new fission source for the_node in nodes: the_node.calc_fis_src() # calculation of total fission source total_fis_src = 0.0 for the_node in nodes: total_fis_src += the_node.get_fis_src() # estimation of eigen value as a ratio of generations keff = total_fis_src / (total_fis_src_old / keff_old) diff = abs((keff - keff_old) / keff) #print( ik, keff, diff) if (diff < conv): break keff_old = keff total_fis_src_old = total_fis_src # set new eigen value to all the nodes for the_node in nodes: the_node.set_keff(keff) # debug #print("flux") #for ix in range(len(nodes)): # print(ix, nodes[ix].get_flux()) self.assertAlmostEqual(keff, 1.41124, places=5) # keff with strict condition
def test_onenode(self): node = Node() xs = CrossSection() # two-group problem xs.set([[1.58, 0.0032, 0.0, 1.0], [0.271, 0.0930, 0.168, 0.0]]) xs.set_smat([[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() #xs.debug() node.set_xs(xs) keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-10 # outer iteration for ik in range(1000): # normalize total fission source total_fis_src = 0.0 for kg in range(2): total_fis_src += node.get_fis_src(kg) * node.get_width() factor = 1.0 / (total_fis_src / keff) for kg in range(2): node.normalize_fis_src(kg, factor) # energy loop for kg in range(2): # update sources node.calc_scat_src(kg) # inner loop for i in range(4): for dir in range(2): node.set_jin(kg, dir, node.get_jout(kg, dir)) # calculate jout, flux with response matrix node.calc(kg) node.calc_fis_src(kg) # calc total fission source and k_eff total_fis_src = 0.0 for kg in range(2): total_fis_src += node.get_fis_src(kg) * node.get_width() keff = total_fis_src / (total_fis_src_old / keff_old) diff = abs((keff - keff_old) / keff) # convergence check if (diff < conv): break # update parameters total_fis_src_old = total_fis_src keff_old = keff node.set_keff(keff) # --- end of loop for outer iteration print("keff=", keff) # analytic solution by Eq.(67) on the page 114 where the buckling is zero. kana_nume = xs.sigr(1) * xs.nusigf(0) + xs.sigs(0, 1) * xs.nusigf(1) kana_deno = xs.sigr(0) * xs.sigr(1) kana = kana_nume / kana_deno print("kana=", kana) self.assertAlmostEqual(keff, kana, places=5) for kg in range(2): self.assertAlmostEqual(node.get_jout(kg, XM), node.get_jout(kg, XP), places=5) self.assertAlmostEqual(node.get_jin(kg, XM), node.get_jout(kg, XM), places=5) self.assertAlmostEqual(node.get_jin(kg, XP), node.get_jout(kg, XP), places=5) self.assertAlmostEqual(node.get_jout(kg, XM) + node.get_jin(kg, XM), node.get_flux(kg) / 2.0, places=5)
def test_operation_add(self): xs1 = CrossSection([1.0, 2.0, 3.0]) xs2 = CrossSection([2.0, 3.0, 4.0]) xs3 = xs1 + xs2 xs3_ref = CrossSection([3.0, 5.0, 7.0]) self.assertEqual(xs3, xs3_ref)
def test_uniform_zeroflux_bc(self): xs = CrossSection() xs.set([[1.58, 0.02, 0.0, 1.0],[0.271, 0.0930, 0.168, 0.0]]) xs.set_smat( [[0.0, 0.0178], [0.0, 0.0]]) xs.calc_sigr() delta = 1.0 geom = [{'xs':xs, 'width':100}] # geometry setting nodes = [] for r in geom: for k in range(int(r['width']/delta)): the_node = Node(r['xs']) the_node.set_width(delta) nodes.append(the_node) keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-8 # outer iteration for ik in range(100): # normalize total fission source total_fis_src = 0.0 for the_node in nodes: for kg in range(2): total_fis_src += the_node.get_fis_src(kg) * the_node.get_width() factor = 1.0 / (total_fis_src/keff) for the_node in nodes: for kg in range(2): the_node.normalize_fis_src(kg, factor) # energy loop for kg in range(2): # update scattering source for the_node in nodes: the_node.calc_scat_src(kg) # inner loop for i in range(4): for istart in range(2): # start color (0: red, 1:black) for ix in range(istart, len(nodes), 2): # pass partial currents to adjacent nodes if(ix==0): jin_xm = -nodes[ix].get_jout(kg, XM) else: jin_xm = nodes[ix-1].get_jout(kg, XP) if(ix==len(nodes)-1): jin_xp = -nodes[ix].get_jout(kg, XP) else: jin_xp = nodes[ix+1].get_jout(kg, XM) nodes[ix].set_jin(kg, XM, jin_xm) nodes[ix].set_jin(kg, XP, jin_xp) # calculate jout, flux with response matrix nodes[ix].calc(kg) # update fission source for the_node in nodes: the_node.calc_fis_src(kg) # calc total fission source and keff total_fis_src = 0.0 for the_node in nodes: for kg in range(2): total_fis_src += the_node.get_fis_src(kg) * the_node.get_width() keff = total_fis_src / (total_fis_src_old/keff_old) diff = abs((keff - keff_old)/keff) # print( keff, diff) # convergence check if(diff < conv): break # update parameters total_fis_src_old = total_fis_src keff_old = keff for the_node in nodes: the_node.set_keff(keff) # --- end of loop for outer iterations # converged print("keff=", keff) # debug #print("fast flux") #for ix in range(len(nodes)): # print(ix, nodes[ix].get_flux(0)) b2 = (math.pi / geom[0]['width'])**2 kana_nume = (xs.sigr(1) + xs.dif(1)*b2)*xs.nusigf(0) + xs.sigs(0,1)*xs.nusigf(1) kana_deno = (xs.dif(0)*b2 + xs.sigr(0) ) * (xs.dif(1)*b2 + xs.sigr(1)) kana = kana_nume / kana_deno print("kana=", kana) self.assertAlmostEqual(keff, kana, places=4)
def test_operation_sub(self): xs1 = CrossSection([1.0, 2.0, 3.0]) xs2 = CrossSection([2.0, 3.0, 4.0]) xs3 = xs2 - xs1 xs3_ref = CrossSection([1.0, 1.0, 1.0]) self.assertEqual(xs3, xs3_ref)
def test_two_regions_zeroflux_bc(self): xs_fuel = CrossSection() xs_fuel.set([[1.58, 0.0032, 0.0, 1.0],[0.271, 0.0930, 0.168, 0.0]]) xs_fuel.set_smat( [[0.0, 0.0178], [0.0, 0.0]]) xs_fuel.calc_sigr() xs_ref = CrossSection() xs_ref.set([[1.41, 0.0, 0.0, 1.0],[0.117, 0.0191, 0.0, 0.0]]) xs_ref.set_smat( [[0.0, 0.0476], [0.0, 0.0]]) xs_ref.calc_sigr() delta = 1.0 geom = [{'xs':xs_ref, 'width':30}, {'xs':xs_fuel, 'width':60}, {'xs':xs_ref, 'width':30} ] # geometry setting nodes = [] for r in geom: for k in range(int(r['width']/delta)): the_node = Node(r['xs']) the_node.set_width(delta) nodes.append(the_node) keff = 1.0 keff_old = 1.0 total_fis_src_old = 1.0 conv = 1.0e-8 # outer iteration for ik in range(100): # normalize total fission source total_fis_src = 0.0 for the_node in nodes: for kg in range(2): total_fis_src += the_node.get_fis_src(kg) * the_node.get_width() factor = 1.0 / (total_fis_src/keff) for the_node in nodes: for kg in range(2): the_node.normalize_fis_src(kg, factor) # energy loop for kg in range(2): # update scattering source for the_node in nodes: the_node.calc_scat_src(kg) # inner loop for i in range(4): for istart in range(2): # start color (0: red, 1:black) for ix in range(istart, len(nodes), 2): # pass partial currents to adjacent nodes if(ix==0): jin_xm = -nodes[ix].get_jout(kg, XM) else: jin_xm = nodes[ix-1].get_jout(kg, XP) if(ix==len(nodes)-1): jin_xp = -nodes[ix].get_jout(kg, XP) else: jin_xp = nodes[ix+1].get_jout(kg, XM) nodes[ix].set_jin(kg, XM, jin_xm) nodes[ix].set_jin(kg, XP, jin_xp) # calculate jout, flux with response matrix nodes[ix].calc(kg) # update fission source for the_node in nodes: the_node.calc_fis_src(kg) # calc total fission source and keff total_fis_src = 0.0 for the_node in nodes: for kg in range(2): total_fis_src += the_node.get_fis_src(kg) * the_node.get_width() keff = total_fis_src / (total_fis_src_old/keff_old) diff = abs((keff - keff_old)/keff) # print( keff, diff) # convergence check if(diff < conv): break # update parameters total_fis_src_old = total_fis_src keff_old = keff for the_node in nodes: the_node.set_keff(keff) # --- end of loop for outer iterations # converged print("keff=", keff) #print("flux") #for ix in range(len(nodes)): # print(ix, nodes[ix].get_flux()) self.assertAlmostEqual(keff, 1.35826, places=5) # keff with strict condition