Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
user.f90
Go to the documentation of this file.
1! User module for the user defined simulation component
2module user
3 use user_intf, only: user_t, simulation_component_user_settings
4 use json_module, only: json_file
6 use simcomp_executor, only: neko_simcomps
7 use fluid_user_source_term, only: fluid_user_source_term_t
8 use num_types, only: rp
9 use field, only: field_t
10 use field_registry, only: neko_field_registry
11 use math, only: rzero, copy, chsign
12 use device_math, only: device_copy, device_cmult
13 use neko_config, only: neko_bcknd_device
14 use operators, only: curl
15 use scratch_registry, only: neko_scratch_registry
16 implicit none
17
18contains
19
20 ! Register user-defined functions (see user_intf.f90)
21 subroutine user_setup(user)
22 type(user_t), intent(inout) :: user
23 user%init_user_simcomp => user_simcomp
24 user%fluid_user_f_vector => adjoint_forcing
25 end subroutine user_setup
26
27 subroutine user_simcomp(params)
28 type(json_file), intent(inout) :: params
29 type(steady_simcomp_t), allocatable :: steady_comp
30 type(json_file) :: simcomp_settings
31
32 ! Allocate a simulation component
33 allocate(steady_comp)
34 simcomp_settings = simulation_component_user_settings("steady", params)
35
36 call neko_simcomps%add_user_simcomp(steady_comp, simcomp_settings)
37
38 end subroutine user_simcomp
39
41 subroutine adjoint_forcing(f, t)
42 class(fluid_user_source_term_t), intent(inout) :: f
43 real(kind=rp), intent(in) :: t
44 type(field_t), pointer :: u, v, w
45 !type(field_t), pointer :: dudx, dudy, dudz
46 !type(field_t), pointer :: dvdx, dvdy, dvdz
47 !type(field_t), pointer :: dwdx, dwdy, dwdz
48 type(field_t), pointer :: wo1, wo2, wo3, wo4, wo5, wo6
49 type(field_t), pointer :: t1 , t2
50 integer :: temp_indices(8)
51 integer n
52 print *, "called forcing"
53
54
55 n = f%dm%size()
56
57 ! fuck I'm not sure about this... I need a pen and paper
58 ! also there should be a way to pre-process this forcing term...
59 ! instead of recalculating it every time
60 u => neko_field_registry%get_field('u')
61 v => neko_field_registry%get_field('v')
62 w => neko_field_registry%get_field('w')
63 call neko_scratch_registry%request_field(wo1, temp_indices(1))
64 call neko_scratch_registry%request_field(wo2, temp_indices(2))
65 call neko_scratch_registry%request_field(wo3, temp_indices(3))
66 call neko_scratch_registry%request_field(wo4, temp_indices(4))
67 call neko_scratch_registry%request_field(wo5, temp_indices(5))
68 call neko_scratch_registry%request_field(wo6, temp_indices(6))
69 call neko_scratch_registry%request_field(t1 , temp_indices(7))
70 call neko_scratch_registry%request_field(t2 , temp_indices(8))
71
72 ! ok we're computing gradients at every timestep... which is stupid...
73 ! BUT
74 ! if this was unsteady we would have to do this.
75
76 ! this is cheating a little bit...
77 ! in strong form, \nabla u . \nabla v => v . \nabla^2 u + bdry
78 !
79 ! we can do this properly later in weak form, ideally using ax_helm or so
80 !
81 ! for now we'll work in strong form and ignore the bdry
82 ! and suffer the double derivative :/
83 !
84 ! in fact, we'll go even quicker and use
85 ! \nabla ^2 u = grad (div (u)) - curl ( curl (u )) and assume divergence
86 ! free u
87
88 call curl(wo1, wo2, wo3, u, v, w, t1, t2, f%coef)
89 call curl(wo4, wo5, wo6, wo1, wo2, wo3, t1, t2, f%coef)
90
91 if (neko_bcknd_device .eq. 1) then
92 call device_copy(f%u_d, wo4%x_d, n)
93 call device_copy(f%v_d, wo5%x_d, n)
94 call device_copy(f%w_d, wo6%x_d, n)
95 call device_cmult(f%u_d, -1.0_rp, n)
96 call device_cmult(f%v_d, -1.0_rp, n)
97 call device_cmult(f%w_d, -1.0_rp, n)
98 else
99 call copy(f%u, wo4%x, n)
100 call copy(f%v, wo5%x, n)
101 call copy(f%w, wo6%x, n)
102 call chsign(f%u, n)
103 call chsign(f%v, n)
104 call chsign(f%w, n)
105 end if
106 ! don't worry... we'll write this MUCH cleaner in the final version
107
108 call neko_scratch_registry%relinquish_field(temp_indices)
109
110 end subroutine adjoint_forcing
111
112
113end module user
Implements the steady_simcomp_t type.
User defined user region.
Definition user.f90:2
subroutine user_setup(user)
Register user defined functions (see nekos user_intf.f90)
Definition user.f90:22
subroutine user_simcomp(params)
Definition user.f90:28
subroutine adjoint_forcing(f, t)
Forcing.
Definition user.f90:42
The steady_simcomp_t type is a simulation component that terminates a simulation when the normed diff...