m_adm Module

Actuator Disc Model (ADM) turbine forcing (iturbine = 2).

Each turbine is a disc that applies a thrust force computed from a thrust coefficient and the disc-averaged inflow velocity. The force is regularised and projected onto the Eulerian grid with a per-disc kernel , built once at init and normalised to sum to one. This operation is also commonly called force spreading or smearing.

The kernels of all discs share two fields, so device memory does not grow with the number of discs: gamma holds the kernel values and disc_id labels each grid point with the disc whose kernel is largest there (zero where every kernel vanishes). Kernels of separate discs must therefore not overlap; init stops if a significant part of any kernel lies where another disc's kernel is larger. The disc-averaged velocities of all discs come from one labelled weighted sum and one MPI reduction, and the projected forces of all discs are added to the momentum RHS in one labelled axpy.

For yaw angle and tilt angle , the rotor-normal vector used by the model is For a grid point and disc centre , the normal and radial distances are The unnormalised anisotropic regularisation kernel is Gaussian in the disc-normal direction and eighth-order super-Gaussian in the radial direction: where The discrete kernel is normalised globally over all MPI ranks: Consequently, the instantaneous disc-normal velocity is the weighted global average an optional first-order low-pass filter is applied: On the first update, or when , . The local thrust coefficient, thrust, and power are Finally, the acceleration added to the momentum right-hand side at grid point is


Uses

  • module~~m_adm~~UsesGraph module~m_adm m_adm m_mpi m_mpi module~m_adm->m_mpi module~m_allocator m_allocator module~m_adm->module~m_allocator module~m_base_backend m_base_backend module~m_adm->module~m_base_backend module~m_common m_common module~m_adm->module~m_common module~m_field m_field module~m_adm->module~m_field module~m_io_session m_io_session module~m_adm->module~m_io_session module~m_logger m_logger module~m_adm->module~m_logger module~m_mesh m_mesh module~m_adm->module~m_mesh module~m_scalar_series m_scalar_series module~m_adm->module~m_scalar_series module~m_turbine_model m_turbine_model module~m_adm->module~m_turbine_model module~m_allocator->module~m_common module~m_allocator->module~m_field module~m_base_backend->module~m_allocator module~m_base_backend->module~m_common module~m_base_backend->module~m_field module~m_base_backend->module~m_logger module~m_base_backend->module~m_mesh iso_c_binding iso_c_binding module~m_base_backend->iso_c_binding module~m_poisson_fft m_poisson_fft module~m_base_backend->module~m_poisson_fft module~m_tdsops m_tdsops module~m_base_backend->module~m_tdsops module~m_common->m_mpi module~m_common->module~m_logger module~m_field->module~m_common module~m_field->iso_c_binding module~m_io_session->module~m_base_backend module~m_io_session->module~m_common module~m_io_session->module~m_field module~m_io_session->module~m_logger module~m_io_backend~2 m_io_backend module~m_io_session->module~m_io_backend~2 module~m_io_base m_io_base module~m_io_session->module~m_io_base module~m_logger->m_mpi iso_fortran_env iso_fortran_env module~m_logger->iso_fortran_env module~m_mesh->m_mpi module~m_mesh->module~m_common module~m_mesh->module~m_field module~m_mesh->module~m_logger module~m_mesh_content m_mesh_content module~m_mesh->module~m_mesh_content module~m_scalar_series->module~m_common module~m_scalar_series->module~m_logger module~m_turbine_model->module~m_allocator module~m_turbine_model->module~m_base_backend module~m_turbine_model->module~m_common module~m_turbine_model->module~m_field module~m_turbine_model->module~m_mesh module~m_checkpoint_state m_checkpoint_state module~m_turbine_model->module~m_checkpoint_state module~m_checkpoint_state->module~m_io_session module~m_io_backend~2->module~m_base_backend module~m_io_backend~2->module~m_common module~m_io_backend~2->module~m_field module~m_io_backend~2->module~m_logger module~m_io_backend~2->module~m_io_base module~m_io_base->module~m_base_backend module~m_io_base->module~m_common module~m_io_base->module~m_field module~m_mesh_content->module~m_common module~m_mesh_content->module~m_logger module~m_poisson_fft->module~m_common module~m_poisson_fft->module~m_field module~m_poisson_fft->module~m_logger module~m_poisson_fft->module~m_mesh module~m_poisson_fft->module~m_tdsops module~m_tdsops->module~m_common module~m_tdsops->module~m_logger

Used by

  • module~~m_adm~~UsedByGraph module~m_adm m_adm module~m_case_wind_turbine m_case_wind_turbine module~m_case_wind_turbine->module~m_adm program~xcompact xcompact program~xcompact->module~m_case_wind_turbine

Derived Types

type, public ::  actuator_disc_t

Components

