Skip to content

Commit 567b064

Browse files
authored
modifications to kynema interface and setup + docs (#1803)
* modifications to kynema interface and setup * incorporate generator efficiency * relax kynema convergence criteria * more consistent name for hub wind vector initialization * documenting kynema inputs * docs issues * full parameter name in reference
1 parent c85a91c commit 567b064

File tree

5 files changed

+215
-14
lines changed

5 files changed

+215
-14
lines changed

amr-wind/wind_energy/actuator/turbine/kynema/KynemaIface.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ void build_turbine(
2121
const int n_blade_nodes,
2222
const int n_tower_nodes,
2323
const double rotor_speed_init,
24-
const double yaw_init)
24+
const double generator_power_init,
25+
const double wind_speed_init,
26+
const double yaw_init,
27+
const double generator_efficiency)
2528
{
2629
// WindIO components
2730
const auto& wio_blade = wio["components"]["blade"];
@@ -50,7 +53,10 @@ void build_turbine(
5053
wio_drivetrain["outer_shape"]["distance_tt_hub"].as<double>())
5154
.SetGearBoxRatio(wio_drivetrain["gearbox"]["gear_ratio"].as<double>())
5255
.SetRotorSpeed(rotor_speed_init)
53-
.SetNacelleYawAngle(yaw_init);
56+
.SetGeneratorPower(generator_power_init)
57+
.SetHubWindSpeed(wind_speed_init)
58+
.SetNacelleYawAngle(yaw_init)
59+
.SetGeneratorEfficiency(generator_efficiency);
5460

5561
//--------------------------------------------------------------------------
5662
// Build Blades
@@ -169,10 +175,7 @@ void build_turbine(
169175
tower_builder
170176
.SetElementOrder(
171177
n_tower_nodes - 1) // Set element order to num nodes - 1
172-
.SetQuadratureStyle(
173-
kynema::interfaces::components::BeamInput::QuadratureStyle::
174-
Segmented)
175-
.SetSectionRefinement(4)
178+
.SetSectionRefinement(2)
176179
.PrescribedRootMotion(false); // Fix displacement of tower base node
177180

178181
// Add reference axis coordinates (WindIO uses Z-axis as reference axis)
@@ -388,14 +391,14 @@ void update_turbine(::ext_turb::KynemaTurbine& fi, bool advance)
388391
}
389392
if (advance) {
390393
// individual turbine step, do not output every step
391-
if (fi.controller_input_file.size() > 0) {
392-
const double t = fi.time_index * fi.dt_ext;
393-
fi.interface->ApplyController(t);
394-
}
395394
bool converged = fi.interface->Step();
396395
if (!converged) {
397396
amrex::Abort("Kynema did not converge\n");
398397
}
398+
if (fi.controller_input_file.size() > 0) {
399+
const double t = fi.time_index * fi.dt_ext;
400+
fi.interface->ApplyController(t);
401+
}
399402
}
400403

401404
if (fi.substep_counter == fi.num_substeps) {
@@ -657,7 +660,8 @@ void ExtTurbIface<KynemaTurbine, KynemaSolverData>::ext_init_turbine(
657660
// Builds turbine, including blades, nacelle, and tower
658661
exw_kynema::build_turbine(
659662
builder, wio, fi.num_blades, fi.num_blade_elem, num_pts_tower_struct,
660-
fi.rotational_speed, fi.yaw);
663+
fi.rotational_speed, fi.generator_power, fi.wind_speed, fi.yaw,
664+
fi.generator_efficiency);
661665

662666
auto n_aero_sections = exw_kynema::build_aero(builder, wio);
663667

amr-wind/wind_energy/actuator/turbine/kynema/kynema_types.H

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,10 @@ struct KynemaTurbine : public ext_turb::ExternalTurbine
243243

244244
double fluid_density{1.};
245245
double rotational_speed{0.};
246+
double generator_power{0.};
247+
double wind_speed{0.};
246248
double yaw{0.};
249+
double generator_efficiency{1.};
247250
int substep_counter{0};
248251

249252
std::string controller_shared_lib_path{""};
@@ -271,8 +274,8 @@ struct KynemaSolverData
271274

272275
double damping_factor{0.};
273276
int nl_iter_max{12};
274-
double abs_err_tol{1e-7};
275-
double rel_err_tol{1e-6};
277+
double abs_err_tol{1e-5};
278+
double rel_err_tol{1e-4};
276279
amrex::Vector<amrex::Real> gravity{0.0, 0.0, -9.81};
277280
};
278281

amr-wind/wind_energy/actuator/turbine/kynema/turbine_kynema_ops.H

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,22 @@ struct ReadInputsOp<TurbineKynema, SrcTrait>
8181
pp.query("rot_speed_rpm", tf.rotational_speed);
8282
tf.rotational_speed *= 2.0 * M_PI / 60.;
8383
}
84+
// Initial generator speed
85+
pp.query("generator_power_init", tf.generator_power);
86+
// Initial wind speed
87+
amrex::Vector<amrex::Real> vel_vec{tf.wind_speed, 0., 0.};
88+
pp.queryarr("hub_wind_vector_init", vel_vec);
89+
tf.wind_speed = std::sqrt(
90+
vel_vec[0] * vel_vec[0] + vel_vec[1] * vel_vec[1] +
91+
vel_vec[2] * vel_vec[2]);
8492
// Initial or constant nacelle yaw
8593
pp.query("yaw_rad", tf.yaw);
8694
if (!pp.contains("yaw_rad")) {
8795
pp.query("yaw_deg", tf.yaw);
8896
tf.yaw *= M_PI / 180.;
8997
}
98+
// Generator efficiency
99+
pp.query("generator_efficiency", tf.generator_efficiency);
90100
}
91101
};
92102

