def test_optimizationContinuation(self):
        definitionPath = "MAPLEAF/Examples/Simulations/InitializedOptimization.mapleaf"
        simDef = SimDefinition(definitionPath, silent=True)

        # Make the optimization use a single particle, single iteration, and only a single time step
        simDef.setValue('Optimization.ParticleSwarm.nParticles', '1')
        simDef.setValue('Optimization.ParticleSwarm.nIterations', '1')
        simDef.setValue('SimControl.EndCondition', 'Time')
        simDef.setValue('SimControl.EndConditionValue', '0.005')
        simDef.setValue('Optimization.showConvergencePlot', 'False')

        opt = optimizationRunnerFactory(simDefinition=simDef, silent=True)
        cost, pos = opt.runOptimization()

        # Make sure the position matches the specified initial position
        self.assertAlmostEqual(pos, 0.1)

        # Make sure a continue file has been created
        continuationPath = definitionPath.replace('.mapleaf',
                                                  '_continue.mapleaf')
        self.assertTrue(os.path.isfile(continuationPath))

        # Check that it can be run
        restartDefinition = SimDefinition(continuationPath)
        opt = optimizationRunnerFactory(simDefinition=restartDefinition,
                                        silent=True)
        opt.runOptimization()

        # Clean up files
        os.remove(continuationPath)
        secondContinuationPath = continuationPath.replace(
            '.mapleaf', '_continue.mapleaf')
        os.remove(secondContinuationPath)
    def test_PSOOptimization(self):
        simDef = SimDefinition(
            "MAPLEAF/Examples/Simulations/Optimization.mapleaf", silent=True)
        optSimRunner = optimizationRunnerFactory(simDefinition=simDef,
                                                 silent=True)

        # Check output of _loadIndependentVariables()
        self.assertEqual(optSimRunner.varKeys,
                         ["Rocket.Sustainer.UpperBodyTube.mass"])
        self.assertEqual(optSimRunner.varNames, ["bodyWeight"])
        self.assertEqual(optSimRunner.minVals, [0.01])
        self.assertEqual(optSimRunner.maxVals, [0.2])

        # Check out of _loadDependentVariables()
        self.assertEqual(optSimRunner.dependentVars,
                         ["Rocket.Sustainer.Nosecone.mass"])
        self.assertEqual(optSimRunner.dependentVarDefinitions,
                         ["!0.007506 + 0.015/bodyWeight!"])

        # Check output of _createOptimizer()
        self.assertEqual(optSimRunner.nIterations, 20)
        self.assertEqual(optSimRunner.showConvergence, True)
        self.assertEqual(optSimRunner.optimizer.n_particles, 5)

        # Check updating independent variable values
        indVarDict = optSimRunner._updateIndependentVariableValues(
            simDef, [0.15])
        self.assertEqual(
            simDef.getValue("Rocket.Sustainer.UpperBodyTube.mass"), "0.15")
        self.assertEqual(indVarDict, {"bodyWeight": 0.15})

        # Check updating dependent variables values
        optSimRunner._updateDependentVariableValues(simDef, indVarDict)
        self.assertAlmostEqual(
            float(simDef.getValue("Rocket.Sustainer.Nosecone.mass")), 0.107506)
