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
84 use bc,
only: bc_t, bc_dirichlet
85 use file,
only: file_t
86 use operators,
only: ortho
87 use opr_device,
only: device_ortho
88 use inflow,
only: inflow_t
89 use field_dirichlet,
only: field_dirichlet_t
90 use blasius,
only: blasius_t
91 use field_dirichlet_vector,
only: field_dirichlet_vector_t
92 use dong_outflow,
only: dong_outflow_t
93 use time_state,
only: time_state_t
94 use vector,
only: vector_t
95 use device_math,
only: device_vlsc3, device_cmult, device_col2
96 use math,
only: vlsc3, cmult, col2
97 use,
intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr, c_associated
98 use comm,
only: neko_comm, mpi_real_precision
99 use mpi_f08,
only: mpi_sum, mpi_max, mpi_allreduce, mpi_integer, &
101 use operators,
only : opgrad
111 type(field_t) :: p_res, u_res, v_res, w_res
115 type(field_t) :: dp, du, dv, dw
122 class(ax_t),
allocatable :: ax_vel
124 class(ax_t),
allocatable :: ax_prs
131 type(projection_t) :: proj_prs
132 type(projection_vel_t) :: proj_vel
139 type(facet_normal_t) :: bc_prs_surface
142 type(facet_normal_t) :: bc_sym_surface
149 class(vector_bc_projector_t),
allocatable :: bcs_vel_projector
151 type(scalar_bc_projector_t) :: bcs_prs_projector
156 logical :: prs_dirichlet = .false.
166 type(field_t) :: abx1, aby1, abz1
167 type(field_t) :: abx2, aby2, abz2
170 type(field_t) :: advx, advy, advz
179 class(rhs_maker_sumab_t),
allocatable :: sumab
182 class(rhs_maker_ext_t),
allocatable :: makeabf
185 class(rhs_maker_bdf_t),
allocatable :: makebdf
188 class(rhs_maker_oifs_t),
allocatable :: makeoifs
194 logical :: full_stress_formulation = .false.
199 real(kind=rp) :: norm_scaling
200 real(kind=rp) :: norm_target
201 real(kind=rp) :: norm_tolerance
207 real(kind=rp) :: norm_l2_base
210 real(kind=rp) :: norm_l2_upper
212 real(kind=rp) :: norm_l2_lower
215 type(file_t) :: file_output
219 procedure, pass(this) :: init => adjoint_fluid_pnpn_init
221 procedure, pass(this) :: free => adjoint_fluid_pnpn_free
223 procedure, pass(this) :: step => adjoint_fluid_pnpn_step
225 procedure, pass(this) :: restart => adjoint_fluid_pnpn_restart
227 procedure, pass(this) :: setup_bcs => adjoint_fluid_pnpn_setup_bcs
229 procedure, pass(this) :: write_boundary_conditions => &
230 adjoint_fluid_pnpn_write_boundary_conditions
233 procedure,
public, pass(this) :: pw_compute_ => power_iterations_compute
245 module subroutine pressure_bc_factory(object, scheme, json, coef, user)
246 class(bc_t),
pointer,
intent(inout) :: object
247 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
248 type(json_file),
intent(inout) :: json
249 type(coef_t),
target,
intent(in) :: coef
250 type(user_t),
target,
intent(in) :: user
251 end subroutine pressure_bc_factory
252 end interface pressure_bc_factory
261 interface velocity_bc_factory
262 module subroutine velocity_bc_factory(object, scheme, json, coef, user)
263 class(bc_t),
pointer,
intent(inout) :: object
264 type(adjoint_fluid_pnpn_t),
intent(in) :: scheme
265 type(json_file),
intent(inout) :: json
266 type(coef_t),
target,
intent(in) :: coef
267 type(user_t),
target,
intent(in) :: user
268 end subroutine velocity_bc_factory
269 end interface velocity_bc_factory
273 subroutine adjoint_fluid_pnpn_init(this, msh, lx, params, user, chkp)
274 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
275 type(mesh_t),
target,
intent(inout) :: msh
276 integer,
intent(in) :: lx
277 type(json_file),
target,
intent(inout) :: params
278 type(user_t),
target,
intent(in) :: user
279 type(chkp_t),
target,
intent(inout) :: chkp
280 character(len=15),
parameter :: scheme =
'Adjoint (Pn/Pn)'
281 real(kind=rp) :: abs_tol
282 character(len=LOG_SIZE) :: log_buf
283 integer :: integer_val, solver_maxiter
284 character(len=:),
allocatable :: solver_type, precon_type
285 logical :: monitor, found
287 type(json_file) :: numerics_params, precon_params
288 type(checkpoint_payload_t),
pointer :: payload
289 real(kind=dp),
pointer :: tlag(:), dtlag(:)
292 character(len=:),
allocatable :: file_name
293 character(len=256) :: header_line
298 call this%init_base(msh, lx, params, scheme, user, .true.)
302 call neko_registry%add_field(this%dm_Xh,
'p_adj')
303 this%p_adj => neko_registry%get_field(
'p_adj')
309 call json_get(params,
'case.numerics.time_order', integer_val)
310 allocate(this%ext_bdf)
311 call this%ext_bdf%init(integer_val)
313 call json_get_or_default(params,
"case.fluid.full_stress_formulation", &
314 this%full_stress_formulation, .false.)
316 if (this%full_stress_formulation .eqv. .true.)
then
318 "Full stress formulation is not supported in the adjoint module.")
329 call ax_helm_allocator(this%Ax_vel, type_name =
"standard")
332 call adjoint_pnpn_prs_res_factory(this%prs_res)
335 call adjoint_pnpn_vel_res_factory(this%vel_res)
338 if (params%valid_path(
'case.fluid.nut_field'))
then
339 if (this%full_stress_formulation .eqv. .false.)
then
340 call neko_error(
"You need to set full_stress_formulation to " // &
341 "true for the fluid to have a spatially varying " // &
344 call json_get(params,
'case.fluid.nut_field', this%nut_field_name)
346 this%nut_field_name =
""
350 call ax_helm_allocator(this%Ax_prs, type_name =
"standard")
354 call rhs_maker_sumab_fctry(this%sumab)
357 call rhs_maker_ext_fctry(this%makeabf)
360 call rhs_maker_bdf_fctry(this%makebdf)
363 call rhs_maker_oifs_fctry(this%makeoifs)
366 associate(xh_lx => this%Xh%lx, xh_ly => this%Xh%ly, xh_lz => this%Xh%lz, &
367 dm_xh => this%dm_Xh, nelv => this%msh%nelv)
369 call this%p_res%init(dm_xh,
"p_res")
370 call this%u_res%init(dm_xh,
"u_res")
371 call this%v_res%init(dm_xh,
"v_res")
372 call this%w_res%init(dm_xh,
"w_res")
373 call this%abx1%init(dm_xh,
"abx1")
374 call this%aby1%init(dm_xh,
"aby1")
375 call this%abz1%init(dm_xh,
"abz1")
376 call this%abx2%init(dm_xh,
"abx2")
377 call this%aby2%init(dm_xh,
"aby2")
378 call this%abz2%init(dm_xh,
"abz2")
379 call this%advx%init(dm_xh,
"advx")
380 call this%advy%init(dm_xh,
"advy")
381 call this%advz%init(dm_xh,
"advz")
384 call this%du%init(this%dm_Xh,
'du')
385 call this%dv%init(this%dm_Xh,
'dv')
386 call this%dw%init(this%dm_Xh,
'dw')
387 call this%dp%init(this%dm_Xh,
'dp')
390 call this%setup_bcs(user, params)
393 call json_get_or_default(params,
'case.output_boundary', found, .false.)
394 if (found)
call this%write_boundary_conditions()
396 call this%proj_prs%init(this%dm_Xh%size(), this%pr_projection_dim, &
397 this%pr_projection_activ_step)
399 call this%proj_vel%init(this%dm_Xh%size(), this%vel_projection_dim, &
400 this%vel_projection_activ_step)
403 call json_get_or_default(params,
'case.numerics.oifs', this%oifs, .false.)
404 if (params%valid_path(
'case.fluid.flow_rate_force'))
then
405 call neko_error(
"Flow rate forcing not available for adjoint_fluid_pnpn")
409 call neko_log%section(
"Pressure solver")
411 call json_get_or_default(params, &
412 'case.fluid.pressure_solver.max_iterations', &
414 call json_get(params,
'case.fluid.pressure_solver.type', solver_type)
415 call json_get(params,
'case.fluid.pressure_solver.preconditioner.type', &
417 call json_get(params, &
418 'case.fluid.pressure_solver.preconditioner', precon_params)
419 call json_get(params,
'case.fluid.pressure_solver.absolute_tolerance', &
421 call json_get_or_default(params,
'case.fluid.pressure_solver.monitor', &
423 call neko_log%message(
'Type : ('// trim(solver_type) // &
424 ', ' // trim(precon_type) //
')')
425 write(log_buf,
'(A,ES13.6)')
'Abs tol :', abs_tol
426 call neko_log%message(log_buf)
428 call this%solver_factory(this%ksp_prs, this%dm_Xh%size(), &
429 solver_type, solver_maxiter, abs_tol, monitor)
430 call this%precon_factory_(this%pc_prs, this%ksp_prs, &
431 this%c_Xh, this%bcs_prs, &
432 precon_type, precon_params)
433 call neko_log%end_section()
436 call neko_log%section(
"Advection factory")
437 call json_get_or_default(params,
'case.fluid.advection', advection, .true.)
438 call json_get(params,
'case.numerics', numerics_params)
439 call chkp%get_time_history(tlag, dtlag)
440 call advection_adjoint_factory(this%adv, numerics_params, this%c_Xh, &
441 this%ulag, this%vlag, this%wlag, &
442 dtlag, tlag, this%ext_bdf, &
447 payload => this%chkp%add_payload(
"adjoint_fluid")
448 call payload%add_field(this%u_adj)
449 call payload%add_field(this%v_adj)
450 call payload%add_field(this%w_adj)
451 call payload%add_field(this%p_adj)
452 call payload%add_field(this%abx1)
453 call payload%add_field(this%abx2)
454 call payload%add_field(this%aby1)
455 call payload%add_field(this%aby2)
456 call payload%add_field(this%abz1)
457 call payload%add_field(this%abz2)
458 call payload%add_series(this%ulag)
459 call payload%add_series(this%vlag)
460 call payload%add_series(this%wlag)
462 call neko_log%end_section()
468 call json_get_or_default(params,
'norm_scaling', &
469 this%norm_scaling, 0.5_rp)
477 this%u_b => neko_registry%get_field(
'u')
478 this%v_b => neko_registry%get_field(
'v')
479 this%w_b => neko_registry%get_field(
'w')
480 this%p_b => neko_registry%get_field(
'p')
483 call json_get_or_default(params,
'norm_target', &
484 this%norm_target, -1.0_rp)
485 call json_get_or_default(params,
'norm_tolerance', &
486 this%norm_tolerance, 10.0_rp)
489 call json_get_or_default(params,
'output_file', &
490 file_name,
'power_iterations.csv')
491 call this%file_output%init(trim(file_name))
492 write(header_line,
'(A)')
'Time, Norm, Scaling'
493 call this%file_output%set_header(header_line)
495 end subroutine adjoint_fluid_pnpn_init
497 subroutine adjoint_fluid_pnpn_restart(this, chkp)
498 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
499 type(chkp_t),
intent(inout) :: chkp
502 n = this%u_adj%dof%size()
503 if (
allocated(this%chkp%previous_mesh%elements) .or. &
504 chkp%previous_Xh%lx .ne. this%Xh%lx)
then
505 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
506 p => this%p_adj, c_xh => this%c_Xh, ulag => this%ulag, &
507 vlag => this%vlag, wlag => this%wlag)
508 call col2(u%x, c_xh%mult, n)
509 call col2(v%x, c_xh%mult, n)
510 call col2(w%x, c_xh%mult, n)
511 call col2(p%x, c_xh%mult, n)
512 do i = 1, this%ulag%size()
513 call col2(ulag%lf(i)%x, c_xh%mult, n)
514 call col2(vlag%lf(i)%x, c_xh%mult, n)
515 call col2(wlag%lf(i)%x, c_xh%mult, n)
520 if (neko_bcknd_device .eq. 1)
then
521 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
522 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag,&
524 call device_memcpy(u%x, u%x_d, u%dof%size(), &
525 host_to_device, sync = .false.)
526 call device_memcpy(v%x, v%x_d, v%dof%size(), &
527 host_to_device, sync = .false.)
528 call device_memcpy(w%x, w%x_d, w%dof%size(), &
529 host_to_device, sync = .false.)
530 call device_memcpy(p%x, p%x_d, p%dof%size(), &
531 host_to_device, sync = .false.)
532 call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
533 u%dof%size(), host_to_device, sync = .false.)
534 call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
535 u%dof%size(), host_to_device, sync = .false.)
537 call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
538 v%dof%size(), host_to_device, sync = .false.)
539 call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
540 v%dof%size(), host_to_device, sync = .false.)
542 call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
543 w%dof%size(), host_to_device, sync = .false.)
544 call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
545 w%dof%size(), host_to_device, sync = .false.)
546 call device_memcpy(this%abx1%x, this%abx1%x_d, &
547 w%dof%size(), host_to_device, sync = .false.)
548 call device_memcpy(this%abx2%x, this%abx2%x_d, &
549 w%dof%size(), host_to_device, sync = .false.)
550 call device_memcpy(this%aby1%x, this%aby1%x_d, &
551 w%dof%size(), host_to_device, sync = .false.)
552 call device_memcpy(this%aby2%x, this%aby2%x_d, &
553 w%dof%size(), host_to_device, sync = .false.)
554 call device_memcpy(this%abz1%x, this%abz1%x_d, &
555 w%dof%size(), host_to_device, sync = .false.)
556 call device_memcpy(this%abz2%x, this%abz2%x_d, &
557 w%dof%size(), host_to_device, sync = .false.)
558 call device_memcpy(this%advx%x, this%advx%x_d, &
559 w%dof%size(), host_to_device, sync = .false.)
560 call device_memcpy(this%advy%x, this%advy%x_d, &
561 w%dof%size(), host_to_device, sync = .false.)
562 call device_memcpy(this%advz%x, this%advz%x_d, &
563 w%dof%size(), host_to_device, sync = .false.)
570 if (
allocated(this%chkp%previous_mesh%elements) &
571 .or. this%chkp%previous_Xh%lx .ne. this%Xh%lx)
then
572 call this%gs_Xh%op(this%u_adj, gs_op_add)
573 call this%gs_Xh%op(this%v_adj, gs_op_add)
574 call this%gs_Xh%op(this%w_adj, gs_op_add)
575 call this%gs_Xh%op(this%p_adj, gs_op_add)
577 do i = 1, this%ulag%size()
578 call this%gs_Xh%op(this%ulag%lf(i), gs_op_add)
579 call this%gs_Xh%op(this%vlag%lf(i), gs_op_add)
580 call this%gs_Xh%op(this%wlag%lf(i), gs_op_add)
584 end subroutine adjoint_fluid_pnpn_restart
586 subroutine adjoint_fluid_pnpn_free(this)
587 class(adjoint_fluid_pnpn_t),
intent(inout) :: this
590 call this%scheme_free()
592 call this%bc_prs_surface%free()
593 call this%bc_sym_surface%free()
594 if (
allocated(this%bcs_vel_projector))
then
595 call this%bcs_vel_projector%free()
596 deallocate(this%bcs_vel_projector)
598 call this%bcs_prs_projector%free()
599 call this%proj_prs%free()
600 call this%proj_vel%free()
602 call this%p_res%free()
603 call this%u_res%free()
604 call this%v_res%free()
605 call this%w_res%free()
612 call this%abx1%free()
613 call this%aby1%free()
614 call this%abz1%free()
616 call this%abx2%free()
617 call this%aby2%free()
618 call this%abz2%free()
620 call this%advx%free()
621 call this%advy%free()
622 call this%advz%free()
624 if (
allocated(this%Ax_vel))
then
625 deallocate(this%Ax_vel)
628 if (
allocated(this%Ax_prs))
then
629 deallocate(this%Ax_prs)
632 if (
allocated(this%prs_res))
then
633 deallocate(this%prs_res)
636 if (
allocated(this%vel_res))
then
637 deallocate(this%vel_res)
640 if (
allocated(this%sumab))
then
641 deallocate(this%sumab)
644 if (
allocated(this%makeabf))
then
645 deallocate(this%makeabf)
648 if (
allocated(this%makebdf))
then
649 deallocate(this%makebdf)
652 if (
allocated(this%makeoifs))
then
653 deallocate(this%makeoifs)
656 if (
allocated(this%ext_bdf))
then
657 deallocate(this%ext_bdf)
662 end subroutine adjoint_fluid_pnpn_free
668 subroutine adjoint_fluid_pnpn_step(this, time, dt_controller)
669 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
670 type(time_state_t),
intent(in) :: time
671 type(time_step_controller_t),
intent(in) :: dt_controller
675 type(ksp_monitor_t) :: ksp_results(4)
676 type(field_t),
pointer :: dx_p_adj, dy_p_adj, dz_p_adj
677 type(field_t),
pointer :: cc_x, cc_y, cc_z, work1, work2, work3, work4
678 integer :: temp_indices(3)
679 integer :: cc_indices(7)
681 if (this%freeze)
return
683 n = this%dm_Xh%size()
685 call profiler_start_region(
'Adjoint')
686 associate(u => this%u_adj, v => this%v_adj, w => this%w_adj, &
688 u_e => this%u_adj_e, v_e => this%v_adj_e, w_e => this%w_adj_e, &
689 du => this%du, dv => this%dv, dw => this%dw, dp => this%dp, &
690 u_b => this%u_b, v_b => this%v_b, w_b => this%w_b, &
691 u_res => this%u_res, v_res => this%v_res, w_res => this%w_res, &
692 p_res => this%p_res, ax_vel => this%Ax_vel, ax_prs => this%Ax_prs, &
694 c_xh => this%c_Xh, dm_xh => this%dm_Xh, gs_xh => this%gs_Xh, &
695 ulag => this%ulag, vlag => this%vlag, wlag => this%wlag, &
696 msh => this%msh, prs_res => this%prs_res, &
697 source_term => this%source_term, vel_res => this%vel_res, &
698 sumab => this%sumab, &
699 makeabf => this%makeabf, makebdf => this%makebdf, &
700 vel_projection_dim => this%vel_projection_dim, &
701 pr_projection_dim => this%pr_projection_dim, &
703 rho => this%rho, mu => this%mu, &
704 f_x => this%f_adj_x, f_y => this%f_adj_y, f_z => this%f_adj_z, &
705 t => time%t, tstep => time%tstep, dt => time%dt, &
706 ext_bdf => this%ext_bdf, event => glb_cmd_event)
709 call sumab%compute_fluid(u_e, v_e, w_e, u, v, w, &
710 ulag, vlag, wlag, ext_bdf%advection_coeffs%x, ext_bdf%nadv)
713 call this%source_term%compute(time, extrapolate = .true.)
716 call this%bcs_vel%apply_vector(f_x%x, f_y%x, f_z%x, &
717 this%dm_Xh%size(), time, strong = .false.)
725 call neko_scratch_registry%request_field(cc_x, cc_indices(1), .false.)
726 call neko_scratch_registry%request_field(cc_y, cc_indices(2), .false.)
727 call neko_scratch_registry%request_field(cc_z, cc_indices(3), .false.)
728 call neko_scratch_registry%request_field(work1, cc_indices(4), .false.)
729 call neko_scratch_registry%request_field(work2, cc_indices(5), .false.)
730 call neko_scratch_registry%request_field(work3, cc_indices(6), .false.)
731 call neko_scratch_registry%request_field(work4, cc_indices(7), .false.)
733 call adjoint_curl_curl_load(cc_x, cc_y, cc_z, p, c_xh, gs_xh, &
734 mu%x(1,1,1,1), rho%x(1,1,1,1), work1, work2, work3, work4)
735 call field_add2(f_x, cc_x, n)
736 call field_add2(f_y, cc_y, n)
737 call field_add2(f_z, cc_z, n)
739 call neko_scratch_registry%relinquish_field(cc_indices)
742 call neko_error(
"OIFS not implemented for adjoint")
746 call this%adv%compute_adjoint(u, v, w, u_b, v_b, w_b, &
748 xh, this%c_Xh, dm_xh%size())
754 call makeabf%compute_fluid(this%abx1, this%aby1, this%abz1,&
755 this%abx2, this%aby2, this%abz2, &
756 f_x%x, f_y%x, f_z%x, &
757 rho%x(1,1,1,1), ext_bdf%advection_coeffs%x, n)
760 call makebdf%compute_fluid(ulag, vlag, wlag, f_x%x, f_y%x, f_z%x, &
761 u, v, w, c_xh%B, c_xh%Blag, c_xh%Blaglag, rho%x(1,1,1,1), dt, &
762 ext_bdf%diffusion_coeffs%x, ext_bdf%ndiff, n)
768 call this%source_term%compute(time, extrapolate = .false., scale = rho)
774 call this%bc_apply_vel(time, strong = .true.)
775 call this%bc_apply_prs(time)
778 call this%update_material_properties(time)
782 call profiler_start_region(
'Adjoint_velocity_residual')
784 call vel_res%compute(ax_vel, u, v, w, &
785 u_res, v_res, w_res, &
789 mu, rho, ext_bdf%diffusion_coeffs%x(1), &
792 call gs_xh%op(u_res, gs_op_add, event)
793 call device_event_sync(event)
794 call gs_xh%op(v_res, gs_op_add, event)
795 call device_event_sync(event)
796 call gs_xh%op(w_res, gs_op_add, event)
797 call device_event_sync(event)
800 call this%bcs_vel_projector%apply(u_res%x, v_res%x, w_res%x, n)
802 call profiler_end_region(
'Adjoint_velocity_residual')
804 call this%proj_vel%pre_solving(u_res%x, v_res%x, w_res%x, &
805 tstep, c_xh, n, dt_controller,
'Velocity')
807 call this%pc_vel%update()
809 call profiler_start_region(
"Adjoint_velocity_solve")
810 ksp_results(1:3) = this%ksp_vel%solve_coupled(ax_vel, du, dv, dw, &
811 u_res%x, v_res%x, w_res%x, n, c_xh, &
812 this%bcs_vel_projector, gs_xh, &
813 this%ksp_vel%max_iter)
815 call this%proj_vel%post_solving(du%x, dv%x, dw%x, ax_vel, c_xh, &
816 this%bcs_vel_projector, gs_xh, n, tstep, &
819 if (neko_bcknd_device .eq. 1)
then
820 call device_opadd2cm(u%x_d, v%x_d, w%x_d, &
821 du%x_d, dv%x_d, dw%x_d, 1.0_rp, n, msh%gdim)
823 call opadd2cm(u%x, v%x, w%x, du%x, dv%x, dw%x, 1.0_rp, n, msh%gdim)
825 call profiler_end_region(
"Adjoint_velocity_solve")
831 call field_copy(f_x, u)
832 call field_copy(f_y, v)
833 call field_copy(f_z, w)
835 call profiler_start_region(
'Adjoint_pressure_residual')
837 call prs_res%compute(p, p_res, &
841 this%bc_prs_surface, this%bc_sym_surface, &
842 ax_prs, ext_bdf%diffusion_coeffs%x(1), dt, &
846 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
847 call device_ortho(p_res%x_d, this%glb_n_points, n)
848 else if (.not. this%prs_dirichlet)
then
849 call ortho(p_res%x, this%glb_n_points, n)
852 call gs_xh%op(p_res, gs_op_add, event)
853 call device_event_sync(event)
856 call this%bcs_prs_projector%apply(p_res%x, p%dof%size())
859 call profiler_end_region(
'Adjoint_pressure_residual')
862 call this%proj_prs%pre_solving(p_res%x, tstep, c_xh, n, dt_controller, &
865 call this%pc_prs%update()
867 call profiler_start_region(
'Adjoint_pressure_solve')
871 this%ksp_prs%solve(ax_prs, dp, p_res%x, n, c_xh, &
872 this%bcs_prs_projector, gs_xh)
875 call profiler_end_region(
'Adjoint_pressure_solve')
877 call this%proj_prs%post_solving(dp%x, ax_prs, c_xh, &
878 this%bcs_prs_projector, gs_xh, n, tstep, dt_controller)
881 call field_add2(p, dp, n)
882 if (.not. this%prs_dirichlet .and. neko_bcknd_device .eq. 1)
then
883 call device_ortho(p%x_d, this%glb_n_points, n)
884 else if (.not. this%prs_dirichlet)
then
885 call ortho(p%x, this%glb_n_points, n)
888 ksp_results(4)%name =
'Adjoint Pressure'
889 ksp_results(1)%name =
'Adjoint Velocity U'
890 ksp_results(2)%name =
'Adjoint Velocity V'
891 ksp_results(3)%name =
'Adjoint Velocity W'
893 if (this%forced_flow_rate)
then
894 call neko_error(
'Forced flow rate is not implemented for the adjoint')
900 call neko_scratch_registry%request_field(dx_p_adj, temp_indices(1), &
902 call neko_scratch_registry%request_field(dy_p_adj, temp_indices(2), &
904 call neko_scratch_registry%request_field(dz_p_adj, temp_indices(3), &
908 call opgrad(dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, this%p_adj%x, c_xh)
911 call gs_xh%op(dx_p_adj, gs_op_add, event)
912 call device_event_sync(event)
913 call gs_xh%op(dy_p_adj, gs_op_add, event)
914 call device_event_sync(event)
915 call gs_xh%op(dz_p_adj, gs_op_add, event)
916 call device_event_sync(event)
919 if (neko_bcknd_device .eq. 1)
then
920 call device_col2(dx_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
921 call device_col2(dy_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
922 call device_col2(dz_p_adj%x_d, c_xh%Binv_d, dx_p_adj%size())
926 call col2(dx_p_adj%x, c_xh%Binv, dx_p_adj%size())
927 call col2(dy_p_adj%x, c_xh%Binv, dx_p_adj%size())
928 call col2(dz_p_adj%x, c_xh%Binv, dx_p_adj%size())
931 if (neko_bcknd_device .eq. 1)
then
932 call device_opadd2cm(u%x_d, v%x_d, w%x_d, dx_p_adj%x_d, &
933 dy_p_adj%x_d, dz_p_adj%x_d, -1.0_rp, n, msh%gdim)
935 call opadd2cm(u%x, v%x, w%x, dx_p_adj%x, dy_p_adj%x, dz_p_adj%x, &
936 -1.0_rp, n, msh%gdim)
939 call neko_scratch_registry%relinquish_field(temp_indices)
942 call fluid_step_info(time, ksp_results, &
943 this%full_stress_formulation, this%strict_convergence)
946 call profiler_end_region(
'Adjoint')
948 end subroutine adjoint_fluid_pnpn_step
954 subroutine adjoint_fluid_pnpn_setup_bcs(this, user, params)
955 use mpi_f08,
only: mpi_in_place
956 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
957 type(user_t),
target,
intent(in) :: user
958 type(json_file),
intent(inout) :: params
959 integer :: i, n_bcs, j, zone_size, global_zone_size, ierr
960 class(bc_t),
pointer :: bc_i
961 type(json_core) :: core
962 type(json_value),
pointer :: bc_object
963 type(json_file) :: bc_subdict
966 logical,
allocatable :: marked_zones(:)
967 integer,
allocatable :: zone_indices(:)
968 character(len=:),
allocatable :: json_key
972 allocate(segregated_vector_bc_projector_t :: this%bcs_vel_projector)
973 call this%bcs_vel_projector%init(this%c_Xh)
976 call this%bc_prs_surface%init_from_components(this%c_Xh)
977 call this%bc_sym_surface%init_from_components(this%c_Xh)
979 json_key =
'case.adjoint_fluid.boundary_conditions'
982 if (params%valid_path(json_key))
then
983 call params%info(json_key, n_children = n_bcs)
984 call params%get_core(core)
985 call params%get(json_key, bc_object, found)
990 call this%bcs_vel%init(n_bcs)
992 allocate(marked_zones(
size(this%msh%labeled_zones)))
993 marked_zones = .false.
997 call json_extract_item(core, bc_object, i, bc_subdict)
999 call json_get(bc_subdict,
"zone_indices", zone_indices)
1004 do j = 1,
size(zone_indices)
1005 zone_size = this%msh%labeled_zones(zone_indices(j))%size
1006 call mpi_allreduce(zone_size, global_zone_size, 1, &
1007 mpi_integer, mpi_max, neko_comm, ierr)
1009 if (global_zone_size .eq. 0)
then
1010 write(error_unit,
'(A, A, I0, A, A, I0, A)')
"*** ERROR ***: ",&
1011 "Zone index ", zone_indices(j), &
1012 " is invalid as this zone has 0 size, meaning it does ", &
1013 "not in the mesh. Check adjoint boundary condition ", &
1018 if (marked_zones(zone_indices(j)) .eqv. .true.)
then
1019 write(error_unit,
'(A, A, I0, A, A, A, A)')
"*** ERROR ***: ", &
1020 "Zone with index ", zone_indices(j), &
1021 " has already been assigned a boundary condition. ", &
1022 "Please check your boundary_conditions entry for the ", &
1023 "adjoint and make sure that each zone index appears ", &
1024 "only in a single boundary condition."
1027 marked_zones(zone_indices(j)) = .true.
1032 call velocity_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1036 if (
associated(bc_i))
then
1041 type is (symmetry_aligned_t)
1045 call neko_error(
"The symmetry boundary condition is not " // &
1046 "supported by the adjoint: the transpose of the " // &
1047 "curl-curl pressure term on symmetry surfaces is " // &
1049 type is (non_normal_aligned_t)
1057 call this%bcs_vel_projector%mark(bc_i%bc_x, component =
'x')
1058 call this%bcs_vel_projector%mark(bc_i%bc_y, component =
'y')
1059 call this%bcs_vel_projector%mark(bc_i%bc_z, component =
'z')
1060 type is (shear_stress_t)
1061 call neko_error(
"The shear_stress boundary condition " // &
1062 "requires the full stress formulation, which the " // &
1063 "adjoint scheme does not support.")
1064 type is (wall_model_bc_t)
1065 call neko_error(
"The wall_model boundary condition " // &
1066 "requires the full stress formulation, which the " // &
1067 "adjoint scheme does not support.")
1072 if (bc_i%bc_type .eq. bc_dirichlet)
then
1073 call this%bc_prs_surface%mark_labeled_zones( &
1075 call this%bcs_vel_projector%mark(bc_i, component =
'x')
1076 call this%bcs_vel_projector%mark(bc_i, component =
'y')
1077 call this%bcs_vel_projector%mark(bc_i, component =
'z')
1080 call this%bcs_vel%append(bc_i)
1086 do i = 1,
size(this%msh%labeled_zones)
1087 if ((this%msh%labeled_zones(i)%size .gt. 0) .and. &
1088 (marked_zones(i) .eqv. .false.))
then
1089 write(error_unit,
'(A, A, I0)')
"*** ERROR ***: ", &
1090 "No adjoint boundary condition assigned to zone ", i
1098 call this%bcs_prs%init(n_bcs)
1102 call json_extract_item(core, bc_object, i, bc_subdict)
1104 call pressure_bc_factory(bc_i, this, bc_subdict, this%c_Xh, user)
1108 if (
associated(bc_i))
then
1109 call this%bcs_prs%append(bc_i)
1112 if (bc_i%bc_type .eq. bc_dirichlet)
then
1113 call this%bcs_prs_projector%mark(bc_i)
1121 do i = 1,
size(this%msh%labeled_zones)
1122 if (this%msh%labeled_zones(i)%size .gt. 0)
then
1123 call neko_error(
"No boundary_conditions entry in the case file!")
1127 call this%bcs_vel%init()
1128 call this%bcs_prs%init()
1132 call this%bc_prs_surface%finalize()
1133 call this%bc_sym_surface%finalize()
1134 call this%bcs_vel_projector%finalize(rebuild_mask = .true.)
1137 this%prs_dirichlet = this%bcs_prs_projector%dof_mask%is_set()
1138 call mpi_allreduce(mpi_in_place, this%prs_dirichlet, 1, &
1139 mpi_logical, mpi_lor, neko_comm)
1141 end subroutine adjoint_fluid_pnpn_setup_bcs
1144 subroutine adjoint_fluid_pnpn_write_boundary_conditions(this)
1145 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1146 type(dirichlet_t) :: bdry_mask
1147 type(field_t),
pointer :: bdry_field
1148 type(file_t) :: bdry_file
1149 integer :: temp_index, i
1150 class(bc_t),
pointer :: bci
1151 character(len=LOG_SIZE) :: log_buf
1153 call neko_log%section(
"Adjoint boundary conditions")
1154 write(log_buf,
'(A)') &
1155 'Marking using integer keys in boundary_adjoint0.f00000'
1156 call neko_log%message(log_buf)
1157 write(log_buf,
'(A)')
'Condition-value pairs: '
1158 call neko_log%message(log_buf)
1159 write(log_buf,
'(A)')
' no_slip = 1'
1160 call neko_log%message(log_buf)
1161 write(log_buf,
'(A)')
' velocity_value = 2'
1162 call neko_log%message(log_buf)
1163 write(log_buf,
'(A)')
' outflow, normal_outflow (+dong) = 3'
1164 call neko_log%message(log_buf)
1165 write(log_buf,
'(A)')
' symmetry = 4'
1166 call neko_log%message(log_buf)
1167 write(log_buf,
'(A)')
' user_velocity_pointwise = 5'
1168 call neko_log%message(log_buf)
1169 write(log_buf,
'(A)')
' periodic = 6'
1170 call neko_log%message(log_buf)
1171 write(log_buf,
'(A)')
' user_velocity = 7'
1172 call neko_log%message(log_buf)
1173 write(log_buf,
'(A)')
' user_pressure = 8'
1174 call neko_log%message(log_buf)
1175 write(log_buf,
'(A)')
' shear_stress = 9'
1176 call neko_log%message(log_buf)
1177 write(log_buf,
'(A)')
' wall_modelling = 10'
1178 call neko_log%message(log_buf)
1179 write(log_buf,
'(A)')
' blasius_profile = 11'
1180 call neko_log%message(log_buf)
1181 call neko_log%end_section()
1183 call neko_scratch_registry%request_field(bdry_field, temp_index, .true.)
1187 call bdry_mask%init_from_components(this%c_Xh, 6.0_rp)
1188 call bdry_mask%mark_zone(this%msh%periodic)
1189 call bdry_mask%finalize()
1190 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1191 call bdry_mask%free()
1193 do i = 1, this%bcs_prs%size()
1194 bci => this%bcs_prs%get(i)
1195 select type (bc => bci)
1196 type is (zero_dirichlet_t)
1197 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1198 call bdry_mask%mark_facets(bci%marked_facet)
1199 call bdry_mask%finalize()
1200 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1201 call bdry_mask%free()
1202 type is (dong_outflow_t)
1203 call bdry_mask%init_from_components(this%c_Xh, 3.0_rp)
1204 call bdry_mask%mark_facets(bci%marked_facet)
1205 call bdry_mask%finalize()
1206 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1207 call bdry_mask%free()
1208 type is (field_dirichlet_t)
1209 call bdry_mask%init_from_components(this%c_Xh, 8.0_rp)
1210 call bdry_mask%mark_facets(bci%marked_facet)
1211 call bdry_mask%finalize()
1212 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1213 call bdry_mask%free()
1217 do i = 1, this%bcs_vel%size()
1218 bci => this%bcs_vel%get(i)
1219 select type (bc => bci)
1220 type is (zero_dirichlet_t)
1221 call bdry_mask%init_from_components(this%c_Xh, 1.0_rp)
1222 call bdry_mask%mark_facets(bci%marked_facet)
1223 call bdry_mask%finalize()
1224 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1225 call bdry_mask%free()
1227 call bdry_mask%init_from_components(this%c_Xh, 2.0_rp)
1228 call bdry_mask%mark_facets(bci%marked_facet)
1229 call bdry_mask%finalize()
1230 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1231 call bdry_mask%free()
1232 type is (symmetry_aligned_t)
1233 call bdry_mask%init_from_components(this%c_Xh, 4.0_rp)
1234 call bdry_mask%mark_facets(bci%marked_facet)
1235 call bdry_mask%finalize()
1236 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1237 call bdry_mask%free()
1238 type is (field_dirichlet_vector_t)
1239 call bdry_mask%init_from_components(this%c_Xh, 7.0_rp)
1240 call bdry_mask%mark_facets(bci%marked_facet)
1241 call bdry_mask%finalize()
1242 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1243 call bdry_mask%free()
1244 type is (shear_stress_t)
1245 call bdry_mask%init_from_components(this%c_Xh, 9.0_rp)
1246 call bdry_mask%mark_facets(bci%marked_facet)
1247 call bdry_mask%finalize()
1248 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1249 call bdry_mask%free()
1250 type is (wall_model_bc_t)
1251 call bdry_mask%init_from_components(this%c_Xh, 10.0_rp)
1252 call bdry_mask%mark_facets(bci%marked_facet)
1253 call bdry_mask%finalize()
1254 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1255 call bdry_mask%free()
1257 call bdry_mask%init_from_components(this%c_Xh, 11.0_rp)
1258 call bdry_mask%mark_facets(bci%marked_facet)
1259 call bdry_mask%finalize()
1260 call bdry_mask%apply_scalar(bdry_field%x, this%dm_Xh%size())
1261 call bdry_mask%free()
1266 call bdry_file%init(
'boundary_adjoint.fld')
1267 call bdry_file%write(bdry_field)
1269 call neko_scratch_registry%relinquish_field(temp_index)
1270 end subroutine adjoint_fluid_pnpn_write_boundary_conditions
1275 subroutine rescale_fluid(fluid_data, scale)
1277 class(adjoint_fluid_pnpn_t),
intent(inout) :: fluid_data
1279 real(kind=rp),
intent(in) :: scale
1285 if (neko_bcknd_device .eq. 1)
then
1286 call device_cmult(fluid_data%u_adj%x_d, scale, fluid_data%u_adj%size())
1287 call device_cmult(fluid_data%v_adj%x_d, scale, fluid_data%v_adj%size())
1288 call device_cmult(fluid_data%w_adj%x_d, scale, fluid_data%w_adj%size())
1290 call cmult(fluid_data%u_adj%x, scale, fluid_data%u_adj%size())
1291 call cmult(fluid_data%v_adj%x, scale, fluid_data%v_adj%size())
1292 call cmult(fluid_data%w_adj%x, scale, fluid_data%w_adj%size())
1296 if (neko_bcknd_device .eq. 1)
then
1297 call device_cmult(fluid_data%f_adj_x%x_d, scale, &
1298 fluid_data%f_adj_x%size())
1299 call device_cmult(fluid_data%f_adj_y%x_d, scale, &
1300 fluid_data%f_adj_y%size())
1301 call device_cmult(fluid_data%f_adj_z%x_d, scale, &
1302 fluid_data%f_adj_z%size())
1305 call device_cmult(fluid_data%abx1%x_d, scale, fluid_data%abx1%size())
1306 call device_cmult(fluid_data%aby1%x_d, scale, fluid_data%aby1%size())
1307 call device_cmult(fluid_data%abz1%x_d, scale, fluid_data%abz1%size())
1308 call device_cmult(fluid_data%abx2%x_d, scale, fluid_data%abx2%size())
1309 call device_cmult(fluid_data%aby2%x_d, scale, fluid_data%aby2%size())
1310 call device_cmult(fluid_data%abz2%x_d, scale, fluid_data%abz2%size())
1313 call cmult(fluid_data%f_adj_x%x, scale, fluid_data%f_adj_x%size())
1314 call cmult(fluid_data%f_adj_y%x, scale, fluid_data%f_adj_y%size())
1315 call cmult(fluid_data%f_adj_z%x, scale, fluid_data%f_adj_z%size())
1317 call cmult(fluid_data%abx1%x, scale, fluid_data%abx1%size())
1318 call cmult(fluid_data%aby1%x, scale, fluid_data%aby1%size())
1319 call cmult(fluid_data%abz1%x, scale, fluid_data%abz1%size())
1321 call cmult(fluid_data%abx2%x, scale, fluid_data%abx2%size())
1322 call cmult(fluid_data%aby2%x, scale, fluid_data%aby2%size())
1323 call cmult(fluid_data%abz2%x, scale, fluid_data%abz2%size())
1327 if (neko_bcknd_device .eq. 1)
then
1328 do i = 1, fluid_data%ulag%size()
1329 call device_cmult(fluid_data%ulag%lf(i)%x_d, &
1330 scale, fluid_data%ulag%lf(i)%size())
1333 do i = 1, fluid_data%vlag%size()
1334 call device_cmult(fluid_data%vlag%lf(i)%x_d, &
1335 scale, fluid_data%vlag%lf(i)%size())
1338 do i = 1, fluid_data%wlag%size()
1339 call device_cmult(fluid_data%wlag%lf(i)%x_d, &
1340 scale, fluid_data%wlag%lf(i)%size())
1343 do i = 1, fluid_data%ulag%size()
1344 call cmult(fluid_data%ulag%lf(i)%x, &
1345 scale, fluid_data%ulag%lf(i)%size())
1348 do i = 1, fluid_data%vlag%size()
1349 call cmult(fluid_data%vlag%lf(i)%x, &
1350 scale, fluid_data%vlag%lf(i)%size())
1353 do i = 1, fluid_data%wlag%size()
1354 call cmult(fluid_data%wlag%lf(i)%x, &
1355 scale, fluid_data%wlag%lf(i)%size())
1359 end subroutine rescale_fluid
1361 function norm(x, y, z, B, volume, n)
1362 use mpi_f08,
only: mpi_in_place
1364 integer,
intent(in) :: n
1365 real(kind=rp),
dimension(n),
intent(in) :: x, y, z
1366 real(kind=rp),
dimension(n),
intent(in) :: b
1367 real(kind=rp),
intent(in) :: volume
1369 real(kind=rp) :: norm
1371 norm = vlsc3(x, x, b, n) + vlsc3(y, y, b, n) + vlsc3(z, z, b, n)
1373 call mpi_allreduce(mpi_in_place, norm, 1, &
1374 mpi_real_precision, mpi_sum, neko_comm)
1376 norm = sqrt(norm / volume)
1379 function device_norm(x_d, y_d, z_d, B_d, volume, n)
1380 use mpi_f08,
only: mpi_in_place
1382 type(c_ptr),
intent(in) :: x_d, y_d, z_d
1383 type(c_ptr),
intent(in) :: B_d
1384 real(kind=rp),
intent(in) :: volume
1385 integer,
intent(in) :: n
1387 real(kind=rp) :: device_norm
1389 device_norm = device_vlsc3(x_d, x_d, b_d, n) + &
1390 device_vlsc3(y_d, y_d, b_d, n) + &
1391 device_vlsc3(z_d, z_d, b_d, n)
1393 call mpi_allreduce(mpi_in_place, device_norm, 1, &
1394 mpi_real_precision, mpi_sum, neko_comm)
1396 device_norm = sqrt(device_norm / volume)
1398 end function device_norm
1404 subroutine power_iterations_compute(this, t, tstep)
1405 class(adjoint_fluid_pnpn_t),
target,
intent(inout) :: this
1406 real(kind=rp),
intent(in) :: t
1407 integer,
intent(in) :: tstep
1410 real(kind=rp) :: scaling_factor
1411 real(kind=rp) :: norm_l2, norm_l2_base
1412 character(len=256) :: log_message
1413 type(vector_t) :: data_line
1416 n = this%c_Xh%dof%size()
1417 if (tstep .eq. 1)
then
1418 if (neko_bcknd_device .eq. 1)
then
1419 norm_l2_base = device_norm(this%u_adj%x_d, this%v_adj%x_d, &
1421 this%c_Xh%B_d, this%c_Xh%volume, n)
1423 norm_l2_base = this%norm_scaling * norm(this%u_adj%x, this%v_adj%x, &
1425 this%c_Xh%B, this%c_Xh%volume, n)
1427 if (this%norm_target .lt. 0.0_rp)
then
1428 this%norm_target = norm_l2_base
1431 this%norm_l2_upper = this%norm_tolerance * this%norm_target
1432 this%norm_l2_lower = this%norm_target / this%norm_tolerance
1437 if (neko_bcknd_device .eq. 1)
then
1438 norm_l2 = device_norm(this%u_adj%x_d, this%v_adj%x_d, this%w_adj%x_d, &
1439 this%c_Xh%B_d, this%c_Xh%volume, n)
1441 norm_l2 = norm(this%u_adj%x, this%v_adj%x, this%w_adj%x, &
1442 this%c_Xh%B, this%c_Xh%volume, n)
1444 norm_l2 = sqrt(this%norm_scaling) * norm_l2
1445 scaling_factor = 1.0_rp
1448 if (norm_l2 .gt. this%norm_l2_upper &
1449 .or. norm_l2 .lt. this%norm_l2_lower)
then
1450 scaling_factor = this%norm_target / norm_l2
1451 call rescale_fluid(this, scaling_factor)
1452 norm_l2 = this%norm_target
1454 if (tstep .eq. 1)
then
1455 scaling_factor = 1.0_rp
1461 call neko_log%section(
'Power Iterations')
1463 write (log_message,
'(A7,E20.14)')
'Norm: ', norm_l2
1464 call neko_log%message(log_message, lvl = neko_log_debug)
1465 write (log_message,
'(A7,E20.14)')
'Scaling: ', scaling_factor
1466 call neko_log%message(log_message, lvl = neko_log_debug)
1469 call data_line%init(2)
1470 data_line%x = [norm_l2, scaling_factor]
1471 call this%file_output%write(data_line, t)
1474 call neko_log%end_section(
'Power Iterations')
1475 end subroutine power_iterations_compute
Boundary condition factory for pressure.
Adjoint of the curl-curl term in the Pn/Pn pressure residual.
subroutine, public adjoint_curl_curl_load(load_x, load_y, load_z, p_adj, coef, gs, mu, rho, work1, work2, work3, work4)
Compute the adjoint curl-curl load .
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.