Octopus
coordinate_system.F90
Go to the documentation of this file.
1!! Copyright (C) 2021 M. Oliveira
2!! Copyright (C) 2025 S. Ohlmann
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
23 use, intrinsic :: iso_fortran_env
24 use global_oct_m
28 implicit none
29
30 private
31 public :: coordinate_system_t
32
39 type, abstract :: coordinate_system_t
40 logical :: local_basis
42 logical :: orthogonal
43 integer :: dim
44 real(real64) :: min_mesh_scaling_product
45 contains
46 generic :: vector_from_cartesian => dvector_from_cartesian, zvector_from_cartesian
47
48 procedure :: dvector_from_cartesian => dcoordinate_system_vector_from_cartesian
49
50 procedure :: zvector_from_cartesian => zcoordinate_system_vector_from_cartesian
51
52 generic :: covector_to_cartesian => dcovector_to_cartesian, zcovector_to_cartesian
53
54 procedure :: dcovector_to_cartesian => dcoordinate_system_covector_to_cartesian
55
56 procedure :: zcovector_to_cartesian => zcoordinate_system_covector_to_cartesian
57
58 procedure :: metric => coordinate_system_metric
59
60 procedure :: metric_inverse => coordinate_system_metric_inverse
61
62 procedure :: jacobian_determinant => coordinate_system_jacobian_determinant
63
64 procedure :: trace_hessian => coordinate_system_trace_hessian
65
66 procedure(coordinate_system_to_cartesian), deferred :: to_cartesian
67
68 procedure(coordinate_system_from_cartesian), deferred :: from_cartesian
69
70 procedure(coordinate_system_write_info), deferred :: write_info
71
72 procedure(coordinates_surface_element), deferred :: surface_element
73
74 procedure(coordinate_system_jacobian), deferred :: jacobian
75
76 procedure(coordinate_system_jacobian_inverse), deferred :: jacobian_inverse
77
78 end type coordinate_system_t
79
80 abstract interface
81 ! ---------------------------------------------------------
84 function coordinate_system_to_cartesian(this, chi) result(xx)
86 import real64
87 class(coordinate_system_t), target, intent(in) :: this
88 real(real64), intent(in) :: chi(:)
89 real(real64) :: xx(1:this%dim)
91
92 ! ---------------------------------------------------------
94 function coordinate_system_from_cartesian(this, xx) result(chi)
96 import real64
97 class(coordinate_system_t), target, intent(in) :: this
98 real(real64), intent(in) :: xx(:)
99 real(real64) :: chi(1:this%dim)
101
102 ! ---------------------------------------------------------
103 subroutine coordinate_system_write_info(this, iunit, namespace)
105 import namespace_t
106 class(coordinate_system_t), intent(in) :: this
107 integer, optional, intent(in) :: iunit
108 type(namespace_t), optional, intent(in) :: namespace
109 end subroutine coordinate_system_write_info
110
111 ! ---------------------------------------------------------
112 real(real64) function coordinates_surface_element(this, idir) result(ds)
114 import real64
115 class(coordinate_system_t), intent(in) :: this
116 integer, intent(in) :: idir
117 end function coordinates_surface_element
118
119 ! ---------------------------------------------------------
120 function coordinate_system_jacobian(this, chi) result(jacobian)
122 import real64
123 class(coordinate_system_t), intent(in) :: this
124 real(real64), intent(in) :: chi(:)
125 real(real64) :: jacobian(1:this%dim, 1:this%dim)
126 end function coordinate_system_jacobian
127
128 ! ---------------------------------------------------------
129 function coordinate_system_jacobian_inverse(this, chi) result(jacobian_inverse)
131 import real64
132 class(coordinate_system_t), intent(in) :: this
133 real(real64), intent(in) :: chi(:)
134 real(real64) :: jacobian_inverse(1:this%dim, 1:this%dim)
136 end interface
138contains
139 ! ---------------------------------------------------------
140 function coordinate_system_metric(this, chi) result(metric)
141 class(coordinate_system_t), intent(in) :: this
142 real(real64), intent(in) :: chi(:)
143 real(real64) :: metric(1:this%dim, 1:this%dim)
144
145 real(real64) :: jacobian(1:this%dim, 1:this%dim)
146
147 jacobian = this%jacobian(chi)
148 metric = matmul(transpose(jacobian), jacobian)
150
151 ! ---------------------------------------------------------
152 function coordinate_system_metric_inverse(this, chi) result(metric_inverse)
153 class(coordinate_system_t), intent(in) :: this
154 real(real64), intent(in) :: chi(:)
155 real(real64) :: metric_inverse(1:this%dim, 1:this%dim)
156
157 real(real64) :: jacobian_inverse(1:this%dim, 1:this%dim)
158
159 jacobian_inverse = this%jacobian_inverse(chi)
160 metric_inverse = matmul(jacobian_inverse, transpose(jacobian_inverse))
162
163 ! ---------------------------------------------------------
164 function coordinate_system_jacobian_determinant(this, chi) result(jacobian_determinant)
165 class(coordinate_system_t), intent(in) :: this
166 real(real64), intent(in) :: chi(:)
167 real(real64) :: jacobian_determinant
168
169 real(real64) :: jacobian(1:this%dim, 1:this%dim)
170
171 jacobian = this%jacobian(chi)
172 jacobian_determinant = lalg_determinant(this%dim, jacobian, preserve_mat=.false.)
174
175 ! ---------------------------------------------------------
176 function coordinate_system_trace_hessian(this, chi) result(trace_hessian)
177 class(coordinate_system_t), intent(in) :: this
178 real(real64), intent(in) :: chi(:)
179 real(real64) :: trace_hessian(1:this%dim)
180
181 ! the Hessian is non-zero only if we have a local basis, i.e. for general curvilinear coordinates
182 if (this%local_basis) then
183 ! needs to be implemented in derived classes
184 call messages_not_implemented("Trace of Hessian for the coordinate system in use")
185 else
186 trace_hessian(:) = m_zero
187 end if
189
190#include "undef.F90"
191#include "real.F90"
192#include "coordinate_system_inc.F90"
193
194#include "undef.F90"
195#include "complex.F90"
196#include "coordinate_system_inc.F90"
197
199
200!! Local Variables:
201!! mode: f90
202!! coding: utf-8
203!! End:
Convert Cartesian coordinates to coordinates in this coordinate system.
Convert coordinates given in this coordinate system to Cartesian coordinates.
real(real64) function, dimension(1:this%dim) coordinate_system_trace_hessian(this, chi)
subroutine dcoordinate_system_covector_to_cartesian(this, chi, cv, src)
subroutine zcoordinate_system_covector_to_cartesian(this, chi, cv, src)
real(real64) function coordinate_system_jacobian_determinant(this, chi)
subroutine zcoordinate_system_vector_from_cartesian(this, chi, vv, src)
real(real64) function, dimension(1:this%dim, 1:this%dim) coordinate_system_metric_inverse(this, chi)
real(real64) function, dimension(1:this%dim, 1:this%dim) coordinate_system_metric(this, chi)
subroutine dcoordinate_system_vector_from_cartesian(this, chi, vv, src)
abstract class to describe coordinate systems