def GenerateLiftingSurface(self, ChordFactor, ScaleFactor, OptimizeChordScale=0): # This is the main method of this class. It builds a lifting surface # (wing, tailplane, etc.) with the given ChordFactor and ScaleFactor or # an optimized ChordFactor and ScaleFactor, with the local search started # from the two given values. x0 = [ChordFactor, ScaleFactor] if OptimizeChordScale: self._CheckOptParCorrectlySpec() self._NormaliseWeightings() self._PrintTargetsAndWeights() print("Optimizing scale factors...") # An iterative local hillclimber type optimizer is needed here. One # option might be SciPy's fmin as below: # x0, fopt, iter, funcalls, warnflag, allvecs = scipy.optimize.fmin(self._LSObjective, x0, retall=True, xtol=0.025, full_output=True) # However, SciPy is not supported on 64-bit Rhino installations, so # so here we use an alternative: a simple evoltionary optimizer # included with AirCONICS_tools. MaxIter = 50 xtol = 0.025 deltax = [x0[0]*0.25,x0[1]*0.25] x0, fopt = act.boxevopmin2d(self._LSObjective, x0, deltax, xtol, MaxIter) x0[0] = abs(x0[0]) x0[1] = abs(x0[1]) print("Optimum chord factor %5.3f, optimum scale factor %5.3f" % (x0[0], x0[1])) LS, ActualSemiSpan, LSP_area, RootChord, AR, WingTip = self._BuildLS(x0[0], x0[1]) self._ClearConstructionGeometry() # Moving the wing into position AP = rs.AddPoint(self.ApexPoint) MoveVec = rs.VectorCreate(AP, (0,0,0)) rs.MoveObject(LS, MoveVec) if WingTip: rs.MoveObject(WingTip, MoveVec) rs.DeleteObject(AP) # FINAL REPORT ON THE COMPLETED SURFACE SA = rs.SurfaceArea(LS) print("Wing complete. Key features (all related to both wings):") print("Proj.area: %5.4f Wet.area: %5.4f Span:%5.4f Aspect ratio: %5.4f Root chord: %5.4f" % (2*LSP_area, 2.0*SA[0], 2.0*ActualSemiSpan, AR, RootChord)) return LS, ActualSemiSpan, LSP_area, RootChord, AR, WingTip