os.chdir('C:\\CUBEM\\') FILENAME = 'cube.cii' ROOTFILE = FILENAME[:-4] DATABASE = ROOTFILE + '_eq.cdb' Geom = Geometry(FILENAME.replace('.cii', '0.cii')) NuFis = Nu_Fission_Map() KM = Kinetic_Map(NPRC=1) _NOG = 1 NPRC = KM.get_NPRC() Flux = MeshFlux(DATABASE + '.meshflux', *Geom.Cantidad_de_Nodos(), _NOG) Nx, Ny, Nz = Flux.shape[1:4] BetaM = np.empty((1, Nx, Ny, Nz, NPRC)) LambdaM = np.empty((1, Nx, Ny, Nz, NPRC)) NuFisM = np.empty((1, Nx, Ny, Nz, _NOG)) VelocityM = np.empty((1, Nx, Ny, Nz, _NOG)) state = 0 Vmesh = Geom.Vmesh() # react = grp(ROOTFILE+'.plt') react = [173.0] keff = 1 / (1 - react[-1] / 100 / 1000) # keff = 1.0015
class AerEvolution(AerModel): def __init__(self): super().__init__() # llama a la creación de AerModel print('- Inicializando Transitorio') self._C0 = {} self.__Ct_1 = {} self._Ct = {} self.__FILENAME = 'aer.cii' self.__ROOTFILE = self.__FILENAME[:-4] self.__DATABASE = self.__ROOTFILE + '_eq.cdb' self.__Geom = Geometry(self.__FILENAME.replace('.cii', '_geo.ci@')) self.__NuFis = NuFissionMap() self.__KM = KineticMap() self._NOG = 2 # TODO: Sería mejor extraer del ci@? self.chi_g = [1.0, 0.0] # TODO: Sería mejor extraer del ci@? self.__Flux_t_1 = self.Flux = MeshFlux( self.__DATABASE + '.meshflux', *self.__Geom.Cantidad_de_Nodos(), self._NOG) Nx, Ny, Nz, _NOG = self.Flux.shape[1:] self.BetaM = np.empty((1, Nx, Ny, Nz, 6)) self.LambdaM = np.empty((1, Nx, Ny, Nz, 6)) self.NuFisM = np.empty((1, Nx, Ny, Nz, _NOG)) self.VelocityM = np.empty((1, Nx, Ny, Nz, _NOG)) state = 0 static_react = -123.1 # reactividad inicial inicial, no inicial self.keff = 1 / (1 - static_react / 100000) self._Q = {} self.EQUILIBRIUM = True self.powers = [] for _x in range(Nx): for _y in range(Ny): for _z in range(Nz): meshmaterial = self.__Geom.sc5[_x][_y][_z] kwargs = {'list_fuels': self.list_fuels, 'time': 0} self.BetaM[state][_x][_y][_z][:] = \ self.__KM.MapMaterial(meshmaterial, **kwargs)['Beta'] self.LambdaM[state][_x][_y][_z][:] = \ self.__KM.MapMaterial(meshmaterial, **kwargs)['Decays'] self.VelocityM[state][_x][_y][_z][:] = \ self.__KM.MapMaterial(meshmaterial, **kwargs)['Neutron Velocity'] self.NuFisM[state][_x][_y][_z][:] = \ self.__NuFis.MapMaterial(meshmaterial, **kwargs)['XS'][:, 3] / self.keff @property def Ct_1(self): """ Precursores calculados en el paso anterior """ return self.__Ct_1.copy() @property def Ct(self): """ Precursores calculados hasta ahora. """ return AddableDict(self._Ct) @property def C0(self): """ Precursores de Equilibrio (reactor estático) """ return AddableDict(self._C0) def equilibrium_precrs(self): print('- Calculando precursores en equilibrio') state = 0 Vmesh = self.__Geom.Vmesh() NPRC = self.BetaM.shape[-1] self._C0[state] = {} for nx in range(self.Flux.shape[1]): self._C0[state][nx] = {} for ny in range(self.Flux.shape[2]): self._C0[state][nx][ny] = {} for nz in range(self.Flux.shape[3]): FluxL = [ self.Flux[state, nx, ny, nz, group] for group in range(self.Flux.shape[-1]) ] NuFisL = [ self.NuFisM[state][nx][ny][nz][group] for group in range(self.Flux.shape[-1]) ] Nu_FluxM = [ NuFisL[group] * FluxL[group] * Vmesh for group in range(self.Flux.shape[-1]) ] Bet_k = self.BetaM[state][nx][ny][nz] Lamb_k = self.LambdaM[state][nx][ny][nz] Nu_Flux = sum(Nu_FluxM) self._C0[state][nx][ny][nz] = [ Bet_k[prec] * Nu_Flux / Lamb_k[prec] if Lamb_k[prec] != 0 else 0.0 for prec in range(NPRC) ] self.__Ct_1 = self._C0.copy() self._Ct = self._C0.copy() def calculate_precrs(self, dt): TFlux = MeshFlux(self.__DATABASE + '.meshflux', *self.__Geom.Cantidad_de_Nodos()[1:4]) self._Ct = PrecCalc(self.__Ct_1, TFlux, self.NuFisM, self.__Geom.Vmesh(), dt, LambdaM=self.LambdaM, BetaM=self.BetaM) self.__Ct_1 = self._Ct.copy() self.__Flux_t_1 = TFlux return @property def Q_as_array(self): """ Fuente calculada al instante t como array de numpy """ return AddableDict(self._Q).as_array() def calculate_source(self, **kwargs): print('- Calculando la fuente') DERIVATIVE = kwargs['DERIVATIVE'] if DERIVATIVE: dt = kwargs['dt'] else: dt = 1 Vmesh = self.__Geom.Vmesh() NPRC = 6 for group in range(self.Flux.shape[-1]): self._Q[group] = {} for state in range(self.Flux.shape[0]): self._Q[group][state] = {} for nx in range(self.Flux.shape[1]): self._Q[group][state][nx] = {} for ny in range(self.Flux.shape[2]): self._Q[group][state][nx][ny] = {} for nz in range(self.Flux.shape[3]): _Lmk = self.LambdaM[state][nx][ny][nz] _C = self._Ct[state][nx][ny][nz] _invV = self.VelocityM[state, nx, ny, nz, group] T_1Flux = self.__Flux_t_1[state, nx, ny, nz, group] self._Q[group][state][nx][ny][nz] = \ self.chi_g[group] * sum([_Lmk[prc] * _C[prc] for prc in range(NPRC)]) \ + (_invV / dt * T_1Flux * Vmesh if DERIVATIVE else 0) def move_control_rods(self, **kwargs): Threshold = 1.0 assert 'time' in kwargs, 'No se ha establecido el tiempo de cálculo' Time = kwargs['time'] Extraction_Velocity = 200 / 0.08 Extraction_CR_26 = 8 - (Extraction_Velocity * Time) // 25 if Time <= 0.08 else 0 self.InsertControlRod(Extraction_CR_26, 26) if Time > Threshold: Insertion_Velocity = 250 / 10.0 # Hasta el fondo del nucleo en 10 segundos Insertion_CR_21 = 8 + (Insertion_Velocity * Time) // 25 if Time <= 2.0 else 10 Insertion_CR_SS = (Insertion_Velocity * Time) // 25 if Time <= 11.0 else 10 # Control Rod Secutiry System (23,25) self.SCRAM(Insertion_CR_SS) self.InsertControlRod(Insertion_CR_21, 21) # TODO testear este método y llevarlo a archivo return def source_to_file(self): print('- Escribiendo el Archivo source.dat') _NOG = 2 with open('source.dat', 'w') as fod: for group in range(_NOG): for state in range(self.Flux.shape[0]): for nz in range(self.Flux.shape[3]): for ny in range(self.Flux.shape[2]): for nx in range(self.Flux.shape[1]): fod.write('{:15.7E}'.format( self._Q[group][state][nx][ny][nz])) fod.write('\n') fod.write('\n') def Execute(self, **kwargs): self.EQUILIBRIUM = False print('- Ejecuntando CITVAP') DERIVATIVE = kwargs['DERIVATIVE'] if DERIVATIVE: dt = kwargs['dt'] else: dt = 1 time = kwargs['time'] p = re.compile(r'POWER\(WATTS\)\s+([0-9]\.[0-9]{5}E\+[0-9]{2})') Nx, Ny, Nz = self.__Geom.Cantidad_de_Nodos() OsArgs = (self.__FILENAME.replace('.cii', 'S.cii'), self._NOG, Nx, Ny, Nz, self.EQUILIBRIUM, *['{:12.5E}'.format(_d) for _d in [dt * DERIVATIVE, time]]) # PARA HACER UNA PERTURBACION ESCALOR,COLOCAR t=1 # PARA CALCULAR SIN DERIVADA TEMPORAL dt=0 try: os.system('ExEqAer.bat ' + ' '.join(map(str, OsArgs))) fid = open(self.__ROOTFILE + 'S.cio', 'r') self.powers.append(float(next(p.finditer(fid.read())).groups()[0])) print(self.powers[-1]) fid.close() if self.EQUILIBRIUM: self.EQUILIBRIUM = False except StopIteration: FAILED_COMPLETE_TEST = True pass # TODO: traer el script a python para ser ejecutado con subprocess.Popen pass # AerEvolution
def mainnomain(): os.chdir('D:\\AER\\') FILENAME = 'aer.cii' ROOTFILE = FILENAME[:-4] DATABASE = ROOTFILE + '_eq.cdb' Geom = Geometry(FILENAME.replace('.cii', '_geo.ci@')) NuFis = NuFissionMap() KM = KineticMap() _NOG = 2 Flux = MeshFlux(DATABASE + '.meshflux', *Geom.Cantidad_de_Nodos(), _NOG) Nx, Ny, Nz = Flux.shape[1:4] BetaM = np.empty((1, Nx, Ny, Nz, 1)) LambdaM = np.empty((1, Nx, Ny, Nz, 1)) NuFisM = np.empty((1, Nx, Ny, Nz, _NOG)) VelocityM = np.empty((1, Nx, Ny, Nz, _NOG)) state = 0 Vmesh = Geom.Vmesh() react = -123.1 # reactividad inicial inicial, no inicial keff = 1 / (1 - react / 100000) for _x in range(Nx): for _y in range(Ny): for _z in range(Nz): meshmaterial = Geom.sc5[_x][_y][_z] KinParam = KM.MapMaterial(meshmaterial) # Obsoleto BetaM[state][_x][_y][_z][:] = KinParam['Beta'] LambdaM[state][_x][_y][_z][:] = KinParam['Decays'] VelocityM[state][_x][_y][_z][:] = KinParam['Neutron Velocity'] NuFisM[state][_x][_y][_z][:] = NuFis.MapMaterial( meshmaterial)['XS'][:, 3] / keff C0 = {} NPRC = BetaM.shape[-1] C0[state] = {} for nx in range(Flux.shape[1]): C0[state][nx] = {} for ny in range(Flux.shape[2]): C0[state][nx][ny] = {} for nz in range(Flux.shape[3]): FluxL = [ Flux[state, nx, ny, nz, group] for group in range(Flux.shape[-1]) ] NuFisL = [ NuFisM[state][nx][ny][nz][group] for group in range(Flux.shape[-1]) ] Nu_FluxM = [ NuFisL[group] * FluxL[group] * Vmesh for group in range(Flux.shape[-1]) ] Bet_k = BetaM[state][nx][ny][nz] Lamb_k = LambdaM[state][nx][ny][nz] Nu_Flux = sum(Nu_FluxM) C0[state][nx][ny][nz] = [ Bet_k[prec] * Nu_Flux / Lamb_k[prec] if Lamb_k[prec] != 0 else 0.0 for prec in range(NPRC) ] p = re.compile(r'POWER\(WATTS\)\s+([0-9]\.[0-9]{5}E\+[0-9]{2})') powers = [] Q = {} EQUILIBRIUM = True chi_g = [1.0, 0.0] v1 = 1.25E+7 v2 = 2.50E+5 dt = 0.01 tfinal = 0.5 DATABASE = ROOTFILE + 'S.cdb' Times = np.arange(0, tfinal + 2 * dt, dt) FAILED_COMPLETE_TEST = False DERIVATIVE = True for t in Times: if EQUILIBRIUM: C_t_1 = C0.copy() C_t = C0.copy() Flux_t_1 = Flux else: TFlux = MeshFlux(DATABASE + '.meshflux', Nx, Ny, Nz, _NOG) # noinspection PyUnboundLocalVariable C_t = PrecCalc(C_t_1, TFlux, NuFisM, Vmesh, dt, LambdaM=LambdaM, BetaM=BetaM) C_t_1 = C_t.copy() Flux_t_1 = TFlux for group in range(Flux.shape[-1]): Q[group] = {} for state in range(Flux.shape[0]): Q[group][state] = {} for nx in range(Flux.shape[1]): Q[group][state][nx] = {} for ny in range(Flux.shape[2]): Q[group][state][nx][ny] = {} for nz in range(Flux.shape[3]): _Lmk = LambdaM[state][nx][ny][nz] _C = C_t[state][nx][ny][nz] _invV = VelocityM[state, nx, ny, nz, group] T_1Flux = Flux_t_1[state, nx, ny, nz, group] Q[group][state][nx][ny][nz] = \ chi_g[group] * sum([_Lmk[prc] * _C[prc] for prc in range(NPRC)]) \ + _invV / dt * T_1Flux * Vmesh * DERIVATIVE # with open('source.dat', 'w') as fod: for group in range(_NOG): for state in range(Flux.shape[0]): for nz in range(Flux.shape[3]): for ny in range(Flux.shape[2]): for nx in range(Flux.shape[1]): fod.write('{:15.7E}'.format( Q[group][state][nx][ny][nz])) fod.write('\n') # Ejecución de archivo AQUI OsArgs = (FILENAME.replace('.cii', 'S.cii'), _NOG, Nx, Ny, Nz, EQUILIBRIUM, *['{:12.5E}'.format(_d) for _d in [dt * DERIVATIVE, t]]) # PARA HACER UNA PERTURBACION ESCALOR,COLOCAR t=1 # PARA CALCULAR SIN DERIVADA TEMPORAL dt=0 try: os.system('ExAer.bat ' + ' '.join(map(str, OsArgs))) fid = open(ROOTFILE + 'S.cio', 'r') powers.append(float(next(p.finditer(fid.read())).groups()[0])) print(powers[-1]) fid.close() if EQUILIBRIUM: EQUILIBRIUM = False except StopIteration: FAILED_COMPLETE_TEST = True break pass Normalized_Pow = np.array(powers) / 1E+06 if FAILED_COMPLETE_TEST: Times = [k * dt for k in range(len(powers))] return
class CubeModel(EvInterface): @property def Ct_1(self): return AddableDict(self._Ct_1).as_array() @property def C0(self): return AddableDict(self._C0).as_array() @property def Ct(self): return AddableDict(self._Ct).as_array() @property def Q(self): return AddableDict(self._Q).as_array() def __init__(self, state=0, nprc=1, Equilibrium=True, file='cubeS.cii', UseDerivative=False): self.t = 0.0 self.dt = 0.0 self.state = state self.chi_g = [1.0] self.__file = file self.Equilibrium = Equilibrium self.nprc = nprc self.__rootfile = self.__file.replace('.cii', '') self.__database = self.__file.replace('.cii', '.cdb') self.__p_parser = re.compile( r'POWER\(WATTS\) +([0-9]\.[0-9]{5}E\+[0-9]{2})') self.Pt = 100 self._Q = {} self._C0 = self._Ct = self._Ct_1 = {self.state: {}} self.__UseDerivative = UseDerivative self.__datfile = r'source.dat' self._init_citvap_model() self._init_mesh_parameters() self._init_parameters() self._init_flux() return def _init_citvap_model(self): self._CV = CitvapSourceModel(file=self.__file, sec4='cube.sc4', sec5='cube.sc5', mat='cube.mat', sec26='cube.sc26', GeometricType='XYZ') self._CV.PrintMeshMap() self._CV.Calculate() return def _init_flux(self): self.Flux_t = self.Flux_t_1 = \ MeshFlux(self.__database.replace('S.cdb', '_eq.cdb.meshflux') , self.Nx, self.Ny, self.Nz, self._NOG) return def _init_parameters(self): self.NuFis = Nu_Fission_Map() self.KM = Kinetic_Map(NPRC=self.nprc) self._NOG = 1 self.BetaM = np.empty((1, self.Nx, self.Ny, self.Nz, self.nprc)) self.LambdaM = np.empty((1, self.Nx, self.Ny, self.Nz, self.nprc)) self.NuFisM = np.empty((1, self.Nx, self.Ny, self.Nz, self._NOG)) self.VelocityM = np.empty((1, self.Nx, self.Ny, self.Nz, self._NOG)) for _x in range(self.Nx): for _y in range(self.Ny): for _z in range(self.Nz): meshmaterial = self.Geom.sc5[_x][_y][_z] KinParam = self.KM.MapMaterial(meshmaterial, NPRC=self.nprc) self.BetaM[self.state][_x][_y][_z][:] = KinParam['Beta'] self.LambdaM[ self.state][_x][_y][_z][:] = KinParam['Decays'] self.VelocityM[self.state][_x][_y][_z][:] = KinParam[ 'Neutron Velocity'] self.NuFisM[self.state][_x][_y][ _z][:] = self.NuFis.MapMaterial(meshmaterial)['XS'][:, 3] self.react = self.__R0 = 173.0E-5 self.keff = 1 / (1 - self.__R0) return 0 def _init_mesh_parameters(self): self.Geom = Geometry(self.__file.replace( 'S.cii', '0.cii')) # HARDCODEADO el *S.cii self.Vmesh = self.Geom.Vmesh() self.Nx, self.Ny, self.Nz = self.Geom.Cantidad_de_Nodos() return def equilibrium_precrs(self, *args, **kwargs): if not self._C0[self.state]: for nx in range(self.Flux_t.shape[1]): self._C0[self.state][nx] = {} for ny in range(self.Flux_t.shape[2]): self._C0[self.state][nx][ny] = {} for nz in range(self.Flux_t.shape[3]): FluxL = [ self.Flux_t[self.state, nx, ny, nz, group] for group in range(self.Flux_t.shape[-1]) ] NuFisL = [ self.NuFisM[self.state][nx][ny][nz][group] / self.keff for group in range(self.Flux_t.shape[-1]) ] Nu_FluxM = [ NuFisL[group] * FluxL[group] * self.Geom.Vmesh() for group in range(self.Flux_t.shape[-1]) ] Bet_k = self.BetaM[self.state][nx][ny][nz] Lamb_k = self.LambdaM[self.state][nx][ny][nz] self._C0[self.state][nx][ny][nz] = [ Bet_k[prec] / Lamb_k[prec] * sum(Nu_FluxM) if Lamb_k[prec] != 0 else 0.0 for prec in range(self.nprc) ] return def calculate_precrs(self, dt): for nx in range(self.Nx): # self._Ct[self.state][nx] = {} for ny in range(self.Ny): # self._Ct[self.state][nx][ny] = {} for nz in range(self.Nz): FluxL = [ self.Flux_t[self.state, nx, ny, nz, group] for group in range(self._NOG) ] NuFisL = [ self.NuFisM[self.state][nx][ny][nz][group] for group in range(self._NOG) ] Bet_k = self.BetaM[self.state][nx][ny][nz] Lamb_k = self.LambdaM[self.state][nx][ny][nz] _c_t_1 = self._Ct_1[self.state][nx][ny][nz] Nu_Flux = [ NuFisL[group] * FluxL[group] * self.Geom.Vmesh() for group in range(self._NOG) ] self._Ct[self.state][nx][ny][nz] = \ [_c_t_1[prec] * np.exp(-Lamb_k[prec] * dt) + Bet_k[prec] / Lamb_k[prec] * sum(Nu_Flux) * (1 - np.exp(-Lamb_k[prec] * dt)) if Lamb_k[prec] != 0 else 0.0 for prec in range(self.nprc)] return def evolve(self, dt, *args, **kwargs): if self.Equilibrium: self.equilibrium_precrs() self._Ct = self._C0.copy() self._Ct_1 = self._C0.copy() else: self._Ct_1 = self._Ct.copy() self.calculate_precrs(dt) self.t += dt if self.__UseDerivative: self.dt = dt self.calculate_source(dt) self.source_to_file() self.__send_to_lu_17__() self.__xsu_mod__() self.run() self.__get_power__() if self.Equilibrium: self.Equilibrium = False self.Flux_t_1 = self.Flux_t.copy() self.Flux_t = MeshFlux(self.__database + '.meshflux', self.Nx, self.Ny, self.Nz, self._NOG) return def source_to_file(self): with open(self.__datfile, 'w') as fod: for group in range(self._NOG): for nz in range(self.Nz): for ny in range(self.Ny): for nx in range(self.Nx): fod.write('{:15.7E}'.format( self._Q[group][self.state][nx][ny][nz])) fod.write('\n') return def __send_to_lu_17__(self): subprocess.run(['copy', '/Y', self.__datfile, 'Source_To_LU17'], shell=True) os.chdir('C:\\CUBEM\\Source_To_LU17') msg = subprocess.run( ['main.exe', *map(str, [self._NOG, self.Nx, self.Ny, self.Nz])], shell=True, capture_output=True) msg2 = subprocess.run( ['copy', '/Y', 'fort.17', '..\\' + self.__rootfile + '.src'], shell=True, capture_output=True) os.chdir('C:\\CUBEM') return msg def __xsu_mod__(self): XSU_FILE = '{}'.format(self.__rootfile + '.XSU') try: self._CV.run(executable='pre_cit.exe') except AssertionError: time.sleep(2.0) self._CV.run(executable='pre_cit.exe') subprocess.run(['move', XSU_FILE, 'XSU_MOD\\'], shell=True) os.chdir('C:\\CUBEM\\XSU_MOD') if self.__UseDerivative: time_step = self.dt else: time_step = 0.0 msg = subprocess.run([ 'neutyp', '{}'.format(XSU_FILE), str(self.Equilibrium), *map(lambda a: '{:12.5E}'.format(round(a, ndigits=5)), [time_step, self.t]) ], shell=True, capture_output=True) assert msg.stderr in [ '', b'' ], 'Error en la sobreescritura del archivo ROOT.XSU' os.chdir('C:\\CUBEM') msg2 = subprocess.run([ 'move', '/Y', 'C:\\CUBEM\\XSU_MOD\\{}'.format(XSU_FILE), XSU_FILE ], shell=True, capture_output=True) assert msg2.stderr in ['', b'' ], 'Error en el movimiento del archivo ROOT.XSU' return msg def __get_power__(self, file=None): if not file: fid = open(self.__rootfile + '.cio', 'r') else: fid = open(file, 'r') self.Pt = float(self.__p_parser.findall(fid.read())[0]) fid.close() return def run(self): try: self._CV.run(executable='cittrs.exe') except AssertionError: time.sleep(2.0) self._CV.run(executable='cittrs.exe') subprocess.run( ['caremdb', '-opt:export', '-val:meshflux', self.__database]) return def calculate_source(self, dt): for group in range(self.Flux_t.shape[-1]): self._Q[group] = {self.state: {}} for nx in range(self.Flux_t.shape[1]): self._Q[group][self.state][nx] = {} for ny in range(self.Flux_t.shape[2]): self._Q[group][self.state][nx][ny] = {} for nz in range(self.Flux_t.shape[3]): _Lmk = self.LambdaM[self.state][nx][ny][nz] _C = self._Ct[self.state][nx][ny][nz] inv_V = self.VelocityM[self.state, nx, ny, nz, group] self._Q[group][self.state][nx][ny][nz] = \ self.chi_g[group] * sum([_Lmk[prc] * _C[prc] for prc in range(self.nprc)]) if self.__UseDerivative: self._Q[group][self.state][nx][ny][nz] +=\ inv_V / dt * self.Flux_t_1[self.state, nx, ny, nz, group] * self.Vmesh return pass # CubeModel