Exemple #1
0
 def setupChecks(self, multiselect, disabled=[]):
     sr = simulationResult(motor(
     ))  # This simres is only used to get the list of channels available
     for c in sr.channels:
         if multiselect:
             check = QCheckBox(sr.channels[c].name)
             check.setCheckState(2)  # Every field is checked by default
         else:
             check = QRadioButton(sr.channels[c].name)
         if c in disabled:
             check.setEnabled(False)
         self.layout().addWidget(check)
         self.checks[c] = check
Exemple #2
0
def defaultMotor():
    dm = motorlib.motor()
    bg = motorlib.batesGrain()
    bg.setProperties({'diameter': 3.27/39.37,
              'length': 5.5/39.37,
              'coreDiameter': 1.25/39.37,
              'inhibitedEnds': 'Neither'
              })
    dm.grains.append(bg)
    dm.grains.append(bg)

    dm.nozzle.setProperties({'throat': 0.55/39.37, 'exit': 1.5/39.37, 'efficiency': 0.85})
    dm.propellant.setProperties(clProps)

    return dm
Exemple #3
0
    def load(self, path=None):
        if self.unsavedCheck():
            if path is None:
                path = QFileDialog.getOpenFileName(None, 'Load motor', '',
                                                   'Motor Files (*.ric)')[0]
            if path != '':  # If they cancel the dialog, path will be an empty string
                try:
                    res = loadFile(path, fileTypes.MOTOR)
                    if res is not None:
                        motor = motorlib.motor()
                        motor.applyDict(res)
                        self.startFromMotor(motor, path)
                        return True
                except Exception as e:
                    self.showException(e)

        return False  # If no file is loaded, return false
Exemple #4
0
    def test_calcKN(self):

        tm = motorlib.motor()

        bg = motorlib.batesGrain()
        bg.setProperties({
            'diameter': 0.083058,
            'length': 0.1397,
            'coreDiameter': 0.05,
            'inhibitedEnds': 'Neither'
        })

        tm.grains.append(bg)
        tm.nozzle.setProperties({'throat': 0.01428})

        self.assertAlmostEqual(tm.calcKN([0]), 180, 0)
        self.assertAlmostEqual(tm.calcKN([0.0025]), 183, 0)
        self.assertAlmostEqual(tm.calcKN([0.005]), 185, 0)
Exemple #5
0
    def __init__(self):
        from .views.CSVExporter_ui import Ui_CSVExporter
        QDialog.__init__(self)
        self.ui = Ui_CSVExporter()
        self.ui.setupUi(self)
        self.simRes = None
        self.preferences = None
        self.ui.buttonBox.accepted.connect(self.exportCSV)
        self.checks = {}

        # Populate list of checks to toggle channels
        checkLayout = QVBoxLayout()
        self.ui.groupBoxChecks.setLayout(checkLayout)
        sr = simulationResult(motor(
        ))  # This simres is only used to get the list of channels available
        for c in sr.channels:
            check = QCheckBox(sr.channels[c].name)
            check.setCheckState(2)  # Every field is checked by default
            if c == "time":  # Time must be set
                check.setEnabled(False)
            checkLayout.addWidget(check)
            self.checks[c] = check
Exemple #6
0
    def test_calcPressure(self):
        tm = motorlib.motor()

        bg = motorlib.batesGrain()
        bg.setProperties({
            'diameter': 0.083058,
            'length': 0.1397,
            'coreDiameter': 0.05,
            'inhibitedEnds': 'Neither'
        })

        tm.grains.append(bg)

        tm.nozzle.setProperties({'throat': 0.01428})
        tm.propellant.setProperties({
            'name': 'KNSU',
            'density': 1890,
            'a': 0.000101,
            'n': 0.319,
            't': 1720,
            'm': 41.98,
            'k': 1.133
        })
        self.assertAlmostEqual(tm.calcIdealPressure([0]), 4050030, 0)
Exemple #7
0
 def getCurrentMotor(self):
     nm = motorlib.motor()
     nm.loadDict(self.fileHistory[self.currentVersion])
     return nm
Exemple #8
0
 def newFile(self):
     if self.unsavedCheck():
         self.startFromMotor(motorlib.motor())
