Пример #1
0
def example(owExe):

    debug = True  # set True so user sees final 'break' message
    start_once = False
    modify_turbine = False
    opt_log = False
    extOpt = False

    for arg in sys.argv[1:]:
        if arg == '-debug':
            debug = True
        if arg == '-once':
            start_once = True
        if arg == '-log':
            opt_log = True
        if arg == '-modturb':
            modify_turbine = True
        if arg == '-extopt':
            extOpt = True
        if arg == '-help':
            sys.stderr.write(
                'USAGE: python openWindComponent.py [-once] [-debug] [-modturb] [-extopt]\n'
            )
            exit()

    # Find OpenWind executable
    if not os.path.isfile(owExe):
        sys.stderr.write(
            'OpenWind executable file "{:}" not found\n'.format(owExe))
        exit()

    # set the external optimiser flag to extOpt:
    #    True : can use our optimizing routines
    acutils.owIniSet(owExe, extVal=extOpt, debug=True)

    # If we are not externally optimizing, we can start OW once and let it run to completion

    if not extOpt:
        start_once = True

    # Set OpenWind script name
    testpath = 'templates/'
    #owXMLname = testpath + 'rtecScript.xml' # replace turb, energy capture #KLD - this script does not work for me with this component
    owXMLname = testpath + 'owScript.xml'  # optimize operation
    #owXMLname = testpath + 'rtopScript.xml' # replace turb, optimize

    if modify_turbine:
        owXMLname = testpath + 'rtopScript.xml'  # replace turb, optimize

    if not os.path.isfile(owXMLname):
        sys.stderr.write(
            'OpenWind script file "{:}" not found\n'.format(owXMLname))
        exit()

    dscript = rwScriptXML.rdScript(owXMLname,
                                   debug=debug)  # Show our operations
    workbook = dscript['workbook']

    # default turbine positions and size of translation

    wt_positions = [[456000.00, 4085000.00], [456500.00, 4085000.00]]
    deltaX = 3000.0
    deltaY = -2000.0
    #deltaX =  200.0
    #deltaY = -200.0
    deltaX = 3.000
    deltaY = -2.000

    # Read turbine positions from workbook
    if debug:
        sys.stderr.write(
            'Getting turbine positions from {:}\n'.format(workbook))
    wb = acutils.WTWkbkFile(wkbk=workbook, owexe=owExe)
    wt_positions = wb.xy
    if debug:
        sys.stderr.write('Got {:} turbine positions\n'.format(
            len(wt_positions)))

    # Initialize OWcomp component
    ow = OWcomp(owExe=owExe,
                debug=debug,
                scriptFile=owXMLname,
                extOpt=extOpt,
                start_once=start_once,
                opt_log=opt_log)  #, stopOW=False)

    if not ow.scriptOK:
        sys.stderr.write("\n*** ERROR found in script file\n\n")
        exit()

    # starting point for turbine mods
    #wt_list_elem = dummy_wt_list()
    base_turbine_file = testpath + 'NREL5MW.owtg'
    wt_list_elem = turbfuncs.owtg_to_wtpc(base_turbine_file)

    if not extOpt:
        # If we're not optimizing externally, run ow and return

        ow.execute()

        print '\nFinal values'
        owd = ow.dump()
        print '  {:}'.format(owd)
        print '-' * 40, '\n'

        return

    # external optimization

    ow.wt_layout.wt_list = [wt_list_elem for i in range(len(wt_positions))]
    if debug:
        sys.stderr.write('Initialized {:} turbines in wt_layout\n'.format(
            len(wt_positions)))

    # With each iteration
    #   move turbines farther offshore
    #   possibly modify the turbine rotor diam and power curve and replace turbine

    if debug:
        ofh = open('wtp.txt', 'w')

    for irun in range(1, 4):
        for i in range(len(wt_positions)):
            wt_positions[i][0] += deltaX
            wt_positions[i][1] += deltaY
            if debug:
                ofh.write('{:2d} {:3d} {:.1f} {:.1f}\n'.format(
                    irun, i, wt_positions[i][0], wt_positions[i][1]))
        ow.wt_layout.wt_positions = wt_positions

        # modify the turbine
        ow.rotor_diameter += 1.0
        if ow.replace_turbine:
            wt_list_elem = ow.wt_layout.wt_list[0]
            wt_list_elem.power_rating *= 1.05
            for i in range(len(wt_list_elem.power_curve)):
                wt_list_elem.power_curve[i][1] *= 1.05
            ow.wt_layout.wt_list = [
                wt_list_elem for i in range(len(ow.wt_layout.wt_list))
            ]
            if debug:
                ofh.write('Updated {:} turbines with:\n'.format(
                    len(ow.wt_layout.wt_list)))
                ofh.write(turbfuncs.wtpc_dump(ow.wt_layout.wt_list[0]))

        ow.execute()  # run the openWind process

        print '\nFinal values'
        owd = ow.dump()
        print '  {:}'.format(owd)
        print '-' * 40, '\n'

    if start_once:
        ow.terminateOW()
