def step5(cfg, cfg2, cfg5): """ This function creates the adjoint neutron source and writes the PARTISN input file for adjoint neutron transport. Parameters ---------- cfg : dictionary User input from 'general' section of config.yml file cfg2 : dictionary User input for step 2 from the config.yml file cfg5 : dictionary User input for step 3 from the config.yml file """ # Get user-input from config file num_n_groups = cfg['n_groups'] num_p_groups = cfg['p_groups'] n_geom = cfg2['n_geom_file'] decay_times = str(cfg2['decay_times']).split(' ') meshflux = cfg5['meshflux'] # Base of geometry file name basename = n_geom.split("/")[-1].split(".")[0] # The total number of photon and neutron energy groups total_num_groups = num_n_groups + num_p_groups # Read given flux file and tag to a mesh if meshflux: # Adjoint flux file is an hdf5 mesh file fw_n_err = meshflux m = Mesh(structured=True, mesh=fw_n_err, mats=None) else: raise RuntimeError("No neutron flux file given") # Size of flux tag is equal to the total number of energy groups m.ERROR_TAG = NativeMeshTag(num_n_groups, name="ERROR_TAG") fw_n_err = m.ERROR_TAG[:] # Load geometry and get material assignments load(n_geom) ml = MaterialLibrary(n_geom) mat_names = list(ml.keys()) cell_mats = cell_material_assignments(n_geom) # Load T matrix if not os.path.exists('step2_T.npy'): raise RuntimeError("T matrix from step 2 (step2_T.npy) not found") T = np.load('step2_T.npy') # Loop over mesh voxels and calculate the error in the photon source by multiplying neutron flux and T matrix dg = discretize_geom(m) for t, dt in enumerate(decay_times): temp = np.zeros(shape=(len(m), num_p_groups)) for i in range(len(m)): for row in np.atleast_1d(dg[dg["idx"] == i]): cell = row[1] if not cell_mats[cell] in mat_names: continue vol_frac = row[2] mat = mat_names.index(cell_mats[cell]) for h in range(num_p_groups): for g in range(num_n_groups): temp[i, h] += (fw_n_err[i, g]**2) * T[mat, t, g, h] * vol_frac print("err ", temp[i, h]) # Tag the mesh with the squared error in the photon source values tag_name = "sq_err_q_src_{0}".format(dt) m.err_q_src = NativeMeshTag(num_p_groups, name=tag_name) m.err_q_src[:] = temp # Save adjoint neutron source mesh file tagged with values for all decay times m.save("sq_err_q_src.h5m")