Neko 0.9.99
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scalar_ic.f90
Go to the documentation of this file.
1! Copyright (c) 2021, 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!
35 use gather_scatter, only : gs_t, gs_op_add
37 use num_types, only : rp
38 use device_math, only : device_col2
40 use field, only : field_t
43 use coefs, only : coef_t
44 use math, only : col2, cfill, cfill_mask
45 use user_intf, only : useric_scalar
46 use json_module, only : json_file
48 use point_zone, only: point_zone_t
51 use logger, only: neko_log, log_size
53 use fld_file, only: fld_file_t
54 use checkpoint, only: chkp_t
55 use file, only: file_t
58 use space, only: space_t, gll
59 implicit none
60 private
61
62 interface set_scalar_ic
63 module procedure set_scalar_ic_int, set_scalar_ic_usr
64 end interface set_scalar_ic
65
66 public :: set_scalar_ic
67
68contains
69
81 subroutine set_scalar_ic_int(s, coef, gs, type, params)
82 type(field_t), intent(inout) :: s
83 type(coef_t), intent(in) :: coef
84 type(gs_t), intent(inout) :: gs
85 character(len=*) :: type
86 type(json_file), intent(inout) :: params
87
88 ! Variables for retrieving JSON parameters
89 real(kind=rp) :: ic_value
90 character(len=:), allocatable :: read_str
91 character(len=NEKO_FNAME_LEN) :: fname, mesh_fname
92 real(kind=rp) :: zone_value, tol
93 logical :: interpolate
94
95 if (trim(type) .eq. 'uniform') then
96
97 call json_get(params, 'case.scalar.initial_condition.value', ic_value)
98 call set_scalar_ic_uniform(s, ic_value)
99
100 else if (trim(type) .eq. 'point_zone') then
101
102 call json_get(params, 'case.scalar.initial_condition.base_value', &
103 ic_value)
104 call json_get(params, 'case.scalar.initial_condition.zone_name', &
105 read_str)
106 call json_get(params, 'case.scalar.initial_condition.zone_value', &
107 zone_value)
108
109 call set_scalar_ic_point_zone(s, ic_value, read_str, zone_value)
110
111 else if (trim(type) .eq. 'field') then
112
113 call json_get(params, 'case.scalar.initial_condition.file_name', &
114 read_str)
115 fname = trim(read_str)
116 call json_get_or_default(params, &
117 'case.scalar.initial_condition.interpolate', interpolate, &
118 .false.)
119 call json_get_or_default(params, &
120 'case.scalar.initial_condition.tolerance', tol, 0.000001_rp)
121 call json_get_or_default(params, &
122 'case.scalar.initial_condition.mesh_file_name', read_str, &
123 "none")
124 mesh_fname = trim(read_str)
125
126 call set_scalar_ic_fld(s, fname, interpolate, tol, mesh_fname)
127
128 else
129 call neko_error('Invalid initial condition')
130 end if
131
132 call set_scalar_ic_common(s, coef, gs)
133
134 end subroutine set_scalar_ic_int
135
143 subroutine set_scalar_ic_usr(s, coef, gs, usr_ic, params)
144 type(field_t), intent(inout) :: s
145 type(coef_t), intent(in) :: coef
146 type(gs_t), intent(inout) :: gs
147 procedure(useric_scalar) :: usr_ic
148 type(json_file), intent(inout) :: params
149
150 call neko_log%message("Type: user")
151 call usr_ic(s, params)
152
153 call set_scalar_ic_common(s, coef, gs)
154
155 end subroutine set_scalar_ic_usr
156
163 subroutine set_scalar_ic_common(s, coef, gs)
164 type(field_t), intent(inout) :: s
165 type(coef_t), intent(in) :: coef
166 type(gs_t), intent(inout) :: gs
167 integer :: n
168
169 n = s%dof%size()
170 if (neko_bcknd_device .eq. 1) then
171 call device_memcpy(s%x, s%x_d, n, &
172 host_to_device, sync = .false.)
173 end if
174
175 ! Ensure continuity across elements for initial conditions
176 call gs%op(s%x, n, gs_op_add)
177
178 if (neko_bcknd_device .eq. 1) then
179 call device_col2(s%x_d, coef%mult_d, n)
180 else
181 call col2(s%x, coef%mult, n)
182 end if
183
184 end subroutine set_scalar_ic_common
185
190 subroutine set_scalar_ic_uniform(s, ic_value)
191 type(field_t), intent(inout) :: s
192 real(kind=rp), intent(in) :: ic_value
193 integer :: n
194 character(len=LOG_SIZE) :: log_buf
195
196 call neko_log%message("Type : uniform")
197 write (log_buf, '(A,ES12.6)') "Value: ", ic_value
198 call neko_log%message(log_buf)
199
200 s = ic_value
201 n = s%dof%size()
202 if (neko_bcknd_device .eq. 1) then
203 call cfill(s%x, ic_value, n)
204 end if
205
206 end subroutine set_scalar_ic_uniform
207
215 subroutine set_scalar_ic_point_zone(s, base_value, zone_name, zone_value)
216 type(field_t), intent(inout) :: s
217 real(kind=rp), intent(in) :: base_value
218 character(len=*), intent(in) :: zone_name
219 real(kind=rp), intent(in) :: zone_value
220
221 ! Internal variables
222 character(len=LOG_SIZE) :: log_buf
223 class(point_zone_t), pointer :: zone
224 integer :: size
225
226 call neko_log%message("Type : point_zone")
227 write (log_buf, '(A,ES12.6)') "Base value: ", base_value
228 call neko_log%message(log_buf)
229 call neko_log%message("Zone name : " // trim(zone_name))
230 write (log_buf, '(A,ES12.6)') "Zone value: ", zone_value
231 call neko_log%message(log_buf)
232
233 size = s%dof%size()
234 zone => neko_point_zone_registry%get_point_zone(trim(zone_name))
235
236 call set_scalar_ic_uniform(s, base_value)
237 call cfill_mask(s%x, zone_value, size, zone%mask, zone%size)
238
239 end subroutine set_scalar_ic_point_zone
240
255 subroutine set_scalar_ic_fld(s, file_name, &
256 interpolate, tolerance, mesh_file_name)
257 type(field_t), intent(inout) :: s
258 character(len=*), intent(in) :: file_name
259 logical, intent(in) :: interpolate
260 real(kind=rp), intent(in) :: tolerance
261 character(len=*), intent(inout) :: mesh_file_name
262
263 character(len=LOG_SIZE) :: log_buf
264 integer :: sample_idx, sample_mesh_idx
265 integer :: last_index
266 type(fld_file_data_t) :: fld_data
267 type(file_t) :: f
268 logical :: mesh_mismatch
269
270 ! ---- For the mesh to mesh interpolation
271 type(global_interpolation_t) :: global_interp
272 ! -----
273
274 ! ---- For space to space interpolation
275 type(space_t) :: prev_Xh
276 type(interpolator_t) :: space_interp
277 ! ----
278
279 call neko_log%message("Type : field")
280 call neko_log%message("File name : " // trim(file_name))
281 write (log_buf, '(A,L1)') "Interpolation : ", interpolate
282 call neko_log%message(log_buf)
283 if (interpolate) then
284 end if
285
286 ! Extract sample index from the file name
287 sample_idx = extract_fld_file_index(file_name, -1)
288
289 if (sample_idx .eq. -1) &
290 call neko_error("Invalid file name for the initial condition. The&
291 & file format must be e.g. 'mean0.f00001'")
292
293 ! Change from "field0.f000*" to "field0.fld" for the fld reader
294 call filename_chsuffix(file_name, file_name, 'fld')
295
296 call fld_data%init
297 f = file_t(trim(file_name))
298
299 if (interpolate) then
300
301 ! If no mesh file is specified, use the default file name
302 if (mesh_file_name .eq. "none") then
303 mesh_file_name = trim(file_name)
304 sample_mesh_idx = sample_idx
305 else
306
307 ! Extract sample index from the mesh file name
308 sample_mesh_idx = extract_fld_file_index(mesh_file_name, -1)
309
310 if (sample_mesh_idx .eq. -1) &
311 call neko_error("Invalid file name for the initial condition. &
312&The file format must be e.g. 'mean0.f00001'")
313
314 write (log_buf, '(A,ES12.6)') "Tolerance : ", tolerance
315 call neko_log%message(log_buf)
316 write (log_buf, '(A,A)') "Mesh file : ", &
317 trim(mesh_file_name)
318 call neko_log%message(log_buf)
319
320 end if ! if mesh_file_name .eq. none
321
322 ! Read the mesh coordinates if they are not in our fld file
323 if (sample_mesh_idx .ne. sample_idx) then
324 call f%set_counter(sample_mesh_idx)
325 call f%read(fld_data)
326 end if
327
328 end if
329
330 ! Read the field file containing (u,v,w,p)
331 call f%set_counter(sample_idx)
332 call f%read(fld_data)
333
334 !
335 ! Check that the data in the fld file matches the current case.
336 ! Note that this is a safeguard and there are corner cases where
337 ! two different meshes have the same dimension and same # of elements
338 ! but this should be enough to cover obvious cases.
339 !
340 mesh_mismatch = (fld_data%glb_nelv .ne. s%msh%glb_nelv .or. &
341 fld_data%gdim .ne. s%msh%gdim)
342
343 if (mesh_mismatch .and. .not. interpolate) then
344 call neko_error("The fld file must match the current mesh! &
345&Use 'interpolate': 'true' to enable interpolation.")
346 else if (.not. mesh_mismatch .and. interpolate) then
347 call neko_log%warning("You have activated interpolation but you might &
348&still be using the same mesh.")
349 end if
350
351
352 ! Mesh interpolation if specified
353 if (interpolate) then
354 ! Issue a warning if the mesh is in single precision
355 select type (ft => f%file_type)
356 type is (fld_file_t)
357 if (.not. ft%dp_precision) then
358 call neko_warning("The coordinates read from the field file are &
359&in single precision.")
360 call neko_log%message("It is recommended to use a mesh in double &
361&precision for better interpolation results.")
362 call neko_log%message("If the interpolation does not work, you&
363&can try to increase the tolerance.")
364 end if
365 class default
366 end select
367
368 ! Generates an interpolator object and performs the point search
369 global_interp = fld_data%generate_interpolator(s%dof, s%msh, tolerance)
370
371 ! Evaluate scalar
372 call global_interp%evaluate(s%x, fld_data%t%x)
373 call global_interp%free
374
375 else ! No interpolation, just potentially from different spaces
376
377 ! Build a space_t object from the data in the fld file
378 call prev_xh%init(gll, fld_data%lx, fld_data%ly, fld_data%lz)
379 call space_interp%init(s%Xh, prev_xh)
380
381 ! Do the space-to-space interpolation
382 call space_interp%map_host(s%x, fld_data%t%x, fld_data%nelv, s%Xh)
383
384 call space_interp%free
385
386 end if
387
388 call fld_data%free
389
390 end subroutine set_scalar_ic_fld
391
392end module scalar_ic
Copy data between host and device (or device and device)
Definition device.F90:51
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.
Abstract interface for user defined scalar initial conditions.
Definition user_intf.f90:70
Defines a checkpoint.
Coefficients.
Definition coef.f90:34
subroutine, public device_col2(a_d, b_d, n)
Vector multiplication .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:47
Defines a registry for storing solution fields.
type(field_registry_t), target, public neko_field_registry
Global field registry.
Defines a field.
Definition field.f90:34
Module for file I/O operations.
Definition file.f90:34
Simple module to handle fld file series. Provides an interface to the different fields sotred in a fl...
NEKTON fld file format.
Definition fld_file.f90:35
Gather-scatter.
Implements global_interpolation given a dofmap.
Routines to interpolate between different spaces.
Utilities for retrieving parameters from the case files.
Logging routines.
Definition log.f90:34
type(log_t), public neko_log
Global log stream.
Definition log.f90:65
integer, parameter, public log_size
Definition log.f90:42
Definition math.f90:60
subroutine, public cfill(a, c, n)
Set all elements to a constant c .
Definition math.f90:347
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:728
subroutine, public cfill_mask(a, c, size, mask, mask_size)
Fill a constant to a masked vector. .
Definition math.f90:296
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
type(point_zone_registry_t), target, public neko_point_zone_registry
Global point_zone registry.
Scalar initial condition.
Definition scalar_ic.f90:34
subroutine set_scalar_ic_uniform(s, ic_value)
Uniform initial condition.
subroutine set_scalar_ic_point_zone(s, base_value, zone_name, zone_value)
Point zone initial condition.
subroutine set_scalar_ic_common(s, coef, gs)
Set scalar initial condition (common)
subroutine set_scalar_ic_usr(s, coef, gs, usr_ic, params)
Set scalar intial condition (user defined)
subroutine set_scalar_ic_fld(s, file_name, interpolate, tolerance, mesh_file_name)
Set the initial condition of the scalar based on a field. @detail The field is read from an fld file....
subroutine set_scalar_ic_int(s, coef, gs, type, params)
Set scalar initial condition (builtin)
Definition scalar_ic.f90:82
Defines a function space.
Definition space.f90:34
integer, parameter, public gll
Definition space.f90:48
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
integer function, public extract_fld_file_index(fld_filename, default_index)
Extracts the index of a field file. For example, "myfield.f00045" will return 45. If the suffix of th...
Definition utils.f90:94
integer, parameter, public neko_fname_len
Definition utils.f90:40
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Definition utils.f90:266
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Definition utils.f90:77
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
Definition utils.f90:70
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:55
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition file.f90:54
Interface for NEKTON fld files.
Definition fld_file.f90:64
Implements global interpolation for arbitrary points in the domain.
Interpolation between two space::space_t.
Base abstract type for point zones.
The function space for the SEM solution fields.
Definition space.f90:62