FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
set_arrays_DirectSolver.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 !-------------------------------------------------------------------------------
7 
9  use hecmw_util
10 
11  implicit none
12 
13  integer (kind=kint) :: numnon0
14  integer (kind=kint), allocatable :: pointers(:)
15  integer (kind=kint), allocatable :: indices(:)
16  real (kind=kreal) , allocatable :: values(:)
17 
19 
20 contains
21 
22 
25  subroutine set_pointersandindices_directsolver(hecMAT,hecLagMAT,is_sym)
26 
27  type(hecmwst_matrix) :: hecMAT
28  type (hecmwST_matrix_lagrange) :: hecLagMAT
29  logical :: is_sym
30 
31  integer (kind=kint) :: np
32  integer (kind=kint) :: ndof
33  integer (kind=kint) :: num_lagrange
34  integer (kind=kint) :: nn
35  integer (kind=kint) :: ierr
36  integer (kind=kint) :: i, j, k, l, countNon0
37 
38  symmetricmatrixstruc = is_sym
39 
40  np = hecmat%NP ; ndof = hecmat%NDOF ; num_lagrange = heclagmat%num_lagrange
41  nn = np*ndof + num_lagrange + 1
42 
43  if( symmetricmatrixstruc )then
44  numnon0 = hecmat%NPU*ndof**2+hecmat%NP*ndof*(ndof+1)/2 &
45  + (heclagmat%numU_lagrange)*ndof+heclagmat%num_lagrange
46  else
47  numnon0 = (hecmat%NPL+hecmat%NPU+hecmat%NP)*ndof**2 &
48  + (heclagmat%numL_lagrange+heclagmat%numU_lagrange)*ndof
49  endif
50 
51  if(allocated(pointers))deallocate(pointers)
52  allocate(pointers(nn), stat=ierr)
53  if( ierr /= 0 ) stop " Allocation error, mkl%pointers "
54  pointers = 0
55 
56  if(allocated(indices))deallocate(indices)
57  allocate(indices(numnon0), stat=ierr)
58  if( ierr /= 0 ) stop " Allocation error, mkl%indices "
59  indices = 0
60 
61  pointers(1) = 1
62  countnon0 = 1
63 
64  do i = 1, np
65  do j = 1, ndof
66  if( .not. symmetricmatrixstruc )then
67  do l = hecmat%indexL(i-1)+1, hecmat%indexL(i)
68  do k = 1, ndof
69  indices(countnon0) = (hecmat%itemL(l)-1)*ndof + k
70  countnon0 = countnon0 + 1
71  enddo
72  enddo
73  do k = 1, j-1
74  indices(countnon0) = (i-1)*ndof + k
75  countnon0 = countnon0 + 1
76  enddo
77  endif
78  do k = j, ndof
79  indices(countnon0) = (i-1)*ndof + k
80  countnon0 = countnon0 + 1
81  enddo
82  do l = hecmat%indexU(i-1)+1, hecmat%indexU(i)
83  do k = 1, ndof
84  indices(countnon0) = (hecmat%itemU(l)-1)*ndof + k
85  countnon0 = countnon0 + 1
86  enddo
87  enddo
88  if( num_lagrange > 0 )then
89  do l = heclagmat%indexU_lagrange(i-1)+1, heclagmat%indexU_lagrange(i)
90  indices(countnon0) = np*ndof + heclagmat%itemU_lagrange(l)
91  countnon0 = countnon0 + 1
92  enddo
93  endif
94  pointers((i-1)*ndof+j+1) = countnon0
95  enddo
96  enddo
97 
98  if( num_lagrange > 0 )then
99  do i = 1, num_lagrange
100  if( symmetricmatrixstruc )then
101  indices(countnon0) = np*ndof + i
102  countnon0 = countnon0 + 1
103  else
104  do l = heclagmat%indexL_lagrange(i-1)+1, heclagmat%indexL_lagrange(i)
105  do k = 1, ndof
106  indices(countnon0) = (heclagmat%itemL_lagrange(l)-1)*ndof + k
107  countnon0 = countnon0 + 1
108  enddo
109  enddo
110  endif
111  pointers(np*ndof+i+1) = countnon0
112  enddo
113  endif
114 
116 
117 
121  subroutine set_values_directsolver(hecMAT,hecLagMAT)
122 
123  type(hecmwst_matrix) :: hecMAT
124  type (hecmwST_matrix_lagrange) :: hecLagMAT
125 
126  integer (kind=kint) :: np
127  integer (kind=kint) :: ndof
128  integer (kind=kint) :: num_lagrange
129  integer (kind=kint) :: ierr
130  integer (kind=kint) :: i, j, k, l
131  integer (kind=kint) :: countNon0, locINal, locINd, locINau, locINal_lag, locINau_lag
132 
133  np = hecmat%NP ; ndof = hecmat%NDOF ; num_lagrange = heclagmat%num_lagrange
134 
135  if(allocated(values))deallocate(values)
136  allocate(values(numnon0), stat=ierr)
137  if( ierr /= 0 ) stop " Allocation error, mkl%values "
138  values = 0.0d0
139 
140  countnon0 = 1
141  do i = 1, np
142  do j = 1, ndof
143  if( .not. symmetricmatrixstruc )then
144  do l = hecmat%indexL(i-1)+1, hecmat%indexL(i)
145  do k = 1, ndof
146  locinal = ((l-1)*ndof+j-1)*ndof + k
147  values(countnon0) = hecmat%AL(locinal)
148  countnon0 = countnon0 + 1
149  enddo
150  enddo
151  do k = 1, j-1
152  locind = ((i-1)*ndof+j-1)*ndof + k
153  values(countnon0) = hecmat%D(locind)
154  countnon0 = countnon0 + 1
155  enddo
156  endif
157  do k = j, ndof
158  locind = ((i-1)*ndof+j-1)*ndof + k
159  values(countnon0) = hecmat%D(locind)
160  countnon0 = countnon0 + 1
161  enddo
162  do l = hecmat%indexU(i-1)+1, hecmat%indexU(i)
163  do k = 1, ndof
164  locinau = ((l-1)*ndof+j-1)*ndof + k
165  values(countnon0) = hecmat%AU(locinau)
166  countnon0 = countnon0 + 1
167  enddo
168  enddo
169  if( num_lagrange > 0 )then
170  do l = heclagmat%indexU_lagrange(i-1)+1, heclagmat%indexU_lagrange(i)
171  locinau_lag = (l-1)*ndof + j
172  values(countnon0) = heclagmat%AU_lagrange(locinau_lag)
173  countnon0 = countnon0 + 1
174  enddo
175  endif
176  enddo
177  enddo
178 
179  if( .not.symmetricmatrixstruc .and. num_lagrange > 0 )then
180  do i = 1, num_lagrange
181  do l = heclagmat%indexL_lagrange(i-1)+1, heclagmat%indexL_lagrange(i)
182  do k = 1, ndof
183  locinal_lag = (l-1)*ndof + k
184  values(countnon0) = heclagmat%AL_lagrange(locinal_lag)
185  countnon0 = countnon0 + 1
186  enddo
187  enddo
188  enddo
189  endif
190 
191  end subroutine set_values_directsolver
192 
194  subroutine getapproximateb(ntdf,x,y)
195 
196  integer(kind=kint) :: ntdf
197  integer(kind=kint) :: i, j, k
198  real(kind=kreal) :: x(ntdf)
199  real(kind=kreal) :: y(ntdf)
200 
201  y = 0.0d0
202  do i = 1, ntdf
203  do j = pointers(i), pointers(i+1)-1
204  k = indices(j)
205  y(i) = y(i) + values(j)*x(k)
206  if( symmetricmatrixstruc .and. k/=i )&
207  y(k)=y(k)+values(j)*x(i)
208  enddo
209  enddo
210 
211  end subroutine getapproximateb
212 
213 
214  subroutine checkresidual(hecMAT,hecLagMAT)
215  type(hecmwst_matrix) :: hecmat
216  type (hecmwst_matrix_lagrange) :: hecLagMAT
217  integer(kind=kint) :: ntdf
218  real(kind=kreal), allocatable :: y(:)
219  real(kind=kreal) :: residual_max
220 
221  ntdf = hecmat%NP*hecmat%NDOF + heclagmat%num_lagrange
222 
223  allocate(y(size(hecmat%B)))
224  y = 0.0d0
225  call getapproximateb(ntdf,hecmat%X,y)
226  residual_max=maxval(dabs(y-hecmat%B))
227  write(*,*)' maximum residual = ',residual_max
228  if( dabs(residual_max) >= 1.0d-8) then
229  write(*,*) ' ###Maximum residual exceeded 1.0d-8---Direct Solver### '
230  ! stop
231  endif
232  deallocate(y)
233 
234  end subroutine checkresidual
235 
236 
m_set_arrays_directsolver_contact::checkresidual
subroutine checkresidual(hecMAT, hecLagMAT)
Definition: set_arrays_DirectSolver.f90:215
m_set_arrays_directsolver_contact::indices
integer(kind=kint), dimension(:), allocatable indices
ja
Definition: set_arrays_DirectSolver.f90:15
m_set_arrays_directsolver_contact::set_values_directsolver
subroutine set_values_directsolver(hecMAT, hecLagMAT)
This subroutine sets the array for direct sparse solver that contains \the non-zero items(elements)of...
Definition: set_arrays_DirectSolver.f90:122
m_set_arrays_directsolver_contact::pointers
integer(kind=kint), dimension(:), allocatable pointers
ia
Definition: set_arrays_DirectSolver.f90:14
m_set_arrays_directsolver_contact::numnon0
integer(kind=kint) numnon0
Definition: set_arrays_DirectSolver.f90:13
hecmw_util
I/O and Utility.
Definition: hecmw_util_f.F90:7
m_set_arrays_directsolver_contact::getapproximateb
subroutine getapproximateb(ntdf, x, y)
This subroutine gets the residual vector.
Definition: set_arrays_DirectSolver.f90:195
hecmw_util::kreal
integer(kind=4), parameter kreal
Definition: hecmw_util_f.F90:16
m_set_arrays_directsolver_contact::symmetricmatrixstruc
logical symmetricmatrixstruc
Definition: set_arrays_DirectSolver.f90:18
m_set_arrays_directsolver_contact::set_pointersandindices_directsolver
subroutine set_pointersandindices_directsolver(hecMAT, hecLagMAT, is_sym)
This subroutine sets index arrays for direct sparse solver from those stored \in the matrix structure...
Definition: set_arrays_DirectSolver.f90:26
hecmw_util::hecmwst_matrix_lagrange
Structure for Lagrange multiplier-related part of stiffness matrix (Lagrange multiplier-related matri...
Definition: hecmw_util_f.F90:427
m_set_arrays_directsolver_contact
This module provides functions to set arrays for direct sparse solver \in the case of using standard ...
Definition: set_arrays_DirectSolver.f90:8
m_set_arrays_directsolver_contact::values
real(kind=kreal), dimension(:), allocatable values
a
Definition: set_arrays_DirectSolver.f90:16
hecmw_util::hecmwst_matrix
Definition: hecmw_util_f.F90:444