FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
hecmw_es_mesh_connectivity.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 
8  use hecmw_util
10  use hecmw_etype
11  implicit none
12 
13  private
15 
16 contains
17 
18 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
19 ! common functions
20 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21 
22  subroutine concat_int_list(inlist, n_in, outlist)
23  integer, allocatable, intent(in) :: inlist(:)
24  integer, intent(in) :: n_in
25  integer, pointer, intent(inout) :: outlist(:)
26 
27  integer :: i, n_ori, n_new, lbd
28  integer, allocatable :: tmp(:)
29 
30  n_ori = size(outlist)
31  lbd = lbound(outlist,1)
32  allocate(tmp(n_ori))
33 
34  do i=1,n_ori
35  tmp(i) = outlist(lbd+i-1)
36  end do
37 
38  n_new = n_ori + n_in
39 
40  deallocate(outlist)
41  allocate(outlist(lbd:lbd+n_new-1))
42  do i=1,n_ori
43  outlist(lbd+i-1) = tmp(i)
44  end do
45  do i=1,n_in
46  outlist(lbd+i-1+n_ori) = inlist(i)
47  end do
48 
49  deallocate(tmp)
50  end subroutine
51 
52  subroutine add_newelements_to_hecmesh( etype, elems, sectionID, hecMESH )
53  integer, intent(in) :: etype
54  type( hecmwST_varray_int ), allocatable, intent(in) :: elems(:)
55  integer, allocatable, intent(in) :: sectionID(:)
56  type(hecmwST_local_mesh), intent(inout) :: hecMESH
57 
58  integer(kind=kint) :: i
59  integer(kind=kint) :: n_newelem, n_newelemnodes, nitem
60  integer(kind=kint), allocatable :: iwork(:)
61 
62  n_newelem = size(elems)
63  n_newelemnodes = 0
64  do i=1,n_newelem
65  n_newelemnodes = n_newelemnodes + hecmw_varray_int_get_nitem(elems(i))
66  end do
67  allocate(iwork(0:n_newelemnodes))
68 
69  ! elem_type_index(:)
70  iwork(1) = hecmesh%elem_type_index(hecmesh%n_elem_type)+n_newelem
71  call concat_int_list(iwork, 1, hecmesh%elem_type_index)
72 
73  ! elem_type_item(:)
74  iwork(1) = etype
75  call concat_int_list(iwork, 1, hecmesh%elem_type_item)
76 
77  ! elem_type(:)
78  iwork(1:n_newelem) = etype
79  call concat_int_list(iwork, n_newelem, hecmesh%elem_type)
80 
81  ! section_ID(:)
82  call concat_int_list(sectionid, n_newelem, hecmesh%section_ID)
83 
84  ! elem_mat_ID_index(:)
85  iwork(0) = hecmesh%elem_mat_ID_index(ubound(hecmesh%elem_mat_ID_index,1))
86  do i=1,n_newelem
87  iwork(i) = iwork(i-1) + 1
88  end do
89  call concat_int_list(iwork, n_newelem, hecmesh%elem_mat_ID_index)
90 
91  ! elem_mat_ID_item(:)
92 
93  ! elem_node_index(:)
94  iwork(0) = hecmesh%elem_node_index(ubound(hecmesh%elem_node_index,1))
95  do i=1,n_newelem
96  iwork(i) = iwork(i-1) + hecmw_varray_int_get_nitem(elems(i))
97  end do
98  call concat_int_list(iwork, n_newelem, hecmesh%elem_node_index)
99 
100  ! elem_node_item(:)
101  n_newelemnodes = 0
102  do i=1,n_newelem
103  nitem = hecmw_varray_int_get_nitem(elems(i))
104  call hecmw_varray_int_get_item_all( elems(i), iwork(n_newelemnodes+1:n_newelemnodes+nitem) )
105  n_newelemnodes = n_newelemnodes + nitem
106  end do
107  call concat_int_list(iwork, n_newelemnodes, hecmesh%elem_node_item)
108 
109  ! elem_ID(:)
110  do i=1,n_newelem
111  iwork(2*i-1) = hecmesh%n_elem + 1
112  iwork(2*i ) = 0
113  end do
114  call concat_int_list(iwork, 2*n_newelem, hecmesh%elem_ID)
115 
116  ! global_elem_ID(:)
117  do i=1,n_newelem
118  iwork(i) = 0
119  end do
120  call concat_int_list(iwork, n_newelem, hecmesh%global_elem_ID)
121 
122  ! elem_internal_list(:)
123  ! elem_mat_int_index(:)
124  ! elem_mat_int_val(:)
125  ! elem_val_index(:)
126  ! elem_val_item(:)
127 
128  ! n_elem
129  !hecMESH%n_elem = hecMESH%n_elem + n_newelem
130 
131  ! n_elem_gross
132  ! ne_internal
133  !hecMESH%ne_internal = hecMESH%ne_internal + n_newelem
134 
135  ! n_elem_type
136  hecmesh%n_elem_type = hecmesh%n_elem_type + 1
137 
138  ! n_elem_mat_ID
139 
140  end subroutine
141 
142  subroutine reorder_tet1( nid, nodlocal )
143  integer, intent(in) :: nid
144  integer, intent(inout) :: nodlocal(4)
145 
146  integer :: i, idx
147  integer :: nodlocal_ori(4)
148 
149  nodlocal_ori(1:4) = nodlocal(1:4)
150  idx = 0
151  do i=1,4
152  if( nodlocal(i) == nid ) then
153  idx = i
154  exit
155  end if
156  end do
157 
158  if( idx == 1 ) then
159  return
160  else if( idx == 2 ) then
161  nodlocal(1) = nodlocal_ori(2)
162  nodlocal(2) = nodlocal_ori(3)
163  nodlocal(3) = nodlocal_ori(1)
164  else if( idx == 3 ) then
165  nodlocal(1) = nodlocal_ori(3)
166  nodlocal(2) = nodlocal_ori(1)
167  nodlocal(3) = nodlocal_ori(2)
168  else if( idx == 4 ) then
169  nodlocal(1) = nodlocal_ori(4)
170  nodlocal(2) = nodlocal_ori(2)
171  nodlocal(3) = nodlocal_ori(1)
172  nodlocal(4) = nodlocal_ori(3)
173  end if
174 
175  end subroutine
176 
177  subroutine reorder_tet1_edge( nid1, nid2, nodlocal )
178  integer, intent(in) :: nid1
179  integer, intent(in) :: nid2
180  integer, intent(inout) :: nodlocal(4)
181 
182  integer :: i, idx
183  integer :: nodlocal_ori(4)
184 
185  call reorder_tet1( nid1, nodlocal )
186 
187  nodlocal_ori(1:4) = nodlocal(1:4)
188  idx = 1
189  do i=2,4
190  if( nodlocal(i) == nid2 ) then
191  idx = i
192  exit
193  end if
194  end do
195 
196  if( idx == 2 ) then
197  return
198  else if( idx == 3 ) then
199  nodlocal(2) = nodlocal_ori(3)
200  nodlocal(3) = nodlocal_ori(4)
201  nodlocal(4) = nodlocal_ori(2)
202  else if( idx == 4 ) then
203  nodlocal(2) = nodlocal_ori(4)
204  nodlocal(3) = nodlocal_ori(2)
205  nodlocal(4) = nodlocal_ori(3)
206  else
207  stop "error in reorder_tet1_edge"
208  end if
209 
210  end subroutine
211 
212 
213 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
214 ! create node-smoothed elements
215 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
216 
217  subroutine initialize_node_elem_list( hecMESH, n_elem_ori, is_selem_list, node_elem_list )
218  type(hecmwST_local_mesh),target :: hecMESH
219  integer(kind=kint), intent(in) :: n_elem_ori
220  logical, allocatable, intent(in) :: is_selem_list(:)
221  type( hecmwST_varray_int ), allocatable, intent(inout) :: node_elem_list(:)
222 
223  integer(kind=kint) :: i, icel, iS, iE, nid
224 
225  call hecmw_varray_int_initialize_all( node_elem_list, hecmesh%n_node, 8 )
226 
227  do icel=1,n_elem_ori
228  if( .not. is_selem_list(icel) ) cycle
229 
230  is = hecmesh%elem_node_index(icel-1)+1
231  ie = hecmesh%elem_node_index(icel)
232 
233  do i=is,ie
234  nid = hecmesh%elem_node_item(i)
235  call hecmw_varray_int_add( node_elem_list(nid), icel )
236  end do
237  end do
238 
239  end subroutine
240 
241  subroutine create_node_smoothed_elements( hecMESH, node_elem_list, nselems, sectionID )
242  type(hecmwST_local_mesh), intent(in) :: hecMESH
243  type( hecmwST_varray_int ), allocatable, intent(in) :: node_elem_list(:)
244  type( hecmwST_varray_int ), allocatable, intent(inout) :: nselems(:)
245  integer, allocatable, intent(inout) :: sectionID(:)
246 
247  integer(kind=kint) :: n_nselems
248  type( hecmwST_varray_int ), allocatable :: n_sections(:)
249  integer(kind=kint) :: i, j, k, icel, isect, iS, iE
250  integer(kind=kint) :: nodlocal(4)
251 
252  !get num of node-smoothed elements
253  call hecmw_varray_int_initialize_all( n_sections, hecmesh%n_node, 2 )
254 
255  n_nselems = 0
256  do i=1,hecmesh%n_node
257  do j=1,hecmw_varray_int_get_nitem(node_elem_list(i))
258  icel = hecmw_varray_int_get_item( node_elem_list(i), j )
259  isect = hecmesh%section_ID(icel)
260  call hecmw_varray_int_add_if_not_exits( n_sections(i), isect )
261  enddo
262  n_nselems = n_nselems + hecmw_varray_int_get_nitem(n_sections(i))
263  end do
264 
265  allocate(sectionid(n_nselems))
266 
267  !create node-smoothed elements
268  !elements which belongs to different sections must not be connected
269  call hecmw_varray_int_initialize_all( nselems, n_nselems, 16 )
270 
271  n_nselems = 0
272  do i=1,hecmesh%n_node
273  do j=1,hecmw_varray_int_get_nitem( n_sections(i) )
274  isect = hecmw_varray_int_get_item( n_sections(i), j )
275  n_nselems = n_nselems + 1
276  sectionid(n_nselems) = isect
277  do k=1,hecmw_varray_int_get_nitem(node_elem_list(i))
278  icel = hecmw_varray_int_get_item( node_elem_list(i), k )
279  if ( hecmesh%section_ID(icel) == isect ) then
280  is = hecmesh%elem_node_index(icel-1)+1
281  ie = hecmesh%elem_node_index(icel)
282  if( ie-is+1 /= 4 ) stop "error in add_elemments_smoothed_by_node(1)"
283  nodlocal(1:4) = hecmesh%elem_node_item(is:ie)
284  call reorder_tet1( i, nodlocal )
285  if( hecmw_varray_int_get_nitem(nselems(n_nselems)) == 0 ) call hecmw_varray_int_add( nselems(n_nselems), nodlocal(1) )
286  call hecmw_varray_int_expand( nselems(n_nselems), 3, nodlocal(2:4) )
287  end if
288  end do
289  enddo
290  end do
291 
292  !finalize n_sections
293  call hecmw_varray_int_finalize_all( n_sections )
294 
295  end subroutine
296 
297  subroutine add_elemments_smoothed_by_node( hecMESH, n_elem_ori, is_selem_list )
298  type(hecmwST_local_mesh),target :: hecMESH
299  integer(kind=kint), intent(in) :: n_elem_ori
300  logical, allocatable, intent(in) :: is_selem_list(:)
301 
302  type( hecmwST_varray_int ), allocatable :: node_elem_list(:)
303  type( hecmwST_varray_int ), allocatable :: nselems(:)
304  integer, allocatable :: sectionID(:)
305 
306 
307  !initialize node_elem_list
308  call initialize_node_elem_list( hecmesh, n_elem_ori, is_selem_list, node_elem_list )
309 
310  !create node-smoothed elements and store them in list data
311  call create_node_smoothed_elements( hecmesh, node_elem_list, nselems, sectionid )
312 
313  !finalize node_elem_list
314  call hecmw_varray_int_finalize_all( node_elem_list )
315 
316  !add node-smoothed elements to hecMESH
317  call add_newelements_to_hecmesh( 881, nselems, sectionid, hecmesh )
318 
319  !finalize nselems
320  call hecmw_varray_int_finalize_all( nselems )
321 
322  end subroutine
323 
324 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
325 ! create edge-smoothed elements
326 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
327 
328  subroutine initialize_edge_elem_list( hecMESH, n_elem_ori, is_selem_list, edges, edge_elem_list )
329  type(hecmwST_local_mesh),target :: hecMESH
330  integer(kind=kint), intent(in) :: n_elem_ori
331  logical, allocatable, intent(in) :: is_selem_list(:)
332  integer, allocatable, intent(inout) :: edges(:)
333  type( hecmwST_varray_int ), allocatable, intent(inout) :: edge_elem_list(:)
334 
335  type( hecmwST_varray_int ), allocatable :: edge_con(:)
336  type( hecmwST_varray_int ), allocatable :: edge_id(:)
337  integer(kind=kint) :: ndlocal(4)
338  integer(kind=kint), parameter :: leid(2,6) = reshape((/1,2,2,3,3,1,1,4,2,4,3,4/),shape(leid))
339 
340  integer(kind=kint) :: i, j, icel, iS, iE, nid1, nid2
341  integer(kind=kint) :: n_edges, edid
342 
343  !create edge connectivity list in node num order
344  !edge_con(i)%items : list of nodes connecting to i by edge
345  call hecmw_varray_int_initialize_all( edge_con, hecmesh%n_node, 8 )
346 
347  do icel=1,n_elem_ori
348  if( .not. is_selem_list(icel) ) cycle
349 
350  is = hecmesh%elem_node_index(icel-1)+1
351  ie = hecmesh%elem_node_index(icel)
352 
353  ndlocal(1:4) = hecmesh%elem_node_item(is:ie)
354  do i=1,6
355  nid1 = ndlocal(leid(1,i))
356  nid2 = ndlocal(leid(2,i))
357  if( nid1 < nid2 ) then
358  call hecmw_varray_int_add_if_not_exits( edge_con(nid1), nid2 )
359  else
360  call hecmw_varray_int_add_if_not_exits( edge_con(nid2), nid1 )
361  end if
362  end do
363  end do
364 
365  !create edges and edge_id
366  n_edges = 0
367  do i=1,hecmesh%n_node
368  n_edges = n_edges + hecmw_varray_int_get_nitem(edge_con(i))
369  end do
370 
371  allocate(edges(2*n_edges))
372  call hecmw_varray_int_initialize_all( edge_id, hecmesh%n_node, 8 )
373  n_edges = 0
374  do i=1,hecmesh%n_node
375  do j=1,hecmw_varray_int_get_nitem(edge_con(i))
376  n_edges = n_edges + 1
377  edges(2*n_edges-1) = i
378  edges(2*n_edges ) = hecmw_varray_int_get_item( edge_con(i), j )
379  call hecmw_varray_int_add( edge_id(i), n_edges )
380  end do
381  end do
382 
383  !create edge-elem list
384  call hecmw_varray_int_initialize_all( edge_elem_list, n_edges, 8 )
385 
386  do icel=1,n_elem_ori
387  if( .not. is_selem_list(icel) ) cycle
388 
389  is = hecmesh%elem_node_index(icel-1)+1
390  ie = hecmesh%elem_node_index(icel)
391 
392  ndlocal(1:4) = hecmesh%elem_node_item(is:ie)
393  do i=1,6
394  nid1 = ndlocal(leid(1,i))
395  nid2 = ndlocal(leid(2,i))
396  if( nid1 < nid2 ) then
397  edid = hecmw_varray_int_get_item( edge_id(nid1), hecmw_varray_int_find( edge_con(nid1), nid2 ) )
398  else
399  edid = hecmw_varray_int_get_item( edge_id(nid2), hecmw_varray_int_find( edge_con(nid2), nid1 ) )
400  end if
401  call hecmw_varray_int_add( edge_elem_list(edid), icel )
402  end do
403  end do
404 
405  call hecmw_varray_int_finalize_all( edge_con )
406  call hecmw_varray_int_finalize_all( edge_id )
407 
408  end subroutine
409 
410  subroutine create_edge_smoothed_elements( hecMESH, edges, edge_elem_list, eselems, sectionID )
411  type(hecmwST_local_mesh), intent(in) :: hecMESH
412  integer(kind=kint), allocatable, intent(in) :: edges(:)
413  type( hecmwST_varray_int ), allocatable, intent(in) :: edge_elem_list(:)
414  type( hecmwST_varray_int ), allocatable, intent(inout) :: eselems(:)
415  integer, allocatable, intent(inout) :: sectionID(:)
416 
417  integer(kind=kint) :: n_edges, n_eselems
418  type( hecmwST_varray_int ), allocatable :: n_sections(:)
419  integer(kind=kint) :: i, j, k, icel, isect, iS, iE
420  integer(kind=kint) :: nodlocal(4)
421 
422  n_edges = size(edge_elem_list)
423 
424  !get num of edge-smoothed elements
425  call hecmw_varray_int_initialize_all( n_sections, n_edges, 2 )
426 
427  n_eselems = 0
428  do i=1,n_edges
429  do j=1,hecmw_varray_int_get_nitem(edge_elem_list(i))
430  icel = hecmw_varray_int_get_item( edge_elem_list(i), j )
431  isect = hecmesh%section_ID(icel)
432  call hecmw_varray_int_add_if_not_exits( n_sections(i), isect )
433  enddo
434  n_eselems = n_eselems + hecmw_varray_int_get_nitem(n_sections(i))
435  end do
436 
437  allocate(sectionid(n_eselems))
438 
439  !create edge-smoothed elements
440  !elements which belongs to different sections must not be connected
441  call hecmw_varray_int_initialize_all( eselems, n_eselems, 16 )
442 
443  n_eselems = 0
444  do i=1,n_edges
445  do j=1,hecmw_varray_int_get_nitem(n_sections(i))
446  isect = hecmw_varray_int_get_item( n_sections(i), j )
447  n_eselems = n_eselems + 1
448  sectionid(n_eselems) = isect
449  do k=1,hecmw_varray_int_get_nitem(edge_elem_list(i))
450  icel = hecmw_varray_int_get_item( edge_elem_list(i), k )
451  if ( hecmesh%section_ID(icel) == isect ) then
452  is = hecmesh%elem_node_index(icel-1)+1
453  ie = hecmesh%elem_node_index(icel)
454  if( ie-is+1 /= 4 ) stop "error in add_elemments_smoothed_by_node(1)"
455  nodlocal(1:4) = hecmesh%elem_node_item(is:ie)
456  call reorder_tet1_edge( edges(2*i-1), edges(2*i), nodlocal )
457  if( hecmw_varray_int_get_nitem(eselems(n_eselems)) == 0 ) &
458  & call hecmw_varray_int_expand( eselems(n_eselems), 2, nodlocal(1:2) )
459  call hecmw_varray_int_expand( eselems(n_eselems), 2, nodlocal(3:4) )
460  end if
461  end do
462  enddo
463  end do
464 
465  !finalize n_sections
466  call hecmw_varray_int_finalize_all( n_sections )
467 
468  end subroutine
469 
470  subroutine add_elemments_smoothed_by_edge( hecMESH, n_elem_ori, is_selem_list )
471  type(hecmwST_local_mesh),target :: hecMESH
472  integer(kind=kint), intent(in) :: n_elem_ori
473  logical, allocatable, intent(in) :: is_selem_list(:)
474 
475  integer, allocatable :: edges(:)
476  type( hecmwST_varray_int ), allocatable :: edge_elem_list(:)
477  type( hecmwST_varray_int ), allocatable :: eselems(:)
478  integer, allocatable :: sectionID(:)
479 
480 
481  !initialize edge_elem_list
482  call initialize_edge_elem_list( hecmesh, n_elem_ori, is_selem_list, edges, edge_elem_list )
483 
484  !create edge-smoothed elements and store them in list data
485  call create_edge_smoothed_elements( hecmesh, edges, edge_elem_list, eselems, sectionid )
486 
487  !finalize edges and edge_elem_list
488  deallocate(edges)
489  call hecmw_varray_int_finalize_all( edge_elem_list )
490 
491  !add edge-smoothed elements to hecMESH
492  call add_newelements_to_hecmesh( 891, eselems, sectionid, hecmesh )
493 
494  !finalize eselems
495  call hecmw_varray_int_finalize_all( eselems )
496 
497  end subroutine
498 
500  subroutine hecmw_create_smoothing_element_connectivity( hecMESH, is_selem_list )
501  type(hecmwst_local_mesh),target :: hecmesh
502  logical, allocatable, intent(in) :: is_selem_list(:)
503 
504  integer(kind=kint) :: n_elem_ori
505 
506  n_elem_ori = hecmesh%n_elem
507 
508  call add_elemments_smoothed_by_node( hecmesh, n_elem_ori, is_selem_list )
509 
510  call add_elemments_smoothed_by_edge( hecmesh, n_elem_ori, is_selem_list )
511 
512  end subroutine
513 
514 end module
hecmw_es_mesh_connectivity
This module contains control file data obtaining functions for dynamic analysis.
Definition: hecmw_es_mesh_connectivity.f90:7
hecmw_varray_int::hecmw_varray_int_get_item_all
subroutine, public hecmw_varray_int_get_item_all(ilist, array)
Definition: hecmw_varray_int_f.f90:222
hecmw_varray_int
Definition: hecmw_varray_int.h:9
hecmw_varray_int::hecmw_varray_int_initialize_all
subroutine, public hecmw_varray_int_initialize_all(ilists, nlists, n_init_in)
Definition: hecmw_varray_int_f.f90:52
hecmw_varray_int::hecmw_varray_int_get_item
integer(kind=kint) function, public hecmw_varray_int_get_item(ilist, n)
Definition: hecmw_varray_int_f.f90:215
hecmw_es_mesh_connectivity::hecmw_create_smoothing_element_connectivity
subroutine, public hecmw_create_smoothing_element_connectivity(hecMESH, is_selem_list)
setup selective es/ns smoothing FEM connectivity
Definition: hecmw_es_mesh_connectivity.f90:501
hecmw_varray_int::hecmw_varray_int_finalize_all
subroutine, public hecmw_varray_int_finalize_all(ilists)
Definition: hecmw_varray_int_f.f90:72
hecmw_varray_int::hecmw_varray_int_add_if_not_exits
subroutine, public hecmw_varray_int_add_if_not_exits(ilist, ival)
Definition: hecmw_varray_int_f.f90:123
hecmw_varray_int::hecmw_varray_int_find
integer(kind=kint) function, public hecmw_varray_int_find(ilist, ival)
Definition: hecmw_varray_int_f.f90:197
hecmw_util
I/O and Utility.
Definition: hecmw_util_f.F90:7
hecmw_util::hecmwst_local_mesh
Definition: hecmw_util_f.F90:234
hecmw_varray_int::hecmw_varray_int_add
subroutine, public hecmw_varray_int_add(ilist, ival)
Definition: hecmw_varray_int_f.f90:112
hecmw_varray_int::hecmw_varray_int_expand
subroutine, public hecmw_varray_int_expand(ilist, n, vals)
Definition: hecmw_varray_int_f.f90:166
hecmw_varray_int::hecmw_varray_int_get_nitem
integer(kind=kint) function, public hecmw_varray_int_get_nitem(ilist)
Definition: hecmw_varray_int_f.f90:209
hecmw_etype
I/O and Utility.
Definition: hecmw_etype_f.f90:7