Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added MoorDyn support to FastFarmCaseCreation #37

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
454 changes: 265 additions & 189 deletions openfast_toolbox/fastfarm/FASTFarmCaseCreation.py

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions openfast_toolbox/fastfarm/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion openfast_toolbox/fastfarm/examples/Ex2_FFarmInputSetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import matplotlib.pyplot as plt
import pandas as pd
# Local packages
from openfast_toolbox.fastfarm import fastFarmTurbSimExtent, writeFastFarm, plotFastFarmSetup
from openfast_toolbox.fastfarm.fastfarm import fastFarmTurbSimExtent, writeFastFarm, plotFastFarmSetup
from openfast_toolbox.io.fast_input_file import FASTInputFile

MyDir=os.path.dirname(__file__)
Expand Down
50 changes: 25 additions & 25 deletions openfast_toolbox/fastfarm/examples/Ex3_FFarmCompleteSetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,31 @@ def main():
# ----------- Template files
templatePath = '/full/path/where/template/files/are'

# Put None on any input that is not applicable to your case
# remove from dict or put None on any input that is not applicable to your case
# Files should be in templatePath
EDfilename = 'ElastoDyn.T'
SEDfilename = 'SimplifiedElastoDyn.T'
HDfilename = 'HydroDyn.dat'
SrvDfilename = 'ServoDyn.T'
ADfilename = 'AeroDyn.dat'
ADskfilename = 'AeroDisk.dat'
SubDfilename = 'SubDyn.dat'
IWfilename = 'InflowWind.dat'
BDfilepath = None
bladefilename = 'Blade.dat'
towerfilename = 'Tower.dat'
turbfilename = 'Model.T'
libdisconfilepath = '/full/path/to/controller/libdiscon.so'
controllerInputfilename = 'DISCON.IN'
coeffTablefilename = 'CpCtCq.csv'
FFfilename = 'Model_FFarm.fstf'

# TurbSim setups
turbsimLowfilepath = './SampleFiles/template_Low_InflowXX_SeedY.inp'
turbsimHighfilepath = './SampleFiles/template_HighT1_InflowXX_SeedY.inp'
templateFiles = {
"EDfilename" : 'ElastoDyn.T',
'SEDfilename' : 'SimplifiedElastoDyn.T',
'HDfilename' : 'HydroDyn.dat',
'SrvDfilename' : 'ServoDyn.T',
'ADfilename' : 'AeroDyn.dat',
'ADskfilename' : 'AeroDisk.dat',
'SubDfilename' : 'SubDyn.dat',
'IWfilename' : 'InflowWind.dat',
'BDfilepath' : None,
'bladefilename' : 'Blade.dat',
'towerfilename' : 'Tower.dat',
'turbfilename' : 'Model.T',
'coeffTablefilename' : 'CpCtCq.csv',
'FFfilename' : 'Model_FFarm.fstf',
'controllerInputfilename' : 'DISCON.IN',
'libdisconfilepath' : '/full/path/to/controller/libdiscon.so',
# MoorDyn Support
'mDynfilename': 'MoorDyn.dat',
# TurbSim setups
'turbsimLowfilepath' : './SampleFiles/template_Low_InflowXX_SeedY.inp',
'turbsimHighfilepath' : './SampleFiles/template_HighT1_InflowXX_SeedY.inp'
}

# SLURM scripts
slurm_TS_high = './SampleFiles/runAllHighBox.sh'
Expand All @@ -129,10 +132,7 @@ def main():
nSeeds=nSeeds, LESpath=LESpath, refTurb_rot=refTurb_rot,
verbose=1)

case.setTemplateFilename(templatePath, EDfilename, SEDfilename, HDfilename, SrvDfilename, ADfilename,
ADskfilename, SubDfilename, IWfilename, BDfilepath, bladefilename, towerfilename,
turbfilename, libdisconfilepath, controllerInputfilename, coeffTablefilename,
turbsimLowfilepath, turbsimHighfilepath, FFfilename)
case.setTemplateFilename(templatePath, templateFiles)

# Get domain paramters
case.getDomainParameters()
Expand Down
115 changes: 115 additions & 0 deletions openfast_toolbox/fastfarm/tests/test_moordyn_support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import os
import unittest
from pathlib import Path
from openfast_toolbox.fastfarm.FASTFarmCaseCreation import FFCaseCreation

