subroutine bind_f90_domain_copy_constructor( &
    out_self, &
    other)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), pointer :: out_self
  type(domain), intent(in) :: other

  nullify(out_self)
  allocate(out_self)
  out_self = other
end subroutine bind_f90_domain_copy_constructor

subroutine bind_f90_domain_type_new( &
    out_self, &
    abc, &
    acell, &
    angrad, &
    bc, &
    detgd, &
    gd, &
    gu, &
    orthorhombic, &
    uabc, &
    units)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), pointer :: out_self
  real(kind = gp), intent(in) :: detgd
  logical, intent(in) :: orthorhombic
  integer, intent(in) :: units
  real(kind = gp), dimension(3), intent(in) :: acell
  real(kind = gp), dimension(3), intent(in) :: angrad
  integer, dimension(3), intent(in) :: bc
  real(kind = gp), dimension(3, &
 3), intent(in) :: abc
  real(kind = gp), dimension(3, &
 3), intent(in) :: gd
  real(kind = gp), dimension(3, &
 3), intent(in) :: gu
  real(kind = gp), dimension(3, &
 3), intent(in) :: uabc

  nullify(out_self)
  allocate(out_self)
  out_self%abc = abc
  out_self%acell = acell
  out_self%angrad = angrad
  out_self%bc = bc
  out_self%detgd = detgd
  out_self%gd = gd
  out_self%gu = gu
  out_self%orthorhombic = orthorhombic
  out_self%uabc = uabc
  out_self%units = units
end subroutine bind_f90_domain_type_new

subroutine bind_f90_domain_free( &
    self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), pointer :: self

  deallocate(self)
  nullify(self)
end subroutine bind_f90_domain_free

subroutine bind_domain_null( &
    out_dom)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), pointer :: out_dom

  nullify(out_dom)
  allocate(out_dom)
  out_dom = domain_null( &
)
end subroutine bind_domain_null

subroutine bind_domain_new( &
    out_dom, &
    units, &
    bc_0, &
    bc_1, &
    bc_2, &
    abc, &
    alpha_bc, &
    beta_ac, &
    gamma_ab, &
    acell)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions, gp=>f_double
  use f_utils
  use f_enums
  use dictionaries
  use at_domain
  implicit none
  type(domain), pointer :: out_dom
  type(f_enumerator), intent(in) :: units
  type(f_enumerator), intent(in) :: bc_0
  type(f_enumerator), intent(in) :: bc_1
  type(f_enumerator), intent(in) :: bc_2
  real(kind = gp), optional, intent(in) :: alpha_bc
  real(kind = gp), optional, intent(in) :: beta_ac
  real(kind = gp), optional, intent(in) :: gamma_ab
  real(kind = gp), dimension(3), optional, intent(in) :: acell
  real(kind = gp), dimension(3, &
 3), optional, intent(in) :: abc
  type(f_enumerator), dimension(3) :: bc

  bc(1) = bc_0
  bc(2) = bc_1
  bc(3) = bc_2
  nullify(out_dom)
  allocate(out_dom)
  out_dom = domain_new( &
    units, &
    bc, &
    abc, &
    alpha_bc, &
    beta_ac, &
    gamma_ab, &
    acell)
end subroutine bind_domain_new

subroutine bind_change_domain_bc( &
    out_dom, &
    dom_in, &
    geocode)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions
  use f_enums
  use dictionaries
  use at_domain
  implicit none
  type(domain), pointer :: out_dom
  type(domain), intent(in) :: dom_in
  character, intent(in) :: geocode

  nullify(out_dom)
  allocate(out_dom)
  out_dom = change_domain_bc( &
    dom_in, &
    geocode)
end subroutine bind_change_domain_bc

subroutine bind_units_enum_from_str( &
    out_units, &
    str, &
    str_len)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions
  use f_enums
  use dictionaries
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_units
  integer(kind = f_long), intent(in) :: str_len
  character(len = str_len), intent(in) :: str

  nullify(out_units)
  allocate(out_units)
  out_units = units_enum_from_str( &
    str)
