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(in), 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(in), 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  call hecmw_trans_b(hecmesh, hecmat, hecmat%B, hecmatmpc%B, time_dumm)
287  hecmatmpc%Iarray=hecmat%Iarray
288  hecmatmpc%Rarray=hecmat%Rarray
289  ! the elimination T^t A T preserves symmetry; direct solvers read this flag,
290  ! which hecmw_mpc_mat_init defaulted to .true. on the newly created hecMATmpc
291  hecmatmpc%symmetric=hecmat%symmetric
292  end select
293 
294  end subroutine hecmw_mpc_trans_rhs
295 
296  !C
297  !C***
298  !C*** hecmw_mpc_tback_sol
299  !C***
300  !C
301  subroutine hecmw_mpc_tback_sol(hecMESH, hecMAT, hecMATmpc)
302  implicit none
303  type (hecmwst_local_mesh), intent(in) :: hecmesh
304  type (hecmwst_matrix), intent(inout) :: hecmat
305  type (hecmwst_matrix), pointer :: hecmatmpc
306  real(kind=kreal) :: time_dumm
307  integer(kind=kint) :: totalmpc, mpc_method, i
308  integer(kind=kint) :: npndof, npndof_mpc, num_lagrange
309 
310  totalmpc = hecmesh%mpc%n_mpc
311  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
312 
313  if (totalmpc == 0) return
314 
315  mpc_method = hecmw_mat_get_mpc_method(hecmat)
316 
317  select case (mpc_method)
318  case (1) ! penalty
319  ! do nothing
320  case (3) ! elimination
321  npndof = hecmat%NP * hecmat%NDOF
322  do i = 1, npndof
323  hecmat%X(i) = hecmatmpc%X(i)
324  enddo
325  call hecmw_tback_x(hecmesh, hecmat%NDOF, hecmat%X, time_dumm)
326  num_lagrange = size(hecmat%X) - npndof
327  npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
328  do i = 1, num_lagrange
329  hecmat%X(npndof+i) = hecmatmpc%X(npndof_mpc+i)
330  enddo
331  hecmat%Iarray=hecmatmpc%Iarray
332  hecmat%Rarray=hecmatmpc%Rarray
333  end select
334  end subroutine hecmw_mpc_tback_sol
335 
336  !C
337  !C***
338  !C*** hecmw_mpc_trans_mass
339  !C***
340  !C
341  subroutine hecmw_mpc_trans_mass(hecMESH, hecMAT, hecMATmpc, mass)
342  implicit none
343  type (hecmwst_local_mesh), intent(inout) :: hecmesh
344  type (hecmwst_matrix), intent(inout) :: hecmat
345  type (hecmwst_matrix), pointer :: hecmatmpc
346  real(kind=kreal), pointer :: mass(:)
347 
348  real(kind=kreal), allocatable :: w(:), mtmp(:)
349  real(kind=kreal) :: time_dumm
350  integer(kind=kint) :: totalmpc, mpc_method, i
351  integer(kind=kint) :: npndof, npndof_mpc
352 
353  totalmpc = hecmesh%mpc%n_mpc
354  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
355 
356  if (totalmpc == 0) return
357 
358  mpc_method = hecmw_mat_get_mpc_method(hecmat)
359 
360  select case (mpc_method)
361  case (1) ! penalty
362  ! do nothing
363  case (3) ! elimination
364  npndof = hecmat%NP * hecmat%NDOF
365  npndof_mpc = hecmatmpc%NP * hecmatmpc%NDOF
366  allocate(w(npndof))
367  allocate(mtmp(npndof))
368  !C-- lumped mass of the reduced system = row sums of [T'][M][T]
369  !C-- {w} = [T]{1}
370  mtmp(:) = 1.d0
371  call hecmw_tvec(hecmesh, hecmat%NDOF, mtmp, w, time_dumm)
372  !C-- {w} = [M]{w}
373  do i = 1, npndof
374  w(i) = mass(i) * w(i)
375  enddo
376  !C-- {Mt} = [T']{w}
377  call hecmw_ttvec(hecmesh, hecmat%NDOF, w, mtmp, time_dumm)
378  !C-- external nodes added by the reduction get zero mass, as the RHS does
379  deallocate(mass)
380  allocate(mass(npndof_mpc))
381  mass(:) = 0.d0
382  do i = 1, npndof
383  mass(i) = mtmp(i)
384  enddo
385  deallocate(w)
386  deallocate(mtmp)
387  end select
388 
389  end subroutine hecmw_mpc_trans_mass
390 
391  !C
392  !C***
393  !C*** hecmw_mpc_tback_eigvec
394  !C***
395  !C
396  subroutine hecmw_mpc_tback_eigvec(hecMESH, hecMAT, neig, eigvec)
397  implicit none
398  type (hecmwst_local_mesh), intent(in) :: hecmesh
399  type (hecmwst_matrix), intent(inout) :: hecmat
400  integer(kind=kint), intent(in) :: neig
401  real(kind=kreal), intent(inout) :: eigvec(:,:)
402 
403  real(kind=kreal) :: time_dumm
404  integer(kind=kint) :: totalmpc, mpc_method, i
405 
406  totalmpc = hecmesh%mpc%n_mpc
407  call hecmw_allreduce_i1 (hecmesh, totalmpc, hecmw_sum)
408 
409  if (totalmpc == 0) return
410 
411  mpc_method = hecmw_mat_get_mpc_method(hecmat)
412 
413  select case (mpc_method)
414  case (1) ! penalty
415  ! do nothing
416  case (3) ! elimination
417  do i = 1, neig
418  call hecmw_tback_x(hecmesh, hecmat%NDOF, eigvec(:,i), time_dumm)
419  !!! need normalization???
420  enddo
421  end select
422  end subroutine hecmw_mpc_tback_eigvec
423 
424  !C
425  !C***
426  !C*** hecmw_mpc_mark_slave
427  !C***
428  !C
429  subroutine hecmw_mpc_mark_slave(hecMESH, hecMAT, mark)
430  implicit none
431  type (hecmwst_local_mesh), intent(in) :: hecmesh
432  type (hecmwst_matrix), intent(inout) :: hecmat
433  integer(kind=kint), intent(out) :: mark(:)
434 
435  integer(kind=kint) :: ndof, i, j, k, kk
436 
437  ndof = hecmat%NDOF
438  mark(:) = 0
439  outer: do i = 1, hecmesh%mpc%n_mpc
440  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
441  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
442  enddo
443  k = hecmesh%mpc%mpc_index(i-1)+1
444  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
445  mark(kk) = 1
446  enddo outer
447  end subroutine hecmw_mpc_mark_slave
448 
449  !C
450  !C***
451  !C*** hecmw_mpc_scale
452  !C***
453  !C
454  subroutine hecmw_mpc_scale(hecMESH)
455  implicit none
456  type (hecmwst_local_mesh), intent(inout) :: hecmesh
457  integer(kind=kint) :: i, j, k
458  real(kind=kreal) :: wval
459 
460  !$omp parallel default(none),private(i,j,k,WVAL),shared(hecMESH)
461  !$omp do
462  do i = 1, hecmesh%mpc%n_mpc
463  k = hecmesh%mpc%mpc_index(i-1)+1
464  wval = 1.d0 / hecmesh%mpc%mpc_val(k)
465  hecmesh%mpc%mpc_val(k) = 1.d0
466  do j = hecmesh%mpc%mpc_index(i-1)+2, hecmesh%mpc%mpc_index(i)
467  hecmesh%mpc%mpc_val(j) = hecmesh%mpc%mpc_val(j) * wval
468  enddo
469  hecmesh%mpc%mpc_const(i) = hecmesh%mpc%mpc_const(i) * wval
470  enddo
471  !$omp end do
472  !$omp end parallel
473 
474  end subroutine hecmw_mpc_scale
475 
476 
477  !C
478  !C***
479  !C*** hecmw_trans_b
480  !C***
481  !C
482  subroutine hecmw_trans_b(hecMESH, hecMAT, B, BT, COMMtime)
483  implicit none
484  type (hecmwst_local_mesh), intent(in) :: hecmesh
485  type (hecmwst_matrix), intent(in) :: hecmat
486  real(kind=kreal), intent(in) :: b(:)
487  real(kind=kreal), intent(out), target :: bt(:)
488  real(kind=kreal), intent(inout) :: commtime
489 
490  real(kind=kreal), allocatable :: w(:)
491  real(kind=kreal), pointer :: xg(:)
492  integer(kind=kint) :: ndof, i, j, k, kk
493 
494  ndof = hecmat%NDOF
495 
496  call debug_write_vector(b, 'original RHS', 'B', ndof, hecmat%N, hecmat%NP, .true.)
497 
498  allocate(w(hecmesh%n_node * ndof))
499 
500  !C===
501  !C +---------------------------+
502  !C | {bt}= [T']({b} - [A]{xg}) |
503  !C +---------------------------+
504  !C===
505  xg => bt
506  do i = 1, hecmat%N * ndof
507  xg(i) = 0.d0
508  enddo
509 
510  !C-- Generate {xg} from mpc_const
511  !$omp parallel default(none),private(i,k,kk),shared(hecMESH,XG),firstprivate(ndof)
512  !$omp do
513  outer: do i = 1, hecmesh%mpc%n_mpc
514  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
515  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
516  enddo
517  k = hecmesh%mpc%mpc_index(i-1) + 1
518  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
519  xg(kk) = hecmesh%mpc%mpc_const(i)
520  enddo outer
521  !$omp end do
522  !$omp end parallel
523 
524  !C-- {w} = {b} - [A]{xg}
525  call hecmw_matresid(hecmesh, hecmat, xg, b, w, commtime)
526 
527  !C-- {bt} = [T'] {w}
528  call hecmw_ttvec(hecmesh, ndof, w, bt, commtime)
529 
530  deallocate(w)
531 
532  call debug_write_vector(bt, 'transformed RHS', 'BT', ndof, hecmat%N, hecmat%NP, .true.)
533  end subroutine hecmw_trans_b
534 
535 
536  !C
537  !C***
538  !C*** hecmw_tback_x
539  !C***
540  !C
541  subroutine hecmw_tback_x(hecMESH, ndof, X, COMMtime)
542  implicit none
543  type (hecmwst_local_mesh), intent(in) :: hecmesh
544  integer(kind=kint), intent(in) :: ndof
545  real(kind=kreal), intent(inout) :: x(:)
546  real(kind=kreal), intent(inout) :: commtime
547 
548  real(kind=kreal), allocatable :: w(:)
549  integer(kind=kint) :: i, j, k, kk
550 
551  call debug_write_vector(x, 'solution for transformed eqn', 'X', ndof, hecmesh%nn_internal, &
552  hecmesh%n_node, .true.)
553 
554  allocate(w(hecmesh%n_node * ndof))
555 
556  !C-- {tx} = [T]{x}
557  call hecmw_tvec(hecmesh, ndof, x, w, commtime)
558 
559  !C-- {x} = {tx} + {xg}
560  !$omp parallel default(none),private(i,k,kk),shared(hecMESH,X,W),firstprivate(ndof)
561  !$omp do
562  do i= 1, hecmesh%nn_internal * ndof
563  x(i)= w(i)
564  enddo
565  !$omp end do
566 
567  !$omp do
568  outer: do i = 1, hecmesh%mpc%n_mpc
569  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
570  if (hecmesh%mpc%mpc_dof(j) > ndof) cycle outer
571  enddo
572  k = hecmesh%mpc%mpc_index(i-1) + 1
573  kk = ndof * (hecmesh%mpc%mpc_item(k) - 1) + hecmesh%mpc%mpc_dof(k)
574  x(kk) = x(kk) + hecmesh%mpc%mpc_const(i)
575  enddo outer
576  !$omp end do
577  !$omp end parallel
578 
579  deallocate(w)
580 
581  call hecmw_update_r(hecmesh, x, hecmesh%n_node, ndof)
582  call debug_write_vector(x, 'recovered solution', 'X', ndof, hecmesh%nn_internal, &
583  hecmesh%n_node, .true.)
584  end subroutine hecmw_tback_x
585 
586  subroutine hecmw_mpc_mesh_copy(src, dst)
587  implicit none
588  type (hecmwst_local_mesh), intent(in) :: src
589  type (hecmwst_local_mesh), intent(out) :: dst
590  dst%zero = src%zero
591  dst%MPI_COMM = src%MPI_COMM
592  dst%PETOT = src%PETOT
593  dst%PEsmpTOT = src%PEsmpTOT
594  dst%my_rank = src%my_rank
595  dst%n_subdomain = src%n_subdomain
596  dst%n_node = src%n_node
597  dst%nn_internal = src%nn_internal
598  dst%n_elem = src%n_elem
599  dst%ne_internal = src%ne_internal
600  dst%n_elem_type = src%n_elem_type
601  dst%n_dof = src%n_dof
602  dst%n_neighbor_pe = src%n_neighbor_pe
603  if (src%n_neighbor_pe > 0) then
604  allocate(dst%neighbor_pe(dst%n_neighbor_pe))
605  dst%neighbor_pe(:) = src%neighbor_pe(:)
606  allocate(dst%import_index(0:dst%n_neighbor_pe))
607  dst%import_index(:)= src%import_index(:)
608  allocate(dst%export_index(0:dst%n_neighbor_pe))
609  dst%export_index(:)= src%export_index(:)
610  allocate(dst%import_item(dst%import_index(dst%n_neighbor_pe)))
611  dst%import_item(:) = src%import_item(:)
612  allocate(dst%export_item(dst%export_index(dst%n_neighbor_pe)))
613  dst%export_item(:) = src%export_item(:)
614  endif
615  allocate(dst%global_node_ID(dst%n_node))
616  dst%global_node_ID(1:dst%n_node) = src%global_node_ID(1:dst%n_node)
617  allocate(dst%node_ID(2*dst%n_node))
618  dst%node_ID(1:2*dst%n_node) = src%node_ID(1:2*dst%n_node)
619  allocate(dst%elem_type_item(dst%n_elem_type))
620  dst%elem_type_item(:) = src%elem_type_item(:)
621  !
622  dst%mpc%n_mpc = src%mpc%n_mpc
623  dst%mpc%mpc_index => src%mpc%mpc_index
624  dst%mpc%mpc_item => src%mpc%mpc_item
625  dst%mpc%mpc_dof => src%mpc%mpc_dof
626  dst%mpc%mpc_val => src%mpc%mpc_val
627  dst%mpc%mpc_const => src%mpc%mpc_const
628  !
629  dst%node_group%n_grp = src%node_group%n_grp
630  dst%node_group%n_bc = src%node_group%n_bc
631  dst%node_group%grp_name => src%node_group%grp_name
632  dst%node_group%grp_index => src%node_group%grp_index
633  dst%node_group%grp_item => src%node_group%grp_item
634  dst%node_group%bc_grp_ID => src%node_group%bc_grp_ID
635  dst%node_group%bc_grp_type => src%node_group%bc_grp_type
636  dst%node_group%bc_grp_index => src%node_group%bc_grp_index
637  dst%node_group%bc_grp_dof => src%node_group%bc_grp_dof
638  dst%node_group%bc_grp_val => src%node_group%bc_grp_val
639  !
640  dst%node => src%node
641  end subroutine hecmw_mpc_mesh_copy
642 
643  subroutine hecmw_mpc_mesh_free(hecMESH)
644  implicit none
645  type (hecmwst_local_mesh), intent(inout) :: hecmesh
646  if (hecmesh%n_neighbor_pe > 1) then
647  deallocate(hecmesh%neighbor_pe)
648  deallocate(hecmesh%import_index)
649  deallocate(hecmesh%export_index)
650  deallocate(hecmesh%import_item)
651  deallocate(hecmesh%export_item)
652  endif
653  deallocate(hecmesh%global_node_ID)
654  deallocate(hecmesh%node_ID)
655  deallocate(hecmesh%elem_type_item)
656  end subroutine hecmw_mpc_mesh_free
657 
660  subroutine debug_write_vector(Vec, label, name, ndof, N, &
661  NP, write_ext, slaves)
662  real(kind=kreal), intent(in) :: vec(:)
663  character(len=*), intent(in) :: label
664  character(len=*), intent(in) :: name
665  integer(kind=kint), intent(in) :: ndof
666  integer(kind=kint), intent(in) :: n
667  integer(kind=kint), intent(in), optional :: np
668  logical, intent(in), optional :: write_ext
669  integer(kind=kint), intent(in), optional :: slaves(:)
670  !
671  integer(kind=kint) :: iunit
672  character(len=128) :: fmt
673 
674  if (.not. debug_vector) return
675 
676  write(fmt,'(a,i0,a)') '(',ndof,'f12.3)'
677 
678  iunit = 1000 + hecmw_comm_get_rank()
679  write(iunit,*) trim(label),'------------------------------------------------------------'
680  write(iunit,*) 'size of ',trim(name),size(vec)
681  write(iunit,*) trim(name),': 1-',n*ndof
682  write(iunit,fmt) vec(1:n*ndof)
683  if (present(write_ext) .and. present(np)) then
684  if (write_ext) then
685  write(iunit,*) trim(name),'(external): ',n*ndof+1,'-',np*ndof
686  write(iunit,fmt) vec(n*ndof+1:np*ndof)
687  endif
688  endif
689  if (present(slaves)) then
690  if (size(slaves) > 0) then
691  write(iunit,*) trim(name),'(slave):',slaves(:)
692  write(iunit,fmt) vec(slaves(:))
693  endif
694  endif
695  end subroutine debug_write_vector
696 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...