def runOptimization(simDef):
    # Make the optimization perform a single iteration of a simulation with only a single time step
    simDef.setValue('Optimization.ScipyMinimize.maxIterations', '1')
    simDef.setValue('Optimization.method',
                    'scipy.optimize.minimize Nelder-Mead')
    simDef.setValue('SimControl.EndCondition', 'Time')
    simDef.setValue('SimControl.EndConditionValue', '0.005')
    simDef.setValue('Optimization.showConvergencePlot', 'False')

    optSimRunner = optimizationRunnerFactory(simDefinition=simDef, silent=True)
    optSimRunner.runOptimization()
    def test_readInitialParticlePositions(self):
        simDef = SimDefinition(
            "MAPLEAF/Examples/Simulations/InitializedOptimization.mapleaf",
            silent=True)
        opt = optimizationRunnerFactory(simDefinition=simDef, silent=True)

        # Check that initial position has been loaded
        bW1 = opt.initPositions[0][0]
        self.assertAlmostEqual(bW1, 0.1)

        # Check that the other initial position has been generated and is inside the expected bands
        bW2 = opt.initPositions[1][0]
        self.assertGreaterEqual(bW2, 0.01)
        self.assertLessEqual(bW2, 0.2)

        # Check that additional unexpected variables cause a crash
        extraVariableKey = 'Optimization.IndependentVariables.InitialParticlePositions.p1.extraVariable'
        with self.assertRaises(ValueError):
            simDef.setValue(extraVariableKey, '25')
            opt = optimizationRunnerFactory(simDefinition=simDef, silent=True)

        simDef.removeKey(extraVariableKey)

        # Check that an out of bounds value causes a crash
        with self.assertRaises(ValueError):
            simDef.setValue(
                'Optimization.IndependentVariables.InitialParticlePositions.p1.bodyWeight',
                '0.21')
            opt = optimizationRunnerFactory(simDefinition=simDef, silent=True)

        # Check that specifying the position of too many particles causes a crash
        with self.assertRaises(ValueError):
            simDef.setValue(
                'Optimization.IndependentVariables.InitialParticlePositions.p2.bodyWeight',
                '0.15')
            simDef.setValue(
                'Optimization.IndependentVariables.InitialParticlePositions.p3.bodyWeight',
                '0.15')
            opt = optimizationRunnerFactory(simDefinition=simDef, silent=True)
    def test_nestedOptimization(self):
        simDef = SimDefinition(
            "MAPLEAF/Examples/Simulations/MultiLoopOptimization.mapleaf",
            silent=True)
        outerSimRunner = optimizationRunnerFactory(simDefinition=simDef,
                                                   silent=True)
        innerSimRunner = outerSimRunner._createNestedOptimization(simDef)
        # Check output of _loadIndependentVariables()
        self.assertEqual(innerSimRunner.varKeys,
                         ["Rocket.Sustainer.GeneralMass.mass"])
        self.assertEqual(innerSimRunner.varNames, ["GeneralMass"])
        self.assertEqual(innerSimRunner.minVals, [0.0045])
        self.assertEqual(innerSimRunner.maxVals, [0.01])

        # Check out of _loadDependentVariables()
        self.assertEqual(innerSimRunner.dependentVars,
                         ["Rocket.Sustainer.AltimeterMass.mass"])
        self.assertEqual(innerSimRunner.dependentVarDefinitions,
                         ["!0.01 + 0.0000475/GeneralMass!"])

        # Check output of _createOptimizer()
        self.assertEqual(innerSimRunner.nIterations, 5)
        self.assertEqual(innerSimRunner.showConvergence, False)
        self.assertEqual(innerSimRunner.optimizer.n_particles, 2)

        # Check updating independent variable values
        indVarDict = innerSimRunner._updateIndependentVariableValues(
            simDef, [0.15])
        self.assertEqual(simDef.getValue("Rocket.Sustainer.GeneralMass.mass"),
                         "0.15")
        self.assertEqual(indVarDict, {"GeneralMass": 0.15})

        # Check updating dependent variables values
        innerSimRunner._updateDependentVariableValues(simDef, indVarDict)
        self.assertAlmostEqual(
            float(simDef.getValue("Rocket.Sustainer.AltimeterMass.mass")),
            0.010316666667)
Exemple #6
0
def main(argv=None) -> int:
    ''' 
        Main function to run a MAPLEAF simulation. 
        Expects to be called from the command line, usually using the `mapleaf` command
        
        For testing purposes, can also pass a list of command line arguments into the argv parameter
    '''
    startTime = time.time()

    # Parse command line call, check for errors
    parser = buildParser()
    args = parser.parse_args(argv)

    if len(args.plotFromLog):
        # Just plot a column from a log file, and not run a whole simulation
        Plotting.plotFromLogFiles([args.plotFromLog[1]], args.plotFromLog[0])
        print("Exiting")
        sys.exit()

    # Load simulation definition file
    simDefPath = findSimDefinitionFile(args.simDefinitionFile)
    simDef = SimDefinition(simDefPath)

    #### Run simulation(s) ####
    if args.parallel:
        try:
            import ray
        except:
            print("""
            Error importing ray. 
            Ensure ray is installed (`pip install -U ray`) and importable (`import ray` should not throw an error). 
            If on windows, consider trying Linux or running in WSL, at the time this was written, ray on windows was still in beta and unreliable.
            Alternatively, run without parallelization.
            """)

    if isOptimizationProblem(simDef):
        optSimRunner = optimizationRunnerFactory(simDefinition=simDef,
                                                 silent=args.silent,
                                                 parallel=args.parallel)
        optSimRunner.runOptimization()

    elif isMonteCarloSimulation(simDef):
        if not args.parallel:
            nCores = 1
        else:
            import multiprocessing
            nCores = multiprocessing.cpu_count()

        runMonteCarloSimulation(simDefinition=simDef,
                                silent=args.silent,
                                nCores=nCores)

    elif args.parallel:
        raise ValueError(
            "ERROR: Can only run Monte Carlo of Optimization-type simulations in multi-threaded mode. Support for multi-threaded batch simulations coming soon."
        )

    elif isBatchSim(simDef):
        print("Batch Simulation\n")
        batchMain([simDef.fileName])

    elif args.converge or args.compareIntegrationSchemes or args.compareAdaptiveIntegrationSchemes:
        cSimRunner = ConvergenceSimRunner(simDefinition=simDef,
                                          silent=args.silent)
        if args.converge:
            cSimRunner.convergeSimEndPosition()
        elif args.compareIntegrationSchemes:
            cSimRunner.compareClassicalIntegrationSchemes(
                convergenceResultFilePath='convergenceResult.csv')
        elif args.compareAdaptiveIntegrationSchemes:
            cSimRunner.compareAdaptiveIntegrationSchemes(
                convergenceResultFilePath='adaptiveConvergenceResult.csv')

    else:
        # Run a regular, single simulation
        sim = Simulation(simDefinition=simDef, silent=args.silent)
        sim.run()

    Logging.removeLogger()

    print("Run time: {:1.2f} seconds".format(time.time() - startTime))
    print("Exiting")
 def test_BatchOptimization(self):
     simDef = SimDefinition(
         "MAPLEAF/Examples/Simulations/CanardsOptimization.mapleaf")
     simRunner = optimizationRunnerFactory(simDefinition=simDef,
                                           silent=True)