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