FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_mpc_prepost.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 !-------------------------------------------------------------------------------
5 
7  use hecmw_util
13  implicit none
14 
15  private
16  public :: hecmw_mpc_mat_init
18  public :: hecmw_mpc_mat_finalize
20  public :: hecmw_mpc_mat_ass
21  public :: hecmw_mpc_trans_rhs
22  public :: hecmw_mpc_tback_sol
23  public :: hecmw_mpc_trans_mass
24  public :: hecmw_mpc_tback_eigvec
25  public :: hecmw_mpc_mark_slave
26 
27  integer, parameter :: DEBUG = 0
28  logical, parameter :: DEBUG_VECTOR = .false.
29 
30 contains
31 
32  !C
33  !C***
34  !C*** hecmw_mpc_mat_init
35  !C***
36  !C
37  subroutine hecmw_mpc_mat_init(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc)
38  implicit none
39  type (hecmwst_local_mesh), intent(inout), target :: hecmesh
40  type (hecmwst_matrix), intent(inout), target :: hecmat
41  type (hecmwst_local_mesh), pointer :: hecmeshmpc
42  type (hecmwst_matrix), pointer :: hecmatmpc
43  type (hecmwst_matrix), intent(in), target, optional :: conmat
44  type (hecmwst_matrix), pointer, optional :: conmatmpc
45  integer(kind=kint) :: totalmpc, mpc_method, solver_type
46 
47  totalmpc = hecmesh%mpc%n_mpc
48  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
49 
50  if (totalmpc == 0) then
51  hecmeshmpc => hecmesh
52  hecmatmpc => hecmat
53  if (present(conmat).and.present(conmatmpc)) conmatmpc => conmat
54  return
55  endif
56 
57  call hecmw_mpc_scale(hecmesh)
58 
59  mpc_method = hecmw_mat_get_mpc_method(hecmat)
60  if (mpc_method == 2 .and. hecmesh%my_rank == 0) then
61  write(*,*) 'WARNING: MPCMETHOD=2 (MPCCG) has been removed; falling back to the default'
62  endif
63  if (mpc_method /= 1 .and. mpc_method /= 3) then
64  solver_type = hecmw_mat_get_solver_type(hecmat)
65  if (solver_type > 1) then ! DIRECT SOLVER
66  mpc_method = 1 ! default: penalty
67  else ! ITERATIVE SOLVER
68  mpc_method = 3 ! default: elimination
69  endif
70  call hecmw_mat_set_mpc_method(hecmat, mpc_method)
71  endif
72 
73  select case (mpc_method)
74  case (1) ! penalty
75  hecmeshmpc => hecmesh
76  hecmatmpc => hecmat
77  if (present(conmat).and.present(conmatmpc)) conmatmpc => conmat
78  case (3) ! elimination
79  allocate(hecmeshmpc)
80  call hecmw_mpc_mesh_copy(hecmesh, hecmeshmpc)
81  allocate(hecmatmpc)
82  call hecmw_mat_init(hecmatmpc)
83  if (present(conmat).and.present(conmatmpc)) then
84  allocate(conmatmpc)
85  call hecmw_mat_init(conmatmpc)
86  endif
87  end select
88 
89  end subroutine hecmw_mpc_mat_init
90 
91  !C
92  !C***
93  !C*** hecmw_mpc_mat_init_explicit
94  !C***
95  !C
96  subroutine hecmw_mpc_mat_init_explicit(hecMESH, hecMAT, hecMATmpc)
97  implicit none
98  type (hecmwst_local_mesh), intent(inout), target :: hecmesh
99  type (hecmwst_matrix), intent(inout), target :: hecmat
100  type (hecmwst_matrix), pointer :: hecmatmpc
101  integer(kind=kint) :: totalmpc, mpc_method
102 
103  totalmpc = hecmesh%mpc%n_mpc
104  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
105 
106  if (totalmpc == 0) then
107  hecmatmpc => hecmat
108  return
109  endif
110 
111  call hecmw_mpc_scale(hecmesh)
112 
113  ! Force MPC_METHOD=3
114  mpc_method = 3
115  call hecmw_mat_set_mpc_method(hecmat, mpc_method)
116 
117  allocate(hecmatmpc)
118  call hecmw_mat_init(hecmatmpc)
119 
120  hecmatmpc%N = hecmat%N
121  hecmatmpc%NP = hecmat%NP
122  hecmatmpc%NDOF = hecmat%NDOF
123  allocate(hecmatmpc%B(size(hecmat%B)))
124  allocate(hecmatmpc%X(size(hecmat%X)))
125  end subroutine hecmw_mpc_mat_init_explicit
126 
127  !C
128  !C***
129  !C*** hecmw_mpc_mat_finalize
130  !C***
131  !C
132  subroutine hecmw_mpc_mat_finalize(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMATmpc)
133  implicit none
134  type (hecmwst_local_mesh), intent(in) :: hecmesh
135  type (hecmwst_matrix), intent(in) :: hecmat
136  type (hecmwst_local_mesh), pointer :: hecmeshmpc
137  type (hecmwst_matrix), pointer :: hecmatmpc
138  type (hecmwst_matrix), pointer, optional :: conmatmpc
139  integer(kind=kint) :: totalmpc, mpc_method
140 
141  totalmpc = hecmesh%mpc%n_mpc
142  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
143 
144  if (totalmpc == 0) then
145  nullify(hecmeshmpc)
146  nullify(hecmatmpc)
147  if (present(conmatmpc)) nullify(conmatmpc)
148  return
149  endif
150 
151  mpc_method = hecmw_mat_get_mpc_method(hecmat)
152 
153  select case (mpc_method)
154  case (1) ! penalty
155  nullify(hecmeshmpc)
156  nullify(hecmatmpc)
157  if (present(conmatmpc)) nullify(conmatmpc)
158  case (3) ! elimination
159  call hecmw_mpc_mesh_free(hecmeshmpc)
160  deallocate(hecmeshmpc)
161  nullify(hecmeshmpc)
162  call hecmw_mat_finalize(hecmatmpc)
163  deallocate(hecmatmpc)
164  nullify(hecmatmpc)
165  if (present(conmatmpc)) then
166  call hecmw_mat_finalize(conmatmpc)
167  deallocate(conmatmpc)
168  nullify(conmatmpc)
169  endif
170  end select
171 
172  end subroutine hecmw_mpc_mat_finalize
173 
174  !C
175  !C***
176  !C*** hecmw_mpc_mat_finalize_explicit
177  !C***
178  !C
179  subroutine hecmw_mpc_mat_finalize_explicit(hecMESH, hecMAT, hecMATmpc)
180  implicit none
181  type (hecmwst_local_mesh), intent(in) :: hecmesh
182  type (hecmwst_matrix), intent(in) :: hecmat
183  type (hecmwst_matrix), pointer :: hecmatmpc
184  integer(kind=kint) :: totalmpc, mpc_method
185 
186  totalmpc = hecmesh%mpc%n_mpc
187  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
188 
189  if (totalmpc == 0) then
190  nullify(hecmatmpc)
191  return
192  endif
193 
194  mpc_method = hecmw_mat_get_mpc_method(hecmat)
195 
196  select case (mpc_method)
197  case (1) ! penalty
198  nullify(hecmatmpc)
199  case (3) ! elimination
200  call hecmw_mat_finalize(hecmatmpc)
201  deallocate(hecmatmpc)
202  nullify(hecmatmpc)
203  end select
204 
205  end subroutine hecmw_mpc_mat_finalize_explicit
206 
207  !C
208  !C***
209  !C*** hecmw_mpc_mat_ass
210  !C***
211  !C
212  subroutine hecmw_mpc_mat_ass(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc, hecLagMAT)
213  implicit none
214  type (hecmwst_local_mesh), intent(in) :: hecmesh
215  type (hecmwst_matrix), intent(inout) :: hecmat
216  type (hecmwst_local_mesh), pointer :: hecmeshmpc
217  type (hecmwst_matrix), pointer :: hecmatmpc
218  type (hecmwst_matrix), intent(in), optional :: conmat
219  type (hecmwst_matrix), pointer, optional :: conmatmpc
220  type (hecmwst_matrix_lagrange), intent(inout), optional :: heclagmat
221  integer(kind=kint) :: totalmpc, mpc_method
222 
223  totalmpc = hecmesh%mpc%n_mpc
224  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
225 
226  if (totalmpc == 0) return
227 
228  mpc_method = hecmw_mat_get_mpc_method(hecmat)
229 
230  select case (mpc_method)
231  case (1) ! penalty
232  !if (hecMESH%my_rank.eq.0) write(0,*) "MPC Method: Penalty"
233  call hecmw_mat_ass_equation ( hecmesh, hecmat )
234  case (3) ! elimination
235  !if (hecMESH%my_rank.eq.0) write(0,*) "MPC Method: Elimination"
236  call hecmw_trimatmul_ttkt_mpc(hecmeshmpc, hecmat, hecmatmpc)
237  if (present(conmat).and.present(conmatmpc).and.present(heclagmat)) then
238  call hecmw_trimatmul_ttkt_mpc(hecmeshmpc, conmat, conmatmpc)
239  call resize_heclagmat(conmat%NP, conmatmpc%NP, conmat%NDOF, heclagmat)
240  endif
241  end select
242 
243  end subroutine hecmw_mpc_mat_ass
244 
245 
246  subroutine resize_heclagmat(NP_orig, NP_new, ndof, hecLagMAT)
247  integer(kind=kint), intent(in) :: np_orig, np_new, ndof
248  type (hecmwst_matrix_lagrange), intent(inout) :: heclagmat
249  integer(kind=kint), pointer :: itemp(:)
250 
251  if (heclagmat%num_lagrange == 0) return
252 
253  allocate(itemp(0:np_new))
254  itemp(0:np_orig) = heclagmat%indexU_lagrange(0:np_orig)
255  itemp(np_orig+1:np_new) = heclagmat%indexU_lagrange(np_orig)
256 
257  deallocate(heclagmat%indexU_lagrange)
258  heclagmat%indexU_lagrange => itemp
259 
260  end subroutine resize_heclagmat
261 
262  !C
263  !C***
264  !C*** hecmw_mpc_trans_rhs
265  !C***
266  !C
267  subroutine hecmw_mpc_trans_rhs(hecMESH, hecMAT, hecMATmpc)
268  implicit none
269  type (hecmwst_local_mesh), intent(inout) :: hecmesh
270  type (hecmwst_matrix), intent(inout) :: hecmat
271  type (hecmwst_matrix), pointer :: hecmatmpc
272  real(kind=kreal) :: time_dumm
273  integer(kind=kint) :: totalmpc, mpc_method
274 
275  totalmpc = hecmesh%mpc%n_mpc
276  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
277 
278  if (totalmpc == 0) return
279 
280  mpc_method = hecmw_mat_get_mpc_method(hecmat)
281 
282  select case (mpc_method)
283  case (1) ! penalty
284  call hecmw_mat_ass_equation_rhs ( hecmesh, hecmatmpc )
285  case (3) ! elimination
286  time_dumm = 0.d0
287  call hecmw_trans_b(hecmesh, hecmat, hecmat%B, hecmatmpc%B, time_dumm)
288  hecmatmpc%Iarray=hecmat%Iarray
289  hecmatmpc%Rarray=hecmat%Rarray
290  ! the elimination T^t A T preserves symmetry; direct solvers read this flag,
291  ! which hecmw_mpc_mat_init defaulted to .true. on the newly created hecMATmpc
292  hecmatmpc%symmetric=hecmat%symmetric
293  end select
294 
295  end subroutine hecmw_mpc_trans_rhs
296 
297  !C
298  !C***
299  !C*** hecmw_mpc_tback_sol
300  !C***
301  !C
302  subroutine hecmw_mpc_tback_sol(hecMESH, hecMAT, hecMATmpc)
303  implicit none
304  type (hecmwst_local_mesh), intent(in) :: hecmesh
305  type (hecmwst_matrix), intent(inout) :: hecmat
306  type (hecmwst_matrix), pointer :: hecmatmpc
307  real(kind=kreal) :: time_dumm
308  integer(kind=kint) :: totalmpc, mpc_method, i
309  integer(kind=kint) :: npndof, npndof_mpc, num_lagrange
310 
311  totalmpc = hecmesh%mpc%n_mpc
312  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
313 
314  if (totalmpc == 0) return
315 
316  mpc_method = hecmw_mat_get_mpc_method(hecmat)
317 
318  select case (mpc_method)
319  case (1) ! penalty
320  ! do nothing
321  case (3) ! elimination
322  npndof = hecmat%NP * hecmat%NDOF
323  do i = 1, npndof
324  hecmat%X(i) = hecmatmpc%X(i)
325  enddo
326  time_dumm = 0.d0
327  call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
328  num_lagrange = size(hecmat%X) - npndof
329  npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
330  do i = 1, num_lagrange
331  hecmat%X(npndof+i) = hecmatmpc%X(npndof_mpc+i)
332  enddo
333  hecmat%Iarray=hecmatmpc%Iarray
334  hecmat%Rarray=hecmatmpc%Rarray
335  end select
336  end subroutine hecmw_mpc_tback_sol
337 
338  !C
339  !C***
340  !C*** hecmw_mpc_trans_mass
341  !C***
342  !C
343  subroutine hecmw_mpc_trans_mass(hecMESH, hecMAT, hecMATmpc, mass)
344  implicit none
345  type (hecmwst_local_mesh), intent(inout) :: hecmesh
346  type (hecmwst_matrix), intent(inout) :: hecmat
347  type (hecmwst_matrix), pointer :: hecmatmpc
348  real(kind=kreal), pointer :: mass(:)
349 
350  real(kind=kreal), allocatable :: w(:), mtmp(:)
351  real(kind=kreal) :: time_dumm
352  integer(kind=kint) :: totalmpc, mpc_method, i
353  integer(kind=kint) :: npndof, npndof_mpc
354 
355  totalmpc = hecmesh%mpc%n_mpc
356  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
357 
358  if (totalmpc == 0) return
359 
360  mpc_method = hecmw_mat_get_mpc_method(hecmat)
361 
362  select case (mpc_method)
363  case (1) ! penalty
364  ! do nothing
365  case (3) ! elimination
366  npndof = hecmat%NP * hecmat%NDOF
367  npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
368  allocate(w(npndof))
369  allocate(mtmp(npndof))
370  !C-- lumped mass of the reduced system = row sums of [T'][M][T]
371  !C-- {w} = [T]{1}
372  mtmp(:) = 1.d0
373  time_dumm = 0.d0
374  call hecmw_tvec(hecmesh, hecmat%NDOF, mtmp, w, time_dumm)
375  !C-- {w} = [M]{w}
376  do i = 1, npndof
377  w(i) = mass(i) * w(i)
378  enddo
379  !C-- {Mt} = [T']{w}
380  call hecmw_ttvec(hecmesh, hecmat%NDOF, w, mtmp, time_dumm)
381  !C-- external nodes added by the reduction get zero mass, as the RHS does
382  deallocate(mass)
383  allocate(mass(npndof_mpc))
384  mass(:) = 0.d0
385  do i = 1, npndof
386  mass(i) = mtmp(i)
387  enddo
388  deallocate(w)
389  deallocate(mtmp)
390  end select
391 
392  end subroutine hecmw_mpc_trans_mass
393 
394  !C
395  !C***
396  !C*** hecmw_mpc_tback_eigvec
397  !C***
398  !C
399  subroutine hecmw_mpc_tback_eigvec(hecMESH, hecMAT, neig, eigvec)
400  implicit none
401  type (hecmwst_local_mesh), intent(in) :: hecmesh
402  type (hecmwst_matrix), intent(inout) :: hecmat
403  integer(kind=kint), intent(in) :: neig
404  real(kind=kreal), intent(inout) :: eigvec(:,:)
405 
406  real(kind=kreal) :: time_dumm
407  integer(kind=kint) :: totalmpc, mpc_method, i
408 
409  totalmpc = hecmesh%mpc%n_mpc
410  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
411 
412  if (totalmpc == 0) return
413 
414  mpc_method = hecmw_mat_get_mpc_method(hecmat)
415 
416  select case (mpc_method)
417  case (1) ! penalty
418  ! do nothing
419  case (3) ! elimination
420  time_dumm = 0.d0
421  do i = 1, neig
422  call hecmw_tback_x(hecmesh, hecmat%NDOF, eigvec(:,i), time_dumm)
423  !!! need normalization???
424  enddo
425  end select
426  end subroutine hecmw_mpc_tback_eigvec
427 
428  !C
429  !C***
430  !C*** hecmw_mpc_mark_slave
431  !C***
432  !C
433  subroutine hecmw_mpc_mark_slave(hecMESH, hecMAT, mark)
434  implicit none
435  type (hecmwst_local_mesh), intent(in) :: hecmesh
436  type (hecmwst_matrix), intent(inout) :: hecmat
437  integer(kind=kint), intent(out) :: mark(:)
438 
439  integer(kind=kint) :: ndof, i, j, k, kk
440 
441  ndof = hecmat%NDOF
442  mark(:) = 0
443  outer: do i = 1, hecmesh%mpc%n_mpc
444  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
445  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
446  enddo
447  k = hecmesh%mpc%mpc_index(i-1)+1
448  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
449  mark(kk) = 1
450  enddo outer
451  end subroutine hecmw_mpc_mark_slave
452 
453  !C
454  !C***
455  !C*** hecmw_mpc_scale
456  !C***
457  !C
458  subroutine hecmw_mpc_scale(hecMESH)
459  implicit none
460  type (hecmwst_local_mesh), intent(inout) :: hecmesh
461  integer(kind=kint) :: i, j, k
462  real(kind=kreal) :: wval
463 
464  !$omp parallel default(none),private(i,j,k,WVAL),shared(hecMESH)
465  !$omp do
466  do i = 1, hecmesh%mpc%n_mpc
467  k = hecmesh%mpc%mpc_index(i-1)+1
468  wval = 1.d0 / hecmesh%mpc%mpc_val(k)
469  hecmesh%mpc%mpc_val(k) = 1.d0
470  do j = hecmesh%mpc%mpc_index(i-1)+2, hecmesh%mpc%mpc_index(i)
471  hecmesh%mpc%mpc_val(j) = hecmesh%mpc%mpc_val(j) * wval
472  enddo
473  hecmesh%mpc%mpc_const(i) = hecmesh%mpc%mpc_const(i) * wval
474  enddo
475  !$omp end do
476  !$omp end parallel
477 
478  end subroutine hecmw_mpc_scale
479 
480 
481  !C
482  !C***
483  !C*** hecmw_trans_b
484  !C***
485  !C
486  subroutine hecmw_trans_b(hecMESH, hecMAT, B, BT, COMMtime)
487  implicit none
488  type (hecmwst_local_mesh), intent(in) :: hecmesh
489  type (hecmwst_matrix), intent(in) :: hecmat
490  real(kind=kreal), intent(in) :: b(:)
491  real(kind=kreal), intent(out), target :: bt(:)
492  real(kind=kreal), intent(inout) :: commtime
493 
494  real(kind=kreal), allocatable :: w(:)
495  real(kind=kreal), pointer :: xg(:)
496  integer(kind=kint) :: ndof, i, j, k, kk
497 
498  ndof = hecmat%NDOF
499 
500  call debug_write_vector(b, 'original RHS', 'B', ndof, hecmat%N, hecmat%NP, .true.)
501 
502  allocate(w(hecmesh%n_node * ndof))
503 
504  !C===
505  !C +---------------------------+
506  !C | {bt}= [T']({b} - [A]{xg}) |
507  !C +---------------------------+
508  !C===
509  xg => bt
510  do i = 1, hecmat%N * ndof
511  xg(i) = 0.d0
512  enddo
513 
514  !C-- Generate {xg} from mpc_const
515  !$omp parallel default(none),private(i,k,kk),shared(hecMESH,XG),firstprivate(ndof)
516  !$omp do
517  outer: do i = 1, hecmesh%mpc%n_mpc
518  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
519  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
520  enddo
521  k = hecmesh%mpc%mpc_index(i-1) + 1
522  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
523  xg(kk) = hecmesh%mpc%mpc_const(i)
524  enddo outer
525  !$omp end do
526  !$omp end parallel
527 
528  !C-- {w} = {b} - [A]{xg}
529  call hecmw_matresid(hecmesh, hecmat, xg, b, w, commtime)
530 
531  !C-- {bt} = [T'] {w}
532  call hecmw_ttvec(hecmesh, ndof, w, bt, commtime)
533 
534  deallocate(w)
535 
536  call debug_write_vector(bt, 'transformed RHS', 'BT', ndof, hecmat%N, hecmat%NP, .true.)
537  end subroutine hecmw_trans_b
538 
539 
540  !C
541  !C***
542  !C*** hecmw_tback_x
543  !C***
544  !C
545  subroutine hecmw_tback_x(hecMESH, ndof, X, COMMtime)
546  implicit none
547  type (hecmwst_local_mesh), intent(in) :: hecmesh
548  integer(kind=kint), intent(in) :: ndof
549  real(kind=kreal), intent(inout) :: x(:)
550  real(kind=kreal), intent(inout) :: commtime
551 
552  real(kind=kreal), allocatable :: w(:)
553  integer(kind=kint) :: i, j, k, kk
554 
555  call debug_write_vector(x, 'solution for transformed eqn', 'X', ndof, hecmesh%nn_internal, &
556  hecmesh%n_node, .true.)
557 
558  allocate(w(hecmesh%n_node * ndof))
559 
560  !C-- {tx} = [T]{x}
561  call hecmw_tvec(hecmesh, ndof, x, w, commtime)
562 
563  !C-- {x} = {tx} + {xg}
564  !$omp parallel default(none),private(i,k,kk),shared(hecMESH,X,W),firstprivate(ndof)
565  !$omp do
566  do i= 1, hecmesh%nn_internal * ndof
567  x(i)= w(i)
568  enddo
569  !$omp end do
570 
571  !$omp do
572  outer: do i = 1, hecmesh%mpc%n_mpc
573  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
574  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
575  enddo
576  k = hecmesh%mpc%mpc_index(i-1) + 1
577  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
578  x(kk) = x(kk) + hecmesh%mpc%mpc_const(i)
579  enddo outer
580  !$omp end do
581  !$omp end parallel
582 
583  deallocate(w)
584 
585  call hecmw_update_r(hecmesh, x, hecmesh%n_node, ndof)
586  call debug_write_vector(x, 'recovered solution', 'X', ndof, hecmesh%nn_internal, &
587  hecmesh%n_node, .true.)
588  end subroutine hecmw_tback_x
589 
590  subroutine hecmw_mpc_mesh_copy(src, dst)
591  implicit none
592  type (hecmwst_local_mesh), intent(in) :: src
593  type (hecmwst_local_mesh), intent(out) :: dst
594  dst%zero = src%zero
595  dst%MPI_COMM = src%MPI_COMM
596  dst%PETOT = src%PETOT
597  dst%PEsmpTOT = src%PEsmpTOT
598  dst%my_rank = src%my_rank
599  dst%n_subdomain = src%n_subdomain
600  dst%n_node = src%n_node
601  dst%nn_internal = src%nn_internal
602  dst%n_elem = src%n_elem
603  dst%ne_internal = src%ne_internal
604  dst%n_elem_type = src%n_elem_type
605  dst%n_dof = src%n_dof
606  dst%n_neighbor_pe = src%n_neighbor_pe
607  if (src%n_neighbor_pe > 0) then
608  allocate(dst%neighbor_pe(dst%n_neighbor_pe))
609  dst%neighbor_pe(:) = src%neighbor_pe(:)
610  allocate(dst%import_index(0:dst%n_neighbor_pe))
611  dst%import_index(:)= src%import_index(:)
612  allocate(dst%export_index(0:dst%n_neighbor_pe))
613  dst%export_index(:)= src%export_index(:)
614  allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
615  dst%import_item(:) = src%import_item(:)
616  allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
617  dst%export_item(:) = src%export_item(:)
618  endif
619  allocate(dst%global_node_ID(dst%n_node))
620  dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:dst%n_node)
621  allocate(dst%node_ID(2*dst%n_node))
622  dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*dst%n_node)
623  allocate(dst%elem_type_item(dst%n_elem_type))
624  dst%elem_type_item(:) = src%elem_type_item(:)
625  !
626  dst%mpc%n_mpc = src%mpc%n_mpc
627  dst%mpc%mpc_index => src%mpc%mpc_index
628  dst%mpc%mpc_item => src%mpc%mpc_item
629  dst%mpc%mpc_dof => src%mpc%mpc_dof
630  dst%mpc%mpc_val => src%mpc%mpc_val
631  dst%mpc%mpc_const => src%mpc%mpc_const
632  !
633  dst%node_group%n_grp = src%node_group%n_grp
634  dst%node_group%n_bc = src%node_group%n_bc
635  dst%node_group%grp_name => src%node_group%grp_name
636  dst%node_group%grp_index => src%node_group%grp_index
637  dst%node_group%grp_item => src%node_group%grp_item
638  dst%node_group%bc_grp_ID => src%node_group%bc_grp_ID
639  dst%node_group%bc_grp_type => src%node_group%bc_grp_type
640  dst%node_group%bc_grp_index => src%node_group%bc_grp_index
641  dst%node_group%bc_grp_dof => src%node_group%bc_grp_dof
642  dst%node_group%bc_grp_val => src%node_group%bc_grp_val
643  !
644  dst%node => src%node
645  dst%elem_type_index => src%elem_type_index
646  dst%elem_node_index => src%elem_node_index
647  dst%elem_node_item => src%elem_node_item
648  end subroutine hecmw_mpc_mesh_copy
649 
650  subroutine hecmw_mpc_mesh_free(hecMESH)
651  implicit none
652  type (hecmwst_local_mesh), intent(inout) :: hecmesh
653  if (hecmesh%n_neighbor_pe > 0) then
654  deallocate(hecmesh%neighbor_pe)
655  deallocate(hecmesh%import_index)
656  deallocate(hecmesh%export_index)
657  deallocate(hecmesh%import_item)
658  deallocate(hecmesh%export_item)
659  endif
660  deallocate(hecmesh%global_node_ID)
661  deallocate(hecmesh%node_ID)
662  deallocate(hecmesh%elem_type_item)
663  end subroutine hecmw_mpc_mesh_free
664 
667  subroutine debug_write_vector(Vec, label, name, ndof, N, &
668  NP, write_ext, slaves)
669  real(kind=kreal), intent(in) :: vec(:)
670  character(len=*), intent(in) :: label
671  character(len=*), intent(in) :: name
672  integer(kind=kint), intent(in) :: ndof
673  integer(kind=kint), intent(in) :: n
674  integer(kind=kint), intent(in), optional :: np
675  logical, intent(in), optional :: write_ext
676  integer(kind=kint), intent(in), optional :: slaves(:)
677  !
678  integer(kind=kint) :: iunit
679  character(len=128) :: fmt
680 
681  if (.not. debug_vector) return
682 
683  write(fmt,'(a,i0,a)') '(',ndof,'f12.3)'
684 
685  iunit = 1000 + hecmw_comm_get_rank()
686  write(iunit,*) trim(label),'------------------------------------------------------------'
687  write(iunit,*) 'size of ',trim(name),size(vec)
688  write(iunit,*) trim(name),': 1-',n*ndof
689  write(iunit,fmt) vec(1:n*ndof)
690  if (present(write_ext) .and. present(np)) then
691  if (write_ext) then
692  write(iunit,*) trim(name),'(external): ',n*ndof+1,'-',np*ndof
693  write(iunit,fmt) vec(n*ndof+1:np*ndof)
694  endif
695  endif
696  if (present(slaves)) then
697  if (size(slaves) > 0) then
698  write(iunit,*) trim(name),'(slave):',slaves(:)
699  write(iunit,fmt) vec(slaves(:))
700  endif
701  endif
702  end subroutine debug_write_vector
703 end module hecmw_mpc_prepost
subroutine, public hecmw_trimatmul_ttkt_mpc(hecMESH, hecMAT, hecTKT)
subroutine, public hecmw_mat_ass_equation_rhs(hecMESH, hecMAT)
subroutine, public hecmw_mat_ass_equation(hecMESH, hecMAT)
integer(kind=kint) function, public hecmw_mat_get_solver_type(hecMAT)
subroutine, public hecmw_mat_init(hecMAT)
subroutine, public hecmw_mat_finalize(hecMAT)
integer(kind=kint) function, public hecmw_mat_get_mpc_method(hecMAT)
subroutine, public hecmw_mat_set_mpc_method(hecMAT, mpc_method)
subroutine, public hecmw_mpc_tback_sol(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_trans_mass(hecMESH, hecMAT, hecMATmpc, mass)
subroutine, public hecmw_mpc_mat_init_explicit(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mat_finalize_explicit(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mat_init(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc)
subroutine, public hecmw_mpc_mat_ass(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMAT, conMATmpc, hecLagMAT)
subroutine, public hecmw_mpc_mat_finalize(hecMESH, hecMAT, hecMESHmpc, hecMATmpc, conMATmpc)
subroutine, public hecmw_mpc_tback_eigvec(hecMESH, hecMAT, neig, eigvec)
subroutine, public hecmw_mpc_trans_rhs(hecMESH, hecMAT, hecMATmpc)
subroutine, public hecmw_mpc_mark_slave(hecMESH, hecMAT, mark)
subroutine, public hecmw_ttvec(hecMESH, ndof, X, Y, COMMtime)
subroutine, public hecmw_tvec(hecMESH, ndof, X, Y, COMMtime)
subroutine, public hecmw_matresid(hecMESH, hecMAT, X, B, R, COMMtime)
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=kint), parameter hecmw_sum
integer(kind=4), parameter kreal
integer(kind=kint) function hecmw_comm_get_rank()
subroutine hecmw_update_r(hecMESH, val, n, m)
subroutine hecmw_allreduce_i1(hecMESH, s, ntag)
Structure for Lagrange multiplier-related part of stiffness matrix (Lagrange multiplier-related matri...