Loading SubKit/build/Model.py +124 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,20 @@ class Model: # which will either be the axial location or the power factor, depending on which dictionary it is. me.axialPowerShapeAxial = {} me.axialPowerShapePower = {} # Axial geometry modification tables. Of the form {ID: {'axial': [a1, a2, ...], 'mult': [m1, m2, ...]}} # Here ID is an ID for the table, the 'axial' list gives the axial level locations, and the 'mult' list # gives the multipliers for each level me.axialGeoShape = {} # Links the axial geometry modification tables to channels in the model. Of the form: # {chID: {'tables': [tab1, tab2, ...], 'aspects': [[aspect1], [aspect1, aspect2]]}} # A single channel may have multiple geometry modification tables applied to it, with each table applying # to multiple aspects of the geometry (momentum area, scalar area, wetted perimeter). me.channelGeoTables = {} # Links the axial geometry modification tables to gaps in the model. A gap can only have one # table applied, so the form is: # {gapID: tab1} # A geometry modification table can only apply to gap width. me.gapGeoTables = {} # List of FormLoss objects in the model me.formLosses = [] # Same size as formLosses. Gives the channel ID of the loss Loading Loading @@ -1079,6 +1093,84 @@ class Model: me.axialPowerShapeAxial[time][powID] = axial me.axialPowerShapePower[time][powID] = power def addAxialGeoShape(me, ID, axialLevels, multipliers): """ Add a axially-dependent geometry modification table to the model This will specify a list of multipliers to be applied at axial levels specified in the axialLevels list. The axial levels shall be integer level indices. The meaning of the node (momentum level or scalar level) depends on how the table is applied. If the table is applied to momentum cell area, it will mean momentum level and if it is applied to scalar cell area, wetted perimeter, or gap width, it will mean scalar level. It is important to consider how CTF will apply these tables. A linear interpolation is done between points in the table to determine the local multiplier. For example, for the following table: 1 0.5 3 0.7 4 0.8 8 0.8 The multiplier that will be applied to level 2 will be 0.6. However, if adjacent levels are specified, as in the case of 3 and 4 in the table, then no interpolation can be done. In this case, the 0.7 multiplier will be applied to Level 3 and 0.8 will be applied to Level 4. If the user desires no interpolation, then each region must be "capped", as in the case of Levels 4 to 8. In this case, each level will have a value of 0.8 applied. Furthermore, the bottom and top of the model should be included in the table to ensure all multipliers are defined. Args: ID (int): Identifier for the table axialLevels (list): List of integer node levels multipliers (list): List of float multiplier values """ assert isinstance(ID, int) assert ID>0 assert len(axialLevels)==len(multipliers) assert all(multipliers)>0.0 assert ID not in me.axialGeoShape me.axialGeoShape[ID] = {'axial': axialLevels, 'mult': multipliers} def assignTableToChannel(me, tableID, chID, applies): """ Use this procedure to assign a geometry modification table to a channel in the model. The tableID must match a table ID that was defined using the :meth:`addAxialGeoTable` procedure. The chID must match a channel ID that was defined using the :meth:`addChannel` procedure. The `applies` input is a list of geometry aspects to which the table shall apply. The `applies` list can include "momentum", "scalar", and "pw", which represent the momentum cell areas, scalar cell areas, and wetted perimeter. Args: tableID (choice): ID of previously defined axial geometry table chID (int): ID of previously defined channel applies (list or str): Can provide a single string value or list of strings to define which aspects of the geometry this table shall apply """ if chID not in me.channelGeoTables: me.channelGeoTables[chID] = {'tables': [], 'aspects': []} me.channelGeoTables[chID]['tables'].append(tableID) validApplies = ['momentum', 'scalar', 'pw'] if not isinstance(applies, list): ls = [applies] assert applies in validApplies else: ls = applies for val in applies: assert val in validApplies me.channelGeoTables[chID]['aspects'].append(ls) def assignTableToGap(me, tableID, gapID): """ Assigns a geometry modification table to a gap in the model The axial geometry modification table assigned to tableID and defined with :meth:`addAxialGeoTable` will be assigned to the specified gapID. The table multipliers will operate on the gap width. Args: tableID (choice): ID of previously defined geometry modification table gapID (int): ID of gap defined by :meth:`setGap` procedure """ assert gapID not in me.gapGeoTables me.gapGeoTables[gapID] = tableID def addTransientGroup(me, tEnd, editInterval=None, dtMin=None, dtMax=None): """ Adds a transient group to the simulation Loading Loading @@ -1573,6 +1665,8 @@ class Model: me._validateBoundaryConditions() me._validateGeoTables() # Add a uniform power profile that covers the entire model so it can be assigned to rods # that had now power shape assigned if me._anyRodsWithoutPowerID(): Loading Loading @@ -2088,6 +2182,36 @@ class Model: raise RuntimeError("For solidID: " + str(solidID) + " in Section: " + str( u) + " percentages of connected channels add up to " + str(totPercent) + " instead of 1.0") def _validateGeoTables(me): """ Ensure all geometry tables applied to model objects were defined and that they were all assigned to objects that exist in the model. """ # Ensure axial geo table IDs are sequential ID = 1 for key in sorted(me.axialGeoShape.keys()): if key!=ID: raise RuntimeError("Axial geometry table IDs must be sequential starting at 1.") ID=ID+1 for chID in me.channelGeoTables.keys(): foundChannel = False for section in me.sections.keys(): if chID in me.sections[section].channels.keys(): foundChannel = True if not foundChannel: raise RuntimeError("Geometry table ID: "+str(me.channelGeoTables[chID]['tables'][0])+ " assigned to non-existent channel: "+str(chID)) for tableID in me.channelGeoTables[chID]['tables']: if tableID not in me.axialGeoShape: raise RuntimeError("Geometry table ID: "+str(tableID)+" was not defined, but is trying "+ "to be applied to channel: "+str(chID)) for gapID in me.gapGeoTables.keys(): if gapID not in me.gaps: raise RuntimeError("Geometry table ID: "+str(me.gapGeoTables[gapID])+" attempting to be applied"+ " to non-existent gap: "+str(gapID)) if tableID not in me.axialGeoShape: raise RuntimeError("Geometry table ID: "+str(tableID)+" was not defined, but is trying "+ "to be applied to gap: "+str(gapID)) class Gap(object): """ Defines a gap (a lateral connection between two channels in the same axial section) Loading SubKit/build/genDeck.py +64 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,60 @@ def writeDeck(model, filename): group4Data.append("** MSIM\n") group4Data.append("{0:8d}\n".format(model._getNCELLS())) group5Data = [] group6Data = [] if len(model.gapGeoTables)>0 or len(model.channelGeoTables)>0: group5Data.append("**NGR\n5\n") group5Data.append("*Card 5.1\n") maxLen = 0 for key in model.axialGeoShape.keys(): maxLen = max(maxLen, len(model.axialGeoShape[key]['axial'])) group5Data.append("** NAFACT NAXL\n") group5Data.append("{:9d}{:7d} 0 0 0 0 0 0 0 0 0 0 0 0\n".format(len(model.axialGeoShape.keys()), maxLen)) group5Data.append("**Card 5.2\n") for key in sorted(model.axialGeoShape.keys()): line = "" for i in range(len(model.axialGeoShape[key]['axial'])): line = line+"{:5d}{:16.4e}".format(model.axialGeoShape[key]['axial'][i], model.axialGeoShape[key]['mult'][i]) # Pad the rest with zeros if this table is shorter than max for i in range(len(model.axialGeoShape[key]['axial']), maxLen): line = line+"{:5d}{:16.4e}".format(0, 0.0) group5Data.append(line+"\n") group6Data.append("**NGR\n6\n") group6Data.append("*Card 6.1\n") group6Data.append("** N1\n") group6Data.append("{:7d} 0 0 0 0 0 0 0 0 0 0 0 0 0\n".format(len(model.channelGeoTables.keys())+ len(model.gapGeoTables.keys()))) group6Data.append("*Card 6.2\n") group6Data.append("** IACT IAMT IPWT ICRG\n") def getMom(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IAMT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'momentum' in channelGeoTables['aspects'][i]: return tableID return 0 def getScal(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IACT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'scalar' in channelGeoTables['aspects'][i]: return tableID return 0 def getPw(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IPWT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'pw' in channelGeoTables['aspects'][i]: return tableID return 0 for chID in sorted(model.channelGeoTables.keys()): group6Data.append("{:7d}{:7d}{:7d}{:7d} 0 0 0 0 0 0 0 0 0 0 0\n".format(getScal(model.channelGeoTables[chID]), getMom(model.channelGeoTables[chID]), getPw(model.channelGeoTables[chID]), chID)) for gapID in sorted(model.gapGeoTables.keys()): group6Data.append("{:7d}{:7d}{:7d}{:7d} 0 0 0 0 0 0 0 0 0 0 0\n".format(-model.gapGeoTables[gapID], 0, 0, gapID)) group7Data = [] group7Data.append("**NGR\n") group7Data.append(" 7\n") Loading Loading @@ -995,6 +1049,16 @@ def writeDeck(model, filename): "GROUP 4 - Vertical Channel Connection Data")) for l in group4Data: newDeckLines.append(l) if len(group5Data)>0: newDeckLines.append(makeGroupBanner( "GROUP 5 - Axial Geometry Variation Tables")) for l in group5Data: newDeckLines.append(l) if len(group6Data)>0: newDeckLines.append(makeGroupBanner( "GROUP 6 - Channel/Gap Variation Table Application")) for l in group6Data: newDeckLines.append(l) newDeckLines.append(makeGroupBanner( "GROUP 7 - Grid Loss Coefficient Data")) for l in group7Data: Loading tests/scriptRegression/case5/deck.inp.gold 0 → 100644 +255 −0 Original line number Diff line number Diff line *********************************************************************************************** *MAIN CONTROL DATA *********************************************************************************************** *ICOBRA 1 *INITIAL DUMPF 1 0 ** EPSO OITMAX IITMAX COURANT 1e-4 5 200 0.800000 *TITLE ctf model *********************************************************************************************** *GROUP 1 - Calculation Variables and Initial Conditions *********************************************************************************************** **NGR 1 **NGAS IRFC EDMD IMIX ISOL GINIT NOTRN MESH MAPS IPRP MFLX IBTM PPV NM14 1 2 0 3 0 1.70995e+02 1 1 0 11 0 0 7 0 *Card 1.2 ** GTOT AFLUX DHFRAC 170.99460 69.79200 0.97629 *Card 1.3 ** PREF HIN HGIN VFRAC1 VFRAC2 3.44738 -908.15000 288.4200000 1.0000000 0.9999000 *Card 1.4 **GTP(1) VFRAC(3) GTP(2) VFRAC(4) GTP(3) VFRAC(5) GTP(4) VFRAC(6) air 0.0001 *********************************************************************************************** *GROUP 2 - Channel Description *********************************************************************************************** **NGR 2 *Card 2.1 ** NCH NDM2 NDM3 NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 2.2 ** I AN PW ABOT ATOP NMGP X Y XSIZ YSIZ 1 1.6360e-01 4.1286e+01 0.0 0.0 0 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 *********************************************************************************************** *GROUP 4 - Vertical Channel Connection Data *********************************************************************************************** **NGR 4 *Card 4.1 **NSEC NSIM IREB NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 4.2 **ISEC NCHN NONO DXS IVAR 1 1 20 1.0160e-01 0 *Card 4.4 ** I NCHA KCHA(:) NCHB KCHB(:) 1 0 0 *Card4.5 ** IWDE 1 *Card 4.6 ** MSIM 20 *********************************************************************************************** *GROUP 7 - Grid Loss Coefficient Data *********************************************************************************************** **NGR 7 *Card 7.1 ** NCD NGT IFGQF IFSDRP IFESPV IFTPE IGTEMP NFBS NDM9 NDM10 NDM11 NDM12 NDM13 NDM14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 7.2 ** CDL J CD1 CD2 CD3 CD4 CD5 CD6 CD7 CD8 CD9 CD10 CD11 CD12 *********************************************************************************************** *GROUP 8 - Rod and Unheated Conductor Data *********************************************************************************************** **NGR 8 *Card 8.1 ** NRRD NSRD NC NRTB NRAD NLTY NSTA NXF NCAN RADF W3 IHTC DNBCHK NDM14 1 0 1 1 0 0 1 1 0 0 -1 1 1 0 *Card 8.2 ** N IFTY IAXP NRND DAXMIN RMULT HGAP ISECR HTAMB TAMB SYMROD HTCMAP TKEMAP NSUBAX NSUBAZ *Card 8.3 **NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE 1 1 1 0 0 5.6900e+02 0.0000e+00 1 0.0000e+00 0.0000e+00 1.000 0 0 1 1 1 1.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 *Card 8.5 ** N ISTYP HPERIM HPERIMI RMULS NOSLCH NSLCHC HTAMBS TAMBS *Card 8.6 ** I NRT1 NST1 NRX1 1 1 0 2 *Card 8.7 **IRTB1 IRTB2 IRTB3 IRTB4 IRTB5 IRTB6 IRTB7 IRTB8 IRTB9 IRTB10 IRTB11 IRTB12 1 *Card 8.8 **ISTB1 ISTB2 ISTB3 ISTB4 ISTB5 ISTB6 ISTB7 ISTB8 ISTB9 ISTB10 ISTB11 ISTB12 *Card 8.9 ** AXIALT TRINIT 0.00000e+00 9.08150e+02 2.03200e+00 9.08150e+02 *********************************************************************************************** *GROUP 9 - Conductor Geometry Description *********************************************************************************************** **NGR 9 *Card 9.1 ** NFLT IRLF ICNF IMWR ISWL IDNS IRLG CREEP NDM9 NM10 NM11 NM12 NM13 NM14 1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 *Card 9.6 ** I FTYP DROD DIN NFUL IMTF IMTC DUM8 DUM9 DUM10 DUM11 DUM12 DUM13 DUM14 EPSO 1 hrod 5.053314e-02 0.00000e+00 1 0 0 0 0 0 0 0 0 0 0.0 *Card 9.7 ** NODER MATR TREG QREG 3 1 2.526657e-02 1.0 *********************************************************************************************** *GROUP 10 - Material Properties Tables *********************************************************************************************** *NGRP 10 *NMAT NDM2 NDM3 NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 0 0 0 0 0 0 0 0 0 0 0 0 0 * N NTDP RCOLD IMATAN 1 20 1740.000 graphite * TPROP CPF1 THCF 250.00 0.5948 177.6810 337.50 0.8370 155.8017 425.00 1.0473 138.9136 512.50 1.2283 125.4402 600.00 1.3823 114.4129 687.50 1.5118 105.2023 775.00 1.6192 97.3804 862.50 1.7069 90.6458 950.00 1.7775 84.7795 1037.50 1.8332 79.6184 1125.00 1.8766 75.0385 1212.50 1.9101 70.9437 1300.00 1.9361 67.2582 1387.50 1.9570 63.9215 1475.00 1.9753 60.8846 1562.50 1.9934 58.1076 1650.00 2.0137 55.5572 1737.50 2.0387 53.2058 1825.00 2.0708 51.0303 1912.50 2.1124 49.0109 * *********************************************************************************************** *GROUP 11 - Core Power Distribution Information *********************************************************************************************** *NGR group number 11 **Card 11.1 * NQA NAXP MNXN NQ NGPFF NQR NDM7 NDM8 NDM9 NDM10 NDM11 NDM12 NDM13 NDM14 1 1 2 0 0 1 0 0 0 0 0 0 0 0 **Card 11.2 * YQA 0.00000e+00 **Card 11.3 * I NAXN 1 2 **Card 11.4 * Y AXIALZ 0.00000e+00 1.00000e+00 2.03200e+00 1.00000e+00 **Radial power profile forcing function **Card 11.7 * YQR 0.00000E+00 **Card 11.8 * FQR1 FQR2 FQR3 FQR4 FQR5 FQR6 FQR7 FQR8 1.00000 *********************************************************************************************** *GROUP 12 - Turbulent Mixing and Void Drift Data *********************************************************************************************** **NGR 12 *Card 12.2 ** AAAK BETA THETM 0.140E+01 3.700e-02 0.500E+01 *********************************************************************************************** *GROUP 13 - Boundary Condition Data *********************************************************************************************** *NGR group number 13 **Card 13.1 * NBND NKBD NFUN NGBD VBC NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 2 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 13.2 ** NPTS *Card 13.3 **Card 13.4 * IBD1 IBD2 ISPC N1FN N2FN N3FN BCVALUE1 BCVALUE2 BCVALUE3 INITGAS 1 1 2 0 0 0 1.70995e+02 -9.08150e+02 0.00000e+00 1 1 22 1 0 0 0 0.00000e+00 -9.08150e+02 3.44738e+00 1 *********************************************************************************************** *GROUP 14 - Output Options *********************************************************************************************** **NGR -14 ** KEY VALUE rod_edits 0 rod_vtk 0 native_hdf5 1 fluid_vtk 0 dnb_edits 0 chan_edits 0 hdf5 0 convergence 1 gap_edits 0 end 14 *********************************************************************************************** *GROUP 15 - Time Domain Data *********************************************************************************************** **NGR 15 *Card 15.1 ** DTMIN DTMAX TEND EDINT DMPINT RTWFP MAXITS 1.00000e-06 1.00000e-01 1.0000E-01 0.0000E+00 0.0000E+00 1.000000e+02 10000 *********************************************************************************************** *GROUP 19 - convergence Criteria for Steady State Solve *********************************************************************************************** **NGR 19 ** Normalized l-infinity of checked solution terms must go below these tolerances for the case ** to be considered steady state. The code converges if the following is true for each checked ** solution term: ** ** abs((X-Xn))<=max(rtol*abs(Xn),atol) ** ** In this equation, 'X' is a vector of the checked solution terms from the current checkpoint ** and 'Xn' is the vector of the same solution terms, but from the previous checkpoint. Checks ** are made every 0.05 seconds in the transient. The relative tolerances are defined on Card ** 19.1 and the absolute tolerances are defined on Card 19.2. This check is done for pressure, ** fluid temperature, solid temperature, and the three components of axial velocity. There is ** also a check on void, but it does not invole the relative check because void is a ** dimensionless value; only the absolute check is done. ** ** The final check involves checking that the mass and energy balance over the system is below ** a tolerance as well. ** Balance of mass ((mass_in-mass_out)/mass_in) and balance of energy ((energy_in-energy_out)/ ** energy_in) must go below tolerance values defined on Card 19.3 for case to be considered ** steady state. *Card 19.1 - relative stopping criteria [unitless] ** LIPRESS LITCOOL LITSOLID LIVL LIVV LIVD 1.000e-03 1.000e-03 1.000e-03 1.000e-03 1.000e-03 1.000e-03 *Card 19.2 - absolute stopping criteria [pressure in psia|bar, velocity in ft/s|m/s, ** and temperature in F|C] ** LIAVOID LIAPRESS LIATCOOL LIATSOLID LIAVL LIAVV LIAVD 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 *Card 19.2 [%] ** ENERGYBAL MASSBAL 1.000000e-01 1.000000e-01 *Card 19.4 [%] ** L2PRESS L2TCOOL L2TSOLID L2VL L2VV L2VD *Card 19.5 - absolute stopping criteria [pressure in psia|bar, velocity in ft/s|m/s, 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 ** and temperature in F|C] ** L2AVOID L2APRESS L2ATCOOL L2ATSOLID L2AVL L2AVV L2AVD 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 tests/scriptRegression/case5/make_deck.py 0 → 100644 +61 −0 File added.Preview size limit exceeded, changes collapsed. Show changes tests/test_script_mode.sh +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ runScriptTest "scriptRegression/case1" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case2" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case3" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case4" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case5" "make_deck.py" "$rebaseline" # Put these at the end because they take forever runScriptTest "mcfr" "coreRegion.py" "$rebaseline" Loading Loading
SubKit/build/Model.py +124 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,20 @@ class Model: # which will either be the axial location or the power factor, depending on which dictionary it is. me.axialPowerShapeAxial = {} me.axialPowerShapePower = {} # Axial geometry modification tables. Of the form {ID: {'axial': [a1, a2, ...], 'mult': [m1, m2, ...]}} # Here ID is an ID for the table, the 'axial' list gives the axial level locations, and the 'mult' list # gives the multipliers for each level me.axialGeoShape = {} # Links the axial geometry modification tables to channels in the model. Of the form: # {chID: {'tables': [tab1, tab2, ...], 'aspects': [[aspect1], [aspect1, aspect2]]}} # A single channel may have multiple geometry modification tables applied to it, with each table applying # to multiple aspects of the geometry (momentum area, scalar area, wetted perimeter). me.channelGeoTables = {} # Links the axial geometry modification tables to gaps in the model. A gap can only have one # table applied, so the form is: # {gapID: tab1} # A geometry modification table can only apply to gap width. me.gapGeoTables = {} # List of FormLoss objects in the model me.formLosses = [] # Same size as formLosses. Gives the channel ID of the loss Loading Loading @@ -1079,6 +1093,84 @@ class Model: me.axialPowerShapeAxial[time][powID] = axial me.axialPowerShapePower[time][powID] = power def addAxialGeoShape(me, ID, axialLevels, multipliers): """ Add a axially-dependent geometry modification table to the model This will specify a list of multipliers to be applied at axial levels specified in the axialLevels list. The axial levels shall be integer level indices. The meaning of the node (momentum level or scalar level) depends on how the table is applied. If the table is applied to momentum cell area, it will mean momentum level and if it is applied to scalar cell area, wetted perimeter, or gap width, it will mean scalar level. It is important to consider how CTF will apply these tables. A linear interpolation is done between points in the table to determine the local multiplier. For example, for the following table: 1 0.5 3 0.7 4 0.8 8 0.8 The multiplier that will be applied to level 2 will be 0.6. However, if adjacent levels are specified, as in the case of 3 and 4 in the table, then no interpolation can be done. In this case, the 0.7 multiplier will be applied to Level 3 and 0.8 will be applied to Level 4. If the user desires no interpolation, then each region must be "capped", as in the case of Levels 4 to 8. In this case, each level will have a value of 0.8 applied. Furthermore, the bottom and top of the model should be included in the table to ensure all multipliers are defined. Args: ID (int): Identifier for the table axialLevels (list): List of integer node levels multipliers (list): List of float multiplier values """ assert isinstance(ID, int) assert ID>0 assert len(axialLevels)==len(multipliers) assert all(multipliers)>0.0 assert ID not in me.axialGeoShape me.axialGeoShape[ID] = {'axial': axialLevels, 'mult': multipliers} def assignTableToChannel(me, tableID, chID, applies): """ Use this procedure to assign a geometry modification table to a channel in the model. The tableID must match a table ID that was defined using the :meth:`addAxialGeoTable` procedure. The chID must match a channel ID that was defined using the :meth:`addChannel` procedure. The `applies` input is a list of geometry aspects to which the table shall apply. The `applies` list can include "momentum", "scalar", and "pw", which represent the momentum cell areas, scalar cell areas, and wetted perimeter. Args: tableID (choice): ID of previously defined axial geometry table chID (int): ID of previously defined channel applies (list or str): Can provide a single string value or list of strings to define which aspects of the geometry this table shall apply """ if chID not in me.channelGeoTables: me.channelGeoTables[chID] = {'tables': [], 'aspects': []} me.channelGeoTables[chID]['tables'].append(tableID) validApplies = ['momentum', 'scalar', 'pw'] if not isinstance(applies, list): ls = [applies] assert applies in validApplies else: ls = applies for val in applies: assert val in validApplies me.channelGeoTables[chID]['aspects'].append(ls) def assignTableToGap(me, tableID, gapID): """ Assigns a geometry modification table to a gap in the model The axial geometry modification table assigned to tableID and defined with :meth:`addAxialGeoTable` will be assigned to the specified gapID. The table multipliers will operate on the gap width. Args: tableID (choice): ID of previously defined geometry modification table gapID (int): ID of gap defined by :meth:`setGap` procedure """ assert gapID not in me.gapGeoTables me.gapGeoTables[gapID] = tableID def addTransientGroup(me, tEnd, editInterval=None, dtMin=None, dtMax=None): """ Adds a transient group to the simulation Loading Loading @@ -1573,6 +1665,8 @@ class Model: me._validateBoundaryConditions() me._validateGeoTables() # Add a uniform power profile that covers the entire model so it can be assigned to rods # that had now power shape assigned if me._anyRodsWithoutPowerID(): Loading Loading @@ -2088,6 +2182,36 @@ class Model: raise RuntimeError("For solidID: " + str(solidID) + " in Section: " + str( u) + " percentages of connected channels add up to " + str(totPercent) + " instead of 1.0") def _validateGeoTables(me): """ Ensure all geometry tables applied to model objects were defined and that they were all assigned to objects that exist in the model. """ # Ensure axial geo table IDs are sequential ID = 1 for key in sorted(me.axialGeoShape.keys()): if key!=ID: raise RuntimeError("Axial geometry table IDs must be sequential starting at 1.") ID=ID+1 for chID in me.channelGeoTables.keys(): foundChannel = False for section in me.sections.keys(): if chID in me.sections[section].channels.keys(): foundChannel = True if not foundChannel: raise RuntimeError("Geometry table ID: "+str(me.channelGeoTables[chID]['tables'][0])+ " assigned to non-existent channel: "+str(chID)) for tableID in me.channelGeoTables[chID]['tables']: if tableID not in me.axialGeoShape: raise RuntimeError("Geometry table ID: "+str(tableID)+" was not defined, but is trying "+ "to be applied to channel: "+str(chID)) for gapID in me.gapGeoTables.keys(): if gapID not in me.gaps: raise RuntimeError("Geometry table ID: "+str(me.gapGeoTables[gapID])+" attempting to be applied"+ " to non-existent gap: "+str(gapID)) if tableID not in me.axialGeoShape: raise RuntimeError("Geometry table ID: "+str(tableID)+" was not defined, but is trying "+ "to be applied to gap: "+str(gapID)) class Gap(object): """ Defines a gap (a lateral connection between two channels in the same axial section) Loading
SubKit/build/genDeck.py +64 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,60 @@ def writeDeck(model, filename): group4Data.append("** MSIM\n") group4Data.append("{0:8d}\n".format(model._getNCELLS())) group5Data = [] group6Data = [] if len(model.gapGeoTables)>0 or len(model.channelGeoTables)>0: group5Data.append("**NGR\n5\n") group5Data.append("*Card 5.1\n") maxLen = 0 for key in model.axialGeoShape.keys(): maxLen = max(maxLen, len(model.axialGeoShape[key]['axial'])) group5Data.append("** NAFACT NAXL\n") group5Data.append("{:9d}{:7d} 0 0 0 0 0 0 0 0 0 0 0 0\n".format(len(model.axialGeoShape.keys()), maxLen)) group5Data.append("**Card 5.2\n") for key in sorted(model.axialGeoShape.keys()): line = "" for i in range(len(model.axialGeoShape[key]['axial'])): line = line+"{:5d}{:16.4e}".format(model.axialGeoShape[key]['axial'][i], model.axialGeoShape[key]['mult'][i]) # Pad the rest with zeros if this table is shorter than max for i in range(len(model.axialGeoShape[key]['axial']), maxLen): line = line+"{:5d}{:16.4e}".format(0, 0.0) group5Data.append(line+"\n") group6Data.append("**NGR\n6\n") group6Data.append("*Card 6.1\n") group6Data.append("** N1\n") group6Data.append("{:7d} 0 0 0 0 0 0 0 0 0 0 0 0 0\n".format(len(model.channelGeoTables.keys())+ len(model.gapGeoTables.keys()))) group6Data.append("*Card 6.2\n") group6Data.append("** IACT IAMT IPWT ICRG\n") def getMom(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IAMT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'momentum' in channelGeoTables['aspects'][i]: return tableID return 0 def getScal(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IACT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'scalar' in channelGeoTables['aspects'][i]: return tableID return 0 def getPw(channelGeoTables): """ Takes the channelGeoTables entry for chID and returns the flag for IPWT in the CTF input deck.""" for i, tableID in enumerate(channelGeoTables['tables']): if 'pw' in channelGeoTables['aspects'][i]: return tableID return 0 for chID in sorted(model.channelGeoTables.keys()): group6Data.append("{:7d}{:7d}{:7d}{:7d} 0 0 0 0 0 0 0 0 0 0 0\n".format(getScal(model.channelGeoTables[chID]), getMom(model.channelGeoTables[chID]), getPw(model.channelGeoTables[chID]), chID)) for gapID in sorted(model.gapGeoTables.keys()): group6Data.append("{:7d}{:7d}{:7d}{:7d} 0 0 0 0 0 0 0 0 0 0 0\n".format(-model.gapGeoTables[gapID], 0, 0, gapID)) group7Data = [] group7Data.append("**NGR\n") group7Data.append(" 7\n") Loading Loading @@ -995,6 +1049,16 @@ def writeDeck(model, filename): "GROUP 4 - Vertical Channel Connection Data")) for l in group4Data: newDeckLines.append(l) if len(group5Data)>0: newDeckLines.append(makeGroupBanner( "GROUP 5 - Axial Geometry Variation Tables")) for l in group5Data: newDeckLines.append(l) if len(group6Data)>0: newDeckLines.append(makeGroupBanner( "GROUP 6 - Channel/Gap Variation Table Application")) for l in group6Data: newDeckLines.append(l) newDeckLines.append(makeGroupBanner( "GROUP 7 - Grid Loss Coefficient Data")) for l in group7Data: Loading
tests/scriptRegression/case5/deck.inp.gold 0 → 100644 +255 −0 Original line number Diff line number Diff line *********************************************************************************************** *MAIN CONTROL DATA *********************************************************************************************** *ICOBRA 1 *INITIAL DUMPF 1 0 ** EPSO OITMAX IITMAX COURANT 1e-4 5 200 0.800000 *TITLE ctf model *********************************************************************************************** *GROUP 1 - Calculation Variables and Initial Conditions *********************************************************************************************** **NGR 1 **NGAS IRFC EDMD IMIX ISOL GINIT NOTRN MESH MAPS IPRP MFLX IBTM PPV NM14 1 2 0 3 0 1.70995e+02 1 1 0 11 0 0 7 0 *Card 1.2 ** GTOT AFLUX DHFRAC 170.99460 69.79200 0.97629 *Card 1.3 ** PREF HIN HGIN VFRAC1 VFRAC2 3.44738 -908.15000 288.4200000 1.0000000 0.9999000 *Card 1.4 **GTP(1) VFRAC(3) GTP(2) VFRAC(4) GTP(3) VFRAC(5) GTP(4) VFRAC(6) air 0.0001 *********************************************************************************************** *GROUP 2 - Channel Description *********************************************************************************************** **NGR 2 *Card 2.1 ** NCH NDM2 NDM3 NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 2.2 ** I AN PW ABOT ATOP NMGP X Y XSIZ YSIZ 1 1.6360e-01 4.1286e+01 0.0 0.0 0 0.0000e+00 0.0000e+00 0.0000e+00 0.0000e+00 *********************************************************************************************** *GROUP 4 - Vertical Channel Connection Data *********************************************************************************************** **NGR 4 *Card 4.1 **NSEC NSIM IREB NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 4.2 **ISEC NCHN NONO DXS IVAR 1 1 20 1.0160e-01 0 *Card 4.4 ** I NCHA KCHA(:) NCHB KCHB(:) 1 0 0 *Card4.5 ** IWDE 1 *Card 4.6 ** MSIM 20 *********************************************************************************************** *GROUP 7 - Grid Loss Coefficient Data *********************************************************************************************** **NGR 7 *Card 7.1 ** NCD NGT IFGQF IFSDRP IFESPV IFTPE IGTEMP NFBS NDM9 NDM10 NDM11 NDM12 NDM13 NDM14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 7.2 ** CDL J CD1 CD2 CD3 CD4 CD5 CD6 CD7 CD8 CD9 CD10 CD11 CD12 *********************************************************************************************** *GROUP 8 - Rod and Unheated Conductor Data *********************************************************************************************** **NGR 8 *Card 8.1 ** NRRD NSRD NC NRTB NRAD NLTY NSTA NXF NCAN RADF W3 IHTC DNBCHK NDM14 1 0 1 1 0 0 1 1 0 0 -1 1 1 0 *Card 8.2 ** N IFTY IAXP NRND DAXMIN RMULT HGAP ISECR HTAMB TAMB SYMROD HTCMAP TKEMAP NSUBAX NSUBAZ *Card 8.3 **NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE NSCH PIE 1 1 1 0 0 5.6900e+02 0.0000e+00 1 0.0000e+00 0.0000e+00 1.000 0 0 1 1 1 1.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 0 0.000 *Card 8.5 ** N ISTYP HPERIM HPERIMI RMULS NOSLCH NSLCHC HTAMBS TAMBS *Card 8.6 ** I NRT1 NST1 NRX1 1 1 0 2 *Card 8.7 **IRTB1 IRTB2 IRTB3 IRTB4 IRTB5 IRTB6 IRTB7 IRTB8 IRTB9 IRTB10 IRTB11 IRTB12 1 *Card 8.8 **ISTB1 ISTB2 ISTB3 ISTB4 ISTB5 ISTB6 ISTB7 ISTB8 ISTB9 ISTB10 ISTB11 ISTB12 *Card 8.9 ** AXIALT TRINIT 0.00000e+00 9.08150e+02 2.03200e+00 9.08150e+02 *********************************************************************************************** *GROUP 9 - Conductor Geometry Description *********************************************************************************************** **NGR 9 *Card 9.1 ** NFLT IRLF ICNF IMWR ISWL IDNS IRLG CREEP NDM9 NM10 NM11 NM12 NM13 NM14 1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 *Card 9.6 ** I FTYP DROD DIN NFUL IMTF IMTC DUM8 DUM9 DUM10 DUM11 DUM12 DUM13 DUM14 EPSO 1 hrod 5.053314e-02 0.00000e+00 1 0 0 0 0 0 0 0 0 0 0.0 *Card 9.7 ** NODER MATR TREG QREG 3 1 2.526657e-02 1.0 *********************************************************************************************** *GROUP 10 - Material Properties Tables *********************************************************************************************** *NGRP 10 *NMAT NDM2 NDM3 NDM4 NDM5 NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 1 0 0 0 0 0 0 0 0 0 0 0 0 0 * N NTDP RCOLD IMATAN 1 20 1740.000 graphite * TPROP CPF1 THCF 250.00 0.5948 177.6810 337.50 0.8370 155.8017 425.00 1.0473 138.9136 512.50 1.2283 125.4402 600.00 1.3823 114.4129 687.50 1.5118 105.2023 775.00 1.6192 97.3804 862.50 1.7069 90.6458 950.00 1.7775 84.7795 1037.50 1.8332 79.6184 1125.00 1.8766 75.0385 1212.50 1.9101 70.9437 1300.00 1.9361 67.2582 1387.50 1.9570 63.9215 1475.00 1.9753 60.8846 1562.50 1.9934 58.1076 1650.00 2.0137 55.5572 1737.50 2.0387 53.2058 1825.00 2.0708 51.0303 1912.50 2.1124 49.0109 * *********************************************************************************************** *GROUP 11 - Core Power Distribution Information *********************************************************************************************** *NGR group number 11 **Card 11.1 * NQA NAXP MNXN NQ NGPFF NQR NDM7 NDM8 NDM9 NDM10 NDM11 NDM12 NDM13 NDM14 1 1 2 0 0 1 0 0 0 0 0 0 0 0 **Card 11.2 * YQA 0.00000e+00 **Card 11.3 * I NAXN 1 2 **Card 11.4 * Y AXIALZ 0.00000e+00 1.00000e+00 2.03200e+00 1.00000e+00 **Radial power profile forcing function **Card 11.7 * YQR 0.00000E+00 **Card 11.8 * FQR1 FQR2 FQR3 FQR4 FQR5 FQR6 FQR7 FQR8 1.00000 *********************************************************************************************** *GROUP 12 - Turbulent Mixing and Void Drift Data *********************************************************************************************** **NGR 12 *Card 12.2 ** AAAK BETA THETM 0.140E+01 3.700e-02 0.500E+01 *********************************************************************************************** *GROUP 13 - Boundary Condition Data *********************************************************************************************** *NGR group number 13 **Card 13.1 * NBND NKBD NFUN NGBD VBC NDM6 NDM7 NDM8 NDM9 NM10 NM11 NM12 NM13 NM14 2 0 0 0 0 0 0 0 0 0 0 0 0 0 *Card 13.2 ** NPTS *Card 13.3 **Card 13.4 * IBD1 IBD2 ISPC N1FN N2FN N3FN BCVALUE1 BCVALUE2 BCVALUE3 INITGAS 1 1 2 0 0 0 1.70995e+02 -9.08150e+02 0.00000e+00 1 1 22 1 0 0 0 0.00000e+00 -9.08150e+02 3.44738e+00 1 *********************************************************************************************** *GROUP 14 - Output Options *********************************************************************************************** **NGR -14 ** KEY VALUE rod_edits 0 rod_vtk 0 native_hdf5 1 fluid_vtk 0 dnb_edits 0 chan_edits 0 hdf5 0 convergence 1 gap_edits 0 end 14 *********************************************************************************************** *GROUP 15 - Time Domain Data *********************************************************************************************** **NGR 15 *Card 15.1 ** DTMIN DTMAX TEND EDINT DMPINT RTWFP MAXITS 1.00000e-06 1.00000e-01 1.0000E-01 0.0000E+00 0.0000E+00 1.000000e+02 10000 *********************************************************************************************** *GROUP 19 - convergence Criteria for Steady State Solve *********************************************************************************************** **NGR 19 ** Normalized l-infinity of checked solution terms must go below these tolerances for the case ** to be considered steady state. The code converges if the following is true for each checked ** solution term: ** ** abs((X-Xn))<=max(rtol*abs(Xn),atol) ** ** In this equation, 'X' is a vector of the checked solution terms from the current checkpoint ** and 'Xn' is the vector of the same solution terms, but from the previous checkpoint. Checks ** are made every 0.05 seconds in the transient. The relative tolerances are defined on Card ** 19.1 and the absolute tolerances are defined on Card 19.2. This check is done for pressure, ** fluid temperature, solid temperature, and the three components of axial velocity. There is ** also a check on void, but it does not invole the relative check because void is a ** dimensionless value; only the absolute check is done. ** ** The final check involves checking that the mass and energy balance over the system is below ** a tolerance as well. ** Balance of mass ((mass_in-mass_out)/mass_in) and balance of energy ((energy_in-energy_out)/ ** energy_in) must go below tolerance values defined on Card 19.3 for case to be considered ** steady state. *Card 19.1 - relative stopping criteria [unitless] ** LIPRESS LITCOOL LITSOLID LIVL LIVV LIVD 1.000e-03 1.000e-03 1.000e-03 1.000e-03 1.000e-03 1.000e-03 *Card 19.2 - absolute stopping criteria [pressure in psia|bar, velocity in ft/s|m/s, ** and temperature in F|C] ** LIAVOID LIAPRESS LIATCOOL LIATSOLID LIAVL LIAVV LIAVD 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 *Card 19.2 [%] ** ENERGYBAL MASSBAL 1.000000e-01 1.000000e-01 *Card 19.4 [%] ** L2PRESS L2TCOOL L2TSOLID L2VL L2VV L2VD *Card 19.5 - absolute stopping criteria [pressure in psia|bar, velocity in ft/s|m/s, 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 ** and temperature in F|C] ** L2AVOID L2APRESS L2ATCOOL L2ATSOLID L2AVL L2AVV L2AVD 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04 1.000e-04
tests/scriptRegression/case5/make_deck.py 0 → 100644 +61 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
tests/test_script_mode.sh +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ runScriptTest "scriptRegression/case1" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case2" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case3" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case4" "make_deck.py" "$rebaseline" runScriptTest "scriptRegression/case5" "make_deck.py" "$rebaseline" # Put these at the end because they take forever runScriptTest "mcfr" "coreRegion.py" "$rebaseline" Loading