35 use simulation_component,
only: simulation_component_t
36 use num_types,
only: rp, dp
37 use field,
only: field_t
38 use json_module,
only: json_file
39 use json_utils,
only: json_get_or_default
40 use case,
only: case_t
41 use field_math,
only: field_sub2, field_copy
43 use device_math,
only: device_glsc3
44 use coefs,
only: coef_t
45 use neko_config,
only : neko_bcknd_device
46 use csv_file,
only : csv_file_t
47 use vector,
only: vector_t
48 use time_state,
only: time_state_t
49 use utils,
only: neko_error
61 type(field_t) :: u_old, v_old, w_old, p_old, s_old
64 logical :: have_scalar = .false.
67 type(csv_file_t) :: logger
69 integer :: log_frequency
71 type(vector_t) :: log_data
75 procedure,
public, pass(this) :: init => steady_simcomp_init_from_json
77 procedure,
public, pass(this) :: init_from_attributes => &
78 steady_simcomp_init_from_attributes
80 procedure,
public, pass(this) :: free => steady_simcomp_free
82 procedure,
public, pass(this) :: compute_ => steady_simcomp_compute
88 subroutine steady_simcomp_init_from_json(this, json, case)
90 type(json_file),
intent(inout) :: json
91 class(case_t),
intent(inout),
target :: case
93 integer :: log_frequency
95 call this%init_base(json, case)
98 call json_get_or_default(json,
"tol", tol, 1.0e-6_dp)
100 call json_get_or_default(json,
"log_frequency", log_frequency, 50)
101 call json_get_or_default(json,
"scalar_coupled", this%have_scalar, .false.)
103 call this%init_from_attributes(tol, log_frequency)
105 end subroutine steady_simcomp_init_from_json
108 subroutine steady_simcomp_init_from_attributes(this, tol, log_frequency)
110 real(kind=dp),
intent(in) :: tol
111 integer,
intent(in) :: log_frequency
114 this%log_frequency = log_frequency
117 call this%logger%init(
'steady_state_data.csv')
118 call this%logger%set_header(
'iter,time,u,v,w,p,t')
119 call this%log_data%init(7)
122 call this%u_old%init(this%case%fluid%u%dof)
123 call this%v_old%init(this%case%fluid%v%dof)
124 call this%w_old%init(this%case%fluid%w%dof)
125 call this%p_old%init(this%case%fluid%p%dof)
128 if (this%have_scalar)
then
129 call this%s_old%init(this%case%scalars%scalar_fields(1)%s%dof)
132 end subroutine steady_simcomp_init_from_attributes
135 subroutine steady_simcomp_free(this)
138 call this%u_old%free()
139 call this%v_old%free()
140 call this%w_old%free()
141 call this%p_old%free()
142 call this%s_old%free()
143 call this%log_data%free()
145 call this%free_base()
147 end subroutine steady_simcomp_free
150 subroutine steady_simcomp_compute(this, time)
152 type(time_state_t),
intent(in) :: time
157 real(kind=rp),
dimension(5) :: normed_diff
158 type(field_t),
pointer :: u, v, w, p, s
161 if (this%case%fluid%freeze)
return
166 dt = this%case%time%dt
174 u => this%case%fluid%u
175 v => this%case%fluid%v
176 w => this%case%fluid%w
177 p => this%case%fluid%p
179 if (this%have_scalar)
then
180 if (
size(this%case%scalars%scalar_fields) .gt. 1)
then
181 call neko_error(
'steady simcomp only works for a single scalar')
183 s => this%case%scalars%scalar_fields(1)%s
189 call field_sub2(this%u_old, u)
190 call field_sub2(this%v_old, v)
191 call field_sub2(this%w_old, w)
192 call field_sub2(this%p_old, p)
193 if (this%have_scalar)
then
194 call field_sub2(this%s_old, s)
199 normed_diff(1) = energy_norm(this%u_old, this%case%fluid%C_Xh, dt)
200 normed_diff(2) = energy_norm(this%v_old, this%case%fluid%C_Xh, dt)
201 normed_diff(3) = energy_norm(this%w_old, this%case%fluid%C_Xh, dt)
202 normed_diff(4) = energy_norm(this%p_old, this%case%fluid%C_Xh, dt)
203 if (this%have_scalar)
then
204 normed_diff(5) = energy_norm(this%s_old, this%case%fluid%C_Xh, dt)
206 normed_diff(5) = 0.0_rp
212 if (maxval(normed_diff) .gt. this%tol)
then
213 call field_copy(this%u_old, u)
214 call field_copy(this%v_old, v)
215 call field_copy(this%w_old, w)
216 call field_copy(this%p_old, p)
217 if (this%have_scalar)
then
218 call field_copy(this%s_old, s)
223 if (mod(tstep, this%log_frequency) .eq. 0)
then
224 this%log_data%x(1) = real(tstep, kind=rp)
225 this%log_data%x(2) = t
226 this%log_data%x(3) = normed_diff(1)
227 this%log_data%x(4) = normed_diff(2)
228 this%log_data%x(5) = normed_diff(3)
229 this%log_data%x(6) = normed_diff(4)
230 this%log_data%x(7) = normed_diff(5)
231 call this%logger%write(this%log_data)
235 this%case%fluid%freeze = .true.
236 if (this%have_scalar)
then
244 end subroutine steady_simcomp_compute
250 function energy_norm(delta_fld, coef, dt)
251 type(field_t),
intent(in) :: delta_fld
252 type(coef_t),
intent(in) :: coef
253 real(kind=rp),
intent(in) :: dt
254 real(kind=rp) :: energy_norm, tmp
258 if (neko_bcknd_device .eq. 1)
then
259 tmp = device_glsc3(delta_fld%x_d, delta_fld%x_d, coef%B_d, n)
261 tmp = glsc3(delta_fld%x, delta_fld%x, coef%B, n)
263 energy_norm = sqrt(tmp) / dt / coef%volume
265 end function energy_norm
Implements the steady_simcomp_t type.
The steady_simcomp_t type is a simulation component that terminates a simulation when the normed diff...