FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_setup_util.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 m_fstr
9  use hecmw
11 
12 contains
13  !------------------------------------------------------------------------------
14 
15  subroutine fstr_ctrl_err_stop
16  implicit none
17  character(len=256) :: msg
18 
19  call fstr_ctrl_get_err_msg( msg, 256 )
20  write(*,*) msg
21  write(imsg,*) msg
22  call fstr_abort( hecmw_exit_input )
23  end subroutine fstr_ctrl_err_stop
24 
25  !------------------------------------------------------------------------------
26 
27  subroutine fstr_setup_util_err_stop( msg )
28  implicit none
29  character(*) :: msg
30 
31  write(*,*) msg
32  write(imsg,*) msg
33  call fstr_abort( hecmw_exit_input )
34  end subroutine fstr_setup_util_err_stop
35 
36  subroutine append_node_grp_from_surf_grp( hecMESH, sgrp_id, ngrp_id )
39  implicit none
40  type(hecmwst_local_mesh), pointer :: hecMESH
41  integer(kind=kint), intent(in) :: sgrp_id
42  integer(kind=kint), intent(out) :: ngrp_id
43  integer(kind=kint) :: is, ie, nnode, i, ic, isurf, ic_type, stype, nn, j0, j, ndup, new_nnode
44  integer(kind=kint) :: snode(20)
45  integer(kind=kint), allocatable :: node(:)
46  character(len=HECMW_NAME_LEN) :: grp_name
47  is= hecmesh%surf_group%grp_index(sgrp_id-1) + 1
48  ie= hecmesh%surf_group%grp_index(sgrp_id )
49  ! count num of nodes on surface incl duplication
50  nnode = 0
51  do i=is,ie
52  ic = hecmesh%surf_group%grp_item(2*i-1)
53  isurf = hecmesh%surf_group%grp_item(2*i)
54  ic_type = hecmesh%elem_type(ic)
55  call getsubface( ic_type, isurf, stype, snode )
56  nnode = nnode + getnumberofnodes( stype )
57  enddo
58  ! extract nodes on surface incl duplication
59  allocate( node(nnode) )
60  nnode = 0
61  do i=is,ie
62  ic = hecmesh%surf_group%grp_item(2*i-1)
63  isurf = hecmesh%surf_group%grp_item(2*i)
64  ic_type = hecmesh%elem_type(ic)
65  call getsubface( ic_type, isurf, stype, snode )
66  nn = getnumberofnodes( stype )
67  j0 = hecmesh%elem_node_index(ic-1)
68  do j=1,nn
69  node(nnode+j) = hecmesh%elem_node_item(j0+snode(j))
70  enddo
71  nnode = nnode + nn
72  enddo
73  ! sort and uniq node list
74  call hecmw_qsort_int_array(node, 1, nnode)
75  call hecmw_uniq_int_array(node, 1, nnode, ndup)
76  new_nnode = nnode - ndup
77  ! append node group
78  write( grp_name, '(a,a)') 'FSTR_S2N_',trim(hecmesh%surf_group%grp_name(sgrp_id))
79  call append_new_group(hecmesh, 'node_grp', grp_name, new_nnode, node, ngrp_id)
80  deallocate(node)
81  end subroutine append_node_grp_from_surf_grp
82 
83  subroutine append_intersection_node_grp( hecMESH, ngrp_id1, ngrp_id2 )
86  implicit none
87  type(hecmwst_local_mesh), pointer :: hecMESH
88  integer(kind=kint), intent(in) :: ngrp_id1, ngrp_id2
89  integer(kind=kint) :: nnode1, nnode2, nnode, is, i, nisect, ngrp_id
90  integer(kind=kint), allocatable :: node(:), isect(:)
91  character(len=HECMW_NAME_LEN) :: grp_name
92  nnode1 = hecmesh%node_group%grp_index(ngrp_id1) - hecmesh%node_group%grp_index(ngrp_id1-1)
93  nnode2 = hecmesh%node_group%grp_index(ngrp_id2) - hecmesh%node_group%grp_index(ngrp_id2-1)
94  nnode = nnode1 + nnode2
95  allocate( node(nnode) )
96  is= hecmesh%node_group%grp_index(ngrp_id1-1)
97  do i=1,nnode1
98  node(i) = hecmesh%node_group%grp_item(is+i)
99  enddo
100  is= hecmesh%node_group%grp_index(ngrp_id2-1)
101  do i=1,nnode2
102  node(nnode1+i) = hecmesh%node_group%grp_item(is+i)
103  enddo
104  call hecmw_qsort_int_array(node, 1, nnode)
105  allocate( isect(nnode) )
106  nisect = 0
107  do i=1,nnode-1
108  if( node(i) == node(i+1) ) then
109  nisect = nisect + 1
110  isect(nisect) = node(i)
111  endif
112  enddo
113  write( grp_name, '(a,a,a,a)') &
114  'FSTR_ISCT_',trim(hecmesh%node_group%grp_name(ngrp_id1)),'_AND_',trim(hecmesh%node_group%grp_name(ngrp_id2))
115  call append_new_group(hecmesh, 'node_grp', grp_name, nisect, isect, ngrp_id)
116  deallocate(node)
117  deallocate(isect)
118  end subroutine append_intersection_node_grp
119 
120  !------------------------------------------------------------------------------
121  ! JP-3
122  ! JP-4
123  ! type_name : 'node', 'element'
124  ! name : group name
125  ! local_id : local id (set only when return value > 0)
126  ! return : -1 if name is not a number
127  ! 0 if name is a number and a node with ID=name is not in myrank
128  ! >0 if name is a number and a node with ID=name is in myrank
129 
130  function get_local_member_index( hecMESH, type_name, name, local_id )
132  implicit none
133  integer(kind=kint) :: get_local_member_index
134  type (hecmwst_local_mesh),target :: hecmesh
135  character(len=*) :: type_name
136  character(len=*) :: name
137  integer(kind=kint) :: local_id
138  integer(kind=kint) :: i, n, no, fg
139  integer(kind=kint),pointer :: global_item(:)
140 
141  if( .not. hecmw_str2index(name, no) ) then
143  return
144  end if
145 
146  if( type_name == 'node' ) then
147  fg = 1
148  n = hecmesh%n_node
149  global_item => hecmesh%global_node_ID
150  else if( type_name == 'element' ) then
151  fg = 2
152  n = hecmesh%n_elem
153  global_item => hecmesh%global_elem_ID
154  else
155  stop 'assert in get_local_member_index: unknown type_name'
156  end if
157 
158  do i = 1, n
159  if( no == global_item(i)) then
160  local_id = i
161  get_local_member_index = local_id
162  return
163  end if
164  end do
165  local_id = 0
167  return
168  end function get_local_member_index
169 
170  !-----------------------------------------------------------------------------!
171  !
172 
173  function get_sorted_local_member_index( hecMESH, hecPARAM, type_name, name, local_id )
176  implicit none
177  integer(kind=kint) :: get_sorted_local_member_index
178  type (hecmwst_local_mesh),target :: hecmesh
179  type(fstr_param), target :: hecparam
180  character(len=*) :: type_name
181  character(len=*) :: name
182  integer(kind=kint) :: local_id, idx
183  integer(kind=kint) :: n, no, fg
184 
185  if( .not. hecmw_str2index(name, no) ) then
187  return
188  end if
189 
190  if( type_name == 'node' ) then
191  fg = 1
192  n = hecmesh%nn_internal
193  ! item => hecMESH%global_node_ID
194  ! else if( type_name == 'element' ) then
195  ! fg = 2
196  ! n = hecMESH%n_elem
197  ! item => hecMESH%global_elem_ID
198  else
199  stop 'assert in get_sorted_local_member_index: unknown type_name'
200  end if
201 
202  call hecmw_bsearch_int_array(hecparam%global_local_ID(1,:), 1, n, no, idx)
203  if(idx > 0)then
204  get_sorted_local_member_index = hecparam%global_local_ID(2,idx)
206  return
207  endif
208 
210  return
211  end function get_sorted_local_member_index
212  !-----------------------------------------------------------------------------!
213 
214  !Find node/surf group from name or nodeid
215 
216  subroutine nodesurf_grp_name_to_id_ex(hecMESH, header_name, n, grp_id_name, grp_ID, grp_TYPE)
218  use m_fstr
219  implicit none
220  type (hecmwST_local_mesh),target :: hecMESH
221  character(len=*) :: header_name
222  integer(kind=kint) :: n
223  character(len=HECMW_NAME_LEN) :: grp_id_name(:)
224  integer(kind=kint) :: grp_ID(:)
225  integer(kind=kint) :: grp_TYPE(:)
226 
227  integer(kind=kint) :: i, id
228  integer(kind=kint) :: no, no_count, exist_n
229  integer(kind=kint),pointer :: no_list(:)
230  character(HECMW_NAME_LEN) :: name
231  character(len=256) :: msg
232 
233  allocate( no_list( n ))
234  no_count = 0
235  do i = 1, n
236  if( hecmw_str2index( grp_id_name(i), no )) then
237  no_count = no_count + 1
238  no_list(no_count) = no
239  grp_id(i) = hecmesh%node_group%n_grp + no_count
240  grp_type(i) = kfloadtype_node
241  else
242  !Find node group
243  grp_id(i) = -1
244  do id = 1, hecmesh%node_group%n_grp
245  if (hecmw_streqr(hecmesh%node_group%grp_name(id), grp_id_name(i))) then
246  grp_id(i) = id
247  grp_type(i) = kfloadtype_node
248  exit
249  end if
250  end do
251  !Find surf group
252  if (grp_id(i) == -1) then
253  do id = 1, hecmesh%surf_group%n_grp
254  if (hecmw_streqr(hecmesh%surf_group%grp_name(id), grp_id_name(i))) then
255  grp_id(i) = id
256  grp_type(i) = kfloadtype_surf
257  exit
258  end if
259  end do
260  end if
261 
262  !not found => exit
263  if( grp_id(i) == -1 ) then
264  write(msg,*) '### Error: ', header_name,' : Node group "',grp_id_name(i),'" does not exist.'
265  call fstr_setup_util_err_stop(msg)
266  end if
267  end if
268  end do
269  if( no_count > 0 ) then
270  name = 'node_grp'
271  exist_n = append_single_group( hecmesh, name, no_count, no_list )
272  end if
273 
274  deallocate( no_list )
275 
276  end subroutine nodesurf_grp_name_to_id_ex
277 
278  !------------------------------------------------------------------------------
279 
280  subroutine dload_grp_name_to_id_ex( hecMESH, n, grp_id_name, fg_surface, grp_ID )
282  implicit none
283  type (hecmwST_local_mesh),target :: hecMESH
284  integer(kind=kint) :: n
285  integer(kind=kint),save :: casha = 1, cashb = 1
286  character(HECMW_NAME_LEN) :: grp_id_name(:)
287  logical :: fg_surface(:)
288  integer(kind=kint) :: grp_ID(:)
289  integer(kind=kint) :: i, id
290  integer(kind=kint) :: no, no_count, exist_n
291  integer(kind=kint),pointer :: no_list(:)
292  character(HECMW_NAME_LEN) :: name
293  character(len=256) :: msg
294 
295  allocate( no_list( n ))
296  no_count = 0
297  do i = 1, n
298  if( fg_surface(i) ) then
299  grp_id(i) = -1
300  if(casha < hecmesh%surf_group%n_grp)then
301  if(hecmw_streqr(hecmesh%surf_group%grp_name(casha), grp_id_name(i))) then
302  grp_id(i) = casha
303  casha = casha + 1
304  cycle
305  end if
306  endif
307  do id = 1, hecmesh%surf_group%n_grp
308  if(hecmw_streqr(hecmesh%surf_group%grp_name(id), grp_id_name(i))) then
309  grp_id(i) = id
310  casha = id + 1
311  exit
312  end if
313  end do
314  if( grp_id(i) == -1 ) then
315  write(msg,*) '### Error: !DLOAD : Surface group "',&
316  grp_id_name(i),'" does not exist.'
317  call fstr_setup_util_err_stop(msg)
318  end if
319  else
320  if( hecmw_str2index( grp_id_name(i), no )) then
321  no_count = no_count + 1
322  no_list(no_count) = no
323  grp_id(i) = hecmesh%elem_group%n_grp + no_count
324  else
325  grp_id(i) = -1
326  if(cashb < hecmesh%surf_group%n_grp)then
327  if(hecmw_streqr(hecmesh%surf_group%grp_name(cashb), grp_id_name(i))) then
328  grp_id(i) = cashb
329  cashb = cashb + 1
330  cycle
331  end if
332  endif
333  do id = 1, hecmesh%elem_group%n_grp
334  if(hecmw_streqr(hecmesh%elem_group%grp_name(id), grp_id_name(i))) then
335  grp_id(i) = id
336  cashb = cashb + 1
337  exit
338  end if
339  end do
340  if( grp_id(i) == -1 ) then
341  write(msg,*) '### Error: !DLOAD : Element group "',&
342  grp_id_name(i),'" does not exist.'
343  call fstr_setup_util_err_stop(msg)
344  end if
345  end if
346  end if
347  end do
348 
349  if( no_count > 0 ) then
350  name = 'elem_grp'
351  exist_n = append_single_group( hecmesh, name, no_count, no_list )
352  ! if( exist_n < no_count ) then
353  ! write(*,*) '### Warning: !DLOAD : following elements are not exist'
354  ! if( hecMESH%my_rank == 0 ) then
355  ! write(imsg,*) '### Warning: !DLOAD : following elements are not exist'
356  ! end if
357  ! do i=1, no_count
358  ! if( no_list(i)<0 ) then
359  ! write(*,*) -no_list(i)
360  ! if( hecMESH%my_rank == 0 ) then
361  ! write(imsg,*) -no_list(i)
362  ! endif
363  ! end if
364  ! end do
365  ! end if
366  end if
367 
368  deallocate( no_list )
369  end subroutine dload_grp_name_to_id_ex
370 
371  !------------------------------------------------------------------------------
372  ! JP-7
373 
375  subroutine append_new_amplitude( amp, name, type_def, type_time, type_val, np, val, table )
376  use hecmw_setup_util, only &
381  , hecmw_streqr
382  type( hecmwst_amplitude ), intent(inout) :: amp
383  character(len=HECMW_NAME_LEN), intent(in) :: name
384  integer(kind=kint), intent(in) :: type_def
385  integer(kind=kint), intent(in) :: type_time
386  integer(kind=kint), intent(in) :: type_val
387  integer(kind=kint), intent(in) :: np
388  real(kind=kreal), intent(in) :: val(:)
389  real(kind=kreal), intent(in) :: table(:)
390 
391  ! type(fstr_str_arr) :: amp_name
392  integer(kind=kint) :: n_amp, new_size, old_size, i
393 
394  do i=1,amp%n_amp
395  if( hecmw_streqr(amp%amp_name(i), name) ) then
396  write(*,*) 'Error: AMPLITUDE with NAME=',trim(name),' already exists'
397  call fstr_ctrl_err_stop
398  endif
399  enddo
400 
401  n_amp = amp%n_amp
402  new_size = n_amp+1
403  amp%n_amp = new_size
404  call hecmw_expand_index_array( amp%amp_index, n_amp+1, new_size+1 )
405  ! amp_name%s => amp%amp_name
406  ! call hecmw_expand_name_array( amp_name, n_amp, new_size )
407  ! amp%amp_name => amp_name%s
408  call hecmw_expand_char_array( amp%amp_name, n_amp, new_size )
409  call hecmw_expand_integer_array( amp%amp_type_definition, n_amp, new_size )
410  call hecmw_expand_integer_array( amp%amp_type_time, n_amp, new_size )
411  call hecmw_expand_integer_array( amp%amp_type_value, n_amp, new_size )
412  old_size = amp%amp_index( n_amp )
413  new_size = old_size+np
414  call hecmw_expand_real_array( amp%amp_val, old_size, new_size )
415  call hecmw_expand_real_array( amp%amp_table, old_size, new_size )
416 
417  amp%amp_index(amp%n_amp) = amp%amp_index(amp%n_amp-1)+np
418  amp%amp_name(amp%n_amp) = name
419  amp%amp_type_definition(amp%n_amp) = type_def
420  amp%amp_type_time(amp%n_amp) = type_time
421  amp%amp_type_value(amp%n_amp) = type_val
422  do i=1,np
423  amp%amp_val(old_size+i) = val(i)
424  amp%amp_table(old_size+i) = table(i)
425  enddo
426  end subroutine append_new_amplitude
427 
428 
429  subroutine amp_name_to_id( hecMESH, header_name, aname, id )
430  implicit none
431  type (hecmwST_local_mesh) :: hecMESH
432  character(len=*) :: header_name
433  character(len=HECMW_NAME_LEN)::aname
434  integer(kind=kint) :: id
435  character(len=256) :: msg
436 
437  id = 0
438  if( aname .eq. ' ' ) return
439  call get_amp_id( hecmesh, aname, id )
440  if( id == 0 ) then
441  write(msg,*) '### Error: ', header_name,' : Amplitude group "',&
442  aname,'" does not exist.'
443  call fstr_setup_util_err_stop(msg)
444  end if
445  end subroutine amp_name_to_id
446 
447 
448  !GET AMPLITUDE INDEX
449 
450  subroutine get_amp_id( hecMESH, aname, id )
451  use hecmw_setup_util, only: hecmw_streqr
452  implicit none
453  type (hecmwST_local_mesh) :: hecMESH
454  character(len=HECMW_NAME_LEN)::aname
455  integer(kind=kint) :: id
456 
457  integer(kind=kint) :: i
458 
459  id = 0
460  if( aname .eq. ' ' ) return
461 
462  do i = 1, hecmesh%amp%n_amp
463  if( hecmw_streqr(hecmesh%amp%amp_name(i), aname)) then
464  id = i
465  return
466  end if
467  end do
468  end subroutine get_amp_id
469 
470  !------------------------------------------------------------------------------
471 
472  subroutine reallocate_integer( array, n )
473  implicit none
474  integer(kind=kint),pointer :: array(:)
475  integer(kind=kint) :: n;
476 
477  if( associated( array )) deallocate(array)
478  allocate( array(n));
479  end subroutine reallocate_integer
480 
481  subroutine reallocate_real( array, n )
482  implicit none
483  real(kind=kreal),pointer :: array(:)
484  integer(kind=kint) :: n;
485 
486  if( associated( array )) deallocate(array)
487  allocate( array(n));
488  end subroutine reallocate_real
489 
490  !-----------------------------------------------------------------------------!
491  ! FSTR_SETUP_VISUALIZE !
492  ! 1) Seeking header to 'WRITE' !
493  ! 2) If parameter 'VISUAL' exists, then 'hecmw_vis.ini' is opened. !
494  ! 3) All following lines under the header are written to the opened file !
495  !-----------------------------------------------------------------------------!
496 
497  subroutine fstr_setup_visualize( ctrl, hecMESH )
498  implicit none
499  integer(kind=kint) :: ctrl
500  type (hecmwST_local_mesh) :: hecMESH
501  integer(kind=kint) :: rcode
502  character(HECMW_FILENAME_LEN) :: vis_filename = 'hecmw_vis.ini'
503  logical :: is_exit
504 
505  rcode = fstr_ctrl_seek_header( ctrl, '!VISUAL ' )
506  if(rcode == 0) return
507 
508  if(hecmesh%my_rank == 0)then
509  call fstr_setup_visualize_main( ctrl, vis_filename )
510  endif
511 
512  call hecmw_barrier( hecmesh )
513 
514  inquire(file = vis_filename, exist = is_exit)
515 
516  if(.not. is_exit)then
517  call fstr_setup_visualize_main( ctrl, vis_filename )
518  endif
519  end subroutine fstr_setup_visualize
520 
521  subroutine fstr_setup_visualize_main( ctrl, vis_filename )
522  implicit none
523  integer(kind=kint) :: ctrl
524  integer(kind=kint) :: rcode
525  integer(kind=kint) :: i, start_n, end_n
526  character(HECMW_FILENAME_LEN) :: vis_filename
527  integer(kind=kint), parameter :: buffsize = 127
528  character( buffsize ) :: buff
529  character( buffsize ) :: head
530  character( buffsize ) :: msg
531 
532  start_n = fstr_ctrl_get_c_h_pos( ctrl )
533  end_n = fstr_ctrl_get_rec_number( ctrl )
534 
535  open ( ifvs, file = trim(vis_filename), status = 'replace', err = 1000)
536  do i=start_n, end_n
537  rcode = fstr_ctrl_get_line( ctrl, i, buff, buffsize )
538  if( rcode /= 0 ) exit
539  read( buff, *) head
540  if( head == '!END') exit
541  write( ifvs, '(a)') buff
542  end do
543  close( ifvs );
544 
545  return
546 
547  1000 write(msg,*) 'Error: cannot create file:"', trim(vis_filename), '" for visualization'
548  call fstr_setup_util_err_stop(msg)
549  end subroutine fstr_setup_visualize_main
550 
551  !******************************************************************************
552 
553 end module fstr_setup_util
void fstr_ctrl_get_err_msg(char *f_buff, int *len)
int fstr_ctrl_get_line(int *ctrl, int *rec_no, char *buff, int *buff_size)
int fstr_ctrl_seek_header(int *ctrl, const char *header_name)
This module contains auxiliary functions in calculation setup.
subroutine fstr_ctrl_err_stop
subroutine dload_grp_name_to_id_ex(hecMESH, n, grp_id_name, fg_surface, grp_ID)
subroutine fstr_setup_visualize(ctrl, hecMESH)
subroutine nodesurf_grp_name_to_id_ex(hecMESH, header_name, n, grp_id_name, grp_ID, grp_TYPE)
subroutine fstr_setup_visualize_main(ctrl, vis_filename)
integer(kind=kint) function get_local_member_index(hecMESH, type_name, name, local_id)
subroutine amp_name_to_id(hecMESH, header_name, aname, id)
subroutine append_new_amplitude(amp, name, type_def, type_time, type_val, np, val, table)
Append new amplitude table at the end of existing amplitude tables.
subroutine append_node_grp_from_surf_grp(hecMESH, sgrp_id, ngrp_id)
subroutine fstr_setup_util_err_stop(msg)
subroutine reallocate_real(array, n)
subroutine append_intersection_node_grp(hecMESH, ngrp_id1, ngrp_id2)
subroutine reallocate_integer(array, n)
integer(kind=kint) function get_sorted_local_member_index(hecMESH, hecPARAM, type_name, name, local_id)
subroutine get_amp_id(hecMESH, aname, id)
subroutine, public hecmw_bsearch_int_array(array, istart, iend, val, idx)
recursive subroutine, public hecmw_qsort_int_array(array, istart, iend)
subroutine, public hecmw_uniq_int_array(array, istart, iend, ndup)
This module contains auxiliary functions in calculation setup.
integer(kind=kint) function append_single_group(hecMESH, grp_type_name, no_count, no_list)
logical function hecmw_str2index(s, x)
subroutine hecmw_expand_integer_array(array, old_size, new_size)
subroutine hecmw_expand_real_array(array, old_size, new_size)
subroutine append_new_group(hecMESH, grp_type_name, name, count, list, grp_id)
subroutine hecmw_expand_char_array(array, old_size, new_size)
logical function hecmw_streqr(s1, s2)
subroutine hecmw_expand_index_array(array, old_size, new_size)
Definition: hecmw.f90:6
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:117
integer(kind=kint), parameter kfloadtype_surf
Definition: m_fstr.F90:90
integer(kind=kint), parameter ifvs
Definition: m_fstr.F90:119
subroutine fstr_abort(code)
Terminate the analysis with a classified exit status. MPI_ABORT does not perform the Fortran I/O fina...
Definition: m_fstr.F90:697
integer(kind=kint), parameter kfloadtype_node
Definition: m_fstr.F90:89
FSTR INNER CONTROL PARAMETERS (fstrPARAM)
Definition: m_fstr.F90:161