FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_EIG_output.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
6 
7 contains
8 
10  subroutine fstr_eigen_residual(hecMESH, hecMAT, fstrEIG)
11  use m_fstr
13  implicit none
14  type(hecmwst_local_mesh) :: hecMESH
15  type(hecmwst_matrix) :: hecMAT
16  type(fstr_eigen) :: fstrEIG
17 
18  integer(kind=kint) :: NNDOF, NPNDOF, i, j
19  real(kind=kreal) :: chk, shift
20  real(kind=kreal), allocatable :: t(:), u(:)
21 
22  nndof = hecmat%N *hecmat%NDOF
23  npndof = hecmat%NP*hecmat%NDOF
24 
25  allocate(fstreig%resid(fstreig%nget))
26  allocate(t(npndof))
27  allocate(u(npndof))
28 
29  ! the free-free case works on [K] + sigma [M], see lanczos_set_initial_value
30  shift = 0.0d0
31  if(fstreig%is_free) shift = fstreig%sigma
32 
33  do j = 1, fstreig%nget
34  u = 0.0d0
35  do i = 1, nndof
36  u(i) = fstreig%eigvec(i,j)
37  enddo
38  call hecmw_matvec(hecmesh, hecmat, u, t)
39 
40  chk = 0.0d0
41  do i = 1, nndof
42  chk = chk + (t(i) - (fstreig%eigval(j) + shift)*fstreig%mass(i)*u(i))**2
43  enddo
44  call hecmw_allreduce_r1(hecmesh, chk, hecmw_sum)
45  fstreig%resid(j) = dsqrt(chk)
46  enddo
47 
48  deallocate(t)
49  deallocate(u)
50  end subroutine fstr_eigen_residual
51 
52  subroutine fstr_eigen_output(hecMESH, hecMAT, fstrEIG)
53  use m_fstr
55  implicit none
56  type(hecmwst_local_mesh) :: hecmesh
57  type(hecmwst_matrix) :: hecMAT
58  type(fstr_eigen) :: fstrEIG
59 
60  integer(kind=kint) :: N, NDOF
61  integer(kind=kint) :: i, j, k, in, nget
62  real(kind=kreal) :: gm
63  real(kind=kreal), allocatable :: r(:)
64  real(kind=kreal), pointer :: mass(:), eigval(:), eigvec(:,:)
65 
66  n = hecmat%N
67  ndof = hecmesh%n_dof
68 
69  nget = fstreig%nget
70  mass => fstreig%mass
71  eigval => fstreig%eigval
72  eigvec => fstreig%eigvec
73 
74  allocate(fstreig%effmass(ndof*nget))
75  allocate(fstreig%partfactor(ndof*nget))
76  allocate(r(ndof))
77  fstreig%effmass = 0.0d0
78  fstreig%partfactor = 0.0d0
79 
80  do i = 1, nget
81  r = 0.0d0
82  gm = 0.0d0
83  do j = 1, n
84  do k = 1, ndof
85  in = ndof*(j-1) + k
86  r(k) = r(k) + mass(in)*eigvec(in,i)
87  gm = gm + mass(in)*eigvec(in,i)*eigvec(in,i)
88  enddo
89  enddo
90 
91  call hecmw_allreduce_r(hecmesh, r, ndof, hecmw_sum)
92  call hecmw_allreduce_r1(hecmesh, gm, hecmw_sum)
93 
94  gm = 1.0d0/gm
95  do j = 1, ndof
96  in = ndof*(i-1) + j
97  fstreig%partfactor(in) = gm*r(j)
98  fstreig%effmass(in) = gm*r(j)*r(j)
99  enddo
100  enddo
101 
102  call eglist(hecmesh, hecmat, fstreig)
103 
104  if(myrank == 0)then
105  write(imsg,*) ''
106  write(imsg,*) '*----------------------------------------------*'
107  write(imsg,*) '*--E I G E N V A L U E C O N V E R G E N C E--*'
108  write(imsg,*) 'Absolute residual = |(||Kx - lambda*Mx||)|'
109  write(imsg,*) ' Iter.# Eigenvalue Abs. Residual '
110  write(ilog,*) ' Iter.# Eigenvalue Abs. Residual '
111  write(imsg,*) ' *-----* *---------* *--------------*'
112  endif
113 
114  do j = 1, fstreig%nget
115  if(myrank == 0)then
116  write(imsg,'(2x,i5,2x,1p5e15.6)') j, eigval(j), fstreig%resid(j)
117  write(ilog,'(i5,1p5e12.4)') j, eigval(j), fstreig%resid(j)
118  endif
119  enddo
120 
121  if(myrank == 0)then
122  write(imsg,*)'* ---END Eigenvalue listing--- *'
123  endif
124 
125  deallocate(r)
126  end subroutine fstr_eigen_output
127 
128  subroutine fstr_eigen_make_result(hecMESH, hecMAT, fstrEIG, fstrRESULT)
129  use m_fstr
131  use hecmw_util
132  implicit none
133  type(hecmwst_local_mesh) :: hecmesh
134  type(hecmwst_matrix) :: hecMAT
135  type(fstr_eigen) :: fstrEIG
136  type(hecmwst_result_data) :: fstrRESULT
137 
138  integer(kind=kint) :: i, istep, nget, NP, NDOF, NPNDOF, totalmpc, MPC_METHOD
139  real(kind=kreal) :: t1
140  real(kind=kreal), pointer :: eigvec(:,:)
141  real(kind=kreal), allocatable :: x(:), egval(:)
142  real(kind=kreal), allocatable :: disp3(:), rot3(:)
143  character(len=HECMW_HEADER_LEN) :: header
144  character(len=HECMW_MSG_LEN) :: comment
145  character(len=HECMW_NAME_LEN) :: label
146  character(len=HECMW_NAME_LEN) :: nameID
147 
148  nget = fstreig%nget
149  np = hecmat%NP
150  ndof = hecmat%NDOF
151  npndof = hecmat%NP*hecmat%NDOF
152  !totalmpc = hecMESH%mpc%n_mpc
153  !call hecmw_allreduce_I1 (hecMESH, totalmpc, hecmw_sum)
154 
155  eigvec => fstreig%eigvec
156 
157  allocate(x(npndof))
158  x = 0.0d0
159  allocate(egval(1))
160 
161  do istep = 1, nget
162  egval(1) = fstreig%eigval(istep)
163  do i=1,npndof
164  x(i) = eigvec(i,istep)
165  enddo
166 
167  !if (totalmpc > 0) then
168  ! MPC_METHOD = hecmw_mat_get_mpc_method(hecMAT)
169  ! if (MPC_METHOD < 1 .or. 3 < MPC_METHOD) MPC_METHOD = 3
170  ! if (MPC_METHOD == 3) then ! elimination
171  ! call hecmw_tback_x_33(hecMESH, X, t1)
172  ! else
173  ! if (hecMESH%my_rank.eq.0) write(0,*) "### ERROR: MPC_METHOD must set to 3"
174  ! stop
175  ! endif
176  !endif
177 
178  call hecmw_update_r(hecmesh, x, hecmat%NP, ndof)
179 
180  ! For 6-DOF elements (e.g. shells 731/741), the eigenvector holds 3
181  ! translational + 3 rotational components per node. Writing all 6 as
182  ! DISPLACEMENT makes VTK/ParaView interpret it as a symmetric tensor
183  ! (NumberOfComponents=6), breaking Warp By Vector. Mirror the static
184  ! solver (make_result.f90, ndof==6) and split DISPLACEMENT (1:3) from
185  ! ROTATION (4:6). Other NDOF (e.g. solid 3) keep the pass-through.
186  if( ndof == 6 ) then
187  allocate(disp3(np*3))
188  allocate(rot3(np*3))
189  disp3 = 0.0d0
190  rot3 = 0.0d0
191  do i = 1, np
192  disp3((i-1)*3+1:(i-1)*3+3) = x((i-1)*ndof+1:(i-1)*ndof+3)
193  rot3((i-1)*3+1:(i-1)*3+3) = x((i-1)*ndof+4:(i-1)*ndof+6)
194  enddo
195  endif
196 
197  if( iresult.eq.1 ) then
198  header = "*fstrresult"
199  comment = "eigen_result"
200  call hecmw_result_init(hecmesh,istep,header,comment)
201  label = "EIGENVALUE"
202  call hecmw_result_add(hecmw_result_dtype_global,1,label,egval)
203  if( ndof == 6 ) then
204  label = "DISPLACEMENT"
205  call hecmw_result_add(hecmw_result_dtype_node,3,label,disp3)
206  label = "ROTATION"
207  call hecmw_result_add(hecmw_result_dtype_node,3,label,rot3)
208  else
209  label = "DISPLACEMENT"
210  call hecmw_result_add(hecmw_result_dtype_node,ndof,label,x)
211  endif
212  nameid = "fstrRES"
213  call hecmw_result_write_by_name(nameid)
214  call hecmw_result_finalize
215  endif
216 
217  if( ivisual.eq.1 ) then
218  call hecmw_nullify_result_data(fstrresult)
219  fstrresult%ng_component = 1
220  fstrresult%ne_component = 0
221  allocate(fstrresult%ng_dof(1))
222  allocate(fstrresult%global_label(1))
223  allocate(fstrresult%global_val_item(1))
224  fstrresult%ng_dof(1) = 1
225  fstrresult%global_label(1) = 'EIGENVALUE'
226  fstrresult%global_val_item(1) = egval(1)
227  if( ndof == 6 ) then
228  fstrresult%nn_component = 2
229  allocate(fstrresult%nn_dof(2))
230  allocate(fstrresult%node_label(2))
231  allocate(fstrresult%node_val_item(6*np))
232  fstrresult%nn_dof(1) = 3
233  fstrresult%nn_dof(2) = 3
234  fstrresult%node_label(1) = 'DISPLACEMENT'
235  fstrresult%node_label(2) = 'ROTATION'
236  do i = 1, np
237  fstrresult%node_val_item((i-1)*6+1:(i-1)*6+3) = disp3((i-1)*3+1:(i-1)*3+3)
238  fstrresult%node_val_item((i-1)*6+4:(i-1)*6+6) = rot3((i-1)*3+1:(i-1)*3+3)
239  enddo
240  else
241  fstrresult%nn_component = 1
242  allocate(fstrresult%nn_dof(1))
243  allocate(fstrresult%node_label(1))
244  allocate(fstrresult%node_val_item(ndof*np))
245  fstrresult%nn_dof(1) = ndof
246  fstrresult%node_label(1) = 'DISPLACEMENT'
247  fstrresult%node_val_item = x
248  endif
249  call fstr2hecmw_mesh_conv(hecmesh)
250  call hecmw_visualize_init
251  call hecmw_visualize( hecmesh, fstrresult, istep )
252  call hecmw_visualize_finalize
253  call hecmw2fstr_mesh_conv(hecmesh)
254  call hecmw_result_free(fstrresult)
255  endif
256 
257  if( ndof == 6 ) then
258  deallocate(disp3)
259  deallocate(rot3)
260  endif
261  enddo
262 
263  deallocate(x)
264 
265  end subroutine fstr_eigen_make_result
266 
268  subroutine eglist(hecMESH, hecMAT, fstrEIG)
269  use m_fstr
270  use hecmw_util
272  implicit none
273  type(hecmwst_local_mesh) :: hecMESH
274  type(hecmwst_matrix) :: hecMAT
275  type(fstr_eigen) :: fstrEIG
276 
277  integer(kind=kint) :: NDOF
278  integer(kind=kint) :: i, j, in, iter ,nget
279  real(kind=kreal) :: pi, angle, freq, pf(3), em(3)
280  real(kind=kreal), pointer :: eigval(:)
281 
282  ndof = hecmat%NDOF
283  nget = fstreig%nget
284  iter = fstreig%iter
285  pi = 4.0d0 * datan(1.0d0)
286  eigval => fstreig%eigval
287 
288  if(myrank == 0)then
289  write(ilog,*)""
290  write(ilog,"(a)")"********************************"
291  write(ilog,"(a)")"*RESULT OF EIGEN VALUE ANALYSIS*"
292  write(ilog,"(a)")"********************************"
293  write(ilog,"(a)")""
294  write(ilog,"(a,i8)")"NUMBER OF ITERATIONS = ",iter
295  write(ilog,"(a,1pe12.4)")"TOTAL MASS = ",fstreig%totalmass
296  write(ilog,"(a)")""
297  write(ilog,"(3a)")" ANGLE FREQUENCY ",&
298  "PARTICIPATION FACTOR EFFECTIVE MASS"
299  write(ilog,"(3a)")" NO. EIGENVALUE FREQUENCY (HZ) ",&
300  "X Y Z X Y Z"
301  write(ilog,"(3a)")" --- ---------- ---------- ---------- ",&
302  "---------- ---------- ---------- ---------- ---------- ----------"
303  write(*,*)""
304  write(*,"(a)")"#----------------------------------#"
305  write(*,"(a)")"# RESULT OF EIGEN VALUE ANALYSIS #"
306  write(*,"(a)")"#----------------------------------#"
307  write(*,"(a)")""
308  write(*,"(a,i8)")"### NUMBER OF ITERATIONS = ",iter
309  write(*,"(a,1pe12.4)")"### TOTAL MASS = ",fstreig%totalmass
310  write(*,"(a)")""
311  write(*,"(3a)")" PERIOD FREQUENCY ",&
312  "PARTICIPATION FACTOR EFFECTIVE MASS"
313  write(*,"(3a)")" NO. [Sec] [HZ] ",&
314  "X Y Z X Y Z"
315  write(*,"(3a)")" --- --------- --------- ",&
316  "--------- --------- --------- --------- --------- ---------"
317 
318  in = 0
319  do i = 1, nget
320  in = in + 1
321  if(eigval(i) < 0.0d0) eigval(i) = 0.0d0
322  angle = dsqrt(eigval(i))
323  freq = angle*0.5d0/pi
324 
325  pf = 0.0d0
326  em = 0.0d0
327  do j = 1, min(ndof, 3)
328  pf(j) = fstreig%partfactor(ndof*(i-1) + j)
329  em(j) = fstreig%effmass(ndof*(i-1) + j)
330  enddo
331 
332  write(ilog,'(I5,1P9E12.4)') in, eigval(i), angle, freq, pf(1), pf(2), pf(3), em(1), em(2), em(3)
333  write(* ,'(I5,1P8E11.3)') in, 1.0d0/freq, freq, pf(1), pf(2), pf(3), em(1), em(2), em(3)
334  enddo
335  write(ilog,*)""
336  write(*,*)""
337  endif
338 
339  end subroutine eglist
340 end module m_fstr_eig_output
341 
342 
subroutine, public hecmw_matvec(hecMESH, hecMAT, X, Y, COMMtime)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=4), parameter kreal
subroutine fstr_eigen_make_result(hecMESH, hecMAT, fstrEIG, fstrRESULT)
subroutine fstr_eigen_output(hecMESH, hecMAT, fstrEIG)
subroutine fstr_eigen_residual(hecMESH, hecMAT, fstrEIG)
residual of the eigenproblem as solved, i.e. in the reduced space of the MPC elimination
subroutine eglist(hecMESH, hecMAT, fstrEIG)
Output eigenvalues and vectors.
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint), pointer iresult
Definition: m_fstr.F90:129
integer(kind=kint) myrank
PARALLEL EXECUTION.
Definition: m_fstr.F90:103
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:117
integer(kind=kint), parameter ilog
FILE HANDLER.
Definition: m_fstr.F90:114
integer(kind=kint), pointer ivisual
Definition: m_fstr.F90:130
HECMW to FSTR Mesh Data Converter. Converting Connectivity of Element Type 232, 342 and 352.
subroutine fstr2hecmw_mesh_conv(hecMESH)
subroutine hecmw2fstr_mesh_conv(hecMESH)
Package of data used by Lanczos eigenvalue solver.
Definition: m_fstr.F90:628