Пример #2
0
    def execute(self):
        """ Executes our component. """

        if self.debug:
            sys.stderr.write("In {0}.execute() {1}...\n".format(
                self.__class__, self.script_file))

        if (len(self.resname) < 1):
            sys.stderr.write(
                '\n*** ERROR: OWcomp results file name not assigned! (problem with script file?)\n\n'
            )
            return False

        # Prepare input file here
        #   - write a new script file?
        #   - write a new turbine file to overwrite the one referenced
        #       in the existing script_file?

        # If there is a turbine replacement operation in the script:
        #   write new turbine description file based on contents of first turbine in layout

        #if 'replturbpath' in self.scriptDict:
        if self.replace_turbine:
            if len(self.wt_layout.wt_list) < 1:
                sys.stderr.write(
                    '\n*** ERROR ***  OWcomp::execute(): no turbines in wt_layout!\n\n'
                )
                return False
            if self.debug:
                sys.stderr.write('Replacement turbine parameters:\n')
                #sys.stderr.write('{:}\n'.format(turbfuncs.wtpc_dump(self.wt_layout.wt_list[0])))
                sys.stderr.write('{:}\n'.format(
                    turbfuncs.wtpc_dump(self.wt_layout.wt_list[0],
                                        shortFmt=True)))
                #sys.stderr.write('{:}\n'.format(wtlDump(self.wt_layout.wt_list[0])))

            newXML = turbfuncs.wtpc_to_owtg(self.wt_layout.wt_list[0],
                                            trbname='ReplTurb',
                                            desc='OWcomp replacement turbine')
            if len(newXML) > 50:
                tfname = self.scriptDict[
                    'replturbpath']  # this is the file that will be overwritten with new turbine parameters
                tfh = open(tfname, 'w')
                tfh.write(newXML)
                tfh.close()
                maxPower = self.wt_layout.wt_list[0].power_rating
                if self.debug:
                    sys.stderr.write(
                        'Wrote new turbine file to {:} (rated pwr {:.2f} MW\n'.
                        format(tfname, maxPower * 0.000001))
            else:
                sys.stderr.write('*** NO new turbine file written\n')

        # Execute the component and save process ID
        if not self.start_once:
            self.proc = subprocess.Popen(self.command)
            self.pid = self.proc.pid
            if self.debug:
                sys.stderr.write('Started OpenWind with pid {:}\n'.format(
                    self.pid))
                sys.stderr.write('  OWComp: dummyVbl {:}\n'.format(
                    self.dummyVbl))
                #sys.stderr.write('Report Path: {:}\n'.format(self.rptpath))

            # Watch for 'results.txt', meaning that OW has run once with the default locations

            if self.debug:
                sys.stderr.write(
                    'OWComp waiting for {:} (first run -  positions unchanged)\n'
                    .format(self.resname))
            acutils.waitForNotify(watchFile=self.resname,
                                  path=self.dname,
                                  debug=False,
                                  callback=self.getCBvalue)

        # Now OW is waiting for a new position file
        # Write new positions and notify file - this time it should use updated positions

        acutils.writePositionFile(self.wt_layout.wt_positions,
                                  path=self.dname,
                                  debug=self.debug)

        # see if results.txt is there already
        if os.path.exists(self.resname):
            resmtime = os.path.getmtime(self.resname)
            if self.debug:
                sys.stderr.write('ModTime({:}): {:}\n'.format(
                    self.resname, time.asctime(time.localtime(resmtime))))
        else:
            if self.debug:
                sys.stderr.write('{:} does not exist yet\n'.format(
                    self.resname))

        acutils.writeNotify(
            path=self.dname, debug=self.debug
        )  # tell OW that we're ready for the next (only) iteration

        # 'results.txt' is in the same directory as the *blb file
        if os.path.exists(self.resname):
            resNewmtime = os.path.getmtime(self.resname)
            if resNewmtime > resmtime:  # file has changed
                if self.debug:
                    sys.stderr.write('results.txt already updated')
            else:
                acutils.waitForNotify(watchFile=self.resname,
                                      path=self.dname,
                                      callback=self.getCBvalue,
                                      debug=self.debug)
        else:
            if self.debug:
                sys.stderr.write(
                    'OWComp waiting for {:} (modified positions)\n'.format(
                        self.resname))
            acutils.waitForNotify(watchFile=self.resname,
                                  path=self.dname,
                                  callback=self.getCBvalue,
                                  debug=self.debug)

        # Parse output file
        #    Enterprise OW writes the report file specified in the script BUT
        #    Academic OW writes 'results.txt' (which doesn't have as much information)

        netEnergy, netNRGturb, grossNRGturb = acutils.parseACresults(
            fname=self.resname)
        if netEnergy is None:
            sys.stderr.write("Error reading results file\n")
            if self.debug:
                sys.stderr.write('Stopping OpenWind with pid {:}\n'.format(
                    self.pid))
            self.proc.terminate()
            return False

        # Set the output variables
        #   - array_aep is not available from Academic 'results.txt' file
        self.nTurbs = len(netNRGturb)
        self.net_aep = netEnergy
        self.gross_aep = sum(grossNRGturb)
        if self.debug:
            sys.stderr.write('{:}\n'.format(self.dump()))

        # Log optimization values
        if self.opt_log:
            self.olfh.write('{:3d} G {:.4f} N {:.4f} XY '.format(
                self.exec_count, self.gross_aep, self.net_aep))
            for ii in range(len(wt_positions)):
                self.olfh.write('{:8.1f} {:9.1f} '.format(
                    self.wt_layout.wt_positions[ii][0],
                    self.wt_layout.wt_positions[ii][1]))
            self.olfh.write('\n')

        if not self.start_once and self.stopOW:
            if self.debug:
                sys.stderr.write('Stopping OpenWind with pid {:}\n'.format(
                    self.pid))
            self.proc.terminate()

        self.checkReport()  # check for execution errors

        if self.debug:
            sys.stderr.write("Leaving {0}.execute() {1}...\n\n".format(
                self.__class__, self.script_file))
