Choral
eigen_Ventcel_2D.f90
Go to the documentation of this file.
1 
58 
60 
61  use choral
63 
64  implicit none
65 
66  !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
67  !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
68  !!
69  !! VARAIBLE DEFINITION : BEGIN
70  !!
71  !!
72  !! GENERAL SETTINGS
73  !!
74  !! verb = verbosity level
75  !! WITH_MUMPS = use MUMPS direct solver for linear system inversions
76  !!
77  integer, parameter :: VERB = 2
78  logical, parameter :: WITH_MUMPS = .false.
79 
80 
81  !! eig = eigen-problem solver
82  !!
83  !! Arnoldi algorithm parameters
84  !! nev = number of computed eigenvalues
85  !! size = problem size (number of DOF)
86  !! sigma = shift factor
87  !! tol = tolerance for resolution
88  !! itMax = maximal number of iterations
89  !!
90  !! lambda = exact eigenvalues (analytic)
91  !!
92  type(eigen) :: eig
93  !!
94  integer , parameter :: nev = 5
95  integer , parameter :: itMax = 100
96  real(RP), parameter :: tol = 1e-7_rp
97  real(RP), parameter :: sigma =-1.0_rp
98  integer :: size
99  !!
100  integer , parameter :: nev_exact = 6
101  real(RP), dimension(nev_exact) :: lambda
102 
103  !! SPACE DISCRETISATION
104  !!
105  !! fe_1 = volumic finite element method in Omega
106  !! fe_2 = surfacic finite element method on Gamma
107  !!
108  !! qd_1 = volumic quadrature method in Omega
109  !! qd_2 = surfacic quadrature method on Gamma
110  !!
111  integer, parameter :: fe_1 = fe_p2_2d
112  integer, parameter :: qd_1 = quad_gauss_trg_12
113  integer, parameter :: fe_2 = fe_p2_1d
114  integer, parameter :: qd_2 = quad_gauss_edg_4
115  !!
116  !! msh = mesh
117  !! X_h = finite element space
118  !! qdm_1 = integration method on Omega
119  !! qdm_2 = integration method on Gamma
120  !!
121  type(mesh) :: msh
122  type(fespace) :: X_h
123  type(quadmesh) :: qdm_1, qdm_2
124  !!
125  !! msh_file
126  character(len=100), parameter :: &
127  & mesh_file= trim(GMSH_DIR)//"disk/disk2_3.msh"
128 
129 
130  !! LINEAR SYSTEM
131  !!
132  !! S1 = stiffness matrix
133  !! S2 = stiffness matrix on the boundary
134  !! M2 = mass matrix on the boundary
135  !! K = ( S1 + S2 )- sigma * M2, sigma the shift factor
136  !!
137  !! lu = mumps decomposition for K ( if WITH_MUMPS )
138  !! kry = krylov method def. ( else )
139  !! pc = preconditioning for the CG krylov
140  !!
141  !! Kinv = pointer to the system inversion K x = y
142  !!
143  type(csr) :: S1, S2, M2, K
144  type(mumps) :: LU
145  type(krylov) :: kry
146  type(precond) :: pc
147  !!
148  procedure(rntornxl), pointer :: Kinv => null()
149 
150 
151  !! OTHER VARS
152  !!
153  real(RP) :: err
154  integer :: ii
155  character(LEN=300) :: shell_com
156  !!
157  !!
158  !! VARAIBLE DEFINITION : END
159  !!
160  !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
161  !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
162 
163 
164  !! !!!!!!!!!!!!!!!!!!!!! INITIALISATION
165  !!
166  call choral_init(verb=1)
167  write(*,*)
168  write(*,*)'eigen_Ventcel_2D: start'
169  write(*,*)""
170  write(*,*)" RESOLUTION OF THE EIGEN-PROBLEM"
171  write(*,*)""
172  write(*,*)" Delta u = 0 on Omega"
173  write(*,*)""
174  write(*,*)" Delta_B u + \partial_n u + lambda u = 0 on Gamma"
175  write(*,*)""
176  write(*,*)""
177 
178  write(*,*) ""
179  write(*,*)"================================== ASSEMBLING THE MESH "
180  msh = mesh(mesh_file, 'gmsh')
181  if (verb>1) call print(msh)
182 
183  write(*,*) ""
184  write(*,*)"================================== ASSEMBLING THE&
185  & FINITE ELEMENT SPACE"
186  x_h = fespace(msh)
187  call set(x_h, fe_1) !! set the volumic elements with fe_1
188  call set(x_h, fe_2) !! set the boundary elements with fe_2
189  call assemble(x_h)
190  if (verb>1) call print(x_h)
191 
192  write(*,*) ""
193  write(*,*)"================================== ASSEMBLING THE&
194  & INTEGRATION METHOD ON Omega"
195  qdm_1 = quadmesh(msh)
196  call set(qdm_1, qd_1)
197  call assemble(qdm_1)
198  if (verb>1) call print(qdm_1)
199 
200  write(*,*) ""
201  write(*,*)"================================== ASSEMBLING THE&
202  & INTEGRATION METHOD ON Gamma"
203  qdm_2 = quadmesh(msh)
204  call set(qdm_2, qd_2)
205  call assemble(qdm_2)
206  if (verb>1) call print(qdm_2)
207 
208  write(*,*) ""
209  write(*,*)"================================== ASSEMBLING THE&
210  & MATRICES S1, S2, M2"
211  !!
212  !! M2 = mass matrix on Gamma
213  !! 'one_R3' is the density function equal to 1 on \Omega
214  call diffusion_massmat(m2, one_r3, x_h, qdm_2)
215  !!
216  !! S1 = stiffness matrix on Omega
217  !! S2 = stiffness matrix on Gamma
218  !! 'EMetric' is the Euclidian metric on \Omega
219  call diffusion_stiffmat(s1, emetric, x_h, qdm_1)
220  call diffusion_stiffmat(s2, emetric, x_h, qdm_2)
221 
222  write(*,*) ""
223  write(*,*)"================================== COMPUTE THE SYSTEM &
224  &MATRIX K = S1 + S2 - sigma * M2"
225  !!
226  call copy(k, s1)
227  call add_submatrix(k, s2)
228  call add_submatrix(k, m2, -sigma)
229 
230  write(*,*) ""
231  write(*,*)"================================== LINEAR SOLVER K*x = y"
232  !!
233  if (with_mumps) then
234  write(*,*) " K = LDLT, decomposition with MUMPS"
235  lu = mumps(k, mumps_ldlt_sdp, verb = 0)
236 
237  kinv => kinv_mumps
238 
239  else
240  write(*,*) " Krylov CG settings"
241  kry = krylov(kry_cg, tol=tol*1.0e-2_rp, itmax=1000, verb=0)
242 
243  pc = precond(k, pc_jacobi)
244 
245  kinv => kinv_pcg
246 
247  end if
248 
249  write(*,*) ""
250  write(*,*)"================================== EIGEN-SOLVER DEF."
251  !!
252  !! create the eigen-solver 'eig'
253  size = x_h%nbDof
254  eig = eigen(size = size, nev = nev, sym=.true., std=.false.)
255  !!
256  !! set the eigen-solver 'eig'
257  call set(eig, itmax=itmax, tol=tol, verb=2)
258  call set(eig, which = eig_which_sm)
259  call set(eig, mode = eig_shift_invert, shift = sigma)
260  if (verb>1) call print(eig)
261 
262 
263  write(*,*) ""
264  write(*,*)"================================== NUMERICAL RESOLUTION"
265  !!
266  call solve(eig, b=pmv_m, op=kinv)
267  !!
268  call residual()
269 
270  write(*,*) ""
271  write(*,*)"================================== POST-PROCESSING"
272  print*
273  write(*,*) "Computed eigenvalues"
274  do ii=1, nev
275  write(*,*) " i =", int(ii,1), ", lambda = ", &
276  & real(eig%lambda(ii), SP)
277  end do
278 
279  write(*,*) ""
280  write(*,*) "Numerical errors |lambda - lambda_h| "
281  !!
282  !! Exact eigen values
283  !!
284  lambda(1) = 0._rp
285  lambda(2) = 2.0_rp
286  lambda(3) = 2.0_rp
287  lambda(4) = 6.0_rp
288  lambda(5) = 6.0_rp
289  lambda(6) = 12.0_rp
290  !!
291  do ii=1, min(nev, nev_exact)
292  err = abs( eig%lambda(ii) - lambda(ii))
293  write(*,*) " i =", int(ii,1), ", error = ", &
294  & real(err, sp)
295  end do
296 
297  if (verb>1) then
298  !!
299  !! graphical display
300  !!
301  !! output file def.
302  shell_com = 'eig_ventcel.msh'
303  !!
304  !! first write the 'finite element mesh'
305  call write(x_h, trim(shell_com), 'gmsh')
306  !!
307  !! second save the eigenvectors u_h
308  !! each eigenvector is a finite element function
309  do ii=1, nev
310  call gmsh_addview(x_h, eig%v(:,ii), &
311  & trim(shell_com), &
312  & 'Eigen-functions', real(ii, RP), ii)
313  end do
314  !!
315  !! shell command to visualise with gmsh
316  shell_com = 'gmsh -option '//trim(gmsh_dir)//'gmsh-options-view'&
317  & //' '//trim(shell_com)
318  call system(shell_com)
319 
320  end if
321 
322 contains
323 
324  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
325  !!
328  subroutine pmv_m(y, x)
329  real(RP), dimension(:), intent(out) :: y
330  real(RP), dimension(:), intent(in) :: x
331 
332  call matvecprod(y, m2, x)
333  end subroutine pmv_m
334 
335  !! Solve K*x = y
336  !!
337  subroutine kinv_pcg(x, ierr, y)
338  real(RP), dimension(:), intent(inout) :: x
339  logical , intent(out) :: ierr
340  real(RP), dimension(:), intent(in) :: y
341 
342  call solve(x, kry, y, k, pc)
343 
344  ierr = kry%ierr
345  end subroutine kinv_pcg
346 
347  !! Solve LU*x = y, LU = LDLT MUMPS decomposition
348  !! of K = (S1 + S2 - sigma*M2)
349  !!
350  subroutine kinv_mumps(x, ierr, y)
351  real(RP), dimension(:), intent(inout) :: x
352  logical , intent(out) :: ierr
353  real(RP), dimension(:), intent(in) :: y
354 
355  call solve(x, lu, y)
356  ierr = .false.
357  end subroutine kinv_mumps
358 
359  !! Compute and display the residuals on the
360  !! computed eigenvalues and eigenvectors
361  !!
362  subroutine residual()
363  real(RP), dimension(size) :: u, v, w
364  real(RP) :: res, nu
365  logical :: ierr
366 
367  write(*,*)
368  write(*,*) "Residual | Ku - lambda Mu |_l2 / | u |_l2"
369  !!
370  do ii=1, nev
371 
372  u = eig%v(:,ii)
373 
374  call matvecprod(v, k , u)
375  call pmv_m(w, u)
376 
377  w = v - eig%lambda(ii)*w
378  res = sqrt( sum(w*w) / sum(u*u) )
379 
380  print*, " i = ", int(ii,1), " : res = ", real(res, sp)
381 
382  end do
383 
384  write(*,*)
385  write(*,*) "Residual | \nu u - K^{-1} M u |_l2 / | u |_l2"
386  !!
387  do ii=1, nev
388  u = eig%v(:,ii)
389 
390  call pmv_m(v , u)
391  call kinv(w, ierr, v)
392 
393 
394  nu = 1.0_rp / ( eig%lambda(ii) - sigma )
395  w = w - nu*u
396  res = sqrt( sum(w*w) / sum(u*u) )
397 
398  print*, " i = ", int(ii,1), " : res = ", real(res, sp)
399 
400  end do
401 
402  end subroutine residual
403 
404 
405 end program eigen_ventcel_2d
integer, parameter eig_shift_invert
Shift-invert mode.
subroutine kinv_mumps(x, ierr, y)
subroutine, public choral_init(verb)
Initialisation for the CHORAL library
Definition: choral.F90:166
TOP-LEVEL MODULE FOR THE LIBRARY CHORAL
Definition: choral.F90:27
integer, parameter fe_p2_2d
integer, parameter quad_gauss_edg_4
subroutine pmv_m(y, x)
Matrix-vector product x –> M*x.
real(rp) function e(x, v1, v2)
CHORAL CONSTANTS
integer, parameter pc_jacobi
Jacobi diagonal preconditioning.
subroutine kinv_pcg(y, ierr, x)
integer, parameter mumps_ldlt_sdp
MUMPS LDLT-SDP, sym def pos mat.
integer, parameter eig_which_sm
Computation of eigenvalues xith smallest magnitude.
program eigen_ventcel_2d
Solves the Ventcel eigenvalue problem
subroutine residual()
integer, parameter quad_gauss_trg_12
integer, parameter fe_p2_1d
integer, parameter kry_cg
CG linear solver.
real(rp) function b(x, w1, w2)