00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_find_intersect (comp_info, global_index, &
00012 num_intersect_per_grid, &
00013 num_dummy_intersect_per_grid,&
00014 ninter, nmyint, nnull, &
00015 lastag, ierror)
00016
00017
00018
00019 use PRISM_constants
00020
00021 use psmile_grid, only : psmile_transform_extent_back, &
00022 code_no_trans
00023
00024 use PSMILe, dummy_interface => PSMILe_Find_intersect
00025 use psmile_common, only : enddef_msg_intersections
00026
00027 implicit none
00028
00029
00030
00031 Integer, Intent (In) :: global_index
00032
00033
00034
00035 Integer, Intent (In) :: lastag
00036
00037 Integer, Intent (InOut) :: num_intersect_per_grid(:),
00038 num_dummy_intersect_per_grid(:)
00039
00040
00041
00042
00043
00044 Type (Enddef_comp), Intent (InOut) :: comp_info
00045
00046
00047
00048
00049 Integer, Intent (InOut) :: ninter
00050
00051
00052
00053
00054 Integer, Intent (InOut) :: nmyint
00055
00056
00057
00058
00059 Integer, Intent (InOut) :: nnull
00060
00061
00062
00063
00064
00065
00066 Integer, Intent (Out) :: ierror
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 integer :: local_comp_id
00077
00078 integer :: global_comp_id
00079
00080 integer :: rank
00081
00082 integer :: icomp
00083
00084 type(enddef_comp), pointer :: icomp_info
00085
00086
00087
00088
00089
00090
00091
00092 integer :: grid_id, grid_type, extent_id
00093 integer :: inum_total_extents
00094
00095 integer :: local_extents_range(2)
00096 integer :: local_grid_extents_range(2)
00097 integer :: jglob, jbeg, jend, n
00098 integer :: max_num_grids_per_comp
00099 integer :: global_dest_grid_id
00100
00101 logical :: mg_gen (Number_of_Grids_allocated)
00102
00103
00104
00105 integer :: m, method_id, n_meths
00106 integer :: poss_meths (Number_of_Methods_allocated)
00107
00108
00109
00110 Integer :: ibeg, n_in_fields, n_out_fields
00111 Integer :: var_id, n_vars
00112 Integer :: poss_fields (Number_of_Fields_allocated)
00113 Type (ch_ptr), pointer :: In_channel(:)
00114
00115
00116
00117 Integer :: defined, last_maskid
00118
00119
00120
00121 Integer :: nbr_blocks
00122 Integer :: extent
00123 Integer :: idim(ndim_3d)
00124 Integer :: offset(ndim_3d)
00125 Integer :: addoffset(ndim_3d)
00126 Integer :: i, j, jj, jglob0
00127 Integer :: nb, ng, nl, npart, npartg
00128 Integer :: num_intersect, num_intersect_allocated
00129 Double Precision :: transformed (2, ndim_3d)
00130 Integer :: range (2, ndim_3d, Number_of_Grids_allocated)
00131 Double Precision, Allocatable :: dinter (:, :, :)
00132 Integer, Allocatable :: inters (:, :, :)
00133 Integer, Allocatable :: inters_save (:, :, :)
00134 Integer, Allocatable :: ids (:, :)
00135 Integer, Allocatable :: found (:)
00136 Integer, Allocatable :: buffer (:)
00137
00138 Integer :: field_list (nd_field_list,
00139 Number_of_Fields_allocated)
00140
00141 Integer :: field_tmp (nd_field_list,
00142 Number_of_Fields_allocated)
00143 Integer :: expand
00144
00145
00146
00147 Integer :: ip
00148 Integer :: msgint (nd_msgint)
00149 type (enddef_msg_intersections) :: msg_intersections
00150
00151
00152
00153 Integer :: dest
00154
00155
00156
00157 integer, parameter :: nerrp = 3
00158 integer :: ierrp (nerrp)
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 Character(len=len_cvs_string), save :: mycvs =
00192 '$Id: psmile_find_intersect.F90 2855 2011-01-05 17:19:54Z coquart $'
00193
00194
00195
00196
00197
00198 double precision :: tol = 1d-6
00199
00200 #ifdef VERBOSE
00201 print 9990, trim(ch_id), comp_info%comp_id, comp_info%global_comp_id
00202
00203 call psmile_flushstd
00204 #endif /* VERBOSE */
00205
00206
00207
00208 ierror = 0
00209 call psmile_init_enddef_msg_inters (msg_intersections)
00210
00211 local_comp_id = comp_info%comp_id
00212 global_comp_id = comp_info%global_comp_id
00213 rank = Comps(local_comp_id)%rank
00214
00215
00216
00217
00218
00219 local_extents_range(1) = SUM (comp_info%Number_of_grids_vector(1:rank)) + 1
00220 local_extents_range(2) = local_extents_range(1) + comp_info%Number_of_grids_vector(rank+1) - 1
00221
00222
00223
00224
00225
00226 mg_gen (:) = .false.
00227
00228 num_intersect_allocated = 0
00229
00230
00231
00232 max_num_grids_per_comp = 0
00233 do icomp = 1, Number_of_coll_comps
00234 max_num_grids_per_comp = max (max_num_grids_per_comp, &
00235 SUM(all_comp_infos(icomp)%Number_of_grids_vector(1:all_comp_infos(icomp)%size)) )
00236 end do
00237
00238
00239
00240 Allocate (found (1:max_num_grids_per_comp), stat = ierror)
00241 if (ierror > 0) then
00242
00243 call psmile_error ( PRISM_Error_Alloc, 'found', &
00244 (/ierror, max_num_grids_per_comp/), &
00245 2, __FILE__, __LINE__ )
00246 return
00247 endif
00248
00249
00250
00251 do icomp = 1, Number_of_coll_comps
00252
00253 icomp_info => all_comp_infos(icomp)
00254
00255 #ifdef DEBUG
00256 print *, "testing comp: ", icomp, " of ", Number_of_coll_comps, &
00257 " (global comp_id ", icomp_info%global_comp_id, ")"
00258 #endif /* DEBUG */
00259
00260
00261 if (global_comp_id == icomp_info%global_comp_id .or. &
00262 .not. psmile_to_be_coupled (global_comp_id, icomp_info%global_comp_id) ) cycle
00263
00264
00265
00266
00267
00268
00269
00270
00271 inum_total_extents = SUM(icomp_info%Number_of_grids_vector(1:icomp_info%size))
00272
00273
00274 local_grid_extents_range(1) = local_extents_range(1)
00275
00276
00277 do while (local_grid_extents_range(1) <= local_extents_range(2))
00278 grid_id = comp_info%all_extent_infos(1, local_grid_extents_range(1))
00279 grid_type = Grids(grid_id)%grid_type
00280
00281 #ifdef PRISM_ASSERTION
00282 if (grid_type /= comp_info%all_extent_infos(2,local_grid_extents_range(1))) then
00283 print *, "grid_id, grid_type, comp_info%all_extent_infos", &
00284 grid_id, grid_type, comp_info%all_extent_infos(2,local_grid_extents_range(1))
00285 call psmile_assert (__FILE__, __LINE__, &
00286 "Inconsistent grid type for grid grid_id")
00287 endif
00288 #endif
00289
00290
00291
00292 local_grid_extents_range(2) = local_grid_extents_range(1)
00293 do while (local_grid_extents_range(2) < local_extents_range(2))
00294 if (comp_info%all_extent_infos(1,local_grid_extents_range(2)+1) /= grid_id) exit
00295 local_grid_extents_range(2) = local_grid_extents_range(2) + 1
00296 enddo
00297
00298
00299
00300
00301 found (1:inum_total_extents) = 0
00302
00303
00304 do i = local_grid_extents_range(1), local_grid_extents_range(2)
00305
00306
00307
00308 do j = 1, inum_total_extents
00309 if (grid_types_are_compatible(grid_type, &
00310 icomp_info%all_extent_infos(2,j)) .and. &
00311 comp_info%all_extents(1, 1, i) <= &
00312 icomp_info%all_extents(2, 1, j) .and. &
00313 comp_info%all_extents(2, 1, i) >= &
00314 icomp_info%all_extents(1, 1, j) .and. &
00315 comp_info%all_extents(1, 2, i) <= &
00316 icomp_info%all_extents(2, 2, j) .and. &
00317 comp_info%all_extents(2, 2, i) >= &
00318 icomp_info%all_extents(1, 2, j) .and. &
00319 comp_info%all_extents(1, 3, i) <= &
00320 icomp_info%all_extents(2, 3, j) .and. &
00321 comp_info%all_extents(2, 3, i) >= &
00322 icomp_info%all_extents(1, 3, j)) then
00323 found (j) = found (j) + 1
00324 #ifdef DEBUG
00325 print *, "extents intersect"
00326 print "(a,6(' ',e13.6))", " local extent :", &
00327 comp_info%all_extents(:,:,i)
00328 print "(a,6(' ',e13.6))", " remote extent:", &
00329 icomp_info%all_extents(:,:,j)
00330 #endif
00331 endif
00332 end do
00333 end do
00334 #ifdef DEBUG
00335 print *, "-----------------------------------------------------"
00336 #endif
00337
00338
00339
00340 num_intersect = sum (found (1:inum_total_extents))
00341 if (num_intersect == 0) then
00342
00343
00344 local_grid_extents_range(1) = local_grid_extents_range(2) + 1
00345 cycle
00346 endif
00347
00348
00349
00350 if (num_intersect > num_intersect_allocated) then
00351
00352 if (num_intersect_allocated > 0) &
00353 Deallocate (dinter, inters, ids, inters_save)
00354
00355 Allocate (dinter (2, ndim_3d, num_intersect+1), &
00356 inters (2, ndim_3d, num_intersect), &
00357 inters_save (2, ndim_3d, num_intersect), &
00358 ids (num_intersect, 2), stat = ierror)
00359 if (ierror /= 0) then
00360 call psmile_error ( &
00361 PRISM_Error_Alloc, 'dinter,inters,ids, inters_save', &
00362 (/ierror, 3*(2*ndim_3d*(num_intersect+1))+num_intersect*2/), 2, &
00363 __FILE__, __LINE__ )
00364 return
00365 endif
00366 num_intersect_allocated = num_intersect
00367 endif
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 n_in_fields = 0
00379 n_out_fields = 0
00380 n_meths = 0
00381
00382
00383 if (Grids(grid_id)%comp_id == local_comp_id) then
00384 do i = 1, Number_of_Methods_allocated
00385 if (Methods(i)%grid_id == grid_id .and. &
00386 Methods(i)%status == PSMILe_status_defined .and. &
00387 Methods(i)%used_for_coupling ) then
00388 n_meths = n_meths + 1
00389 poss_meths (n_meths) = i
00390 endif
00391 end do
00392 endif
00393
00394 if (n_meths == 0) then
00395
00396
00397
00398 #ifdef DEBUG
00399 print *, "n_meths ", n_meths
00400 write (*, 9960) trim(ch_id), local_comp_id, grid_id
00401 #endif /* DEBUG */
00402 endif
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 if (n_meths > 0) then
00414
00415 do i = 1, Number_of_Fields_allocated
00416 if (Fields(i)%status == PSMILe_status_defined) then
00417 if ( Fields(i)%comp_id == local_comp_id .and. &
00418 Methods(Fields(i)%method_id)%grid_id == grid_id .and. &
00419 Fields(i)%used_for_coupling ) then
00420
00421 IF ( ASSOCIATED(Fields(i)%Taskin%In_channel) ) THEN
00422 DO j = 1, SIZE(Fields(i)%Taskin%In_channel)
00423 IF (Fields(i)%Taskin%In_channel(j)%remote_comp_id == &
00424 all_comp_infos(icomp)%global_comp_id ) THEN
00425 n_in_fields = n_in_fields + 1
00426 poss_fields (n_in_fields) = i
00427 ENDIF
00428 ENDDO
00429 ENDIF
00430
00431 if ( Associated(Fields(i)%Taskout) ) then
00432 DO j = 1, SIZE(Fields(i)%Taskout)
00433 IF (Fields(i)%Taskout(j)%remote_comp_id == &
00434 all_comp_infos(icomp)%global_comp_id ) THEN
00435 n_out_fields = n_out_fields + 1
00436 ENDIF
00437 ENDDO
00438 endif
00439
00440 endif
00441 endif
00442 enddo
00443
00444 #ifdef DEBUG
00445 if (n_in_fields + n_out_fields == 0) then
00446
00447
00448 print *, "n_in_fields, n_out_fields ", n_in_fields, n_out_fields
00449 write (*, 9960) trim(ch_id), local_comp_id, grid_id
00450 endif
00451 #endif /* DEBUG */
00452 endif
00453
00454
00455
00456 jbeg = 1
00457
00458 do while ( jbeg <= inum_total_extents )
00459
00460 do jglob = jbeg, inum_total_extents
00461 if (found (jglob) > 0) exit
00462 end do
00463
00464 if (jglob > inum_total_extents) exit
00465
00466
00467
00468
00469
00470
00471
00472 n = 0
00473
00474 do i = 1, icomp_info%size
00475 if (jglob <= n+icomp_info%Number_of_grids_vector(i)) exit
00476 n = n + icomp_info%Number_of_grids_vector(i)
00477 end do
00478
00479 if (i > icomp_info%size) then
00480 ierror = PRISM_Error_Internal
00481 ierrp (1) = icomp
00482 ierrp (2) = icomp_info%size
00483 call psmile_error (ierror, "Cannot find grid", ierrp, 2, &
00484 __FILE__, __LINE__)
00485 return
00486 endif
00487
00488 dest = icomp_info%psmile_ranks(i)
00489 jend = n + icomp_info%Number_of_grids_vector(i)
00490
00491
00492
00493
00494
00495 extent_id = icomp_info%all_extent_infos(1,jglob)
00496
00497 do jbeg = jglob+1, jend
00498 if (icomp_info%all_extent_infos(1,jbeg) /= &
00499 extent_id) exit
00500 end do
00501
00502 if (n_in_fields + n_out_fields == 0) then
00503 npart = 0
00504 go to 1000
00505 endif
00506
00507 npartg = jbeg - jglob
00508 jglob0 = jglob - 1
00509
00510 global_dest_grid_id = icomp_info%all_extent_infos(4,jglob)
00511
00512
00513
00514
00515
00516 n = 0
00517 do ng = 1, npartg
00518 if (found (jglob0+ng) > 0) then
00519 do i = local_grid_extents_range(1), local_grid_extents_range(2)
00520 dinter (1,:, n+1) = max ( &
00521 comp_info%all_extents(1,:,i), &
00522 icomp_info%all_extents(1,:,jglob0+ng))
00523 dinter (2,:, n+1) = min ( &
00524 comp_info%all_extents(2,:,i), &
00525 icomp_info%all_extents(2,:,jglob0+ng))
00526
00527 if (minval (dinter (2,:, n+1) - dinter (1,:, n+1)) >= 0.0d0) then
00528
00529 n = n + 1
00530 ids (n, 1) = i
00531 ids (n, 2) = jglob0 + ng
00532 #ifdef DEBUG
00533 print "(a,6(' ',e13.6))", "local extent :", &
00534 comp_info%all_extents(:,:,i)
00535 print "(a,6(' ',e13.6))", "remote extent:", &
00536 icomp_info%all_extents(:,:,jglob0+ng)
00537 print "(a,6(e13.6,' '))", "intersection: ", dinter (:,:, n)
00538 #endif
00539 endif
00540 end do
00541 endif
00542 end do
00543
00544 #ifdef PRISM_ASSERTION
00545 if (n > num_intersect) then
00546 print *, 'n, num_intersect', n, num_intersect
00547 call psmile_assert (__FILE__, __LINE__, 'n > num_intersect !')
00548 endif
00549 #endif
00550 npart = n
00551
00552
00553
00554 do n = 1, npart
00555 if (comp_info%all_extent_infos(3, ids(n,1)) /= code_no_trans) then
00556 call psmile_transform_extent_back ( &
00557 (/comp_info%all_extent_infos(3,ids(n,1))/), &
00558 dinter(:, :, n), transformed, 1, ierror)
00559 if ( ierror /= 0 ) return
00560 dinter (:, :, n) = transformed
00561 #ifdef DEBUG
00562 print "(a,6(e13.6,' '),a)", "intersection: ", dinter (:,:, n), " (transformed)"
00563 #endif
00564 endif
00565 end do
00566
00567
00568
00569
00570
00571
00572 if (grid_type == PRISM_Gridless) then
00573
00574
00575
00576
00577
00578
00579
00580
00581 inters (:, :, 1:npart) = nint (dinter (:, :, 1:npart))
00582
00583 inters_save = inters
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 if (Associated (Grids(grid_id)%partition)) then
00594
00595 nbr_blocks = size(Grids(grid_id)%partition(:,1))
00596
00597 if ( nbr_blocks > 1 ) then
00598
00599 do n = 1, npart
00600
00601
00602
00603 do nb = 1, nbr_blocks
00604
00605 if ( inters(2,1,n) >= Grids(grid_id)%partition(nb,1) + 1 .and. &
00606 inters(1,1,n) <= Grids(grid_id)%partition(nb,1) + &
00607 Grids(grid_id)%extent (nb,1) .and. &
00608 inters(2,2,n) >= Grids(grid_id)%partition(nb,2) + 1 .and. &
00609 inters(1,2,n) <= Grids(grid_id)%partition(nb,2) + &
00610 Grids(grid_id)%extent (nb,2) .and. &
00611 inters(2,3,n) >= Grids(grid_id)%partition(nb,3) + 1 .and. &
00612 inters(1,3,n) <= Grids(grid_id)%partition(nb,3) + &
00613 Grids(grid_id)%extent (nb,3) ) exit
00614
00615 enddo
00616
00617
00618
00619 if ( nb <= nbr_blocks ) then
00620 #ifdef DEBUG
00621 print *, ' Transform block ', nb, Grids(grid_id)%partition(nb,1)+1 &
00622 , ' - ', Grids(grid_id)%partition(nb,1)+ &
00623 Grids(grid_id)%extent (nb,1)
00624 print *, ' global inter ', nb, inters(:, :, n)
00625 #endif
00626 offset = 0
00627 addoffset = 0
00628
00629 do i = 1, ndim_3d
00630 idim(i) = Grids(grid_id)%grid_shape(2,i) - &
00631 Grids(grid_id)%grid_shape(1,i)+1
00632 do nl = 1, nb-1
00633 addoffset(i) = Grids(grid_id)%extent(nl,i) + offset(i)
00634 if ( addoffset(i) < idim(i) ) &
00635 offset(i) = addoffset(i)
00636 enddo
00637 enddo
00638
00639 do i = 1, ndim_3d
00640 extent = inters(2,i,n) - inters(1,i,n)
00641 inters(1, i, n) = inters(1, i, n) + offset(i) &
00642 - Grids(grid_id)%partition(nb,i) &
00643 + Grids(grid_id)%grid_shape(1,i) - 1
00644 inters(2, i, n) = inters(1, i, n) + extent
00645 end do
00646 #ifdef DEBUG
00647 print *, ' part offset ', nb, offset(:)
00648 print *, ' local inter ', nb, inters(:, :, n)
00649 #endif
00650 else
00651
00652 ierror = PRISM_Error_Internal
00653 ierrp (1) = nb
00654 ierrp (2) = nbr_blocks
00655 call psmile_error (ierror, "No block found", ierrp, 2, &
00656 __FILE__, __LINE__)
00657 return
00658
00659 endif
00660
00661 enddo
00662
00663 else
00664
00665
00666
00667 do n = 1, npart
00668 do i = 1, ndim_3d
00669 inters (1:2, i, n) = &
00670 inters (1:2, i, n) - Grids(grid_id)%partition (1,i) &
00671 + Grids(grid_id)%grid_shape(1,i) - 1
00672 end do
00673 end do
00674
00675 endif
00676
00677 endif
00678
00679 if (npart > 1) then
00680 call psmile_remove_intersect_int (inters, ids(1:npart,1), &
00681 ids(1:npart,2), npart, ierror)
00682 if (ierror > 0) return
00683 endif
00684
00685 #ifdef PRISM_ASSERTION
00686 if (icomp_info%all_extent_infos(2,jglob) /= &
00687 PRISM_Gridless) then
00688 call psmile_assert (__FILE__, __LINE__, &
00689 'Coupling of gridless grid with real grid is impossible !')
00690 endif
00691 #endif
00692 else
00693
00694
00695
00696
00697 if (npart > 1) then
00698 call psmile_remove_intersect (dinter, ids(1:npart,1), &
00699 ids(1:npart,2), npart, &
00700 comp_info%all_extent_infos, &
00701 icomp_info%all_extent_infos, &
00702 ierror)
00703 if (ierror > 0) return
00704 endif
00705
00706 do n = 1, npart
00707 #ifdef DEBUG
00708 PRINT *, ' In psmile_find_intersect intersection :',n,'over :',npart
00709 #endif
00710 call psmile_sel_grid_range (grid_id, dinter (:, :, n), &
00711 inters(:, :, n), ierror)
00712 if ( ierror /= 0 ) return
00713 end do
00714
00715 n = 1
00716 do while (n <= npart)
00717 if (minval (inters(2, :, n) - inters (1, :, n)) < 0) then
00718 if (n /= npart) then
00719 inters (:, :, n) = inters (:, :, npart)
00720 ids (n, 1) = ids (npart, 1)
00721 ids (n, 2) = ids (npart, 2)
00722 endif
00723
00724 npart = npart - 1
00725 else
00726 n = n + 1
00727 endif
00728 end do
00729 #ifdef HUHU
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 if (npart > 1) then
00742 call psmile_remove_intersect_int (inters, ids(1:npart,1), &
00743 ids(1:npart,2), npart, ierror)
00744 if (ierror > 0) return
00745 endif
00746 #endif
00747 endif
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 if (n_in_fields == 0) go to 1000
00759
00760 n_vars = 0
00761
00762 do m = 1, n_meths
00763 ibeg = 1
00764 method_id = poss_meths (m)
00765
00766 search_vars: do while (ibeg <= n_in_fields)
00767
00768
00769
00770
00771 do i = ibeg, n_in_fields
00772 if (Fields(poss_fields(i))%method_id == method_id) exit
00773 end do
00774
00775 ibeg = i + 1
00776 if (i > n_in_fields) exit search_vars
00777
00778
00779
00780
00781 #ifdef DEBUG
00782 print *, 'search Taskin for dest component', icomp_info%global_comp_id
00783 #endif /* DEBUG */
00784 In_channel => Fields(poss_fields(i))%Taskin%In_channel
00785
00786 do j = 1, size (In_channel)
00787 #ifdef DEBUG
00788 print 9970, j, &
00789 In_channel(j)%origin_type, &
00790 In_channel(j)%remote_comp_id, &
00791 In_channel(j)%global_transi_id, &
00792 In_channel(j)%remote_transi_id, &
00793 global_dest_grid_id
00794 #endif /* DEBUG */
00795 if (In_channel(j)%origin_type == PSMILe_comp .and. &
00796 In_channel(j)%remote_comp_id == &
00797 icomp_info%global_comp_id &
00798 .and. &
00799 field2grid(In_channel(j)%remote_transi_id) == &
00800 global_dest_grid_id) then
00801 n_vars = n_vars + 1
00802 field_tmp (1, n_vars) = method_id
00803 field_tmp (2, n_vars) = poss_fields(i)
00804 field_tmp (4, n_vars) = In_channel(j)%global_transi_id
00805 field_tmp (5, n_vars) = In_channel(j)%remote_transi_id
00806 field_tmp (6, n_vars) = 0
00807 do jj = 1, 3
00808 if ( In_channel(j)%interp%interp_meth(jj) == PSMILe_conserv2D .or. &
00809 In_channel(j)%interp%interp_meth(jj) == PSMILe_conserv3D ) then
00810 field_tmp (6, n_vars) = In_channel(j)%interp%interp_meth(jj)
00811 endif
00812 enddo
00813 endif
00814 end do
00815
00816 end do search_vars
00817 end do
00818
00819
00820
00821
00822
00823 j = 0
00824 do n = 1, n_vars
00825 if ( field_tmp (6, n) == PSMILe_conserv2D .or. &
00826 field_tmp (6, n) == PSMILe_conserv3D ) then
00827 j = j + 1
00828 field_list(:,j) = field_tmp(:,n)
00829 endif
00830 enddo
00831 do n = 1, n_vars
00832 if ( field_tmp (6, n) /= PSMILe_conserv2D .and. &
00833 field_tmp (6, n) /= PSMILe_conserv3D ) then
00834 j = j + 1
00835 field_list(:,j) = field_tmp(:,n)
00836 endif
00837 enddo
00838
00839 if (n_vars == 0) then
00840
00841
00842 #ifdef DEBUG
00843 print *, "n_vars", n_vars
00844 write (*, 9960) trim(ch_id), local_comp_id, grid_id
00845 #endif /* DEBUG */
00846
00847 npart = 0
00848 endif
00849
00850
00851
00852 1000 continue
00853
00854
00855 if (n_out_fields > 0 .and. npart > 0 .and. &
00856 grid_type /= PRISM_Gridless) then
00857 if (.not. mg_gen (grid_id)) then
00858 mg_gen (grid_id) = .true.
00859 range (:, :, grid_id) = inters (:, :, 1)
00860 endif
00861
00862
00863
00864
00865 do n = 1, npart
00866 range (1, 1:ndim_3d, grid_id) = min ( &
00867 range (1, 1:ndim_3d, grid_id), inters (1, 1:ndim_3d, n))
00868 range (2, 1:ndim_3d, grid_id) = max ( &
00869 range (2, 1:ndim_3d, grid_id), inters (2, 1:ndim_3d, n))
00870 end do
00871 endif
00872
00873
00874
00875
00876 #ifdef DEBUG
00877 PRINT*, 'Number of input fields :',n_in_fields
00878 PRINT*, 'Number of output fields :',n_out_fields
00879 call psmile_flushstd
00880 #endif
00881
00882 if (npart == 0 .or. n_in_fields == 0) then
00883 if (dest == psmile_rank) continue
00884
00885 nnull = nnull + 1
00886 num_dummy_intersect_per_grid(grid_id) = &
00887 num_dummy_intersect_per_grid(grid_id) + 1
00888 n_vars = 0
00889 npart = 0
00890 endif
00891
00892 ninter = ninter + 1
00893 num_intersect_per_grid(grid_id) = &
00894 num_intersect_per_grid(grid_id) + 1
00895 #define CONS_REMAP_DEADLOCK_WORKAROUND
00896 #ifdef CONS_REMAP_DEADLOCK_WORKAROUND
00897 paction%intersect_ranks(ninter) = dest
00898 #endif
00899
00900 if (dest == psmile_rank) nmyint = nmyint + 1
00901
00902
00903
00904
00905
00906 msg_intersections%relative_msg_tag = ninter - nnull
00907
00908
00909
00910
00911 msg_intersections%src_comp_id = icomp_info%comp_id
00912
00913
00914
00915
00916 msg_intersections%tgt_comp_id = local_comp_id
00917 msg_intersections%tgt_grid_id = grid_id
00918
00919 msg_intersections%all_comp_infos_comp_idx = global_index
00920
00921 msg_intersections%num_parts = npart
00922
00923 if (n_vars > 0) then
00924
00925
00926 do i = 1, n_vars
00927 field_list (3, i) = Fields(field_list(2,i))%mask_id
00928 end do
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 do n = 1, n_vars
00944 if ( field_list(6,n) == PSMILe_conserv2D .or. &
00945 field_list(6,n) == PSMILe_conserv3D ) then
00946 last_maskid = field_list(3,n)
00947 do i = n+1, n_vars
00948 if ( field_list(3,i) == last_maskid ) then
00949 field_list(3,i) = PRISM_UNDEFINED
00950 endif
00951 enddo
00952 endif
00953 enddo
00954
00955 if (grid_type == PRISM_Gridless) then
00956 last_maskid = PRISM_UNDEFINED
00957
00958 do i = 1, n_vars
00959 if (field_list (3, i) /= PRISM_UNDEFINED) then
00960 if (field_list (3, i) == last_maskid) cycle
00961
00962 call psmile_is_mask_defined ( &
00963 Masks(field_list (3, i))%mask_array, &
00964 Masks(field_list (3, i))%mask_shape, &
00965 inters, npart, defined, ierror)
00966 if (ierror > 0) return
00967
00968
00969
00970 if (defined == 2) then
00971 do j = i+1, n_vars
00972 if (field_list (3,j) == field_list (3,i)) &
00973 field_list (3,j) = PRISM_UNDEFINED
00974 end do
00975
00976 field_list (3,i) = PRISM_UNDEFINED
00977 else
00978 last_maskid = field_list (3,i)
00979 endif
00980
00981 endif
00982 end do
00983 endif
00984
00985
00986
00987 method_id = field_list (1, 1)
00988 var_id = field_list (2, 1)
00989
00990 msg_intersections%first_tgt_method_id = method_id
00991 msg_intersections%first_tgt_var_id = var_id
00992
00993 msg_intersections%tgt_mask_id = field_list (3, 1)
00994
00995
00996
00997 msg_intersections%transient_in_id = field_list (4, 1)
00998 msg_intersections%transient_out_id = field_list (5, 1)
00999 msg_intersections%num_vars = n_vars
01000 msg_intersections%requires_conserv_remap = field_list (6, 1)
01001
01002
01003
01004 msg_intersections%method_type = Methods (method_id)%method_type
01005
01006 select case (Methods (method_id)%method_type)
01007 case (PSMILe_PointMethod)
01008 msg_intersections%method_datatype = &
01009 Methods (method_id)%coords_pointer%coords_datatype
01010
01011 case (PSMILe_VectorPointMethod)
01012 #ifdef TODO
01013 msg_intersections%method_datatype = &
01014 Methods (method_id)%vector_pointer%vector_datatype
01015 #else
01016 ierrp (1) = Methods (method_id)%method_type
01017 ierror = PRISM_Error_Internal
01018
01019 call psmile_error ( ierror, 'vector method type is currently not supported', &
01020 ierrp, 1, __FILE__, __LINE__ )
01021 #endif
01022
01023 case (PSMILe_SubgridMethod)
01024 msg_intersections%method_datatype = &
01025 Methods (method_id)%subgrid_pointer%subgrid_datatype
01026
01027 case default
01028 ierrp (1) = Methods (method_id)%method_type
01029 ierror = PRISM_Error_Internal
01030
01031 call psmile_error ( ierror, 'unsupported method type', &
01032 ierrp, 1, __FILE__, __LINE__ )
01033 end select
01034
01035 endif
01036
01037
01038
01039 ip = ip_msgint_inter + npart*(2*ndim_3d)
01040
01041
01042
01043
01044
01045
01046 expand = PSMILe_Undef
01047
01048 if (npart > 0) then
01049
01050 msg_intersections%first_src_all_extents_grid_id = ids (1, 2)
01051 msg_intersections%first_tgt_all_extents_grid_id = ids (1, 1)
01052
01053 if (grid_type == PRISM_Gridless) then
01054 allocate (msg_intersections%intersections(2*npart))
01055 else
01056 allocate (msg_intersections%intersections(npart))
01057 endif
01058
01059
01060
01061
01062
01063 if ( grid_type /= PRISM_Gaussreduced_regvrt ) then
01064
01065 if ( msg_intersections%requires_conserv_remap == PSMILe_conserv2D ) then
01066
01067 do n = 1, npart
01068 inters (2, 1:ndim_2d, n) = inters (2, 1:ndim_2d, n) + 1
01069 enddo
01070
01071 expand = PSMILe_conserv2D
01072
01073 else if ( msg_intersections%requires_conserv_remap == PSMILe_conserv3D ) then
01074
01075 do n = 1, npart
01076 inters (2, 1:ndim_3d, n) = inters (2, 1:ndim_3d, n) + 1
01077 enddo
01078
01079 expand = PSMILe_conserv3D
01080
01081 endif
01082
01083
01084 if ( expand == PSMILe_conserv2D .and. &
01085 msg_intersections%requires_conserv_remap /= PSMILe_conserv2D ) then
01086
01087 do n = 1, npart
01088 inters (2, 1:ndim_2d, n) = inters (2, 1:ndim_2d, n) - 1
01089 enddo
01090
01091 else if ( expand == PSMILe_conserv3D .and. &
01092 msg_intersections%requires_conserv_remap /= PSMILe_conserv3D ) then
01093
01094 do n = 1, npart
01095 inters (2, 1:ndim_3d, n) = inters (2, 1:ndim_3d, n) - 1
01096 enddo
01097
01098 endif
01099
01100 endif
01101
01102 do n = 1, npart
01103 msg_intersections%intersections(n)%intersection = inters(:, :, n)
01104 msg_intersections%intersections(n)%tgt_all_extents_grid_id = ids (n, 1)
01105 msg_intersections%intersections(n)%src_all_extents_grid_id = ids (n, 2)
01106 enddo
01107
01108 ip = ip + 2 * npart
01109
01110 if (grid_type == PRISM_Gridless) then
01111
01112
01113
01114 if (Associated(Grids(grid_id)%partition)) then
01115
01116 do n = 1, npart
01117
01118 msg_intersections%intersections(n+npart)%intersection = inters_save(:, :, n)
01119 msg_intersections%intersections(n+npart)%tgt_all_extents_grid_id = psmile_undef
01120 msg_intersections%intersections(n+npart)%src_all_extents_grid_id = psmile_undef
01121 enddo
01122 endif
01123
01124 ip = ip + 1 + npart*2*ndim_3d
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 endif
01148 else
01149 msg_intersections%first_tgt_all_extents_grid_id = psmile_undef
01150 msg_intersections%first_src_all_extents_grid_id = psmile_undef
01151 nullify (msg_intersections%intersections)
01152 end if
01153
01154 #ifdef DEBUG
01155 print *, "psmile_find_intersect: psmile_rank->dest, tag:", &
01156 psmile_rank, dest, lastag
01157 PRINT *, "psmile_find_intersect: datatype, npart:", &
01158 msg_intersections%method_datatype, npart
01159 PRINT*, 'psmile_find_intersect : ninter, nmyint , nnull:',ninter, nmyint , nnull
01160 call psmile_flushstd
01161 do n = 1, npart
01162 print *, "psmile_find_intersect: ipart, inter", n, inters (:, :, n)
01163 print *, "psmile_find_intersect: ipart, ids", n, ids(n, 1), ids (n,2)
01164 call psmile_flushstd
01165 end do
01166 #endif /* DEBUG */
01167
01168
01169
01170
01171 #ifdef DEBUG
01172 print *, ' Sending tag ', lastag, ' to destination ', dest
01173 #endif /* DEBUG */
01174
01175
01176 call psmile_pack_msg_intersections(msg_intersections, msgint)
01177
01178 call psmile_bsend (msgint, ip, MPI_INTEGER, dest, lastag, &
01179 comm_psmile, ierror)
01180
01181 if (ierror /= MPI_SUCCESS) then
01182 ierrp (1) = ierror
01183 ierrp (2) = dest
01184 ierrp (3) = lastag
01185 ierror = PRISM_Error_Send
01186
01187 call psmile_error (ierror, 'MPI_Send', &
01188 ierrp, 3, __FILE__, __LINE__ )
01189 return
01190 endif
01191
01192 if ( associated (msg_intersections%intersections)) &
01193 deallocate (msg_intersections%intersections)
01194
01195 if (grid_type == PRISM_Gridless .and. npart > maxpart ) then
01196
01197 #ifdef PRISM_ASSERTION
01198 call psmile_assert (__FILE__, __LINE__, &
01199 "This part of the code does not work. I am sorry.")
01200 #endif
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 endif
01216
01217
01218
01219
01220 if (n_vars > 1) then
01221 #ifdef DEBUG
01222 print *, ' Sending tag ', vartag, ' to destination ', dest
01223 #endif /* DEBUG */
01224 call psmile_bsend (field_list(1,2), (n_vars-1)*nd_field_list, &
01225 MPI_INTEGER, dest, vartag, comm_psmile, &
01226 ierror)
01227 if (ierror /= MPI_SUCCESS) then
01228 ierrp (1) = ierror
01229 ierrp (2) = dest
01230 ierrp (3) = vartag
01231 ierror = PRISM_Error_Send
01232
01233 call psmile_error (ierror, 'MPI_Send', &
01234 ierrp, 3, __FILE__, __LINE__ )
01235 return
01236 endif
01237 endif
01238
01239 end do
01240
01241
01242 local_grid_extents_range(1) = local_grid_extents_range(2) + 1
01243 enddo
01244
01245 end do
01246
01247
01248
01249
01250 do grid_id = 1, Number_of_Grids_allocated
01251 if (mg_gen (grid_id)) then
01252
01253 call psmile_mg_setup (grid_id, range(1, 1, grid_id), &
01254 tol, ierror)
01255 if (ierror /= 0) return
01256
01257 endif
01258 end do
01259
01260
01261
01262
01263
01264 Deallocate (found)
01265 if (num_intersect_allocated > 0) then
01266 Deallocate (dinter, inters, ids, inters_save)
01267 endif
01268
01269
01270
01271 #ifdef VERBOSE
01272 print 9980, trim(ch_id), ierror
01273 call psmile_flushstd
01274 #endif /* VERBOSE */
01275
01276
01277
01278
01279
01280 #ifdef VERBOSE
01281
01282 9990 format (1x, a, ': psmile_find_intersect: local comp_id', i3, ' global comp_id', i3)
01283 9980 format (1x, a, ': psmile_find_intersect: eof ierror =', i3)
01284
01285 #endif /* VERBOSE */
01286
01287 #ifdef DEBUG
01288 9970 format (1x, 'Taskin%In_channel(', i3, '): origin_type', i5, &
01289 ', remote comp id', i4, &
01290 ', global_transi_id', i4, ', remote_transi_id', i8, &
01291 /1x, 'global_dest_grid_id', i4)
01292 9960 format (1x, a, ': psmile_find_intersect: #### Grid is not used for coupling !', &
01293 /1x, 'Introduce test before !!! comp_id', i4, '; grid id', i4)
01294 #endif /* DEBUG */
01295
01296 contains
01297
01298
01299 function grid_types_are_compatible(type1, type2)
01300
01301 use prism, only: prism_gridless
01302
01303 integer, intent(in) :: type1, type2
01304 logical grid_types_are_compatible
01305
01306
01307 grid_types_are_compatible = &
01308 type1 == prism_gridless .eqv. type2 == prism_gridless
01309
01310 end function grid_types_are_compatible
01311
01312 end subroutine PSMILe_Find_intersect