Octopus
lorentz_force.F90
Go to the documentation of this file.
1!! Copyright (C) 2020 Heiko Appel
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 debug_oct_m
24 use global_oct_m
31
32 implicit none
33
34 private
35 public :: &
37
39 type, extends(force_interaction_t) :: lorentz_force_t
40 private
41 real(real64), pointer :: system_charge(:) => null()
42 real(real64), pointer, public :: system_pos(:,:) => null()
43 real(real64), pointer :: system_vel(:,:) => null()
44
45 real(real64), allocatable, public :: partner_e_field(:,:)
46 ! !! at the positions of the system particles
47 real(real64), allocatable, public :: partner_b_field(:,:)
48 ! !! at the positions of the system particles
49
50 contains
51 procedure :: init => lorentz_force_init
52 procedure :: calculate => lorentz_force_calculate
53 procedure :: calculate_energy => lorentz_force_calculate_energy
55 end type lorentz_force_t
56
57 interface lorentz_force_t
58 module procedure lorentz_force_constructor
59 end interface lorentz_force_t
60
61contains
62
63 ! ---------------------------------------------------------
64 function lorentz_force_constructor(partner) result(this)
65 class(interaction_partner_t), target, intent(inout) :: partner
66 class(lorentz_force_t), pointer :: this
67
69
70 allocate(this)
71
72 this%label = "lorentz_force"
73
74 this%partner => partner
75
76 ! The Lorentz force needs the position, velocity and charge of the system
77 this%system_quantities = [character(8) :: "position", "velocity", "charge"]
78
79 ! The Lorenz force needs the E and B field of the interaction partner at the particle position
80 this%couplings_from_partner = ["E field", "B field"]
81 this%intra_interaction = .false. ! This interaction does not support intra-interactions
82
83
85 end function lorentz_force_constructor
86
87 ! ---------------------------------------------------------
88 subroutine lorentz_force_init(this, dim, system_np, system_charge, system_pos, system_vel, namespace)
89 class(lorentz_force_t), intent(inout) :: this
90 integer, intent(in) :: dim
91 integer, intent(in) :: system_np
92 real(real64), target, intent(in) :: system_charge(:)
93 real(real64), target, intent(in) :: system_pos(:,:)
94 real(real64), target, intent(in) :: system_vel(:,:)
95 type(namespace_t), intent(in) :: namespace
96
97 push_sub(lorentz_force_init)
98
99 message(1) = "Energies for Lorentz forces are not yet implemented, and currently set to 0."
100 call messages_warning(1, namespace=namespace)
101
102 this%dim = dim
103 this%system_np = system_np
104 this%energy = m_zero
105 safe_allocate(this%force(dim, system_np))
106 this%force = m_zero
107
108 safe_allocate(this%partner_e_field(1:dim, 1:system_np))
109 this%partner_e_field = m_zero
110 safe_allocate(this%partner_b_field(1:dim, 1:system_np))
111 this%partner_b_field = m_zero
112
113 this%system_charge => system_charge
114 this%system_pos => system_pos
115 this%system_vel => system_vel
116
117 pop_sub(lorentz_force_init)
118 end subroutine lorentz_force_init
119
120 ! ---------------------------------------------------------
121 subroutine lorentz_force_calculate(this)
122 class(lorentz_force_t), intent(inout) :: this
123
124 integer :: ip
125
127
128 ! Curl is defined only in 3D
129 assert(this%dim == 3)
130 assert(.not. this%intra_interaction)
131
132 do ip = 1, this%system_np
133 this%force(1, ip) = this%partner_e_field(1, ip) + &
134 this%system_vel(2, ip)*this%partner_b_field(3, ip) - this%system_vel(3, ip)*this%partner_b_field(2, ip)
136 this%force(2, ip) = this%partner_e_field(2, ip) + &
137 this%system_vel(3, ip)*this%partner_b_field(1, ip) - this%system_vel(1, ip)*this%partner_b_field(3, ip)
139 this%force(3, ip) = this%partner_e_field(3, ip) + &
140 this%system_vel(1, ip)*this%partner_b_field(2, ip) - this%system_vel(2, ip)*this%partner_b_field(1, ip)
141
142 this%force(1:3, ip) = this%force(1:3, ip)*this%system_charge(ip)
143 end do
148 ! ---------------------------------------------------------
149 subroutine lorentz_force_calculate_energy(this)
150 class(lorentz_force_t), intent(inout) :: this
151
152 integer :: ip
153 real(real64) :: power
154
156
157 ! the rate at which the energy is transferred from the EM field to the particle
158 ! the B field does not contribute any energy to the particles
159 power = m_zero
160 do ip = 1, this%system_np
161 power = power - dot_product(this%system_vel(1:3,ip), this%force(1:3,ip))
162 end do
163
164 this%energy = m_zero
165 !TODO: We need to implement the proper time integration of the power.
166 ! However, to that end, we first need to implement another clock at which the energies are
167 ! calculated.
168 ! this%energy = this%energy + power*this%partner%iteration%get_time_step()
169
171 end subroutine lorentz_force_calculate_energy
172
173
174 ! ---------------------------------------------------------
175 subroutine lorentz_force_finalize(this)
176 type(lorentz_force_t), intent(inout) :: this
177
178 push_sub(lorentz_force_finalize)
179
180 this%force = m_zero
181 nullify(this%system_charge)
182 nullify(this%system_pos)
183 nullify(this%system_vel)
184 safe_deallocate_a(this%force)
185 safe_deallocate_a(this%partner_e_field)
186 safe_deallocate_a(this%partner_b_field)
187
188 call interaction_end(this)
189
191 end subroutine lorentz_force_finalize
192
193end module lorentz_force_oct_m
194
195!! Local Variables:
196!! mode: f90
197!! coding: utf-8
198!! End:
real(real64), parameter, public m_zero
Definition: global.F90:188
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
subroutine, public interaction_end(this)
This module defines classes and functions for interaction partners.
subroutine lorentz_force_calculate_energy(this)
class(lorentz_force_t) function, pointer lorentz_force_constructor(partner)
subroutine lorentz_force_finalize(this)
subroutine lorentz_force_init(this, dim, system_np, system_charge, system_pos, system_vel, namespace)
subroutine lorentz_force_calculate(this)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:537
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:138
Lorenz force between a systems of particles and an electromagnetic field.