35 use num_types,
only: rp, dp, sp
36 use case,
only: case_t
41 use scalar_ic,
only: set_scalar_ic
42 use flow_ic,
only: set_flow_ic
43 use output_controller,
only: output_controller_t
44 use file,
only: file_t
45 use json_module,
only: json_file
46 use json_utils,
only: json_get, json_get_or_default, json_extract_object
49 use logger,
only : neko_log
50 use utils,
only: neko_error
53 use json_utils_ext,
only: json_key_fallback
68 adjoint_convection_term
69 type(case_t),
pointer :: case
74 type(output_controller_t) :: output_controller
76 logical :: have_scalar = .false.
81 module procedure adjoint_init_from_json, adjoint_init_from_attributes
87 subroutine adjoint_init_from_json(this, neko_case)
88 class(adjoint_case_t),
intent(inout) :: this
89 type(case_t),
target,
intent(inout) :: neko_case
91 logical :: have_scalar
94 call json_get_or_default(neko_case%params,
"tol", tol, 1.0e-6_rp)
99 call json_get_or_default(neko_case%params, &
100 'case.adjoint_scalar.enabled', have_scalar, .false.)
102 call adjoint_init_from_attributes(this, neko_case, tol, have_scalar)
104 end subroutine adjoint_init_from_json
107 subroutine adjoint_init_from_attributes(this, neko_case, tol, have_scalar)
108 class(adjoint_case_t),
intent(inout) :: this
109 class(case_t),
intent(inout),
target :: neko_case
110 real(kind=rp),
intent(in) :: tol
111 logical :: have_scalar
113 this%case => neko_case
115 this%have_scalar = have_scalar
118 call adjoint_case_init_common(this, neko_case)
120 end subroutine adjoint_init_from_attributes
123 subroutine adjoint_case_init_common(this, neko_case)
124 class(adjoint_case_t),
intent(inout) :: this
125 type(case_t),
intent(inout) :: neko_case
127 real(kind=rp) :: real_val = 0.0_rp
128 character(len=:),
allocatable :: string_val
132 type(json_file) :: ic_json
133 character(len=:),
allocatable :: json_key
138 call json_get(neko_case%params,
'case.fluid.scheme', string_val)
139 call adjoint_fluid_scheme_factory(this%fluid_adj, trim(string_val))
141 call json_get(neko_case%params,
'case.numerics.polynomial_order', lx)
143 call this%fluid_adj%init(neko_case%msh, lx, neko_case%params, &
144 neko_case%usr, neko_case%fluid%ext_bdf)
156 if (this%have_scalar)
then
157 allocate(this%scalar_adj)
164 call this%scalar_adj%init(neko_case%msh, neko_case%fluid%c_Xh, &
165 neko_case%fluid%gs_Xh, neko_case%params, neko_case%usr, &
166 neko_case%fluid%ulag, neko_case%fluid%vlag, &
167 neko_case%fluid%wlag, neko_case%fluid%ext_bdf, neko_case%fluid%rho)
204 allocate(this%adjoint_convection_term)
206 call this%adjoint_convection_term%init_from_components( &
207 this%fluid_adj%f_adj_x, this%fluid_adj%f_adj_y, &
208 this%fluid_adj%f_adj_z, this%case%scalar%s, &
209 this%scalar_adj%s_adj, this%fluid_adj%c_Xh)
211 call this%fluid_adj%source_term%add(this%adjoint_convection_term)
233 json_key = json_key_fallback(neko_case%params, &
234 'case.adjoint_fluid.initial_condition',
'case.fluid.initial_condition')
236 call json_extract_object(neko_case%params, json_key, ic_json)
237 call json_get(ic_json,
'type', string_val)
239 if (trim(string_val) .ne.
'user')
then
241 this%fluid_adj%u_adj, this%fluid_adj%v_adj, this%fluid_adj%w_adj, &
242 this%fluid_adj%p_adj, this%fluid_adj%c_Xh, this%fluid_adj%gs_Xh, &
246 this%fluid_adj%u_adj, this%fluid_adj%v_adj, this%fluid_adj%w_adj, &
247 this%fluid_adj%p_adj, this%fluid_adj%c_Xh, this%fluid_adj%gs_Xh, &
248 neko_case%usr%fluid_user_ic, neko_case%params)
251 call neko_log%end_section()
253 if (this%have_scalar)
then
256 call json_get(neko_case%params, &
257 'case.adjoint_scalar.initial_condition.type', string_val)
258 call json_extract_object(neko_case%params, &
259 'case.adjoint_scalar.initial_condition', ic_json)
263 if (trim(string_val) .ne.
'user')
then
264 call set_scalar_ic(this%scalar_adj%s_adj, this%scalar_adj%c_Xh, &
265 this%scalar_adj%gs_Xh, string_val, ic_json)
267 call neko_error(
"user defined ICs not implemented for adjoint scalar")
278 select type (f => this%fluid_adj)
280 call f%ulag%set(f%u_adj)
281 call f%vlag%set(f%v_adj)
282 call f%wlag%set(f%w_adj)
288 call this%fluid_adj%validate
290 if (this%have_scalar)
then
291 call this%scalar_adj%s_adj_lag%set(this%scalar_adj%s_adj)
292 call this%scalar_adj%validate
298 call json_get_or_default(neko_case%params,
'case.output_precision', &
299 string_val,
'single')
301 if (trim(string_val) .eq.
'double')
then
310 call this%output_controller%init(neko_case%time%end_time)
311 if (this%have_scalar)
then
313 this%scalar_adj, path = trim(neko_case%output_directory))
316 path = trim(neko_case%output_directory))
319 call json_get_or_default(neko_case%params,
'case.fluid.output_control',&
322 if (trim(string_val) .eq.
'org')
then
324 call json_get(neko_case%params,
'case.nsamples', real_val)
325 call this%output_controller%add(this%f_out, real_val,
'nsamples')
326 else if (trim(string_val) .eq.
'never')
then
328 call json_get_or_default(neko_case%params,
'case.fluid.output_value', &
330 call this%output_controller%add(this%f_out, 0.0_rp, string_val)
332 call json_get(neko_case%params,
'case.fluid.output_value', real_val)
333 call this%output_controller%add(this%f_out, real_val, string_val)
355 end subroutine adjoint_case_init_common
358 subroutine adjoint_free(this)
359 class(adjoint_case_t),
intent(inout) :: this
362 if (
allocated(this%scalar_adj))
then
363 call this%scalar_adj%free()
366 if (
allocated(this%fluid_adj))
then
367 call this%fluid_adj%free()
369 call this%output_controller%free()
371 end subroutine adjoint_free
373end module adjoint_case
Factory for all adjoint fluid schemes.
Adjoint Pn/Pn formulation.
Defines an output for a adjoint.
Implements the adjoint_scalar_convection_source_term type.
Contains the adjoint_scalar_pnpn_t type.
Contains the adjoint_scalar_scheme_t type.
Adjoint case type. Todo: This should Ideally be a subclass of case_t, however, that is not yet suppor...
Base type of all fluid formulations.
Base type for a scalar advection-diffusion solver.