end subroutine bind_units_enum_from_str

subroutine bind_geocode_to_bc( &
    out_bc, &
    geocode)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions
  use f_enums
  use dictionaries, only: f_err_throw
  use at_domain
  implicit none
  integer, dimension(3), intent(out) :: out_bc
  character, intent(in) :: geocode

  out_bc = geocode_to_bc( &
    geocode)
end subroutine bind_geocode_to_bc

subroutine bind_domain_geocode( &
    out_dom_geocode, &
    dom)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), intent(in) :: dom
  character :: out_dom_geocode

  out_dom_geocode = domain_geocode( &
    dom)
end subroutine bind_domain_geocode

subroutine bind_domain_volume( &
    out_cell_volume, &
    acell, &
    dom)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions, gp=>f_double
  use f_enums
  use wrapper_linalg, only: det_3x3
  use dictionaries
  use at_domain
  implicit none
  real(kind = gp) :: out_cell_volume
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: acell

  out_cell_volume = domain_volume( &
    acell, &
    dom)
end subroutine bind_domain_volume

subroutine bind_rxyz_ortho( &
    dom, &
    out_rxyz_ortho, &
    rxyz)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(out) :: out_rxyz_ortho
  real(kind = gp), dimension(3), intent(in) :: rxyz

  out_rxyz_ortho = rxyz_ortho( &
    dom, &
    rxyz)
end subroutine bind_rxyz_ortho

subroutine bind_distance( &
    out_d, &
    dom, &
    r, &
    c)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_strings
  use f_precisions, gp=>f_double
  use f_enums
  use dictionaries, only: f_err_throw
  use at_domain
  implicit none
  real(kind = gp) :: out_d
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: r
  real(kind = gp), dimension(3), intent(in) :: c

  out_d = distance( &
    dom, &
    r, &
    c)
end subroutine bind_distance

subroutine bind_closest_r( &
    dom, &
    out_r, &
    v, &
    center)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(out) :: out_r
  real(kind = gp), dimension(3), intent(in) :: v
  real(kind = gp), dimension(3), intent(in) :: center

  out_r = closest_r( &
    dom, &
    v, &
    center)
end subroutine bind_closest_r

subroutine bind_domain_set_from_dict( &
    dict, &
    dom)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use yaml_output
  use yaml_strings
  use f_precisions, gp=>f_double
  use f_utils
  use f_enums
  use dictionaries
  use at_domain
  implicit none
  type(dictionary), pointer :: dict
  type(domain), intent(out) :: dom

  call domain_set_from_dict( &
    dict, &
    dom)
end subroutine bind_domain_set_from_dict

subroutine bind_domain_merge_to_dict( &
    dict, &
    dom)
  use numerics, only: bohr_ang
  use yaml_strings
  use f_precisions, gp=>f_double
  use f_enums
  use dictionaries
  use at_domain
  implicit none
  type(dictionary), pointer :: dict
  type(domain), intent(in) :: dom

  call domain_merge_to_dict( &
    dict, &
    dom)
end subroutine bind_domain_merge_to_dict

subroutine bind_dotp_gu( &
    out_dotp_gu, &
    dom, &
    v1, &
    v2)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp_gu
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: v1
  real(kind = gp), dimension(3), intent(in) :: v2

  out_dotp_gu = dotp_gu( &
    dom, &
    v1, &
    v2)
end subroutine bind_dotp_gu

subroutine bind_dotp_gu_add2( &
    out_dotp, &
    dom, &
    v1, &
    v2_add)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp
  type(domain), intent(in) :: dom
  real(kind = gp) :: v2_add
  real(kind = gp), dimension(3), intent(in) :: v1

  out_dotp = dotp_gu( &
    dom, &
    v1, &
    v2_add)
