Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
neko_ext.f90
Go to the documentation of this file.
1
6
9module neko_ext
10 use case, only: case_t
11 use json_utils, only: json_get, json_get_or_default, json_extract_object, &
12 json_extract_item
13 use num_types, only: rp
14 use simcomp_executor, only: neko_simcomps
15 use flow_ic, only: set_flow_ic
16 use scalar_ic, only: set_scalar_ic
17 use field, only: field_t
18 use chkp_output, only: chkp_output_t
19 use output_controller, only: output_controller_t
20 ! for vector/field math
21 use math, only: copy
22 use device_math, only: device_copy
23 use neko_config, only : neko_bcknd_device
24 use vector, only: vector_t
25 use field, only: field_t
26 use utils, only: neko_error
27 use json_module, only : json_file
28 use scalars, only: scalars_t
30
31 implicit none
32
33 ! ========================================================================= !
34 ! Module interface
35 ! ========================================================================= !
36 private
39
40contains
41
42 ! ========================================================================= !
43 ! Public routines
44 ! ========================================================================= !
45
54 subroutine reset(neko_case)
55 type(case_t), intent(inout) :: neko_case
56 real(kind=rp) :: t
57 integer :: i, n_scalars
58 character(len=:), allocatable :: string_val
59 logical :: has_scalar, freezeflow
60 type(field_t), pointer :: u, v, w, p, s
61 type(json_file) :: json_subdict, scalar_params
62
63 ! ------------------------------------------------------------------------ !
64 ! Setup shorthand notation
65 ! ------------------------------------------------------------------------ !
66
67 u => neko_case%fluid%u
68 v => neko_case%fluid%v
69 w => neko_case%fluid%w
70 p => neko_case%fluid%p
71 if (allocated(neko_case%scalars)) then
72 s => neko_case%scalars%scalar_fields(1)%s
73 else
74 nullify(s)
75 end if
76
77 ! ------------------------------------------------------------------------ !
78 ! Reset the timing parameters
79 ! ------------------------------------------------------------------------ !
80
81 t = 0.0_rp
82 neko_case%time%t = t
83 neko_case%time%tstep = 0
84
85 ! Setup lagged time step parameters
86 neko_case%time%tlag = t
87 neko_case%time%dtlag = neko_case%time%dt
88 do i = 1, size(neko_case%time%tlag)
89 neko_case%time%tlag(i) = t - i*neko_case%time%dtlag(i)
90 end do
91
92 ! Reset the time step counter
93 call neko_case%output_controller%set_counter(neko_case%time)
94
95 ! Restart the fields
96 call neko_case%fluid%restart(neko_case%chkp)
97 if (allocated(neko_case%scalars)) then
98 call neko_case%scalars%restart(neko_case%chkp)
99 end if
100
101 ! Reset the external BDF coefficients
102 do i = 1, size(neko_case%time%dtlag)
103 call neko_case%fluid%ext_bdf%set_coeffs(neko_case%time%dtlag)
104 end do
105
106 ! Restart the simulation components
107 call neko_simcomps%restart(neko_case%time)
108
109 ! ------------------------------------------------------------------------ !
110 ! Reset the fluid field to the initial condition
111 ! ------------------------------------------------------------------------ !
112
113 call json_get(neko_case%params, &
114 'case.fluid.initial_condition.type', string_val)
115 call json_extract_object(neko_case%params, 'case.fluid.initial_condition', &
116 json_subdict)
117
118 if (trim(string_val) .ne. 'user') then
119 call set_flow_ic(u, v, w, p, &
120 neko_case%fluid%c_Xh, neko_case%fluid%gs_Xh, &
121 string_val, json_subdict)
122 else
123 call set_flow_ic(u, v, w, p, &
124 neko_case%fluid%c_Xh, neko_case%fluid%gs_Xh, &
125 neko_case%user%fluid_user_ic, neko_case%params)
126 end if
127
128 ! ------------------------------------------------------------------------ !
129 ! Reset the scalar field to the initial condition
130 ! ------------------------------------------------------------------------ !
131
132 call json_get_or_default(neko_case%params, &
133 'case.scalar.enabled', has_scalar, .false.)
134
135 if (has_scalar) then
136 if (neko_case%params%valid_path('case.adjoint_scalar')) then
137 ! we shouldn't fallback to the primal here.
138 call json_get(neko_case%params, &
139 'case.adjoint_scalar.initial_condition.type', string_val)
140 call json_extract_object(neko_case%params, &
141 'case.adjoint_scalar.initial_condition', json_subdict)
142
143 !call neko_log%section("Adjoint scalar initial condition ")
144
145 if (trim(string_val) .ne. 'user') then
146 call set_scalar_ic(neko_case%scalars%scalar_fields(1)%s, &
147 neko_case%fluid%c_Xh, neko_case%fluid%gs_Xh, string_val, &
148 json_subdict)
149 else
150 call neko_error("user defined ICs not implemented for " // &
151 "adjoint scalar")
152 ! call set_scalar_ic(this%adjoint_scalars%s_adj, &
153 ! this%adjoint_scalars%c_Xh, this%adjoint_scalars%gs_Xh, &
154 ! this%usr%scalar_user_ic, neko_case%params)
155 end if
156
157 ! call neko_log%end_section()
158 else
159
160 ! Handle multiple scalars
161 call neko_case%params%info('case.scalars', n_children = n_scalars)
162
163 do i = 1, n_scalars
164 call json_extract_item(neko_case%params, 'case.adjoint_scalars', &
165 i, scalar_params)
166 call json_get(scalar_params, 'initial_condition.type', string_val)
167 call json_extract_object(scalar_params, 'initial_condition', &
168 json_subdict)
169
170 if (trim(string_val) .ne. 'user') then
171 call set_scalar_ic(neko_case%scalars%scalar_fields(i)%s, &
172 neko_case%scalars%scalar_fields(i)%c_Xh, &
173 neko_case%scalars%scalar_fields(i)%gs_Xh, string_val, &
174 json_subdict)
175 else
176 call neko_error("user defined ICs not implemented for " // &
177 "adjoint scalar")
178 end if
179 end do
180 end if
181 end if
182
183 ! ------------------------------------------------------------------------ !
184 ! Reset the "freeze" parameter of the flow
185 ! ------------------------------------------------------------------------ !
186
187 call json_get_or_default(neko_case%params, &
188 'case.fluid.freeze_flow', freezeflow, .false.)
189
190 neko_case%fluid%freeze = freezeflow
191
192 end subroutine reset
193
202 subroutine setup_iteration(neko_case, iter)
203 type(case_t), intent(inout) :: neko_case
204 integer, intent(in) :: iter
205
206 character(len=:), allocatable :: dirname
207 character(len=80) :: file_name
208
209 if (iter .ne. 1) then
210 call reset(neko_case)
211 end if
212
213 call json_get_or_default(neko_case%params, &
214 'case.output_directory', dirname, './')
215
216 write (file_name, '(a,a,i5.5,a)') &
217 trim(adjustl(dirname)), '/topopt_', iter, '_.fld'
218
219 neko_case%f_out%output_t%file_%file_type%fname = trim(file_name)
220 neko_case%f_out%output_t%file_%file_type%counter = 0
221 neko_case%f_out%output_t%file_%file_type%start_counter = 0
222 call neko_case%output_controller%execute(neko_case%time, .true.)
223
224 end subroutine setup_iteration
225
233 subroutine vector_to_field(field, vector)
234 type(field_t), intent(inout) :: field
235 type(vector_t), intent(in) :: vector
236
237 ! first check they're the same size
238 if (field%size() .ne. vector%size()) then
239 call neko_error("vector and field are not the same size")
240 end if
241
242 if (neko_bcknd_device .eq. 1) then
243 call device_copy(field%x_d, vector%x_d, field%size())
244 else
245 call copy(field%x, vector%x, field%size())
246 end if
247
248 end subroutine vector_to_field
249
257 subroutine field_to_vector(vector, field)
258 type(vector_t), intent(inout) :: vector
259 type(field_t), intent(in) :: field
260
261 ! first check they're the same size
262 if (field%size() .ne. vector%size()) then
263 call neko_error("vector and field are not the same size")
264 end if
265
266 if (neko_bcknd_device .eq. 1) then
267 call device_copy(vector%x_d, field%x_d, field%size())
268 else
269 call copy(vector%x, field%x, field%size())
270 end if
271
272 end subroutine field_to_vector
273
282 subroutine get_scalar_indicies(i_primal, i_adjoint, scalars, &
283 adjoint_scalars, primal_name)
284 integer, intent(out) :: i_primal
285 integer, intent(out) :: i_adjoint
286 type(scalars_t), intent(inout) :: scalars
287 type(adjoint_scalars_t), intent(inout) :: adjoint_scalars
288 character(len=*), intent(in) :: primal_name
289 integer :: i, n_primal_scalars, n_adjoint_scalars
290
291 i_primal = -1
292 i_adjoint = -1
293 n_adjoint_scalars = size(adjoint_scalars%adjoint_scalar_fields)
294 n_primal_scalars = size(scalars%scalar_fields)
295
296 if ((n_adjoint_scalars .eq. 1) .and. (n_primal_scalars .eq. 1)) then
297 i_primal = 1
298 i_adjoint = 1
299 return
300 end if
301
302 do i = 1, n_adjoint_scalars
303 if (adjoint_scalars%adjoint_scalar_fields(i)%primal_name &
304 .eq. primal_name) then
305 i_adjoint = i
306 exit
307 end if
308 end do
309
310 do i = 1, n_primal_scalars
311 if (scalars%scalar_fields(i)%name .eq. primal_name) then
312 i_primal = i
313 exit
314 end if
315 end do
316
317 if (i_primal .le. 0 .or. i_adjoint .le. 0) then
318 call neko_error('could not find matching primal and adjoint' // &
319 ' scalar fields')
320 end if
321
322 end subroutine get_scalar_indicies
323
324end module neko_ext
Contains the adjoint_scalars_t type that manages multiple scalar fields.
Contains extensions to the neko library required to run the topology optimization code.
Definition neko_ext.f90:9
subroutine, public field_to_vector(vector, field)
Field to vector.
Definition neko_ext.f90:258
subroutine, public reset(neko_case)
Reset the case data structure.
Definition neko_ext.f90:55
subroutine, public vector_to_field(field, vector)
Vector to field.
Definition neko_ext.f90:234
subroutine, public setup_iteration(neko_case, iter)
Setup the iteration.
Definition neko_ext.f90:203
subroutine, public get_scalar_indicies(i_primal, i_adjoint, scalars, adjoint_scalars, primal_name)
get scalar indices
Definition neko_ext.f90:284
Type to manage multiple adjoint scalar transport equations.