Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
combine_point_zone.f90
Go to the documentation of this file.
1! Copyright (c) 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 geometry subset that combines different zones.
36 point_zone_wrapper_t, point_zone_factory
40 use num_types, only : rp
42 use json_module, only : json_file, json_core, json_value
44 use logger, only : neko_log
45 implicit none
46 private
47
49 type, public, extends(point_zone_t) :: combine_point_zone_t
51 type(point_zone_pointer_t), allocatable :: zones(:)
53 type(point_zone_wrapper_t), allocatable :: internal_zones(:)
55 character(len=80), allocatable :: names(:)
57 integer :: n_zones = 0
59 integer :: n_external_zones = 0
61 integer :: n_internal_zones = 0
62
64 character(len=:), allocatable :: operator
65 contains
67 procedure, pass(this) :: init => combine_point_zone_init_from_json
69 procedure, pass(this) :: free => combine_point_zone_free
72 procedure, pass(this) :: criterion => combine_point_zone_criterion
74
75contains
76
80 subroutine combine_point_zone_init_from_json(this, json, size)
81 class(combine_point_zone_t), intent(inout) :: this
82 type(json_file), intent(inout) :: json
83 integer, intent(in) :: size
84
85 ! Json low-level manipulator.
86 type(json_core) :: core
87 ! Pointer to the point_zones JSON object and the individual sources.
88 type(json_value), pointer :: source_object, source_pointer
89 ! Buffer for serializing the json.
90 character(len=:), allocatable :: buffer
91 ! A single source term as its own json_file.
92 type(json_file) :: source_subdict
93 character(len=:), allocatable :: type_name
94 character(len=:), allocatable :: type_string
95
96 character(len=:), allocatable :: str_read
97 integer :: i, n_zones, i_internal, i_external
98 logical :: found, invert, full_elements
99
100 call json_get(json, "name", str_read)
101 call json_get_or_default(json, "invert", invert, .false.)
102 call json_get_or_default(json, "full_elements", full_elements, .false.)
103 call this%init_base(size, trim(str_read), invert, full_elements)
104
105 call json%get_core(core)
106 call json%get('subsets', source_object, found)
107
108 if (.not. found) call neko_error("No subsets found")
109
110 this%n_zones = core%count(source_object)
111
112 ! Allocate arrays if we found things
113 if (this%n_zones .gt. 0) then
114 allocate(this%zones(this%n_zones))
115 end if
116
117 ! First, count how many external zones we have (external = only "name",
118 ! to be retrieved by the register later).
119 do i = 1, this%n_zones
120 ! Create a new json containing just the subdict for this source.
121 call core%get_child(source_object, i, source_pointer, found)
122 call core%print_to_string(source_pointer, buffer)
123 call source_subdict%destroy()
124 call source_subdict%load_from_string(buffer)
125
126 if (.not. source_subdict%valid_path("geometry")) then
127 this%n_external_zones = this%n_external_zones + 1
128 end if
129 end do
130
131 this%n_internal_zones = this%n_zones - this%n_external_zones
132 if (this%n_external_zones .gt. 0) &
133 allocate(this%names(this%n_external_zones))
134 if (this%n_internal_zones .gt. 0) &
135 allocate(this%internal_zones(this%n_internal_zones))
136
137 i_internal = 1
138 i_external = 1
139
140 ! now go through everything again and either construct a point zone or
141 ! save its name for the registry to fill it in later
142 do i = 1, this%n_zones
143
144 ! Create a new json containing just the subdict for this source.
145 call core%get_child(source_object, i, source_pointer, found)
146 call core%print_to_string(source_pointer, buffer)
147 call source_subdict%destroy()
148 call source_subdict%load_from_string(buffer)
149
150 if (source_subdict%valid_path("geometry")) then
151 call point_zone_factory(this%internal_zones(i_internal)%pz, &
152 source_subdict)
153 call assign_point_zone(this%zones(i_internal)%pz, &
154 this%internal_zones(i_internal)%pz)
155 i_internal = i_internal + 1
156 else
157 call json_get(source_subdict, "name", type_name)
158 this%names(i_external) = trim(type_name)
159 i_external = i_external + 1
160 end if
161
162 end do
163
164 ! Chcek that we got the proper operator
165 call json_get(json, "operator", this%operator)
166 select case (trim(this%operator))
167 case ("OR")
168 case ("AND")
169 case ("XOR")
170 case default
171 call neko_error("Unknown operator " // trim(this%operator))
172 end select
173
175
176 subroutine assign_point_zone(pt, tgt)
177 class(point_zone_t), intent(inout), pointer :: pt
178 class(point_zone_t), intent(inout), target :: tgt
179
180 pt => tgt
181
182 end subroutine assign_point_zone
183
185 subroutine combine_point_zone_free(this)
186 class(combine_point_zone_t), intent(inout) :: this
187
188 integer :: i
189
190 if (allocated(this%zones)) then
191 do i = 1, this%n_zones
192 nullify(this%zones(i)%pz)
193 end do
194 deallocate(this%zones)
195 end if
196
197 if (allocated(this%internal_zones)) then
198 do i = 1, this%n_internal_zones
199 call this%internal_zones(i)%pz%free
200 end do
201 deallocate(this%internal_zones)
202 end if
203
204 if (allocated(this%names)) deallocate(this%names)
205
206 if (allocated(this%operator)) deallocate(this%operator)
207
208 this%n_zones = 0
209 this%n_internal_zones = 0
210 this%n_external_zones = 0
211 call this%free_base()
212
213 end subroutine combine_point_zone_free
214
224 pure function combine_point_zone_criterion(this, x, y, z, j, k, l, e) &
225 result(is_inside)
226 class(combine_point_zone_t), intent(in) :: this
227 real(kind=rp), intent(in) :: x
228 real(kind=rp), intent(in) :: y
229 real(kind=rp), intent(in) :: z
230 integer, intent(in) :: j
231 integer, intent(in) :: k
232 integer, intent(in) :: l
233 integer, intent(in) :: e
234 logical :: is_inside
235
236 integer :: i
237
238 is_inside = this%zones(1)%pz%criterion(x, &
239 y, z, j, k, l, e) .neqv. this%zones(1)%pz%invert
240
241 do i = 2, this%n_zones
242 select case (trim(this%operator))
243 case ("OR")
244 is_inside = is_inside .or. (this%zones(i)%pz%criterion(x, &
245 y, z, j, k, l, e) .neqv. this%zones(i)%pz%invert)
246
247 case ("AND")
248 is_inside = is_inside .and. (this%zones(i)%pz%criterion(x, &
249 y, z, j, k, l, e) .neqv. this%zones(i)%pz%invert)
250
251 case ("XOR")
252 is_inside = is_inside .neqv. (this%zones(i)%pz%criterion(x, &
253 y, z, j, k, l, e).neqv. this%zones(i)%pz%invert)
254
255 case default
256 end select
257 end do
258
260
261end module combine_point_zone
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
subroutine combine_point_zone_free(this)
Destructor.
subroutine assign_point_zone(pt, tgt)
subroutine combine_point_zone_init_from_json(this, json, size)
Constructor from json object file. Reads.
pure logical function combine_point_zone_criterion(this, x, y, z, j, k, l, e)
Defines the criterion of selection of a GLL point in the combined point zone.
Implements a cylinder geometry subset.
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:92
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Utilities.
Definition utils.f90:35
character(:) function, allocatable, public concat_string_array(array, sep, prepend)
Concatenate an array of strings into one string with array items separated by spaces.
Definition utils.f90:468
A point zone that combines different point zones.
A helper type to build a list of pointers to point_zones.
Base abstract type for point zones.
A helper type to build a list of polymorphic point_zones.