89 character(len=:),
allocatable :: name
91 type(field_t),
pointer :: u
93 type(field_t),
pointer :: v
95 type(field_t),
pointer :: w
97 type(field_t),
pointer :: s
99 type(field_t),
pointer :: s_adj
101 type(field_series_t) :: s_adj_lag
103 type(space_t),
pointer :: xh
105 type(dofmap_t),
pointer :: dm_xh
107 type(gs_t),
pointer :: gs_xh
109 type(coef_t),
pointer :: c_xh
111 type(field_t),
pointer :: f_xh => null()
113 type(scalar_source_term_t) :: source_term
115 class(ksp_t),
allocatable :: ksp
117 integer :: ksp_maxiter
119 integer :: projection_dim
121 integer :: projection_activ_step
123 class(pc_t),
allocatable :: pc
125 type(bc_list_t) :: bcs
127 type(json_file),
pointer :: params
129 type(mesh_t),
pointer :: msh => null()
131 type(chkp_t),
pointer :: chkp => null()
133 character(len=:),
allocatable :: nut_field_name
135 type(field_t),
pointer :: rho => null()
137 type(field_t) :: lambda
141 real(kind=rp) :: pr_turb
143 type(field_list_t) :: material_properties
145 logical :: variable_material_properties = .false.
146 procedure(user_material_properties),
nopass,
pointer :: &
147 user_material_properties => null()
149 logical :: if_gradient_jump_penalty
150 type(gradient_jump_penalty_t) :: gradient_jump_penalty
153 procedure, pass(this) :: scheme_init => adjoint_scalar_scheme_init
155 procedure, pass(this) :: scheme_free => adjoint_scalar_scheme_free
157 procedure, pass(this) :: validate => adjoint_scalar_scheme_validate
159 procedure, pass(this) :: set_material_properties => &
160 adjoint_scalar_scheme_set_material_properties
162 procedure, pass(this) :: update_material_properties => &
163 adjoint_scalar_scheme_update_material_properties
247 subroutine adjoint_scalar_scheme_init(this, msh, c_Xh, gs_Xh, params, &
250 type(mesh_t),
target,
intent(in) :: msh
251 type(coef_t),
target,
intent(in) :: c_Xh
252 type(gs_t),
target,
intent(inout) :: gs_Xh
253 type(json_file),
target,
intent(inout) :: params
254 character(len=*),
intent(in) :: scheme
255 type(user_t),
target,
intent(in) :: user
256 type(field_t),
target,
intent(in) :: rho
258 character(len=LOG_SIZE) :: log_buf
260 logical :: logical_val
261 real(kind=rp) :: solver_abstol
262 integer :: integer_val
263 character(len=:),
allocatable :: solver_type, solver_precon
265 character(len=:),
allocatable :: json_key
266 type(json_file) :: precon_params
268 this%u => neko_field_registry%get_field(
'u')
269 this%v => neko_field_registry%get_field(
'v')
270 this%w => neko_field_registry%get_field(
'w')
271 this%s => neko_field_registry%get_field(
's')
274 call neko_log%section(
'Adjoint scalar')
277 call json_get(params,
'case.scalar.solver.type', solver_type)
278 json_key = json_key_fallback(params, &
279 'case.adjoint_scalar.solver.preconditioner.type', &
280 'case.scalar.solver.preconditioner.type')
281 call json_get(params, json_key, solver_precon)
283 json_key = json_key_fallback(params, &
284 'case.adjoint_scalar.solver.preconditioner', &
285 'case.scalar.solver.preconditioner')
286 call json_extract_object(params, json_key, precon_params)
288 json_key = json_key_fallback(params, &
289 'case.adjoint_scalar.solver.absolute_tolerance', &
290 'case.scalar.solver.absolute_tolerance')
291 call json_get(params, json_key, solver_abstol)
293 json_key = json_key_fallback(params, &
294 'case.adjoint_scalar.solver.projection_space_size', &
295 'case.scalar.solver.projection_space_size')
296 call json_get_or_default(params, json_key, this%projection_dim, 0)
298 json_key = json_key_fallback(params, &
299 'case.adjoint_scalar.solver.projection_hold_steps', &
300 'case.scalar.solver.projection_hold_steps')
301 call json_get_or_default(params, json_key, this%projection_activ_step, 5)
304 write(log_buf,
'(A, A)')
'Type : ', trim(scheme)
305 call neko_log%message(log_buf)
306 call neko_log%message(
'Ksp adjoint scalar : ('// trim(solver_type) // &
307 ', ' // trim(solver_precon) //
')')
308 write(log_buf,
'(A,ES13.6)')
' `-abs tol :', solver_abstol
309 call neko_log%message(log_buf)
312 this%dm_Xh => this%u%dof
313 this%params => params
315 if (.not. neko_field_registry%field_exists(
's_adj'))
then
316 call neko_field_registry%add_field(this%dm_Xh,
's_adj')
318 this%s_adj => neko_field_registry%get_field(
's_adj')
320 call this%s_adj_lag%init(this%s_adj, 2)
328 call this%set_material_properties(params, user)
332 if (params%valid_path(
'case.scalar.variable_material_properties'))
then
333 call json_get(params,
'variable_material_properties', &
334 this%variable_material_properties)
337 if ((params%valid_path(
'case.scalar.nut_field')) .and. &
338 (this%variable_material_properties .eqv. .false.))
then
339 call neko_warning(
"You set variable_material properties to " // &
340 "false, the nut_field setting will have no effect.")
344 if ((.not.
associated(user%material_properties, &
345 dummy_user_material_properties)) .and. &
346 (this%variable_material_properties .eqv. .false.))
then
347 call neko_warning(
"You set variable_material properties to " // &
348 "false, you can only vary rho and mu in time in the user file.")
350 else if (params%valid_path(
'case.scalar.nut_field'))
then
351 call json_get(params,
'case.scalar.Pr_t', this%pr_turb)
352 call json_get(params,
'case.scalar.nut_field', this%nut_field_name)
353 this%variable_material_properties = .true.
354 else if (.not.
associated(user%material_properties, &
355 dummy_user_material_properties))
then
356 this%nut_field_name =
""
357 this%variable_material_properties = .true.
360 write(log_buf,
'(A,L1)')
'LES : ', this%variable_material_properties
361 call neko_log%message(log_buf)
368 call this%f_Xh%init(this%dm_Xh, fld_name =
"adjoint_scalar_rhs")
371 call this%source_term%init(this%f_Xh, this%c_Xh, user)
373 call this%source_term%add(params,
'case.adjoint_scalar.source_terms')
376 json_key = json_key_fallback(params, &
377 'case.adjoint_fluid.velocity_solver.max_iterations', &
378 'case.fluid.velocity_solver.max_iterations')
379 call json_get_or_default(params, json_key, integer_val, ksp_max_iter)
380 json_key = json_key_fallback(params, &
381 'case.adjoint_fluid.velocity_solver.monitor', &
382 'case.fluid.velocity_solver.monitor')
383 call json_get_or_default(params, json_key, logical_val, .false.)
384 call scalar_scheme_solver_factory(this%ksp, this%dm_Xh%size(), &
385 solver_type, integer_val, solver_abstol, logical_val)
386 call scalar_scheme_precon_factory(this%pc, this%ksp, &
387 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs, &
388 solver_precon, precon_params)
391 json_key = json_key_fallback(params, &
392 'case.adjoint_scalar.gradient_jump_penalty.enabled', &
393 'case.scalar.gradient_jump_penalty.enabled')
394 call json_get_or_default(params, json_key, &
395 this%if_gradient_jump_penalty, .false.)
397 if (this%if_gradient_jump_penalty .eqv. .true.)
then
398 call neko_error(
"gradient jump not implemented for adjoint scalar")
416 call neko_log%end_section()
505 subroutine adjoint_scalar_scheme_update_material_properties(t, tstep, this)
507 real(kind=rp),
intent(in) :: t
508 integer,
intent(in) :: tstep
509 type(field_t),
pointer :: nut
512 type(field_t),
pointer :: lambda_factor
514 call this%user_material_properties(t, tstep, this%name, &
515 this%material_properties)
518 if (this%variable_material_properties .and. &
519 len(trim(this%nut_field_name)) > 0)
then
520 nut => neko_field_registry%get_field(this%nut_field_name)
523 call neko_scratch_registry%request_field(lambda_factor, index)
525 call field_col3(lambda_factor, this%cp, this%rho)
526 call field_cmult2(lambda_factor, nut, 1.0_rp / this%pr_turb)
527 call field_add2(this%lambda, lambda_factor)
528 call neko_scratch_registry%relinquish_field(index)
535 if (neko_bcknd_device .eq. 1)
then
536 call device_memcpy(this%cp%x, this%cp%x_d, this%cp%size(), &
537 device_to_host, sync=.false.)
546 subroutine adjoint_scalar_scheme_set_material_properties(this, params, user)
548 type(json_file),
intent(inout) :: params
549 type(user_t),
target,
intent(in) :: user
550 character(len=LOG_SIZE) :: log_buf
552 procedure(user_material_properties),
pointer :: dummy_mp_ptr
553 real(kind=rp) :: const_cp, const_lambda
558 dummy_mp_ptr => dummy_user_material_properties
561 call this%lambda%init(this%dm_Xh,
"lambda")
562 call this%cp%init(this%dm_Xh,
"cp")
564 call this%material_properties%init(2)
565 call this%material_properties%assign_to_field(1, this%cp)
566 call this%material_properties%assign_to_field(2, this%lambda)
568 if (.not.
associated(user%material_properties, dummy_mp_ptr))
then
570 write(log_buf,
'(A)')
"Material properties must be set in the user " // &
572 call neko_log%message(log_buf)
573 this%user_material_properties => user%material_properties
574 call user%material_properties(0.0_rp, 0, this%name, &
575 this%material_properties)
577 this%user_material_properties => dummy_user_material_properties
578 if (params%valid_path(
'case.scalar.Pe') .and. &
579 (params%valid_path(
'case.scalar.lambda') .or. &
580 params%valid_path(
'case.scalar.cp')))
then
581 call neko_error(
"To set the material properties for the scalar, " // &
582 "either provide Pe OR lambda and cp in the case file.")
584 else if (params%valid_path(
'case.scalar.Pe'))
then
585 write(log_buf,
'(A)')
'Non-dimensional scalar material properties' //&
587 call neko_log%message(log_buf, lvl = neko_log_verbose)
588 write(log_buf,
'(A)')
'Specific heat capacity will be set to 1,'
589 call neko_log%message(log_buf, lvl = neko_log_verbose)
590 write(log_buf,
'(A)')
'conductivity to 1/Pe. Assumes density is 1.'
591 call neko_log%message(log_buf, lvl = neko_log_verbose)
594 call json_get(params,
'case.scalar.Pe', const_lambda)
595 write(log_buf,
'(A,ES13.6)')
'Pe :', const_lambda
596 call neko_log%message(log_buf)
601 const_lambda = 1.0_rp/const_lambda
604 call json_get(params,
'case.scalar.lambda', const_lambda)
605 call json_get(params,
'case.scalar.cp', const_cp)
610 if (
associated(user%material_properties, dummy_mp_ptr))
then
612 call field_cfill(this%lambda, const_lambda)
613 call field_cfill(this%cp, const_cp)
615 write(log_buf,
'(A,ES13.6)')
'lambda :', const_lambda
616 call neko_log%message(log_buf)
617 write(log_buf,
'(A,ES13.6)')
'cp :', const_cp
618 call neko_log%message(log_buf)
625 if (neko_bcknd_device .eq. 1)
then
626 call device_memcpy(this%cp%x, this%cp%x_d, this%cp%size(), &
627 device_to_host, sync=.false.)