20 logical,
save :: INITIALIZED = .false.
21 logical,
save :: NEED_ANALYSIS = .true.
22 logical,
save :: IS_SYMMETRIC = .true.
26 type (hecmwST_matrix),
save :: mfMAT
30 integer(kind=kint),
parameter :: MFC_IR_STEPS = 5
31 real(kind=
kreal),
parameter :: mfc_ir_tol = 1.0d-8
40 logical,
intent(in) :: is_sym
48 need_analysis = .true.
57 type (hecmwst_ebc),
intent(inout) :: hecebc
58 integer(kind=kint),
intent(out) :: istat
59 integer(kind=kint) :: ntdf, mpc_method, iterlog, timelog, irmax, it
60 real(kind=
kreal) :: bnrm, rnrm, rprev, irtol, t1, t2
61 real(kind=
kreal),
allocatable :: bb(:), xx(:), rr(:), xp(:)
63 integer(kind=kint),
parameter :: imsg = 51
66 if (mpc_method < 1 .or. 3 < mpc_method)
then
70 if (mpc_method /= 1)
then
71 write(*,*)
'ERROR: MPCMETHOD other than penalty is not available for DIRECTmf solver', &
72 ' in contact analysis without elimination'
81 if (need_analysis)
then
82 call mf_contact_set_profile(hecmat, heclagmat)
83 need_analysis = .false.
86 call mf_contact_set_values(hecmat, heclagmat)
87 ntdf = hecmat%NP*hecmat%NDOF + heclagmat%num_lagrange
88 mfmat%B(1:ntdf) = hecmat%B(1:ntdf)
89 mfmat%X(1:ntdf) = 0.0d0
91 mfmat%symmetric = is_symmetric
98 irmax = hecmat%Iarray(44)
99 if (irmax == 0) irmax = mfc_ir_steps
103 irtol = hecmat%Rarray(42)
104 if (.not. (irtol > 0.0d0)) irtol = mfc_ir_tol
105 allocate(bb(ntdf), xx(ntdf), rr(ntdf), xp(ntdf))
106 bb(1:ntdf) = mfmat%B(1:ntdf)
107 xx(1:ntdf) = mfmat%X(1:ntdf)
108 bnrm = sqrt(dot_product(bb(1:ntdf), bb(1:ntdf)))
112 call mf_contact_resid(ntdf, xx, bb, rr)
113 rnrm = sqrt(dot_product(rr(1:ntdf), rr(1:ntdf))) / max(bnrm, tiny(bnrm))
114 if (iterlog > 0)
write(*,
'(a,i0,a,1pe11.4)')
'[DIRECTmf]: refinement ', it - 1,
': residual = ', rnrm
115 if (rnrm <= irtol)
exit
118 if (rnrm > rprev)
then
119 xx(1:ntdf) = xp(1:ntdf)
120 write(*,
'(a,1pe11.4)')
'[DIRECTmf]: WARNING: refinement diverged, reverted to residual = ', rprev
124 xp(1:ntdf) = xx(1:ntdf)
125 mfmat%B(1:ntdf) = rr(1:ntdf)
127 xx(1:ntdf) = xx(1:ntdf) + mfmat%X(1:ntdf)
130 if (timelog > 0)
write(*,
'(a,f10.3,a)')
'[DIRECTmf]: refinement done (', t2 - t1,
' sec)'
131 mfmat%X(1:ntdf) = xx(1:ntdf)
132 deallocate(bb, xx, rr, xp)
135 hecmat%X(1:ntdf) = mfmat%X(1:ntdf)
144 subroutine mf_contact_set_profile(hecMAT, hecLagMAT)
148 integer(kind=kint) :: np, ndof, nlag, ntdf, npl, npu
149 integer(kind=kint) :: i, j, k, l, cl, cu
153 nlag = heclagmat%num_lagrange
154 ntdf = np*ndof + nlag
155 npl = hecmat%NPL*ndof*ndof + np*ndof*(ndof-1)/2
156 npu = hecmat%NPU*ndof*ndof + np*ndof*(ndof-1)/2
158 npl = npl + heclagmat%numL_lagrange*ndof
159 npu = npu + heclagmat%numU_lagrange*ndof
168 allocate(mfmat%indexL(0:ntdf), mfmat%indexU(0:ntdf))
169 allocate(mfmat%itemL(npl), mfmat%itemU(npu))
170 allocate(mfmat%D(ntdf), mfmat%AL(npl), mfmat%AU(npu))
171 allocate(mfmat%B(ntdf), mfmat%X(ntdf))
179 do l = hecmat%indexL(i-1)+1, hecmat%indexL(i)
182 mfmat%itemL(cl) = (hecmat%itemL(l)-1)*ndof + k
187 mfmat%itemL(cl) = (i-1)*ndof + k
191 mfmat%itemU(cu) = (i-1)*ndof + k
193 do l = hecmat%indexU(i-1)+1, hecmat%indexU(i)
196 mfmat%itemU(cu) = (hecmat%itemU(l)-1)*ndof + k
200 do l = heclagmat%indexU_lagrange(i-1)+1, heclagmat%indexU_lagrange(i)
202 mfmat%itemU(cu) = np*ndof + heclagmat%itemU_lagrange(l)
205 mfmat%indexL((i-1)*ndof+j) = cl
206 mfmat%indexU((i-1)*ndof+j) = cu
210 do l = heclagmat%indexL_lagrange(i-1)+1, heclagmat%indexL_lagrange(i)
213 mfmat%itemL(cl) = (heclagmat%itemL_lagrange(l)-1)*ndof + k
216 mfmat%indexL(np*ndof+i) = cl
217 mfmat%indexU(np*ndof+i) = cu
220 mfmat%Iarray = hecmat%Iarray
221 mfmat%Rarray = hecmat%Rarray
222 if (mfmat%Iarray(43) /= 0)
then
225 '[DIRECTmf]: BLR is not available in contact analysis without elimination; disabled'
230 mfmat%Iarray(44) = -1
233 end subroutine mf_contact_set_profile
237 subroutine mf_contact_set_values(hecMAT, hecLagMAT)
241 integer(kind=kint) :: np, ndof, nlag
242 integer(kind=kint) :: i, j, k, l, cl, cu
246 nlag = heclagmat%num_lagrange
252 do l = hecmat%indexL(i-1)+1, hecmat%indexL(i)
255 mfmat%AL(cl) = hecmat%AL(((l-1)*ndof+j-1)*ndof+k)
260 mfmat%AL(cl) = hecmat%D(((i-1)*ndof+j-1)*ndof+k)
262 mfmat%D((i-1)*ndof+j) = hecmat%D(((i-1)*ndof+j-1)*ndof+j)
265 mfmat%AU(cu) = hecmat%D(((i-1)*ndof+j-1)*ndof+k)
267 do l = hecmat%indexU(i-1)+1, hecmat%indexU(i)
270 mfmat%AU(cu) = hecmat%AU(((l-1)*ndof+j-1)*ndof+k)
274 do l = heclagmat%indexU_lagrange(i-1)+1, heclagmat%indexU_lagrange(i)
276 mfmat%AU(cu) = heclagmat%AU_lagrange((l-1)*ndof+j)
282 mfmat%D(np*ndof+i) = 0.0d0
283 do l = heclagmat%indexL_lagrange(i-1)+1, heclagmat%indexL_lagrange(i)
286 mfmat%AL(cl) = heclagmat%AL_lagrange((l-1)*ndof+k)
290 end subroutine mf_contact_set_values
293 subroutine mf_contact_resid(ntdf, x, b, r)
295 integer(kind=kint),
intent(in) :: ntdf
296 real(kind=
kreal),
intent(in) :: x(:), b(:)
297 real(kind=
kreal),
intent(out) :: r(:)
298 integer(kind=kint) :: i, l
299 real(kind=
kreal) :: s
303 do l = mfmat%indexL(i-1)+1, mfmat%indexL(i)
304 s = s + mfmat%AL(l)*x(mfmat%itemL(l))
306 do l = mfmat%indexU(i-1)+1, mfmat%indexU(i)
307 s = s + mfmat%AU(l)*x(mfmat%itemU(l))
311 end subroutine mf_contact_resid
Essential boundary conditions kept as per-DOF marks and values so that they can be imposed on the mat...
subroutine, public hecmw_ebc_apply(hecMESH, hecMAT, hecEBC, conMAT)
subroutine, public hecmw_mat_ass_equation_rhs(hecMESH, hecMAT)
subroutine, public hecmw_mat_ass_equation(hecMESH, hecMAT)
subroutine, public hecmw_mat_dump(hecMAT, hecMESH)
subroutine, public hecmw_mat_dump_solution(hecMAT)
subroutine, public hecmw_mat_init(hecMAT)
subroutine, public hecmw_mat_finalize(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_iterlog(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_timelog(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_mpc_method(hecMAT)
subroutine, public hecmw_mat_set_mpc_method(hecMAT, mpc_method)
Multifrontal direct solver (METHOD=DIRECTmf): LDLt with threshold pivoting for symmetric (possibly in...
subroutine, public hecmw_solve_direct_mf(hecMESH, hecMAT, imsg)
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
real(kind=kreal) function hecmw_wtime()
Structure for Lagrange multiplier-related part of stiffness matrix (Lagrange multiplier-related matri...