Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
point_zone_registry.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2024, 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!
33! Implements a point zone registry for storing point zones.
36 point_zone_factory
38 use dofmap, only : dofmap_t
39 use mesh, only : mesh_t
40 use space, only : space_t, gll
41 use utils, only : neko_error
43 use json_module, only : json_file, json_core, json_value
44 implicit none
45 private
46
49 type(point_zone_wrapper_t), allocatable :: point_zones(:)
51 integer, private :: n = 0
53 integer, private :: expansion_size
54 contains
56 procedure, private, pass(this) :: expand
58 procedure, pass(this) :: init => point_zone_registry_init
60 procedure, pass(this) :: free => point_zone_registry_free
62 procedure, pass(this) :: add_point_zone_from_json
64 procedure, pass(this) :: n_point_zones
67 procedure, pass(this) :: get_point_zone_by_index
69 procedure, pass(this) :: get_point_zone_by_name
72 procedure, pass(this) :: get_expansion_size
75 procedure, pass(this) :: get_size
77 procedure, pass(this) :: point_zone_exists
78 generic :: get_point_zone => get_point_zone_by_index, &
80 generic :: add_point_zone => add_point_zone_from_json
82
85
86contains
96 subroutine point_zone_registry_init(this, json, msh, expansion_size)
97 class(point_zone_registry_t), intent(inout) :: this
98 type(json_file), intent(inout) :: json
99 type(mesh_t), target, intent(inout) :: msh
100 integer, optional, intent(in) :: expansion_size
101
102 ! Json low-level manipulator.
103 type(json_core) :: core
104 ! Pointer to the source_terms JSON object and the individual sources.
105 type(json_value), pointer :: source_object, source_pointer
106 ! Buffer for serializing the json.
107 character(len=:), allocatable :: buffer
108 ! A single source term as its own json_file.
109 type(json_file) :: source_subdict
110 logical :: found
111 integer :: n_zones, i, izone
112 character(len=:), allocatable :: type_name
113
114 ! Parameters used to setup the GLL space.
115 integer :: order
116 type(space_t), target :: Xh
117 type(dofmap_t) :: dof
118
119
120 call json_get_or_lookup(json, 'case.numerics.polynomial_order', order)
121 order = order + 1 ! add 1 to get poly order
122
123 if (msh%gdim .eq. 2) then
124 call xh%init(gll, order, order)
125 else
126 call xh%init(gll, order, order, order)
127 end if
128 call dof%init(msh, xh)
129
130 call this%free()
131
132 if (present(expansion_size)) then
133 this%expansion_size = expansion_size
134 else
135 this%expansion_size = 10
136 end if
137
138 this%n = 0
139
140 !
141 ! Count if there are any point zones defined in the json
142 !
143 if (json%valid_path('case.point_zones')) then
144
145 call json%get_core(core)
146 call json%get('case.point_zones', source_object, found)
147
148 n_zones = core%count(source_object)
149 this%n = n_zones
150
151 allocate(this%point_zones(n_zones))
152
153 ! Initialize all the primitive zones
154 izone = 1
155 do i = 1, n_zones
156
157 ! Create a new json containing just the subdict for this source.
158 call core%get_child(source_object, i, source_pointer, found)
159 call core%print_to_string(source_pointer, buffer)
160 call source_subdict%destroy()
161 call source_subdict%load_from_string(buffer)
162
163 call json_get(source_subdict, "geometry", type_name)
164 if (trim(type_name) .ne. "combine") then
165 call point_zone_factory(this%point_zones(izone)%pz, &
166 source_subdict, dof)
167 izone = izone + 1
168 end if
169 end do
170
171 ! Now initialize the combine zones
172 do i = 1, n_zones
173
174 ! Create a new json containing just the subdict for this source.
175 call core%get_child(source_object, i, source_pointer, found)
176 call core%print_to_string(source_pointer, buffer)
177 call source_subdict%destroy()
178 call source_subdict%load_from_string(buffer)
179
180 call json_get(source_subdict, "geometry", type_name)
181 if (trim(type_name) .eq. "combine") then
182 call build_combine_point_zone(this%point_zones(izone)%pz, &
183 source_subdict, dof)
184 izone = izone + 1
185 end if
186 end do
187
188 end if
189
190 call xh%free()
191 call dof%free()
192
193 end subroutine point_zone_registry_init
194
201 subroutine build_combine_point_zone(object, json, dof)
202 class(point_zone_t), allocatable, target, intent(inout) :: object
203 type(json_file), intent(inout) :: json
204 type(dofmap_t), intent(inout) :: dof
205
206 type(combine_point_zone_t), pointer :: cpz
207 integer :: i, i_external
208
209 allocate(combine_point_zone_t::object)
210
211 ! Here we initialize all the names of the zones to combine
212 call object%init(json, dof%size())
213
214 select type (object)
215 type is (combine_point_zone_t)
216 cpz => object
217 class default
218 end select
219
220 i_external = 1
221 ! Load the external zones in the combine zone array
222 do i = cpz%n_internal_zones + 1, cpz%n_zones
223 cpz%zones(i)%pz => &
224 neko_point_zone_registry%get_point_zone(cpz%names(i_external))
225 end do
226
227 call object%map(dof)
228 call object%finalize()
229
230 end subroutine build_combine_point_zone
231
234 class(point_zone_registry_t), intent(inout) :: this
235 integer :: i
236
237 if (allocated(this%point_zones)) then
238
239 do i = 1, this%n_point_zones()
240 call this%point_zones(i)%pz%free()
241 end do
242
243 deallocate(this%point_zones)
244
245 end if
246
247 this%n = 0
248 this%expansion_size = 0
249 end subroutine point_zone_registry_free
250
252 subroutine expand(this)
253 class(point_zone_registry_t), intent(inout) :: this
254 type(point_zone_wrapper_t), allocatable :: temp(:)
255
256 allocate(temp(this%n + this%expansion_size))
257 temp(1:this%n) = this%point_zones(1:this%n)
258 call move_alloc(temp, this%point_zones)
259
260 end subroutine expand
261
265 subroutine add_point_zone_from_json(this, json, dof)
266 class(point_zone_registry_t), intent(inout) :: this
267 type(json_file), intent(inout) :: json
268 type(dofmap_t), target, intent(inout) :: dof
269! type(h_cptr_t) :: key
270 character(len=:), allocatable :: str_read
271
272 !
273 ! Allocate the point zones array as it was not necessarily done
274 ! in init
275 !
276 if (.not. allocated(this%point_zones)) then
277 allocate(this%point_zones(this%expansion_size))
278 end if
279
280 call json_get(json, "name", str_read)
281
282 ! Check if point zone exists with the input name
283 if (this%point_zone_exists(trim(str_read))) then
284 call neko_error("Field with name " // trim(str_read) // &
285 " is already registered")
286 end if
287
288 !
289 ! This will always be true if point_zones was allocated in
290 ! init.
291 !
292 if (this%n_point_zones() .eq. this%get_size()) then
293 call this%expand()
294 end if
295
296 this%n = this%n + 1
297
298 ! initialize the point_zone at the appropriate index
299 call point_zone_factory(this%point_zones(this%n)%pz, json, dof)
300
301 ! generate a key for the name lookup map and assign it to the index
302 ! key%ptr = c_loc(fld_name)
303 ! call this%name_index_map%set(key, this%n)
304
305 ! write(*,*) "HTABLE DATA, ", this%name_index_map%get(key, i)
306 end subroutine add_point_zone_from_json
307
309 pure function n_point_zones(this) result(n)
310 class(point_zone_registry_t), intent(in) :: this
311 integer :: n
312
313 n = this%n
314 end function n_point_zones
315
320 pure function get_size(this) result(n)
321 class(point_zone_registry_t), intent(in) :: this
322 integer :: n
323
324 n = size(this%point_zones)
325 end function get_size
326
329 pure function get_expansion_size(this) result(n)
330 class(point_zone_registry_t), intent(in) :: this
331 integer :: n
332
333 n = this%expansion_size
334 end function get_expansion_size
335
339 function get_point_zone_by_index(this, i) result(pz)
340 class(point_zone_registry_t), target, intent(in) :: this
341 integer, intent(in) :: i
342 class(point_zone_t), pointer :: pz
343
344 if (i < 1) then
345 call neko_error("Field index must be > 1")
346 else if (i > this%n_point_zones()) then
347 call neko_error("Field index exceeds number of stored point_zones")
348 end if
349
350 pz => this%point_zones(i)%pz
351 end function get_point_zone_by_index
352
355 function get_point_zone_by_name(this, name) result(pz)
356 class(point_zone_registry_t), target, intent(in) :: this
357 character(len=*), intent(in) :: name
358 class(point_zone_t), pointer :: pz
359 logical :: found
360 integer :: i
361
362 found = .false.
363 do i = 1, this%n_point_zones()
364 if (trim(this%point_zones(i)%pz%name) .eq. trim(name)) then
365 pz => this%point_zones(i)%pz
366 found = .true.
367 exit
368 end if
369 end do
370
371 if (.not. found) then
372 call neko_error("Point zone " // trim(name) // &
373 " could not be found in the registry")
374 end if
375 end function get_point_zone_by_name
376
379 function point_zone_exists(this, name) result(found)
380 class(point_zone_registry_t), target, intent(in) :: this
381 character(len=*), intent(in) :: name
382 logical :: found
383 integer :: i
384
385 found = .false.
386 do i = 1, this%n_point_zones()
387 if (trim(this%point_zones(i)%pz%name) .eq. trim(name)) then
388 found = .true.
389 exit
390 end if
391 end do
392 end function point_zone_exists
393
394end module point_zone_registry
Retrieves a parameter by name or throws an error.
Generic buffer that is extended with buffers of varying rank.
Definition buffer.F90:34
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Utilities for retrieving parameters from the case files.
Defines a mesh.
Definition mesh.f90:34
subroutine build_combine_point_zone(object, json, dof)
Constructs a combine_point_zone_t object.
subroutine expand(this)
Expand the point_zones array so as to accomodate more point_zones.
subroutine point_zone_registry_free(this)
Destructor.
pure integer function n_point_zones(this)
Returns the number of point zones in the registry.
subroutine point_zone_registry_init(this, json, msh, expansion_size)
Constructor, reading from json point zones.
logical function point_zone_exists(this, name)
Checks if a point zone exists in the registry.
pure integer function get_size(this)
Returns the total size of the point_zones array (not the number of point zones in the registry!...
type(point_zone_registry_t), target, public neko_point_zone_registry
Global point_zone registry.
subroutine add_point_zone_from_json(this, json, dof)
Adds a point zone object to the registry from a json object.
class(point_zone_t) function, pointer get_point_zone_by_name(this, name)
Retrieves a point zone in the registry by its name.
pure integer function get_expansion_size(this)
Returns the expansion size with which the point_zone_registry_t was initialized.
class(point_zone_t) function, pointer get_point_zone_by_index(this, i)
Retrieves a point zone in the registry by its index in the point_zones array.
Defines a function space.
Definition space.f90:34
integer, parameter, public gll
Definition space.f90:50
Utilities.
Definition utils.f90:35
A point zone that combines different point zones.
Base abstract type for point zones.
A helper type to build a list of polymorphic point_zones.
The function space for the SEM solution fields.
Definition space.f90:64