Пример #3
0
    def execute(self):
        """ Executes our component. """

        if self.debug:
            sys.stderr.write("In {0}.execute() {1}...\n".format(self.__class__, self.script_file))
        
        if (len(self.resname) < 1):
            sys.stderr.write('\n*** ERROR: OWcomp results file name not assigned! (problem with script file?)\n\n')
            return False

        # Prepare input file here
        #   - write a new script file?
        #   - write a new turbine file to overwrite the one referenced
        #       in the existing script_file?

        # If there is a turbine replacement operation in the script:
        #   write new turbine description file based on contents of first turbine in layout
        
        #if 'replturbpath' in self.scriptDict: 
        if self.replace_turbine:
            if len(self.wt_layout.wt_list) < 1:
                sys.stderr.write('\n*** ERROR ***  OWcomp::execute(): no turbines in wt_layout!\n\n')
                return False
            if self.debug:
                sys.stderr.write('Replacement turbine parameters:\n')
                #sys.stderr.write('{:}\n'.format(turbfuncs.wtpc_dump(self.wt_layout.wt_list[0])))
                sys.stderr.write('{:}\n'.format(turbfuncs.wtpc_dump(self.wt_layout.wt_list[0], shortFmt=True)))
                #sys.stderr.write('{:}\n'.format(wtlDump(self.wt_layout.wt_list[0])))
                
            newXML = turbfuncs.wtpc_to_owtg(self.wt_layout.wt_list[0], 
                                            trbname='ReplTurb', 
                                            desc='OWcomp replacement turbine')
            if len(newXML) > 50:
                tfname = self.scriptDict['replturbpath'] # this is the file that will be overwritten with new turbine parameters
                tfh = open(tfname, 'w')
                tfh.write(newXML)
                tfh.close()
                maxPower = self.wt_layout.wt_list[0].power_rating
                if self.debug:
                    sys.stderr.write('Wrote new turbine file to {:} (rated pwr {:.2f} MW\n'.format(tfname, maxPower*0.000001))
            else:
                sys.stderr.write('*** NO new turbine file written\n')
            
        # Execute the component and save process ID
        if not self.start_once:
            self.proc = subprocess.Popen(self.command)
            self.pid = self.proc.pid
            if self.debug:
                sys.stderr.write('Started OpenWind with pid {:}\n'.format(self.pid))
                sys.stderr.write('  OWComp: dummyVbl {:}\n'.format(self.dummyVbl))
                #sys.stderr.write('Report Path: {:}\n'.format(self.rptpath))

            # Watch for 'results.txt', meaning that OW has run once with the default locations 
            
            if self.debug:
                sys.stderr.write('OWComp waiting for {:} (first run -  positions unchanged)\n'.format(self.resname))
            acutils.waitForNotify(watchFile=self.resname, path=self.dname, debug=False, callback=self.getCBvalue)

        # Now OW is waiting for a new position file
        # Write new positions and notify file - this time it should use updated positions

        acutils.writePositionFile(self.wt_layout.wt_positions, path=self.dname, debug=self.debug)
        
        # see if results.txt is there already
        if os.path.exists(self.resname):
            resmtime = os.path.getmtime(self.resname)
            if self.debug:
                sys.stderr.write('ModTime({:}): {:}\n'.format(self.resname, time.asctime(time.localtime(resmtime))))
        else:
            if self.debug:
                sys.stderr.write('{:} does not exist yet\n'.format(self.resname))
            
        acutils.writeNotify(path=self.dname, debug=self.debug) # tell OW that we're ready for the next (only) iteration
        
        # 'results.txt' is in the same directory as the *blb file
        if os.path.exists(self.resname):
            resNewmtime = os.path.getmtime(self.resname)
            if resNewmtime > resmtime: # file has changed
                if self.debug:
                    sys.stderr.write('results.txt already updated')
            else:
                acutils.waitForNotify(watchFile=self.resname, path=self.dname, callback=self.getCBvalue, debug=self.debug)
        else:
            if self.debug:
                sys.stderr.write('OWComp waiting for {:} (modified positions)\n'.format(self.resname))
            acutils.waitForNotify(watchFile=self.resname, path=self.dname, callback=self.getCBvalue, debug=self.debug)

        # Parse output file 
        #    Enterprise OW writes the report file specified in the script BUT
        #    Academic OW writes 'results.txt' (which doesn't have as much information)
        
        netEnergy, netNRGturb, grossNRGturb = acutils.parseACresults(fname=self.resname)
        if netEnergy is None:
            sys.stderr.write("Error reading results file\n")
            if self.debug:
                sys.stderr.write('Stopping OpenWind with pid {:}\n'.format(self.pid))
            self.proc.terminate()
            return False
        
        # Set the output variables
        #   - array_aep is not available from Academic 'results.txt' file
        self.nTurbs = len(netNRGturb)
        self.net_aep = netEnergy
        self.gross_aep = sum(grossNRGturb)
        if self.debug:
            sys.stderr.write('{:}\n'.format(self.dump()))
        
        # Log optimization values
        if self.opt_log:
            self.olfh.write('{:3d} G {:.4f} N {:.4f} XY '.format(self.exec_count, self.gross_aep, self.net_aep))
            for ii in range(len(wt_positions)):
                self.olfh.write('{:8.1f} {:9.1f} '.format(self.wt_layout.wt_positions[ii][0], self.wt_layout.wt_positions[ii][1]))
            self.olfh.write('\n')
                
        if not self.start_once and self.stopOW:
            if self.debug:
                sys.stderr.write('Stopping OpenWind with pid {:}\n'.format(self.pid))
            self.proc.terminate()
            
        self.checkReport() # check for execution errors

        if self.debug:
            sys.stderr.write("Leaving {0}.execute() {1}...\n\n".format(self.__class__, self.script_file))
