30 use,
intrinsic :: iso_fortran_env
53 type(stencil_t),
intent(inout) :: this
54 integer,
intent(in) :: dim
55 class(coordinate_system_t),
intent(in) :: coord_system
57 real(real64) :: theta(dim), basis_vectors(dim, dim)
60 real(real64) :: norm, min_norm(dim)
62 real(real64),
parameter :: tol = 1e-14_real64
68 this%stargeneral%narms = 0
69 this%stargeneral%arms = 0
77 select type (coord_system)
79 basis_vectors = coord_system%basis%vectors
81 message(1) =
"Stencil stargeneral can currently only be used with affine coordinate systems."
87 theta(1) =
acos(
clamp(dot_product(basis_vectors(:, 1), basis_vectors(:, 2)), -
m_one,
m_one))
90 this%stargeneral%narms = this%stargeneral%narms + 1
92 this%stargeneral%arms(this%stargeneral%narms, 1:dim) = arm
94 this%stargeneral%narms = this%stargeneral%narms + 1
96 this%stargeneral%arms(this%stargeneral%narms, 1:dim) = arm
109 theta(1) =
acos(
clamp(dot_product(basis_vectors(:, 1), basis_vectors(:, 2)), -
m_one,
m_one))
110 if (abs(theta(1) -
m_pi*
m_half) > 1e-8_real64) this%stargeneral%narms = this%stargeneral%narms + 1
112 theta(2) =
acos(
clamp(dot_product(basis_vectors(:, 2), basis_vectors(:, 3)), -
m_one,
m_one))
113 if (abs(theta(2)-
m_pi*
m_half) > 1e-8_real64) this%stargeneral%narms = this%stargeneral%narms + 1
115 theta(3) =
acos(
clamp(dot_product(basis_vectors(:, 3), basis_vectors(:, 1)), -
m_one,
m_one))
116 if (abs(theta(3) -
m_pi*
m_half) > 1e-8_real64) this%stargeneral%narms = this%stargeneral%narms + 1
120 if (this%stargeneral%narms == 0)
then
132 if (ii == 0 .and. jj == 0) cycle
133 if (ii == 0 .and. kk == 0) cycle
134 if (kk == 0 .and. jj == 0) cycle
137 if (abs(theta(1) -
m_pi*
m_half) <= 1e-8_real64 .and. kk == 0) cycle
138 if (abs(theta(2) -
m_pi*
m_half) <= 1e-8_real64 .and. ii == 0) cycle
139 if (abs(theta(3) -
m_pi*
m_half) <= 1e-8_real64 .and. jj == 0) cycle
141 norm = sum((ii*basis_vectors(:, 1) + jj*basis_vectors(:, 2) + kk*basis_vectors(:, 3))**2)
143 if (min_norm(1) - norm > tol)
then
144 if (min_norm(2) - min_norm(1) > tol .and. this%stargeneral%narms >= 2)
then
145 if (min_norm(3) - min_norm(2) > tol .and. this%stargeneral%narms == 3)
then
146 this%stargeneral%arms(3, 1:3) = this%stargeneral%arms(2, 1:3)
147 min_norm(3) = min_norm(2)
149 this%stargeneral%arms(2, 1:3) = this%stargeneral%arms(1, 1:3)
150 min_norm(2) = min_norm(1)
153 this%stargeneral%arms(1, 1:3) = (/ii, jj, kk/)
158 if (this%stargeneral%arms(1, 1) == -ii &
159 .and. this%stargeneral%arms(1, 2) == -jj &
160 .and. this%stargeneral%arms(1, 3) == -kk) cycle
162 if (this%stargeneral%narms == 1) cycle
164 if (min_norm(2) - norm > tol)
then
165 if (min_norm(3) - min_norm(2) > tol .and. this%stargeneral%narms == 3)
then
166 this%stargeneral%arms(3, 1:3) = this%stargeneral%arms(2, 1:3)
167 min_norm(3) = min_norm(2)
170 this%stargeneral%arms(2, 1:3) = (/ii, jj, kk/)
174 if (this%stargeneral%narms == 2) cycle
177 if (this%stargeneral%arms(2, 1) == -ii &
178 .and. this%stargeneral%arms(2, 2) == -jj &
179 .and. this%stargeneral%arms(2, 3) == -kk) cycle
181 if (min_norm(3) - norm > tol)
then
183 this%stargeneral%arms(3, 1:3) = (/ii, jj, kk/)
196 integer,
intent(in) :: dim
197 integer,
intent(in) :: order
205 n = n + 2 * order * this%stargeneral%narms
216 integer,
intent(in) :: dir
217 integer,
intent(in) :: order
224 if (dir >= 1 .and. dir <= 3)
then
241 integer,
intent(in) :: dim
242 integer,
intent(in) :: order
245 logical :: got_center
259 this%points(i, n) = j
268 this%points(i, n) = j
274 do i = 1, this%stargeneral%narms
276 this%points(1:2, n) = this%stargeneral%arms(i, 1:2)*j
297 this%points(i, n) = j
303 do i = 1, this%stargeneral%narms
305 this%points(1:3, n) = this%stargeneral%arms(i, 1:3)*j
322 integer,
intent(in) :: dim
323 integer,
intent(in) :: order
324 integer,
intent(out) :: pol(:,:)
326 integer :: i, j, n, j1
327 logical :: zeros_treated(dim)
353 do i = 1, this%stargeneral%narms
355 if (sum(this%stargeneral%arms(i,1:dim)) == 0)
then
356 pol(1:2, n) = (/j,1/)
358 pol(1:2, n) = (/1,j/)
375 zeros_treated = .false.
376 do i = 1, this%stargeneral%narms
377 if (this%stargeneral%arms(i, 1) == 0)
then
380 pol(1:3, n) = (/0, 1, j1/)
382 zeros_treated(1) = .
true.
383 else if (this%stargeneral%arms(i, 2) == 0)
then
386 pol(1:3, n) = (/j1, 0, 1/)
388 zeros_treated(2) = .
true.
389 else if (this%stargeneral%arms(i, 3) == 0)
then
392 pol(1:3, n) = (/1, j1, 0/)
394 zeros_treated(3) = .
true.
398 do i = 1, this%stargeneral%narms - count(zeros_treated)
399 if (.not. zeros_treated(1))
then
402 pol(1:3, n) = (/0, 1, j1/)
404 zeros_treated(1) = .
true.
405 else if (.not. zeros_treated(2))
then
408 pol(1:3, n) = (/j1, 0, 1/)
410 zeros_treated(2) = .
true.
411 else if (.not. zeros_treated(3))
then
414 pol(1:3, n) = (/1, j1, 0/)
416 zeros_treated(3) = .
true.
double acos(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_huge
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module is intended to contain "only mathematical" functions and procedures.
elemental real(real64) function, public clamp(x, xmin, xmax)
Return the value of x restricted to [xmin;xmax].
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
This module defines stencils used in Octopus.
subroutine, public stencil_allocate(this, dim, size)
subroutine, public stencil_init_center(this)
This module defines routines, generating operators for a generalized star stencil.
subroutine, public stencil_stargeneral_get_arms(this, dim, coord_system)
Finds the direction of the arms of the star-general stencil as described in Natan et al....
subroutine, public stencil_stargeneral_pol_lapl(this, dim, order, pol)
integer function, public stencil_stargeneral_extent(dir, order)
Returns maximum extension of the stencil in spatial direction dir = 1, 2, 3 for a given discretizatio...
subroutine, public stencil_stargeneral_get_lapl(this, dim, order)
integer function, public stencil_stargeneral_size_lapl(this, dim, order)
The class representing the stencil, which is used for non-local mesh operations.