class TestMoorDynSupport(unittest.TestCase):
def setUp(self):
"""
Setup the testing environment.
"""
# Create a temporary directory for the test
self.test_dir = Path('test_moordyn_support')
self.test_dir.mkdir(exist_ok=True)

# Define MoorDyn template
self.moordyn_template = self.test_dir / "MoorDyn_template.dat"
self.moordyn_template.write_text(
"""Node X Y Z M B
0.0 0.0 -20.0 0.0 0.0
100.0 0.0 -20.0 0.0 0.0
0.0 100.0 -20.0 0.0 0.0
"""
)
# Initialize FFCaseCreation with minimal parameters
self.case = FFCaseCreation(
path=str(self.test_dir),
wts={
0: {
'x': 0.0,
'y': 0.0,
'z': 0.0,
'D': 240, # Rotor diameter
'zhub': 150, # Hub height
'cmax': 5, # Maximum blade chord (m)
'fmax': 10 / 6, # Maximum excitation frequency (Hz)
'Cmeander': 1.9 # Meandering constant (-)
}
},
tmax=600,
zbot=1.0,
vhub=[10.0],
shear=[0.2],
TIvalue=[10],
inflow_deg=[30.0], # Rotate MoorDyn file by 30 degrees
dt_high_les=0.6,
ds_high_les=10.0,
extent_high=1.2,
dt_low_les=3.0,
ds_low_les=20.0,
extent_low=[3, 8, 3, 3, 2],
ffbin="/Users/ombahiwal/Desktop/WS24/Courses_WS24/Simulation Software Engineering/contri/openfast/glue-codes/fast-farm/FAST.Farm",
mod_wake=1,
yaw_init=None,
nSeeds=1,
LESpath=None,
refTurb_rot=0,
verbose=1,
)

# def tearDown(self):
# """
# Cleanup after tests.
# """
# for file in self.test_dir.glob("*"):
# file.unlink()
# self.test_dir.rmdir()

def test_moordyn_file_copy_and_rotation(self):
"""
Test the copying and rotation of the MoorDyn file.
"""
# TODO: Test moordyn support.
"""case = self.case
# Set the MoorDyn template
case.setTemplateFilename(str(self.test_dir), templateFiles={
"mDynfilename": self.moordyn_template.name,
"EDfilename": ""
})

# Simulate case generation
case.copyTurbineFilesForEachCase()

# Verify MoorDyn file is created
output_file = self.test_dir / "case_0_inflow30_Seed0" / "MoorDyn.dat"
self.assertTrue(output_file.exists(), "MoorDyn file was not created")

# Check the MoorDyn file content for rotation
with open(output_file, "r") as f_out:
rotated_lines = f_out.readlines()

# Expected rotated values (30 degrees rotation)
import numpy as np
rotation_matrix = np.array([
[np.cos(np.radians(30)), -np.sin(np.radians(30)), 0],
[np.sin(np.radians(30)), np.cos(np.radians(30)), 0],
[0, 0, 1],
])
expected_coordinates = [
[0.0, 0.0, -20.0],
[100.0, 0.0, -20.0],
[0.0, 100.0, -20.0],
]
rotated_coordinates = [np.dot(rotation_matrix, np.array(coord)) for coord in expected_coordinates]

# Validate each node's position
for i, expected_coord in enumerate(rotated_coordinates):
parts = rotated_lines[i + 1].split()
x, y, z = map(float, parts[1:4])
self.assertAlmostEqual(x, expected_coord[0], places=4, msg=f"Node {i} X mismatch")
self.assertAlmostEqual(y, expected_coord[1], places=4, msg=f"Node {i} Y mismatch")
self.assertAlmostEqual(z, expected_coord[2], places=4, msg=f"Node {i} Z mismatch")
"""

if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Node X Y Z M B
0.0 0.0 -20.0 0.0 0.0
100.0 0.0 -20.0 0.0 0.0
0.0 100.0 -20.0 0.0 0.0

2 changes: 1 addition & 1 deletion openfast_toolbox/fastfarm/tests/test_turbsimExtent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import numpy as np

from openfast_toolbox.fastfarm import *
from openfast_toolbox.fastfarm.fastfarm import *

MyDir=os.path.dirname(__file__)

Expand Down