20 public :: hecmwst_matrix_lagrange
30 integer(kind=kint),
save :: NPL_org, NPU_org
31 type(nodeRelated),
pointer,
save :: list_nodeRelated_org(:) => null()
33 type(nodeRelated),
pointer :: list_nodeRelated(:) => null()
35 logical :: permission = .false.
40 integer(kind=kint) :: algtype
41 if( algtype == contactsslid .or. algtype == contactfslid )
then
43 else if( algtype == contacttied )
then
51 type(hecmwst_matrix) :: hecmat
53 if(
associated(list_noderelated_org) )
return
54 call hecmw_construct_noderelated_from_hecmat(hecmat, npl_org, npu_org, list_noderelated_org)
60 subroutine fstr_mat_con_contact(cstep,contact_algo,hecMAT,fstrSOLID,hecLagMAT,infoCTChange,conMAT,is_contact_active_flag)
62 integer(kind=kint) :: cstep
63 integer(kind=kint) :: contact_algo
64 type(hecmwst_matrix) :: hecmat
66 type(hecmwst_matrix_lagrange) :: heclagmat
67 type(fstr_info_contactchange) :: infoctchange
69 integer(kind=kint) :: num_lagrange
70 integer(kind=kint) :: countnon0lu_node, countnon0lu_lagrange
71 integer(kind=kint) :: numnon0_node, numnon0_lagrange
73 type (hecmwst_matrix) :: conmat
74 logical,
intent(in) :: is_contact_active_flag
76 integer(kind=kint) :: i, j, grpid
77 integer(kind=kint) :: count_n2s, count_s2s
78 integer(kind=kint) :: nlag
82 do i = 1, fstrsolid%n_contacts
83 if( fstrsolid%contacts(i)%method == contactn2s ) count_n2s = count_n2s + 1
84 if( fstrsolid%contacts(i)%method == contacts2s ) count_s2s = count_s2s + 1
86 count_n2s = count_n2s + fstrsolid%n_embeds
90 do i = 1, fstrsolid%n_contacts
91 grpid = fstrsolid%contacts(i)%group
94 do j = 1,
size(fstrsolid%contacts(i)%slave)
95 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
96 num_lagrange = num_lagrange + nlag
100 do i = 1, fstrsolid%n_embeds
101 grpid = fstrsolid%embeds(i)%group
104 do j = 1,
size(fstrsolid%embeds(i)%slave)
105 if( .not. is_contact_active(fstrsolid%embeds(i)%states(j)%state) ) cycle
106 num_lagrange = num_lagrange + nlag
112 call hecmw_init_noderelated_from_org(hecmat%NP,num_lagrange,is_contact_active_flag,list_noderelated_org,list_noderelated)
115 countnon0lu_node = npl_org + npu_org
116 countnon0lu_lagrange = 0
117 if( is_contact_active_flag )
then
118 if( count_n2s > 0 ) &
119 call getnewlistofrelatednodesandlagrangemultipliers(cstep,contact_algo, &
120 & hecmat%NP,fstrsolid,countnon0lu_node,countnon0lu_lagrange,list_noderelated)
121 if( count_s2s > 0 ) &
122 call getnewlistofrelatednodesandlagrangemultipliers_ss(cstep,contact_algo, &
123 & hecmat%NP,fstrsolid,countnon0lu_node,countnon0lu_lagrange,list_noderelated)
127 numnon0_node = countnon0lu_node/2
128 numnon0_lagrange = countnon0lu_lagrange/2
129 call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
130 & numnon0_node, num_lagrange, list_noderelated, hecmat)
131 call hecmw_construct_hecmat_from_noderelated(hecmat%N, hecmat%NP, hecmat%NDOF, &
132 & numnon0_node, num_lagrange, list_noderelated, conmat)
133 if( contact_algo ==
kcaslagrange )
call hecmw_construct_heclagmat_from_noderelated(hecmat%NP, &
134 & hecmat%NDOF, num_lagrange, numnon0_lagrange, is_contact_active_flag, list_noderelated, heclagmat)
135 call hecmw_finalize_noderelated(list_noderelated)
138 if( is_contact_active_flag .and. contact_algo ==
kcaslagrange ) &
139 call fstr_copy_lagrange_contact(fstrsolid,heclagmat)
144 subroutine getnewlistofrelatednodesandlagrangemultipliers( &
145 & cstep, contact_algo, np, fstrSOLID, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
146 integer(kind=kint),
intent(in) :: cstep
147 integer(kind=kint),
intent(in) :: contact_algo
148 integer(kind=kint),
intent(in) :: np
150 integer(kind=kint),
intent(inout) :: countnon0lu_node, countnon0lu_lagrange
151 type(noderelated),
pointer,
intent(inout) :: list_noderelated(:)
153 integer(kind=kint) :: grpid
154 integer(kind=kint) :: count_lagrange
155 integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(l_max_surface_node + 1)
156 integer(kind=kint) :: i, j, k, nlag, algtype
157 real(kind=kreal) :: fcoeff
158 logical :: necessary_to_insert_node, necessary_to_insert_node_pair
159 logical :: is_contact_active_flag, is_damping_active_flag
162 do i = 1, fstrsolid%n_contacts
166 if( fstrsolid%contacts(i)%method /= contactn2s ) cycle
168 grpid = fstrsolid%contacts(i)%group
171 fcoeff = fstrsolid%contacts(i)%fcoeff
172 necessary_to_insert_node = ( fcoeff /= 0.0d0 .or. contact_algo ==
kcaalagrange )
174 algtype = fstrsolid%contacts(i)%algtype
177 if( algtype == contacttied ) permission = .true.
179 do j = 1,
size(fstrsolid%contacts(i)%slave)
181 is_contact_active_flag = is_contact_active(fstrsolid%contacts(i)%states(j)%state)
183 is_damping_active_flag = fstrsolid%contacts(i)%states(j)%state == contactnear .and. &
186 if( is_contact_active_flag .or. is_damping_active_flag )
then
188 ctsurf = fstrsolid%contacts(i)%states(j)%surface
189 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
191 stop
" ##Error: This element type is not supported in contact analysis !!! "
192 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
193 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
194 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
198 necessary_to_insert_node_pair = necessary_to_insert_node .or. is_damping_active_flag
200 if( is_contact_active_flag )
then
202 if( contact_algo ==
kcaslagrange ) count_lagrange = count_lagrange + 1
203 call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
204 & necessary_to_insert_node_pair, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
208 call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, 0, permission, &
209 & necessary_to_insert_node_pair, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
218 do i = 1, fstrsolid%n_embeds
220 grpid = fstrsolid%embeds(i)%group
223 necessary_to_insert_node = ( contact_algo ==
kcaalagrange )
229 do j = 1,
size(fstrsolid%embeds(i)%slave)
231 if( .not. is_contact_active(fstrsolid%embeds(i)%states(j)%state) ) cycle
232 ctsurf = fstrsolid%embeds(i)%states(j)%surface
233 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
234 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
235 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
236 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
239 if( contact_algo ==
kcaslagrange ) count_lagrange = count_lagrange + 1
240 call hecmw_ass_noderelated_from_contact_pair(np, nnode, ndlocal, count_lagrange, permission, &
241 & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
247 end subroutine getnewlistofrelatednodesandlagrangemultipliers
250 subroutine fstr_copy_lagrange_contact(fstrSOLID,hecLagMAT)
253 type(hecmwst_matrix_lagrange) :: heclagmat
254 integer (kind=kint) :: id_lagrange, algtype, i, j, k, nlag, slave_node
258 do i = 1, fstrsolid%n_contacts
260 algtype = fstrsolid%contacts(i)%algtype
263 do j = 1,
size(fstrsolid%contacts(i)%slave)
264 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
265 slave_node = fstrsolid%contacts(i)%slave(j)
266 heclagmat%lag_node_table(slave_node) = id_lagrange + 1
268 id_lagrange = id_lagrange + 1
269 heclagmat%Lagrange(id_lagrange)=fstrsolid%contacts(i)%states(j)%multiplier(k)
274 do i = 1, fstrsolid%n_embeds
276 do j = 1,
size(fstrsolid%embeds(i)%slave)
277 if( .not. is_contact_active(fstrsolid%embeds(i)%states(j)%state) ) cycle
278 slave_node = fstrsolid%embeds(i)%slave(j)
279 heclagmat%lag_node_table(slave_node) = id_lagrange + 1
281 id_lagrange = id_lagrange + 1
282 heclagmat%Lagrange(id_lagrange)=fstrsolid%embeds(i)%states(j)%multiplier(k)
287 end subroutine fstr_copy_lagrange_contact
293 type(hecmwst_local_mesh) :: hecmesh
294 integer (kind=kint) :: is_in_contact
297 if( fstrsolid%n_contacts>0 )
then
298 if( any(fstrsolid%contacts(:)%fcoeff /= 0.0d0) ) is_in_contact = 1
300 call hecmw_allreduce_i1(hecmesh, is_in_contact, hecmw_max)
313 type(hecmwst_local_mesh) :: hecmesh
314 integer (kind=kint) :: is_unsymmetric
320 if( fstrsolid%n_contacts>0 )
then
321 if( any( fstrsolid%contacts(:)%fcoeff /= 0.0d0 .and. .not.fstrsolid%contacts(:)%symmetric ) ) is_unsymmetric = 1
323 call hecmw_allreduce_i1(hecmesh, is_unsymmetric, hecmw_max)
332 type(hecmwst_local_mesh) :: hecmesh
333 integer (kind=kint) :: is_unsymmetric, i, ytype
339 if(
associated(fstrsolid%materials) )
then
340 do i = 1,
size(fstrsolid%materials)
341 ytype = getyieldfunction( fstrsolid%materials(i)%mtype )
342 if( ytype == 1 )
then
343 if( fstrsolid%materials(i)%variables(m_plconst3) /= fstrsolid%materials(i)%variables(m_plconst4) ) &
345 elseif( ytype == 2 )
then
346 if( fstrsolid%materials(i)%variables(m_plconst3) /= fstrsolid%materials(i)%variables(m_plconst5) ) &
351 call hecmw_allreduce_i1(hecmesh, is_unsymmetric, hecmw_max)
358 type(hecmwst_matrix_lagrange),
intent(inout) :: heclagmat
359 integer(kind=kint),
intent(in) :: ilag
360 real(kind=kreal),
intent(in) ::
value
362 if (ilag < 1 .or. ilag > heclagmat%num_lagrange)
then
363 write(*,*)
'Error in fstr_set_lagrange_diagonal: invalid Lagrange multiplier index', ilag
367 if (.not.
associated(heclagmat%D_lagrange))
then
368 write(*,*)
'Error in fstr_set_lagrange_diagonal: D_lagrange not allocated'
372 heclagmat%D_lagrange(ilag) =
value
378 type(hecmwst_matrix_lagrange),
intent(in) :: heclagmat
379 integer(kind=kint),
intent(in) :: ilag
381 if (ilag < 1 .or. ilag > heclagmat%num_lagrange)
then
382 write(*,*)
'Error in fstr_get_lagrange_diagonal: invalid Lagrange multiplier index', ilag
387 if (.not.
associated(heclagmat%D_lagrange))
then
388 write(*,*)
'Error in fstr_get_lagrange_diagonal: D_lagrange not allocated'
398 subroutine getnewlistofrelatednodesandlagrangemultipliers_ss( &
399 & cstep, contact_algo, np, fstrSOLID, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
400 integer(kind=kint),
intent(in) :: cstep
401 integer(kind=kint),
intent(in) :: contact_algo
402 integer(kind=kint),
intent(in) :: np
404 integer(kind=kint),
intent(inout) :: countnon0lu_node, countnon0lu_lagrange
405 type(noderelated),
pointer,
intent(inout) :: list_noderelated(:)
406 integer(kind=kint) :: grpid
407 integer(kind=kint) :: ctsurf, nsurf
408 integer(kind=kint) :: i, j, m
409 integer(kind=kint) :: g, unique_count
410 integer(kind=kint) :: maplist(max_n_intp), master_idxs(max_n_intp)
411 real(kind=kreal) :: fcoeff
412 logical :: necessary_to_insert_node
414 do i = 1, fstrsolid%n_contacts
415 if( fstrsolid%contacts(i)%method /= contacts2s ) cycle
416 grpid = fstrsolid%contacts(i)%group
419 fcoeff = fstrsolid%contacts(i)%fcoeff
420 necessary_to_insert_node = ( fcoeff /= 0.0d0 .or. contact_algo ==
kcaalagrange )
422 do j = 1,
size(fstrsolid%contacts(i)%slave_surf)
423 if( fstrsolid%contacts(i)%slave_surf(j)%state == contactfree ) cycle
429 call get_unique_map( fstrsolid%contacts(i)%slave_surf(j), maplist, master_idxs, unique_count )
430 do g = 1, unique_count
431 ctsurf = master_idxs(g)
433 call register_pair_to_sparsity( np, fstrsolid%contacts(i)%slave_surf(j)%nodes, &
434 fstrsolid%contacts(i)%master(ctsurf), necessary_to_insert_node, &
435 countnon0lu_node, countnon0lu_lagrange, list_noderelated )
438 if( fstrsolid%contacts(i)%sparsity_expansion == sparsity_neighbor )
then
439 do m = 1, fstrsolid%contacts(i)%master(ctsurf)%n_neighbor
440 nsurf = fstrsolid%contacts(i)%master(ctsurf)%neighbor(m)
441 call register_pair_to_sparsity( np, fstrsolid%contacts(i)%slave_surf(j)%nodes, &
442 fstrsolid%contacts(i)%master(nsurf), necessary_to_insert_node, &
443 countnon0lu_node, countnon0lu_lagrange, list_noderelated )
451 end subroutine getnewlistofrelatednodesandlagrangemultipliers_ss
456 subroutine register_pair_to_sparsity( np, slave_nodes, master_surf, &
457 & necessary_to_insert_node, countNon0LU_node, countNon0LU_lagrange, list_nodeRelated )
458 integer(kind=kint),
intent(in) :: np
459 integer(kind=kint),
intent(in) :: slave_nodes(:)
460 type(tsurfelement),
intent(in) :: master_surf
461 logical,
intent(in) :: necessary_to_insert_node
462 integer(kind=kint),
intent(inout) :: countnon0lu_node, countnon0lu_lagrange
463 type(noderelated),
pointer,
intent(inout) :: list_noderelated(:)
465 integer(kind=kint) :: nnode_s, nnode_m, l, m, idx, nnode_pair, etype
466 integer(kind=kint) :: ndlocal(2*l_max_surface_node + 1)
468 etype = master_surf%etype
469 if( etype/=
fe_tri3n .and. etype/=
fe_quad4n ) stop
" ##Error: This element type is not supported in contact analysis !!! "
470 nnode_s =
size(slave_nodes)
471 nnode_m =
size(master_surf%nodes)
473 ndlocal(1) = slave_nodes(l)
479 ndlocal(idx) = slave_nodes(m)
481 ndlocal(idx+1:idx+nnode_m) = master_surf%nodes(:)
482 nnode_pair = nnode_s - 1 + nnode_m
484 call hecmw_ass_noderelated_from_contact_pair( np, nnode_pair, ndlocal, 0, permission, &
485 & necessary_to_insert_node, list_noderelated_org, list_noderelated, countnon0lu_node, countnon0lu_lagrange )
487 end subroutine register_pair_to_sparsity
513 integer(kind=kint),
intent(in) :: cstep
514 integer(kind=kint),
intent(in) :: contact_algo
516 type(hecmwst_matrix),
intent(in) :: conmat
518 integer(kind=kint) :: i, j, g, ctsurf, grpid, unique_count
519 integer(kind=kint) :: maplist(max_n_intp), master_idxs(max_n_intp)
524 do i = 1, fstrsolid%n_contacts
525 if( fstrsolid%contacts(i)%method /= contacts2s ) cycle
526 grpid = fstrsolid%contacts(i)%group
529 do j = 1,
size(fstrsolid%contacts(i)%slave_surf)
530 if( fstrsolid%contacts(i)%slave_surf(j)%state == contactfree ) cycle
532 call get_unique_map( fstrsolid%contacts(i)%slave_surf(j), maplist, master_idxs, unique_count )
533 do g = 1, unique_count
534 ctsurf = master_idxs(g)
535 if( .not. pair_cross_profile_complete( fstrsolid%contacts(i)%slave_surf(j)%nodes, &
536 & fstrsolid%contacts(i)%master(ctsurf), conmat ) )
then
548 logical function pair_cross_profile_complete( slave_nodes, master_surf, conMAT )
549 integer(kind=kint),
intent(in) :: slave_nodes(:)
550 type(tsurfelement),
intent(in) :: master_surf
551 type(hecmwst_matrix),
intent(in) :: conmat
553 integer(kind=kint) :: s, m
555 pair_cross_profile_complete = .true.
556 do s = 1,
size(slave_nodes)
557 do m = 1,
size(master_surf%nodes)
559 pair_cross_profile_complete = .false.
564 end function pair_cross_profile_complete
This module encapsulate the basic functions of all elements provide by this software.
integer, parameter fe_tri3n
integer, parameter fe_quad4n
logical function, public hecmw_mat_profile_has_node(hecMAT, inod, jnod)
Read-only companion to hecmw_mat_add_node: report whether the (inod, jnod) block exists in the matrix...
This module defines common data and basic structures for analysis.
logical function fstr_isembedactive(fstrSOLID, nbc, cstep)
logical function fstr_iscontactactive(fstrSOLID, nbc, cstep)
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
integer(kind=kint), parameter kcaalagrange