end subroutine bind_dotp_gu_add2

subroutine bind_dotp_gu_add1( &
    out_dotp, &
    dom, &
    v1_add, &
    v2)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp
  type(domain), intent(in) :: dom
  real(kind = gp) :: v1_add
  real(kind = gp), dimension(3), intent(in) :: v2

  out_dotp = dotp_gu( &
    dom, &
    v1_add, &
    v2)
end subroutine bind_dotp_gu_add1

subroutine bind_square( &
    out_square, &
    dom, &
    v)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_square
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: v

  out_square = square_gu( &
    dom, &
    v)
end subroutine bind_square

subroutine bind_square_add( &
    out_square, &
    dom, &
    v_add)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_square
  type(domain), intent(in) :: dom
  real(kind = gp) :: v_add

  out_square = square_gu( &
    dom, &
    v_add)
end subroutine bind_square_add

subroutine bind_dotp_gd( &
    out_dotp_gd, &
    dom, &
    v1, &
    v2)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp_gd
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: v1
  real(kind = gp), dimension(3), intent(in) :: v2

  out_dotp_gd = dotp_gd( &
    dom, &
    v1, &
    v2)
end subroutine bind_dotp_gd

subroutine bind_dotp_gd_add2( &
    out_dotp, &
    dom, &
    v1, &
    v2_add)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp
  type(domain), intent(in) :: dom
  real(kind = gp) :: v2_add
  real(kind = gp), dimension(3), intent(in) :: v1

  out_dotp = dotp_gd( &
    dom, &
    v1, &
    v2_add)
end subroutine bind_dotp_gd_add2

subroutine bind_dotp_gd_add1( &
    out_dotp, &
    dom, &
    v1_add, &
    v2)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp
  type(domain), intent(in) :: dom
  real(kind = gp) :: v1_add
  real(kind = gp), dimension(3), intent(in) :: v2

  out_dotp = dotp_gd( &
    dom, &
    v1_add, &
    v2)
end subroutine bind_dotp_gd_add1

subroutine bind_dotp_gd_add12( &
    out_dotp, &
    dom, &
    v1_add, &
    v2_add)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_dotp
  type(domain), intent(in) :: dom
  real(kind = gp) :: v1_add
  real(kind = gp) :: v2_add

  out_dotp = dotp_gd( &
    dom, &
    v1_add, &
    v2_add)
end subroutine bind_dotp_gd_add12

subroutine bind_square_gd( &
    out_square_gd, &
    dom, &
    v)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_square_gd
  type(domain), intent(in) :: dom
  real(kind = gp), dimension(3), intent(in) :: v

  out_square_gd = square_gd( &
    dom, &
    v)
end subroutine bind_square_gd

subroutine bind_square_gd_add( &
    out_square, &
    dom, &
    v_add)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  real(kind = gp) :: out_square
  type(domain), intent(in) :: dom
  real(kind = gp) :: v_add

  out_square = square_gd( &
    dom, &
    v_add)
end subroutine bind_square_gd_add

subroutine bind_angstroem_units( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = angstroem_units
end subroutine bind_angstroem_units

subroutine bind_periodic_bc( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = periodic_bc
end subroutine bind_periodic_bc

subroutine bind_free_bc( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = free_bc
end subroutine bind_free_bc

subroutine bind_atomic_units( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = atomic_units
end subroutine bind_atomic_units

subroutine bind_double_precision_enum( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = double_precision_enum
end subroutine bind_double_precision_enum

subroutine bind_nanometer_units( &
    out_self)
  use numerics, only: onehalf, &
    radian_degree, &
    pi
  use f_enums
  use dictionaries
  use f_precisions, gp=>f_double
  use yaml_strings
  use at_domain
  implicit none
  type(f_enumerator), pointer :: out_self

  nullify(out_self)
  allocate(out_self)
  out_self = nanometer_units
end subroutine bind_nanometer_units

