def __init__(self, inpParam=None, outParam=None, functionToCall=None, findmin=0, tolerance=1.0E-6, maxLoops=400, failValue=None): '''Initialize parameter properties @param inpParam: input parameter object (InputParam) @param outParam: output parameter object (OutputParam) @param functionToCall: function using InputParam to calc OutputParam (callable) @param findmin: findmin is a logic flag (1=minimize, 0=maximize) (int) @param tolerance: allowable error of OutputParam.val (float) @param maxLoops: maximum loops in root solver @param failValue: returned value if solution attempt fails, (if not input use inpParam.minVal) ''' self.inpParam = inpParam #: InputParam object self.outParam = outParam #: OutputParam object self.functionToCall = functionToCall #: function using InputParam to calc OutputParam self.findmin = floatDammit( findmin) #: flag to minimize or maximize OutputParam.val self.tolerance = floatDammit( tolerance) #: allowable error of OutputParam.val self.maxLoops = intDammit(maxLoops) #: maximum loops in root solver if failValue == None: failValue = inpParam.minVal self.failValue = failValue #: returned value if solution attempt fails
def __init__(self, inpParam=None, outParam=None, functionToCall=None, feasibleVal=0.0, tolerance=1.0E-6, maxLoops=40, failValue=None): '''Initialize parameter properties @param inpParam: input parameter object (InputParam) @param outParam: output parameter object (OutputParam) @param functionToCall: function using InputParam to calc OutputParam (callable) @param feasibleVal: feasible value that OutputParam Must have (float) @param tolerance: allowable error of OutputParam.val (float) @param maxLoops: maximum loops in root solver @param failValue: returned value if solution attempt fails, (if not input use inpParam.minVal) ''' self.inpParam = inpParam #: InputParam object self.outParam = outParam #: OutputParam object self.functionToCall = functionToCall #: function using InputParam to calc OutputParam self.feasibleVal = floatDammit(feasibleVal) #: feasable value of OutputParam.val self.tolerance = floatDammit(tolerance) #: allowable error of OutputParam.val self.maxLoops = intDammit(maxLoops) #: maximum loops in root solver if failValue==None: failValue = inpParam.minVal self.failValue = failValue #: returned value if solution attempt fails self.G = Goal(goalVal=feasibleVal, minX=inpParam.minVal, maxX=inpParam.maxVal, funcOfX=self.feasibleFunc, tolerance=tolerance, maxLoops=maxLoops, failValue=failValue)
def __init__(self, name='a', description='speed of sound', units='ft/sec', val=1.0, minVal=0.0, maxVal=10.0, NSteps=10, stepVal=None, linear=1): '''Initialize parameter properties and calculate range list (rangeL) @param name: simple name (str) @param description: long description (str) @param units: physical units; Blank string if no units (str) @param val: current numeric value (float) @param minVal: minimum value (float) @param maxVal: maximum value (float) @param NSteps: number of steps from minVal to maxVal in rangeL (int) @param stepVal: if input, then step size from minVal to maxVal in rangeL (float) @param linear: linear/geometric flag for steps from minVal to maxVal (boolean or int) ''' # if minVal, maxVal are reversed, correct them if minVal > maxVal: minVal, maxVal = maxVal, minVal self.name = name #: simple name self.description = description #: long description self.units = units #: physical units; Blank string if no units self.val = floatDammit(val) #: current numeric value self.savedVal = self.val #: temporary storage location for val self.InitialVal = self.val #: initial val (for possible reset) self.minVal = floatDammit(minVal) #: minimum value self.maxVal = floatDammit(maxVal) #: maximum value self.linear = intDammit(linear) #: linear/geometric flag for steps from minVal to maxVal if NSteps<1: NSteps=1 if stepVal and linear: #use stepVal only if linear steps try: NSteps = int( (maxVal-minVal)/stepVal ) except: stepVal = (maxVal-minVal)/float(NSteps) else: stepVal = (maxVal-minVal)/float(NSteps) self.NSteps = NSteps #: number of steps from minVal to maxVal in rangeL self.stepVal = stepVal #: if input, then step size from minVal to maxVal in rangeL if linear : self.buildLinearRange() else: try: self.buildGeometricRange() self.stepVal = None #: undefined if using geometric range except: # only annoy the user slightly with non-critical error print 'WARNING... Switched to linear range in parameters.InputParam for min/max=%g/%g'%(self.minVal,self.maxVal) self.buildLinearRange() # make scaleFactor for other modules to use (e.g. optimize) self.scaleFactor = (abs(self.minVal) + abs(self.maxVal)) / 2.0
def __init__(self, inpParam=None, outParam=None, functionToCall=None, feasibleVal=0.0, tolerance=1.0E-6, maxLoops=40, failValue=None): '''Initialize parameter properties @param inpParam: input parameter object (InputParam) @param outParam: output parameter object (OutputParam) @param functionToCall: function using InputParam to calc OutputParam (callable) @param feasibleVal: feasible value that OutputParam Must have (float) @param tolerance: allowable error of OutputParam.val (float) @param maxLoops: maximum loops in root solver @param failValue: returned value if solution attempt fails, (if not input use inpParam.minVal) ''' self.inpParam = inpParam #: InputParam object self.outParam = outParam #: OutputParam object self.functionToCall = functionToCall #: function using InputParam to calc OutputParam self.feasibleVal = floatDammit( feasibleVal) #: feasable value of OutputParam.val self.tolerance = floatDammit( tolerance) #: allowable error of OutputParam.val self.maxLoops = intDammit(maxLoops) #: maximum loops in root solver if failValue == None: failValue = inpParam.minVal self.failValue = failValue #: returned value if solution attempt fails self.G = Goal(goalVal=feasibleVal, minX=inpParam.minVal, maxX=inpParam.maxVal, funcOfX=self.feasibleFunc, tolerance=tolerance, maxLoops=maxLoops, failValue=failValue)
def __init__(self, inpParam=None, outParam=None, functionToCall=None, findmin=0, tolerance=1.0E-6, maxLoops=400, failValue=None): '''Initialize parameter properties @param inpParam: input parameter object (InputParam) @param outParam: output parameter object (OutputParam) @param functionToCall: function using InputParam to calc OutputParam (callable) @param findmin: findmin is a logic flag (1=minimize, 0=maximize) (int) @param tolerance: allowable error of OutputParam.val (float) @param maxLoops: maximum loops in root solver @param failValue: returned value if solution attempt fails, (if not input use inpParam.minVal) ''' self.inpParam = inpParam #: InputParam object self.outParam = outParam #: OutputParam object self.functionToCall = functionToCall #: function using InputParam to calc OutputParam self.findmin = floatDammit(findmin) #: flag to minimize or maximize OutputParam.val self.tolerance = floatDammit(tolerance) #: allowable error of OutputParam.val self.maxLoops = intDammit(maxLoops) #: maximum loops in root solver if failValue==None: failValue = inpParam.minVal self.failValue = failValue #: returned value if solution attempt fails
def __init__(self, name='a', description='speed of sound', units='ft/sec', val=1.0, minVal=0.0, maxVal=10.0, NSteps=10, stepVal=None, linear=1): '''Initialize parameter properties and calculate range list (rangeL) @param name: simple name (str) @param description: long description (str) @param units: physical units; Blank string if no units (str) @param val: current numeric value (float) @param minVal: minimum value (float) @param maxVal: maximum value (float) @param NSteps: number of steps from minVal to maxVal in rangeL (int) @param stepVal: if input, then step size from minVal to maxVal in rangeL (float) @param linear: linear/geometric flag for steps from minVal to maxVal (boolean or int) ''' # if minVal, maxVal are reversed, correct them if minVal > maxVal: minVal, maxVal = maxVal, minVal self.name = name #: simple name self.description = description #: long description self.units = units #: physical units; Blank string if no units self.val = floatDammit(val) #: current numeric value self.savedVal = self.val #: temporary storage location for val self.InitialVal = self.val #: initial val (for possible reset) self.minVal = floatDammit(minVal) #: minimum value self.maxVal = floatDammit(maxVal) #: maximum value self.linear = intDammit( linear) #: linear/geometric flag for steps from minVal to maxVal if NSteps < 1: NSteps = 1 if stepVal and linear: #use stepVal only if linear steps try: NSteps = int((maxVal - minVal) / stepVal) except: stepVal = (maxVal - minVal) / float(NSteps) else: stepVal = (maxVal - minVal) / float(NSteps) self.NSteps = NSteps #: number of steps from minVal to maxVal in rangeL self.stepVal = stepVal #: if input, then step size from minVal to maxVal in rangeL if linear: self.buildLinearRange() else: try: self.buildGeometricRange() self.stepVal = None #: undefined if using geometric range except: # only annoy the user slightly with non-critical error print 'WARNING... Switched to linear range in parameters.InputParam for min/max=%g/%g' % ( self.minVal, self.maxVal) self.buildLinearRange() # make scaleFactor for other modules to use (e.g. optimize) self.scaleFactor = (abs(self.minVal) + abs(self.maxVal)) / 2.0
def optimize(PS, figureOfMerit="mass_lbm", desVars=None, findmin=1, MaxLoop=500, printLevel=1): '''to find max, set findmin = 0''' PS.firstEvaluateIfReqd() global optFSys, _optLoopCount, _findmin, _constraintLoopCount optFSys = PS _optLoopCount = 0 _constraintLoopCount = 0 _findmin = findmin # use global flag in objective function PS.figureOfMerit = figureOfMerit PS.optDesVars = [] for dvStr in desVars: dv = PS.desVarDict[dvStr] if PS.hasFeasibleControlVar( dv.name ): print 'WARNING... %s is a feasible design variable\n It can NOT be used as an optimization variable.'%dvStr pass else: PS.optDesVars.append( dvStr ) #PS.summFile.write('\nPRIOR TO OPTIMIZATION\n') if _findmin: mLabel = 'MINIMIZE' else: mLabel = 'MAXIMIZE' if printLevel: saveOptVarSummary(PS, PS.optDesVars,'\nPRIOR TO %s OPTIMIZATION\n'%mLabel) ndv = len( PS.optDesVars ) ncon = 0 if ndv <= 0: print "ERROR... there are no legal design variables for optimization" return xlow=[] xhigh=[] xinit = [] # get limits of design variables i = 0 for dvStr in PS.optDesVars: dv = PS.desVarDict[dvStr] xlow.append( dv.minVal / dv.scaleFactor ) xhigh.append( dv.maxVal / dv.scaleFactor ) xinit.append( PS.getDesignVar( dvStr) / dv.scaleFactor ) i += 1 # count any result variables that might be constraints PS.constraintList[:] = [] for key,rv in PS.resultVarDict.items(): # only handle inequality constraints, equality constraints handled by feasibility variables if rv.hasLowConstraint() : PS.constraintList.append( ['>',key] ) ncon += 1 if rv.hasHighConstraint(): PS.constraintList.append( ['<',key] ) ncon += 1 #xOut = mdot.findminormax(findmin,ndv,ncon,MaxLoop, xlow,xhigh,xinit,objAndConstraints) # set up constraint calling functions cons = [] # first do bounds on x array def makeLo(n): return lambda x: x[n] - xlow[n] def makeHi(n): return lambda x: xhigh[n] - x[n] for n in range( len(xlow) ): conLo = makeLo(n) conHi = makeHi(n) cons.append( conLo ) cons.append( conHi ) # then do any constraints on result variables def makeCon(n): return lambda x: constraintFunc(x, n) for n in range( len(PS.constraintList) ): con = makeCon(n) cons.append( con ) # rhobeg can be 1.0 because x values are scaled. xOut = fmin_cobyla(objFunction, xinit, cons, rhobeg=1.0, rhoend=1e-6, iprint=cast.intDammit(printLevel), maxfun=MaxLoop) if printLevel: print print " ==> OPTIMIZATION (Loops = %i)"%_optLoopCount, "(Max = %g)"%MaxLoop, print " (%i constraint loops)\n"%_constraintLoopCount for i in range( len(PS.optDesVars) ): dvStr = PS.optDesVars[i] dv = PS.desVarDict[ dvStr ] dvVal = xOut[i] * dv.scaleFactor if printLevel: print 'optimum',dvStr,'=',dvVal #PS.summFile.write( '\noptimum %10s = %g'%(dvStr, dvVal) ) if printLevel: print '\nscaled desVars',PS.optDesVars,'=',xOut[:ndv] print 'gives',figureOfMerit,'=',PS.getResultVar(figureOfMerit),'\n' #PS.summFile.write('\n\ngives '+ str(figureOfMerit)+\ # ' = '+ str(PS.getResultVar(figureOfMerit))+'\n') for i in range(ndv): dvStr = PS.optDesVars[i] dv = PS.desVarDict[ dvStr ] dvVal = xOut[i] * dv.scaleFactor PS.setDesignVar( dvStr, dvVal) PS.evaluate() #PS.summFile.write('\nAFTER OPTIMIZATION\n') if printLevel: saveOptVarSummary(PS, PS.optDesVars,'\nAFTER %s OPTIMIZATION\n'%mLabel)
def optimize(PS, figureOfMerit="mass_lbm", desVars=None, findmin=1, MaxLoop=500, printLevel=1): '''to find max, set findmin = 0''' PS.firstEvaluateIfReqd() global optFSys, _optLoopCount, _findmin, _constraintLoopCount optFSys = PS _optLoopCount = 0 _constraintLoopCount = 0 _findmin = findmin # use global flag in objective function PS.figureOfMerit = figureOfMerit PS.optDesVars = [] for dvStr in desVars: dv = PS.desVarDict[dvStr] if PS.hasFeasibleControlVar(dv.name): print 'WARNING... %s is a feasible design variable\n It can NOT be used as an optimization variable.' % dvStr pass else: PS.optDesVars.append(dvStr) #PS.summFile.write('\nPRIOR TO OPTIMIZATION\n') if _findmin: mLabel = 'MINIMIZE' else: mLabel = 'MAXIMIZE' if printLevel: saveOptVarSummary(PS, PS.optDesVars, '\nPRIOR TO %s OPTIMIZATION\n' % mLabel) ndv = len(PS.optDesVars) ncon = 0 if ndv <= 0: print "ERROR... there are no legal design variables for optimization" return xlow = [] xhigh = [] xinit = [] # get limits of design variables i = 0 for dvStr in PS.optDesVars: dv = PS.desVarDict[dvStr] xlow.append(dv.minVal / dv.scaleFactor) xhigh.append(dv.maxVal / dv.scaleFactor) xinit.append(PS.getDesignVar(dvStr) / dv.scaleFactor) i += 1 # count any result variables that might be constraints PS.constraintList[:] = [] for key, rv in PS.resultVarDict.items(): # only handle inequality constraints, equality constraints handled by feasibility variables if rv.hasLowConstraint(): PS.constraintList.append(['>', key]) ncon += 1 if rv.hasHighConstraint(): PS.constraintList.append(['<', key]) ncon += 1 #xOut = mdot.findminormax(findmin,ndv,ncon,MaxLoop, xlow,xhigh,xinit,objAndConstraints) # set up constraint calling functions cons = [] # first do bounds on x array def makeLo(n): return lambda x: x[n] - xlow[n] def makeHi(n): return lambda x: xhigh[n] - x[n] for n in range(len(xlow)): conLo = makeLo(n) conHi = makeHi(n) cons.append(conLo) cons.append(conHi) # then do any constraints on result variables def makeCon(n): return lambda x: constraintFunc(x, n) for n in range(len(PS.constraintList)): con = makeCon(n) cons.append(con) # rhobeg can be 1.0 because x values are scaled. xOut = fmin_cobyla(objFunction, xinit, cons, rhobeg=1.0, rhoend=1e-6, iprint=cast.intDammit(printLevel), maxfun=MaxLoop) if printLevel: print print " ==> OPTIMIZATION (Loops = %i)" % _optLoopCount, "(Max = %g)" % MaxLoop, print " (%i constraint loops)\n" % _constraintLoopCount for i in range(len(PS.optDesVars)): dvStr = PS.optDesVars[i] dv = PS.desVarDict[dvStr] dvVal = xOut[i] * dv.scaleFactor if printLevel: print 'optimum', dvStr, '=', dvVal #PS.summFile.write( '\noptimum %10s = %g'%(dvStr, dvVal) ) if printLevel: print '\nscaled desVars', PS.optDesVars, '=', xOut[:ndv] print 'gives', figureOfMerit, '=', PS.getResultVar(figureOfMerit), '\n' #PS.summFile.write('\n\ngives '+ str(figureOfMerit)+\ # ' = '+ str(PS.getResultVar(figureOfMerit))+'\n') for i in range(ndv): dvStr = PS.optDesVars[i] dv = PS.desVarDict[dvStr] dvVal = xOut[i] * dv.scaleFactor PS.setDesignVar(dvStr, dvVal) PS.evaluate() #PS.summFile.write('\nAFTER OPTIMIZATION\n') if printLevel: saveOptVarSummary(PS, PS.optDesVars, '\nAFTER %s OPTIMIZATION\n' % mLabel)