Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
adjoint_scalar_convection_source_term.f90
Go to the documentation of this file.
1
34!
36! this is a such a dumb name
38 use num_types, only: rp
39 use field_list, only: field_list_t
40 use field, only: field_t
41 use json_module, only: json_file
42 use time_state, only: time_state_t
43 use source_term, only: source_term_t
44 use interpolation, only: interpolator_t
45 use space, only: space_t, gl
46 use coefs, only: coef_t
47 use field_math, only: field_subcol3, field_sub2, field_col3
48 use operators, only: grad, dudxyz
49 use utils, only: neko_error
50 use gather_scatter, only: gs_op_add
51 use scratch_registry, only: neko_scratch_registry, scratch_registry_t
52 use neko_config, only: neko_bcknd_device
53 use math, only: col2
54 use device_math, only: device_col2
55 implicit none
56 private
58
59 ! I don't know how to name this term, but when you have a passive
60 ! scalar you get an extra term in the adjoint velocity equation, which comes
61 ! from the convective term in the passive scalar equation.
62 ! Maybe this should be called just `adjoint_scalar_convection`?
63 ! but it does come in a source term...
64
65 ! In any case,
66 ! it's a source term acting on the adjoint velocity equations, of the form:
67 ! \f$\nabla s s_adj\f$
68 type, public, extends(source_term_t) :: &
71 type(field_t), pointer :: s_adj => null()
73 type(field_t), pointer :: s => null()
74 ! --- for over-integration
76 type(space_t), pointer :: xh_gll
78 type(space_t), pointer :: xh_gl
80 type(coef_t), pointer :: c_xh_gl
82 type(interpolator_t), pointer :: gll_to_gl
84 logical :: dealias
86 type(scratch_registry_t), pointer :: scratch_gl
87
88 contains
90 procedure, pass(this) :: init => &
91 adjoint_scalar_convection_source_term_init_from_json
93 procedure, pass(this) :: init_from_components => &
94 adjoint_scalar_convection_source_term_init_from_components
96 procedure, pass(this) :: free => adjoint_scalar_convection_source_term_free
98 procedure, pass(this) :: compute_ => &
99 adjoint_scalar_convection_source_term_compute
101
102contains
103
106 class(source_term_t), allocatable, intent(inout) :: obj
109
116 subroutine adjoint_scalar_convection_source_term_init_from_json(this, &
117 json, fields, coef, variable_name)
118 class(adjoint_scalar_convection_source_term_t), intent(inout) :: this
119 type(json_file), intent(inout) :: json
120 type(field_list_t), intent(in), target :: fields
121 type(coef_t), intent(in), target :: coef
122 character(len=*), intent(in) :: variable_name
123
124 ! this is a bit weird... because I don't think this should come from the
125 ! JSON.
126 ! Maybe we should think of all these source terms as only "appendable"
127 !
128 ! Because we'll never have the whole case here, so we'll never be able
129 ! init from components anyway...
130
131
132 end subroutine adjoint_scalar_convection_source_term_init_from_json
133
144 subroutine adjoint_scalar_convection_source_term_init_from_components(this,&
145 f_x, f_y, f_z, s, s_adj, coef, c_Xh_GL, GLL_to_GL, dealias, scratch_GL)
146 class(adjoint_scalar_convection_source_term_t), intent(inout) :: this
147 type(field_t), pointer, intent(in) :: f_x, f_y, f_z
148 type(field_t), intent(in), target :: s, s_adj
149 type(coef_t), intent(in), target :: coef
150 type(coef_t), intent(in), target :: c_xh_gl
151 type(interpolator_t), intent(in), target :: gll_to_gl
152 logical, intent(in) :: dealias
153 type(scratch_registry_t), intent(in), target :: scratch_gl
154
155 type(field_list_t) :: fields
156 real(kind=rp) :: start_time
157 real(kind=rp) :: end_time
158
159 ! I wish you didn't need a start time and end time...
160 ! but I'm just going to set a super big number...
161 start_time = 0.0_rp
162 end_time = 100000000.0_rp
163
164 call this%free()
165
166 ! this is copying the fluid source term init
167 ! We package the fields for the source term to operate on in a field list.
168 call fields%init(3)
169 call fields%assign(1, f_x)
170 call fields%assign(2, f_y)
171 call fields%assign(3, f_z)
172
173 call this%init_base(fields, coef, start_time, end_time)
174 call fields%free()
175
176 ! point everything in the correct places
177 this%s_adj => s_adj
178 this%s => s
179
180 ! for over integration
181 this%dealias = dealias
182 this%c_Xh_GL => c_xh_gl
183 this%Xh_GL => this%c_Xh_GL%Xh
184 this%Xh_GLL => this%coef%Xh
185 this%GLL_to_GL => gll_to_gl
186 this%scratch_GL => scratch_gl
187
188 end subroutine adjoint_scalar_convection_source_term_init_from_components
189
191 subroutine adjoint_scalar_convection_source_term_free(this)
192 class(adjoint_scalar_convection_source_term_t), intent(inout) :: this
193
194 call this%free_base()
195 nullify(this%s_adj)
196 nullify(this%s)
197 nullify(this%c_Xh_GL)
198 nullify(this%Xh_GL)
199 nullify(this%Xh_GLL)
200 nullify(this%GLL_to_GL)
201 nullify(this%scratch_GL)
202
203 end subroutine adjoint_scalar_convection_source_term_free
204
208 subroutine adjoint_scalar_convection_source_term_compute(this, time)
209 class(adjoint_scalar_convection_source_term_t), intent(inout) :: this
210 type(time_state_t), intent(in) :: time
211 type(field_t), pointer :: fu, fv, fw
212 integer :: temp_indices(4)
213 type(field_t), pointer :: dsdx, dsdy, dsdz, work
214 type(field_t), pointer :: accumulate, fld_gl, s_gl, s_adj_gl
215 integer :: temp_indices_gl(4)
216 integer :: n_gl, nel
217
218
219 call neko_scratch_registry%request_field(dsdx, temp_indices(1), .false.)
220 call neko_scratch_registry%request_field(dsdy, temp_indices(2), .false.)
221 call neko_scratch_registry%request_field(dsdz, temp_indices(3), .false.)
222 call neko_scratch_registry%request_field(work, temp_indices(4), .false.)
223
224 fu => this%fields%get(1)
225 fv => this%fields%get(2)
226 fw => this%fields%get(3)
227
228 ! we need the term \f$\nabla s s_adj\f$
229 if (this%dealias) then
230 nel = this%coef%msh%nelv
231 n_gl = nel * this%Xh_GL%lxyz
232 call this%scratch_GL%request_field(accumulate, temp_indices_gl(1), .false.)
233 call this%scratch_GL%request_field(fld_gl, temp_indices_gl(2), .false.)
234 call this%scratch_GL%request_field(s_gl, temp_indices_gl(3), .false.)
235 call this%scratch_GL%request_field(s_adj_gl, temp_indices_gl(4), .false.)
236
237 call this%GLL_to_GL%map(s_gl%x, this%s%x, nel, this%Xh_GL)
238 call this%GLL_to_GL%map(s_adj_gl%x, this%s_adj%x, nel, this%Xh_GL)
239
240 ! u
241 call dudxyz(fld_gl%x, s_gl%x, this%c_Xh_GL%drdx, &
242 this%c_Xh_GL%dsdx, this%c_Xh_GL%dtdx, this%c_Xh_GL)
243 call field_col3(accumulate, s_adj_gl, fld_gl)
244 ! Evaluate term on GL and preempt the GLL premultiplication
245 if (neko_bcknd_device .eq. 1) then
246 call device_col2(accumulate%x_d, this%c_Xh_GL%B_d, n_gl)
247 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
248 ! Sum contributions from adjoining elements at shared dofs before
249 ! normalizing.
250 call this%coef%gs_h%op(work, gs_op_add)
251 call device_col2(work%x_d, this%coef%Binv_d, work%size())
252 else
253 call col2(accumulate%x, this%c_Xh_GL%B, n_gl)
254 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
255 ! See comment in the device branch above.
256 call this%coef%gs_h%op(work, gs_op_add)
257 call col2(work%x, this%coef%Binv, work%size())
258 end if
259 call field_sub2(fu, work)
260
261 ! v
262 call dudxyz(fld_gl%x, s_gl%x, this%c_Xh_GL%drdy, &
263 this%c_Xh_GL%dsdy, this%c_Xh_GL%dtdy, this%c_Xh_GL)
264 call field_col3(accumulate, s_adj_gl, fld_gl)
265 ! Evaluate term on GL and preempt the GLL premultiplication
266 if (neko_bcknd_device .eq. 1) then
267 call device_col2(accumulate%x_d, this%c_Xh_GL%B_d, n_gl)
268 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
269 ! Sum contributions from adjoining elements at shared dofs before
270 ! normalizing.
271 call this%coef%gs_h%op(work, gs_op_add)
272 call device_col2(work%x_d, this%coef%Binv_d, work%size())
273 else
274 call col2(accumulate%x, this%c_Xh_GL%B, n_gl)
275 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
276 ! See comment in the device branch above.
277 call this%coef%gs_h%op(work, gs_op_add)
278 call col2(work%x, this%coef%Binv, work%size())
279 end if
280 call field_sub2(fv, work)
281
282 ! w
283 call dudxyz(fld_gl%x, s_gl%x, this%c_Xh_GL%drdz, &
284 this%c_Xh_GL%dsdz, this%c_Xh_GL%dtdz, this%c_Xh_GL)
285 call field_col3(accumulate, s_adj_gl, fld_gl)
286 ! Evaluate term on GL and preempt the GLL premultiplication
287 if (neko_bcknd_device .eq. 1) then
288 call device_col2(accumulate%x_d, this%c_Xh_GL%B_d, n_gl)
289 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
290 ! Sum contributions from adjoining elements at shared dofs before
291 ! normalizing.
292 call this%coef%gs_h%op(work, gs_op_add)
293 call device_col2(work%x_d, this%coef%Binv_d, work%size())
294 else
295 call col2(accumulate%x, this%c_Xh_GL%B, n_gl)
296 call this%GLL_to_GL%map(work%x, accumulate%x, nel, this%Xh_GLL)
297 ! See comment in the device branch above.
298 call this%coef%gs_h%op(work, gs_op_add)
299 call col2(work%x, this%coef%Binv, work%size())
300 end if
301 call field_sub2(fw, work)
302
303 call this%scratch_GL%relinquish_field(temp_indices_gl)
304
305 else
306 call grad(dsdx%x, dsdy%x, dsdz%x, this%s%x, this%coef)
307 call field_subcol3(fu, this%s_adj, dsdx)
308 call field_subcol3(fv, this%s_adj, dsdy)
309 call field_subcol3(fw, this%s_adj, dsdz)
310 end if
311
312 ! free the scratch
313 call neko_scratch_registry%relinquish_field(temp_indices)
314 end subroutine adjoint_scalar_convection_source_term_compute
315
Implements the adjoint_scalar_convection_source_term type.
subroutine, public adjoint_scalar_convection_source_term_allocate(obj)
Allocator for the adjoint scalar convection source term.