37 use,
intrinsic :: iso_fortran_env, only: error_unit
38 use coefs,
only: coef_t
39 use symmetry_aligned,
only: symmetry_aligned_t
40 use registry,
only: neko_registry
41 use logger,
only: neko_log, log_size, neko_log_debug
42 use num_types,
only: rp, dp
43 use krylov,
only: ksp_monitor_t
46 adjoint_pnpn_vel_res_factory
47 use rhs_maker,
only: rhs_maker_sumab_t, rhs_maker_bdf_t, rhs_maker_ext_t, &
48 rhs_maker_oifs_t, rhs_maker_sumab_fctry, rhs_maker_bdf_fctry, &
49 rhs_maker_ext_fctry, rhs_maker_oifs_fctry
52 use device_mathops,
only: device_opadd2cm
53 use fluid_aux,
only: fluid_step_info
54 use scratch_registry,
only: neko_scratch_registry
55 use projection,
only: projection_t
56 use projection_vel,
only: projection_vel_t
57 use device,
only: device_memcpy, host_to_device, device_event_sync, &
60 use profiler,
only: profiler_start_region, profiler_end_region
61 use json_module,
only: json_file, json_core, json_value
62 use json_utils,
only: json_get, json_get_or_default, json_extract_item
63 use ax_product,
only: ax_t, ax_helm_allocator
64 use field,
only: field_t
65 use dirichlet,
only: dirichlet_t
66 use shear_stress,
only: shear_stress_t
67 use wall_model_bc,
only: wall_model_bc_t
68 use facet_normal,
only: facet_normal_t
69 use non_normal_aligned,
only: non_normal_aligned_t
70 use checkpoint,
only: chkp_t
71 use checkpoint_payload,
only : checkpoint_payload_t
72 use mesh,
only: mesh_t
73 use user_intf,
only: user_t
74 use time_step_controller,
only: time_step_controller_t
75 use gs_ops,
only: gs_op_add
76 use neko_config,
only: neko_bcknd_device
77 use mathops,
only: opadd2cm
78 use scalar_bc_projector,
only: scalar_bc_projector_t
79 use vector_bc_projector,
only: vector_bc_projector_t, &
80 segregated_vector_bc_projector_t
81 use zero_dirichlet,
only: zero_dirichlet_t
82 use utils,
only: neko_error
83 use field_math,
only: field_add2, field_copy, &
85 use bc,
only: bc_t, bc_dirichlet
86 use file,
only: file_t
87 use operators,
only: ortho
88 use opr_device,
only: device_ortho
89 use inflow,
only: inflow_t
90 use field_dirichlet,
only: field_dirichlet_t
91 use blasius,
only: blasius_t
92 use field_dirichlet_vector,
only: field_dirichlet_vector_t
93 use dong_outflow,
only: dong_outflow_t
94 use time_state,
only: time_state_t
95 use vector,
only: vector_t
96 use device_math,
only: device_vlsc3, device_cmult, device_col2
97 use math,
only: vlsc3, cmult, col2
98 use,
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr, c_associated
99 use comm,
only: neko_comm, mpi_real_precision
100 use mpi_f08,
only: mpi_sum, mpi_max, mpi_allreduce, mpi_integer, &
102 use operators,
only : opgrad, curl, grad
112 type(field_t) :: p_res, u_res, v_res, w_res
116 type(field_t) :: dp, du, dv, dw
123 class(ax_t),
allocatable :: ax_vel
125 class(ax_t),
allocatable :: ax_prs
132 type(projection_t) :: proj_prs
133 type(projection_vel_t) :: proj_vel
140 type(facet_normal_t) :: bc_prs_surface
143 type(facet_normal_t) :: bc_sym_surface
153 class(vector_bc_projector_t),
allocatable :: bcs_vel_projector
155 type(scalar_bc_projector_t) :: bcs_prs_projector
160 logical :: prs_dirichlet = .false.
170 type(field_t) :: abx1, aby1, abz1
171 type(field_t) :: abx2, aby2, abz2
174 type(field_t) :: advx, advy, advz
183 class(rhs_maker_sumab_t),
allocatable :: sumab
186 class(rhs_maker_ext_t),
allocatable :: makeabf
189 class(rhs_maker_bdf_t),
allocatable :: makebdf
192 class(rhs_maker_oifs_t),
allocatable :: makeoifs
198 logical :: full_stress_formulation = .false.
203 real(kind=rp) :: norm_scaling
204 real(kind=rp) :: norm_target
205 real(kind=rp) :: norm_tolerance
211 real(kind=rp) :: norm_l2_base
214 real(kind=rp) :: norm_l2_upper
216 real(kind=rp) :: norm_l2_lower
219 type(file_t) :: file_output
223 procedure, pass(this) :: init => adjoint_fluid_pnpn_init
225 procedure, pass(this) :: free => adjoint_fluid_pnpn_free
227 procedure, pass(this) :: step => adjoint_fluid_pnpn_step
229 procedure, pass(this) :: restart => adjoint_fluid_pnpn_restart
231 procedure, pass(this) :: setup_bcs => adjoint_fluid_pnpn_setup_bcs
233 procedure, pass(this) :: write_boundary_conditions => &
234 adjoint_fluid_pnpn_write_boundary_conditions
237 procedure,
public, pass(this) :: pw_compute_ => power_iterations_compute
249 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
250 class(bc_t),
pointer,
intent(inout) :: object
251 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
252 type(json_file),
intent(inout) :: json
253 type(coef_t),
target,
intent(in) :: coef
254 type(user_t),
target,
intent(in) :: user
255 end subroutine pressure_bc_factory
256 end interface pressure_bc_factory
265 interface velocity_bc_factory
266 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
267 class(bc_t),
pointer,
intent(inout) :: object
268 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
269 type(json_file),
intent(inout) :: json
270 type(coef_t),
target,
intent(in) :: coef
271 type(user_t),
target,
intent(in) :: user
272 end subroutine velocity_bc_factory
273 end interface velocity_bc_factory
277 subroutine adjoint_fluid_pnpn_init(this, msh, lx, params, user, chkp)
278 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
279 type(mesh_t),
target,
intent(inout) :: msh
280 integer,
intent(in) :: lx
281 type(json_file),
target,
intent(inout) :: params
282 type(user_t),
target,
intent(in) :: user
283 type(chkp_t),
target,
intent(inout) :: chkp
284 character(len=15),
parameter :: scheme =
'Adjoint (Pn/Pn)'
285 real(kind=rp) :: abs_tol
286 character(len=LOG_SIZE) :: log_buf
287 integer :: integer_val, solver_maxiter
288 character(len=:),
allocatable :: solver_type, precon_type
289 logical :: monitor, found
291 type(json_file) :: numerics_params, precon_params
292 type(checkpoint_payload_t),
pointer :: payload
293 real(kind=dp),
pointer :: tlag(:), dtlag(:)
296 character(len=:),
allocatable :: file_name
297 character(len=256) :: header_line
302 call this%init_base(msh, lx, params, scheme, user, .true.)
306 call neko_registry%add_field(this%dm_Xh,
'p_adj')
307 this%p_adj => neko_registry%get_field(
'p_adj')
313 call json_get(params,
'case.numerics.time_order', integer_val)
314 allocate(this%ext_bdf)
315 call this%ext_bdf%init(integer_val)
317 call json_get_or_default(params,
"case.fluid.full_stress_formulation", &
318 this%full_stress_formulation, .false.)
320 if (this%full_stress_formulation .eqv. .true.)
then
322 "Full stress formulation is not supported in the adjoint module.")
333 call ax_helm_allocator(this%Ax_vel, type_name =
"standard")
336 call adjoint_pnpn_prs_res_factory(this%prs_res)
339 call adjoint_pnpn_vel_res_factory(this%vel_res)
342 if (params%valid_path(
'case.fluid.nut_field'))
then
343 if (this%full_stress_formulation .eqv. .false.)
then
344 call neko_error(
"You need to set full_stress_formulation to " // &
345 "true for the fluid to have a spatially varying " // &
348 call json_get(params,
'case.fluid.nut_field', this%nut_field_name)
350 this%nut_field_name =
""
354 call ax_helm_allocator(this%Ax_prs, type_name =
"standard")
358 call rhs_maker_sumab_fctry(this%sumab)
361 call rhs_maker_ext_fctry(this%makeabf)
364 call rhs_maker_bdf_fctry(this%makebdf)
367 call rhs_maker_oifs_fctry(this%makeoifs)
370 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
371 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
373 call this%p_res%init(dm_xh,
"p_res")
374 call this%u_res%init(dm_xh,
"u_res")
375 call this%v_res%init(dm_xh,
"v_res")
376 call this%w_res%init(dm_xh,
"w_res")
377 call this%abx1%init(dm_xh,
"abx1")
378 call this%aby1%init(dm_xh,
"aby1")
379 call this%abz1%init(dm_xh,
"abz1")
380 call this%abx2%init(dm_xh,
"abx2")
381 call this%aby2%init(dm_xh,
"aby2")
382 call this%abz2%init(dm_xh,
"abz2")
383 call this%advx%init(dm_xh,
"advx")
384 call this%advy%init(dm_xh,
"advy")
385 call this%advz%init(dm_xh,
"advz")
388 call this%du%init(this%dm_Xh,
'du')
389 call this%dv%init(this%dm_Xh,
'dv')
390 call this%dw%init(this%dm_Xh,
'dw')
391 call this%dp%init(this%dm_Xh,
'dp')
394 call this%setup_bcs(user, params)
397 call json_get_or_default(params,
'case.output_boundary', found, .false.)
398 if (found)
call this%write_boundary_conditions()
400 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
401 this%pr_projection_activ_step)
403 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
404 this%vel_projection_activ_step)
407 call json_get_or_default(params,
'case.numerics.oifs', this%oifs, .false.)
408 if (params%valid_path(
'case.fluid.flow_rate_force'))
then
409 call neko_error(
"Flow rate forcing not available for adjoint_fluid_pnpn")
413 call neko_log%section(
"Pressure solver")
415 call json_get_or_default(params, &
416 'case.fluid.pressure_solver.max_iterations', &
418 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
419 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
421 call json_get(params, &
422 'case.fluid.pressure_solver.preconditioner', precon_params)
423 call json_get(params,
'case.fluid.pressure_solver.absolute_tolerance', &
425 call json_get_or_default(params,
'case.fluid.pressure_solver.monitor', &
427 call neko_log%message(
'Type : ('// trim(solver_type) // &
428 ', ' // trim(precon_type) //
')')
429 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
430 call neko_log%message(log_buf)
432 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
433 solver_type, solver_maxiter, abs_tol, monitor)
434 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
435 this%c_Xh, this%dm_Xh, this%gs_Xh, this%bcs_prs, &
436 precon_type, precon_params)
437 call neko_log%end_section()
440 call neko_log%section(
"Advection factory")
441 call json_get_or_default(params,
'case.fluid.advection', advection, .true.)
442 call json_get(params,
'case.numerics', numerics_params)
443 call chkp%get_time_history(tlag, dtlag)
444 call advection_adjoint_factory(this%adv, numerics_params, this%c_Xh, &
445 this%ulag, this%vlag, this%wlag, &
446 dtlag, tlag, this%ext_bdf, &
451 payload => this%chkp%add_payload(
"adjoint_fluid")
452 call payload%add_field(this%u_adj)
453 call payload%add_field(this%v_adj)
454 call payload%add_field(this%w_adj)
455 call payload%add_field(this%p_adj)
456 call payload%add_field(this%abx1)
457 call payload%add_field(this%abx2)
458 call payload%add_field(this%aby1)
459 call payload%add_field(this%aby2)
460 call payload%add_field(this%abz1)
461 call payload%add_field(this%abz2)
462 call payload%add_series(this%ulag)
463 call payload%add_series(this%vlag)
464 call payload%add_series(this%wlag)
466 call neko_log%end_section()
472 call json_get_or_default(params,
'norm_scaling', &
473 this%norm_scaling, 0.5_rp)
481 this%u_b => neko_registry%get_field(
'u')
482 this%v_b => neko_registry%get_field(
'v')
483 this%w_b => neko_registry%get_field(
'w')
484 this%p_b => neko_registry%get_field(
'p')
487 call json_get_or_default(params,
'norm_target', &
488 this%norm_target, -1.0_rp)
489 call json_get_or_default(params,
'norm_tolerance', &
490 this%norm_tolerance, 10.0_rp)
493 call json_get_or_default(params,
'output_file', &
494 file_name,
'power_iterations.csv')
495 call this%file_output%init(trim(file_name))
496 write(header_line,
'(A)')
'Time, Norm, Scaling'
497 call this%file_output%set_header(header_line)
499 end subroutine adjoint_fluid_pnpn_init
501 subroutine adjoint_fluid_pnpn_restart(this, chkp)
502 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
503 type(chkp_t),
intent(inout) :: chkp
506 n = this%u_adj%dof%size()
507 if (
allocated(this%chkp%previous_mesh%elements) .or. &
508 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
509 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
510 p => this%p_adj, c_xh => this%c_Xh, ulag => this%ulag, &
511 vlag => this%vlag, wlag => this%wlag)
512 call col2(u%x, c_xh%mult, n)
513 call col2(v%x, c_xh%mult, n)
514 call col2(w%x, c_xh%mult, n)
515 call col2(p%x, c_xh%mult, n)
516 do i = 1, this%ulag%size()
517 call col2(ulag%lf(i)%x, c_xh%mult, n)
518 call col2(vlag%lf(i)%x, c_xh%mult, n)
519 call col2(wlag%lf(i)%x, c_xh%mult, n)
524 if (neko_bcknd_device .eq. 1)
then
525 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
526 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
528 call device_memcpy(u%x, u%x_d, u%dof%size(), &
529 host_to_device, sync = .false.)
530 call device_memcpy(v%x, v%x_d, v%dof%size(), &
531 host_to_device, sync = .false.)
532 call device_memcpy(w%x, w%x_d, w%dof%size(), &
533 host_to_device, sync = .false.)
534 call device_memcpy(p%x, p%x_d, p%dof%size(), &
535 host_to_device, sync = .false.)
536 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
537 u%dof%size(), host_to_device, sync = .false.)
538 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
539 u%dof%size(), host_to_device, sync = .false.)
541 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
542 v%dof%size(), host_to_device, sync = .false.)
543 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
544 v%dof%size(), host_to_device, sync = .false.)
546 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
547 w%dof%size(), host_to_device, sync = .false.)
548 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
549 w%dof%size(), host_to_device, sync = .false.)
550 call device_memcpy(this%abx1%x, this%abx1%x_d, &
551 w%dof%size(), host_to_device, sync = .false.)
552 call device_memcpy(this%abx2%x, this%abx2%x_d, &
553 w%dof%size(), host_to_device, sync = .false.)
554 call device_memcpy(this%aby1%x, this%aby1%x_d, &
555 w%dof%size(), host_to_device, sync = .false.)
556 call device_memcpy(this%aby2%x, this%aby2%x_d, &
557 w%dof%size(), host_to_device, sync = .false.)
558 call device_memcpy(this%abz1%x, this%abz1%x_d, &
559 w%dof%size(), host_to_device, sync = .false.)
560 call device_memcpy(this%abz2%x, this%abz2%x_d, &
561 w%dof%size(), host_to_device, sync = .false.)
562 call device_memcpy(this%advx%x, this%advx%x_d, &
563 w%dof%size(), host_to_device, sync = .false.)
564 call device_memcpy(this%advy%x, this%advy%x_d, &
565 w%dof%size(), host_to_device, sync = .false.)
566 call device_memcpy(this%advz%x, this%advz%x_d, &
567 w%dof%size(), host_to_device, sync = .false.)
574 if (
allocated(this%chkp%previous_mesh%elements) &
575 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx)
then
576 call this%gs_Xh%op(this%u_adj, gs_op_add)
577 call this%gs_Xh%op(this%v_adj, gs_op_add)
578 call this%gs_Xh%op(this%w_adj, gs_op_add)
579 call this%gs_Xh%op(this%p_adj, gs_op_add)
581 do i = 1, this%ulag%size()
582 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
583 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
584 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
588 end subroutine adjoint_fluid_pnpn_restart
590 subroutine adjoint_fluid_pnpn_free(this)
591 class(adjoint_fluid_pnpn_t),
intent(inout) :: this
594 call this%scheme_free()
596 call this%bc_prs_surface%free()
597 call this%bc_sym_surface%free()
598 call this%bc_curl_curl%free()
599 if (
allocated(this%bcs_vel_projector))
then
600 call this%bcs_vel_projector%free()
601 deallocate(this%bcs_vel_projector)
603 call this%bcs_prs_projector%free()
604 call this%proj_prs%free()
605 call this%proj_vel%free()
607 call this%p_res%free()
608 call this%u_res%free()
609 call this%v_res%free()
610 call this%w_res%free()
617 call this%abx1%free()
618 call this%aby1%free()
619 call this%abz1%free()
621 call this%abx2%free()
622 call this%aby2%free()
623 call this%abz2%free()
625 call this%advx%free()
626 call this%advy%free()
627 call this%advz%free()
629 if (
allocated(this%Ax_vel))
then
630 deallocate(this%Ax_vel)
633 if (
allocated(this%Ax_prs))
then
634 deallocate(this%Ax_prs)
637 if (
allocated(this%prs_res))
then
638 deallocate(this%prs_res)
641 if (
allocated(this%vel_res))
then
642 deallocate(this%vel_res)
645 if (
allocated(this%sumab))
then
646 deallocate(this%sumab)
649 if (
allocated(this%makeabf))
then
650 deallocate(this%makeabf)
653 if (
allocated(this%makebdf))
then
654 deallocate(this%makebdf)
657 if (
allocated(this%makeoifs))
then
658 deallocate(this%makeoifs)
661 if (
allocated(this%ext_bdf))
then
662 deallocate(this%ext_bdf)
667 end subroutine adjoint_fluid_pnpn_free
673 subroutine adjoint_fluid_pnpn_step(this, time, dt_controller)
674 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
675 type(time_state_t),
intent(in) :: time
676 type(time_step_controller_t),
intent(in) :: dt_controller
680 type(ksp_monitor_t) :: ksp_results(4)
681 type(field_t),
pointer :: dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, &
683 integer :: temp_indices(3)
684 integer :: cc_indices(8)
685 real(kind=rp) :: rho_val, mu_val
687 if (this%freeze)
return
689 n = this%dm_Xh%size()
691 call profiler_start_region(
'Adjoint')
692 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
694 u_e => this%u_adj_e, v_e => this%v_adj_e, w_e => this%w_adj_e, &
695 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
696 u_b => this%u_b, v_b => this%v_b, w_b => this%w_b, &
697 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
698 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
700 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
701 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
702 msh => this%msh, prs_res => this%prs_res, &
703 source_term => this%source_term, vel_res => this%vel_res, &
704 sumab => this%sumab, &
705 makeabf => this%makeabf, makebdf => this%makebdf, &
706 vel_projection_dim => this%vel_projection_dim, &
707 pr_projection_dim => this%pr_projection_dim, &
709 rho => this%rho, mu => this%mu, &
710 f_x => this%f_adj_x, f_y => this%f_adj_y, f_z => this%f_adj_z, &
711 t => time%t, tstep => time%tstep, dt => time%dt, &
712 ext_bdf => this%ext_bdf, event => glb_cmd_event)
715 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
716 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
719 call this%source_term%compute(time)
722 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
723 this%dm_Xh%size(), time, strong = .false.)
726 call neko_error(
"OIFS not implemented for adjoint")
730 call this%adv%compute_adjoint(u, v, w, u_b, v_b, w_b, &
732 xh, this%c_Xh, dm_xh%size())
738 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
739 this%abx2, this%aby2, this%abz2, &
740 f_x%x, f_y%x, f_z%x, &
741 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
744 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
745 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), dt, &
746 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
753 call this%bc_apply_vel(time, strong = .true.)
754 call this%bc_apply_prs(time)
757 call neko_scratch_registry%request_field(dx_p_adj, cc_indices(1), .false.)
758 call neko_scratch_registry%request_field(dy_p_adj, cc_indices(2), .false.)
759 call neko_scratch_registry%request_field(dz_p_adj, cc_indices(3), .false.)
762 call neko_scratch_registry%request_field(nx1, cc_indices(4), .true.)
763 call neko_scratch_registry%request_field(nx2, cc_indices(5), .true.)
764 call neko_scratch_registry%request_field(nx3, cc_indices(6), .true.)
766 call neko_scratch_registry%request_field(work1, cc_indices(7), .false.)
767 call neko_scratch_registry%request_field(work2, cc_indices(8), .false.)
770 call grad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
773 call this%bc_curl_curl%apply_n_cross(nx1%x, nx2%x, nx3%x, dx_p_adj%x, &
774 dy_p_adj%x, dz_p_adj%x, dx_p_adj%size())
779 call curl(dx_p_adj, dy_p_adj, dz_p_adj, nx1, nx2, nx3, work1, work2, c_xh)
782 call gs_xh%op(dx_p_adj, gs_op_add, event)
783 call device_event_sync(event)
784 call gs_xh%op(dy_p_adj, gs_op_add, event)
785 call device_event_sync(event)
786 call gs_xh%op(dz_p_adj, gs_op_add, event)
787 call device_event_sync(event)
790 if (neko_bcknd_device .eq. 1)
then
791 call device_col2(dx_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
792 call device_col2(dy_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
793 call device_col2(dz_p_adj%x_d, c_xh%mult_d, dx_p_adj%size())
795 call col2(dx_p_adj%x, c_xh%mult, dx_p_adj%size())
796 call col2(dy_p_adj%x, c_xh%mult, dx_p_adj%size())
797 call col2(dz_p_adj%x, c_xh%mult, dx_p_adj%size())
800 rho_val = rho%x(1,1,1,1)
801 mu_val = mu%x(1,1,1,1)
802 call field_add2s2(f_x, dx_p_adj, -mu_val / rho_val)
803 call field_add2s2(f_y, dy_p_adj, -mu_val / rho_val)
804 call field_add2s2(f_z, dz_p_adj, -mu_val / rho_val)
806 call neko_scratch_registry%relinquish_field(cc_indices)
809 call this%update_material_properties(time)
813 call profiler_start_region(
'Adjoint_velocity_residual')
815 call vel_res%compute(ax_vel, u, v, w, &
816 u_res, v_res, w_res, &
820 mu, rho, ext_bdf%diffusion_coeffs%x(1), &
823 call gs_xh%op(u_res, gs_op_add, event)
824 call device_event_sync(event)
825 call gs_xh%op(v_res, gs_op_add, event)
826 call device_event_sync(event)
827 call gs_xh%op(w_res, gs_op_add, event)
828 call device_event_sync(event)
831 call this%bcs_vel_projector%apply(u_res%x, v_res%x, w_res%x, n)
833 call profiler_end_region(
'Adjoint_velocity_residual')
835 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
836 tstep, c_xh, n, dt_controller,
'Velocity')
838 call this%pc_vel%update()
840 call profiler_start_region(
"Adjoint_velocity_solve")
841 ksp_results(1:3) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
842 u_res%x, v_res%x, w_res%x, n, c_xh, &
843 this%bcs_vel_projector, gs_xh, &
844 this%ksp_vel%max_iter)
846 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
847 this%bcs_vel_projector, gs_xh, n, tstep, &
850 if (neko_bcknd_device .eq. 1)
then
851 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
852 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
854 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
856 call profiler_end_region(
"Adjoint_velocity_solve")
862 call field_copy(f_x, u)
863 call field_copy(f_y, v)
864 call field_copy(f_z, w)
866 call profiler_start_region(
'Adjoint_pressure_residual')
868 call prs_res%compute(p, p_res, &
872 this%bc_prs_surface, this%bc_sym_surface, &
873 ax_prs, ext_bdf%diffusion_coeffs%x(1), dt, &
877 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
878 call device_ortho(p_res%x_d, this%glb_n_points, n)
879 else if (.not. this%prs_dirichlet)
then
880 call ortho(p_res%x, this%glb_n_points, n)
883 call gs_xh%op(p_res, gs_op_add, event)
884 call device_event_sync(event)
887 call this%bcs_prs_projector%apply(p_res%x, p%dof%size())
890 call profiler_end_region(
'Adjoint_pressure_residual')
893 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
896 call this%pc_prs%update()
898 call profiler_start_region(
'Adjoint_pressure_solve')
902 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
903 this%bcs_prs_projector, gs_xh)
906 call profiler_end_region(
'Adjoint_pressure_solve')
908 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
909 this%bcs_prs_projector, gs_xh, n, tstep, dt_controller)
912 call field_add2(p, dp, n)
913 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
914 call device_ortho(p%x_d, this%glb_n_points, n)
915 else if (.not. this%prs_dirichlet)
then
916 call ortho(p%x, this%glb_n_points, n)
919 ksp_results(4)%name =
'Adjoint Pressure'
920 ksp_results(1)%name =
'Adjoint Velocity U'
921 ksp_results(2)%name =
'Adjoint Velocity V'
922 ksp_results(3)%name =
'Adjoint Velocity W'
924 if (this%forced_flow_rate)
then
925 call neko_error(
'Forced flow rate is not implemented for the adjoint')
931 call neko_scratch_registry%request_field(dx_p_adj, temp_indices(1), &
933 call neko_scratch_registry%request_field(dy_p_adj, temp_indices(2), &
935 call neko_scratch_registry%request_field(dz_p_adj, temp_indices(3), &
939 call opgrad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
942 call gs_xh%op(dx_p_adj, gs_op_add, event)
943 call device_event_sync(event)
944 call gs_xh%op(dy_p_adj, gs_op_add, event)
945 call device_event_sync(event)
946 call gs_xh%op(dz_p_adj, gs_op_add, event)
947 call device_event_sync(event)
950 if (neko_bcknd_device .eq. 1)
then
951 call device_col2(dx_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
952 call device_col2(dy_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
953 call device_col2(dz_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
957 call col2(dx_p_adj%x, c_xh%Binv, dx_p_adj%size())
958 call col2(dy_p_adj%x, c_xh%Binv, dx_p_adj%size())
959 call col2(dz_p_adj%x, c_xh%Binv, dx_p_adj%size())
962 if (neko_bcknd_device .eq. 1)
then
963 call device_opadd2cm(u%x_d, v%x_d, w%x_d, dx_p_adj%x_d, &
964 dy_p_adj%x_d, dz_p_adj%x_d, -1.0_rp, n, msh%gdim)
966 call opadd2cm(u%x, v%x, w%x, dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, &
967 -1.0_rp, n, msh%gdim)
970 call neko_scratch_registry%relinquish_field(temp_indices)
973 call fluid_step_info(time, ksp_results, &
974 this%full_stress_formulation, this%strict_convergence)
977 call profiler_end_region(
'Adjoint')
979 end subroutine adjoint_fluid_pnpn_step
985 subroutine adjoint_fluid_pnpn_setup_bcs(this, user, params)
986 use mpi_f08,
only: mpi_in_place
987 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
988 type(user_t),
target,
intent(in) :: user
989 type(json_file),
intent(inout) :: params
990 integer :: i, n_bcs, j, zone_size, global_zone_size, ierr
991 class(bc_t),
pointer :: bc_i
992 type(json_core) :: core
993 type(json_value),
pointer :: bc_object
994 type(json_file) :: bc_subdict
997 logical,
allocatable :: marked_zones(:)
998 integer,
allocatable :: zone_indices(:)
999 character(len=:),
allocatable :: json_key
1003 allocate(segregated_vector_bc_projector_t :: this%bcs_vel_projector)
1004 call this%bcs_vel_projector%init(this%c_Xh)
1007 call this%bc_prs_surface%init_from_components(this%c_Xh)
1008 call this%bc_sym_surface%init_from_components(this%c_Xh)
1009 call this%bc_curl_curl%init_from_components(this%c_Xh)
1011 json_key =
'case.adjoint_fluid.boundary_conditions'
1014 if (params%valid_path(json_key))
then
1015 call params%info(json_key, n_children = n_bcs)
1016 call params%get_core(core)
1017 call params%get(json_key, bc_object, found)
1022 call this%bcs_vel%init(n_bcs)
1024 allocate(marked_zones(
size(this%msh%labeled_zones)))
1025 marked_zones = .false.
1029 call json_extract_item(core, bc_object, i, bc_subdict)
1031 call json_get(bc_subdict,
"zone_indices", zone_indices)
1036 do j = 1,
size(zone_indices)
1037 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1038 call mpi_allreduce(zone_size, global_zone_size, 1, &
1039 mpi_integer, mpi_max, neko_comm, ierr)
1041 if (global_zone_size .eq. 0)
then
1042 write(error_unit,
'(A, A, I0, A, A, I0, A)')
"*** ERROR ***: ",&
1043 "Zone index ", zone_indices(j), &
1044 " is invalid as this zone has 0 size, meaning it does ", &
1045 "not in the mesh. Check adjoint boundary condition ", &
1050 if (marked_zones(zone_indices(j)) .eqv. .true.)
then
1051 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
1052 "Zone with index ", zone_indices(j), &
1053 " has already been assigned a boundary condition. ", &
1054 "Please check your boundary_conditions entry for the ", &
1055 "adjoint and make sure that each zone index appears ", &
1056 "only in a single boundary condition."
1059 marked_zones(zone_indices(j)) = .true.
1064 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1068 if (
associated(bc_i))
then
1073 type is (symmetry_aligned_t)
1078 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1079 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1080 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1081 call this%bcs_vel%append(bc_i)
1082 call this%bc_sym_surface%mark_facets(bc_i%marked_facet)
1083 type is (non_normal_aligned_t)
1090 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1091 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1092 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1093 type is (shear_stress_t)
1094 call neko_error(
"The shear_stress boundary condition " // &
1095 "requires the full stress formulation, which the " // &
1096 "adjoint scheme does not support.")
1097 type is (wall_model_bc_t)
1098 call neko_error(
"The wall_model boundary condition " // &
1099 "requires the full stress formulation, which the " // &
1100 "adjoint scheme does not support.")
1105 if (bc_i%bc_type .eq. bc_dirichlet)
then
1106 call this%bc_prs_surface%mark_labeled_zones( &
1108 call this%bcs_vel_projector%mark(bc_i, component =
'x')
1109 call this%bcs_vel_projector%mark(bc_i, component =
'y')
1110 call this%bcs_vel_projector%mark(bc_i, component =
'z')
1114 call this%bc_curl_curl%mark_facets(bc_i%marked_facet)
1116 call this%bcs_vel%append(bc_i)
1122 do i = 1,
size(this%msh%labeled_zones)
1123 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1124 (marked_zones(i) .eqv. .false.))
then
1125 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
1126 "No adjoint boundary condition assigned to zone ", i
1134 call this%bcs_prs%init(n_bcs)
1138 call json_extract_item(core, bc_object, i, bc_subdict)
1140 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1144 if (
associated(bc_i))
then
1145 call this%bcs_prs%append(bc_i)
1148 if (bc_i%bc_type .eq. bc_dirichlet)
then
1149 call this%bcs_prs_projector%mark(bc_i)
1157 do i = 1,
size(this%msh%labeled_zones)
1158 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1159 call neko_error(
"No boundary_conditions entry in the case file!")
1163 call this%bcs_vel%init()
1164 call this%bcs_prs%init()
1168 call this%bc_prs_surface%finalize()
1169 call this%bc_sym_surface%finalize()
1170 call this%bc_curl_curl%finalize()
1171 call this%bcs_vel_projector%finalize(rebuild_mask = .true.)
1174 this%prs_dirichlet = this%bcs_prs_projector%dof_mask%is_set()
1175 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1176 mpi_logical, mpi_lor, neko_comm)
1178 end subroutine adjoint_fluid_pnpn_setup_bcs
1181 subroutine adjoint_fluid_pnpn_write_boundary_conditions(this)
1182 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1183 type(dirichlet_t) :: bdry_mask
1184 type(field_t),
pointer :: bdry_field
1185 type(file_t) :: bdry_file
1186 integer :: temp_index, i
1187 class(bc_t),
pointer :: bci
1188 character(len=LOG_SIZE) :: log_buf
1190 call neko_log%section(
"Adjoint boundary conditions")
1191 write(log_buf,
'(A)') &
1192 'Marking using integer keys in boundary_adjoint0.f00000'
1193 call neko_log%message(log_buf)
1194 write(log_buf,
'(A)')
'Condition-value pairs: '
1195 call neko_log%message(log_buf)
1196 write(log_buf,
'(A)')
' no_slip = 1'
1197 call neko_log%message(log_buf)
1198 write(log_buf,
'(A)')
' velocity_value = 2'
1199 call neko_log%message(log_buf)
1200 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1201 call neko_log%message(log_buf)
1202 write(log_buf,
'(A)')
' symmetry = 4'
1203 call neko_log%message(log_buf)
1204 write(log_buf,
'(A)')
' user_velocity_pointwise = 5'
1205 call neko_log%message(log_buf)
1206 write(log_buf,
'(A)')
' periodic = 6'
1207 call neko_log%message(log_buf)
1208 write(log_buf,
'(A)')
' user_velocity = 7'
1209 call neko_log%message(log_buf)
1210 write(log_buf,
'(A)')
' user_pressure = 8'
1211 call neko_log%message(log_buf)
1212 write(log_buf,
'(A)')
' shear_stress = 9'
1213 call neko_log%message(log_buf)
1214 write(log_buf,
'(A)')
' wall_modelling = 10'
1215 call neko_log%message(log_buf)
1216 write(log_buf,
'(A)')
' blasius_profile = 11'
1217 call neko_log%message(log_buf)
1218 call neko_log%end_section()
1220 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1224 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1225 call bdry_mask%mark_zone(this%msh%periodic)
1226 call bdry_mask%finalize()
1227 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1228 call bdry_mask%free()
1230 do i = 1, this%bcs_prs%size()
1231 bci => this%bcs_prs%get(i)
1232 select type (bc => bci)
1233 type is (zero_dirichlet_t)
1234 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1235 call bdry_mask%mark_facets(bci%marked_facet)
1236 call bdry_mask%finalize()
1237 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1238 call bdry_mask%free()
1239 type is (dong_outflow_t)
1240 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1241 call bdry_mask%mark_facets(bci%marked_facet)
1242 call bdry_mask%finalize()
1243 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1244 call bdry_mask%free()
1245 type is (field_dirichlet_t)
1246 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1247 call bdry_mask%mark_facets(bci%marked_facet)
1248 call bdry_mask%finalize()
1249 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1250 call bdry_mask%free()
1254 do i = 1, this%bcs_vel%size()
1255 bci => this%bcs_vel%get(i)
1256 select type (bc => bci)
1257 type is (zero_dirichlet_t)
1258 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1259 call bdry_mask%mark_facets(bci%marked_facet)
1260 call bdry_mask%finalize()
1261 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1262 call bdry_mask%free()
1264 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1265 call bdry_mask%mark_facets(bci%marked_facet)
1266 call bdry_mask%finalize()
1267 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1268 call bdry_mask%free()
1269 type is (symmetry_aligned_t)
1270 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1271 call bdry_mask%mark_facets(bci%marked_facet)
1272 call bdry_mask%finalize()
1273 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1274 call bdry_mask%free()
1275 type is (field_dirichlet_vector_t)
1276 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1277 call bdry_mask%mark_facets(bci%marked_facet)
1278 call bdry_mask%finalize()
1279 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1280 call bdry_mask%free()
1281 type is (shear_stress_t)
1282 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1283 call bdry_mask%mark_facets(bci%marked_facet)
1284 call bdry_mask%finalize()
1285 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1286 call bdry_mask%free()
1287 type is (wall_model_bc_t)
1288 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1289 call bdry_mask%mark_facets(bci%marked_facet)
1290 call bdry_mask%finalize()
1291 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1292 call bdry_mask%free()
1294 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1295 call bdry_mask%mark_facets(bci%marked_facet)
1296 call bdry_mask%finalize()
1297 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1298 call bdry_mask%free()
1303 call bdry_file%init(
'boundary_adjoint.fld')
1304 call bdry_file%write(bdry_field)
1306 call neko_scratch_registry%relinquish_field(temp_index)
1307 end subroutine adjoint_fluid_pnpn_write_boundary_conditions
1312 subroutine rescale_fluid(fluid_data, scale)
1314 class(adjoint_fluid_pnpn_t),
intent(inout) :: fluid_data
1316 real(kind=rp),
intent(in) :: scale
1322 if (neko_bcknd_device .eq. 1)
then
1323 call device_cmult(fluid_data%u_adj%x_d, scale, fluid_data%u_adj%size())
1324 call device_cmult(fluid_data%v_adj%x_d, scale, fluid_data%v_adj%size())
1325 call device_cmult(fluid_data%w_adj%x_d, scale, fluid_data%w_adj%size())
1327 call cmult(fluid_data%u_adj%x, scale, fluid_data%u_adj%size())
1328 call cmult(fluid_data%v_adj%x, scale, fluid_data%v_adj%size())
1329 call cmult(fluid_data%w_adj%x, scale, fluid_data%w_adj%size())
1333 if (neko_bcknd_device .eq. 1)
then
1334 call device_cmult(fluid_data%f_adj_x%x_d, scale, &
1335 fluid_data%f_adj_x%size())
1336 call device_cmult(fluid_data%f_adj_y%x_d, scale, &
1337 fluid_data%f_adj_y%size())
1338 call device_cmult(fluid_data%f_adj_z%x_d, scale, &
1339 fluid_data%f_adj_z%size())
1342 call device_cmult(fluid_data%abx1%x_d, scale, fluid_data%abx1%size())
1343 call device_cmult(fluid_data%aby1%x_d, scale, fluid_data%aby1%size())
1344 call device_cmult(fluid_data%abz1%x_d, scale, fluid_data%abz1%size())
1345 call device_cmult(fluid_data%abx2%x_d, scale, fluid_data%abx2%size())
1346 call device_cmult(fluid_data%aby2%x_d, scale, fluid_data%aby2%size())
1347 call device_cmult(fluid_data%abz2%x_d, scale, fluid_data%abz2%size())
1350 call cmult(fluid_data%f_adj_x%x, scale, fluid_data%f_adj_x%size())
1351 call cmult(fluid_data%f_adj_y%x, scale, fluid_data%f_adj_y%size())
1352 call cmult(fluid_data%f_adj_z%x, scale, fluid_data%f_adj_z%size())
1354 call cmult(fluid_data%abx1%x, scale, fluid_data%abx1%size())
1355 call cmult(fluid_data%aby1%x, scale, fluid_data%aby1%size())
1356 call cmult(fluid_data%abz1%x, scale, fluid_data%abz1%size())
1358 call cmult(fluid_data%abx2%x, scale, fluid_data%abx2%size())
1359 call cmult(fluid_data%aby2%x, scale, fluid_data%aby2%size())
1360 call cmult(fluid_data%abz2%x, scale, fluid_data%abz2%size())
1364 if (neko_bcknd_device .eq. 1)
then
1365 do i = 1, fluid_data%ulag%size()
1366 call device_cmult(fluid_data%ulag%lf(i)%x_d, &
1367 scale, fluid_data%ulag%lf(i)%size())
1370 do i = 1, fluid_data%vlag%size()
1371 call device_cmult(fluid_data%vlag%lf(i)%x_d, &
1372 scale, fluid_data%vlag%lf(i)%size())
1375 do i = 1, fluid_data%wlag%size()
1376 call device_cmult(fluid_data%wlag%lf(i)%x_d, &
1377 scale, fluid_data%wlag%lf(i)%size())
1380 do i = 1, fluid_data%ulag%size()
1381 call cmult(fluid_data%ulag%lf(i)%x, &
1382 scale, fluid_data%ulag%lf(i)%size())
1385 do i = 1, fluid_data%vlag%size()
1386 call cmult(fluid_data%vlag%lf(i)%x, &
1387 scale, fluid_data%vlag%lf(i)%size())
1390 do i = 1, fluid_data%wlag%size()
1391 call cmult(fluid_data%wlag%lf(i)%x, &
1392 scale, fluid_data%wlag%lf(i)%size())
1396 end subroutine rescale_fluid
1398 function norm(x, y, z, B, volume, n)
1399 use mpi_f08,
only: mpi_in_place
1401 integer,
intent(in) :: n
1402 real(kind=rp),
dimension(n),
intent(in) :: x, y, z
1403 real(kind=rp),
dimension(n),
intent(in) :: b
1404 real(kind=rp),
intent(in) :: volume
1406 real(kind=rp) :: norm
1408 norm = vlsc3(x, x, b, n) + vlsc3(y, y, b, n) + vlsc3(z, z, b, n)
1410 call mpi_allreduce(mpi_in_place, norm, 1, &
1411 mpi_real_precision, mpi_sum, neko_comm)
1413 norm = sqrt(norm / volume)
1416 function device_norm(x_d, y_d, z_d, B_d, volume, n)
1417 use mpi_f08,
only: mpi_in_place
1419 type(c_ptr),
intent(in) :: x_d, y_d, z_d
1420 type(c_ptr),
intent(in) :: B_d
1421 real(kind=rp),
intent(in) :: volume
1422 integer,
intent(in) :: n
1424 real(kind=rp) :: device_norm
1426 device_norm = device_vlsc3(x_d, x_d, b_d, n) + &
1427 device_vlsc3(y_d, y_d, b_d, n) + &
1428 device_vlsc3(z_d, z_d, b_d, n)
1430 call mpi_allreduce(mpi_in_place, device_norm, 1, &
1431 mpi_real_precision, mpi_sum, neko_comm)
1433 device_norm = sqrt(device_norm / volume)
1435 end function device_norm
1441 subroutine power_iterations_compute(this, t, tstep)
1442 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1443 real(kind=rp),
intent(in) :: t
1444 integer,
intent(in) :: tstep
1447 real(kind=rp) :: scaling_factor
1448 real(kind=rp) :: norm_l2, norm_l2_base
1449 character(len=256) :: log_message
1450 type(vector_t) :: data_line
1453 n = this%c_Xh%dof%size()
1454 if (tstep .eq. 1)
then
1455 if (neko_bcknd_device .eq. 1)
then
1456 norm_l2_base = device_norm(this%u_adj%x_d, this%v_adj%x_d, &
1458 this%c_Xh%B_d, this%c_Xh%volume, n)
1460 norm_l2_base = this%norm_scaling * norm(this%u_adj%x, this%v_adj%x, &
1462 this%c_Xh%B, this%c_Xh%volume, n)
1464 if (this%norm_target .lt. 0.0_rp)
then
1465 this%norm_target = norm_l2_base
1468 this%norm_l2_upper = this%norm_tolerance * this%norm_target
1469 this%norm_l2_lower = this%norm_target / this%norm_tolerance
1474 if (neko_bcknd_device .eq. 1)
then
1475 norm_l2 = device_norm(this%u_adj%x_d, this%v_adj%x_d, this%w_adj%x_d, &
1476 this%c_Xh%B_d, this%c_Xh%volume, n)
1478 norm_l2 = norm(this%u_adj%x, this%v_adj%x, this%w_adj%x, &
1479 this%c_Xh%B, this%c_Xh%volume, n)
1481 norm_l2 = sqrt(this%norm_scaling) * norm_l2
1482 scaling_factor = 1.0_rp
1485 if (norm_l2 .gt. this%norm_l2_upper &
1486 .or. norm_l2 .lt. this%norm_l2_lower)
then
1487 scaling_factor = this%norm_target / norm_l2
1488 call rescale_fluid(this, scaling_factor)
1489 norm_l2 = this%norm_target
1491 if (tstep .eq. 1)
then
1492 scaling_factor = 1.0_rp
1498 call neko_log%section(
'Power Iterations')
1500 write (log_message,
'(A7,E20.14)')
'Norm: ', norm_l2
1501 call neko_log%message(log_message, lvl = neko_log_debug)
1502 write (log_message,
'(A7,E20.14)')
'Scaling: ', scaling_factor
1503 call neko_log%message(log_message, lvl = neko_log_debug)
1506 call data_line%init(2)
1507 data_line%x = [norm_l2, scaling_factor]
1508 call this%file_output%write(data_line, t)
1511 call neko_log%end_section(
'Power Iterations')
1512 end subroutine power_iterations_compute
Boundary condition factory for pressure.
Adjoint Pn/Pn formulation.
Subroutines to add advection terms to the RHS of a transport equation.
Base type of all fluid formulations.
Abstract type to compute pressure residual.
Abstract type to compute velocity residual.
Base abstract type for computing the advection operator.
Dirichlet condition in facet normal direction.