Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
mapping_handler.f90
1
2! Copyright (c) 2023, The Neko Authors
3! All rights reserved.
4!
5! Redistribution and use in mapping and binary forms, with or without
6! modification, are permitted provided that the following conditions
7! are met:
8!
9! * Redistributions of mapping code must retain the above copyright
10! notice, this list of conditions and the following disclaimer.
11!
12! * Redistributions in binary form must reproduce the above
13! copyright notice, this list of conditions and the following
14! disclaimer in the documentation and/or other materials provided
15! with the distribution.
16!
17! * Neither the name of the authors nor the names of its
18! contributors may be used to endorse or promote products derived
19! from this software without specific prior written permission.
20!
21! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32! POSSIBILITY OF SUCH DAMAGE.
33!
36 use neko_config, only: neko_bcknd_device
37 use num_types, only: rp
40 use field, only: field_t
41 use field_list, only: field_list_t
42 use json_utils, only: json_get, json_extract_item, json_get_or_default
43 use json_module, only: json_file
44 use coefs, only: coef_t
45 use user_intf, only: user_t
46 use field_math, only: field_rzero, field_copy
47 use math, only: col2
48 use device_math, only: device_col2
49 use scratch_registry, only: neko_scratch_registry
50 use utils, only: neko_warning
51 implicit none
52 private
53
60 type, public :: mapping_handler_t
64 class(mapping_wrapper_t), allocatable :: mapping_cascade(:)
66 type(field_list_t) :: rhs_fields
68 type(coef_t), pointer :: coef
69
70 contains
72 procedure, pass(this) :: init_base => mapping_handler_init_base
74 procedure, pass(this) :: free => mapping_handler_free
76 procedure, pass(this) :: apply_forward => mapping_handler_apply_forward
79 procedure, pass(this) :: apply_backward => mapping_handler_apply_backward
81 generic :: add => add_mapping, add_json_mappings
83 procedure, pass(this) :: add_mapping => &
84 mapping_handler_add_mapping
86 procedure, pass(this) :: add_json_mappings => &
87 mapping_handler_add_json_mappings
88 end type mapping_handler_t
89
90contains
91
93 subroutine mapping_handler_init_base(this, coef)
94 class(mapping_handler_t), intent(inout) :: this
95 type(coef_t), target, intent(in) :: coef
96
97 call this%free()
98
99 this%coef => coef
100
101 end subroutine mapping_handler_init_base
102
103
105 subroutine mapping_handler_free(this)
106 class(mapping_handler_t), intent(inout) :: this
107 integer :: i
108
109 if (allocated(this%mapping_cascade)) then
110 do i = 1, size(this%mapping_cascade)
111 call this%mapping_cascade(i)%free()
112 end do
113 deallocate(this%mapping_cascade)
114 end if
115
116 end subroutine mapping_handler_free
117
122 subroutine mapping_handler_apply_forward(this, X_out, X_in)
123 class(mapping_handler_t), intent(inout) :: this
124 type(field_t), intent(in) :: X_in
125 type(field_t), intent(inout) :: X_out
126 integer :: i
127 type(field_t), pointer :: tmp_fld_in, tmp_fld_out
128 integer :: temp_indices(2)
129
130 call neko_scratch_registry%request_field(tmp_fld_in, temp_indices(1))
131 call neko_scratch_registry%request_field(tmp_fld_out, temp_indices(2))
132
133 ! Start by copying the first X_in into the tmp_fld_out to begin the
134 ! cascade.
135 call field_copy(tmp_fld_out, x_in)
136
137 ! We enter the cascade
138 if (allocated(this%mapping_cascade)) then
139 do i = 1, size(this%mapping_cascade)
140 ! the output from one mapping becomes the input for the next.
141 call field_copy(tmp_fld_in, tmp_fld_out)
142 ! apply the mapping on temp_fld
143 call this%mapping_cascade(i)%mapping%apply_forward(tmp_fld_out, &
144 tmp_fld_in)
145
146 end do
147
148 end if
149
150 ! our final mapping should now live in tmp_fld_out
151 call field_copy(x_out, tmp_fld_out)
152
153 ! free the scratch.
154 call neko_scratch_registry%relinquish_field(temp_indices)
155
156 end subroutine mapping_handler_apply_forward
157
164 subroutine mapping_handler_apply_backward(this, sens_out, sens_in)
165 class(mapping_handler_t), intent(inout) :: this
166 type(field_t), intent(inout) :: sens_out
167 type(field_t), intent(in) :: sens_in
168 integer :: i
169 type(field_t), pointer :: tmp_fld_in, tmp_fld_out
170 integer :: temp_indices(2)
171
172 call neko_scratch_registry%request_field(tmp_fld_in, temp_indices(1))
173 call neko_scratch_registry%request_field(tmp_fld_out, temp_indices(2))
174
175 ! Start by copying the first sens_in into the tmp_fld_out to begin the
176 ! cascade.
177 call field_copy(tmp_fld_out, sens_in)
178
179 ! We enter the cascade
180 if (allocated(this%mapping_cascade)) then
181 do i = 1, size(this%mapping_cascade)
182 ! the output from one mapping becomes the input for the next.
183 call field_copy(tmp_fld_in, tmp_fld_out)
184 ! apply the mapping on temp_fld
185 ! NOTE
186 ! all the X_in that is required to map backward should be held
187 ! internally by each mapping
188 call this%mapping_cascade(i)%mapping%apply_backward(tmp_fld_out, &
189 tmp_fld_in)
190
191 end do
192
193 end if
194
195 ! our final mapping should now live in tmp_fld_out
196 call field_copy(sens_out, tmp_fld_out)
197
198 ! free the scratch.
199 call neko_scratch_registry%relinquish_field(temp_indices)
200
201
202 end subroutine mapping_handler_apply_backward
203
205 subroutine mapping_handler_add_json_mappings(this, json, name)
206 class(mapping_handler_t), intent(inout) :: this
207 type(json_file), intent(inout) :: json
208 character(len=*), intent(in) :: name
209
210 class(mapping_wrapper_t), dimension(:), allocatable :: temp
211
212 ! A single mapping as its own json_file.
213 type(json_file) :: mapping_subdict
214 integer :: n_mappings, i, i0
215
216 if (json%valid_path(name)) then
217 ! Get the number of mapping_cascade.
218 call json%info(name, n_children = n_mappings)
219
220 if (allocated(this%mapping_cascade)) then
221 i0 = size(this%mapping_cascade)
222 call move_alloc(this%mapping_cascade, temp)
223 allocate(this%mapping_cascade(i0 + n_mappings))
224 if (allocated(temp)) then
225 do i = 1, i0
226 call move_alloc(temp(i)%mapping, &
227 this%mapping_cascade(i)%mapping)
228 end do
229 end if
230 else
231 i0 = 0
232 allocate(this%mapping_cascade(n_mappings))
233 end if
234
235 do i = 1, n_mappings
236 ! Create a new json containing just the subdict for this mapping.
237 call json_extract_item(json, name, i, mapping_subdict)
238 call mapping_factory(this%mapping_cascade(i + i0)%mapping, &
239 mapping_subdict, this%coef)
240 end do
241 else
242 ! I was considering an error, but maybe a warning is more appropriate
243 call neko_warning("No mappings selected")
244 end if
245
246 end subroutine mapping_handler_add_json_mappings
247
251 subroutine mapping_handler_add_mapping(this, mapping)
252 class(mapping_handler_t), intent(inout) :: this
253 class(mapping_t), intent(in) :: mapping
254 class(mapping_wrapper_t), dimension(:), allocatable :: temp
255
256 integer :: n_mappings, i
257
258 if (allocated(this%mapping_cascade)) then
259 n_mappings = size(this%mapping_cascade)
260 else
261 n_mappings = 0
262 end if
263
264 call move_alloc(this%mapping_cascade, temp)
265 allocate(this%mapping_cascade(n_mappings + 1))
266
267 if (allocated(temp)) then
268 do i = 1, n_mappings
269 call move_alloc(temp(i)%mapping, this%mapping_cascade(i)%mapping)
270 end do
271 end if
272
273 this%mapping_cascade(n_mappings + 1)%mapping = mapping
274
275 end subroutine mapping_handler_add_mapping
276end module mapping_handler
mapping factory. Both constructs and initializes the object.
Definition mapping.f90:137
Implements the mapping_handler_t type.
Mappings to be applied to a scalar field.
Definition mapping.f90:35
Base abstract class for mapping.
Definition mapping.f90:45
A helper type that is needed to have an array of polymorphic objects.
Definition mapping.f90:72
Abstract class for handling mapping_cascade.