Пример #4
0
def example(owExe):

    debug = True  # set True so user sees final 'break' message
    start_once = False
    modify_turbine = False
    opt_log = False
    extOpt = False
    
    for arg in sys.argv[1:]:
        if arg == '-debug':
            debug = True
        if arg == '-once':
            start_once = True
        if arg == '-log':
            opt_log = True
        if arg == '-modturb':
            modify_turbine = True
        if arg == '-extopt':
            extOpt = True
        if arg == '-help':
            sys.stderr.write('USAGE: python openWindComponent.py [-once] [-debug] [-modturb] [-extopt]\n')
            exit()
    
    # Find OpenWind executable
    if not os.path.isfile(owExe):
        sys.stderr.write('OpenWind executable file "{:}" not found\n'.format(owExe))
        exit()

    # set the external optimiser flag to extOpt:
    #    True : can use our optimizing routines
    acutils.owIniSet(owExe, extVal=extOpt, debug=True)
    
    # If we are not externally optimizing, we can start OW once and let it run to completion
    
    if not extOpt:
        start_once = True
        
    # Set OpenWind script name
    testpath = 'templates/'
    #owXMLname = testpath + 'rtecScript.xml' # replace turb, energy capture #KLD - this script does not work for me with this component
    owXMLname = testpath + 'owScript.xml' # optimize operation
    #owXMLname = testpath + 'rtopScript.xml' # replace turb, optimize
    
    if modify_turbine:
        owXMLname = testpath + 'rtopScript.xml' # replace turb, optimize
        
    if not os.path.isfile(owXMLname):
        sys.stderr.write('OpenWind script file "{:}" not found\n'.format(owXMLname))
        exit()
    
    dscript = rwScriptXML.rdScript(owXMLname,debug=debug) # Show our operations
    workbook = dscript['workbook']
    
    # default turbine positions and size of translation
    
    wt_positions = [[456000.00,4085000.00],
                    [456500.00,4085000.00]]
    deltaX =  3000.0
    deltaY = -2000.0
    #deltaX =  200.0
    #deltaY = -200.0
    deltaX =  3.000
    deltaY = -2.000
    
    # Read turbine positions from workbook
    if debug:
        sys.stderr.write('Getting turbine positions from {:}\n'.format(workbook))        
    wb = acutils.WTWkbkFile(wkbk=workbook, owexe=owExe)
    wt_positions = wb.xy
    if debug:
        sys.stderr.write('Got {:} turbine positions\n'.format(len(wt_positions)))        
    
    # Initialize OWcomp component
    ow = OWcomp(owExe=owExe, debug=debug, scriptFile=owXMLname, 
                extOpt=extOpt,
                start_once=start_once, opt_log=opt_log) #, stopOW=False)

    if not ow.scriptOK:
        sys.stderr.write("\n*** ERROR found in script file\n\n")
        exit()
    
    # starting point for turbine mods
    #wt_list_elem = dummy_wt_list()    
    base_turbine_file = testpath + 'NREL5MW.owtg'
    wt_list_elem = turbfuncs.owtg_to_wtpc(base_turbine_file)
    
    if not extOpt:
        # If we're not optimizing externally, run ow and return
        
        ow.execute()
        
        print '\nFinal values'
        owd = ow.dump()
        print '  {:}'.format(owd)
        print '-' * 40, '\n'
        
        return
    
    # external optimization
            
    ow.wt_layout.wt_list = [ wt_list_elem for i in range(len(wt_positions)) ]
    if debug:
        sys.stderr.write('Initialized {:} turbines in wt_layout\n'.format(len(wt_positions)))
    
    # With each iteration
    #   move turbines farther offshore 
    #   possibly modify the turbine rotor diam and power curve and replace turbine
    
    if debug:
        ofh = open('wtp.txt', 'w')
        
    for irun in range(1,4):
        for i in range(len(wt_positions)):
            wt_positions[i][0] += deltaX
            wt_positions[i][1] += deltaY
            if debug:
                ofh.write('{:2d} {:3d} {:.1f} {:.1f}\n'.format(irun, i, wt_positions[i][0], wt_positions[i][1]))
        ow.wt_layout.wt_positions = wt_positions
        
        # modify the turbine
        ow.rotor_diameter += 1.0
        if ow.replace_turbine:
            wt_list_elem = ow.wt_layout.wt_list[0]
            wt_list_elem.power_rating *= 1.05
            for i in range(len(wt_list_elem.power_curve)):
                wt_list_elem.power_curve[i][1] *= 1.05
            ow.wt_layout.wt_list = [wt_list_elem for i in range(len(ow.wt_layout.wt_list)) ]
            if debug:
                ofh.write('Updated {:} turbines with:\n'.format(len(ow.wt_layout.wt_list)))
                ofh.write(turbfuncs.wtpc_dump(ow.wt_layout.wt_list[0]))
        
        ow.execute() # run the openWind process
        
        print '\nFinal values'
        owd = ow.dump()
        print '  {:}'.format(owd)
        print '-' * 40, '\n'

    if start_once:
        ow.terminateOW()
