def integratorFactory(integrationMethod="Euler", simDefinition=None, discardedTimeStepCallback=None): ''' Returns a callable integrator object Inputs: * integrationMethod: (str) Name of integration method: Examples = "Euler", "RK4", "RK23Adaptive", and "RK45Adaptive" * simDefinition: (`MAPLEAF.IO.SimDefinition`) for adaptive integration, provide a simdefinition file with time step adaptation parameters * discardedTimeStepCallback: (1-argument function reference) for adaptive integration, this function (if provided) is called when a time step is computed, but then discarded and re-computed with a smaller timestep to remain below the max estimated error threshold. Used by MAPLEAF to remove force calculation logs from those discarded time steps ''' if "Adapt" in integrationMethod: if simDefinition == None: raise ValueError("SimDefinition object required to initialize adaptive integrator") from MAPLEAF.IO import SubDictReader adaptDictReader = SubDictReader("SimControl.TimeStepAdaptation", simDefinition) # Adaptive Integration controller = adaptDictReader.getString("controller") if controller == "PID": PIDCoeffs = [ float(x) for x in adaptDictReader.getString("PID.coefficients").split() ] safetyFactor = None elif controller == "elementary": safetyFactor = adaptDictReader.getFloat("Elementary.safetyFactor") PIDCoeffs = None targetError = adaptDictReader.getFloat("targetError") minFactor = adaptDictReader.getFloat("minFactor") maxFactor = adaptDictReader.getFloat("maxFactor") maxTimeStep = adaptDictReader.getFloat("maxTimeStep") minTimeStep = adaptDictReader.getFloat("minTimeStep") return AdaptiveIntegrator( method=integrationMethod, controller=controller, targetError=targetError, maxMinSafetyFactors=[maxFactor, minFactor, safetyFactor], PIDCoeffs=PIDCoeffs, maxTimeStep=maxTimeStep, minTimeStep=minTimeStep, discardedTimeStepCallback=discardedTimeStepCallback ) else: # Constant time step integrator return ClassicalIntegrator(method=integrationMethod)
def rocketComponentFactory(subDictPath, rocket, stage): """ Initializes a rocket component based on the stringNameToClassMap Inputs: subDictPath: (string) Path to subDict in simulation definition, like "Rocket.Stage1.Nosecone" rocket: (Rocket) that the component is a part of stage: (Stage) That the component is a part of Also uses the stringNameToClassMap dictionary """ # Create SubDictReader for the rocket component's dictionary componentDictReader = SubDictReader(subDictPath, rocket.simDefinition) # Figure out which class to initialize className = componentDictReader.getString("class") referencedClass = stringNameToClassMap[className] # Initialize the rocket component newComponent = referencedClass(componentDictReader, rocket, stage) # Initialize logging component forces (if desired) initializeForceLogging(newComponent, subDictPath, rocket) return newComponent