Type Visibility Attributes Name Initial
real(kind=dp), public :: coords(3)

disc centre

real(kind=dp), public :: yaw

rotor yaw/tilt angles [rad]

real(kind=dp), public :: tilt

rotor yaw/tilt angles [rad]

real(kind=dp), public :: D

diameter and swept area

real(kind=dp), public :: area

diameter and swept area

real(kind=dp), public :: thick

kernel thickness h along rot_N

real(kind=dp), public :: C_T

thrust and induction coefficients

real(kind=dp), public :: alpha

thrust and induction coefficients

real(kind=dp), public :: rot_N(3)

unit rotor-axis vector

real(kind=dp), public :: U_disc = 0._dp

instantaneous disc-averaged speed

real(kind=dp), public :: U_disc_filt = 0._dp

filtered disc-averaged speed

real(kind=dp), public :: thrust = 0._dp

instantaneous thrust

real(kind=dp), public :: power = 0._dp

instantaneous power

real(kind=dp), public :: U_disc_mean = 0._dp
real(kind=dp), public :: thrust_mean = 0._dp
real(kind=dp), public :: power_mean = 0._dp

type, public, extends(turbine_model_t) ::  adm_t

Components

Type Visibility Attributes Name Initial
integer, public :: n_turb = 0
real(kind=dp), public :: rho_air = 1._dp
real(kind=dp), public :: T_relax = -1._dp
real(kind=dp), public :: cell_vol
real(kind=dp), public :: dt
real(kind=dp), public :: last_update_time = -huge(1._dp)
integer, public :: current_iter = 0
integer, public :: stats_start = 1
integer, public :: stats_freq = 1
integer, public :: sample_count = 0
logical, public :: filter_initialized = .false.
logical, public :: recompute_forces = .true.
character(len=256), public :: coords_file = ''
type(actuator_disc_t), public, allocatable :: disc(:)
class(field_t), public, pointer :: gamma => null()

smearing kernels (DIR_X)

class(field_t), public, pointer :: disc_id => null()

disc label (DIR_X)

type(scalar_series_t), public, allocatable :: output(:)
class(base_backend_t), public, pointer :: backend => null()
type(mesh_t), public, pointer :: mesh => null()
type(allocator_t), public, pointer :: host_allocator => null()

Type-Bound Procedures

procedure, public :: init => init_adm
procedure, public :: update => update_adm
procedure, public :: project_forces => project_forces_adm
procedure, public :: write_output => write_output_adm
procedure, public :: setup_output => setup_output_adm
procedure, public :: write_checkpoint => write_checkpoint_adm
procedure, public :: read_checkpoint => read_checkpoint_adm
procedure, public :: finalise => finalise_adm

Functions

public pure function disc_kernel(disc, coords) result(gamma_val)

Unnormalised smearing kernel of disc at coords: Gaussian in the rotor-normal direction (delta_N), super-Gaussian (^8) in the radial direction (delta_R) to give a flat-topped disc.

Arguments

Type IntentOptional Attributes Name
type(actuator_disc_t), intent(in) :: disc
real(kind=dp), intent(in) :: coords(3)

Return Value real(kind=dp)


Subroutines

public subroutine init_adm(self, backend, mesh, host_allocator, dt)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
class(base_backend_t), intent(in), target :: backend
type(mesh_t), intent(in), target :: mesh
type(allocator_t), intent(in), target :: host_allocator
real(kind=dp), intent(in) :: dt

public subroutine update_adm(self, t, dt)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
real(kind=dp), intent(in) :: t
real(kind=dp), intent(in) :: dt

public subroutine project_forces_adm(self, du, dv, dw, u, v, w)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
class(field_t), intent(inout) :: du
class(field_t), intent(inout) :: dv
class(field_t), intent(inout) :: dw
class(field_t), intent(in) :: u
class(field_t), intent(in) :: v
class(field_t), intent(in) :: w

public subroutine write_output_adm(self, iter, is_root)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
integer, intent(in) :: iter
logical, intent(in) :: is_root

public subroutine setup_output_adm(self, is_root, append)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
logical, intent(in) :: is_root
logical, intent(in) :: append

public subroutine write_checkpoint_adm(self, writer)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
type(writer_session_t), intent(inout) :: writer

public subroutine read_checkpoint_adm(self, reader)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self
type(reader_session_t), intent(inout) :: reader

public subroutine finalise_adm(self)

Arguments

Type IntentOptional Attributes Name
class(adm_t), intent(inout) :: self

public subroutine read_ad_file(filename, disc_params)

Read turbine disc parameters from a .ad file. Format: one header line followed by one row per disc of CoR(x) CoR(y) CoR(z) Yaw[deg] Tilt[deg] RotorDiam C_T alpha

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: filename
real(kind=dp), intent(out), allocatable :: disc_params(:,:)