Skip to content

Commit

Permalink
Enable heterogeneous inflow in FlorisStandin (#112)
Browse files Browse the repository at this point in the history
* Example code.

* Handling for heterogeneous inflows.

* Minor documentation updates.

* Add tests for heterogeneous inflow feature.

* Add exclusion for input data file to gitignore and add file to repo.

* Another needed input excluded in gitignore...
  • Loading branch information
misi9170 authored Sep 20, 2024
1 parent ec97c75 commit 69ed95c
Show file tree
Hide file tree
Showing 13 changed files with 681 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ hercules/local_amr_wind_demo/sample_copy.nc

#Ignore csv files
*.csv
!tests/test_inputs/amr_standin_data.csv
!tests/test_inputs/external_data.csv
!tests/test_inputs/*.csv
!example_case_folders/10_heterogeneous_wind/floris_standin_data.csv
!example_case_folders/10_heterogeneous_wind/wind_power_reference_data.csv

# Some output files to ignore
t_00*
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# README

# hercules
Hercules, based on the acronym "Hybrid Energy and Control Using Large Eddy Simulations", is an open-source tool for wind-based hybrid plant simulation in real time. Hercules is based around high fidelity wind farm flow simulations through AMR-Wind, co-simulated with a hybrid plant that includes solar, storage, and generation. The entire hybrid plant can be controlled using the Wind Hybrid Open Controller (WHOC).
Hercules, based on the acronym "Hybrid Energy and Control Using Large Eddy Simulations", is an open-source tool for wind-based hybrid plant simulation in real time. Hercules is based around high fidelity wind farm flow simulations through AMR-Wind, co-simulated with a hybrid plant that includes solar, storage, and generation. The entire hybrid plant can be controlled using the [Wind Hybrid Open Controller (WHOC)](https://github.com/nrel/wind-hybrid-open-controller).

# Documentation

Expand Down
163 changes: 163 additions & 0 deletions example_case_folders/10_heterogeneous_wind/amr_input.inp
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# SIMULATION STOP #
#.......................................#
time.stop_time = 100.0 # Max (simulated) time to evolve
time.max_step = -1 # Max number of time steps

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# TIME STEP COMPUTATION #
#.......................................#
time.fixed_dt = 0.5 # Use this constant dt if > 0
time.cfl = 0.95 # CFL factor

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# INPUT AND OUTPUT #
#.......................................#
time.plot_interval = 3600 # Steps between plot files
time.checkpoint_interval = 3600 # Steps between checkpoint files
io.restart_file = "/projects/ssc/amr_precursors/b_abl_neutral_lowTI_redo/chk14400"

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# PHYSICS #
#.......................................#
incflo.gravity = 0. 0. -9.81 # Gravitational force (3D)
incflo.density = 1.0 # Reference density

incflo.use_godunov = 1
incflo.godunov_type = weno_z
incflo.diffusion_type = 1
transport.viscosity = 1.0e-5
transport.laminar_prandtl = 0.7
transport.turbulent_prandtl = 0.3333
turbulence.model = OneEqKsgsM84

incflo.physics = ABL Actuator
ICNS.source_terms = BoussinesqBuoyancy CoriolisForcing ABLMeanBoussinesq ActuatorForcing
TKE.source_terms = KsgsM84Src
BoussinesqBuoyancy.reference_temperature = 300.0
CoriolisForcing.latitude = 41.3
ABLForcing.abl_forcing_height = 90
incflo.velocity = 6.928203230275509 4.0 0.0


# Atmospheric boundary layer
ABL.temperature_heights = 0.0 700.0 800.0 1280.0
ABL.temperature_values = 300.0 300.0 308.0 309.44
ABL.reference_temperature = 300.0
ABL.kappa = .40
ABL.surface_roughness_z0 = 1.0E-4
ABL.Uperiods = 25.0
ABL.Vperiods = 25.0
ABL.cutoff_height = 50.0
ABL.deltaU = 1.0
ABL.deltaV = 1.0
ABL.normal_direction = 2
ABL.perturb_ref_height = 50.0
ABL.perturb_temperature = false
ABL.perturb_velocity = true
ABL.stats_output_format = netcdf
ABL.stats_output_frequency = 1
ABL.surface_temp_flux = 0.00
ABL.wall_shear_stress_type = "Moeng"

ABL.bndry_file = "/projects/ssc/amr_precursors/b_abl_neutral_lowTI_redo/bndry_files"
ABL.bndry_io_mode = 1
ABL.bndry_planes = ylo xlo # I'm (Paul) adding this but not sure if I have to
ABL.bndry_var_names = velocity temperature tke


# Output boundary files
ABL.bndry_planes = ylo xlo
ABL.bndry_output_start_time = 7200.0
ABL.bndry_var_names = velocity temperature tke
ABL.bndry_output_format = native
ABL.stats_output_frequency = 1
ABL.stats_output_format = netcdf

# Whether to use helics
helics.activated = true
helics.broker_port = 32000

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# ADAPTIVE MESH REFINEMENT #
#.......................................#
amr.n_cell = 512 512 128 # Grid cells at coarsest AMRlevel
amr.max_level = 0 # Max AMR level in hierarchy

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# GEOMETRY #
#.......................................#
geometry.prob_lo = 0. 0. 0. # Lo corner coordinates
geometry.prob_hi = 5120. 5120. 1280. # Hi corner coordinates
geometry.is_periodic = 0 0 0
xlo.type = "mass_inflow"
xlo.density = 1.0
xlo.temperature = 0.0 # value required but ignored
xlo.tke = 0.0
xhi.type = "pressure_outflow"

ylo.type = "mass_inflow"
ylo.density = 1.0
ylo.temperature = 0.0
ylo.tke = 0.0
yhi.type = "pressure_outflow"

# Boundary conditions
zlo.type = "wall_model"
zlo.tke_type = "zero_gradient"

zhi.type = "slip_wall"
zhi.temperature_type = "fixed_gradient"
zhi.temperature = 0.003 # tracer is used to specify potential temperature gradient

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# VERBOSITY #
#.......................................#
incflo.verbose = 0 # incflo_level



#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# SAMPLING #
#.......................................#
incflo.post_processing = samplingPlane samplingLine

samplingPlane.output_frequency = 600
samplingPlane.labels = z_plane
samplingPlane.fields = velocity temperature
samplingPlane.z_plane.type = PlaneSampler
samplingPlane.z_plane.axis1 = 5110 0.0 0.0
samplingPlane.z_plane.axis2 = 0.0 5110 0.0
samplingPlane.z_plane.origin = 5.0 5.0 0.0
samplingPlane.z_plane.num_points = 512 512
samplingPlane.z_plane.normal = 0.0 0.0 1.0
samplingPlane.z_plane.offsets = 5.0 85.0 155.0 255.0


samplingLine.output_frequency = 1
samplingLine.labels = z_line
samplingLine.fields = velocity temperature
samplingLine.z_line.type = LineSampler
samplingLine.z_line.num_points = 128
samplingLine.z_line.start = 5.0 5.0 5.0
samplingLine.z_line.end = 5.0 5.0 1275.0

#¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨#
# TURBINES #
#.......................................#

Actuator.type = UniformCtDisk
Actuator.UniformCtDisk.rotor_diameter = 126.0
Actuator.UniformCtDisk.hub_height = 90.0
Actuator.UniformCtDisk.thrust_coeff = 0.0 0.0 1.132034888 0.999470963 0.917697381 0.860849503 0.815371198 0.811614904 0.807939328 0.80443352 0.800993851 0.79768116 0.794529244 0.791495834 0.788560434 0.787217182 0.787127977 0.785839257 0.783812219 0.783568108 0.783328285 0.781194418 0.777292539 0.773464375 0.769690236 0.766001924 0.762348072 0.758760824 0.755242872 0.751792927 0.748434131 0.745113997 0.717806682 0.672204789 0.63831272 0.610176496 0.585456847 0.563222111 0.542912273 0.399312061 0.310517829 0.248633226 0.203543725 0.169616419 0.143478955 0.122938861 0.106515296 0.093026095 0.081648606 0.072197368 0.064388275 0.057782745 0.0 0.0
Actuator.UniformCtDisk.wind_speed = 0.0 2.9 3.0 4.0 5.0 6.0 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 8.0 9.0 10.0 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 11.0 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 12.0 13.0 14.0 15.0 16.0 17.0 18.0 19.0 20.0 21.0 22.0 23.0 24.0 25.0 25.1 50.0
Actuator.UniformCtDisk.epsilon = 10.0
Actuator.UniformCtDisk.density = 1.225
Actuator.UniformCtDisk.diameters_to_sample = 1.0
Actuator.UniformCtDisk.num_points_r = 20
Actuator.UniformCtDisk.num_points_t = 5


Actuator.labels = T00 T01
Actuator.T00.base_position = 0.0 0.0 0.0
Actuator.T01.base_position = 1000.0 0.0 0.0
23 changes: 23 additions & 0 deletions example_case_folders/10_heterogeneous_wind/bash_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Example bash for running things locally
# I just run these one at a t time

# A lot of modules and conda stuff
conda activate hercules

# Set the helics port to use:
export HELICS_PORT=32000

#make sure you use the same port number in the amr_input.inp and hercules_input_000.yaml files.

# Remove any existing outputs/ folder
if [ -d "outputs" ]; then
rm -f outputs/*.log
fi

# Create the outputs/ folder
mkdir -p outputs

# Wait for the open-loop control simulation to finish and then run the closed-loop simulation
helics_broker -t zmq -f 2 --loglevel="debug" --local_port=$HELICS_PORT &
python3 hercules_runscript_CLcontrol.py hercules_input_000.yaml >> outputs/hercules.log 2>&1 &
python3 floris_runscript.py amr_input.inp floris_standin_data.csv >> outputs/floris.log 2>&1
19 changes: 19 additions & 0 deletions example_case_folders/10_heterogeneous_wind/floris_runscript.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import sys

from hercules.floris_standin import launch_floris

# Check that one command line argument was given
if len(sys.argv) < 2:
raise Exception("Usage: python floris_runscript.py <amr_input_file>")

# # Get the first command line argument
# This is the name of the file to read
amr_input_file = sys.argv[1]
print(f"Running FLORIS standin with input file: {amr_input_file}")
if len(sys.argv) > 2:
amr_standin_data_file = sys.argv[2]
print(f"Using standin data for AMR-Wind from file: {amr_standin_data_file}")
else:
amr_standin_data_file = None

launch_floris(amr_input_file, amr_standin_data_file)
Loading

0 comments on commit 69ed95c

Please sign in to comment.