Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
adjoint_lube_source_term.f90
Go to the documentation of this file.
1! Copyright (c) 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!
34!
35!
36! I know this is a stupid naming convention...
37! The `lube` aspect came from a paper that attributed this term to out of plane
38! stresses based on lubrication theory.
39!
40! I preffer to think of it as a constraint that penalizes non-binary designs
41!
42! The term is $K \int_\Omega \frac{1}{2}\chi|\mathbf{u}|^2$
43!
44! the corresponding adjoint forcing is $K \chi \mathbf{u}$
46 use num_types, only: rp
47 use field_list, only: field_list_t
48 use json_module, only: json_file
49 use source_term, only: source_term_t
50 use coefs, only: coef_t
51 use field, only: field_t
52 use design, only: design_t
54 use field_math, only: field_addcol3, field_copy, field_cmult
55 use scratch_registry, only: neko_scratch_registry
57 use point_zone, only: point_zone_t
58 use utils, only: neko_error
59 use field_registry, only: neko_field_registry
60 implicit none
61 private
62
64 ! $K \int_\Omega \frac{1}{2}\chi|\mathbf{u}|^2$.
65 type, public, extends(source_term_t) :: adjoint_lube_source_term_t
66
68 type(field_t), pointer :: u,v,w
70 type(field_t), pointer :: chi
72 real(kind=rp) :: k
74 class(point_zone_t), pointer :: mask
76 logical :: if_mask
77
78 contains
80 procedure, pass(this) :: init => adjoint_lube_source_term_init_from_json
82 procedure, pass(this) :: init_from_components => &
85 procedure, pass(this) :: free => adjoint_lube_source_term_free
87 procedure, pass(this) :: compute_ => adjoint_lube_source_term_compute
89
90contains
95 subroutine adjoint_lube_source_term_init_from_json(this, json, fields, coef)
96 class(adjoint_lube_source_term_t), intent(inout) :: this
97 type(json_file), intent(inout) :: json
98 type(field_list_t), intent(in), target :: fields
99 type(coef_t), intent(in), target :: coef
100 ! real(kind=rp), allocatable :: values(:)
101 ! real(kind=rp) :: start_time, end_time
102
103
104 ! we shouldn't be initializing this from JSON
105 ! maybe throw an error?
106
107
109
115 ! $u,v,w$ reffer to the primal, not the adjoint
117 f_x, f_y, f_z, design, K, &
118 u, v, w, &
119 mask, if_mask, &
120 coef)
121 class(adjoint_lube_source_term_t), intent(inout) :: this
122 type(field_t), pointer, intent(in) :: f_x, f_y, f_z
123 class(design_t), intent(in), target :: design
124 class(point_zone_t), intent(in), target :: mask
125 type(coef_t), intent(in) :: coef
126 real(kind=rp) :: start_time
127 real(kind=rp) :: end_time
128 type(field_list_t) :: fields
129 logical :: if_mask
130 real(kind=rp) :: k
131 type(field_t), intent(in), target :: u, v, w
132
133 ! I wish you didn't need a start time and end time...
134 ! but I'm just going to set a super big number...
135 start_time = 0.0_rp
136 end_time = 100000000.0_rp
137
138 call this%free()
139
140 ! this is copying the fluid source term init
141 ! We package the fields for the source term to operate on in a field list.
142 call fields%init(3)
143 call fields%assign(1, f_x)
144 call fields%assign(2, f_y)
145 call fields%assign(3, f_z)
146
147 call this%init_base(fields, coef, start_time, end_time)
148
149 ! point everything in the correct places
150 ! NOTE!!!
151 ! this is the primal!
152 this%u => u
153 this%v => v
154 this%w => w
155
156 select type (design)
157 type is (brinkman_design_t)
158 this%chi => neko_field_registry%get_field("brinkman_amplitude")
159 class default
160 call neko_error('Unknown design type')
161 end select
162
163 this%K = k
164 this%if_mask = if_mask
165 if (this%if_mask) then
166 this%mask => mask
167 end if
168
170
173 class(adjoint_lube_source_term_t), intent(inout) :: this
174
175 call this%free_base()
176 end subroutine adjoint_lube_source_term_free
177
181 subroutine adjoint_lube_source_term_compute(this, t, tstep)
182 class(adjoint_lube_source_term_t), intent(inout) :: this
183 real(kind=rp), intent(in) :: t
184 integer, intent(in) :: tstep
185 type(field_t), pointer :: fu, fv, fw
186 type(field_t), pointer :: work
187 integer :: temp_indices(1)
188
189 fu => this%fields%get_by_index(1)
190 fv => this%fields%get_by_index(2)
191 fw => this%fields%get_by_index(3)
192
193 ! BE SO CAREFUL HERE
194 ! It make look the same as the Brinkman term, but it's assumed that
195 ! this source term acts on the adjoint, and the u,v,w here come from
196 ! the primal
197 call neko_scratch_registry%request_field(work, temp_indices(1))
198 call field_copy(work, this%chi)
199
200 ! scale by K
201 call field_cmult(work, this%K)
202
203 ! mask
204 if (this%if_mask) then
205 call mask_exterior_const(work, this%mask, 0.0_rp)
206 end if
207
208 ! multiple and add the RHS
209 call field_addcol3(fu, this%u, work)
210 call field_addcol3(fv, this%v, work)
211 call field_addcol3(fw, this%w, work)
212 call neko_scratch_registry%relinquish_field(temp_indices)
213
215
Implements the adjoint_lube_source_term_t type.
subroutine adjoint_lube_source_term_free(this)
Destructor.
subroutine adjoint_lube_source_term_init_from_json(this, json, fields, coef)
The common constructor using a JSON object.
subroutine adjoint_lube_source_term_init_from_components(this, f_x, f_y, f_z, design, k, u, v, w, mask, if_mask, coef)
The constructor from type components.
subroutine adjoint_lube_source_term_compute(this, t, tstep)
Computes the source term and adds the result to fields.
Implements the design_t.
Definition design.f90:34
Some common Masking operations we may need.
Definition mask_ops.f90:34
A adjoint source term corresponding to an objective of.
A topology optimization design variable.
An abstract design type.
Definition design.f90:48