Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 122 additions & 11 deletions docs/source/install_linux.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,136 @@
OpenFAST
========
Building OpenFAST
=================

OpenFAST uses the `CMake <https://cmake.org>`__ build system.
We recommend building OpenFAST using `Spack <https://spack.readthedocs.io/en/latest>`__.
However, we also provide some sample scripts in ``openfast/share`` if you choose to proceed without `Spack`.

Dependencies
------------

OpenFAST has the following dependencies:

- LAPACK libraries provided through the variable ``BLASLIB``
- for the C++ API, `HDF5 <https://support.hdfgroup.org/HDF5/>`__ (provided by ``HDF5_ROOT``) and `yaml-cpp <https://github.com/jbeder/yaml-cpp>`__ (provided by ``YAML_ROOT``).

CMake Build Instructions
------------------------

::

git clone https://github.com/OpenFAST/OpenFAST.git
cd OpenFAST
mkdir build && cd build
cmake ../
make

A sample installation shell script is also provided in the ``openfast/share``. Run the script from ``openfast/`` as:
::

git clone https://github.com/OpenFAST/OpenFAST.git
cd OpenFAST
bash share/install.sh

Current CMake Options
~~~~~~~~~~~~~~~~~~~~~

- ``DOUBLE_PRECISION`` - Enable/disable ``-DDOUBLE_PRECISION`` flag
(Default: ON)
- ``USE_DLL_INTERFACE`` - Enable dynamic library loading capability
(Default: ON)
- ``CMAKE_BUILD_TYPE`` - Release, Debug builds (Default: Release)
- ``CMAKE_INSTALL_PREFIX`` - Set desired installation directory
- ``BUILD_SHARED_LIBS`` - Enable/disable building shared libraries
(Default: OFF)
- ``BUILD_DOCUMENTATION`` - Build documentation (Default: OFF)
- ``BUILD_FAST_CPP_API`` - Enable building FAST - C++ API (Default: OFF)
- ``BUILD_SHARED_LIBS`` - Enable building shared libraries (Default: OFF)
- ``CMAKE_BUILD_TYPE`` - Choose the build type: Debug Release (Default: Release)
- ``CMAKE_INSTALL_PREFIX`` - Install path prefix, prepended onto install directories.
- ``DOUBLE_PRECISION`` - Treat REAL as double precision (Default: ON)
- ``FPE_TRAP_ENABLED`` - Enable Floating Point Exception (FPE) trap in compiler options (Default: OFF)
- ``ORCA_DLL_LOAD`` - Enable OrcaFlex library load (Default: OFF)
- ``USE_DLL_INTERFACE`` - Enable runtime loading of dynamic libraries (Default: ON)

Building OpenFAST Semi-Automatically Using Spack on macOS or Linux
---------------------------------------------------------------------

The following describes how to build OpenFAST and its dependencies
mostly automatically on your Mac using
`Spack <https://spack.readthedocs.io/en/latest>`__.
This can also be used as a template to build OpenFAST on any
Linux system with Spack.

These instructions were developed on macOS 10.11 with the following tools installed via Homebrew:

- GCC 6.3.0
- CMake 3.6.1
- pkg-config 0.29.2

Step 1
~~~~~~

Checkout the official Spack repo from github (we will checkout into ``${HOME}``):

``cd ${HOME} && git clone https://github.com/LLNL/spack.git``

Step 2
~~~~~~

Add Spack shell support to your ``.profile`` by adding the lines:

::

export SPACK_ROOT=${HOME}/spack
. $SPACK_ROOT/share/spack/setup-env.sh

Step 3
~~~~~~

Copy the `https://github.com/OpenFAST/openfast/dev/share/spack/package.py`__ file
to your installation of Spack:

::

mkdir ${SPACK_ROOT}/var/spack/repos/builtin/packages/openfast
cd ${SPACK_ROOT}/var/spack/repos/builtin/packages/openfast
wget --no-check-certificate https://github.com/OpenFAST/openfast/dev/share/spack/package.py

Step 4
~~~~~~

Try ``spack info openfast`` to see if Spack works. If it does, check the
compilers you have available by:

::

machine:~ user$ spack compilers
==> Available compilers
-- gcc ----------------------------------------------------------
gcc@6.3.0 gcc@4.2.1

-- clang --------------------------------------------------------
clang@8.0.0-apple clang@7.3.0-apple

Step 5
~~~~~~

Install OpenFAST with your chosen version of GCC:

::

spack install openfast %gcc@6.3.0

To install OpenFAST with the C++ API, do:

::

spack install openfast+cxx %gcc@6.3.0

That should be it! Spack will automatically use the most up-to-date dependencies
unless otherwise specified. For example to constrain OpenFAST to use some specific
versions of dependencies you could issue the Spack install command:

::

