Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • toolbox/WindEnergyToolbox
  • tlbl/WindEnergyToolbox
  • cpav/WindEnergyToolbox
  • frza/WindEnergyToolbox
  • borg/WindEnergyToolbox
  • mmpe/WindEnergyToolbox
  • ozgo/WindEnergyToolbox
  • dave/WindEnergyToolbox
  • mmir/WindEnergyToolbox
  • wluo/WindEnergyToolbox
  • welad/WindEnergyToolbox
  • chpav/WindEnergyToolbox
  • rink/WindEnergyToolbox
  • shfe/WindEnergyToolbox
  • shfe1/WindEnergyToolbox
  • acdi/WindEnergyToolbox
  • angl/WindEnergyToolbox
  • wliang/WindEnergyToolbox
  • mimc/WindEnergyToolbox
  • wtlib/WindEnergyToolbox
  • cmos/WindEnergyToolbox
  • fabpi/WindEnergyToolbox
22 results
Show changes
Showing
with 3958 additions and 235 deletions
...@@ -14,7 +14,7 @@ This tool comes handy in the following scenarios: ...@@ -14,7 +14,7 @@ This tool comes handy in the following scenarios:
* different parameters variations are required, e.g. different wind speed range or different number of turbulent seed. * different parameters variations are required, e.g. different wind speed range or different number of turbulent seed.
The generator of the cases uses an input spreadsheet where the cases are defined The generator of the cases uses an input spreadsheet where the cases are defined
in a more compact way. in a more compact way.
The tool is based on the "tags" concept that is used for the generation of the htc files. The tool is based on the "tags" concept that is used for the generation of the htc files.
Main spreadsheet Main spreadsheet
...@@ -36,9 +36,9 @@ In each sheet the type of tag is defined in the line above the tag by typing one ...@@ -36,9 +36,9 @@ In each sheet the type of tag is defined in the line above the tag by typing one
Functions (F) tags Functions (F) tags
------------------ ------------------
* Numbers can be converted to strings (for example when a tag refers to a file name) * Numbers can be converted to strings (for example when a tag refers to a file name)
by using double quotes ```"``` for Functions (F): by using double quotes ```"``` for Functions (F):
* ```"wdir_[wdir]deg_wsp_[wsp]ms"``` will result in the tags ``` [wdir]``` * ```"wdir_[wdir]deg_wsp_[wsp]ms"``` will result in the tags ``` [wdir]```
and ```[wsp]``` being replaced with formatted text. and ```[wsp]``` being replaced with formatted text.
* following formatting rules are used: * following formatting rules are used:
* ```[wsp]```, ```[gridgustdelay]``` : ```02i``` * ```[wsp]```, ```[gridgustdelay]``` : ```02i```
...@@ -62,11 +62,11 @@ Generate the files ...@@ -62,11 +62,11 @@ Generate the files
------------------ ------------------
To generate the files defining the different DLC the following lines need to be executed: To generate the files defining the different DLC the following lines need to be executed:
export PATH=/home/python/miniconda3/bin:$PATH export PATH=/home/python/miniconda3/bin:$PATH
source activate wetb_py3 source activate py36-wetb
python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py --folder=DLCs python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py --folder=DLCs
the first two lines activate the virtual environment. The third calls the routine *GenerateDLCs.py * that generates the files. the first two lines activate the virtual environment. The third calls the routine *GenerateDLCs.py * that generates the files.
The routine should be called from the folder *htc* where also the master spreadsheet *DLCs.xlsx* need to be located. The routine should be called from the folder *htc* where also the master spreadsheet *DLCs.xlsx* need to be located.
The generated files are placed in the folder *DLCs*. The generated files are placed in the folder *DLCs*.
...@@ -61,11 +61,11 @@ do this when the turbulence box size changes (e.g., if the rotor size changes) ...@@ -61,11 +61,11 @@ do this when the turbulence box size changes (e.g., if the rotor size changes)
or if you have a model that's never been simulated on mimer. or if you have a model that's never been simulated on mimer.
2. Determine your set ID code. There are two scenarios: 2. Determine your set ID code. There are two scenarios:
* No one else in your project has run simulations on mimer. In this case, * No one else in your project has run simulations on mimer. In this case,
create a new set ID alpha code (e.g., "AA", "AB", etc.). create a new set ID alpha code (e.g., "AA", "AB", etc.).
* Simulations for this project/turbine configuration already exist. In this * Simulations for this project/turbine configuration already exist. In this
case, use a pre-existing set ID alpha code and add one to the most recent case, use a pre-existing set ID alpha code and add one to the most recent
Set ID (e.g., if "AB0008" exists, your new folder should be "AB0009"). Set ID (e.g., if "AB0008" exists, your new folder should be "AB0009").
##### 3. Add proper log files for your Set ID folder. ##### 3. Add proper log files for your Set ID folder.
See the [house rules](docs/houserules-mimerhawc2sim.md) regarding log files. See the [house rules](docs/houserules-mimerhawc2sim.md) regarding log files.
...@@ -86,7 +86,7 @@ structure similar to this: ...@@ -86,7 +86,7 @@ structure similar to this:
Your master htc file, stored in ```htc/_master/```, can take any desired naming Your master htc file, stored in ```htc/_master/```, can take any desired naming
convention, but it must have ```_master_``` in the name or future scripts will convention, but it must have ```_master_``` in the name or future scripts will
abort. ```htc/DLCs.xlsx``` is your master Excel file that will create the abort. ```htc/DLCs.xlsx``` is your master Excel file that will create the
subordinate Excel files in the coming steps. subordinate Excel files in the coming steps.
##### 5. Create your subordinate Excel files. ##### 5. Create your subordinate Excel files.
...@@ -94,7 +94,7 @@ From a terminal, change to your htc directory. Then run the following code: ...@@ -94,7 +94,7 @@ From a terminal, change to your htc directory. Then run the following code:
``` ```
$ export PATH=/home/python/miniconda3/bin:$PATH $ export PATH=/home/python/miniconda3/bin:$PATH
$ source activate wetb_py3 $ source activate py36-wetb
$ python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py --folder=DLCs $ python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py --folder=DLCs
$ source deactivate $ source deactivate
``` ```
...@@ -125,7 +125,7 @@ $ launch.py -n 100 -p pbs_in/ ...@@ -125,7 +125,7 @@ $ launch.py -n 100 -p pbs_in/
``` ```
There are many launch options available. You can read more about the options There are many launch options available. You can read more about the options
and querying the cluster configurations/status/etc. on and querying the cluster configurations/status/etc. on
[this page](docs/howto-make-dlcs.md), or you can use the ```launchy.py``` [this page](docs/howto-make-dlcs.md), or you can use the ```launchy.py```
help function to print available launch options: help function to print available launch options:
...@@ -135,7 +135,7 @@ $ launch.py --help ...@@ -135,7 +135,7 @@ $ launch.py --help
##### 8. Post-process results. ##### 8. Post-process results.
The wetb function ```qsub-wrap.py``` can not only generate htc files but also The wetb function ```qsub-wrap.py``` can not only generate htc files but also
post-process results. For example, here is code to check the log files post-process results. For example, here is code to check the log files
and calculate the statistics, the AEP and the lifetime equivalent loads and calculate the statistics, the AEP and the lifetime equivalent loads
(must be executed from the top-level Set ID folder): (must be executed from the top-level Set ID folder):
......
HAWC2 tools
===========================
``wetb`` includes functions to help with the writing of HAWC2 input
files, also know as htc files. The documentation is in a Jupyter
notebook format. You can download the source notebooks from the
``wetb`` repository, under ``docs/source/hawc2``.
.. toctree::
:caption: HAWC2
notebooks/hawc2/InputFileWriting
notebooks/hawc2/RunningSimulations
notebooks/hawc2/RunningSimulationsJess
...@@ -15,7 +15,7 @@ DONE: ...@@ -15,7 +15,7 @@ DONE:
--> -->
> WARNING: these notes contain configuration settings that are specif to the > WARNING: these notes contain configuration settings that are specif to the
DTU Wind Energy cluster Gorm. Only follow this guide in another environment if DTU Wind Energy cluster Jess. Only follow this guide in another environment if
you know what you are doing! you know what you are doing!
...@@ -41,7 +41,7 @@ result and log files with lower case file names, regardless of the user input. ...@@ -41,7 +41,7 @@ result and log files with lower case file names, regardless of the user input.
Hence, in order to avoid possible ambiguities at all times, make sure that there Hence, in order to avoid possible ambiguities at all times, make sure that there
are no upper case symbols defined in the value of the following tags (as defined are no upper case symbols defined in the value of the following tags (as defined
in the Excel spreadsheets): ```[Case folder]```, ```[Case id.]```, and in the Excel spreadsheets): ```[Case folder]```, ```[Case id.]```, and
```[Turb base name]```. ```[turb_base_name]```.
The system will always force the values of the tags to be lower case anyway, and The system will always force the values of the tags to be lower case anyway, and
when working on Windows, this might cause some confusing and unexpected behavior. when working on Windows, this might cause some confusing and unexpected behavior.
...@@ -53,8 +53,8 @@ either let the system fill that in for you (by using the variable ```$USER```), ...@@ -53,8 +53,8 @@ either let the system fill that in for you (by using the variable ```$USER```),
or explicitly user your user name instead. This user name is the same as your or explicitly user your user name instead. This user name is the same as your
DTU account name (or student account/number). DTU account name (or student account/number).
This document refers to commands to be entered in the terminal on Gorm when the This document refers to commands to be entered in the terminal on Jess when the
line starts with ```g-000 $```. The command that needs to be entered starts line starts with ```j-000 $```. The command that needs to be entered starts
after the ```$```. after the ```$```.
...@@ -73,10 +73,7 @@ Connecting to the cluster ...@@ -73,10 +73,7 @@ Connecting to the cluster
------------------------- -------------------------
We provide here an overview of how to connect to the cluster, but general, We provide here an overview of how to connect to the cluster, but general,
up-to-date information can be found in the [HPC documentation](https://docs.hpc.ait.dtu.dk) up-to-date information can be found in the [HPC documentation](https://docs.hpc.ait.dtu.dk).
or on the [Gorm wiki](http://gorm.risoe.dk/gormwiki). Note that the
information from the Gorm wiki will be migrated into the HPC documentation
over time.
You connect to the cluster via an SSH terminal, and there are different SSH You connect to the cluster via an SSH terminal, and there are different SSH
terminals based on your operating system (see the platform-specific terminals based on your operating system (see the platform-specific
...@@ -94,10 +91,10 @@ be downloaded from ...@@ -94,10 +91,10 @@ be downloaded from
Once you have installed PuTTY and placed the executable somewhere convenient Once you have installed PuTTY and placed the executable somewhere convenient
(e.g., the Desktop), double click on the executable. In the window that opens (e.g., the Desktop), double click on the executable. In the window that opens
up, enter/verify the following settings: up, enter/verify the following settings:
* Session > Host Name: gorm.risoe.dk * Session > Host Name: jess.dtu.dk
* Session > Port: 22 * Session > Port: 22
* Session > Connection type: SSH * Session > Connection type: SSH
* Session > Saved Sessions: Gorm * Session > Saved Sessions: Jess
* Connection > Data > Auto-login username: your DTU username * Connection > Data > Auto-login username: your DTU username
* Connection > Data > When username is not specified: Use system username * Connection > Data > When username is not specified: Use system username
* Window > Colours > Select a colour to adjust > ANSI Blue: RGB = 85, 85, 255 * Window > Colours > Select a colour to adjust > ANSI Blue: RGB = 85, 85, 255
...@@ -110,12 +107,12 @@ to be lighter and therefore easier to read when working in the terminal. Once ...@@ -110,12 +107,12 @@ to be lighter and therefore easier to read when working in the terminal. Once
you have entered these options, click "Save" on the "Session" tab and close you have entered these options, click "Save" on the "Session" tab and close
the window. the window.
With PuTTY configured, you can connect to Gorm by double-clicking the PuTTY With PuTTY configured, you can connect to Jess by double-clicking the PuTTY
executable; then, in the window that opens select "Gorm" in "Saved Sessions", executable; then, in the window that opens select "Jess" in "Saved Sessions",
click the "Load" button, and finally click the "Open" button. A terminal click the "Load" button, and finally click the "Open" button. A terminal
window will open up. Type your DTU password in this new window when prompted window will open up. Type your DTU password in this new window when prompted
(your text will not appear in the window) and then hit the Enter key. You (your text will not appear in the window) and then hit the Enter key. You
should now be logged into Gorm. should now be logged into Jess.
To close the PuTTY window, you can either hit the red "X" in the upper-right To close the PuTTY window, you can either hit the red "X" in the upper-right
corner of the window or type "exit" in the terminal and hit enter. corner of the window or type "exit" in the terminal and hit enter.
...@@ -133,11 +130,11 @@ terminals. To connect to the cluster, enter the following command into ...@@ -133,11 +130,11 @@ terminals. To connect to the cluster, enter the following command into
the terminal: the terminal:
``` ```
ssh $USER@gorm.risoe.dk ssh $USER@jess.dtu.dk
``` ```
Enter your DTU password when prompted. This will give you terminal access Enter your DTU password when prompted. This will give you terminal access
to the Gorm cluster. to the Jess cluster.
Mounting the cluster discs Mounting the cluster discs
...@@ -145,7 +142,7 @@ Mounting the cluster discs ...@@ -145,7 +142,7 @@ Mounting the cluster discs
When doing the HAWC2 simulations, you will interact regularly with the cluster When doing the HAWC2 simulations, you will interact regularly with the cluster
file system and discs. Thus, it can be very useful to have two discs mounted file system and discs. Thus, it can be very useful to have two discs mounted
locally so you can easily access them: 1) your home directory on Gorm and 2) locally so you can easily access them: 1) your home directory on Jess and 2)
the HAWC2 simulation folder on Mimer. the HAWC2 simulation folder on Mimer.
You need to be connected to the DTU network (either directly or via VPN) for You need to be connected to the DTU network (either directly or via VPN) for
...@@ -167,17 +164,17 @@ $WIN_VERSION is your version number. ...@@ -167,17 +164,17 @@ $WIN_VERSION is your version number.
In Windows 7, you can map a network drive in the following steps: In Windows 7, you can map a network drive in the following steps:
1. Open a Windows Explorer window 1. Open a Windows Explorer window
2. Right-click on "Computer" and select "Map network drive" 2. Right-click on "Computer" and select "Map network drive"
3. Select any unused drive and type ```\\gorm.risoe.dk\$USER``` into the folder field, 3. Select any unused drive and type ```\\Jess.dtu.dk\$USER``` into the folder field,
replacing "$USER" with your DTU username (e.g., DTU user "ABCD" has a Gorm home replacing "$USER" with your DTU username (e.g., DTU user "ABCD" has a Jess home
drive of ```\\gorm.risoe.dk\abcd```) drive of ```\\Jess.dtu.dk\abcd```)
4. Check the "Reconnect at logon" box if you want to connect to this drive 4. Check the "Reconnect at logon" box if you want to connect to this drive
every time you log into your computer (recommended) every time you log into your computer (recommended)
5. Click the Finish button 5. Click the Finish button
6. Repeat Steps 1 through 5, replacing the Gorm home address in Step 3 with the 6. Repeat Steps 1 through 5, replacing the Jess home address in Step 3 with the
HAWC2 simulation folder address: ```\\mimer.risoe.dk\hawc2sim``` HAWC2 simulation folder address: ```\\mimer.risoe.dk\hawc2sim```
Note that by default Windows Explorer will hide some of the files you will need Note that by default Windows Explorer will hide some of the files you will need
edit. In order to show all files on your Gorm home drive, you need to un-hide edit. In order to show all files on your Jess home drive, you need to un-hide
system files: Explorer > Organize > Folder and search options > "View" tab > system files: Explorer > Organize > Folder and search options > "View" tab >
Hidden files and folders > "Show hidden files, folders, and drives". Hidden files and folders > "Show hidden files, folders, and drives".
...@@ -187,7 +184,7 @@ From Linux/Mac, you should be able to mount using either of the following ...@@ -187,7 +184,7 @@ From Linux/Mac, you should be able to mount using either of the following
addresses: addresses:
``` ```
//mimer.risoe.dk/hawc2sim //mimer.risoe.dk/hawc2sim
//gorm.risoe.dk/$USER //jess.dtu.dk/$USER
``` ```
You can use either ```sshfs``` or ```mount -t cifs``` to mount the discs. You can use either ```sshfs``` or ```mount -t cifs``` to mount the discs.
...@@ -195,8 +192,8 @@ You can use either ```sshfs``` or ```mount -t cifs``` to mount the discs. ...@@ -195,8 +192,8 @@ You can use either ```sshfs``` or ```mount -t cifs``` to mount the discs.
Preparation Preparation
----------- -----------
Add the cluster-tools script to your system's PATH of you Gorm environment, Add the cluster-tools script to your system's PATH of you Jess environment,
by editing the file ```.bash_profile``` file in your Gorm’s home directory by editing the file ```.bash_profile``` file in your Jess’s home directory
(```/home/$USER/.bash_profile```), and add the following lines (add at the end, (```/home/$USER/.bash_profile```), and add the following lines (add at the end,
or create a new file with this file name in case it doesn't exist): or create a new file with this file name in case it doesn't exist):
...@@ -212,13 +209,13 @@ are much appreciated!) ...@@ -212,13 +209,13 @@ are much appreciated!)
> If you have been using an old version of this how-to, you might be pointing > If you have been using an old version of this how-to, you might be pointing
to an earlier version of these tools/utils and any references containing to an earlier version of these tools/utils and any references containing
```cluster-tools``` or ```prepost``` should be removed ```cluster-tools``` or ```prepost``` should be removed
from your ```.bash_profile``` and/or ```.bashrc``` file on your gorm home drive. from your ```.bash_profile``` and/or ```.bashrc``` file on your Jess home drive.
After modifying ```.bash_profile```, save and close it. Then, in the terminal, After modifying ```.bash_profile```, save and close it. Then, in the terminal,
run the command (or logout and in again to be safe): run the command (or logout and in again to be safe):
``` ```
g-000 $ source ~/.bash_profile j-000 $ source ~/.bash_profile
g-000 $ source ~/.bashrc j-000 $ source ~/.bashrc
``` ```
You will also need to configure wine and place the HAWC2 executables in your You will also need to configure wine and place the HAWC2 executables in your
...@@ -226,7 +223,7 @@ local wine directory, which by default is assumed to be ```~/.wine32```, and ...@@ -226,7 +223,7 @@ local wine directory, which by default is assumed to be ```~/.wine32```, and
```pbsutils``` contains and automatic configuration script you can run: ```pbsutils``` contains and automatic configuration script you can run:
``` ```
g-000 $ /home/MET/repositories/toolbox/pbsutils/config-wine-hawc2.sh j-000 $ /home/MET/repositories/toolbox/pbsutils/config-wine-hawc2.sh
``` ```
If you need more information on what is going on, you can read a more detailed If you need more information on what is going on, you can read a more detailed
...@@ -252,7 +249,7 @@ precedence over the ones placed in ```/home/$USER/wine_exe/win32```. ...@@ -252,7 +249,7 @@ precedence over the ones placed in ```/home/$USER/wine_exe/win32```.
At this stage you can run HAWC2 as follows: At this stage you can run HAWC2 as follows:
``` ```
g-000 $ wine32 hawc2-latest htc/some-intput-file.htc j-000 $ wine32 hawc2-latest htc/some-intput-file.htc
``` ```
...@@ -263,7 +260,7 @@ When there is a new version of HAWC2, or when a new license manager is released, ...@@ -263,7 +260,7 @@ When there is a new version of HAWC2, or when a new license manager is released,
you can update your local wine directory as follows: you can update your local wine directory as follows:
``` ```
g-000 $ rsync -au /home/MET/hawc2exe/win32 /home/$USER/wine_exe/win32 --progress j-000 $ rsync -au /home/MET/hawc2exe/win32 /home/$USER/wine_exe/win32 --progress
``` ```
The file ```hawc2-latest.exe``` will always be the latest HAWC2 The file ```hawc2-latest.exe``` will always be the latest HAWC2
...@@ -310,19 +307,19 @@ For example, in order to generate all the HAWC2 htc input files and the ...@@ -310,19 +307,19 @@ For example, in order to generate all the HAWC2 htc input files and the
corresponding ```*.p``` cluster launch files using this default DLB setup with: corresponding ```*.p``` cluster launch files using this default DLB setup with:
``` ```
g-000 $ cd /mnt/mimer/hawc2sim/demo/A0001 # folder where the hawc2 model is located j-000 $ cd /mnt/mimer/hawc2sim/demo/A0001 # folder where the hawc2 model is located
g-000 $ qsub-wrap.py -f /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py --prep j-000 $ qsub-wrap.py -f /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py --prep
``` ```
You could consider adding ```dlctemplate.py``` into the turbine folder or in You could consider adding ```dlctemplate.py``` into the turbine folder or in
the simulation set id folder for your convenience: the simulation set id folder for your convenience:
``` ```
g-000 $ cd /mnt/mimer/hawc2sim/demo/ j-000 $ cd /mnt/mimer/hawc2sim/demo/
# copy the dlctemplate to your turbine model folder and rename to myturbine.py # copy the dlctemplate to your turbine model folder and rename to myturbine.py
g-000 $ cp /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py ./myturbine.py j-000 $ cp /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py ./myturbine.py
g-000 $ cd A0001 j-000 $ cd A0001
g-000 $ qsub-wrap.py -f ../myturbine.py --prep j-000 $ qsub-wrap.py -f ../myturbine.py --prep
``` ```
...@@ -338,23 +335,23 @@ First activate the Anaconda Python environment by typing: ...@@ -338,23 +335,23 @@ First activate the Anaconda Python environment by typing:
```bash ```bash
# add the Anaconda Python environment paths to the system PATH # add the Anaconda Python environment paths to the system PATH
g-000 $ export PATH=/home/python/miniconda3/bin:$PATH j-000 $ export PATH=/home/python/miniconda3/bin:$PATH
# activate the custom python environment: # activate the custom python environment:
g-000 $ source activate wetb_py3 j-000 $ source activate py36-wetb
``` ```
For example, launch the auto-generation of DLCs input files: For example, launch the auto-generation of DLCs input files:
``` ```
# folder where the HAWC2 model is located # folder where the HAWC2 model is located
g-000 $ cd /mnt/mimer/hawc2sim/demo/AA0001 j-000 $ cd /mnt/mimer/hawc2sim/demo/AA0001
# assuming myturbine.py is copy of dlctemplate.py and is placed one level up # assuming myturbine.py is copy of dlctemplate.py and is placed one level up
g-000 $ python ../myturbine.py --prep j-000 $ python ../myturbine.py --prep
``` ```
Or start an interactive IPython shell: Or start an interactive IPython shell:
``` ```
g-000 $ ipython j-000 $ ipython
``` ```
Users should be aware that running computational heavy loads on the login node Users should be aware that running computational heavy loads on the login node
...@@ -406,12 +403,12 @@ Required, and used for the PBS output and post-processing ...@@ -406,12 +403,12 @@ Required, and used for the PBS output and post-processing
Optional Optional
* ```[turb_db_dir] = '../turb/'``` * ```[turb_db_dir] = '../turb/'```
* ```[wake_dir] = False``` * ```[micro_dir] = False```
* ```[wake_db_dir] = False``` * ```[micro_db_dir] = False```
* ```[wake_base_name] = 'turb_'``` * ```[micro_base_name] = 'turb_'```
* ```[meander_dir] = False``` * ```[meander_dir] = False```
* ```[meand_db_dir] = False``` * ```[meander_db_dir] = False```
* ```[meand_base_name] = 'turb_'``` * ```[meander_base_name] = 'turb_'```
* ```[mooring_dir] = False```, all files and sub-folders copied to node * ```[mooring_dir] = False```, all files and sub-folders copied to node
* ```[hydro_dir] = False```, all files and sub-folders copied to node * ```[hydro_dir] = False```, all files and sub-folders copied to node
...@@ -464,19 +461,48 @@ turbulence boxes using the 64-bit version of the stand alone Mann turbulence ...@@ -464,19 +461,48 @@ turbulence boxes using the 64-bit version of the stand alone Mann turbulence
box generator. The appropriate input parameters are taken from the following box generator. The appropriate input parameters are taken from the following
tags: tags:
* ```[tu_model]``` * Atmospheric turbulence:
* ```[Turb base name]``` * ```[tu_model] = 1```
* ```[MannAlfaEpsilon]``` * ```[turb_base_name]```
* ```[MannL]``` * ```[MannAlfaEpsilon]```
* ```[MannGamma]``` * ```[MannL]```
* ```[seed]``` * ```[MannGamma]```
* ```[turb_nr_u]``` : number of grid points in the u direction * ```[seed]```
* ```[turb_nr_v]``` : number of grid points in the v direction * ```[turb_nr_u]``` : number of grid points in the u direction
* ```[turb_nr_w]``` : number of grid points in the w direction * ```[turb_nr_v]``` : number of grid points in the v direction
* ```[turb_dx]``` : grid spacing in meters in the u direction * ```[turb_nr_w]``` : number of grid points in the w direction
* ```[turb_dy]``` : grid spacing in meters in the v direction * ```[turb_dx]``` : grid spacing in meters in the u direction
* ```[turb_dz]``` : grid spacing in meters in the w direction * ```[turb_dy]``` : grid spacing in meters in the v direction
* ```[high_freq_comp]``` * ```[turb_dz]``` : grid spacing in meters in the w direction
* ```[high_freq_comp]```
* Micro turbulence for DWM:
* ```[micro_base_name]```
* ```[MannAlfaEpsilon_micro]```
* ```[MannL_micro]```
* ```[MannGamma_micro]```
* ```[seed_micro]```
* ```[turb_nr_u_micro]``` : number of grid points in the u direction
* ```[turb_nr_v_micro]``` : number of grid points in the v direction
* ```[turb_nr_w_micro]``` : number of grid points in the w direction
* ```[turb_dx_micro]``` : grid spacing in meters in the u direction
* ```[turb_dy_micro]``` : grid spacing in meters in the v direction
* ```[turb_dz_micro]``` : grid spacing in meters in the w direction
* ```[high_freq_comp_micro]```
* Meander turbulence for DWM
* ```[meander_base_name]```
* ```[MannAlfaEpsilon_meander]```
* ```[MannL_meander]```
* ```[MannGamma_meander]```
* ```[seed_meander]```
* ```[turb_nr_u_meander]``` : number of grid points in the u direction
* ```[turb_nr_v_meander]``` : number of grid points in the v direction
* ```[turb_nr_w_meander]``` : number of grid points in the w direction
* ```[turb_dx_meander]``` : grid spacing in meters in the u direction
* ```[turb_dy_meander]``` : grid spacing in meters in the v direction
* ```[turb_dz_meander]``` : grid spacing in meters in the w direction
* ```[high_freq_comp_meander]```
### Tags required for hydro file generation ### Tags required for hydro file generation
...@@ -489,6 +515,11 @@ tags: ...@@ -489,6 +515,11 @@ tags:
* ```[Hs]``` : see HAWC2 manual for options * ```[Hs]``` : see HAWC2 manual for options
* ```[Tp]``` : see HAWC2 manual for options * ```[Tp]``` : see HAWC2 manual for options
* ```[wave_seed]``` : see HAWC2 manual for options * ```[wave_seed]``` : see HAWC2 manual for options
* ```[wave_gamma]``` : see HAWC2 manual for options
* ```[wave_coef]``` : see HAWC2 manual for options
* ```[stretching]``` : see HAWC2 manual for options
* ```[embed_sf]``` : see HAWC2 manual for options, and look for how it is implemented
in [prepost.dlcsdefs.vartag_excel_stabcon(master)](wetb/prepost/dlcdefs.py).
And the corresponding section the htc master file: And the corresponding section the htc master file:
...@@ -571,7 +602,7 @@ The ```launch.py``` script has various different options, and you can read about ...@@ -571,7 +602,7 @@ The ```launch.py``` script has various different options, and you can read about
them by using the help function (the output is included for your convenience): them by using the help function (the output is included for your convenience):
```bash ```bash
g-000 $ launch.py --help j-000 $ launch.py --help
Usage: Usage:
launch.py -n nr_cpus launch.py -n nr_cpus
...@@ -627,8 +658,8 @@ Then launch the actual jobs (each job is a ```*.p``` file in ```pbs_in```) using ...@@ -627,8 +658,8 @@ Then launch the actual jobs (each job is a ```*.p``` file in ```pbs_in```) using
100 cpu's: 100 cpu's:
```bash ```bash
g-000 $ cd /mnt/mimer/hawc2sim/demo/A0001 j-000 $ cd /mnt/mimer/hawc2sim/demo/A0001
g-000 $ launch.py -n 100 -p pbs_in/ j-000 $ launch.py -n 100 -p pbs_in/
``` ```
If the launching process requires hours, and you have to close you SHH/PuTTY If the launching process requires hours, and you have to close you SHH/PuTTY
...@@ -641,8 +672,8 @@ simple and light job. ```launch.py``` will remove all the users crontab jobs ...@@ -641,8 +672,8 @@ simple and light job. ```launch.py``` will remove all the users crontab jobs
at the end with ```crontab -r```. at the end with ```crontab -r```.
```bash ```bash
g-000 $ cd /mnt/mimer/hawc2sim/demo/A0001 j-000 $ cd /mnt/mimer/hawc2sim/demo/A0001
g-000 $ launch.py -n 100 -p pbs_in/ --crontab j-000 $ launch.py -n 100 -p pbs_in/ --crontab
``` ```
...@@ -660,25 +691,25 @@ length of the queue, etc ...@@ -660,25 +691,25 @@ length of the queue, etc
Notice that the pbs output files in ```pbs_out``` are only created when the job Notice that the pbs output files in ```pbs_out``` are only created when the job
has ended (or failed). When you want to inspect a running job, you can ssh from has ended (or failed). When you want to inspect a running job, you can ssh from
the Gorm login node to node that runs the job. First, find the job id by listing the Jess login node to node that runs the job. First, find the job id by listing
all your current jobs (```qstat -u $USER```). The job id can be found in the all your current jobs (```qstat -u $USER```). The job id can be found in the
first column, and you only need to consider the number, not the domain name first column, and you only need to consider the number, not the domain name
attached to it. Now find the on which node it runs with (replace 123546 with the attached to it. Now find the on which node it runs with (replace 123546 with the
relevant job id): relevant job id):
``` ```
g-000 $ qstat -f 123456 | grep exec_host j-000 $ qstat -f 123456 | grep exec_host
``` ```
From here you login into the node as follows (replace g-078 with the relevant From here you login into the node as follows (replace j-078 with the relevant
node): node):
``` ```
g-000 $ ssh g-078 j-000 $ ssh j-078
``` ```
And browse to the scratch directory which lands you in the root directory of And browse to the scratch directory which lands you in the root directory of
your running HAWC2 model (replace 123456 with the relevant job id): your running HAWC2 model (replace 123456 with the relevant job id):
``` ```
g-000 $ cd /scratch/$USER/123456.g-000.risoe.dk j-000 $ cd /scratch/$USER/123456.j-000.risoe.dk
``` ```
You can find what HAWC2 (or whatever other executable you are running) is You can find what HAWC2 (or whatever other executable you are running) is
...@@ -690,8 +721,6 @@ Or when watch what is happening at the end in real time ...@@ -690,8 +721,6 @@ Or when watch what is happening at the end in real time
``` ```
# on Jess: # on Jess:
tail -f /var/lib/torque/spool/JOBID.jess.dtu.dk.OU tail -f /var/lib/torque/spool/JOBID.jess.dtu.dk.OU
# on Gorm:
tail -f /var/spool/pbs/spool/JOBID.g-000.risoe.dk.OU
``` ```
...@@ -706,7 +735,7 @@ found in the ```pbs_in``` folder) of the failed cases to a new folder (for ...@@ -706,7 +735,7 @@ found in the ```pbs_in``` folder) of the failed cases to a new folder (for
example ```pbs_in_failed```). Now run ```launch.py``` again, but instead point example ```pbs_in_failed```). Now run ```launch.py``` again, but instead point
to the folder that contains the ```*.p``` files of the failed cases, for example: to the folder that contains the ```*.p``` files of the failed cases, for example:
``` ```
g-000 $ launch.py -n 100 --node -p pbs_in_failed j-000 $ launch.py -n 100 --node -p pbs_in_failed
``` ```
2. Use the ```--cache``` option, and edit the PBS file list in the file 2. Use the ```--cache``` option, and edit the PBS file list in the file
...@@ -718,7 +747,7 @@ job will be launched. ...@@ -718,7 +747,7 @@ job will be launched.
3. Each pbs file can be launched manually as follows: 3. Each pbs file can be launched manually as follows:
``` ```
g-000 $ qsub path/to/pbs_file.p j-000 $ qsub path/to/pbs_file.p
``` ```
Alternatively, one can use the following options in ```launch.py```: Alternatively, one can use the following options in ```launch.py```:
...@@ -742,13 +771,13 @@ files, calculating the statistics, the AEP and the life time equivalent loads: ...@@ -742,13 +771,13 @@ files, calculating the statistics, the AEP and the life time equivalent loads:
``` ```
# myturbine.py (copy of dlctemplate.py) is assumed to be located one folder up # myturbine.py (copy of dlctemplate.py) is assumed to be located one folder up
g-000 $ qsub-wrap.py -f ../myturbine.py --years=25 --neq=1e7 --stats --check_logs --fatigue j-000 $ qsub-wrap.py -f ../myturbine.py --years=25 --neq=1e7 --stats --check_logs --fatigue
``` ```
Other options for the original ```dlctemplate.py``` script: Other options for the original ```dlctemplate.py``` script:
``` ```
(wetb_py3) [dave@jess]$ python dlctemplate.py --help (py36-wetb) [dave@jess]$ python dlctemplate.py --help
usage: dlctemplate.py [-h] [--prep] [--check_logs] usage: dlctemplate.py [-h] [--prep] [--check_logs]
[--pbs_failed_path PBS_FAILED_PATH] [--stats] [--pbs_failed_path PBS_FAILED_PATH] [--stats]
[--fatigue] [--AEP] [--csv] [--years YEARS] [--fatigue] [--AEP] [--csv] [--years YEARS]
......
Welcome to WETB
===========================================
*- The Wind Energy Toolbox of DTU*
This toolbox provides Python tools intended for use in the wind
community, and especially HAWC2 users. Please see the Installation
tab on the left to install the code and get started.
Source code repository (and issue tracker):
https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox
License:
GPLv3_
.. _GPLv3: https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/LICENSE.txt
Contents:
.. toctree::
installation
fatigue
hawc2
bladed/bladed2hawc
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
``` ```
conda update --all conda update --all
conda create -n wetb_py3 python=3.5 conda create -n py36-wetb python=3.6
source activate wetb_py3 source activate py36-wetb
conda install setuptools_scm future h5py pytables pytest nose sphinx blosc psutil conda install setuptools_scm mock h5py pytables pytest nose sphinx blosc psutil
conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl paramiko conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl paramiko
conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov
``` ```
...@@ -17,9 +17,9 @@ conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov ...@@ -17,9 +17,9 @@ conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov
``` ```
conda update --all conda update --all
conda create -n wetb_py3 python=3.4 conda create -n py36-wetb python=3.6
source activate wetb_py3 source activate py36-wetb
conda install setuptools_scm future h5py pytables pytest nose sphinx psutil conda install setuptools_scm mock h5py pytables pytest nose sphinx psutil
conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl paramiko conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl paramiko
conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov conda install -c https://conda.anaconda.org/conda-forge pyscaffold pytest-cov
``` ```
......
# Anaconda (Windows/Mac/Linux) # Anaconda (Windows/Mac/Linux)
## Installation ## Installation
...@@ -7,9 +5,9 @@ ...@@ -7,9 +5,9 @@
Install the necessary Python dependencies using the ```conda``` package manager: Install the necessary Python dependencies using the ```conda``` package manager:
``` ```
>> conda install setuptools_scm future h5py pytables pytest pytest-cov nose sphinx blosc pbr paramiko >> conda install setuptools_scm mock h5py pytables pytest pytest-cov nose sphinx blosc pbr paramiko
>> conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl psutil >> conda install scipy pandas matplotlib cython xlrd coverage xlwt openpyxl psutil
>> conda install -c conda-forge pyscaffold sshtunnel --no-deps >> conda install -c conda-forge sshtunnel --no-deps
``` ```
Now you can install ```wetb``` with ```pip``` (there is no ```conda``` package Now you can install ```wetb``` with ```pip``` (there is no ```conda``` package
...@@ -32,34 +30,12 @@ expclicitally tell ```pip``` to only install ```wetb``` and nothing more: ...@@ -32,34 +30,12 @@ expclicitally tell ```pip``` to only install ```wetb``` and nothing more:
# Pip (Windows/Mac/Linux) # Pip (Windows/Mac/Linux)
Do not use this procedure in conda environments. See above.
## Installation and update ## Installation and update
``` ```
>> pip install --upgrade wetb >> pip install --upgrade wetb
``` ```
# Works with Python 2 and Python 3
This module is tested for Python 2.7 and 3.4+ compatibility, and works on both
Windows and Linux. Testing for Mac is on the way, but in theory it should work.
Python 2 and 3 compatibility is achieved with a single code base with the help
of the Python module [future](http://python-future.org/index.html).
Switching to Python 3 is in general a very good idea especially since Python 3.5
was released. Some even dare to say it
[is like eating your vegetables](http://nothingbutsnark.svbtle.com/porting-to-python-3-is-like-eating-your-vegetables).
So if you are still on Python 2, we would recommend you to give Python 3 a try!
You can automatically convert your code from Python 2 to 3 using the
[2to3](https://docs.python.org/2/library/2to3.html) utility which is included
in Python 2.7 by default. You can also write code that is compatible with both
2 and 3 at the same time (you can find additional resources in
[issue 1](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/issues/1)).
# Note
This project has been set up using PyScaffold 2.5. For details and usage
information on PyScaffold see http://pyscaffold.readthedocs.org/.
.. _installation:
Installation
===========================
Normal user
--------------------------------
* Quick install::
pip install wetb
* Install a specific version on PyPI::
pip install wetb==0.0.21
* Update an installation to the most recent version::
pip install --upgrade wetb
* Install with dependencies needed by prepost
pip install wetb[prepost]
* Install with all dependencies
pip install wetb[all]
**NOTE**. Dependency conflicts can arise if you do not install
``wetb`` into a clean environment. In particular, your installation
might break if ``wetb`` is installed using ``pip``, and then later
packages are installed using ``conda``. (See more details at
`this article <https://www.anaconda.com/blog/using-pip-in-a-conda-environment>`_.
We therefore recommend that you install ``wetb`` in a clean
environment.
Advanced user
--------------------------------
Clone the repository and install a local editable copy::
git clone https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox.git
cd WindEnergyToolbox
pip install -e .[all]
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
Source diff could not be displayed: it is too large. Options to address this: view the blob.
%% Cell type:markdown id: tags:
# Input file writing
%% Cell type:markdown id: tags:
## HTCFile
### Quickstart
The HTCFile class allows you to open, modify, save htc files and run HAWC2 simulations
%% Cell type:code id: tags:
``` python
from wetb import hawc2
from wetb.hawc2 import HTCFile
from wetb.hawc2.tests.test_files import tfp
htc = HTCFile(tfp + "htcfiles/DTU_10MW_RWT.htc")
htc.wind.wsp=11
print (htc)
htc.save("tmp/tmp.htc")
# htc.simulate('<path_to_hawc2>/hawc2mb.exe')
```
%% Output
;DTU_10MW_RWT, version 9, 25-09-2017, mhha
;
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
begin new_htc_structure;
; beam_output_file_name ./log/DTU_10MW_RWT_beam.dat; Optional - Calculated beam properties of the bodies are written to file
; body_output_file_name ./log/DTU_10MW_RWT_body.dat; Optional - Body initial position and orientation are written to file
; body_eigenanalysis_file_name ./eig/DTU_10MW_RWT_body_eigen.dat;
; structure_eigenanalysis_file_name ./eig/DTU_10MW_RWT_strc_eigen.dat ;
;-------------------------------------------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------------------------------------------
begin main_body; tower 115m
name tower;
type timoschenko;
nbodies 1;
node_distribution c2_def;
damping_posdef 0 0 0 0.00412 0.00412 0.00045; Mx My Mz Kx Ky Kz , M´s raises overall level, K´s raises high freguency level "tuned by Larh"
begin timoschenko_input;
filename ./data/DTU_10MW_RWT_Tower_st.dat;
set 1 1;
end timoschenko_input;
begin c2_def; Definition of centerline (main_body coordinates)
nsec 11;
sec 1 0 0 0 0; x,y,z,twist
sec 2 0 0 -11.5 0;
sec 3 0 0 -23 0;
sec 4 0 0 -34.5 0;
sec 5 0 0 -46 0;
sec 6 0 0 -57.5 0;
sec 7 0 0 -69 0;
sec 8 0 0 -80.5 0;
sec 9 0 0 -92 0;
sec 10 0 0 -103.5 0;
sec 11 0 0 -115.63 0;
end c2_def;
end main_body;
;
begin main_body;
name towertop;
type timoschenko;
nbodies 1;
node_distribution c2_def;
damping_posdef 0 0 0 0.007 0.007 0.007; "changed by Larh"
concentrated_mass 2 0 2.687 0.30061 446040 4106000 410600 4106000; Nacelle mass and inertia "corrected by Anyd 25/4/13"
begin timoschenko_input;
filename ./data/DTU_10MW_RWT_Towertop_st.dat;
set 1 2;
end timoschenko_input;
begin c2_def; Definition of centerline (main_body coordinates)
nsec 2;
sec 1 0 0 0 0; x,y,z,twist
sec 2 0 0 -2.75 0;
end c2_def;
end main_body;
;
begin main_body;
name shaft;
type timoschenko;
nbodies 1;
node_distribution c2_def;
damping_posdef 0 0 0 0.000465 0.000465 0.003983; "tuned by Anyd 23/5/13 to 31.45 log decr. damping for free free with stiff rotor and tower"
concentrated_mass 1 0 0 0 0 0 0 3751000; generator equivalent slow shaft "re_tuned by Anyd 20/2/13"
concentrated_mass 5 0 0 0 105520 0 0 325700; hub mass and inertia; "re_tuned by Anyd 20/2/13"
begin timoschenko_input;
filename ./data/DTU_10MW_RWT_Shaft_st.dat;
set 1 1;
end timoschenko_input;
begin c2_def; Definition of centerline (main_body coordinates)
nsec 5;
sec 1 0 0 0 0; Tower top x,y,z,twist
sec 2 0 0 1.5 0;
sec 3 0 0 3 0;
sec 4 0 0 4.4 0; Main bearing
sec 5 0 0 7.1 0; Rotor centre
end c2_def;
end main_body;
;
begin main_body;
name hub1;
type timoschenko;
nbodies 1;
node_distribution c2_def;
damping_posdef 0 0 0 3e-06 3e-06 2e-05; "changed by Larh"
begin timoschenko_input;
filename ./data/DTU_10MW_RWT_Hub_st.dat;
set 1 2;
end timoschenko_input;
begin c2_def; Definition of centerline (main_body coordinates)
nsec 2;
sec 1 0 0 0 0; x,y,z,twist
sec 2 0 0 2.8 0;
end c2_def;
end main_body;
;
begin main_body;
name hub2;
copy_main_body hub1;
end main_body;
;
begin main_body;
name hub3;
copy_main_body hub1;
end main_body;
;
begin main_body;
name blade1;
type timoschenko;
nbodies 10;
node_distribution c2_def;
damping_posdef 0 0 0 0.00153 0.00255 0.00033; " 3% damping tuned by tkim 23/03/13 unable to fit 3rd and higher mode"
begin timoschenko_input;
filename ./data/DTU_10MW_RWT_Blade_st.dat;
set 1 1; set subset
end timoschenko_input;
begin c2_def; Definition of centerline (main_body coordinates)
nsec 27;
sec 1 0 7.006e-05 4.44089e-16 -14.5;
sec 2 -2.06477e-05 -0.0122119 3 -14.5;
sec 3 -0.0072881 -0.0249251 6 -14.4851;
sec 4 -0.0189235 -0.0273351 7.00004 -14.461;
sec 5 -0.0541282 -0.0282163 8.70051 -14.3388;
sec 6 -0.126633 -0.021321 10.402 -14.0201;
sec 7 -0.225666 -0.0128378 12.2046 -13.3904;
sec 8 -0.288563 -0.00770659 13.2065 -12.9371;
sec 9 -0.399194 -0.00488317 15.01 -11.9445;
sec 10 -0.576634 -0.0180296 18.2151 -9.98243;
sec 11 -0.707136 -0.0501772 21.4178 -8.45147;
sec 12 -0.791081 -0.0941228 24.6189 -7.46417;
sec 13 -0.837195 -0.14888 27.8193 -6.72916;
sec 14 -0.853948 -0.214514 31.0194 -6.08842;
sec 15 -0.849367 -0.290618 34.2197 -5.49322;
sec 16 -0.79392 -0.462574 40.2204 -4.39222;
sec 17 -0.716284 -0.688437 46.6217 -3.09315;
sec 18 -0.634358 -0.960017 53.0232 -1.75629;
sec 19 -0.553179 -1.28424 59.4245 -0.50065;
sec 20 -0.475422 -1.66402 65.8255 0.601964;
sec 21 -0.40318 -2.10743 72.2261 1.5556;
sec 22 -0.330085 -2.6563 79.0266 2.51935;
sec 23 -0.31014 -2.78882 80.5267 2.7295;
sec 24 -0.286719 -2.92517 82.0271 2.93201;
sec 25 -0.255823 -3.06577 83.5274 3.11874;
sec 26 -0.207891 -3.20952 85.0277 3.28847;
sec 27 -0.089894 -3.33685 86.3655 3.42796;
end c2_def;
end main_body;
;
begin main_body;
name blade2;
copy_main_body blade1;
end main_body;
;
begin main_body;
name blade3;
copy_main_body blade1;
end main_body;
;-------------------------------------------------------------------------------------------------------------------------------
;
begin orientation;
begin base;
body tower;
inipos 0 0 0; initial position of node 1
body_eulerang 0 0 0;
end base;
;
begin relative;
body1 tower last;
body2 towertop 1;
body2_eulerang 0 0 0;
end relative;
;
begin relative;
body1 towertop last;
body2 shaft 1;
body2_eulerang 90 0 0;
body2_eulerang 5 0 0; 5 deg tilt angle
mbdy2_ini_rotvec_d1 0 0 -1 0.2; mbdy2_ini_rotvec_d1 0.0 0.0 -1.0 [init_wr];
end relative;
;
begin relative;
body1 shaft last;
body2 hub1 1;
body2_eulerang -90 0 0;
body2_eulerang 0 180 0;
body2_eulerang 2.5 0 0; 2.5deg cone angle
end relative;
;
begin relative;
body1 shaft last;
body2 hub2 1;
body2_eulerang -90 0 0;
body2_eulerang 0 60 0;
body2_eulerang 2.5 0 0; 2.5deg cone angle
end relative;
;
begin relative;
body1 shaft last;
body2 hub3 1;
body2_eulerang -90 0 0;
body2_eulerang 0 -60 0;
body2_eulerang 2.5 0 0; 2.5deg cone angle
end relative;
;
begin relative;
body1 hub1 last;
body2 blade1 1;
body2_eulerang 0 0 0;
end relative;
;
begin relative;
body1 hub2 last;
body2 blade2 1;
body2_eulerang 0 0 0;
end relative;
;
begin relative;
body1 hub3 last;
body2 blade3 1;
body2_eulerang 0 0 0;
end relative;
;
end orientation;
;-------------------------------------------------------------------------------------------------------------------------------
begin constraint;
;
begin fix0; fixed to ground in translation and rotation of node 1
body tower;
end fix0;
;
begin fix1;
body1 tower last;
body2 towertop 1;
end fix1;
;
begin bearing1; free bearing
name shaft_rot;
body1 towertop last;
body2 shaft 1;
bearing_vector 2 0 0 -1; x=coo (0=global.1=body1.2=body2) vector in body2 coordinates where the free rotation is present
end bearing1;
;
begin fix1;
body1 shaft last;
body2 hub1 1;
end fix1;
;
begin fix1;
body1 shaft last;
body2 hub2 1;
end fix1;
;
begin fix1;
body1 shaft last;
body2 hub3 1;
end fix1;
;
begin bearing2;
name pitch1;
body1 hub1 last;
body2 blade1 1;
bearing_vector 2 0 0 -1;
end bearing2;
;
begin bearing2;
name pitch2;
body1 hub2 last;
body2 blade2 1;
bearing_vector 2 0 0 -1;
end bearing2;
;
begin bearing2;
name pitch3;
body1 hub3 last;
body2 blade3 1;
bearing_vector 2 0 0 -1;
end bearing2;
end constraint;
;
end new_htc_structure;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
begin wind;
density 1.225;
wsp 11;
tint 0;
horizontal_input 1;
windfield_rotations 0 0 0; yaw, tilt, rotation
center_pos0 0 0 -119; hub heigth
shear_format 1 0.2;
turb_format 0; 0=none, 1=mann,2=flex
tower_shadow_method 0; 0=none, 1=potential flow, 2=jet
scale_time_start 0;
wind_ramp_factor 0 40 0.6 1;
; Steps ;
wind_ramp_abs 140 141 0 1; wsp. after the step: 5.0
wind_ramp_abs 181 182 0 1; wsp. after the step: 6.0
wind_ramp_abs 222 223 0 1; wsp. after the step: 7.0
wind_ramp_abs 263 264 0 1; wsp. after the step: 8.0
wind_ramp_abs 304 305 0 1; wsp. after the step: 9.0
wind_ramp_abs 345 346 0 1; wsp. after the step: 10.0
wind_ramp_abs 386 387 0 1; wsp. after the step: 11.0
wind_ramp_abs 427 428 0 1; wsp. after the step: 12.0
wind_ramp_abs 468 469 0 1; wsp. after the step: 13.0
wind_ramp_abs 509 510 0 1; wsp. after the step: 14.0
wind_ramp_abs 550 551 0 1; wsp. after the step: 15.0
wind_ramp_abs 591 592 0 1; wsp. after the step: 16.0
wind_ramp_abs 632 633 0 1; wsp. after the step: 17.0
wind_ramp_abs 673 674 0 1; wsp. after the step: 18.0
wind_ramp_abs 714 715 0 1; wsp. after the step: 19.0
wind_ramp_abs 755 756 0 1; wsp. after the step: 20.0
wind_ramp_abs 796 797 0 1; wsp. after the step: 21.0
wind_ramp_abs 837 838 0 1; wsp. after the step: 22.0
wind_ramp_abs 878 879 0 1; wsp. after the step: 23.0
wind_ramp_abs 919 920 0 1; wsp. after the step: 24.0
wind_ramp_abs 960 961 0 1; wsp. after the step: 25.0
;
begin tower_shadow_potential_2;
tower_mbdy_link tower;
nsec 2;
radius 0 4.15;
radius 115.63 2.75;
end tower_shadow_potential_2;
end wind;
;
begin aerodrag;
begin aerodrag_element;
mbdy_name tower;
aerodrag_sections uniform 10;
nsec 2;
sec 0 0.6 8.3; tower bottom
sec 115.63 0.6 5.5; tower top
end aerodrag_element;
;
begin aerodrag_element; Nacelle drag side
mbdy_name shaft;
aerodrag_sections uniform 2;
nsec 2;
sec 0 0.8 10;
sec 7.01 0.8 10;
end aerodrag_element;
end aerodrag;
;
begin aero;
nblades 3;
hub_vec shaft -3; rotor rotation vector (normally shaft composant directed from pressure to sustion side)
link 1 mbdy_c2_def blade1;
link 2 mbdy_c2_def blade2;
link 3 mbdy_c2_def blade3;
ae_filename ./data/DTU_10MW_RWT_ae.dat;
pc_filename ./data/DTU_10MW_RWT_pc.dat;
induction_method 1; 0=none, 1=normal
aerocalc_method 1; 0=ingen aerodynamic, 1=med aerodynamic
aerosections 50; def. 50
ae_sets 1 1 1;
tiploss_method 1; 0=none, 1=prandtl
dynstall_method 2; 0=none, 1=stig øye method,2=mhh method
;
end aero;
;-------------------------------------------------------------------------------------------------
begin dll;
;
begin type2_dll;
name dtu_we_controller;
filename ./control/dtu_we_controller.dll;
dll_subroutine_init init_regulation_advanced;
dll_subroutine_update update_regulation;
arraysizes_init 100 1;
arraysizes_update 100 100;
begin init;
; Overall parameters
constant 1 10000; Rated power [kW]
constant 2 0.628; Minimum rotor (LSS) speed [rad/s]
constant 3 1.005; Rated rotor (LSS) speed [rad/s]
constant 4 15600000; Maximum allowable generator torque [Nm]
constant 5 100; Minimum pitch angle, theta_min [deg],
; if |theta_min|>90, then a table of <wsp,theta_min> is read ;
; from a file named 'wptable.n', where n=int(theta_min)
constant 6 82; Maximum pitch angle [deg]
constant 7 10; Maximum pitch velocity operation [deg/s]
constant 8 0.4; Frequency of generator speed filter [Hz]
constant 9 0.7; Damping ratio of speed filter [-]
constant 10 1.8; Frequency of free-free DT torsion mode [Hz], if zero no notch filter used
; Partial load control parameters
constant 11 13013100; Optimal Cp tracking K factor [Nm/(rad/s)^2], ;
; Qg=K*Omega^2, K=eta*0.5*rho*A*Cp_opt*R^3/lambda_opt^3
constant 12 68345600; Proportional gain of torque controller [Nm/(rad/s)]
constant 13 15336700; Integral gain of torque controller [Nm/rad]
constant 14 0; Differential gain of torque controller [Nm/(rad/s^2)]
; Full load control parameters
constant 15 1; Generator control switch [1=constant power, 2=constant torque]
constant 16 1.06713; Proportional gain of pitch controller [rad/(rad/s)]
constant 17 0.242445; Integral gain of pitch controller [rad/rad]
constant 18 0; Differential gain of pitch controller [rad/(rad/s^2)]
constant 19 4e-09; Proportional power error gain [rad/W]
constant 20 4e-09; Integral power error gain [rad/(Ws)]
constant 21 11.4; Coefficient of linear term in aerodynamic gain scheduling, KK1 [deg]
constant 22 402.9; Coefficient of quadratic term in aerodynamic gain scheduling, KK2 [deg^2] &
; (if zero, KK1 = pitch angle at double gain)
constant 23 1.3; Relative speed for double nonlinear gain [-]
; Cut-in simulation parameters
constant 24 -1; Cut-in time [s], no cut-in is simulated if zero or negative
constant 25 1; Time delay for soft start of torque [1/1P]
; Cut-out simulation parameters
constant 26 -1; Shut-down time [s], no shut-down is simulated if zero or negative
constant 27 5; Time of linear torque cut-out during a generator assisted stop [s]
constant 28 1; Stop type [1=normal, 2=emergency]
constant 29 1; Time delay for pitch stop after shut-down signal [s]
constant 30 3; Maximum pitch velocity during initial period of stop [deg/s]
constant 31 3; Time period of initial pitch stop phase [s] (maintains pitch speed specified in constant 30)
constant 32 4; Maximum pitch velocity during final phase of stop [deg/s]
; Expert parameters (keep default values unless otherwise given)
constant 33 2; Time for the maximum torque rate = Maximum allowable generator torque/(constant 33 + 0.01s) [s]
constant 34 2; Upper angle above lowest minimum pitch angle for switch [deg], if equal then hard switch
constant 35 95; Percentage of the rated speed when the torque limits are fully opened [%]
constant 36 2; Time constant of 1st order filter on wind speed used for minimum pitch [1/1P]
constant 37 1; Time constant of 1st order filter on pitch angle used for gain scheduling [1/1P]
; Drivetrain damper
constant 38 0; Proportional gain of active DT damper [Nm/(rad/s)], requires frequency in input 10
; Over speed
constant 39 25; Overspeed percentage before initiating turbine controller alarm (shut-down) [%]
; Additional non-linear pitch control term (not used when all zero)
constant 40 0; Rotor speed error scaling factor [rad/s]
constant 41 0; Rotor acceleration error scaling factor [rad/s^2]
constant 42 0; Pitch rate gain [rad/s]
; Storm control command
constant 43 28; Wind speed 'Vstorm' above which derating of rotor speed is used [m/s]
constant 44 28; Cut-out wind speed (only used for derating of rotor speed in storm) [m/s]
; Safety system parameters
constant 45 30; Overspeed percentage before initiating safety system alarm (shut-down) [%]
constant 46 1.5; Max low-pass filtered tower top acceleration level [m/s^2]
; Turbine parameter
constant 47 178; Nominal rotor diameter [m]
; Parameters for rotor inertia reduction in variable speed region
constant 48 0; Proportional gain on rotor acceleration in variable speed region [Nm/(rad/s^2)] (not used when zero)
; Parameters for alternative partial load controller with PI regulated TSR tracking
constant 49 7.8; Optimal tip speed ratio [-] (only used when K=constant 11 = 0 otherwise Qg=K*Omega^2 is used)
; Parameters for adding aerodynamic drivetrain damping on gain scheduling
constant 50 0; Aerodynamic DT damping coefficient at the operational point of zero pitch angle [Nm/(rad/s)] (not used when zero)
constant 51 0; Coefficient of linear term in aerodynamic DT damping scheduling, KK1 [deg]
constant 52 0; Coefficient of quadratic term in aerodynamic DT damping scheduling, KK2 [deg^2]
; Torque exclusion zone
constant 53 0; Exclusion zone: Lower speed limit [rad/s] (Default 0 used if zero)
constant 54 0; Exclusion zone: Generator torque at lower limit [Nm] (Default 0 used if zero)
constant 55 0; Exclusion zone: Upper speed limit [rad/s] (if =< 0 then exclusion zone functionality is inactive)
constant 56 0; Exclusion zone: Generator torque at upper limit [Nm] (Default 0 used if zero)
constant 57 0; Time constant of reference switching at exclusion zone [s] (Default 0 used if zero)
; DT torsion mode damper
constant 58 0; Frequency of notch filter [Hz] (Default 10 x input 10 used if zero)
constant 59 0; Damping of BP filter [-] (Default 0.02 used if zero)
constant 60 0; Damping of notch filter [-] (Default 0.01 used if zero)
constant 61 0; Phase lag of damper [s] => max 40*dt (Default 0 used if zero)
; Fore-aft Tower mode damper
constant 62 0; Frequency of BP filter [Hz] (Default 10 used if zero)\\
constant 63 0; Frequency of notch fiter [Hz] (Default 10 used if zero)\\
constant 64 0; Damping of BP filter [-] (Default 0.02 used if zero)\\
constant 65 0; Damping of notch filter [-] (Default 0.01 used if zero)\\
constant 66 0; Gain of damper [-] (Default 0 used if zero)\\
constant 67 0; Phase lag of damper [s] => max 40*dt (Default 0 used if zero)\\
constant 68 0; Time constant of 1st order filter on PWR used for fore-aft Tower mode damper GS [Hz] (Default 10 used if zero)
constant 69 0; Lower PWR limit used for fore-aft Tower mode damper GS [-] (Default 0 used if zero)
constant 70 0; Upper PWR limit used for fore-aft Tower mode damper GS [-] (Default 0 used if zero)
; Side-to-side Tower mode filter
constant 71 0; Frequency of Tower side-to-sede notch filter [Hz] (Default 100 used if zero)
constant 72 0; Damping of notch filter [-] (Default 0.01 used if zero)
constant 73 0; Max low-pass filtered tower top acceleration level before initiating safety system alarm (shut-down) [m/s^2] (Default 1.1 x input 46 used if zero)
constant 74 0; Time constant of 1st order filter on tower top acceleration [1/1P] (Default 1 used if zero)
; Pitch deviation monitor parameters
constant 75 1005020; Parameters for pitch deviation monitoring. The format is 1,nnn,mmm
; where 'nnn' [s] is the period of the moving average and 'mmm' is threshold of the deviation [0.1 deg] (functionality is inactive if value $<$ 1,000,000)
; Gear ratio
constant 76 0; Gear ratio used for the calculation of the LSS rotational speeds and the HSS generator torque reference [-] (Default 1 if zero)
end init;
;
begin output;
general time; [s]
constraint bearing1 shaft_rot 1 only 2; Drivetrain speed [rad/s]
constraint bearing2 pitch1 1 only 1; [rad]
constraint bearing2 pitch2 1 only 1; [rad]
constraint bearing2 pitch3 1 only 1; [rad]
wind free_wind 1 0 0 -119; Global coordinates at hub height
dll inpvec 2 2; Elec. power from generator servo .dll
dll inpvec 2 8; Grid state flag from generator servo .dll
mbdy state acc towertop 1 1 global only 1; Tower top x-acceleration [m/s^2]
mbdy state acc towertop 1 1 global only 2; Tower top y-acceleration [m/s^2]
end output;
end type2_dll;
;
begin type2_dll;
name generator_servo;
filename ./control/generator_servo.dll;
dll_subroutine_init init_generator_servo;
dll_subroutine_update update_generator_servo;
arraysizes_init 100 1;
arraysizes_update 100 100;
begin init;
constant 1 20; Frequency of 2nd order servo model of generator-converter system [Hz]
constant 2 0.9; Damping ratio 2nd order servo model of generator-converter system [-]
constant 3 15600000; Maximum allowable LSS torque (pull-out torque) [Nm]
constant 4 0.94; Generator efficiency [-]
constant 5 1; Gearratio [-]
constant 6 0; Time for half value in softstart of torque [s]
constant 7 -1; Time for grid loss [s] (never if lower than zero)
end init;
;
begin output;
general time; Time [s]
dll inpvec 1 1; Electrical torque reference [Nm]
constraint bearing1 shaft_rot 1 only 2; Generator LSS speed [rad/s]
mbdy momentvec shaft 1 1 shaft only 3; Shaft moment [kNm] (Qshaft)
end output;
;
begin actions;
mbdy moment_int shaft 1 -3 shaft towertop 2; Generator LSS torque [Nm]
end actions;
end type2_dll;
;
begin type2_dll;
name mech_brake;
filename ./control/mech_brake.dll;
dll_subroutine_init init_mech_brake;
dll_subroutine_update update_mech_brake;
arraysizes_init 100 1;
arraysizes_update 100 100;
begin init;
constant 1 9360000; Fully deployed maximum brake torque [Nm] (0.6*max torque)
constant 2 100; Parameter alpha used in Q = tanh(omega*alpha), typically 1e2/Omega_nom
constant 3 0.5; Delay time for before brake starts to deploy [s]
constant 4 0.6; Time for brake to become fully deployed [s]
end init;
;
begin output;
general time; Time [s]
constraint bearing1 shaft_rot 1 only 2; Generator LSS speed [rad/s]
dll inpvec 1 25; Command to deploy mechanical disc brake [0,1]
end output;
;
begin actions;
mbdy moment_int shaft 1 -3 shaft towertop 2; Brake LSS torque [Nm]
end actions;
end type2_dll;
;
begin type2_dll;
name servo_with_limits;
filename ./control/servo_with_limits.dll;
dll_subroutine_init init_servo_with_limits;
dll_subroutine_update update_servo_with_limits;
arraysizes_init 100 1;
arraysizes_update 100 100;
begin init;
constant 1 3; Number of blades [-]
constant 2 1; Frequency of 2nd order servo model of pitch system [Hz]
constant 3 0.7; Damping ratio 2nd order servo model of pitch system [-]
constant 4 10; Max. pitch speed [deg/s]
constant 5 15; Max. pitch acceleration [deg/s^2]
constant 6 -5; Min. pitch angle [deg]
constant 7 90; Max. pitch angle [deg]
constant 8 -1; Time for pitch runaway [s]
constant 9 -1; Time for stuck blade 1 [s]
constant 10 0; Angle of stuck blade 1 [deg] (if > 90 deg then blade is stuck at instantaneous angle)
end init;
begin output;
general time; Time [s]
dll inpvec 1 2; Pitch1 demand angle [rad]
dll inpvec 1 3; Pitch2 demand angle [rad]
dll inpvec 1 4; Pitch3 demand angle [rad]
dll inpvec 1 26; Flag for emergency pitch stop [0=off/1=on]
end output;
;
begin actions;
constraint bearing2 angle pitch1; Angle pitch1 bearing [rad]
constraint bearing2 angle pitch2; Angle pitch2 bearing [rad]
constraint bearing2 angle pitch3; Angle pitch3 bearing [rad]
end actions;
end type2_dll;
;
; --- DLL for tower-blade tip distance -- ;
;-------------------------------------------
begin type2_dll;
name towerclearance_mblade;
filename ./control/towerclearance_mblade.dll;
dll_subroutine_init initialize;
dll_subroutine_update update;
arraysizes_init 3 1;
arraysizes_update 15 6;
begin init; Variables passed into initialization function
constant 1 4.15; Tower radius at tower bottom [m]
constant 2 2.75; Tower radius at tower top [m]
constant 3 3; Number of points to check [-]
end init;
begin output; Variables passed into update function
mbdy state pos tower 1 0 global; [1,2,3] global coordinates of tower base
mbdy state pos tower 10 1 global; [4,5,6] global coordinates of tower top
mbdy state pos blade1 26 1 global; [7,8,9] global coordinates of point 1 (blade 1 tip)
mbdy state pos blade2 26 1 global; [10,11,12] global coordinates of point 2 (blade 2 tip)
mbdy state pos blade3 26 1 global; [13,14,15] global coordinates of point 3 (blade 3 tip)
end output;
end type2_dll;
;
end dll;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
;
begin output;
filename ./res/DTU_10MW_RWT_ver09;
data_format hawc_binary;
buffer 1;
;
general time;
constraint bearing1 shaft_rot 2; angle and angle velocity
constraint bearing2 pitch1 5; angle and angle velocity
constraint bearing2 pitch2 5; angle and angle velocity
constraint bearing2 pitch3 5; angle and angle velocity
aero omega;
aero torque;
aero power;
aero thrust;
wind free_wind 1 0 0 -119; local wind at fixed position: coo (1=global,2=non-rotation rotor coo.), pos x, pos y, pos z
; Moments:
mbdy momentvec tower 1 1 tower # tower base;
mbdy momentvec tower 10 2 tower # tower yaw bearing;
mbdy momentvec shaft 4 1 shaft # main bearing;
mbdy momentvec blade1 2 2 blade1 # blade 1 root;
mbdy momentvec blade2 2 2 blade2 # blade 2 root;
mbdy momentvec blade3 2 2 blade3 # blade 3 root;
mbdy momentvec blade1 13 1 local # blade 1 50% local e coo;
mbdy momentvec blade2 13 1 local # blade 2 50% local e coo;
mbdy momentvec blade3 13 1 local # blade 3 50% local e coo;
; Displacements and accellerations
mbdy state pos tower 10 1 global only 1 # Tower top FA displ;
mbdy state pos tower 10 1 global only 2 # Tower top SS displ;
mbdy state acc tower 10 1 global only 1 # Tower top FA acc;
mbdy state acc tower 10 1 global only 2 # Tower top SS acc;
;
mbdy state pos blade1 26 1 blade1 # blade 1 tip pos;
mbdy state pos blade2 26 1 blade2 # blade 2 tip pos;
mbdy state pos blade3 26 1 blade3 # blade 3 tip pos;
mbdy state pos blade1 26 1 global # gl blade 1 tip pos;
; - Monitor Aerodynamics - ;
aero windspeed 3 1 1 72.5;
aero alfa 1 72.5;
aero alfa 2 72.5;
aero alfa 3 72.5;
aero cl 1 72.5;
aero cl 2 72.5;
aero cl 3 72.5;
aero cd 1 72.5;
aero cd 2 72.5;
aero cd 3 72.5;
; DLL outputs and into HAWC2
dll inpvec 1 1 # Generator torque reference [Nm];
dll inpvec 1 2 # Pitch angle reference of blade 1 [rad];
dll inpvec 1 3 # Pitch angle reference of blade 2 [rad];
dll inpvec 1 4 # Pitch angle reference of blade 3 [rad];
dll inpvec 1 5 # Power reference [W];
dll inpvec 1 6 # Filtered wind speed [m/s];
dll inpvec 1 7 # Filtered rotor speed [rad/s];
dll inpvec 1 8 # Filtered rotor speed error for torque [rad/s];
dll inpvec 1 9 # Bandpass filtered rotor speed [rad/s];
dll inpvec 1 10 # Proportional term of torque contr. [Nm];
dll inpvec 1 11 # Integral term of torque controller [Nm];
dll inpvec 1 12 # Minimum limit of torque [Nm];
dll inpvec 1 13 # Maximum limit of torque [Nm];
dll inpvec 1 14 # Torque limit switch based on pitch [-];
dll inpvec 1 15 # Filtered rotor speed error for pitch [rad/s];
dll inpvec 1 16 # Power error for pitch [W];
dll inpvec 1 17 # Proportional term of pitch controller [rad];
dll inpvec 1 18 # Integral term of pitch controller [rad];
dll inpvec 1 19 # Minimum limit of pitch [rad];
dll inpvec 1 20 # Maximum limit of pitch [rad];
dll inpvec 1 21 # Torque reference from DT dammper [Nm];
dll inpvec 1 22 # Status signal [-];
dll inpvec 1 23 # Total added pitch rate [rad/s];
dll inpvec 1 24 # Filtered Mean pitch for gain sch [rad];
dll inpvec 1 25 # Flag for mechnical brake [0=off/1=on];
dll inpvec 1 26 # Flag for emergency pitch stop [0=off/1=on];
dll inpvec 1 27 # LP filtered acceleration level [m/s^2];
dll inpvec 1 31 # Monitored average of reference pitch [rad];
dll inpvec 1 32 # Monitored ave. of actual pitch (blade 1) [rad];
; Input from generator model
dll inpvec 2 1 # Mgen LSS [Nm];
dll inpvec 2 2 # Pelec [W];
dll inpvec 2 3 # Mframe [Nm];
dll inpvec 2 4 # Mgen HSS [Nm];
dll inpvec 2 8 # Grid flag [0=run/1=stop];
; Input from mechanical brake
dll inpvec 3 1 # Brake torque [Nm];
; Input from pitch servo
dll inpvec 4 1 # pitch 1 [rad];
dll inpvec 4 2 # pitch 2 [rad];
dll inpvec 4 3 # pitch 3 [rad];
; Check tower clearence
dll inpvec 5 1 # Bltip tow min d [m];
end output;
;
exit;
%% Cell type:markdown id: tags:
### Load htc files
`HTCFile` takes the htc-filename and optionally the modelpath as input.
The `modelpath` is the path from where HAWC2 should be run, i.e. the the origion for relative data file paths in the htc file. If not specified (default) the `modelpath` is autodetected if possible.
%% Cell type:code id: tags:
``` python
htc = HTCFile(filename=tfp+"htcfiles/DTU_10MW_RWT.htc",
modelpath=None # modelpath autodetected
)
print (htc.modelpath)
```
%% Output
C:/mmpe/programming/python/WindEnergyToolbox/wetb/hawc2/tests/test_files/
%% Cell type:markdown id: tags:
### Access htc contents
Access elements(lines and sections) in the htc file via dot or string notation
%% Cell type:code id: tags:
``` python
wsp = htc.wind.wsp # dot notation
print (wsp)
convergence_limits = htc['simulation.convergence_limits'] # string notation with dot
print (convergence_limits)
```
%% Output
wsp 4;
convergence_limits 1000 1 1e-07;
%% Cell type:markdown id: tags:
you can also store a (sub)section in a varble and access subelements from that
%% Cell type:code id: tags:
``` python
wind = htc.wind
print (wind.wsp)
```
%% Output
wsp 4;
%% Cell type:markdown id: tags:
Values of a line are obtained by
%% Cell type:code id: tags:
``` python
print (wsp[0])
print (htc.simulation.convergence_limits[:])
```
%% Output
4
[1000, 1, 1e-07]
%% Cell type:markdown id: tags:
In case there is more than one element with the same name, e.g. main_body sections in new_htc_structure:
%% Cell type:code id: tags:
``` python
htc.new_htc_structure.keys()
```
%% Output
['main_body',
'main_body__2',
'main_body__3',
'main_body__4',
'main_body__5',
'main_body__6',
'main_body__7',
'main_body__8',
'main_body__9',
'orientation',
'constraint']
%% Cell type:markdown id: tags:
Then the right element can be access by adding `__x` (where x is the section number).
The first element can be accessed without `__x` or with `__1`
%% Cell type:code id: tags:
``` python
htc.new_htc_structure.main_body__1 == htc.new_htc_structure.main_body
```
%% Output
True
%% Cell type:markdown id: tags:
Another way to access these elements are:
%% Cell type:code id: tags:
``` python
htc.new_htc_structure.get_subsection_by_name('shaft')
htc.new_htc_structure.main_body(name='shaft')
```
%% Output
<wetb.hawc2.htc_contents.HTCSection at 0x1ff94e5eb50>
%% Cell type:markdown id: tags:
#### HTC Section
%% Cell type:code id: tags:
``` python
section = htc.new_htc_structure.main_body__3.c2_def
print(section.section_name)
print(section.keys())
print(section.parent.section_name)
print(section.parent.location())
print()
print(section)
```
%% Output
c2_def
['nsec', 'sec', 'sec__2', 'sec__3', 'sec__4', 'sec__5']
main_body
DTU_10MW_RWT.htc/new_htc_structure/main_body__3
begin c2_def; Definition of centerline (main_body coordinates)
nsec 5;
sec 1 0 0 0 0; Tower top x,y,z,twist
sec 2 0 0 1.5 0;
sec 3 0 0 3 0;
sec 4 0 0 4.4 0; Main bearing
sec 5 0 0 7.1 0; Rotor centre
end c2_def;
%% Cell type:markdown id: tags:
#### HTC Line
%% Cell type:code id: tags:
``` python
line = htc.new_htc_structure.main_body__3.c2_def.sec__4
print(line.values) # print all values in line
print(line.values[3]) # print value 4 (zero-indexed)
print(line.comments) # print comments
print()
print(line) # print line
```
%% Output
[4, 0, 0, 4.4, 0]
4.4
Main bearing
sec 4 0 0 4.4 0; Main bearing
%% Cell type:markdown id: tags:
#### Output sensor
%% Cell type:code id: tags:
``` python
print (htc.output.sensors[3])
print (htc.output.sensors[3].type)
print (htc.output.sensors[3].sensor)
print (htc.output.sensors[3].values)
print (htc.output.sensors[3].comments)
```
%% Output
constraint bearing2 pitch2 5; angle and angle velocity
constraint
bearing2
['pitch2', 5]
angle and angle velocity
%% Cell type:markdown id: tags:
### Add htc contents
#### Add htc line
%% Cell type:code id: tags:
``` python
htc.simulation.my_line = "value1", 2
htc.simulation.my_line.comments = "MyComment"
print (htc.simulation)
```
%% Output
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
my_line value1 2; MyComment
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
%% Cell type:markdown id: tags:
In case there is already one line with the same key, then you need to use the `add_line` function
%% Cell type:code id: tags:
``` python
htc.simulation.add_line(name="my_line",
values=["value1", 2],
comments="MyComment for second my_line" #defaults to ""
)
print (htc.simulation)
```
%% Output
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
my_line value1 2; MyComment
my_line value1 2; MyComment for second my_line
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
%% Cell type:markdown id: tags:
#### Add htc section
%% Cell type:code id: tags:
``` python
my_section = htc.simulation.add_section(section_name="my_section",
members={"Line1":1, "line2":[21,22,23]},
allow_duplicate=False,
line3=[31,32])
print (htc.simulation)
```
%% Output
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
my_line value1 2; MyComment
my_line value1 2; MyComment for second my_line
begin my_section;
line3 31 32;
Line1 1;
line2 21 22 23;
end my_section;
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
%% Cell type:markdown id: tags:
If `allow_duplicate` is `False` and a section with the same name already exists, then `add_section` has no effect
%% Cell type:code id: tags:
``` python
my_section = htc.simulation.add_section(section_name="my_section",
allow_duplicate=False,
line4=4)
print (htc.simulation)
```
%% Output
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
my_line value1 2; MyComment
my_line value1 2; MyComment for second my_line
begin my_section;
line3 31 32;
Line1 1;
line2 21 22 23;
end my_section;
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
%% Cell type:markdown id: tags:
#### Add output sensor
%% Cell type:code id: tags:
``` python
htc.output.add_sensor('sensor_type', 'sensor_name', ['arg1', 2], comment = "MySensor", nr=3)
print (htc.output)
```
%% Output
begin output;
filename ./res/DTU_10MW_RWT_ver09;
data_format hawc_binary;
buffer 1;
;
general time;
constraint bearing1 shaft_rot 2; angle and angle velocity
constraint bearing2 pitch1 5; angle and angle velocity
sensor_type sensor_name arg1 2; MySensor
constraint bearing2 pitch2 5; angle and angle velocity
constraint bearing2 pitch3 5; angle and angle velocity
aero omega;
aero torque;
aero power;
aero thrust;
wind free_wind 1 0 0 -119; local wind at fixed position: coo (1=global,2=non-rotation rotor coo.), pos x, pos y, pos z
; Moments:
mbdy momentvec tower 1 1 tower # tower base;
mbdy momentvec tower 10 2 tower # tower yaw bearing;
mbdy momentvec shaft 4 1 shaft # main bearing;
mbdy momentvec blade1 2 2 blade1 # blade 1 root;
mbdy momentvec blade2 2 2 blade2 # blade 2 root;
mbdy momentvec blade3 2 2 blade3 # blade 3 root;
mbdy momentvec blade1 13 1 local # blade 1 50% local e coo;
mbdy momentvec blade2 13 1 local # blade 2 50% local e coo;
mbdy momentvec blade3 13 1 local # blade 3 50% local e coo;
; Displacements and accellerations
mbdy state pos tower 10 1 global only 1 # Tower top FA displ;
mbdy state pos tower 10 1 global only 2 # Tower top SS displ;
mbdy state acc tower 10 1 global only 1 # Tower top FA acc;
mbdy state acc tower 10 1 global only 2 # Tower top SS acc;
;
mbdy state pos blade1 26 1 blade1 # blade 1 tip pos;
mbdy state pos blade2 26 1 blade2 # blade 2 tip pos;
mbdy state pos blade3 26 1 blade3 # blade 3 tip pos;
mbdy state pos blade1 26 1 global # gl blade 1 tip pos;
; - Monitor Aerodynamics - ;
aero windspeed 3 1 1 72.5;
aero alfa 1 72.5;
aero alfa 2 72.5;
aero alfa 3 72.5;
aero cl 1 72.5;
aero cl 2 72.5;
aero cl 3 72.5;
aero cd 1 72.5;
aero cd 2 72.5;
aero cd 3 72.5;
; DLL outputs and into HAWC2
dll inpvec 1 1 # Generator torque reference [Nm];
dll inpvec 1 2 # Pitch angle reference of blade 1 [rad];
dll inpvec 1 3 # Pitch angle reference of blade 2 [rad];
dll inpvec 1 4 # Pitch angle reference of blade 3 [rad];
dll inpvec 1 5 # Power reference [W];
dll inpvec 1 6 # Filtered wind speed [m/s];
dll inpvec 1 7 # Filtered rotor speed [rad/s];
dll inpvec 1 8 # Filtered rotor speed error for torque [rad/s];
dll inpvec 1 9 # Bandpass filtered rotor speed [rad/s];
dll inpvec 1 10 # Proportional term of torque contr. [Nm];
dll inpvec 1 11 # Integral term of torque controller [Nm];
dll inpvec 1 12 # Minimum limit of torque [Nm];
dll inpvec 1 13 # Maximum limit of torque [Nm];
dll inpvec 1 14 # Torque limit switch based on pitch [-];
dll inpvec 1 15 # Filtered rotor speed error for pitch [rad/s];
dll inpvec 1 16 # Power error for pitch [W];
dll inpvec 1 17 # Proportional term of pitch controller [rad];
dll inpvec 1 18 # Integral term of pitch controller [rad];
dll inpvec 1 19 # Minimum limit of pitch [rad];
dll inpvec 1 20 # Maximum limit of pitch [rad];
dll inpvec 1 21 # Torque reference from DT dammper [Nm];
dll inpvec 1 22 # Status signal [-];
dll inpvec 1 23 # Total added pitch rate [rad/s];
dll inpvec 1 24 # Filtered Mean pitch for gain sch [rad];
dll inpvec 1 25 # Flag for mechnical brake [0=off/1=on];
dll inpvec 1 26 # Flag for emergency pitch stop [0=off/1=on];
dll inpvec 1 27 # LP filtered acceleration level [m/s^2];
dll inpvec 1 31 # Monitored average of reference pitch [rad];
dll inpvec 1 32 # Monitored ave. of actual pitch (blade 1) [rad];
; Input from generator model
dll inpvec 2 1 # Mgen LSS [Nm];
dll inpvec 2 2 # Pelec [W];
dll inpvec 2 3 # Mframe [Nm];
dll inpvec 2 4 # Mgen HSS [Nm];
dll inpvec 2 8 # Grid flag [0=run/1=stop];
; Input from mechanical brake
dll inpvec 3 1 # Brake torque [Nm];
; Input from pitch servo
dll inpvec 4 1 # pitch 1 [rad];
dll inpvec 4 2 # pitch 2 [rad];
dll inpvec 4 3 # pitch 3 [rad];
; Check tower clearence
dll inpvec 5 1 # Bltip tow min d [m];
end output;
;
%% Cell type:markdown id: tags:
### Modify htc contents
%% Cell type:code id: tags:
``` python
htc.wind.wsp = 12 # set single value element
print (htc.wind.wsp)
c2def = htc.new_htc_structure.main_body__3.c2_def
c2def.section_name = "c2_def_new"
c2def.sec__4 = 1,2,3,4 # set element with four values
c2def.sec__4[3] = 9
print (c2def)
```
%% Output
wsp 12;
begin c2_def_new; Definition of centerline (main_body coordinates)
nsec 5;
sec 1 0 0 0 0; Tower top x,y,z,twist
sec 2 0 0 1.5 0;
sec 3 0 0 3 0;
sec 1 2 3 9; Main bearing
sec 5 0 0 7.1 0; Rotor centre
end c2_def_new;
%% Cell type:markdown id: tags:
Note, that you cannot change modify values of the current line, e.g.
```python
line = htc.new_htc_structure.main_body__3.c2_def.sec__4
line = 1,2,3,4
```
as it will overwrite the variable `line` with the tuple (1,2,3,4) instead of updating the values
%% Cell type:markdown id: tags:
### Delete
Sections and lines are deleted by calling their `delete` method
%% Cell type:code id: tags:
``` python
htc.simulation.my_line.delete() # second my_line (my_line__2) remains
htc.simulation.my_section.delete()
print (htc.simulation)
```
%% Output
begin simulation;
time_stop 1000;
solvertype 1; (newmark)
on_no_convergence continue;
convergence_limits 1000 1 1e-07;
logfile ./log/DTU_10MW_RWT_ver09.log;
begin newmark;
deltat 0.01;
end newmark;
my_line value1 2; MyComment for second my_line
end simulation;
;
;----------------------------------------------------------------------------------------------------------------------------------------------------------------
%% Cell type:markdown id: tags:
### HTC functions
#### set_name()
The `set_name` function sets the filename, as well as the
- log filename
- animation filename
- visualization filename
- output filename (only first output section)
%% Cell type:code id: tags:
``` python
htc.set_name(name="new_name", subfolder='my_folder')
print (htc.filename)
print (htc.simulation.logfile)
print (htc.output.filename)
```
%% Output
c:/mmpe/programming/python/windenergytoolbox/wetb/hawc2/tests/test_files/htc/my_folder/new_name.htc
logfile ./log/my_folder/new_name.log;
filename ./res/my_folder/new_name;
%% Cell type:markdown id: tags:
#### set_time()
The `set_time(start=None, stop=None, step=None)` function sets the start, stop and step time if specified:
%% Cell type:code id: tags:
``` python
htc.set_time(10,20,.1)
print (htc.simulation.time_stop)
print (htc.simulation.newmark.deltat)
print (htc.wind.scale_time_start)
print (htc.output.time)
```
%% Output
time_stop 20;
deltat 0.1;
scale_time_start 10;
time 10 20;
%% Cell type:markdown id: tags:
#### simulate()
The `simulate(exe)` function saves the htc file, performs the simulation using the specified exe (HAWC2), raises an error if the simulation fails and returns the console output and log
```python
stdout, log = htc.simulate("<path_to_hawc2>\hawc2mb.exe")
```
%% Cell type:markdown id: tags:
# Parameter study
HTC files for parameter studies, can be generated by a loop that updates the desired values of the htc and saves the result:
%% Cell type:code id: tags:
``` python
from wetb.hawc2 import HTCFile
from wetb.hawc2.tests.test_files import tfp
htc = HTCFile(tfp + "htcfiles/DTU_10MW_RWT.htc")
for wsp in [4,6,8]:
htc.wind.wsp = wsp
htc.set_name("case_wsp%d"%wsp)
htc.save()
```
%% Cell type:markdown id: tags:
## HAWC2InputWriter
An easier way for more complicate studies is to use the HAWC2InputWriter which takes a case as input (see [Case list generation](#Case-list-generation))
A case is dictionary of (key,value)-pairs. Keys can be:
1. Htc address, e.g. wind.wsp
2. Function name, e.g. `wsp` in which case `value` is passed to the `set_wsp` of `HAWC2InputWriter` (which you must implement)
3. A tag that is replaced by `value`
Note, all three types can be combined
%% Cell type:markdown id: tags:
First we create the htc file that we want the parameter study to be based on
%% Cell type:code id: tags:
``` python
%%writefile "tmp/base.htc"
begin simulation;
time_stop 600;
logfile log.txt
end simulation;
;
begin wind;
wsp 10;
end wind;
exit;
```
%% Output
Writing tmp/base.htc
%% Cell type:markdown id: tags:
### htc address
For (key-value) cases where the keys are htc addresses, we just need a `HAWC2InputWriter`
%% Cell type:code id: tags:
``` python
from wetb.hawc2 import HTCFile
from wetb.hawc2 import HAWC2InputWriter
h2writer = HAWC2InputWriter(base_htc_file='tmp/base.htc')
```
%% Cell type:markdown id: tags:
that allow us to make a case like this
%% Cell type:code id: tags:
``` python
h2writer('tmp/my_case.htc', **{'wind.wsp':12, 'simulation.logfile': "my_case.log"})
```
%% Cell type:code id: tags:
``` python
print (HTCFile('tmp/my_case.htc'))
```
%% Output
begin simulation;
time_stop 600;
logfile my_case.log;
end simulation;
;
begin wind;
wsp 12;
end wind;
exit;
%% Cell type:markdown id: tags:
### Function name
For (key-value) cases where the keys are function names, a subclass of `HAWC2InputWriter` with the required functions must be implemented:
%% Cell type:code id: tags:
``` python
class MyInputWriter(HAWC2InputWriter):
def set_wsp(self, htc, wsp, **_):
htc.wind.wsp = wsp
bs = self.begin_step
for i, o in enumerate([0,50],1):
htc.wind.add_line("wind_ramp_abs", [bs+o, bs+o+1, 0, 1], "wsp. after the step: %d.0"%(wsp+i))
# ...
def set_log(self, htc, log, **_):
if log:
htc.simulation.logfile = log
else:
htc.simulation.logfile.delete()
```
%% Cell type:markdown id: tags:
This approach enables
- Multiple values, e.g. wind speed, turbulence grid size, wind ramp etc., can be set by one (key,value)-pair
- Lines or sections can be deleted
- Use of constants (specified when creating the writer)
- Modification of e.g. aerodynamic, profile or structural data files
%% Cell type:code id: tags:
``` python
h2writer = MyInputWriter(base_htc_file='tmp/base.htc',
begin_step=100, # constant need in the implemented functions (specify as many as you want)
)
h2writer('tmp/my_case.htc', wsp=12, log=None, sensor_y=[10,20])
```
%% Cell type:code id: tags:
``` python
print (HTCFile('tmp/my_case.htc'))
```
%% Output
begin simulation;
time_stop 600;
end simulation;
;
begin wind;
wsp 12;
wind_ramp_abs 100 101 0 1; wsp. after the step: 13.0
wind_ramp_abs 150 151 0 1; wsp. after the step: 14.0
end wind;
exit;
%% Cell type:markdown id: tags:
### Tags
The tag options offers template rendering via the [jinja](https://en.wikipedia.org/wiki/Jinja_(template_engine)) templating language. Jinja templates allows:
- variable substitution,
```
wsp {{wsp}}
```
- conditionals
```
{% if logfilename %}
logfile {{logfilename}}
{% endif %}
```
- loops
```
{%- for y in sensor_y %}
wind free_wind 1 0.0 {{ y }} -119;
{%- endfor %}
```
let us make a new template.htc
%% Cell type:code id: tags:
``` python
%%writefile "tmp/template.htc"
begin simulation;
time_stop 600;
{% if logfilename %}
logfile {{logfilename}}
{% endif %}
end simulation;
;
begin wind;
wsp {{wsp}};
{%- for i in range(2) %}
wind_ramp_abs {{begin_step+i*50}} {{begin_step+i*50+1}} 0 1; wsp. after the step: {{wsp+i+1}}
{%- endfor %}
end wind;
exit;
```
%% Output
Writing tmp/template.htc
%% Cell type:code id: tags:
``` python
h2writer = HAWC2InputWriter(base_htc_file='tmp/template.htc')
h2writer('tmp/my_case.htc', wsp=12, log=None, begin_step=100)
```
%% Cell type:code id: tags:
``` python
print (HTCFile('tmp/my_case.htc'))
```
%% Output
begin simulation;
time_stop 600;
end simulation;
;
begin wind;
wsp 12;
wind_ramp_abs 100 101 0 1; wsp. after the step: 13
wind_ramp_abs 150 151 0 1; wsp. after the step: 14
end wind;
exit;
%% Cell type:markdown id: tags:
## Case list generation
The `HAWC2InputWriter` can also handle a list of cases.
These cases can be defined in a [Pandas DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) or an excel sheet
Note, case lists must contain a `Name` column
%% Cell type:markdown id: tags:
### Pandas Dataframe
%% Cell type:code id: tags:
``` python
import pandas as pd
df = pd.DataFrame({'Name':['case10', 'case12'], 'wsp':[10,12], 'log':['','log.txt']})
df
```
%% Output
Name wsp log
0 case10 10
1 case12 12 log.txt
%% Cell type:code id: tags:
``` python
h2writer = MyInputWriter(base_htc_file='tmp/base.htc',
begin_step=100, # constant need in the implemented functions (specify as many as you want)
)
h2writer.from_pandas(df)
h2writer.write_all(out_dir="tmp")
```
%% Output
Generating 2 htc files in directory: tmp
%% Cell type:code id: tags:
``` python
print(HTCFile('tmp/case10.htc'))
```
%% Output
begin simulation;
time_stop 600;
end simulation;
;
begin wind;
wsp 10;
wind_ramp_abs 100 101 0 1; wsp. after the step: 11.0
wind_ramp_abs 150 151 0 1; wsp. after the step: 12.0
end wind;
exit;
%% Cell type:code id: tags:
``` python
print(HTCFile('tmp/case12.htc'))
```
%% Output
begin simulation;
time_stop 600;
logfile log.txt;
end simulation;
;
begin wind;
wsp 12;
wind_ramp_abs 100 101 0 1; wsp. after the step: 13.0
wind_ramp_abs 150 151 0 1; wsp. after the step: 14.0
end wind;
exit;
%% Cell type:markdown id: tags:
### Excel
Saving previous dataframe as Excel spreadsheet
%% Cell type:code id: tags:
``` python
df.to_excel('tmp/caselist.xlsx', index=False)
```
%% Cell type:markdown id: tags:
which can be opened and modified in Excel
%% Cell type:code id: tags:
``` python
# uncomment to open in excel
# %system "tmp/caselist.xlsx"
```
%% Cell type:markdown id: tags:
Loading case list from (modifyed) excel sheet and write htc files
%% Cell type:code id: tags:
``` python
h2writer.from_excel('tmp/caselist.xlsx')
h2writer.contents
h2writer.write_all('tmp')
```
%% Output
Generating 2 htc files in directory: tmp
%% Cell type:markdown id: tags:
# Design Load Basis (DLB)
The `DTU_IEC64100_1_Ref_DLB` can make a case list covering a subset of the full DLB as defined in IEC64100-1(2005).
Note, some DLCs are missing.
Some interpretation are made see [Hansen, M. H., Thomsen, K., Natarajan, A., & Barlas, A. (2015). Design Load Basis for onshore turbines - Revision 00. DTU Wind Energy. DTU Wind Energy E, No. 0074(EN)](https://backend.orbit.dtu.dk/ws/portalfiles/portal/106567720/Design_Load_Basis_for_onshore_turbines.pdf)
%% Cell type:code id: tags:
``` python
from wetb.dlb.iec64100_1 import DTU_IEC64100_1_Ref_DLB, DLB, DLC
dlb = DTU_IEC64100_1_Ref_DLB(iec_wt_class='1A', #IEC wind turbine class
Vin=4, # cut-in wind speed
Vout=25, # cut-out wind speed
Vr=8, # rated wind speed
D=180, # Rotor diameter
z_hub=110 # hub height
)
```
%% Cell type:markdown id: tags:
## DLB definition
You can work with a DLB on an definition level
%% Cell type:code id: tags:
``` python
dlb.dlcs
```
%% Output
Name Description \
DLC12 DLC12 Normal production
DLC13 DLC13 Normal production with high turbulence
DLC14 DLC14 Normal production with gust and direction change
DLC15 DLC15 Normal production with extreme wind shear
DLC21 DLC21 Loss of electical network
DLC22y DLC22y Abnormal yaw error
WSP Wdir Turb Seeds Shear Gust Fault Time
DLC12 Vin:2:Vout -10/0/10 NTM 6.0 NWP None None 600
DLC13 Vin:2:Vout -10/0/10 ETM 6.0 NWP None None 600
DLC14 Vr/Vr+2/Vr-2 0 NoTurb NaN NWP ECD None 100
DLC15 Vin:2:Vout 0 NoTurb NaN EWS None None 100
DLC21 Vin:2:Vout -10/0/10 NTM 4.0 NWP None GridLoss10 100
DLC22y Vin:2:Vout 15:15:345 NTM 1.0 NWP None None 600
%% Cell type:code id: tags:
``` python
dlb.variables
```
%% Output
Name Value Description
Vin Vin 4 Cut-in wind speed
Vout Vout 25 Cut-out wind speed
Vr Vr 8 Rated wind speed
D D 180 Rotor diameter
z_hub z_hub 110 Hub height
Vstep Vstep 2 Wind speed distribution step
iec_wt_class iec_wt_class 1A IEC wind turbine class, e.g. 1A
%% Cell type:markdown id: tags:
### Edit DLB definition
`dlb.dlcs` is a Pandas DataFrame that you can edit in python
%% Cell type:code id: tags:
``` python
dlb.dlcs.loc['DLC12','Seeds'] = 1
dlb.dlcs
```
%% Output
Name Description \
DLC12 DLC12 Normal production
DLC13 DLC13 Normal production with high turbulence
DLC14 DLC14 Normal production with gust and direction change
DLC15 DLC15 Normal production with extreme wind shear
DLC21 DLC21 Loss of electical network
DLC22y DLC22y Abnormal yaw error
WSP Wdir Turb Seeds Shear Gust Fault Time
DLC12 Vin:2:Vout -10/0/10 NTM 1.0 NWP None None 600
DLC13 Vin:2:Vout -10/0/10 ETM 6.0 NWP None None 600
DLC14 Vr/Vr+2/Vr-2 0 NoTurb NaN NWP ECD None 100
DLC15 Vin:2:Vout 0 NoTurb NaN EWS None None 100
DLC21 Vin:2:Vout -10/0/10 NTM 4.0 NWP None GridLoss10 100
DLC22y Vin:2:Vout 15:15:345 NTM 1.0 NWP None None 600
%% Cell type:markdown id: tags:
`dlb.variables` is a Pandas DataFrame that you can edit in python
%% Cell type:code id: tags:
``` python
dlb.variables.loc['Vin','Value'] = 8
dlb.variables.loc['Vout', 'value']=10
dlb.variables
```
%% Output
Name Value Description value
Vin Vin 8 Cut-in wind speed NaN
Vout Vout 25 Cut-out wind speed 10.0
Vr Vr 8 Rated wind speed NaN
D D 180 Rotor diameter NaN
z_hub z_hub 110 Hub height NaN
Vstep Vstep 2 Wind speed distribution step NaN
iec_wt_class iec_wt_class 1A IEC wind turbine class, e.g. 1A NaN
%% Cell type:markdown id: tags:
### Edit DLB definition in Excel
You can also save the DLB definition and variables as an Excel workbook
%% Cell type:code id: tags:
``` python
dlb.to_excel('tmp/overview.xlsx')
```
%% Cell type:markdown id: tags:
open, edit and save in Excel
%% Cell type:code id: tags:
``` python
# uncomment to open file in excel
# %system "tmp/overview.xlsx"
```
%% Cell type:markdown id: tags:
and load the modified DLB
%% Cell type:code id: tags:
``` python
dlb = DLB.from_excel('tmp/overview.xlsx')
dlb.dlcs
```
%% Output
Name Description \
DLC12 DLC12 Normal production
DLC13 DLC13 Normal production with high turbulence
DLC14 DLC14 Normal production with gust and direction change
DLC15 DLC15 Normal production with extreme wind shear
DLC21 DLC21 Loss of electical network
DLC22y DLC22y Abnormal yaw error
WSP Wdir Turb Seeds Shear Gust Fault Time
DLC12 Vin:2:Vout -10/0/10 NTM 1.0 NWP NaN NaN 600
DLC13 Vin:2:Vout -10/0/10 ETM 6.0 NWP NaN NaN 600
DLC14 Vr/Vr+2/Vr-2 0 NoTurb NaN NWP ECD NaN 100
DLC15 Vin:2:Vout 0 NoTurb NaN EWS NaN NaN 100
DLC21 Vin:2:Vout -10/0/10 NTM 4.0 NWP NaN GridLoss10 100
DLC22y Vin:2:Vout 15:15:345 NTM 1.0 NWP NaN NaN 600
%% Cell type:markdown id: tags:
## DLC cases
%% Cell type:markdown id: tags:
You can generate a Pandas DataFrame with all cases of all DLCs
%% Cell type:code id: tags:
``` python
dlb.to_pandas()
```
%% Output
DLC Name Folder V_hub wdir \
0 DLC12 DLC12_wsp08_wdir350_s1001 DLC12 8.0 -10.0
1 DLC12 DLC12_wsp08_wdir000_s1001 DLC12 8.0 0.0
2 DLC12 DLC12_wsp08_wdir010_s1001 DLC12 8.0 10.0
3 DLC12 DLC12_wsp10_wdir350_s1101 DLC12 10.0 -10.0
4 DLC12 DLC12_wsp10_wdir000_s1101 DLC12 10.0 0.0
.. ... ... ... ... ...
225 DLC22y DLC22y_wsp26_wdir285_s1901 DLC22y 26.0 285.0
226 DLC22y DLC22y_wsp26_wdir300_s1901 DLC22y 26.0 300.0
227 DLC22y DLC22y_wsp26_wdir315_s1901 DLC22y 26.0 315.0
228 DLC22y DLC22y_wsp26_wdir330_s1901 DLC22y 26.0 330.0
229 DLC22y DLC22y_wsp26_wdir345_s1901 DLC22y 26.0 345.0
simulation_time ti seed \
0 600 0.232000 1001
1 600 0.232000 1001
2 600 0.232000 1001
3 600 0.209600 1101
4 600 0.209600 1101
.. ... ... ...
225 600 0.154462 1901
226 600 0.154462 1901
227 600 0.154462 1901
228 600 0.154462 1901
229 600 0.154462 1901
shear Gust Fault
0 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
1 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
2 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
3 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
4 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
.. ... ... ...
225 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
226 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
227 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
228 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
229 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
[603 rows x 11 columns]
%% Cell type:markdown id: tags:
or the cases of a single DLC
%% Cell type:code id: tags:
``` python
dlb['DLC14']
```
%% Output
DLC Name Folder V_hub wdir simulation_time seed \
0 DLC14 DLC14_wsp06_wdir000 DLC14 6.0 0.0 100 None
1 DLC14 DLC14_wsp08_wdir000 DLC14 8.0 0.0 100 None
2 DLC14 DLC14_wsp10_wdir000 DLC14 10.0 0.0 100 None
shear \
0 {'type': 'NWP', 'profile': ('power', 0.2)}
1 {'type': 'NWP', 'profile': ('power', 0.2)}
2 {'type': 'NWP', 'profile': ('power', 0.2)}
Gust
0 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 120.0,...
1 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 90.0, ...
2 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 72.0, ...
%% Cell type:markdown id: tags:
### Edit DLC cases
The dlc cases returned by `dlb.dlcs[<dlc>]` is a Pandas DataFrame that you can edit in python
!!! Note, editing dlc cases will not influence the DLB
%% Cell type:code id: tags:
``` python
dlc14_ed = dlb['DLC14']
dlc14_ed.loc[0,'V_hub'] = 4
dlc14_ed
```
%% Output
DLC Name Folder V_hub wdir simulation_time seed \
0 DLC14 DLC14_wsp06_wdir000 DLC14 4.0 0.0 100 None
1 DLC14 DLC14_wsp08_wdir000 DLC14 8.0 0.0 100 None
2 DLC14 DLC14_wsp10_wdir000 DLC14 10.0 0.0 100 None
shear \
0 {'type': 'NWP', 'profile': ('power', 0.2)}
1 {'type': 'NWP', 'profile': ('power', 0.2)}
2 {'type': 'NWP', 'profile': ('power', 0.2)}
Gust
0 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 120.0,...
1 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 90.0, ...
2 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 72.0, ...
%% Cell type:markdown id: tags:
### Edit DLC cases in Excel
You can also save the DLC case list as an Excel spreadsheet
%% Cell type:code id: tags:
``` python
dlc14_ed.to_excel('tmp/dlc14_ed.xlsx')
```
%% Cell type:markdown id: tags:
and open and edit the cases in Excel
%% Cell type:code id: tags:
``` python
# uncomment to open file in excel
# %system "tmp/dlc14_ed.xlsx"
```
%% Cell type:markdown id: tags:
The modified cases can be loaded by the input writer, see below
%% Cell type:markdown id: tags:
### Write DLB/DLC cases as HAWC2 input files
#### Load into HAWC2_IEC_DLC_Writer
To write the HTC files correponding to the DLB cases, you need the `HAWC2_IEC_DLC_Writer` and a base htc file
%% Cell type:code id: tags:
``` python
from wetb.hawc2.tests.test_files import tfp
from wetb.dlb.hawc2_iec_dlc_writer import HAWC2_IEC_DLC_Writer
path = tfp + '/simulation_setup/DTU10MWRef6.0/'
writer = HAWC2_IEC_DLC_Writer(path + 'htc/DTU_10MW_RWT.htc', diameter=180)
```
%% Cell type:markdown id: tags:
Load all cases into the writer
%% Cell type:code id: tags:
``` python
writer.from_pandas(dlb)
writer.contents
```
%% Output
DLC Name Folder V_hub wdir \
0 DLC12 DLC12_wsp08_wdir350_s1001 DLC12 8.0 -10.0
1 DLC12 DLC12_wsp08_wdir000_s1001 DLC12 8.0 0.0
2 DLC12 DLC12_wsp08_wdir010_s1001 DLC12 8.0 10.0
3 DLC12 DLC12_wsp10_wdir350_s1101 DLC12 10.0 -10.0
4 DLC12 DLC12_wsp10_wdir000_s1101 DLC12 10.0 0.0
.. ... ... ... ... ...
225 DLC22y DLC22y_wsp26_wdir285_s1901 DLC22y 26.0 285.0
226 DLC22y DLC22y_wsp26_wdir300_s1901 DLC22y 26.0 300.0
227 DLC22y DLC22y_wsp26_wdir315_s1901 DLC22y 26.0 315.0
228 DLC22y DLC22y_wsp26_wdir330_s1901 DLC22y 26.0 330.0
229 DLC22y DLC22y_wsp26_wdir345_s1901 DLC22y 26.0 345.0
simulation_time ti seed \
0 600 0.232000 1001
1 600 0.232000 1001
2 600 0.232000 1001
3 600 0.209600 1101
4 600 0.209600 1101
.. ... ... ...
225 600 0.154462 1901
226 600 0.154462 1901
227 600 0.154462 1901
228 600 0.154462 1901
229 600 0.154462 1901
shear Gust Fault
0 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
1 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
2 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
3 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
4 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
.. ... ... ...
225 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
226 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
227 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
228 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
229 {'type': 'NWP', 'profile': ('power', 0.2)} NaN NaN
[603 rows x 11 columns]
%% Cell type:markdown id: tags:
Load a single DLC
%% Cell type:code id: tags:
``` python
writer.from_pandas(dlb['DLC14'])
writer.contents
```
%% Output
DLC Name Folder V_hub wdir simulation_time seed \
0 DLC14 DLC14_wsp06_wdir000 DLC14 6.0 0.0 100 None
1 DLC14 DLC14_wsp08_wdir000 DLC14 8.0 0.0 100 None
2 DLC14 DLC14_wsp10_wdir000 DLC14 10.0 0.0 100 None
shear \
0 {'type': 'NWP', 'profile': ('power', 0.2)}
1 {'type': 'NWP', 'profile': ('power', 0.2)}
2 {'type': 'NWP', 'profile': ('power', 0.2)}
Gust
0 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 120.0,...
1 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 90.0, ...
2 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 72.0, ...
%% Cell type:markdown id: tags:
Load the modified DLC
%% Cell type:code id: tags:
``` python
writer.from_pandas(dlc14_ed)
writer.contents
```
%% Output
DLC Name Folder V_hub wdir simulation_time seed \
0 DLC14 DLC14_wsp06_wdir000 DLC14 4.0 0.0 100 None
1 DLC14 DLC14_wsp08_wdir000 DLC14 8.0 0.0 100 None
2 DLC14 DLC14_wsp10_wdir000 DLC14 10.0 0.0 100 None
shear \
0 {'type': 'NWP', 'profile': ('power', 0.2)}
1 {'type': 'NWP', 'profile': ('power', 0.2)}
2 {'type': 'NWP', 'profile': ('power', 0.2)}
Gust
0 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 120.0,...
1 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 90.0, ...
2 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 72.0, ...
%% Cell type:markdown id: tags:
Load the DLC from the (modified) excel file
%% Cell type:code id: tags:
``` python
writer.from_excel('tmp/dlc14_ed.xlsx')
writer.contents
```
%% Output
DLC Name Folder V_hub wdir simulation_time seed \
0 DLC14 DLC14_wsp06_wdir000 DLC14 4 0 100
1 DLC14 DLC14_wsp08_wdir000 DLC14 8 0 100
2 DLC14 DLC14_wsp10_wdir000 DLC14 10 0 100
shear \
0 {'type': 'NWP', 'profile': ('power', 0.2)}
1 {'type': 'NWP', 'profile': ('power', 0.2)}
2 {'type': 'NWP', 'profile': ('power', 0.2)}
Gust
0 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 120.0,...
1 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 90.0, ...
2 {'type': 'ECD', 'V_cg': 15, 'theta_cg': 72.0, ...
%% Cell type:markdown id: tags:
#### Write files
%% Cell type:code id: tags:
``` python
writer.write_all(out_dir='tmp')
```
%% Output
Generating 3 htc files in directory: tmp
%% Cell type:code id: tags:
``` python
%ls "tmp/DLC14"
```
%% Output
Volume in drive C is Windows
Volume Serial Number is 1AB2-743B
Directory of c:\mmpe\programming\python\WindEnergyToolbox\notebooks\hawc2\tmp\DLC14
29-04-2020 14:56 <DIR> .
29-04-2020 14:56 <DIR> ..
29-04-2020 14:56 28,439 DLC14_wsp06_wdir000.htc
29-04-2020 14:56 28,438 DLC14_wsp08_wdir000.htc
29-04-2020 14:56 28,439 DLC14_wsp10_wdir000.htc
3 File(s) 85,316 bytes
2 Dir(s) 56,159,342,592 bytes free
%% Cell type:markdown id: tags:
# Running simulations
%% Cell type:markdown id: tags:
## Single simulation on local pc
%% Cell type:code id: tags:
``` python
from wetb import hawc2
from wetb.hawc2 import HTCFile
from wetb.hawc2.tests.test_files import tfp
```
%% Cell type:code id: tags:
``` python
hawc2_path = "HAWC2MB.exe" # make sure HAWC2MB.exe is on your path or specify the full path to HAWC2
```
%% Cell type:markdown id: tags:
Generate and save a HAWC2 input htc file for a short simulation
%% Cell type:code id: tags:
``` python
htc = HTCFile(tfp + "simulation_setup/DTU10MWRef6.0/htc/DTU_10MW_RWT.htc")
htc.simulation.time_stop = 1 # stop the simulation after 1 s
htc.save(tfp + 'simulation_setup/DTU10MWRef6.0/htc/tmp.htc')
```
%% Cell type:markdown id: tags:
Execute the simulation
%% Cell type:code id: tags:
``` python
stdout, log = htc.simulate(hawc2_path)
```
%% Cell type:code id: tags:
``` python
print(stdout)
```
%% Output
***********************************************************************
* Build information for HAWC2MB.exe (GIT)
* Intel, version 1900 , 20190206
* WINDOWS 32-bit
***********************************************************************
* GIT-TAG = 12.8.0
* BUILDER = mmpe
* COMPUTER_NAME = VINDRI-D17205
* BUILD_DATE = 30-01-2020
***********************************************************************
Logfile: ./log/dtu_10mw_rwt_ver4.log is open for log outputs
Basic DTU Wind Energy Controller (ver. 2.3 v0.1.dev69.17400ca) loaded ...
Gen. torque Servo (ver. 2.2 v0.1.dev15.eddfec3) loaded...
Mech brake (ver. 2.2 v0.1.dev14.9e614a3) loaded...
Pitch Servo (ver. 2.2 v0.1.dev15.eddfec3) loaded...
Using licence_manager.dll, version: unknown
License verified - OK
Opening main command file: htc\tmp.htc
Current directory is
c:\mmpe\programming\python\windenergytoolbox\wetb\hawc2\tests\test_files\simula
tion_setup\DTU10MWRef6.0
Continue on no convergence = true
%% Cell type:code id: tags:
``` python
print(log)
```
%% Output
***********************************************************************
* Build information for HAWC2MB.exe (GIT)
* Intel, version 1900 , 20190206
* WINDOWS 32-bit
***********************************************************************
* GIT-TAG = 12.8.0
* BUILDER = mmpe
* COMPUTER_NAME = VINDRI-D17205
* BUILD_DATE = 30-01-2020
***********************************************************************
________________________________________________________________________________________________________________________
Log file output
Time : 14:55:07
Date : 26:05.2020
________________________________________________________________________________________________________________________
Newmark commands read with succes
Simulation commands read with succes
Reading data of main body : tower
Succes opening ./data/dtu_10mw_rwt_tower_st.dat
timoschenko input commands read with succes
topologi_c2def_inputs read with succes
Topologi main body tower commands read with succes
Reading data of main body : towertop
Succes opening ./data/dtu_10mw_rwt_towertop_st.dat
timoschenko input commands read with succes
topologi_c2def_inputs read with succes
Topologi main body towertop commands read with succes
Reading data of main body : shaft
Succes opening ./data/dtu_10mw_rwt_shaft_st.dat
timoschenko input commands read with succes
topologi_c2def_inputs read with succes
Topologi main body shaft commands read with succes
Reading data of main body : hub1
Succes opening ./data/dtu_10mw_rwt_hub_st.dat
timoschenko input commands read with succes
topologi_c2def_inputs read with succes
Topologi main body hub1 commands read with succes
Reading data of main body : hub2
Topologi main body hub2 commands read with succes
Reading data of main body : hub3
Topologi main body hub3 commands read with succes
Reading data of main body : blade1
Succes opening ./data/dtu_10mw_rwt_blade_st.dat
timoschenko input commands read with succes
topologi_c2def_inputs read with succes
Topologi main body blade1 commands read with succes
Reading data of main body : blade2
Topologi main body blade2 commands read with succes
Reading data of main body : blade3
Topologi main body blade3 commands read with succes
Base orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
relative orientation input commands read with succes
Orientation input commands read with succes
Fix0 constraint input commands read with succes
Fix1 constraint input commands read with succes
Bearing1 constraint input commands read with succes
Fix1 constraint input commands read with succes
Fix1 constraint input commands read with succes
Fix1 constraint input commands read with succes
bearing2 constraint input commands read with succes
bearing2 constraint input commands read with succes
bearing2 constraint input commands read with succes
constraint input commands read with succes
Topologi commands read with succes
Tower shadow (potential2 flow) commands read with succes
Wind commands read with succes
aerodrag element commands read with succes
aerodrag element commands read with succes
Aerodrag commands read with succes
Aerodynamic commands read with succes
output commands read with succes
Output commands read
Dll type2 input commands read with succes
output commands read with succes
Output commands read
Actions commands read
Dll type2 input commands read with succes
output commands read with succes
Output commands read
Actions commands read
Dll type2 input commands read with succes
output commands read with succes
Output commands read
Actions commands read
Dll type2 input commands read with succes
output commands read with succes
Output commands read
Dll type2 input commands read with succes
DLL commands read with succes
output commands read with succes
Output commands read
output_at read with succes
Initialization of structure
Initializing of aero rotor...
Initialization of rotor aerodynamics
Succes opening ./data/dtu_10mw_rwt_ae.dat
Succes opening ./data/dtu_10mw_rwt_pc.dat
Initialization of rotor induction
Initialization of wind
Initialization of external type2 DLL
External DLL ./control/dtu_we_controller.dll is attempted to open
Using ./control/dtu_we_controller.dll, version: unknown
Succes opening external DLL ./control/dtu_we_controller.dll
DLL subroutine init init_regulation is called
In initialization call of ./control/dtu_we_controller.dll Output is
0.000000000000000E+000
*** INFO *** The DLL subroutine message could not be loaded - bypassed!
Initialization of external type2 DLL
External DLL ./control/generator_servo.dll is attempted to open
Using ./control/generator_servo.dll, version: unknown
Succes opening external DLL ./control/generator_servo.dll
DLL subroutine init init_generator_servo is called
In initialization call of ./control/generator_servo.dll Output is
0.000000000000000E+000
*** INFO *** The DLL subroutine message could not be loaded - bypassed!
Initialization of external type2 DLL
External DLL ./control/mech_brake.dll is attempted to open
Using ./control/mech_brake.dll, version: unknown
Succes opening external DLL ./control/mech_brake.dll
DLL subroutine init init_mech_brake is called
In initialization call of ./control/mech_brake.dll Output is
0.000000000000000E+000
*** INFO *** The DLL subroutine message could not be loaded - bypassed!
Initialization of external type2 DLL
External DLL ./control/servo_with_limits.dll is attempted to open
Using ./control/servo_with_limits.dll, version: unknown
Succes opening external DLL ./control/servo_with_limits.dll
DLL subroutine init init_servo_with_limits is called
In initialization call of ./control/servo_with_limits.dll Output is
0.000000000000000E+000
*** INFO *** The DLL subroutine message could not be loaded - bypassed!
Initialization of external type2 DLL
External DLL ./control/towclearsens.dll is attempted to open
Using ./control/towclearsens.dll, version: unknown
Succes opening external DLL ./control/towclearsens.dll
DLL subroutine init initialize is called
In initialization call of ./control/towclearsens.dll Output is
2.66000000000000
*** INFO *** The DLL subroutine message could not be loaded - bypassed!
Creating link between structure and aerodynamics
Creating link between structure and aerodrag
Initialization of Aerodrag
Starting simulation
Dynamic stall method: 2 used for entire rotor
Global time = 2.000000000000000E-002 Iter = 2
Global time = 4.000000000000000E-002 Iter = 2
Global time = 6.000000000000000E-002 Iter = 2
Global time = 8.000000000000000E-002 Iter = 2
Global time = 0.100000000000000 Iter = 2
Global time = 0.120000000000000 Iter = 2
Global time = 0.140000000000000 Iter = 2
Global time = 0.160000000000000 Iter = 2
Global time = 0.180000000000000 Iter = 2
Global time = 0.200000000000000 Iter = 2
Global time = 0.220000000000000 Iter = 2
Global time = 0.240000000000000 Iter = 2
Global time = 0.260000000000000 Iter = 2
Global time = 0.280000000000000 Iter = 3
Global time = 0.300000000000000 Iter = 3
Global time = 0.320000000000000 Iter = 3
Global time = 0.340000000000000 Iter = 3
Global time = 0.360000000000000 Iter = 3
Global time = 0.380000000000000 Iter = 3
Global time = 0.400000000000000 Iter = 3
Global time = 0.420000000000000 Iter = 3
Global time = 0.440000000000000 Iter = 3
Global time = 0.460000000000000 Iter = 3
Global time = 0.480000000000000 Iter = 3
Global time = 0.500000000000000 Iter = 3
Global time = 0.520000000000000 Iter = 3
Global time = 0.540000000000000 Iter = 2
Global time = 0.560000000000000 Iter = 3
Global time = 0.580000000000000 Iter = 3
Global time = 0.600000000000000 Iter = 3
Global time = 0.620000000000000 Iter = 3
Global time = 0.640000000000000 Iter = 3
Global time = 0.660000000000000 Iter = 3
Global time = 0.680000000000000 Iter = 3
Global time = 0.700000000000000 Iter = 3
Global time = 0.720000000000000 Iter = 3
Global time = 0.740000000000000 Iter = 2
Global time = 0.760000000000000 Iter = 3
Global time = 0.780000000000000 Iter = 3
Global time = 0.800000000000000 Iter = 2
Global time = 0.820000000000000 Iter = 2
Global time = 0.840000000000000 Iter = 3
Global time = 0.860000000000000 Iter = 2
Global time = 0.880000000000000 Iter = 2
Global time = 0.900000000000000 Iter = 3
Global time = 0.920000000000000 Iter = 3
Global time = 0.940000000000000 Iter = 2
Global time = 0.960000000000000 Iter = 2
Global time = 0.980000000000000 Iter = 2
Global time = 1.00000000000000 Iter = 3
Closing of external type2 DLL
Closing of external type2 DLL
Closing of external type2 DLL
Closing of external type2 DLL
Closing of external type2 DLL
Elapsed time : 0.9218750
%% Cell type:code id: tags:
``` python
```
%% Cell type:markdown id: tags:
## Running simulations on Jess
%% Cell type:code id: tags:
``` python
import os
from wetb import hawc2
from wetb.hawc2 import HTCFile
from wetb.hawc2.tests.test_files import tfp
```
%% Cell type:markdown id: tags:
Generate some HAWC2 input htc files
%% Cell type:code id: tags:
``` python
htc_lst = []
for wsp in [4,6]:
htc = HTCFile(tfp + "simulation_setup/DTU10MWRef6.0/htc/DTU_10MW_RWT.htc")
htc.simulation.time_stop = 1
htc.wind.wsp=wsp
htc.set_name("tmp%d"%wsp)
htc.save()
htc_lst.append(htc)
print (htc.filename)
```
%% Output
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/htc/tmp4.htc
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/htc/tmp6.htc
%% Cell type:code id: tags:
``` python
pbs = htc.pbs_file("hawc2_path", "hawc2_cmd",
queue='workq', # workq, windq, xpresq
walltime=None, # defaults to expected (currently 600s) * 2
input_files=None, # If none, required files are autodetected from htc file
output_files=None, # If none, output files are autodetected from htc file
copy_turb=(True, True) # copy turbulence files (to, from) simulation
)
```
%% Cell type:markdown id: tags:
### Generate PBS files
A PBS file defines a job that can be submitted to the queuing system of PBS featured clusters, e.g. Jess.
A PBS file has header that specifies:
- output file for stdout and stderr
- wall time (after which the job will be terminated)
- nodes (numbers of nodes to request)
- ppn (number of processors/CPUs to use at each node. Jess has 20 CPUs per node)
- queue (e.g. `workq`, `windq`, `xpresq`)
PBS files can be generated from a HAWC2 input htc file. The body (command section) of these files will:
- Copy HAWC2 to a common folder on the the scratch drive (i.e. a hard drive local to the node) if it is not already there.
- Create a run folder on the scratch drive for the current simulation
- Copy HAWC2 to the run folder
- Copy all required input files (turbulence files are optional) to a common folder on the scratch drive if they are not already there
- Copy all required input files to the run folder
- Launch the simulation
- Copy all output files (turbulence files are optional) back from the model directory
%% Cell type:markdown id: tags:
HAWC2 can be copied from a local folder or from the shared group folder `/mnt/aiolos/groups/hawc2sim/HAWC2/<version>/<platform>`.
HAWC2 can be a zip file, which will be unzipped at the scratch drive, and/or a set of files (exe, dll, ...)
%% Cell type:code id: tags:
``` python
version = "v12.8.0.0"
platform = "win32"
hawc2_path="/mnt/aiolos/groups/hawc2sim/HAWC2/%s/%s/" % (version, platform)
print(hawc2_path)
```
%% Output
/mnt/aiolos/groups/hawc2sim/HAWC2/v12.8.0.0/win32/
%% Cell type:markdown id: tags:
The command needed to run HAWC2 must be specified. It can be obtained via the `wine_cmd` function:
%% Cell type:code id: tags:
``` python
from wetb.hawc2.hawc2_pbs_file import JESS_WINE32_HAWC2MB, wine_cmd
hawc2_cmd = wine_cmd(platform='win32', hawc2='hawc2mb.exe', cluster='jess')
print (hawc2_cmd)
```
%% Output
WINEARCH=win32 WINEPREFIX=~/.wine32 winefix
WINEARCH=win32 WINEPREFIX=~/.wine32 wine hawc2mb.exe
%% Cell type:markdown id: tags:
The PBS files are generated from the htc files
%% Cell type:code id: tags:
``` python
pbs_lst = []
for htc in htc_lst:
pbs = htc.pbs_file(hawc2_path, hawc2_cmd,
queue='workq', # workq, windq, xpresq
walltime=None, # defaults to expected (currently 600s) * 2
input_files=None, # If none, required files are autodetected from htc file
output_files=None, # If none, output files are autodetected from htc file
copy_turb=(True, True) # copy turbulence files (to, from) simulation
)
pbs.save()
pbs_lst.append(pbs)
print (os.path.join(pbs.workdir, pbs.filename))
```
%% Output
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/pbs_in/tmp4.in
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/pbs_in/tmp6.in
%% Cell type:code id: tags:
``` python
from wetb.utils.cluster_tools.os_path import pjoin, relpath, abspath,\
cluster_path, repl
print(abspath(pbs.exe_dir))
print(pbs.modelpath)
rel_exe_dir = relpath(pbs.exe_dir, pbs.modelpath)
print (rel_exe_dir)
```
%% Output
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0
.
%% Cell type:markdown id: tags:
You can see the contents of the last pbs file here
%% Cell type:code id: tags:
``` python
print(pbs)
```
%% Output
### Jobid
#PBS -N tmp6
### Standard Output
#PBS -o /home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/stdout/tmp6.out
### merge stderr into stdout
#PBS -j oe
#PBS -W umask=0003
### Maximum wallclock time format HOURS:MINUTES:SECONDS
#PBS -l walltime=00:20:00
#PBS -l nodes=1:ppn=1
### Queue name
#PBS -q workq
cd "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0"
mkdir -p "stdout"
if [ -z "$PBS_JOBID" ]; then echo "Run using qsub"; exit ; fi
pwd
#===============================================================================
echo copy hawc2 to scratch
#===============================================================================
(flock -x 200
mkdir -p "/scratch/$USER/$PBS_JOBID/hawc2/"
unzip -u -o -q "/mnt/aiolos/groups/hawc2sim/HAWC2/v12.8.0.0/win32/"*.zip -d "/scratch/$USER/$PBS_JOBID/hawc2/"
find "/mnt/aiolos/groups/hawc2sim/HAWC2/v12.8.0.0/win32/"* ! -name *.zip -exec cp -u -t "/scratch/$USER/$PBS_JOBID/hawc2/" {} +
) 200>"/scratch/$USER/$PBS_JOBID/lock_file_hawc2"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/."
cp "/scratch/$USER/$PBS_JOBID/hawc2/"* "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/."
#===============================================================================
echo copy input
#===============================================================================
cd "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0"
(flock -x 200
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_Tower_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/mech_brake.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_Hub_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/dtu_we_controller_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/towclearsens.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_Towertop_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/servo_with_limits_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/servo_with_limits.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/wpdata.100" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/mech_brake_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/generator_servo.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/dtu_we_controller.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/generator_servo_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_pc.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control" && cp -u -r "control/towclearsens_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_ae.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/htc" && cp -u -r "htc/tmp6.htc" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/htc"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_Shaft_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data" && cp -u -r "data/DTU_10MW_RWT_Blade_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/data"
) 200>/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/lock_file_model
cd "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_Tower_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/mech_brake.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_Hub_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/dtu_we_controller_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/towclearsens.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_Towertop_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/servo_with_limits_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/servo_with_limits.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/wpdata.100" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/mech_brake_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/generator_servo.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/dtu_we_controller.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/generator_servo_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_pc.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control" && cp -u -r "control/towclearsens_64.dll" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/control"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_ae.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/htc" && cp -u -r "htc/tmp6.htc" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/htc"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_Shaft_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
mkdir -p "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data" && cp -u -r "data/DTU_10MW_RWT_Blade_st.dat" "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/data"
#===============================================================================
echo Run HAWC2
#===============================================================================
cd "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6/."
WINEARCH=win32 WINEPREFIX=~/.wine32 winefix
WINEARCH=win32 WINEPREFIX=~/.wine32 wine hawc2mb.exe htc/tmp6.htc
#===============================================================================
echo Copy output
#===============================================================================
cd "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6"
mkdir -p "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/log" && cp -u -r "log/tmp6.log" "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/log"
mkdir -p "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res" && cp -u -r "res/tmp6.sel" "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res"
mkdir -p "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res" && cp -u -r "res/tmp6.dat" "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res"
mkdir -p "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res" && cp -u -r "res/at.dat" "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/res"
rm -r "/scratch/$USER/$PBS_JOBID/DTU10MWRef6.0/run_tmp6"
echo Done
exit
%% Cell type:markdown id: tags:
### Run single simulation
%% Cell type:markdown id: tags:
You can run a simulation by executing the pbs file in an interactive seession. This way is very handy for debugging.
```bash
qsub -I -l nodes=1:ppn=1 -l walltime=01:00:00
<...>/wetb/hawc2/tests/test_files/simulation_setup/pbs_in/tmp6.in
```
%% Cell type:markdown id: tags:
or by summiting the pbs file to the queing system
```
qsub <...>/wetb/hawc2/tests/test_files/simulation_setup\pbs_in/tmp6.in
```
This done here:
%% Cell type:code id: tags:
``` python
print(os.path.join(pbs.workdir,pbs.filename))
!qsub {os.path.join(pbs.workdir,pbs.filename)}
```
%% Output
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/pbs_in/tmp6.in
3221545.jess.dtu.dk
%% Cell type:markdown id: tags:
The job will now enter the cluster queue and be launched when free resoureces are available.
You can check the status of the job:
%% Cell type:code id: tags:
``` python
!qstat -n -u $USER
```
%% Cell type:markdown id: tags:
Wait as long as the `qstat` command above prints information about the job
When the job is finished we can check the output file
%% Cell type:code id: tags:
``` python
!cat {pbs.stdout_filename}
```
%% Output
Start of prologue
/scratch/mmpe/3221545.jess.dtu.dk created
End of prologue
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0
copy hawc2 to scratch
copy input
cp: cannot stat `control/dtu_we_controller_64.dll': No such file or directory
cp: cannot stat `control/servo_with_limits_64.dll': No such file or directory
cp: cannot stat `control/mech_brake_64.dll': No such file or directory
cp: cannot stat `control/generator_servo_64.dll': No such file or directory
cp: cannot stat `control/towclearsens_64.dll': No such file or directory
cp: cannot stat `control/dtu_we_controller_64.dll': No such file or directory
cp: cannot stat `control/servo_with_limits_64.dll': No such file or directory
cp: cannot stat `control/mech_brake_64.dll': No such file or directory
cp: cannot stat `control/generator_servo_64.dll': No such file or directory
cp: cannot stat `control/towclearsens_64.dll': No such file or directory
Run HAWC2
***********************************************************************
* Build information for HAWC2MB.exe (GIT)
* Intel, version 1900 , 20190206
* WINDOWS 32-bit
***********************************************************************
* GIT-TAG = 12.8.0
* BUILDER = mmpe
* COMPUTER_NAME = VINDRI-D17205
* BUILD_DATE = 30-01-2020
***********************************************************************
fixme:console:GetNumberOfConsoleMouseButtons (0x684ec44): stub
Using licence_manager.dll, version: unknown
License verified - OK
Opening main command file: htc/tmp6.htc
Current directory is Z:\scratch\mmpe\3221545.jess.dtu.dk\DTU10MWRef6.0\run_tmp6
Continue on no convergence = true
Logfile: ./log/tmp6.log is open for log outputs
Basic DTU Wind Energy Controller (ver. 2.3 v0.1.dev69.17400ca) loaded ...
Gen. torque Servo (ver. 2.2 v0.1.dev15.eddfec3) loaded...
Mech brake (ver. 2.2 v0.1.dev14.9e614a3) loaded...
Pitch Servo (ver. 2.2 v0.1.dev15.eddfec3) loaded...
Copy output
Done
Start of epilogue on j-177
Resources Used: cput=00:00:04,mem=5744kb,vmem=3856592kb,walltime=00:00:07
End of epilogue on j-177
%% Cell type:markdown id: tags:
Highlights:
- copy hawc2 to scratch
- copy input
- It states that it cannot copy the 64-bit control dlls (control/*_64.dll) - which does not matter as we are using the 32-bit HAWC2
- Run HAWC2
- Copy output
- Done
%% Cell type:code id: tags:
``` python
!head -n 20 {os.path.join(htc.modelpath, htc.simulation.logfile[0])}
```
%% Output
***********************************************************************
* Build information for HAWC2MB.exe (GIT)
* Intel, version 1900 , 20190206
* WINDOWS 32-bit
***********************************************************************
* GIT-TAG = 12.8.0
* BUILDER = mmpe
* COMPUTER_NAME = VINDRI-D17205
* BUILD_DATE = 30-01-2020
***********************************************************************
________________________________________________________________________________________________________________________
Log file output
Time : 12:19:17
Date : 29:05.2020
________________________________________________________________________________________________________________________
Newmark commands read with succes
Simulation commands read with succes
Reading data of main body : tower
Succes opening ./data/dtu_10mw_rwt_tower_st.dat
timoschenko input commands read with succes
%% Cell type:markdown id: tags:
### Run multiple simulations
%% Cell type:markdown id: tags:
Multiple simulations can easily be executed using the `PBSMultiRunner`.
The `PBSMultiRunner` generates a top-level `pbs_multirunner.all` pbs job capable of launching all the HTC-specific PBS files in a folder.
The `PBSMultiRunner` needs some information:
- queue (e.g. workq, windq, xpresq)
- nodes (number of nodes)
- ppn (processors per node). Be careful, ppn does not limit the job to this number of CPUs, i.e. you may occupy all resources of a full node even if you set ppn=10 - annoying other users of the node. Hence ppn should be 20 if you need to run more than a few simulations)
- wall time in seconds (after which the job will be terminated, i.e. approximately total simulation time divided by number of)
%% Cell type:code id: tags:
``` python
from wetb.utils.cluster_tools.pbsfile import PBSMultiRunner
pbs_all = PBSMultiRunner(workdir=pbs.workdir,
queue='workq', # alternatives workq, windq, xpresq
walltime=10, # expected total simulation time in seconds
nodes=1, # Number of nodes
ppn=2, # number of processors of each node (normally 20)
pbsfiles=None # If None, the multirunner searches for *.in files
)
pbs_all.save()
print (os.path.join(pbs_all.workdir, pbs_all.filename))
```
%% Output
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/pbs_multirunner.all
%% Cell type:markdown id: tags:
The pbs_multirunner.all will do the following:
- Get list of nodes assigned for the current job
- Make list of *.in pbs files.
- Sort pbs files according to their wall time and distribute the files to the available nodes. Longest simulations are run first
- Generate a file, `pbs.dict`, containing for each node a list of (pbs file, stdout filename, wall time):
`{'j-177': [('./pbs_in/tmp4.in', './stdout/tmp4.out', '00:20:00'), ('./pbs_in/tmp6.in', './stdout/tmp6.out', '00:20:00')]}`
- On each node, launch the assigned pbs files in parallel via Python's multiprocessing module.
You can see the content of the `pbs_multirunner.all` here:
%% Cell type:code id: tags:
``` python
!cat {os.path.join(pbs_all.workdir, pbs_all.filename)}
```
%% Output
### Jobid
#PBS -N pbs_multirunner
### Standard Output
#PBS -o /home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/stdout/pbs_multirunner.out
### merge stderr into stdout
#PBS -j oe
#PBS -W umask=0003
### Maximum wallclock time format HOURS:MINUTES:SECONDS
#PBS -l walltime=00:00:10
#PBS -l nodes=1:ppn=2
### Queue name
#PBS -q workq
cd "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0"
mkdir -p "stdout"
if [ -z "$PBS_JOBID" ]; then echo "Run using qsub"; exit ; fi
pwd
echo "import os
import glob
import numpy as np
import re
# find available nodes
with open(os.environ['PBS_NODEFILE']) as fid:
nodes = set([f.strip() for f in fid.readlines() if f.strip() != ''])
pbs_files = [os.path.join(root, f) for root, folders, f_lst in os.walk('.') for f in f_lst if f.endswith('.in')]
# Make a list of [(pbs_in_filename, stdout_filename, walltime),...]
pat = re.compile(r'[\s\S]*#\s*PBS\s+-o\s+(.*)[\s\S]*(\d\d:\d\d:\d\d)[\s\S]*')
def get_info(f):
try:
with open(f) as fid:
return (f,) + pat.match(fid.read()).groups()
except Exception:
return (f, f.replace('.in', '.out'), '00:30:00')
pbs_info_lst = map(get_info, pbs_files)
# sort wrt walltime
pbs_info_lst = sorted(pbs_info_lst, key=lambda fow: tuple(map(int, fow[2].split(':'))))[::-1]
# make dict {node1: pbs_info_lst1, ...} and save
d = dict([(f, pbs_info_lst[i::len(nodes)]) for i, f in enumerate(nodes)])
with open('pbs.dict', 'w') as fid:
fid.write(str(d))
" | python
for node in `cat $PBS_NODEFILE | sort | uniq`
do
ssh -T $node << EOF &
cd "/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0"
python -c "import os
import multiprocessing
import platform
import time
with open('pbs.dict') as fid:
pbs_info_lst = eval(fid.read())[platform.node()]
arg_lst = ['echo starting %s && mkdir -p "%s" && env PBS_JOBID=$PBS_JOBID "%s" &> "%s" && echo finished %s' %
(f, os.path.dirname(o), f, o, f) for f, o, _ in pbs_info_lst]
print(arg_lst[0])
print('Starting %d jobs on %s' % (len(arg_lst), platform.node()))
pool = multiprocessing.Pool(int('$PBS_NUM_PPN'))
res = pool.map_async(os.system, arg_lst)
t = time.time()
for (f, _, _), r in zip(pbs_info_lst, res.get()):
print('%-50s\t%s' % (f, ('Errorcode %d' % r, 'Done')[r == 0]))
print('Done %d jobs on %s in %ds' % (len(arg_lst), platform.node(), time.time() - t))
"
EOF
done
wait
exit
%% Cell type:markdown id: tags:
You can launch the multirunner via
```bash
qsub <...>/wetb/hawc2/tests/test_files/simulation_setup\pbs_multirunner.all
```
It is done here:
%% Cell type:code id: tags:
``` python
!qsub {os.path.join(pbs_all.workdir, pbs_all.filename)}
```
%% Output
3221548.jess.dtu.dk
%% Cell type:markdown id: tags:
The job will now enter the cluster queue and be launched when free resoureces are available. You can check the status of the job:
%% Cell type:code id: tags:
``` python
!qstat -n -u $USER
```
%% Cell type:markdown id: tags:
Wait as long as the qstat command above prints information about the job
When the job is finished we can check the output file
%% Cell type:code id: tags:
``` python
!cat {pbs_all.stdout_filename}
```
%% Output
Start of prologue
/scratch/mmpe/3221548.jess.dtu.dk created
End of prologue
/home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0
Warning: Permanently added 'j-176,172.16.1.76' (RSA) to the list of known hosts.
echo starting ./pbs_in/tmp4.in && mkdir -p /home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/stdout && env PBS_JOBID=3221548.jess.dtu.dk ./pbs_in/tmp4.in &> /home/mmpe/gitlab/WindEnergyToolbox/wetb/hawc2/tests/test_files/simulation_setup/DTU10MWRef6.0/stdout/tmp4.out && echo finished ./pbs_in/tmp4.in
Starting 2 jobs on j-176
starting ./pbs_in/tmp4.in
starting ./pbs_in/tmp6.in
finished ./pbs_in/tmp6.in
finished ./pbs_in/tmp4.in
./pbs_in/tmp4.in Done
./pbs_in/tmp6.in Done
Done 2 jobs on j-176 in 4s
Start of epilogue on j-176
Resources Used: cput=00:00:00,mem=0kb,vmem=0kb,walltime=00:00:06
End of epilogue on j-176
%% Cell type:code id: tags:
``` python
```
# Tutorial 2: Creating subordinate Excel files # Tutorial 2: Creating subordinate Excel files
The Wind Energy Toolbox has a workflow for automatically running design load The Wind Energy Toolbox has a workflow for automatically running design load
bases (DLBs) on Gorm. bases (DLBs) on Gorm.
This workflow has the following steps: This workflow has the following steps:
1. [Create a master Excel sheet defining each case in the DLB](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/1-creating-master-excel.md) 1. [Create a master Excel sheet defining each case in the DLB](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/1-creating-master-excel.md)
2. Create subordinate Excel sheets from each tab in the master Excel sheet 2. Create subordinate Excel sheets from each tab in the master Excel sheet
3. [Create htc files and PBS job scripts for each requisite simulation using 3. [Create htc files and PBS job scripts for each requisite simulation using
the subordinate Excel files and a master htc file.](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/3-creating-htc-pbs-files.md) the subordinate Excel files and a master htc file.](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/3-creating-htc-pbs-files.md)
4. Submit all PBS job scripts to the cluster 4. Submit all PBS job scripts to the cluster
5. Post-process results 5. Post-process results
...@@ -13,7 +13,7 @@ the subordinate Excel files and a master htc file.](https://gitlab.windenergy.dt ...@@ -13,7 +13,7 @@ the subordinate Excel files and a master htc file.](https://gitlab.windenergy.dt
This tutorial presents how to accomplish Step 2. This tutorial presents how to accomplish Step 2.
Note that it is possible to customize your simulations by skipping/modifying Note that it is possible to customize your simulations by skipping/modifying
steps. steps.
Such a procedure will be discussed in a later tutorial. Such a procedure will be discussed in a later tutorial.
...@@ -22,44 +22,44 @@ https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/issues). ...@@ -22,44 +22,44 @@ https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/issues).
## 1. Background: Subordinate Excel Files ## 1. Background: Subordinate Excel Files
The subordinate Excel files are a series of basic Excel files that are The subordinate Excel files are a series of basic Excel files that are
generated from the master Excel file. (See our tutorial on generating the generated from the master Excel file. (See our tutorial on generating the
master Excel file [here]( https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tut orials/1-creating-master-excel.md).) master Excel file [here]( https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tut orials/1-creating-master-excel.md).)
There is a different subordinate Excel file for every tab in the master Excel There is a different subordinate Excel file for every tab in the master Excel
file, except for the "Main" tab, one for each case to simulate (e.g., design file, except for the "Main" tab, one for each case to simulate (e.g., design
load case 1.2 from IEC-61400-1). load case 1.2 from IEC-61400-1).
Each subordinate Excel file has a single tab that lists the different tag Each subordinate Excel file has a single tab that lists the different tag
values for the htc master file in the column, and each row corresponds to a values for the htc master file in the column, and each row corresponds to a
different htc file to be generated. different htc file to be generated.
The generation of the htc files from the subordinate Excel files is discused The generation of the htc files from the subordinate Excel files is discused
in the next tutorial. in the next tutorial.
## 2. Tutorial ## 2. Tutorial
The generation of the subordinate Excel files is done using the The generation of the subordinate Excel files is done using the
[GenerateDLS.py](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/wetb/prepost/GenerateDLCs.py) [GenerateDLS.py](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/wetb/prepost/GenerateDLCs.py)
function in the Wind Energy Toolbox. function in the Wind Energy Toolbox.
On Gorm, the command can be executed from the htc directory with the master On Gorm, the command can be executed from the htc directory with the master
Excel file as follows: Excel file as follows:
``` ```
export PATH=/home/python/miniconda3/bin:$PATH export PATH=/home/python/miniconda3/bin:$PATH
source activate wetb_py3 source activate py36-wetb
python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py [--folder=$FOLDER_NAME] [--master=$MASTER_NAME] python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/GenerateDLCs.py [--folder=$FOLDER_NAME] [--master=$MASTER_NAME]
source deactivate source deactivate
``` ```
The ```export PATH``` command adds the miniconda bin directory to the path, The ```export PATH``` command adds the miniconda bin directory to the path,
which is necessary for the toolbox. which is necessary for the toolbox.
The ```source activate wetb_py3``` and ```source deactivate``` are The ```source activate py36-wetb``` and ```source deactivate``` are
Gorm-specific commands to activate the Wind Energy Toolbox Python environment. Gorm-specific commands to activate the Wind Energy Toolbox Python environment.
The ```--folder``` and ```--master``` flags are optional flags to specify, The ```--folder``` and ```--master``` flags are optional flags to specify,
respectively, the name of the folder to which the subordinate Excel files respectively, the name of the folder to which the subordinate Excel files
should be written to and the name of the master Excel file. should be written to and the name of the master Excel file.
The default values for these two options are './' (i.e., the current The default values for these two options are './' (i.e., the current
directory) and 'DLCs.xlsx', respectively. directory) and 'DLCs.xlsx', respectively.
After running the commands in the above box on Gorm, you should see a folder in After running the commands in the above box on Gorm, you should see a folder in
your htc directory with all of your subordinate Excel files. your htc directory with all of your subordinate Excel files.
......
# Tutorial 3: Creating htc and PBS files # Tutorial 3: Creating htc and PBS files
The Wind Energy Toolbox has a workflow for automatically running design load The Wind Energy Toolbox has a workflow for automatically running design load
bases (DLBs) on Gorm. bases (DLBs) on Gorm.
This workflow has the following steps: This workflow has the following steps:
1. [Create a master Excel sheet defining each case in the DLB](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/1-creating-master-excel.md) 1. [Create a master Excel sheet defining each case in the DLB](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/1-creating-master-excel.md)
2. [Create subordinate Excel sheets from each tab in the master Excel sheet](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/2-creating-subordinate-excels.md) 2. [Create subordinate Excel sheets from each tab in the master Excel sheet](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/docs/tutorials/2-creating-subordinate-excels.md)
3. Create htc files and PBS job scripts for each requisite simulation using 3. Create htc files and PBS job scripts for each requisite simulation using
the subordinate Excel files and a master htc file. the subordinate Excel files and a master htc file.
4. Submit all PBS job scripts to the cluster 4. Submit all PBS job scripts to the cluster
5. Post-process results 5. Post-process results
...@@ -13,7 +13,7 @@ the subordinate Excel files and a master htc file. ...@@ -13,7 +13,7 @@ the subordinate Excel files and a master htc file.
This tutorial presents how to accomplish Step 3. This tutorial presents how to accomplish Step 3.
Note that it is possible to customize your simulations by skipping/modifying Note that it is possible to customize your simulations by skipping/modifying
steps. steps.
Such a procedure will be discussed in a later tutorial. Such a procedure will be discussed in a later tutorial.
...@@ -23,16 +23,16 @@ https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/issues). ...@@ -23,16 +23,16 @@ https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/issues).
## 1. Background: htc and PBS file creation ## 1. Background: htc and PBS file creation
The main function used in this tutorial is [dlctemplate.py](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/wetb/prepost/dlctemplate.py), The main function used in this tutorial is [dlctemplate.py](https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox/blob/master/wetb/prepost/dlctemplate.py),
which creates all htc and PBS job scripts for the cases specified in the which creates all htc and PBS job scripts for the cases specified in the
subordinate Excel file folder. subordinate Excel file folder.
The htc files are the main input files for HAWC2 simulations. The htc files are the main input files for HAWC2 simulations.
They are created by copying the master htc file in the ```_master/``` folder in They are created by copying the master htc file in the ```_master/``` folder in
your htc directory and replacing all of the tags with the values specified in your htc directory and replacing all of the tags with the values specified in
the subordinate Excel files. the subordinate Excel files.
All of htc files for a single case are saved in a case-specific folder in your All of htc files for a single case are saved in a case-specific folder in your
htc folder. htc folder.
Thus, if you were running a standard DLB calculation for IEC 61400-1, your Thus, if you were running a standard DLB calculation for IEC 61400-1, your
folder structure after generating your htc files might look like this: folder structure after generating your htc files might look like this:
``` ```
|-- $TURB_NAME/ |-- $TURB_NAME/
...@@ -50,9 +50,9 @@ folder structure after generating your htc files might look like this: ...@@ -50,9 +50,9 @@ folder structure after generating your htc files might look like this:
| | | |-- ... | | | |-- ...
``` ```
The PBS job scripts are a series of text files that are used to tell the job The PBS job scripts are a series of text files that are used to tell the job
scheduler on the high-performance computing (HPC) cluster how to run each job. scheduler on the high-performance computing (HPC) cluster how to run each job.
These files end with ".p", and are saved to a folder ```pbs_in/``` that is These files end with ".p", and are saved to a folder ```pbs_in/``` that is
created in the main set ID folder on Gorm. created in the main set ID folder on Gorm.
...@@ -61,29 +61,29 @@ created in the main set ID folder on Gorm. ...@@ -61,29 +61,29 @@ created in the main set ID folder on Gorm.
There are two ways to call ```dlctemplate.py```. There are two ways to call ```dlctemplate.py```.
The first is to call the function directly. The first is to call the function directly.
The second is to wrap it in a job scheduler to submit the job to the HPC cluster. The second is to wrap it in a job scheduler to submit the job to the HPC cluster.
The first option is fine if you have only a few htc files or if the job The first option is fine if you have only a few htc files or if the job
scheduler is not working for some reason. scheduler is not working for some reason.
The second option is generally preferred. The second option is generally preferred.
### 2.1 Directly generate htc files ### 2.1 Directly generate htc files
The htc and PBS files can be directly generated by running the following The htc and PBS files can be directly generated by running the following
commands from the set ID directory: commands from the set ID directory:
``` ```
export PATH=/home/python/miniconda3/bin:$PATH export PATH=/home/python/miniconda3/bin:$PATH
source activate wetb_py3 source activate py36-wetb
python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py --prep python /home/MET/repositories/toolbox/WindEnergyToolbox/wetb/prepost/dlctemplate.py --prep
source deactivate source deactivate
``` ```
The ```export PATH``` command adds the miniconda bin directory to the path, The ```export PATH``` command adds the miniconda bin directory to the path,
which is necessary for the toolbox. which is necessary for the toolbox.
The ```source activate wetb_py3``` and ```source deactivate``` are The ```source activate py36-wetb``` and ```source deactivate``` are
Gorm-specific commands to activate the Wind Energy Toolbox Python environment. Gorm-specific commands to activate the Wind Energy Toolbox Python environment.
The ```--prep``` option tells the script to run in preparation mode, in which The ```--prep``` option tells the script to run in preparation mode, in which
case it creates the htc and pbs files. case it creates the htc and pbs files.
After running the commands in the above box on Gorm, you should have all of your After running the commands in the above box on Gorm, you should have all of your
PBS input files in ```pbs_in/``` and all of your htc files in ```htc```. PBS input files in ```pbs_in/``` and all of your htc files in ```htc```.
### 2.2 Generate files using job scheduler ### 2.2 Generate files using job scheduler
......
# Update conda ```wetb_py3``` environment and ```wetb``` # Update conda ```py36-wetb``` environment and ```wetb```
There are pre-configured miniconda/anaconda python environments installed on There are pre-configured miniconda/anaconda python environments installed on
Gorm and Jess at: Gorm and Jess at:
``` ```
/home/python/miniconda3/envs/wetb_py3 /home/python/miniconda3/envs/py36-wetb
``` ```
Note that these refer to the home drives of Gorm and Jess respectively and thus Note that these refer to the home drives of Gorm and Jess respectively and thus
refer to two different directories (but are named the same). refer to two different directories (but are named the same).
...@@ -15,20 +15,20 @@ Update the root Anaconda environment: ...@@ -15,20 +15,20 @@ Update the root Anaconda environment:
conda update --all conda update --all
``` ```
Activate the ```wetb_py3``` environment: Activate the ```py36-wetb``` environment:
``` ```
source activate wetb_py3 source activate py36-wetb
``` ```
Update the ```wetb_py3``` environment: Update the ```py36-wetb``` environment:
``` ```
conda update --all conda update --all
``` ```
Pull latest wetb changes and create re-distributable binary wheel package for ```wetb_py3```: Pull latest wetb changes and create re-distributable binary wheel package for ```py36-wetb```:
``` ```
cd /home/MET/repositories/tooblox/WindEnergyToolbox cd /home/MET/repositories/tooblox/WindEnergyToolbox
...@@ -45,5 +45,5 @@ pip install --no-deps -U dist/wetb-X.Y.Z.post0.devXXXXXXXX-cp35m-linux_x86_64.wh ...@@ -45,5 +45,5 @@ pip install --no-deps -U dist/wetb-X.Y.Z.post0.devXXXXXXXX-cp35m-linux_x86_64.wh
The option ```--no-deps``` is used here to avoid pip installing possible newer The option ```--no-deps``` is used here to avoid pip installing possible newer
versions of packages that should be managed by conda. This only works when all versions of packages that should be managed by conda. This only works when all
dependencies of ```wetb``` are met (which is assumed by default for the dependencies of ```wetb``` are met (which is assumed by default for the
```wetb_py3``` environment). ```py36-wetb``` environment).
"""
Created on Wed Oct 10 12:47:10 2018
@author: dave
"""
import os
from wetb.prepost import windIO
from wetb.hawc2 import Hawc2io
from wetb.prepost import hawcstab2
# =============================================================================
# READ HAWC2 RESULT FILE
# =============================================================================
# METHOD A
fname = '../wetb/hawc2/tests/test_files/hawc2io/Hawc2ascii.sel'
res = Hawc2io.ReadHawc2(fname)
sig = res.ReadAll()
# METHOD B
path, file = os.path.dirname(fname), os.path.basename(fname)
res = windIO.LoadResults(path, file)
sig = res.sig
sel = res.ch_details
# result in dataframe with unique channel names (instead of indices)
sig_df = res.sig2df()
ch_df = res.ch_df
# =============================================================================
# READ HAWCStab2 files
# =============================================================================
res = hawcstab2.results()
fname = '../wetb/prepost/tests/data/campbell_diagram.cmb'
df_cmb = res.load_cmb_df(fname)
fname = '../wetb/prepost/tests/data/dtu10mw_v1_defl_u10000.ind'
df_ind = res.load_ind(fname)
fname = '../wetb/prepost/tests/data/dtu10mw.opt'
df_opt = res.load_operation(fname)
fname = '../wetb/prepost/tests/data/dtu10mw_v1.pwr'
df_pwr, units = res.load_pwr_df(fname)
fname = '../wetb/prepost/tests/data/controller_input_quadratic.txt'
tuning = hawcstab2.ReadControlTuning()
tuning.read_parameters(fname)
# tuning parameters are saved as attributes
tuning.pi_gen_reg1.K
tuning.pi_gen_reg2.I
tuning.pi_gen_reg2.Kp
tuning.pi_gen_reg2.Ki
tuning.pi_gen_reg2.Kd
tuning.pi_pitch_reg3.Kp
tuning.pi_pitch_reg3.Ki
tuning.pi_pitch_reg3.Kd
tuning.pi_pitch_reg3.K1
tuning.pi_pitch_reg3.K2
tuning.aero_damp.Kp2
tuning.aero_damp.Ko1
tuning.aero_damp.Ko2
# or you can get them as a dictionary
tune_tags = tuning.parameters2tags()
'''
Created on 28. jul. 2017
@author: mmpe
'''
import os
import subprocess
def _run_git_cmd(cmd, git_repo_path=None):
git_repo_path = git_repo_path or os.getcwd()
if not os.path.isdir(os.path.join(git_repo_path, ".git")):
raise Warning("'%s' does not appear to be a Git repository." % git_repo_path)
try:
process = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
cwd=os.path.abspath(git_repo_path))
stdout,stderr = process.communicate()
if process.returncode != 0:
raise EnvironmentError("%s\n%s"%(stdout, stderr))
return stdout.strip()
except EnvironmentError as e:
raise e
raise Warning("unable to run git")
def get_git_branch(git_repo_path=None):
cmd = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
return _run_git_cmd(cmd, git_repo_path)
def get_git_version(git_repo_path=None):
cmd = ["git", "describe", "--tags", "--dirty", "--always"]
# format it will return: 'v0.1.0-12-g22668f0'
v = _run_git_cmd(cmd, git_repo_path)
# convert to something Pypi likes: 0.1.2.dev3.123456
# see also https://setuptools.pypa.io/en/latest/userguide/distribution.html
# and/or PEP440 https://peps.python.org/pep-0440/
v = v.replace('-', '.post', 1)
return v
def get_tag(git_repo_path=None, verbose=False):
tag = _run_git_cmd(['git', 'describe', '--tags', '--always', '--abbrev=0'],
git_repo_path)
if verbose:
print(tag)
return tag
def set_tag(tag, push, git_repo_path=None):
_run_git_cmd(["git", "tag", tag], git_repo_path)
if push:
_run_git_cmd(["git", "push"], git_repo_path)
_run_git_cmd(["git", "push", "--tags"], git_repo_path)
def update_git_version(version_module, git_repo_path=None):
"""Update <version_module>.__version__ to git version"""
version_str = get_git_version(git_repo_path)
assert os.path.isfile(version_module.__file__)
with open(version_module.__file__, "w") as fid:
fid.write("__version__ = '%s'" % version_str)
# ensure file is written, closed and ready
with open(version_module.__file__) as fid:
fid.read()
return version_str
def write_vers(vers_file='wetb/__init__.py', repo=None, skip_chars=1):
"""Writes out version string as follows:
"last tag"-("nr commits since tag")-("branch name")-("hash commit")
and where nr of commits since last tag is only included if >0,
branch name is only inlcuded when not on master,
and hash commit is only included when not at a tag (when nr of commits > 0)
"""
if not repo:
repo = os.getcwd()
version_long = get_git_version(repo)
branch = get_git_branch(repo)
verel = version_long.split('-')
# tag name
version = verel[0][skip_chars:]
# number of commits since last tag, only if >0
nr_commits = 0
if len(verel) > 1:
try:
nr_commits = int(verel[1])
except ValueError:
nr_commits = -1
if nr_commits > 0:
version += '-' + verel[1]
# branch name, only when NOT on master
if branch != 'master':
version += '-' + branch
# hash commit, only if not at tag
if len(verel) > 2 and nr_commits > 0:
# first character on the hash is always a g (not part of the hash)
version += '-' + verel[2][1:]
# if "-HEAD" is added to the version, which pypi does not like:
if version.endswith('-HEAD'):
version = version[:-5]
print(version_long)
print('Writing version: {} in {}'.format(version, vers_file))
with open(vers_file, 'r') as f:
lines = f.readlines()
for n, l in enumerate(lines):
if l.startswith('__version__'):
lines[n] = "__version__ = '{}'\n".format(version)
for n, l in enumerate(lines):
if l.startswith('__release__'):
lines[n] = "__release__ = '{}'\n".format(version)
with open(vers_file, 'w') as f:
f.write(''.join(lines))
return version
def rename_dist_file():
for f in os.listdir('dist'):
if f.endswith('whl'):
split = f.split('linux')
new_name = 'manylinux1'.join(split)
old_path = os.path.join('dist', f)
new_path = os.path.join('dist', new_name)
os.rename(old_path, new_path)
def main():
"""Example of how to run (pytest-friendly)"""
if __name__ == '__main__':
pass
main()
File added
[build-system]
requires = [
"setuptools>=60",
"setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"
[project]
name = "wetb"
authors = [{name="DTU Wind and Energy Systems"}]
description = "The Wind Energy Toolbox (or ```wetb```, pronounce as wee-tee-bee) is a collection of Python scripts that facilitate working with (potentially a lot) of HAWC2, HAWCStab2, FAST or other text input based simulation tools."
dependencies = [
'certifi',
'click',
'Cython',
'h5py',
'Jinja2',
'lxml',
'matplotlib',
'pillow',
'mock',
'numpy',
'numba',
'openpyxl',
'pandas',
'paramiko',
'psutil',
'pytest',
'pytest-cov',
'scipy',
'sshtunnel',
'tables',
'tqdm',
'xarray',
'xlwt',
'XlsxWriter',
]
license = {text = "wetb is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL, http://www.gnu.org/copyleft/gpl.html) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. wetb is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details http://www.gnu.org/licenses/ We encourage you to submit new code for possible inclusion in future versions of wetb."}
dynamic = ["version"]
[project.urls]
repository = "https://gitlab.windenergy.dtu.dk/toolbox/WindEnergyToolbox"
documentation = "https://toolbox.pages.windenergy.dtu.dk/WindEnergyToolbox/"
[project.optional-dependencies]
prepost = ["openpyxl", "tables", "xlwt", "Cython"]
all = ["openpyxl", "tables", "xlwt", "Cython", "paramiko", "sshtunnel", 'pytest', 'mock', 'click']
[tool.setuptools_scm]
version_scheme = "no-guess-dev"
[tool.setuptools]
packages = ["wetb"]