Octopus
symmetrizer.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use comm_oct_m
23 use debug_oct_m
24 use global_oct_m
25 use index_oct_m
27 use mesh_oct_m
28 use mpi_oct_m
31 use space_oct_m
34
35 implicit none
36
37 private
38 public :: &
50
51 type symmetrizer_t
52 private
53 type(symmetries_t), pointer :: symm
54 integer(int64), allocatable :: map(:,:)
55 integer(int64), allocatable :: map_inv(:,:)
56 end type symmetrizer_t
57
58contains
59
60 ! ---------------------------------------------------------
61 subroutine symmetrizer_init(this, mesh, symm)
62 type(symmetrizer_t), intent(out) :: this
63 class(mesh_t), intent(in) :: mesh
64 type(symmetries_t), target, intent(in) :: symm
65
66 integer :: nops, ip, iop, idir, idx(3)
67 real(real64) :: destpoint(3), srcpoint(3), srcpoint_inv(3), lsize(3), offset(3)
68
69 push_sub(symmetrizer_init)
70
71 assert(mesh%box%dim <= 3)
72
73 this%symm => symm
74
75 !For each operation, we create a mapping between the grid point and the symmetric point
76 nops = symmetries_number(symm)
77
78 safe_allocate(this%map(1:mesh%np, 1:nops))
79 safe_allocate(this%map_inv(1:mesh%np, 1:nops))
80
81 call profiling_in("SYMMETRIZER_INIT")
82
83 lsize = real(mesh%idx%ll, real64)
84 offset = real(mesh%idx%nr(1, :) + mesh%idx%enlarge, real64)
85
86 do ip = 1, mesh%np
87 call mesh_local_index_to_coords(mesh, ip, idx)
88 destpoint = real(idx, real64) - offset
89 ! offset moves corner of cell to origin, in integer mesh coordinates
90
91 assert(all(destpoint >= 0))
92 assert(all(destpoint < lsize))
93
94 ! move to center of cell in real coordinates
95 destpoint = destpoint + offset
96
97 !convert to proper reduced coordinates
98 destpoint = destpoint/lsize
99
100 ! iterate over all points that go to this point by a symmetry operation
101 do iop = 1, nops
102 srcpoint = symm_op_apply_red(symm%ops(iop), destpoint)
103 srcpoint_inv = symm_op_apply_inv_red(symm%ops(iop), destpoint)
104
105 !We now come back to what should be an integer, if the symmetric point beloings to the grid
106 !At this point, this is already checked
107 srcpoint = srcpoint*lsize
108 srcpoint_inv = srcpoint_inv*lsize
109
110 ! move back to reference to origin at corner of cell
111 srcpoint = srcpoint - offset
112 srcpoint_inv = srcpoint_inv - offset
113 ! apply periodic boundary conditions in periodic directions
114 do idir = 1, symm%periodic_dim
115 if (nint(srcpoint(idir)) < 0 .or. nint(srcpoint(idir)) >= mesh%idx%ll(idir)) then
116 srcpoint(idir) = real(modulo(nint(srcpoint(idir)), mesh%idx%ll(idir)), real64)
117 end if
118 if (nint(srcpoint_inv(idir)) < 0 .or. nint(srcpoint_inv(idir)) >= mesh%idx%ll(idir)) then
119 srcpoint_inv(idir) = real(modulo(nint(srcpoint_inv(idir)), mesh%idx%ll(idir)), real64)
120 end if
121 end do
122 assert(all(nint(srcpoint) >= 0))
123 assert(all(nint(srcpoint) < mesh%idx%ll))
124 srcpoint = srcpoint + offset
125
126 assert(all(nint(srcpoint_inv) >= 0))
127 assert(all(nint(srcpoint_inv) < mesh%idx%ll))
128 srcpoint_inv = srcpoint_inv + offset
129
130 this%map(ip, iop) = mesh_global_index_from_coords(mesh, nint(srcpoint))
131 assert(this%map(ip, iop) <= mesh%np_global)
132 this%map_inv(ip, iop) = mesh_global_index_from_coords(mesh, nint(srcpoint_inv))
133 assert(this%map_inv(ip, iop) <= mesh%np_global)
134 end do
135 end do
136
137 call profiling_out("SYMMETRIZER_INIT")
138
139 pop_sub(symmetrizer_init)
140 end subroutine symmetrizer_init
141
142 ! ---------------------------------------------------------
143
144 subroutine symmetrizer_end(this)
145 type(symmetrizer_t), intent(inout) :: this
148 nullify(this%symm)
149
150 safe_deallocate_a(this%map)
151 safe_deallocate_a(this%map_inv)
152
153 pop_sub(symmetrizer_end)
154 end subroutine symmetrizer_end
155
156 ! ---------------------------------------------------------
157
158#include "undef.F90"
159#include "real.F90"
160#include "symmetrizer_inc.F90"
161
162#include "undef.F90"
163#include "complex.F90"
164#include "symmetrizer_inc.F90"
165
166end module symmetrizer_oct_m
167
168!! Local Variables:
169!! mode: f90
170!! coding: utf-8
171!! End:
This module implements the index, used for the mesh points.
Definition: index.F90:122
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
integer(int64) function, public mesh_global_index_from_coords(mesh, ix)
This function returns the true global index of the point for a given vector of integer coordinates.
Definition: mesh.F90:916
subroutine, public mesh_local_index_to_coords(mesh, ip, ix)
Given a local point index, this function returns the set of integer coordinates of the point.
Definition: mesh.F90:947
Some general things and nomenclature:
Definition: par_vec.F90:171
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
integer pure function, public symmetries_number(this)
Definition: symmetries.F90:556
subroutine, public dsymmetrizer_apply(this, mesh, field, field_vector, symmfield, symmfield_vector, suppress_warning, reduced_quantity)
supply field and symmfield, and/or field_vector and symmfield_vector
subroutine, public dsymmetrize_magneto_optics_cart(symm, tensor)
subroutine, public symmetrizer_end(this)
subroutine, public zsymmetrizer_apply_single(this, mesh, iop, field, symmfield)
subroutine, public zsymmetrizer_apply(this, mesh, field, field_vector, symmfield, symmfield_vector, suppress_warning, reduced_quantity)
supply field and symmfield, and/or field_vector and symmfield_vector
subroutine, public dsymmetrizer_apply_single(this, mesh, iop, field, symmfield)
subroutine, public dsymmetrize_tensor_cart(symm, tensor, use_non_symmorphic)
Symmetric a rank-2 tensor defined in Cartesian space.
subroutine, public zsymmetrize_tensor_cart(symm, tensor, use_non_symmorphic)
Symmetric a rank-2 tensor defined in Cartesian space.
subroutine, public zsymmetrize_magneto_optics_cart(symm, tensor)
subroutine, public symmetrizer_init(this, mesh, symm)