spack install openfast %gcc@6.3.0 ^hdf5@1.8.16

The executables and libraries will be located at

::

spack location -i openfast


Add the appropriate paths to your ``PATH`` and ``LD_LIBRARY_PATH`` to run OpenFAST.
10 changes: 10 additions & 0 deletions glue-codes/fast-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,30 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(MPI REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(ZLIB REQUIRED)
find_package(HDF5 REQUIRED COMPONENTS C HL)
find_package(YAMLCPP REQUIRED)

include_directories(${YAML_INCLUDES})
include_directories(${HDF5_INCLUDES})
include_directories(${HDF5_INCLUDE_DIR})
include_directories(${ZLIB_INCLUDES})
include_directories(${LIBXML2_INCLUDE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/modules-local/fast-library/src/)
include_directories(${CMAKE_BINARY_DIR}/modules-local/openfoam/)
include_directories(${CMAKE_BINARY_DIR}/modules-local/supercontroller/)
include_directories(${MPI_INCLUDE_PATH})

add_library(openfastcpplib
src/OpenFAST.cpp)
set_property(TARGET openfastcpplib PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(openfastcpplib
openfastlib
${HDF5_C_LIBRARIES}
${HDF5_HL_LIBRARIES}
${ZLIB_LIBRARIES}
${LIBXML2_LIBRARIES}
${CMAKE_DL_LIBS})

add_executable(openfastcpp
Expand All @@ -43,6 +51,8 @@ target_link_libraries(openfastcpp openfastcpplib openfastlib
${MPI_LIBRARIES} ${YAML_LIBRARIES}
${HDF5_C_LIBRARIES}
${HDF5_HL_LIBRARIES}
${ZLIB_LIBRARIES}
${LIBXML2_LIBRARIES}
${CMAKE_DL_LIBS})

if(MPI_COMPILE_FLAGS)
Expand Down
2 changes: 1 addition & 1 deletion glue-codes/fast-cpp/src/OpenFAST.H
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class OpenFAST {
void end();

hid_t openVelocityDataFile(bool createFile);
int readVelocityData();
void readVelocityData(int nTimesteps);
void writeVelocityData(hid_t h5file, int iTurb, int iTimestep, OpFM_InputType_t iData, OpFM_OutputType_t oData);
herr_t closeVelocityDataFile(int nt_global, hid_t velDataFile);

Expand Down
26 changes: 8 additions & 18 deletions glue-codes/fast-cpp/src/OpenFAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,8 @@ void fast::OpenFAST::init() {
int nTimesteps;

if (nTurbinesProc > 0) {
nTimesteps = readVelocityData();
if (nTimesteps != ntStart) throw std::runtime_error("Start time is not consistent with the number of timesteps in the velocity data file");
readVelocityData(ntStart);
}

for (int iTurb=0; iTurb < nTurbinesProc; iTurb++) {
applyVelocityData(0, iTurb, cDriver_Output_to_FAST[iTurb], velNodeData[iTurb]);
}
Expand Down Expand Up @@ -758,9 +756,9 @@ void fast::OpenFAST::end() {

}

int fast::OpenFAST::readVelocityData() {
void fast::OpenFAST::readVelocityData(int nTimesteps) {

int nTurbines, nTimesteps;
int nTurbines;

hid_t velDataFile = H5Fopen(("velDatafile." + std::to_string(worldMPIRank) + ".h5").c_str(), H5F_ACC_RDWR, H5P_DEFAULT);

Expand All @@ -769,10 +767,6 @@ int fast::OpenFAST::readVelocityData() {
herr_t ret = H5Aread(attr, H5T_NATIVE_INT, &nTurbines) ;
H5Aclose(attr);

attr = H5Aopen(velDataFile, "nTimesteps", H5P_DEFAULT);
ret = H5Aread(attr, H5T_NATIVE_INT, &nTimesteps) ;
H5Aclose(attr);

}

// Allocate memory and read the velocity data.
Expand All @@ -797,8 +791,6 @@ int fast::OpenFAST::readVelocityData() {

}

return nTimesteps;

}

hid_t fast::OpenFAST::openVelocityDataFile(bool createFile) {
Expand Down Expand Up @@ -854,19 +846,13 @@ hid_t fast::OpenFAST::openVelocityDataFile(bool createFile) {

herr_t fast::OpenFAST::closeVelocityDataFile(int nt_global, hid_t velDataFile) {


hid_t attr_id = H5Aopen_by_name(velDataFile, ".", "nTimesteps", H5P_DEFAULT, H5P_DEFAULT);
herr_t status = H5Awrite(attr_id, H5T_NATIVE_INT, &nt_global);
status = H5Aclose(attr_id);

status = H5Fclose(velDataFile) ;
herr_t status = H5Fclose(velDataFile) ;
return status;
}


void fast::OpenFAST::writeVelocityData(hid_t h5File, int iTurb, int iTimestep, OpFM_InputType_t iData, OpFM_OutputType_t oData) {


hsize_t start[3]; start[0] = iTimestep; start[1] = 0; start[2] = 0;
int nVelPts = get_numVelPtsLoc(iTurb) ;
hsize_t count[3]; count[0] = 1; count[1] = nVelPts; count[2] = 6;
Expand All @@ -893,6 +879,10 @@ void fast::OpenFAST::writeVelocityData(hid_t h5File, int iTurb, int iTimestep, O
H5Sclose(dspace_id);
H5Sclose(mspace_id);

hid_t attr_id = H5Aopen_by_name(h5File, ".", "nTimesteps", H5P_DEFAULT, H5P_DEFAULT);
herr_t status = H5Awrite(attr_id, H5T_NATIVE_INT, &iTimestep);
status = H5Aclose(attr_id);

}

void fast::OpenFAST::applyVelocityData(int iPrestart, int iTurb, OpFM_OutputType_t cDriver_Output_to_FAST, std::vector<double> & velData) {
Expand Down
16 changes: 10 additions & 6 deletions modules-local/openfoam/src/OpenFOAM.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ SUBROUTINE CalcForceActuatorPositionsBlade(InitIn_OpFM, p_OpFM, structPositions,
! Now calculate the positions of the force nodes based on interpolation
DO I=1,p_OpFM%NnodesForceBlade ! Calculate the position of the force nodes
jLower=1
do while ( (rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .gt. 0 )
do while ( ( (rStructNodes(jLower) - p_OpFM%forceBldRnodes(I))*(rStructNodes(jLower+1) - p_OpFM%forceBldRnodes(I)) .gt. 0) .and. (jLower .lt. nStructNodes) )
jLower = jLower + 1
end do
rInterp = (p_OpFM%forceBldRnodes(I) - rStructNodes(jLower))/(rStructNodes(jLower+1)-rStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes
Expand Down Expand Up @@ -1066,7 +1066,7 @@ SUBROUTINE CalcForceActuatorPositionsTower(InitIn_OpFM, p_OpFM, structPositions,
! Now calculate the positions of the force nodes based on interpolation
DO I=1,p_OpFM%NnodesForceTower ! Calculate the position of the force nodes
jLower=1
do while ( (hStructNodes(jLower) - p_OpFM%forceTwrHnodes(I))*(hStructNodes(jLower+1) - p_OpFM%forceTwrHnodes(I)) .gt. 0 )
do while ( ((hStructNodes(jLower) - p_OpFM%forceTwrHnodes(I))*(hStructNodes(jLower+1) - p_OpFM%forceTwrHnodes(I)) .gt. 0) .and. (jLower .lt. nStructNodes))
jLower = jLower + 1
end do
hInterp = (p_OpFM%forceTwrHnodes(I) - hStructNodes(jLower))/(hStructNodes(jLower+1)-hStructNodes(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes
Expand Down Expand Up @@ -1098,18 +1098,20 @@ SUBROUTINE OpFM_CreateActForceBladeTowerNodes(p_OpFM, ErrStat, ErrMsg)
!Do the blade first
allocate(p_OpFM%forceBldRnodes(p_OpFM%NnodesForceBlade), stat=errStat2)
dRforceNodes = p_OpFM%BladeLength/(p_OpFM%NnodesForceBlade-1)
do i=1,p_OpFM%NnodesForceBlade
do i=1,p_OpFM%NnodesForceBlade-1
p_OpFM%forceBldRnodes(i) = (i-1)*dRforceNodes
end do
p_OpFM%forceBldRnodes(p_OpFM%NnodesForceBlade) = p_OpFM%BladeLength


!Do the tower now
allocate(p_OpFM%forceTwrHnodes(p_OpFM%NnodesForceTower), stat=errStat2)
dRforceNodes = p_OpFM%TowerHeight/(p_OpFM%NnodesForceTower-1)
do i=1,p_OpFM%NnodesForceTower
do i=1,p_OpFM%NnodesForceTower-1
p_OpFM%forceTwrHnodes(i) = (i-1)*dRforceNodes
end do

p_OpFM%forceTwrHnodes(p_OpFM%NnodesForceTower) = p_OpFM%TowerHeight

return

END SUBROUTINE OpFM_CreateActForceBladeTowerNodes
Expand All @@ -1127,6 +1129,7 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat,
!Local variables
INTEGER(IntKI) :: i,j,k,node ! Loop variables
INTEGER(IntKI) :: nNodesBladeProps ! Number of nodes in the blade properties for a given blade
INTEGER(IntKI) :: nNodesTowerProps ! Number of nodes in the tower properties
INTEGER(IntKI) :: jLower ! Index of the blade properties node just smaller than the force node
INTEGER(IntKi) :: ErrStat2 ! temporary Error status of the operation
CHARACTER(ErrMsgLen) :: ErrMsg2 ! temporary Error message if ErrStat /= ErrID_None
Expand Down Expand Up @@ -1159,12 +1162,13 @@ SUBROUTINE OpFM_InterpolateForceNodesChord(InitOut_AD, p_OpFM, u_OpFM, ErrStat,


! The tower now
nNodesTowerProps = SIZE(InitOut_AD%TwrElev)
do k = p_OpFM%NumBl+1,p_OpFM%NMappings
! Calculate the chord at the force nodes based on interpolation
DO I=1,p_OpFM%NnodesForceTower
Node = Node + 1
jLower=1
do while ( (InitOut_AD%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I))*(InitOut_AD%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)) .gt. 0 ) !Determine the closest two nodes at which the blade properties are specified
do while ( ( (InitOut_AD%TwrElev(jLower) - p_OpFM%forceTwrHnodes(I))*(InitOut_AD%TwrElev(jLower+1) - p_OpFM%forceTwrHnodes(I)) .gt. 0) .and. (jLower .le. nNodesTowerProps) ) !Determine the closest two nodes at which the blade properties are specified
jLower = jLower + 1
end do
rInterp = (p_OpFM%forceTwrHnodes(I) - InitOut_AD%TwrElev(jLower))/(InitOut_AD%TwrElev(jLower+1)-InitOut_AD%TwrElev(jLower)) ! The location of this force node in (0,1) co-ordinates between the jLower and jLower+1 nodes
Expand Down
41 changes: 41 additions & 0 deletions share/fast-build-cpp-spack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

set -ex

COMPILER=gcc
SPACK_ROOT=
SPACK_EXE=${SPACK_ROOT}/bin/spack
module purge
module load gcc/5.2.0
module load python/2.7.8
module use ${SPACK_ROOT}/share/spack/modules/$(${SPACK_EXE} arch)
module load $(${SPACK_EXE} module find cmake %${COMPILER})
module load $(${SPACK_EXE} module find openmpi %${COMPILER})
module load $(${SPACK_EXE} module find hdf5 %${COMPILER})
module load $(${SPACK_EXE} module find zlib %${COMPILER})
module load $(${SPACK_EXE} module find libxml2 %${COMPILER})
module load $(${SPACK_EXE} module find xz %${COMPILER})
module load $(${SPACK_EXE} module find binutils %${COMPILER})
module list
which cmake


OPENFAST_DIR=
yaml_install_dir=`${SPACK_EXE} location -i yaml-cpp %${COMPILER}`
hdf5_install_dir=`${SPACK_EXE} location -i hdf5 %${COMPILER}`
zlib_install_dir=`${SPACK_EXE} location -i zlib %${COMPILER}`
libxml2_install_dir=`${SPACK_EXE} location -i libxml2 %${COMPILER}`
CC=gcc CXX=g++ FC=gfortran cmake \
-DCMAKE_INSTALL_PREFIX=${OPENFAST_DIR}/install/ \
-DCMAKE_BUILD_TYPE=DEBUG \
-DBUILD_FAST_CPP_API=ON \
-DFPE_TRAP_ENABLED:BOOL=ON \
-DYAML_ROOT:PATH=$yaml_install_dir \
-DHDF5_USE_STATIC_LIBRARIES=ON \
-DHDF5_ROOT:PATH=$hdf5_install_dir \
-DLIBXML2_ROOT:PATH=$libxml2_install_dir \
-DLIBXML2_USE_STATIC_LIBRARIES=ON \
-DHDF5_ROOT:PATH=$hdf5_install_dir \
$EXTRA_ARGS \
../ &> log.cmake
make VERBOSE=1 &> log.make
19 changes: 19 additions & 0 deletions share/fast-build-cpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
openfast_dir=
yaml_install_dir=$openfast_dir/install/
hdf5_install_dir=$openfast_dir/install/

EXTRA_ARGS=$@

CC=mpicc CXX=mpic++ FC=gfortran cmake \
-DCMAKE_INSTALL_PREFIX=$openfast_dir/install/ \
-DCMAKE_BUILD_TYPE=RELEASE \
-DBUILD_FAST_CPP_API=ON \
-DYAML_ROOT:PATH=$yaml_install_dir \
-DHDF5_USE_STATIC_LIBRARIES=ON \
-DHDF5_ROOT:PATH=$hdf5_install_dir \
-DLAPACK_LIBRARIES="$BLASLIB" \
-DBLAS_LIBRARIES="$BLASLIB" \
-DFPE_TRAP_ENABLED=OFF \
$EXTRA_ARGS \
../ &> log.cmake

Loading