! This file is part of mctc-lib. ! ! Licensed under the Apache License, Version 2.0 (the "License"); ! you may not use this file except in compliance with the License. ! You may obtain a copy of the License at ! ! http://www.apache.org/licenses/LICENSE-2.0 ! ! Unless required by applicable law or agreed to in writing, software ! distributed under the License is distributed on an "AS IS" BASIS, ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ! See the License for the specific language governing permissions and ! limitations under the License. !> Basic structure representation of the system of interest module mctc_io_structure use mctc_env_accuracy, only : wp use mctc_io_symbols, only : to_number, to_symbol, symbol_length, get_identity, & & collect_identical use mctc_io_structure_info, only : structure_info, pdb_data, sdf_data implicit none private public :: structure_type, new_structure, new !> Structure representation type :: structure_type !> Number of atoms integer :: nat = 0 !> Number of unique species integer :: nid = 0 !> Number of bonds integer :: nbd = 0 !> Species identifier integer, allocatable :: id(:) !> Atomic number for each species integer, allocatable :: num(:) !> Element symbol for each species character(len=symbol_length), allocatable :: sym(:) !> Cartesian coordinates, in Bohr real(wp), allocatable :: xyz(:, :) !> Number of unpaired electrons integer :: uhf = 0 !> Total charge real(wp) :: charge = 0.0_wp !> Lattice parameters real(wp), allocatable :: lattice(:, :) !> Periodic directions logical, allocatable :: periodic(:) !> Bond indices integer, allocatable :: bond(:, :) !> Comment, name or identifier for this structure character(len=:), allocatable :: comment !> Vendor specific structure annotations type(structure_info) :: info = structure_info() !> SDF atomic data annotations type(sdf_data), allocatable :: sdf(:) !> PDB atomic data annotations type(pdb_data), allocatable :: pdb(:) end type structure_type interface new module procedure :: new_structure module procedure :: new_structure_num module procedure :: new_structure_sym end interface contains !> Constructor for structure representations subroutine new_structure(self, num, sym, xyz, charge, uhf, lattice, periodic, & & info, bond) !> Instance of the structure representation type(structure_type), intent(out) :: self !> Atomic numbers integer, intent(in) :: num(:) !> Element symbols character(len=*), intent(in) :: sym(:) !> Cartesian coordinates real(wp), intent(in) :: xyz(:, :) !> Total charge real(wp), intent(in), optional :: charge !> Number of unpaired electrons integer, intent(in), optional :: uhf !> Lattice parameters real(wp), intent(in), optional :: lattice(:, :) !> Periodic directions logical, intent(in), optional :: periodic(:) !> Vendor specific structure information type(structure_info), intent(in), optional :: info !> Bond topology of the system integer, intent(in), optional :: bond(:, :) integer :: ndim, iid integer, allocatable :: map(:) ndim = min(size(num, 1), size(xyz, 2), size(sym, 1)) self%nat = ndim allocate(self%id(ndim)) allocate(self%xyz(3, ndim)) if (present(lattice)) then self%lattice = lattice else allocate(self%lattice(0, 0)) end if if (present(periodic)) then self%periodic = periodic else if (present(lattice)) then allocate(self%periodic(3)) self%periodic(:) = .true. else allocate(self%periodic(1)) self%periodic(:) = .false. end if end if call get_identity(self%nid, self%id, sym) allocate(map(self%nid)) call collect_identical(self%id, map) allocate(self%num(self%nid)) allocate(self%sym(self%nid)) do iid = 1, self%nid self%num(iid) = num(map(iid)) self%sym(iid) = sym(map(iid)) end do self%xyz(:, :) = xyz(:, :ndim) if (present(charge)) then self%charge = charge else self%charge = 0.0_wp end if if (present(uhf)) then self%uhf = uhf else self%uhf = 0 end if if (present(info)) then self%info = info else self%info = structure_info() end if if (present(bond)) then self%nbd = size(bond, 2) self%bond = bond end if end subroutine new_structure !> Simplified constructor for structure representations subroutine new_structure_num(self, num, xyz, charge, uhf, lattice, periodic, & & info, bond) !> Instance of the structure representation type(structure_type), intent(out) :: self !> Atomic numbers integer, intent(in) :: num(:) !> Cartesian coordinates real(wp), intent(in) :: xyz(:, :) !> Total charge real(wp), intent(in), optional :: charge !> Number of unpaired electrons integer, intent(in), optional :: uhf !> Lattice parameters real(wp), intent(in), optional :: lattice(:, :) !> Periodic directions logical, intent(in), optional :: periodic(:) !> Vendor specific structure information type(structure_info), intent(in), optional :: info !> Bond topology of the system integer, intent(in), optional :: bond(:, :) integer :: ndim, iat character(len=symbol_length), allocatable :: sym(:) ndim = min(size(num, 1), size(xyz, 2)) allocate(sym(ndim)) do iat = 1, ndim sym(iat) = to_symbol(num(iat)) end do call new_structure(self, num, sym, xyz, charge, uhf, lattice, periodic, & & info, bond) end subroutine new_structure_num !> Simplified constructor for structure representations subroutine new_structure_sym(self, sym, xyz, charge, uhf, lattice, periodic, & & info, bond) !> Instance of the structure representation type(structure_type), intent(out) :: self !> Element symbols character(len=*), intent(in) :: sym(:) !> Cartesian coordinates real(wp), intent(in) :: xyz(:, :) !> Total charge real(wp), intent(in), optional :: charge !> Number of unpaired electrons integer, intent(in), optional :: uhf !> Lattice parameters real(wp), intent(in), optional :: lattice(:, :) !> Periodic directions logical, intent(in), optional :: periodic(:) !> Vendor specific structure information type(structure_info), intent(in), optional :: info !> Bond topology of the system integer, intent(in), optional :: bond(:, :) integer :: ndim, iat integer, allocatable :: num(:) ndim = min(size(sym, 1), size(xyz, 2)) allocate(num(ndim)) do iat = 1, ndim num(iat) = to_number(sym(iat)) end do call new_structure(self, num, sym, xyz, charge, uhf, lattice, periodic, & & info, bond) end subroutine new_structure_sym end module mctc_io_structure