Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
fluid_output.f90
Go to the documentation of this file.
1! Copyright (c) 2020-2023, 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 num_types, only : rp
40 use field_list, only : field_list_t
42 use device
43 use output, only : output_t
44 use scalars, only : scalars_t
46 use field, only : field_t
47 implicit none
48 private
49
51 type, public, extends(output_t) :: fluid_output_t
52 type(field_list_t) :: fluid
53 contains
54 procedure, pass(this) :: init => fluid_output_init
55 procedure, pass(this) :: sample => fluid_output_sample
56 procedure, pass(this) :: free => fluid_output_free
57 end type fluid_output_t
58
59contains
60
61 subroutine fluid_output_init(this, precision, fluid, scalar_fields, name, path, &
62 fmt, layout)
63 class(fluid_output_t), intent(inout) :: this
64 integer, intent(inout) :: precision
65 class(fluid_scheme_base_t), intent(in), target :: fluid
66 class(scalars_t), intent(in), optional, target :: scalar_fields
67 character(len=*), intent(in), optional :: name
68 character(len=*), intent(in), optional :: path
69 character(len=*), intent(in), optional :: fmt
70 integer, intent(in), optional :: layout
71 character(len=1024) :: fname
72 integer :: i, j, n_scalars
73 character(len=10) :: suffix
74 logical :: has_max_wave_speed, has_density
75 type(field_t), pointer :: max_wave_speed_field
76
77 suffix = '.fld'
78 if (present(fmt)) then
79 if (fmt .eq. 'adios2') then
80 suffix = '.bp'
81 end if
82 end if
83
84 if (present(name) .and. present(path)) then
85 fname = trim(path) // trim(name) // trim(suffix)
86 else if (present(name)) then
87 fname = trim(name) // trim(suffix)
88 else if (present(path)) then
89 fname = trim(path) // 'field' // trim(suffix)
90 else
91 fname = 'field' // trim(suffix)
92 end if
93
94 if (present(layout)) then
95 call this%init_base(fname, precision, layout)
96 else
97 call this%init_base(fname, precision)
98 end if
99
100 ! Calculate total number of fields
101 n_scalars = 0
102 if (present(scalar_fields)) then
103 n_scalars = size(scalar_fields%scalar_fields)
104 end if
105
106 ! Check if max_wave_speed field exists (for compressible flows)
107 has_max_wave_speed = neko_field_registry%field_exists("max_wave_speed")
108
109 ! Check if density field exists (for compressible flows)
110 ! We need to check the solver type here since the incompressible
111 ! solver also has a rho field due to the material properties
112 select type (fluid)
114 has_density = associated(fluid%rho)
115 class default
116 has_density = .false.
117 end select
118
119 ! Initialize field list with appropriate size
120 ! Standard fields: p, u, v, w (4)
121 ! Scalar fields: n_scalars
122 ! Compressible fields: density + max_wave_speed (2 additional)
123 i = 4
124
125 if (has_density) then
126 i = i + 1
127 end if
128
129 if (has_max_wave_speed) then
130 i = i + 1
131 end if
132
133 call this%fluid%init(i + n_scalars)
134
135 call this%fluid%assign(1, fluid%p)
136 call this%fluid%assign(2, fluid%u)
137 call this%fluid%assign(3, fluid%v)
138 call this%fluid%assign(4, fluid%w)
139
140 ! Assign all scalar fields first
141 i = 4
142 if (present(scalar_fields)) then
143 do j = 1, n_scalars
144 i = i + 1
145 call this%fluid%assign(i, scalar_fields%scalar_fields(j)%s)
146 end do
147 end if
148
149 ! Add density field if it exists (for compressible flows)
150 if (has_density) then
151 i = i + 1
152 call this%fluid%assign(i, fluid%rho)
153 end if
154
155 ! Add max_wave_speed field if it exists (for compressible flows)
156 if (has_max_wave_speed) then
157 i = i + 1
158 max_wave_speed_field => neko_field_registry%get_field("max_wave_speed")
159 call this%fluid%assign(i, max_wave_speed_field)
160 end if
161
162 end subroutine fluid_output_init
163
165 subroutine fluid_output_free(this)
166 class(fluid_output_t), intent(inout) :: this
167
168 call this%fluid%free()
169
170 end subroutine fluid_output_free
171
173 subroutine fluid_output_sample(this, t)
174 class(fluid_output_t), intent(inout) :: this
175 real(kind=rp), intent(in) :: t
176 integer :: i
177
178 if (neko_bcknd_device .eq. 1) then
179
180 associate(fields => this%fluid%items)
181 do i = 1, size(fields)
182 call device_memcpy(fields(i)%ptr%x, fields(i)%ptr%x_d, &
183 fields(i)%ptr%dof%size(), device_to_host, &
184 sync = (i .eq. size(fields))) ! Sync on the last field
185 end do
186 end associate
187
188 end if
189
190 call this%file_%write(this%fluid, t)
191
192 end subroutine fluid_output_sample
193
194end module fluid_output
Copy data between host and device (or device and device)
Definition device.F90:66
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public device_to_host
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
Defines an output for a fluid.
subroutine fluid_output_sample(this, t)
Sample a fluid solution at time t.
subroutine fluid_output_free(this)
Destroy a fluid output list.
subroutine fluid_output_init(this, precision, fluid, scalar_fields, name, path, fmt, layout)
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Defines an output.
Definition output.f90:34
Contains the scalar_scheme_t type.
Contains the scalars_t type that manages multiple scalar fields.
Definition scalars.f90:35
field_list_t, To be able to group fields together
Base type of all fluid formulations.
Abstract type defining an output type.
Definition output.f90:41
Base type for a scalar advection-diffusion solver.
Type to manage multiple scalar transport equations.
Definition scalars.f90:63