Exemple #9
0
    def importFile(self, path):
        motor = motorlib.motor()
        tree = ET.parse(path)
        root = tree.getroot()
        errors = ''
        propSet = False
        for child in root:
            if child.tag == 'Nozzle':
                motor.nozzle.setProperty('throat',
                                         inToM(child.attrib['ThroatDia']))
                motor.nozzle.setProperty('exit',
                                         inToM(child.attrib['ExitDia']))
                motor.nozzle.setProperty(
                    'efficiency',
                    float(child.attrib['NozzleEfficiency']) / 100)
            if child.tag == 'Grain':
                if child.attrib['Type'] in supportedGrainTable:
                    motor.grains.append(
                        supportedGrainTable[child.attrib['Type']]())
                    motor.grains[-1].setProperty(
                        'diameter', inToM(child.attrib['Diameter']))
                    motor.grains[-1].setProperty('length',
                                                 inToM(child.attrib['Length']))

                    grainType = child.attrib['Type']

                    if child.attrib['EndsInhibited'] == '1':
                        motor.grains[-1].setProperty('inhibitedEnds', 'Top')
                    elif child.attrib['EndsInhibited'] == '2':
                        motor.grains[-1].setProperty('inhibitedEnds', 'Both')

                    if grainType in ('1', '3',
                                     '7'):  # Grains with core diameter
                        motor.grains[-1].setProperty(
                            'coreDiameter',
                            inToM(child.attrib['CoreDiameter']))

                    if grainType == '2':  # D grain specific properties
                        motor.grains[-1].setProperty(
                            'slotOffset', inToM(child.attrib['EdgeOffset']))

                    elif grainType == '3':  # Moonburner specific properties
                        motor.grains[-1].setProperty(
                            'coreOffset', inToM(child.attrib['CoreOffset']))

                    elif grainType == '5':  # C grain specific properties
                        motor.grains[-1].setProperty(
                            'slotWidth', inToM(child.attrib['SlotWidth']))
                        radius = motor.grains[-1].getProperty('diameter') / 2
                        motor.grains[-1].setProperty(
                            'slotOffset',
                            radius - inToM(child.attrib['SlotDepth']))

                    elif grainType == '6':  # X core specific properties
                        motor.grains[-1].setProperty(
                            'slotWidth', inToM(child.attrib['SlotWidth']))
                        motor.grains[-1].setProperty(
                            'slotLength',
                            inToM(child.attrib['CoreDiameter']) / 2)

                    elif grainType == '7':  # Finocyl specific properties
                        motor.grains[-1].setProperty(
                            'finWidth', inToM(child.attrib['FinWidth']))
                        motor.grains[-1].setProperty(
                            'finLength', inToM(child.attrib['FinLength']))
                        motor.grains[-1].setProperty(
                            'numFins', int(child.attrib['FinCount']))

                    if not propSet:  # Use propellant numbers from the forward grain
                        impProp = child.find('Propellant')
                        propellant = motorlib.propellant()
                        propellant.setProperty('name', impProp.attrib['Name'])
                        n = float(impProp.attrib['BallisticN'])
                        a = float(impProp.attrib['BallisticA']) * 1 / (6895**n)
                        propellant.setProperty('n', n)
                        propellant.setProperty(
                            'a',
                            motorlib.convert(a, 'in/(s*psi^n)', 'm/(s*Pa^n)')
                        )  # Conversion only does in/s to m/s, the rest is handled above
                        propellant.setProperty(
                            'density',
                            motorlib.convert(float(impProp.attrib['Density']),
                                             'lb/in^3', 'kg/m^3'))
                        propellant.setProperty(
                            'k', float(impProp.attrib['SpecificHeatRatio']))
                        impMolarMass = impProp.attrib['MolarMass']
                        if impMolarMass == '0':
                            propellant.setProperty(
                                'm', 23.67
                            )  # If the user has entered 0, override it to match the default propellant.
                        else:
                            propellant.setProperty('m', float(impMolarMass))
                        propellant.setProperty(
                            't', 3500
                        )  # Burnsim doesn't provide this property. Set it to match the default propellant.
                        motor.propellant = propellant
                        propSet = True

                else:
                    if child.attrib['Type'] in unsupportedGrainTable:
                        errors += "File contains a " + unsupportedGrainTable[
                            child.attrib[
                                'Type']] + " grain, which can't be imported.\n"
                    else:
                        errors += "File contains an unknown grain of type " + child.attrib[
                            'Type'] + '.\n'

            if child.tag == 'TestData':
                errors += "\nFile contains test data, which is not imported."

        if errors != '':
            self.showWarning(errors +
                             '\nThe rest of the motor will be imported.')

        self.fileManager.startFromMotor(motor)
        return True
Exemple #10
0
    if '-h' in sys.argv:
        if len(sys.argv) < 3:
            print(
                'Not enough arguments. Headless mode requires an input file.')
        else:
            preferences = uilib.defaultPreferences()
            try:
                prefDict = uilib.loadFile('preferences.yaml',
                                          uilib.fileTypes.PREFERENCES)
                preferences.applyDict(prefDict)
            except:
                print('Preferences could not be loaded, using default')

            try:
                motorData = uilib.loadFile(sys.argv[-1], uilib.fileTypes.MOTOR)
                motor = motorlib.motor()
                motor.loadDict(motorData)
                simres = motor.runSimulation(preferences)
                for alert in simres.alerts:
                    print(motorlib.alertLevelNames[alert.level] + '(' +
                          motorlib.alertTypeNames[alert.type] + ', ' +
                          alert.location + '): ' + alert.description)
                print()
                if '-o' in sys.argv:
                    with open(sys.argv[sys.argv.index('-o') + 1],
                              'w') as outputFile:
                        outputFile.write(simres.getCSV(preferences))
                else:
                    print(simres.getCSV(preferences))
            except:
                print('Motor could not be loaded')