Пример #5
0
    def execute(self):
        """
            Set up XML and run OpenWind
        """

        if self.debug:
            sys.stderr.write("\nIn {0}.execute()...\n".format(self.__class__))
        
        # ---- Set up parameters
            
        # initial positions are 'connect'ed to OWcomp object with passthrough of wt_layout
        
        # set turbine positions
        #   - from initial positions?
        #   - using another component that sets positions?
        
        self.wt_layout.wt_positions = self.init_wt_positions # use initial positions
        
        # 2014 05 26 - initialize or modify the turbine type here
        #   - read from file
        #   - modify existing turbine type
        #   - add component that returns a new turbine type
        # trb == ExtendedWindTurbinePowerCurveVT()
        
        nt = len(self.wt_layout.wt_positions)
        
        # initialize from file

        #owtg_file = '../test/NREL5MW.owtg'
        #sys.stderr.write('\n*** WARNING: initializing turbine from {:} - why??\n\n'.format(owtg_file))
        #trb = turbfuncs.owtg_to_wtpc(owtg_file)
        
        if self.debug:
            sys.stderr.write('\n*** WARNING: initializing turbine from ExtendedWindTurbinePowerCurveVT\n\n')
        trb = ExtendedWindTurbinePowerCurveVT()
        #trb.power_rating = 1000000.0 # watts!
        trb.power_rating = self.machine_rating
        
        for i in range(nt):
            self.wt_layout.wt_list[i] = trb
        
        # show parameters
        
        if self.debug:
            sys.stderr.write('Initial Turbine Positions\n')
            for i in range(len(self.wt_layout.wt_positions)):
                sys.stderr.write('{:3d} {:.1f} {:.1f}\n'.format(i, 
                   self.wt_layout.wt_positions[i][0],self.wt_layout.wt_positions[i][1]))
            
            s = turbfuncs.wtpc_dump(self.wt_layout.wt_list[0])
            sys.stderr.write('\n' + s)
            
        #report_path = self.workDir + '/' + 'scrtest1.txt'
        #workbook_path = self.workbook_path

        # Prepare for next iteration here...
        #   - write new scripts
        #   - write new turbine files
        #   - etc.
        
        # owtg_str = turbfuncs.wtpc_to_owtg(self.turb_props)
        
        # write new script for execution  
    
        # newScriptName = 'OpenWind_Script.xml'
        # self.writeNewScript(newScriptName)
        # self.command[1] = newScriptName
        
        # ---- Run the workflow
        
        super(openwindAC_assembly, self).execute()

        # ---- Process results
        
        # calculate capacity factor
        #  - assumes that all turbines have the same power rating
        #    and that self.wt_layout is correct
        
        if (self.wt_layout.wt_list[0].power_rating is None or 
            self.wt_layout.wt_list[0].power_rating == 0.0):
            self.capacity_factor = 0.0
            sys.stderr.write('\n*** WARNING: turbine power_rating not set\n\n')
        else:
            # power_rating is in W, but net_aep is in kWh
            #self.capacity_factor = ((self.net_aep) / (self.wt_layout.wt_list[0].power_rating*0.001 * 8760.0 * self.nTurbs))
            # 8766 hrs = 365.25 days to agree with OpenWind
            self.capacity_factor = ((self.net_aep) / (self.wt_layout.wt_list[0].power_rating*0.001 * 8766.0 * self.nTurbs))
        
        self.total_losses = (self.gross_aep - self.net_aep) / self.gross_aep