FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_solver_contact.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 !-------------------------------------------------------------------------------
8 
10 
11  use hecmw_util
17  use m_hecmw_comm_f
18  use hecmw_ebc_defer
19 
20  implicit none
21 
22  private
23  public :: solve_lineq_contact_init
24  public :: solve_lineq_contact
25 
26 contains
27 
29  subroutine solve_lineq_contact_init(hecMESH,hecMAT,hecLagMAT,is_sym)
30  type (hecmwst_local_mesh) :: hecmesh
31  type (hecmwst_matrix) :: hecmat
32  type (hecmwst_matrix_lagrange) :: heclagmat
33  logical :: is_sym
34  integer(kind=kint) :: contact_elim, solver_type, iterlog, timelog, myrank
35  logical :: writelog
36 
37  contact_elim = hecmw_mat_get_contact_elim(hecmat)
38  solver_type = hecmw_mat_get_solver_type(hecmat)
39  iterlog = hecmw_mat_get_iterlog(hecmat)
40  timelog = hecmw_mat_get_timelog(hecmat)
41  myrank = hecmw_comm_get_rank()
42  writelog = (myrank==0 .and. (iterlog>0 .or. timelog>0))
43 
44  if( contact_elim==0 )then ! auto
45  if( solver_type==1 )then ! iterative
46  contact_elim=1
47  else ! direct
48  contact_elim=-1
49  endif
50  call hecmw_mat_set_contact_elim(hecmat,contact_elim)
51  endif
52 
53  if( contact_elim==1 )then
54  if( writelog ) write(*,*) 'solve contact with elimination'
55  call solve_lineq_contact_elim_init(hecmesh,hecmat,heclagmat,is_sym)
56  else
57  if( writelog ) write(*,*) 'solve contact without elimination'
58  if( solver_type==1 )then
59  write(*,*) 'ERROR: iterative solver without elimination not available in contact analysis'
61  elseif( solver_type==2 )then
62  call solve_lineq_serial_lag_hecmw_init(hecmat,heclagmat,is_sym)
63  else if( solver_type==3 )then
64  call solve_lineq_mkl_contact_init(hecmesh,is_sym)
65  elseif( solver_type==5 ) then
66  call solve_lineq_mumps_contact_init(hecmesh,hecmat,heclagmat,is_sym)
67  endif
68  endif
69  end subroutine solve_lineq_contact_init
70 
71 
73  subroutine solve_lineq_contact(hecMESH,hecMAT,hecLagMAT,conMAT,hecEBC,istat,rf,is_contact_active)
74 
75  type (hecmwst_local_mesh) :: hecmesh
76  type (hecmwst_matrix) :: hecmat
77  type (hecmwst_matrix_lagrange) :: heclagmat
78  type (hecmwst_matrix) :: conmat
79  type (hecmwst_ebc) :: hecebc
80  integer(kind=kint), intent(out) :: istat
81  real(kind=kreal), optional :: rf
82  logical :: is_contact_active
83 
84  real(kind=kreal) :: factor
85  real(kind=kreal) :: t1, t2
86  integer(kind=kint) :: ndof
87  integer(kind=kint) :: contact_elim, solver_type
88 
89  contact_elim = hecmw_mat_get_contact_elim(hecmat)
90  solver_type = hecmw_mat_get_solver_type(hecmat)
91 
92  factor = 1.0d0
93  if( present(rf) )factor = rf
94 
95  t1 = hecmw_wtime()
96 
97  istat = 0
98  ! the direct-solver branches below report failure through istat only and never
99  ! touch these flags; clear them so a stale verdict from an earlier solve is not
100  ! mistaken for this one's. The elimination branch overwrites them with the real result.
101  call hecmw_mat_set_flag_converged(hecmat, 1)
102  call hecmw_mat_set_flag_diverged(hecmat, 0)
103  if( contact_elim==1 )then
104  call solve_lineq_contact_elim(hecmesh,hecmat,heclagmat,hecebc,istat,conmat,is_contact_active)
105  else
106  if( solver_type==1 )then
107  write(*,*) 'ERROR: iterative solver without elimination not available in contact analysis'
109  elseif( solver_type==2 )then
110  if( hecmw_comm_get_size() > 1) then
111  write(*,*) 'ERROR: !SOLVER,METHOD=DIRECT not available in parallel contact analysis;',&
112  ' please use MUMPS or DIRECTmkl instead'
114  else
115  call add_conmat_to_hecmat(hecmat,conmat,heclagmat)
116  call solve_lineq_serial_lag_hecmw(hecmesh,hecmat,heclagmat,hecebc)
117  endif
118  elseif( solver_type==3 )then
119  if( hecmw_comm_get_size() > 1) then
120  call solve_lineq_mkl_contact(hecmesh,hecmat,heclagmat,hecebc,istat,conmat)
121  else
122  call add_conmat_to_hecmat(hecmat,conmat,heclagmat)
123  call solve_lineq_mkl_contact(hecmesh,hecmat,heclagmat,hecebc,istat)
124  endif
125  elseif( solver_type==5 ) then
126  call solve_lineq_mumps_contact(hecmesh,hecmat,heclagmat,hecebc,istat,conmat)
127  endif
128  endif
129 
130  ndof = hecmat%NDOF
131  call hecmw_update_r(hecmesh,hecmat%X,hecmesh%n_node, ndof)
132 
133  t2 = hecmw_wtime()
134  if (hecmw_mat_get_timelog(hecmat) .ge. 1) then
135  if ( hecmw_comm_get_rank() ==0) write(*,*) ' solve time :', t2 - t1
136  endif
137 
138  hecmat%X=factor*hecmat%X
139 
140  end subroutine solve_lineq_contact
141 
142 
143  subroutine add_conmat_to_hecmat(hecMAT,conMAT,hecLagMat)
144  type (hecmwst_matrix), intent(inout) :: hecmat
145  type (hecmwst_matrix), intent(in) :: conmat
146  type (hecmwst_matrix_lagrange), intent(in) :: heclagmat
147 
148 
149  integer(kind=kint) :: ndof,ndof2,i
150 
151  ndof = hecmat%NDOF
152  ndof2 = ndof*ndof
153 
154  do i=1,hecmat%NP*ndof + heclagmat%num_lagrange
155  hecmat%B(i) = hecmat%B(i) + conmat%B(i)
156  enddo
157 
158  do i=1,hecmat%NP*ndof2
159  hecmat%D(i) = hecmat%D(i) + conmat%D(i)
160  enddo
161 
162  do i=1,hecmat%NPL*ndof2
163  hecmat%AL(i) = hecmat%AL(i) + conmat%AL(i)
164  enddo
165 
166  do i=1,hecmat%NPU*ndof2
167  hecmat%AU(i) = hecmat%AU(i) + conmat%AU(i)
168  enddo
169  end subroutine add_conmat_to_hecmat
170 
171 
172 end module m_solve_lineq_contact
Essential boundary conditions kept as per-DOF marks and values so that they can be imposed on the mat...
integer(kind=kint) function, public hecmw_mat_get_solver_type(hecMAT)
subroutine, public hecmw_mat_set_contact_elim(hecMAT, contact_elim)
subroutine, public hecmw_mat_set_flag_diverged(hecMAT, flag_diverged)
subroutine, public hecmw_mat_set_flag_converged(hecMAT, flag_converged)
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_contact_elim(hecMAT)
I/O and Utility.
Definition: hecmw_util_f.F90:7
subroutine hecmw_abort(comm, code)
integer(kind=kint) function hecmw_comm_get_size()
integer(kind=kint) function hecmw_comm_get_comm()
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
real(kind=kreal) function hecmw_wtime()
subroutine hecmw_update_r(hecMESH, val, n, m)
This module provides interface of iteratie linear equation solver for contact problems using Lagrange...
subroutine, public solve_lineq_contact_elim_init(hecMESH, hecMAT, hecLagMAT, is_sym)
subroutine, public solve_lineq_contact_elim(hecMESH, hecMAT, hecLagMAT, hecEBC, istat, conMAT, is_contact_active)
This module provides functions to solve sparse system of \linear equitions in the case of contact ana...
subroutine, public solve_lineq_contact_init(hecMESH, hecMAT, hecLagMAT, is_sym)
This subroutine.
subroutine, public solve_lineq_contact(hecMESH, hecMAT, hecLagMAT, conMAT, hecEBC, istat, rf, is_contact_active)
This subroutine.
subroutine solve_lineq_serial_lag_hecmw_init(hecMAT, hecLagMAT, is_sym)
subroutine solve_lineq_serial_lag_hecmw(hecMESH, hecMAT, hecLagMAT, hecEBC)
This module provides functions to solve sparse system of \linear equitions using intel MKL direct spa...
subroutine, public solve_lineq_mkl_contact_init(hecMESH, is_sym)
subroutine, public solve_lineq_mkl_contact(hecMESH, hecMAT, hecLagMAT, hecEBC, istat, conMAT)
This subroutine executes the MKL solver.
This module provides linear equation solver interface of MUMPS for contact problems using Lagrange mu...
subroutine, public solve_lineq_mumps_contact_init(hecMESH, hecMAT, hecLagMAT, is_sym)
subroutine, public solve_lineq_mumps_contact(hecMESH, hecMAT, hecLagMAT, hecEBC, istat, conMAT)
Structure for Lagrange multiplier-related part of stiffness matrix (Lagrange multiplier-related matri...