docs/sphinx/spelling-wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Fortran
1212
Joukowsky
1313
Jupyter
1414
Karman
15+
Kynema
1516
Liungman
1617
MPI
1718
Menter

docs/sphinx/user/inputs_Actuator.rst

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ turbines as actuator disks and actuator line models.
2525
**type:** String, mandatory
2626

2727
This string identifies the type of actuator to use. The ones currently
28-
supported are: ``UniformCtDisk``, ``JoukowskyDisk``, ``TurbineFastLine``, ``TurbineFastDisk``, and
28+
supported are: ``UniformCtDisk``, ``JoukowskyDisk``, ``TurbineFastLine``,
29+
``TurbineFastDisk``, ``TurbineKynemaLine``, and
2930
``FixedWingLine``.
3031

3132
It is recommended to group common parameters across actuators using the ``Actuator.[type].[param]``. For example::
@@ -395,6 +396,188 @@ Example for ``TurbineFastLine``::
395396

396397
This is the name of the openfast input file with all the turbine information.
397398

399+
TurbineKynemaLine
400+
"""""""""""""""""
401+
402+
This actuator type requires an AMR-Wind build with Kynema coupling
403+
enabled. This is a similar coupling to OpenFAST, but Kynema
404+
acts as the turbine solver in this instance. Some turbine quantities
405+
that the OpenFAST interface needs from the AMR-Wind input file
406+
are instead found directly by the code within the Kynema input file,
407+
whereas other quantities that OpenFAST has stored within its inputs
408+
need to be directly supplied through the AMR-Wind input file for Kynema,
409+
especially for initialization.
410+
411+
Example for ``TurbineKynemaLine``::
412+
413+
incflo.physics = FreeStream Actuator
414+
Actuator.labels = WTG01
415+
Actuator.type = TurbineKynemaLine
416+
## Turbine discretization parameters
417+
Actuator.TurbineKynemaLine.num_struct_nodes_blade = 6
418+
Actuator.TurbineKynemaLine.num_points_blade = 64
419+
Actuator.TurbineKynemaLine.num_points_tower = 0 # not enabled yet
420+
## Turbine setup
421+
Actuator.TurbineKynemaLine.rot_speed_rpm = 12.1
422+
Actuator.TurbineKynemaLine.yaw_deg = 30
423+
Actuator.WTG01.kynema_input_file = NREL-15MW-aero.yaml
424+
Actuator.WTG01.base_position = 5.0191 0. -89.56256
425+
## Turbine - flow coupling parameters
426+
Actuator.TurbineKynemaLine.epsilon = 10.0 10.0 10.0
427+
Actuator.TurbineKynemaLine.epsilon_chord = 0.25 0.25 0.25
428+
Actuator.TurbineKynemaLine.fllc = 0
429+
Actuator.TurbineKynemaLine.nacelle_drag_coeff = 0.0
430+
Actuator.TurbineKynemaLine.nacelle_area = 0.0
431+
Actuator.TurbineKynemaLine.density = 1.225
432+
## Turbine controller parameters and initial state
433+
Actuator.TurbineKynemaLine.controller_shared_library_path = /path/to/libdiscon.so # or libdiscon.dylib
434+
Actuator.TurbineKynemaLine.generator_power_init = 5e6
435+
Actuator.TurbineKynemaLine.hub_wind_vector_init = 9.8726896031426 5.7 0.0
436+
Actuator.TurbineKynemaLine.generator_efficiency = 0.944
437+
## Turbine solver numerical parameters
438+
Actuator.TurbineKynemaLine.dt = 0.01
439+
Kynema.abs_err_tol = 1e-6
440+
441+
Actuator.TurbineKynemaLine.output_frequency = 10
442+
443+
ICNS.source_terms = ActuatorForcing
444+
445+
.. input_param:: Actuator.TurbineKynemaLine.num_struct_nodes_blade
446+
447+
**type:** Int, required
448+
449+
This is the number of structural nodes for Kynema to use when modeling each turbine blade.
450+
451+
.. input_param:: Actuator.TurbineKynemaLine.num_points_blade
452+
453+
**type:** Int, required
454+
455+
This is the number of aerodynamic sections for Kynema to use when modeling each turbine blade.
456+
This will correspond to the number of force points and velocity points on each blade in AMR-Wind.
457+
This must be the same number as provided in the Kynema input file.
458+
459+
.. input_param:: Actuator.TurbineKynemaLine.num_points_tower
460+
461+
**type:** Int, required
462+
463+
This is the number of aerodynamic sections for Kynema to use when modeling the tower.
464+
This feature is still under development, so this argument must be set to 0.
465+
466+
.. input_param:: Actuator.TurbineKynemaLine.rot_speed_rpm
467+
468+
**type:** Real, optional, default = 0
469+
470+
This is the initial rotational speed of the turbine in RPM. This parameter can
471+
alternatively be set in radians per second using the input parameter
472+
:input_param:`Actuator.TurbineKynemaLine.rot_speed_radps`.
473+
474+
.. input_param:: Actuator.TurbineKynemaLine.rot_speed_radps
475+
476+
**type:** Real, optional, default = 0
477+
478+
This is the initial rotational speed of the turbine in radians per second.
479+
If this argument is present,
480+
:input_param:`Actuator.TurbineKynemaLine.rot_speed_rpm` will be ignored.
481+
482+
.. input_param:: Actuator.TurbineKynemaLine.yaw_deg
483+
484+
**type:** Real, optional, default = 0
485+
486+
This is the initial yaw angle of the turbine in degrees, counterclockwise
487+
from the -x direction. This parameter can alternatively be set in radians
488+
using the input parameter :input_param:`Actuator.TurbineKynemaLine.yaw_rad`.
489+
490+
.. input_param:: Actuator.TurbineKynemaLine.yaw_rad
491+
492+
**type:** Real, optional, default = 0
493+
494+
This is the initial yaw angle of the turbine in radians. If this argument is
495+
present, :input_param:`Actuator.TurbineKynemaLine.yaw_deg` will be ignored.
496+
497+
.. input_param:: Actuator.TurbineKynemaLine.kynema_input_file
498+
499+
**type:** String, required
500+
501+
This is the input file used to initialize the Kynema turbine model. It
502+
conforms to the WindIO format. A pre-processing tool is provided in the
503+
Kynema repository to change the number of aerodynamic sections per blade,
504+
if needed, as well as to address some format edge cases.
505+
506+
.. input_param:: Actuator.TurbineKynemaLine.controller_shared_library_path
507+
508+
**type:** String, optional, default = empty
509+
510+
This is the path to the controller shared library (typically ROSCO).
511+
If this parameter is not provided, no controller will be created in
512+
the turbine model, and the controller-related input parameters will not be used.
513+
514+
.. input_param:: Actuator.TurbineKynemaLine.generator_power_init
515+
516+
**type:** Real, optional, default = 0
517+
518+
Power of the generator at the start of the simulation.
519+
520+
.. input_param:: Actuator.TurbineKynemaLine.hub_wind_vector_init
521+
522+
**type:** Vector<Real>, optional, default = 0 0 0
523+
524+
This is the initial wind vector that the turbine hub is exposed to.
525+
It does not have to be the actual wind there at initialization; this
526+
number is converted to a wind speed that is used as the controller's
527+
initial guess.
528+
529+
.. input_param:: Actuator.TurbineKynemaLine.generator_efficiency
530+
531+
**type:** Real, optional, default = 1
532+
533+
This is the efficiency of the generator. If not populated,
534+
the efficiency is assumed to be 1, i.e., 100%.
535+
536+
.. input_param:: Actuator.TurbineKynemaLine.dt
537+
538+
**type:** Real, optional, default = same as AMR-Wind dt
539+
540+
This is the time step size chosen for the Kynema turbine model. It must
541+
be a factor of the AMR-Wind time step so that Kynema can take an integer
542+
number of sub-steps for each AMR-Wind time step. If not populated, the Kynema time
543+
step size will be the same as the flow solver time step, and, due to the
544+
robustness of Kynema, this is typically fine.
545+
546+
.. input_param:: Actuator.TurbineKynemaLine.output_frequency
547+
548+
**type:** Int, optional, default = 10
549+
550+
This is how often, in time steps, to output actuator data from AMR-Wind.
551+
Note, this does not govern how often Kynema outputs turbine data. Kynema
552+
automatically outputs data every AMR-Wind time step.
553+
554+
.. input_param:: Kynema.abs_err_tol
555+
556+
**type:** Real, optional, default = 1e-5
557+
558+
This turbine solver parameter is not turbine-specific; rather, it informs the
559+
solution parameters of Kynema overall. This, in particular, sets the absolute
560+
tolerance of the Kynema solver.
561+
562+
.. input_param:: Kynema.rel_err_tol
563+
564+
**type:** Real, optional, default = 1e-4
565+
566+
This parameter sets the relative tolerance of the Kynema solver.
567+
568+
.. input_param:: Kynema.max_nonlinear_iterations
569+
570+
**type:** Int, optional, default = 12
571+
572+
This parameter sets the maximum number of nonlinear iterations for the Kynema solver.
573+
574+
.. input_param:: Kynema.damping_factor
575+
576+
**type:** Real, optional, default = 0
577+
578+
This parameter sets the numerical damping (time-based) of the Kynema solver.
579+
Counterintuitively, full damping corresponds to 0 and no damping corresponds to 1.
580+
398581
Active Wake Control with Joukowsky Disk
399582
"""""""""""""""""""""""""""""""""""""""
400583

0 commit comments

Comments
 (0)