Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scalars.f90
Go to the documentation of this file.
1! Copyright (c) 2022-2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
34
35module scalars
36 use num_types, only : rp
39 use mesh, only : mesh_t
40 use space, only : space_t
41 use gather_scatter, only : gs_t
44 use json_module, only : json_file
46 use field, only : field_t
47 use field_list, only : field_list_t
49 use checkpoint, only : chkp_t
50 use krylov, only : ksp_t, ksp_monitor_t
52 use user_intf, only : user_t
53 use utils, only : neko_error
54 use coefs, only : coef_t
55 use time_state, only : time_state_t
56 implicit none
57 private
58
60 type, public :: scalars_t
62 type(scalar_scheme_wrapper_t), allocatable :: scalar_fields(:)
64 class(ksp_t), allocatable :: shared_ksp
65 contains
68 procedure, private :: scalars_init
69 procedure, private :: scalars_init_single
71 procedure :: step => scalars_step
73 procedure :: restart => scalars_restart
75 procedure :: set_initial_conditions => scalars_set_initial_conditions
77 procedure :: validate => scalars_validate
79 procedure :: free => scalars_free
80 end type scalars_t
81
82contains
83
85 subroutine scalars_init(this, n_scalars, msh, coef, gs, params, &
86 numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
87 class(scalars_t), intent(inout) :: this
88 integer, intent(in) :: n_scalars
89 type(mesh_t), target, intent(in) :: msh
90 type(coef_t), target, intent(in) :: coef
91 type(gs_t), target, intent(inout) :: gs
92 type(json_file), target, intent(inout) :: params
93 type(json_file), target, intent(inout) :: numerics_params
94 type(user_t), target, intent(in) :: user
95 type(field_series_t), target, intent(in) :: ulag, vlag, wlag
96 type(time_scheme_controller_t), target, intent(in) :: time_scheme
97 TYPE(field_t), TARGET, INTENT(IN) :: rho
98 type(chkp_t), target, intent(inout) :: chkp
99 type(json_file) :: json_subdict
100 integer :: i, j
101 character(len=:), allocatable :: field_name
102 character(len=:), allocatable :: field_names(:)
103 character(len=256) :: error_msg, buffer
104
105 ! Allocate the array of the scalar scheme wrappers
106 allocate(this%scalar_fields(n_scalars))
107
108 ! Collect and validate field names for all scalars
109 allocate(character(len=256) :: field_names(n_scalars))
110
111 do i = 1, n_scalars
112 ! Extract element i from the "scalars" array
113 call json_extract_item(params, "", i, json_subdict)
114
115 ! Try to get name from JSON, generate one if not found or empty
116 call json_get_or_default(json_subdict, 'name', field_name, '')
117
118 ! If name is empty or not provided, generate a default one
119 if (len_trim(field_name) == 0) then
120 if (n_scalars == 1) then
121 field_name = 's' ! Single scalar gets default name 's'
122 else
123 write(buffer, '(A,I0)') 's_', i
124 field_name = trim(buffer)
125 end if
126 end if
127
128 field_names(i) = trim(field_name)
129
130 ! If there's a duplicate, append a number until unique
131 if (n_scalars > 1) then
132 j = 1
133 do while (j < i)
134 if (trim(field_names(i)) == trim(field_names(j))) then
135 call neko_error("Duplicate scalar field name detected: "// &
136 trim(field_names(i)) // &
137 ". Please provide unique names for each scalar field.")
138 else
139 j = j + 1
140 end if
141 end do
142 end if
143 end do
144
145 do i = 1, n_scalars
146 call json_extract_item(params, "", i, json_subdict)
147
148 ! Use the processed field names for all scalars
149 call json_subdict%add('name', trim(field_names(i)))
150
151 ! Allocate the scalar fields
152 call this%scalar_fields(i)%init(msh, coef, gs, json_subdict, &
153 numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
154 end do
155 end subroutine scalars_init
156
157 subroutine scalars_init_single(this, msh, coef, gs, params, numerics_params, &
158 user, chkp, ulag, vlag, wlag, time_scheme, rho)
159 class(scalars_t), intent(inout) :: this
160 type(mesh_t), target, intent(in) :: msh
161 type(coef_t), target, intent(in) :: coef
162 type(gs_t), target, intent(inout) :: gs
163 type(json_file), target, intent(inout) :: params
164 type(json_file), target, intent(inout) :: numerics_params
165 type(user_t), target, intent(in) :: user
166 type(chkp_t), target, intent(inout) :: chkp
167 type(field_series_t), target, intent(in) :: ulag, vlag, wlag
168 type(time_scheme_controller_t), target, intent(in) :: time_scheme
169 TYPE(field_t), TARGET, INTENT(IN) :: rho
170
171 ! Allocate a single scalar field
172 allocate(this%scalar_fields(1))
173
174 ! Set the scalar name to "s"
175 if (.not. params%valid_path('name')) then
176 call params%add('name', 's')
177 end if
178
179 ! Initialize it directly with the params
180 call this%scalar_fields(1)%init(msh, coef, gs, params, numerics_params, &
181 user, chkp, ulag, vlag, wlag, time_scheme, rho)
182 end subroutine scalars_init_single
183
185 subroutine scalars_step(this, time, ext_bdf, dt_controller)
186 class(scalars_t), intent(inout) :: this
187 type(time_state_t), intent(in) :: time
188 type(time_scheme_controller_t), intent(inout) :: ext_bdf
189 type(time_step_controller_t), intent(inout) :: dt_controller
190 integer :: i
191 type(ksp_monitor_t), dimension(size(this%scalar_fields)) :: ksp_results
192 logical :: all_frozen
193
194 all_frozen = .true.
195
196 ! Iterate through all scalar fields
197 do i = 1, size(this%scalar_fields)
198 all_frozen = all_frozen .and. this%scalar_fields(i)%scalar%freeze
199 call this%scalar_fields(i)%scalar%step(time, ext_bdf, dt_controller, &
200 ksp_results(i))
201 end do
202
203 if (.not. all_frozen) then
204 call ksp_results(i)%print_header()
205 end if
206
207 do i = 1, size(this%scalar_fields)
208 if (this%scalar_fields(i)%scalar%freeze) cycle
209 call scalar_step_info(time, ksp_results(i))
210 end do
211 end subroutine scalars_step
212
214 subroutine scalars_restart(this, chkp)
215 class(scalars_t), intent(inout) :: this
216 type(chkp_t), intent(inout) :: chkp
217 integer :: i, n_scalars
218
219 n_scalars = size(this%scalar_fields)
220 do i = 1, size(this%scalar_fields)
221 call this%scalar_fields(i)%scalar%restart(chkp)
222 end do
223 end subroutine scalars_restart
224
228 subroutine scalars_set_initial_conditions(this, user, is_restart)
229 class(scalars_t), intent(inout) :: this
230 type(user_t), intent(in) :: user
231 logical, intent(in) :: is_restart
232 integer :: i, running_scalar_index, scalar_index
233
234 call neko_log%section("Scalar initial condition ")
235
236 if (is_restart) then
237 call neko_log%message("Restart file specified, " // &
238 "initial conditions ignored")
239 else
240 running_scalar_index = 0
241 do i = 1, size(this%scalar_fields)
242 if (trim(this%scalar_fields(i)%scalar%name) .eq. 'temperature') then
243 scalar_index = 0
244 else
245 running_scalar_index = running_scalar_index + 1
246 scalar_index = running_scalar_index
247 end if
248
249 call this%scalar_fields(i)%scalar%set_initial_condition(user, &
250 scalar_index)
251 end do
252 end if
253
254 call neko_log%end_section()
255
256 end subroutine scalars_set_initial_conditions
257
259 subroutine scalars_validate(this)
260 class(scalars_t), intent(inout) :: this
261 integer :: i
262 ! Iterate through all scalar fields
263 do i = 1, size(this%scalar_fields)
264 call this%scalar_fields(i)%scalar%slag%set( &
265 this%scalar_fields(i)%scalar%s)
266 call this%scalar_fields(i)%scalar%validate()
267 end do
268 end subroutine scalars_validate
269
271 subroutine scalars_free(this)
272 class(scalars_t), intent(inout) :: this
273 integer :: i
274
275 ! Iterate through all scalar fields
276 if (allocated(this%scalar_fields)) then
277 do i = 1, size(this%scalar_fields)
278 call this%scalar_fields(i)%free()
279 end do
280 deallocate(this%scalar_fields)
281 end if
282
283 if (allocated(this%shared_ksp)) then
284 call this%shared_ksp%free()
285 deallocate(this%shared_ksp)
286 end if
287 end subroutine scalars_free
288
289end module scalars
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Generic buffer that is extended with buffers of varying rank.
Definition buffer.F90:34
Defines format-independent checkpoint registration and restart state.
Coefficients.
Definition coef.f90:34
Contains the field_serties_t type.
Defines a field.
Definition field.f90:34
Gather-scatter.
Utilities for retrieving parameters from the case files.
Implements the base abstract type for Krylov solvers plus helper types.
Definition krylov.f90:34
Logging routines.
Definition log.f90:34
integer, parameter, public neko_log_verbose
Verbose.
Definition log.f90:54
type(log_t), public neko_log
Global log stream.
Definition log.f90:91
integer, parameter, public log_size
Definition log.f90:46
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Auxiliary routines for fluid solvers.
subroutine, public scalar_step_info(time, ksp_results, strict_convergence, allow_stabilization)
Prints for prs, velx, vely, velz the following: Number of iterations, start residual,...
Contains the scalar_scheme_t type.
Contains the scalars_t type that manages multiple scalar fields.
Definition scalars.f90:35
subroutine scalars_validate(this)
Check if the configuration is valid.
Definition scalars.f90:260
subroutine scalars_set_initial_conditions(this, user, is_restart)
Set initial conditions for all scalar fields.
Definition scalars.f90:229
subroutine scalars_init(this, n_scalars, msh, coef, gs, params, numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
Initialize the scalars container.
Definition scalars.f90:87
subroutine scalars_init_single(this, msh, coef, gs, params, numerics_params, user, chkp, ulag, vlag, wlag, time_scheme, rho)
Definition scalars.f90:159
subroutine scalars_free(this)
Clean up all resources.
Definition scalars.f90:272
subroutine scalars_step(this, time, ext_bdf, dt_controller)
Perform a time step for all scalar fields.
Definition scalars.f90:186
subroutine scalars_restart(this, chkp)
Restart from checkpoint data.
Definition scalars.f90:215
Defines a function space.
Definition space.f90:34
Compound scheme for the advection and diffusion operators in a transport equation.
Base class for time integration schemes.
Module with things related to the simulation time.
Implements type time_step_controller.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
Collection of live simulation data registered for checkpointing.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:135
field_list_t, To be able to group fields together
Stores a series (sequence) of fields, logically connected to a base field, and arranged according to ...
Gather-scatter kernel.
Type for storing initial and final residuals in a Krylov solver.
Definition krylov.f90:57
Base abstract type for a canonical Krylov method, solving .
Definition krylov.f90:74
A helper type that is needed to have an array of polymorphic objects.
Type to manage multiple scalar transport equations.
Definition scalars.f90:60
The function space for the SEM solution fields.
Definition space.f90:64
Implements the logic to compute the time coefficients for the advection and diffusion operators in a ...
A struct that contains all info about the time, expand as needed.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...