XBeach
|
00001 module spaceparams 00002 use spaceparamsdef 00003 use xmpi_module 00004 use mnemmodule 00005 implicit none 00006 save 00007 ! 00008 00009 #ifdef USEMPI 00010 00011 ! This interface an cause complains by memcache because the it is conditional on uninitialized variables. 00012 ! I don't think this is an error 00013 interface space_distribute 00014 module procedure space_distribute_matrix_real8 00015 module procedure space_distribute_matrix_integer 00016 module procedure space_distribute_block_real8 00017 module procedure space_distribute_block_integer 00018 module procedure space_distribute_block4_real8 00019 module procedure space_distribute_vector 00020 module procedure space_distribute_block_vector 00021 end interface space_distribute 00022 00023 interface space_shift_borders 00024 module procedure space_shift_borders_matrix_real8 00025 module procedure space_shift_borders_block_real8 00026 end interface space_shift_borders 00027 00028 interface space_collect 00029 module procedure space_collect_block_real8 00030 module procedure space_collect_block_integer 00031 module procedure space_collect_block4_real8 00032 module procedure space_collect_block4_integer 00033 module procedure space_collect_matrix_real8 00034 module procedure space_collect_matrix_integer 00035 end interface space_collect 00036 00037 #endif 00038 00039 contains 00040 00041 subroutine indextos(s,index,t) 00042 ! 00043 ! given s and index, this subroutine returns in t 00044 ! a pointer to the requested array 00045 ! 00046 use mnemmodule 00047 use logging_module 00048 use spaceparamsdef 00049 implicit none 00050 type (spacepars), intent(in),target :: s 00051 integer, intent(in) :: index 00052 type(arraytype), intent(out) :: t 00053 00054 if (index .lt. 1 .or. index .gt. numvars) then 00055 call writelog('els','(a,i3,a)','invalid index ',index,' in indextos. Program will stop') 00056 call halt_program 00057 endif 00058 00059 select case(index) 00060 include 'indextos.inc' 00061 end select 00062 00063 end subroutine indextos 00064 00065 subroutine index_allocate(s,par,index,choice) 00066 ! allocates, deallocates reallocates in type s, based on index 00067 ! choice: 00068 ! 'a': allocate 00069 ! 'd': deallocate 00070 ! 'r': reallocate 00071 use params 00072 use logging_module 00073 use spaceparamsdef 00074 implicit none 00075 type (spacepars), intent(inout) :: s 00076 type(parameters), intent(in) :: par 00077 integer, intent(in) :: index 00078 character(*) :: choice 00079 00080 ! the .inc files contain code for allocatable entities 00081 ! scalars will be skipped silently 00082 select case(choice(1:1)) 00083 case('a','A') 00084 select case(index) 00085 case default 00086 continue 00087 include 'index_allocate.inc' 00088 end select 00089 case ('d','D') 00090 select case(index) 00091 case default 00092 continue 00093 include 'index_deallocate.inc' 00094 end select 00095 case ('r','R') 00096 select case(index) 00097 case default 00098 continue 00099 include 'index_reallocate.inc' 00100 end select 00101 end select 00102 end subroutine index_allocate 00103 00104 logical function index_allocated(s,index) 00105 use logging_module 00106 use spaceparamsdef 00107 implicit none 00108 type (spacepars), intent(in) :: s 00109 integer, intent(in) :: index 00110 00111 logical :: r 00112 00113 r = .true. ! for scalars: function will return always .true. 00114 select case(index) 00115 case default 00116 continue 00117 include 'index_allocated.inc' 00118 end select 00119 00120 index_allocated = r 00121 00122 end function index_allocated 00123 00124 ! Generated subroutine to allocate the scalars in s 00125 subroutine space_alloc_scalars(s) 00126 use mnemmodule 00127 implicit none 00128 type(spacepars),intent(inout) :: s 00129 00130 include 'space_alloc_scalars.inc' 00131 00132 end subroutine space_alloc_scalars 00133 00134 ! Generated subroutine to allocate all arrays in s 00135 subroutine space_alloc_arrays(s,par) 00136 use mnemmodule 00137 use params 00138 implicit none 00139 type(spacepars),intent(inout) :: s 00140 type(parameters),intent(in) :: par 00141 00142 include 'space_alloc_arrays.inc' 00143 00144 end subroutine space_alloc_arrays 00145 00146 ! Generated subroutine to allocate dummy address for all arrays in s 00147 subroutine space_alloc_arrays_dummies(s,par) 00148 use mnemmodule 00149 use params 00150 implicit none 00151 type(spacepars),intent(inout) :: s 00152 type(parameters),intent(in) :: par 00153 00154 include 'space_alloc_arrays_dummies.inc' 00155 00156 end subroutine space_alloc_arrays_dummies 00157 00158 #ifdef USEMPI 00159 00160 ! copies scalars from sg to sl on xmaster, and distributes 00161 ! them 00162 subroutine space_copy_scalars(sg,sl) 00163 use mnemmodule 00164 implicit none 00165 type(spacepars),intent(inout) :: sg,sl 00166 00167 type(arraytype) :: tg,tl 00168 integer :: j 00169 00170 do j = 1,numvars 00171 call indextos(sg,j,tg) 00172 if (tg%rank .eq. 0) then 00173 call indextos(sl,j,tl) 00174 select case (tg%type) 00175 case('i') 00176 tl%i0 = tg%i0 00177 case('r') 00178 tl%r0 = tg%r0 00179 end select 00180 endif 00181 enddo 00182 end subroutine space_copy_scalars 00183 00184 ! The scalars are needed for allocating the arrays, 00185 ! we distribute them here: 00186 subroutine space_distribute_scalars(sl) 00187 use mnemmodule 00188 use xmpi_module 00189 type (spacepars) :: sl 00190 00191 type (arraytype) :: tl 00192 integer :: i 00193 logical, parameter :: toall = .true. 00194 00195 do i=1,numvars 00196 call indextos(sl,i,tl) 00197 if (tl%rank .eq. 0) then 00198 if (tl%type .eq. 'i') then 00199 call xmpi_bcast(tl%i0,toall) 00200 else 00201 call xmpi_bcast(tl%r0,toall) 00202 endif 00203 endif 00204 enddo 00205 00206 end subroutine space_distribute_scalars 00207 !________________________________________________________________________ 00208 subroutine space_distribute_matrix_real8(sl,a,b,toall) 00209 use xmpi_module 00210 use general_mpi_module 00211 implicit none 00212 type (spacepars), intent(inout) :: sl 00213 real*8, dimension(:,:), intent(in) :: a 00214 real*8, dimension(:,:), intent(out) :: b 00215 include 'space_distribute.inc' 00216 call matrix_distr(a,b,sl%is,sl%lm,sl%js,sl%ln,src,comm) 00217 end subroutine space_distribute_matrix_real8 00218 00219 !________________________________________________________________________ 00220 subroutine space_distribute_matrix_integer(sl,a,b,toall) 00221 use xmpi_module 00222 use general_mpi_module 00223 implicit none 00224 type (spacepars), intent(inout) :: sl 00225 integer, dimension(:,:), intent(in) :: a 00226 integer, dimension(:,:), intent(out) :: b 00227 include 'space_distribute.inc' 00228 00229 call matrix_distr(a,b,sl%is,sl%lm,sl%js,sl%ln,src,comm) 00230 00231 end subroutine space_distribute_matrix_integer 00232 00233 !________________________________________________________________________ 00234 subroutine space_distribute_block_real8(sl,a,b,toall) 00235 use xmpi_module 00236 use general_mpi_module 00237 implicit none 00238 type (spacepars), intent(inout) :: sl 00239 real*8, dimension(:,:,:), intent(in) :: a 00240 real*8, dimension(:,:,:), intent(out) :: b 00241 00242 real*8, dimension(1,1) :: dum 00243 integer :: i 00244 include 'space_distribute.inc' 00245 00246 do i=1,size(b,3) ! assuming that b is allocated on all processes 00247 if (iamsrc) then 00248 call matrix_distr(a(:,:,i),b(:,:,i),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00249 else 00250 call matrix_distr(dum, b(:,:,i),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00251 endif 00252 enddo 00253 00254 end subroutine space_distribute_block_real8 00255 !________________________________________________________________________ 00256 00257 subroutine space_distribute_block_integer(sl,a,b,toall) 00258 use xmpi_module 00259 use general_mpi_module 00260 implicit none 00261 type (spacepars), intent(inout) :: sl 00262 integer, dimension(:,:,:), intent(in) :: a 00263 integer, dimension(:,:,:), intent(out) :: b 00264 00265 integer, dimension(1,1) :: dum 00266 integer :: i 00267 include 'space_distribute.inc' 00268 00269 do i=1,size(b,3) ! assuming that b is allocated on all processes 00270 if(iamsrc) then 00271 call matrix_distr(a(:,:,i),b(:,:,i),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00272 else 00273 call matrix_distr(dum, b(:,:,i),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00274 endif 00275 00276 enddo 00277 00278 end subroutine space_distribute_block_integer 00279 !________________________________________________________________________ 00280 00281 subroutine space_distribute_block4_real8(sl,a,b,toall) 00282 use xmpi_module 00283 use general_mpi_module 00284 implicit none 00285 type (spacepars), intent(inout) :: sl 00286 real*8, dimension(:,:,:,:), intent(in) :: a 00287 real*8, dimension(:,:,:,:), intent(out) :: b 00288 00289 integer :: i,j 00290 real*8, dimension(1,1) :: dum 00291 include 'space_distribute.inc' 00292 00293 do i=1,size(b,3) 00294 do j=1,size(b,4) 00295 if(iamsrc) then 00296 call matrix_distr(a(:,:,i,j),b(:,:,i,j),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00297 else 00298 call matrix_distr(dum, b(:,:,i,j),sl%is,sl%lm,sl%js,sl%ln,src,comm) 00299 endif 00300 enddo 00301 enddo 00302 00303 end subroutine space_distribute_block4_real8 00304 !________________________________________________________________________ 00305 00306 subroutine space_distribute_vector(xy,sl,a,b,toall) 00307 use xmpi_module 00308 use general_mpi_module 00309 implicit none 00310 ! Not sure what this xy is doing here. 00311 ! Ok, the master process holds a vector of length ny+1 or nx+1 00312 ! This vector will be distributed among all processes. 00313 ! if xy .eq. 'x', the distribution is done according 00314 ! to the values in is and lm, i.e. the global vector 00315 ! has a size equal to the size of the first dimension of the 00316 ! global area: nx+1. 00317 ! In the other case, the distribution is done according to 00318 ! the values in js and ln, i.e. the global vector has a size 00319 ! equal to the second dimension of the global area: ny+1 00320 ! 00321 character, intent(in) :: xy 00322 type (spacepars), intent(inout), target :: sl 00323 real*8, dimension(:), intent(in) :: a 00324 real*8, dimension(:), intent(out) :: b 00325 00326 integer, dimension(:), pointer :: ijs,lmn 00327 include 'space_distribute.inc' 00328 00329 if(xy .eq.'x') then 00330 ijs => sl%is 00331 lmn => sl%lm 00332 else 00333 ijs => sl%js 00334 lmn => sl%ln 00335 endif 00336 call vector_distr(a,b,ijs,lmn,src,comm) 00337 00338 end subroutine space_distribute_vector 00339 !________________________________________________________________________ 00340 00341 subroutine space_distribute_block_vector(xy,sl,a,b,toall) 00342 use xmpi_module 00343 use general_mpi_module 00344 implicit none 00345 character, intent(in) :: xy 00346 type (spacepars), intent(in) :: sl 00347 real*8, dimension(:,:), intent(in) :: a 00348 real*8, dimension(:,:), intent(out) :: b 00349 00350 ! integer :: i 00351 include 'space_distribute.inc' 00352 00353 !DF do i=1,sl%ntheta 00354 ! do i=1,size(b,2) 00355 ! call space_distribute(xy,sl,a(:,i),b(:,i)) 00356 ! enddo 00357 00358 select case(xy) 00359 case('y') 00360 call vector_distr(a,b,sl%js,sl%ln,src,comm) 00361 case default 00362 print *,'error in space_distribute_block_vector, other than "y" not tested' 00363 call xmpi_abort() 00364 end select 00365 00366 end subroutine space_distribute_block_vector 00367 !________________________________________________________________________ 00368 00369 00370 subroutine space_distribute_space(sg,sl,par) 00371 use xmpi_module 00372 use logging_module 00373 use general_mpi_module 00374 use params 00375 use mnemmodule 00376 00377 implicit none 00378 type(spacepars), intent(inout) :: sg 00379 type(spacepars), intent(inout) :: sl 00380 type(parameters) :: par 00381 00382 integer :: i,j,lid,eid, wid 00383 real*8, pointer, dimension(:) :: vectorg, vectorl 00384 type (arraytype) :: tg, tl 00385 00386 logical, parameter :: toall = .true. 00387 integer, parameter :: nbord = 2 00388 character(1000) :: txt 00389 00390 ! 00391 ! This subroutine takes care that all contents of the global 00392 ! space is distributed to the local space. 00393 ! 00394 00395 ! allocate scalars 00396 00397 call space_alloc_scalars(sl) 00398 00399 ! copy scalars to sl, only on master 00400 ! distributing will take place later 00401 00402 00403 if(xmaster) then 00404 call space_copy_scalars(sg,sl) 00405 endif 00406 00407 ! copy scalars to all processes, nx and ny will be adapted later 00408 call space_distribute_scalars(sl) 00409 call space_distribute_scalars(sg) 00410 00411 ! Also, the isleft, isright, istop and isbot logicals from 00412 ! the xmpi module are put in sg and sl. 00413 ! 00414 00415 ! 00416 ! Distribute is,js,ln,lm,isleft,isright,istop,isbot 00417 ! 00418 00419 if(xmaster) then 00420 allocate(sg%is(xmpi_size)) 00421 allocate(sg%js(xmpi_size)) 00422 allocate(sg%lm(xmpi_size)) 00423 allocate(sg%ln(xmpi_size)) 00424 allocate(sg%isleft(xmpi_size)) 00425 allocate(sg%isright(xmpi_size)) 00426 allocate(sg%istop(xmpi_size)) 00427 allocate(sg%isbot(xmpi_size)) 00428 endif 00429 00430 00431 allocate(sl%is(xmpi_size)) 00432 allocate(sl%js(xmpi_size)) 00433 allocate(sl%lm(xmpi_size)) 00434 allocate(sl%ln(xmpi_size)) 00435 allocate(sl%isleft(xmpi_size)) 00436 allocate(sl%isright(xmpi_size)) 00437 allocate(sl%istop(xmpi_size)) 00438 allocate(sl%isbot(xmpi_size)) 00439 00440 if(xmaster) then 00441 call det_submatrices(sg%nx+1, sg%ny+1, xmpi_m, xmpi_n, & 00442 sg%is, sg%lm, sg%js, sg%ln, & 00443 sg%isleft, sg%isright, sg%istop, sg%isbot) 00444 call writelog('l','','--------------------------------') 00445 call writelog('l','','MPI implementation: ') 00446 call writelog('sl','','Distribution of matrix on processors') 00447 call writelog('sl','',' proc is lm js ln') 00448 do i=1,xmpi_size 00449 call writelog('sl','(i5,i5,i5,i5,i5)',i-1,sg%is(i),sg%lm(i),sg%js(i),sg%ln(i)) 00450 enddo 00451 call writelog('ls','',' proc left right top bot') 00452 do i=1,xmpi_size 00453 call writelog('ls','',i-1,sg%isleft(i),sg%isright(i),sg%istop(i),sg%isbot(i)) 00454 enddo 00455 call writelog('l','','--------------------------------') 00456 endif 00457 00458 ! determine the computational regions, i.e. the parts of the matrices 00459 ! that are computed in the processes. 00460 ! In general, the 2 borders left, right, top and bottom are not 00461 ! computed but received from the neighbours. 00462 ! Exceptions for the rows and colomns of left, right, top or 00463 ! bottom processes. 00464 ! 00465 ! icgs, icge: start and end indices in global coordinates 1st dimension 00466 ! jcgs: jcge: start and end indices in global coordinates 2nd dimension 00467 ! icls, icle: start and end indices in local coordinates 1st dimension 00468 ! jcls, jcle: start and end indices in local coordinates 2nd dimension 00469 00470 if (xmaster) then 00471 allocate (sg%icgs(xmpi_size)) 00472 allocate (sg%icge(xmpi_size)) 00473 allocate (sg%jcgs(xmpi_size)) 00474 allocate (sg%jcge(xmpi_size)) 00475 allocate (sg%icls(xmpi_size)) 00476 allocate (sg%icle(xmpi_size)) 00477 allocate (sg%jcls(xmpi_size)) 00478 allocate (sg%jcle(xmpi_size)) 00479 endif 00480 00481 allocate (sl%icgs(xmpi_size)) 00482 allocate (sl%icge(xmpi_size)) 00483 allocate (sl%jcgs(xmpi_size)) 00484 allocate (sl%jcge(xmpi_size)) 00485 allocate (sl%icls(xmpi_size)) 00486 allocate (sl%icle(xmpi_size)) 00487 allocate (sl%jcls(xmpi_size)) 00488 allocate (sl%jcle(xmpi_size)) 00489 00490 if (xmaster) then 00491 do i = 1,xmpi_size 00492 sg%icgs(i) = sg%is(i) + nbord 00493 sg%icge(i) = sg%is(i) + sg%lm(i) - 1 - nbord 00494 sg%jcgs(i) = sg%js(i) + nbord 00495 sg%jcge(i) = sg%js(i) + sg%ln(i) - 1 - nbord 00496 sg%icls(i) = nbord + 1 00497 sg%icle(i) = sg%lm(i) - nbord 00498 sg%jcls(i) = nbord + 1 00499 sg%jcle(i) = sg%ln(i) - nbord 00500 00501 if (sg%istop(i)) then 00502 sg%icgs(i) = sg%icgs(i) - nbord 00503 sg%icls(i) = sg%icls(i) - nbord 00504 endif 00505 00506 if (sg%isbot(i)) then 00507 sg%icge(i) = sg%icge(i) + nbord 00508 sg%icle(i) = sg%icle(i) + nbord 00509 endif 00510 00511 if (sg%isleft(i)) then 00512 sg%jcgs(i) = sg%jcgs(i) - nbord 00513 sg%jcls(i) = sg%jcls(i) - nbord 00514 endif 00515 00516 if (sg%isright(i)) then 00517 sg%jcge(i) = sg%jcge(i) + nbord 00518 sg%jcle(i) = sg%jcle(i) + nbord 00519 endif 00520 00521 enddo 00522 endif 00523 00524 if (xmaster) then 00525 sl%is = sg%is 00526 sl%js = sg%js 00527 sl%lm = sg%lm 00528 sl%ln = sg%ln 00529 sl%isleft = sg%isleft 00530 sl%isright = sg%isright 00531 sl%istop = sg%istop 00532 sl%isbot = sg%isbot 00533 00534 sl%icgs = sg%icgs 00535 sl%icge = sg%icge 00536 sl%jcgs = sg%jcgs 00537 sl%jcge = sg%jcge 00538 sl%icls = sg%icls 00539 sl%icle = sg%icle 00540 sl%jcls = sg%jcls 00541 sl%jcle = sg%jcle 00542 endif 00543 00544 call xmpi_bcast(sl%is,toall) 00545 call xmpi_bcast(sl%js,toall) 00546 call xmpi_bcast(sl%lm,toall) 00547 call xmpi_bcast(sl%ln,toall) 00548 call xmpi_bcast(sl%isleft,toall) 00549 call xmpi_bcast(sl%isright,toall) 00550 call xmpi_bcast(sl%istop,toall) 00551 call xmpi_bcast(sl%isbot,toall) 00552 00553 call xmpi_bcast(sl%icgs,toall) 00554 call xmpi_bcast(sl%icge,toall) 00555 call xmpi_bcast(sl%jcgs,toall) 00556 call xmpi_bcast(sl%jcge,toall) 00557 call xmpi_bcast(sl%icls,toall) 00558 call xmpi_bcast(sl%icle,toall) 00559 call xmpi_bcast(sl%jcls,toall) 00560 call xmpi_bcast(sl%jcle,toall) 00561 00562 if (xmaster) then 00563 call writelog('l','','--------------------------------') 00564 call writelog('sl','','computational domains on processors') 00565 call writelog('sl','',' proc icgs icge jcgs jcge icls icle jcls jcle') 00566 do i=1,xmpi_size 00567 write(txt,'(9i7)')i-1,sg%icgs(i),sg%icge(i),sg%jcgs(i),sg%jcge(i), & 00568 sg%icls(i),sg%icle(i),sg%jcls(i),sg%jcle(i) 00569 call writelog('sl','',txt) 00570 enddo 00571 call writelog('l','','--------------------------------') 00572 endif 00573 00574 ! 00575 ! compute the values for local nx and ny 00576 ! 00577 00578 if(xcompute) then 00579 sl%nx = sl%lm(xmpi_rank+1) - 1 00580 sl%ny = sl%ln(xmpi_rank+1) - 1 00581 endif 00582 00583 00584 ! 00585 ! allocate all arrays in sl 00586 ! 00587 00588 call space_alloc_arrays(sl,par) 00589 00590 ! for each variable in sg, find out how to distribute it 00591 ! and distribute 00592 ! 00593 00594 do i = 1,numvars 00595 00596 call indextos(sg,i,tg) 00597 call indextos(sl,i,tl) 00598 select case (tl%btype) 00599 case('b') ! have to broadcast this 00600 select case (tl%type) 00601 case('i') 00602 select case(tl%rank) 00603 case(0) ! do nothing, scalars are already in place 00604 ! Have to be prudent here. all scalars are broadcasted, exept nx 00605 ! and ny 00606 !if (tl%name .ne. mnem_nx .and. tl%name .ne. mnem_ny) then 00607 ! if(xmaster) then 00608 ! tl%i0 = tg%i0 00609 ! endif 00610 ! call xmpi_bcast(tl%i0) 00611 !endif 00612 case(1) 00613 if(xmaster) then 00614 tl%i1 = tg%i1 00615 endif 00616 call xmpi_bcast(tl%i1,toall) 00617 case(2) ! wwvv : try to fix error with integer pdish 00618 if(xmaster) then 00619 tl%i2 = tg%i2 00620 endif 00621 call xmpi_bcast(tl%i2,toall) 00622 case default 00623 goto 100 00624 end select ! rank 00625 case('r') 00626 select case(tl%rank) 00627 case(0) ! do nothing here, scalars are already in place 00628 ! Have to be prudent here. all scalars are broadcasted, exept nx 00629 ! and ny 00630 ! here only real*8 is broadcasted, so no check necessary here 00631 !if(xmaster) then 00632 ! tl%r0 = tg%r0 00633 !endif 00634 !call xmpi_bcast(tl%r0) 00635 case(1) 00636 if(xmaster) then 00637 tl%r1 = tg%r1 00638 endif 00639 call xmpi_bcast(tl%r1,toall) 00640 case(2) 00641 if(xmaster) then 00642 tl%r2 = tg%r2 00643 endif 00644 call xmpi_bcast(tl%r2,toall) 00645 case default 00646 goto 100 00647 end select ! rank 00648 case default 00649 goto 100 00650 end select ! type 00651 case('d') ! have to distribute this 00652 select case(tl%type) 00653 case ('i') 00654 select case(tl%rank) 00655 case(1) ! wwvv 2013: superfluous, there is a default case 00656 goto 100 00657 case(2) 00658 call space_distribute(sl,tg%i2,tl%i2) 00659 case(3) 00660 call space_distribute(sl,tg%i3,tl%i3) 00661 case default 00662 goto 100 00663 end select ! rank 00664 case ('r') 00665 select case(tl%rank) 00666 case(1) 00667 ! Robert: these don't exist anymore? 00668 ! case(mnem_xz,mnem_xu) 00669 ! call space_distribute_vector('x',sl,tg%r1,tl%r1) 00670 ! case(mnem_yz, mnem_yv, mnem_bi) 00671 select case(tl%name) 00672 case(mnem_bi) 00673 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00674 case(mnem_runup) 00675 ! Not sure why vector expects a name.... 00676 ! This name is x or y, it relates to the length of the vector. 00677 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00678 case(mnem_hrunup) 00679 ! Not sure why vector expects a name.... 00680 ! This name is x or y, it relates to the length of the vector. 00681 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00682 case(mnem_xhrunup) 00683 ! Not sure why vector expects a name.... 00684 ! This name is x or y, it relates to the length of the vector. 00685 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00686 case(mnem_strucslope) 00687 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00688 case(mnem_istruct) 00689 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00690 case(mnem_iwl) 00691 call space_distribute_vector('y',sl,tg%r1,tl%r1) 00692 case default 00693 goto 100 00694 end select 00695 case(2) 00696 call space_distribute(sl,tg%r2,tl%r2) 00697 case(3) 00698 call space_distribute(sl,tg%r3,tl%r3) 00699 case(4) 00700 call space_distribute(sl,tg%r4,tl%r4) 00701 case default 00702 continue 00703 end select ! rank 00704 case default 00705 goto 100 00706 end select ! type 00707 case('2') 00708 ! the umean case 00709 ! dimension 2,s%ny+1 00710 if(xmaster) then 00711 allocate(vectorg(sg%ny+1)) 00712 else 00713 allocate(vectorg(1)) 00714 vectorg = 0 00715 endif 00716 allocate(vectorl(sl%ny+1)) 00717 ! Let's keep this 2 case explicit. (because tg%r2 is only known on master) 00718 ! This one is distributed as 2 vectors. 00719 do j=1,2 00720 if (xmaster) then 00721 vectorg = tg%r2(j,:) 00722 endif 00723 call space_distribute("y", sl,vectorg,vectorl) 00724 tl%r2(j,:) = vectorl 00725 enddo 00726 if(xmaster) then 00727 deallocate(vectorg) 00728 endif 00729 deallocate(vectorl) 00730 case default 00731 goto 100 00732 end select ! btype 00733 enddo ! numvars 00734 return 00735 00736 100 continue 00737 call writelog('sel','',xmpi_rank,': Error in space_distribute_space, trying to distribute:') 00738 call get_logfileid(lid,eid, wid) 00739 call printvar(tl,lid,eid, wid) 00740 call halt_program 00741 return 00742 00743 end subroutine space_distribute_space 00744 00745 subroutine space_who_has(sl,i,j,p) 00746 ! determine which process contains element(i,j) 00747 ! sl: local spacepars 00748 ! i,j: global indices 00749 ! p: process in xmpi_ocomm which contains the element 00750 00751 ! icgs, icge: start and end indices in global coordinates 1st dimension 00752 ! jcgs: jcge: start and end indices in global coordinates 2nd dimension 00753 implicit none 00754 type(spacepars), intent(in) :: sl 00755 integer, intent(in) :: i,j 00756 integer, intent(out) :: p 00757 00758 integer k 00759 00760 p = -123 00761 00762 do k = 1,xmpi_size 00763 if (i .ge. sl%icgs(k) .and. i .le. sl%icge(k) .and. & 00764 & j .ge. sl%jcgs(k) .and. j .le. sl%jcge(k)) then 00765 p = xmpi_rank_to_orank(k-1) 00766 exit 00767 endif 00768 enddo 00769 00770 end subroutine space_who_has 00771 00772 subroutine space_global_to_local(sl,ig,jg,il,jl) 00773 ! given global coordinates (ig,jg), compute local coordinates (il,jl) 00774 implicit none 00775 type(spacepars), intent(in) :: sl 00776 integer, intent(in) :: ig,jg 00777 integer, intent(out) :: il,jl 00778 00779 il = ig - sl%is(xmpi_rank+1) + 1 00780 jl = jg - sl%js(xmpi_rank+1) + 1 00781 00782 end subroutine space_global_to_local 00783 00784 subroutine space_local_to_global(sl,il,jl,ig,jg) 00785 ! given local coordinates (il,jl), compute global coordinates (ig,jg) 00786 implicit none 00787 type(spacepars), intent(in) :: sl 00788 integer, intent(in) :: il,jl 00789 integer, intent(out) :: ig,jg 00790 00791 ig = il + sl%is(xmpi_rank+1) - 1 00792 jg = jl + sl%js(xmpi_rank+1) - 1 00793 00794 end subroutine space_local_to_global 00795 00796 subroutine space_shift_borders_matrix_real8(a) 00797 use general_mpi_module 00798 use xmpi_module 00799 implicit none 00800 real*8, intent(inout),dimension(:,:) :: a 00801 call shift_borders_matrix_real8(a,xmpi_left,xmpi_right, & 00802 xmpi_top,xmpi_bot,xmpi_comm) 00803 end subroutine space_shift_borders_matrix_real8 00804 00805 subroutine space_shift_borders_block_real8(a) 00806 use general_mpi_module 00807 use xmpi_module 00808 implicit none 00809 real*8, intent(inout),dimension(:,:,:) :: a 00810 00811 integer i 00812 00813 do i=1,size(a,3) 00814 call shift_borders_matrix_real8(a(:,:,i),xmpi_left,xmpi_right,& 00815 xmpi_top,xmpi_bot,xmpi_comm) 00816 enddo 00817 end subroutine space_shift_borders_block_real8 00818 00819 ! 00820 ! wwvv a subtle point with the collect subroutines: the second 00821 ! argument: the matrix wherein the submatrices are to be collected, 00822 ! does not have to be available on the non-master processes, so 00823 ! the dimensions are not defined. 00824 ! The third argument is always defined, on master and non-master 00825 ! processes, so its dimensions (notably the 3rd in the block subroutines 00826 ! are available 00827 ! 00828 ! parameters of the space_collect routines: 00829 ! s: spacepars: LOCAL s 00830 ! a: output: in this matrix the submatrices are collected 00831 ! b: input: the local submatrix 00832 00833 subroutine space_collect_block_real8(s,a,b) 00834 use general_mpi_module 00835 use xmpi_module 00836 implicit none 00837 type(spacepars), intent(in) :: s 00838 real*8, dimension(:,:,:), intent(out) :: a 00839 real*8, dimension(:,:,:), intent(in) :: b 00840 00841 integer i 00842 real*8, dimension(1,1) :: dum 00843 00844 do i = 1,size(b,3) 00845 if (xomaster) then 00846 call matrix_coll(a(:,:,i),b(:,:,i),s%is,s%lm,s%js,s%ln, & 00847 s%isleft,s%isright,s%istop,s%isbot, & 00848 xmpi_omaster,xmpi_ocomm) 00849 else 00850 call matrix_coll(dum, b(:,:,i),s%is,s%lm,s%js,s%ln, & 00851 s%isleft,s%isright,s%istop,s%isbot, & 00852 xmpi_omaster,xmpi_ocomm) 00853 endif 00854 enddo 00855 00856 end subroutine space_collect_block_real8 00857 00858 subroutine space_collect_block_integer(s,a,b) 00859 use general_mpi_module 00860 use xmpi_module 00861 implicit none 00862 type(spacepars), intent(in) :: s 00863 integer, dimension(:,:,:), intent(out) :: a 00864 integer, dimension(:,:,:), intent(in) :: b 00865 00866 integer i 00867 00868 !real*8, dimension(:,:,:), allocatable :: ra,rb 00869 ! wwvv changed this into 00870 ! wwvv huh? TODO 00871 integer, dimension(:,:,:), allocatable :: ra,rb 00872 integer :: m,n,o 00873 integer, dimension(1,1) :: dum 00874 00875 m = size(b,1) 00876 n = size(b,2) 00877 o = size(b,3) 00878 00879 allocate(rb(m,n,o)) 00880 00881 if (xomaster) then 00882 m = size(a,1) 00883 n = size(a,2) 00884 o = size(a,3) 00885 allocate(ra(m,n,o)) 00886 else 00887 allocate(ra(1,1,1)) 00888 endif 00889 00890 rb = b 00891 00892 do i = 1,o 00893 if(xomaster) then 00894 call matrix_coll(ra(:,:,i),rb(:,:,i),s%is,s%lm,s%js,s%ln, & 00895 s%isleft,s%isright,s%istop,s%isbot, & 00896 xmpi_omaster,xmpi_ocomm) 00897 else 00898 call matrix_coll(dum, rb(:,:,i),s%is,s%lm,s%js,s%ln, & 00899 s%isleft,s%isright,s%istop,s%isbot, & 00900 xmpi_omaster,xmpi_ocomm) 00901 endif 00902 enddo 00903 00904 if (xomaster) then 00905 a = ra 00906 endif 00907 00908 deallocate(ra,rb) 00909 00910 end subroutine space_collect_block_integer 00911 00912 subroutine space_collect_block4_real8(s,a,b) 00913 use general_mpi_module 00914 use xmpi_module 00915 implicit none 00916 type(spacepars), intent(in) :: s 00917 real*8, dimension(:,:,:,:), intent(out) :: a 00918 real*8, dimension(:,:,:,:), intent(in) :: b 00919 00920 integer i,j 00921 real*8, dimension(1,1) :: dum 00922 00923 do j = 1,size(b,4) 00924 do i = 1,size(b,3) 00925 if (xomaster) then 00926 call matrix_coll(a(:,:,i,j),b(:,:,i,j),s%is,s%lm,s%js,s%ln, & 00927 s%isleft,s%isright,s%istop,s%isbot, & 00928 xmpi_omaster,xmpi_ocomm) 00929 else 00930 call matrix_coll(dum, b(:,:,i,j),s%is,s%lm,s%js,s%ln, & 00931 s%isleft,s%isright,s%istop,s%isbot, & 00932 xmpi_omaster,xmpi_ocomm) 00933 endif 00934 enddo 00935 enddo 00936 00937 end subroutine space_collect_block4_real8 00938 00939 subroutine space_collect_block4_integer(s,a,b) 00940 use general_mpi_module 00941 use xmpi_module 00942 implicit none 00943 type(spacepars), intent(in) :: s 00944 integer, dimension(:,:,:,:), intent(out) :: a 00945 integer, dimension(:,:,:,:), intent(in) :: b 00946 00947 integer i,j 00948 integer :: dum(1,1) 00949 00950 do j = 1,size(b,4) 00951 do i = 1,size(b,3) 00952 if(xomaster) then 00953 call matrix_coll(a(:,:,i,j),b(:,:,i,j),s%is,s%lm,s%js,s%ln, & 00954 s%isleft,s%isright,s%istop,s%isbot, & 00955 xmpi_omaster,xmpi_ocomm) 00956 else 00957 call matrix_coll(dum, b(:,:,i,j),s%is,s%lm,s%js,s%ln, & 00958 s%isleft,s%isright,s%istop,s%isbot, & 00959 xmpi_omaster,xmpi_ocomm) 00960 endif 00961 enddo 00962 enddo 00963 00964 end subroutine space_collect_block4_integer 00965 00966 subroutine space_collect_matrix_real8(s,a,b) 00967 use general_mpi_module 00968 use xmpi_module 00969 implicit none 00970 type(spacepars), intent(in) :: s 00971 real*8, dimension(:,:), intent(out) :: a 00972 real*8, dimension(:,:), intent(in) :: b 00973 00974 call matrix_coll(a,b,s%is,s%lm,s%js,s%ln, & 00975 s%isleft,s%isright,s%istop,s%isbot, & 00976 xmpi_omaster,xmpi_ocomm) 00977 00978 end subroutine space_collect_matrix_real8 00979 00980 subroutine space_collect_vector_real8(loc,s,a,b) 00981 use general_mpi_module 00982 use xmpi_module 00983 implicit none 00984 type(spacepars), intent(in) :: s 00985 real*8, dimension(:,:), intent(out) :: a 00986 real*8, dimension(:,:), intent(in) :: b 00987 character*1, intent(in) :: loc 00988 select case (loc) 00989 case ('t') 00990 call matrix_coll(a,b,s%is,s%lm,s%js,s%ln, & 00991 s%isleft,s%isright,s%istop,s%isbot, & 00992 xmpi_omaster,xmpi_ocomm) 00993 case ('b') 00994 call matrix_coll(a,b,s%is,s%lm,s%js,s%ln, & 00995 s%isleft,s%isright,s%istop,s%isbot, & 00996 xmpi_omaster,xmpi_ocomm) 00997 case ('l') 00998 call matrix_coll(a,b,s%is,s%lm,s%js,s%ln, & 00999 s%isleft,s%isright,s%istop,s%isbot, & 01000 xmpi_omaster,xmpi_ocomm) 01001 case ('r') 01002 call matrix_coll(a,b,s%is,s%lm,s%js,s%ln, & 01003 s%isleft,s%isright,s%istop,s%isbot, & 01004 xmpi_omaster,xmpi_ocomm) 01005 end select 01006 01007 end subroutine space_collect_vector_real8 01008 01009 subroutine space_collect_matrix_integer(s,a,b) 01010 use general_mpi_module 01011 use xmpi_module 01012 implicit none 01013 type(spacepars), intent(in) :: s 01014 integer, dimension(:,:), intent(out) :: a 01015 integer, dimension(:,:), intent(in) :: b 01016 01017 ! not used often, so we convert the integers to real*8, 01018 ! collect and convert back. 01019 ! if this routine becomes heavily used, than a special 01020 ! matrix_coll has to be made. (Now we understand why 01021 ! C++ has templates) 01022 01023 !real*8, dimension(:,:), allocatable :: ra,rb 01024 ! wwvv changed this into 01025 integer, dimension(:,:), allocatable :: ra,rb 01026 01027 integer :: m,n 01028 01029 m = size(b,1) 01030 n = size(b,2) 01031 01032 allocate(rb(m,n)) 01033 01034 if (xomaster) then 01035 m = size(a,1) 01036 n = size(a,2) 01037 allocate(ra(m,n)) 01038 else 01039 allocate(ra(1,1)) 01040 endif 01041 01042 rb = b 01043 01044 call matrix_coll(ra,rb,s%is,s%lm,s%js,s%ln, & 01045 s%isleft,s%isright,s%istop,s%isbot, & 01046 xmpi_omaster,xmpi_ocomm) 01047 01048 if (xomaster) then 01049 a = ra 01050 endif 01051 01052 deallocate(ra,rb) 01053 01054 end subroutine space_collect_matrix_integer 01055 01056 #endif 01057 01058 01059 #ifdef USEMPI 01060 ! 01061 ! collects data from processes in master 01062 ! using the index number of the variable to be 01063 ! collected 01064 ! 01065 subroutine space_collect_index(sg,sl,par,index) 01066 use xmpi_module 01067 use mnemmodule 01068 use logging_module 01069 use params 01070 type(spacepars) :: sg 01071 type(spacepars), intent(in) :: sl 01072 type(parameters) :: par 01073 integer, intent(in) :: index 01074 01075 integer :: lid,eid, wid,ierr 01076 type(arraytype) :: tg,tl 01077 logical :: iscollected 01078 01079 #ifdef USEMPE 01080 call MPE_Log_event(event_coll_start,0,'cstart') 01081 #endif 01082 01083 if (xomaster) then 01084 iscollected = sg%collected(index) 01085 endif 01086 01087 call MPI_Bcast(iscollected,1,MPI_LOGICAL,xmpi_omaster,xmpi_ocomm,ierr) 01088 01089 ! return if this alreay has been collected 01090 if(iscollected) then 01091 return 01092 endif 01093 01094 #ifdef USEMPI 01095 if (xomaster) then 01096 call index_allocate(sg,par,index,'r') 01097 endif 01098 #endif 01099 01100 call indextos(sl,index,tl) 01101 call indextos(sg,index,tg) 01102 01103 select case(tl%type) 01104 case('i') 01105 select case(tl%rank) 01106 case(0) ! nothing to do 01107 case(2) 01108 call space_collect(sl, tg%i2, tl%i2) 01109 case(3) 01110 call space_collect(sl, tg%i3, tl%i3) 01111 case default ! case 1 and 4 are not handled 01112 goto 100 01113 end select ! rank 01114 case('r') 01115 select case(tl%rank) 01116 case(0) ! nothing to do 01117 case(2) 01118 !if (tl%name .eq. mnem_umean) then 01119 ! goto 100 01120 !endif 01121 call space_collect(sl,tg%r2,tl%r2) 01122 case(3) 01123 call space_collect(sl,tg%r3,tl%r3) 01124 case(4) 01125 call space_collect(sl,tg%r4,tl%r4) 01126 case default 01127 end select ! rank 01128 case default 01129 end select ! type 01130 01131 #ifdef USEMPE 01132 call MPE_Log_event(event_coll_start,0,'cend') 01133 #endif 01134 01135 sg%collected(index) = .true. 01136 return 01137 01138 100 continue 01139 call writelog('lse','','Problem in space_collect_index with variable ',trim(tg%name ) ) 01140 call writelog('lse','','Don''t know how to collect that on the masternode') 01141 call get_logfileid(lid,eid, wid) 01142 call printvar(tl,lid,eid, wid) 01143 call halt_program 01144 01145 end subroutine space_collect_index 01146 01147 subroutine space_collect_mnem(sg,sl,par,mnem) 01148 use params 01149 type(spacepars) :: sg 01150 type(spacepars), intent(in) :: sl 01151 type(parameters) :: par 01152 character(*) :: mnem 01153 01154 integer index 01155 index = chartoindex(mnem) 01156 call space_collect_index(sg,sl,par,index) 01157 01158 end subroutine space_collect_mnem 01159 #endif 01160 01161 subroutine gridprops (s) 01162 01163 IMPLICIT NONE 01164 01165 type(spacepars),target :: s 01166 ! Temporary local arrays and variables 01167 integer :: i, j 01168 real*8,dimension(:,:),allocatable :: xc ! x-coordinate c-points 01169 real*8,dimension(:,:),allocatable :: yc ! y-coordinate c-points 01170 real*8 :: dsdnu ! surface of cell centered around u-point 01171 real*8 :: dsdnv ! surface of cell centered around v-point 01172 real*8 :: dsdnz ! surface of cell centered around z-point 01173 real*8 :: x1,y1,x2,y2,x3,y3,x4,y4 01174 01175 allocate (xc(s%nx+1,s%ny+1)) 01176 allocate (yc(s%nx+1,s%ny+1)) 01177 01178 ! x and y were read in grid_bathy.f90 (initialize.f90) and can be either (cartesian) world coordinates or 01179 ! XBeach coordinates (xori, yori and alfa are nonzero). Here x and y are transformed to cartesian world coordinates. 01180 ! XBeach performs all computations (after implementation of curvi-lineair option) world coordinate grid. 01181 01182 ! world coordinates of z-points 01183 s%xz=s%xori+s%x*cos(s%alfa)-s%y*sin(s%alfa) 01184 s%yz=s%yori+s%x*sin(s%alfa)+s%y*cos(s%alfa) 01185 01186 ! world coordinates of u-points 01187 do j=1,s%ny+1 01188 do i=1,s%nx 01189 s%xu(i,j)=.5d0*(s%xz(i,j)+s%xz(i+1,j)) 01190 s%yu(i,j)=.5d0*(s%yz(i,j)+s%yz(i+1,j)) 01191 enddo 01192 s%xu(s%nx+1,j)=1.5d0*s%xz(s%nx+1,j)-0.5d0*s%xz(s%nx,j) 01193 s%yu(s%nx+1,j)=1.5d0*s%yz(s%nx+1,j)-0.5d0*s%yz(s%nx,j) 01194 enddo 01195 01196 ! world coordinates of v-points 01197 if (s%ny>0) then 01198 do i=1,s%nx+1 01199 do j=1,s%ny 01200 s%xv(i,j)=.5d0*(s%xz(i,j)+s%xz(i,j+1)) 01201 s%yv(i,j)=.5d0*(s%yz(i,j)+s%yz(i,j+1)) 01202 enddo 01203 s%xv(i,s%ny+1)=1.5d0*s%xz(i,s%ny+1)-0.5d0*s%xz(i,s%ny) 01204 s%yv(i,s%ny+1)=1.5d0*s%yz(i,s%ny+1)-0.5d0*s%yz(i,s%ny) 01205 enddo 01206 else 01207 s%xv=s%xz 01208 s%yv=s%yz 01209 endif 01210 01211 ! world coordinates of corner points 01212 if (s%ny>0) then 01213 do j=1,s%ny 01214 do i=1,s%nx 01215 xc(i,j)=.25d0*(s%xz(i,j)+s%xz(i+1,j)+s%xz(i,j+1)+s%xz(i+1,j+1)) 01216 yc(i,j)=.25d0*(s%yz(i,j)+s%yz(i+1,j)+s%yz(i,j+1)+s%yz(i+1,j+1)) 01217 enddo 01218 xc(s%nx+1,j)=0.5d0*(s%xu(s%nx+1,j)+s%xu(s%nx+1,j+1)) 01219 yc(s%nx+1,j)=0.5d0*(s%yu(s%nx+1,j)+s%yu(s%nx+1,j+1)) 01220 enddo 01221 do i=1,s%nx 01222 xc(i,s%ny+1)=0.5d0*(s%xv(i,s%ny+1)+s%xv(i+1,s%ny+1)) 01223 yc(i,s%ny+1)=0.5d0*(s%yv(i,s%ny+1)+s%yv(i+1,s%ny+1)) 01224 enddo 01225 xc(s%nx+1,s%ny+1)=1.5d0*s%xu(s%nx+1,s%ny+1)-0.5*s%xu(s%nx,s%ny+1) 01226 yc(s%nx+1,s%ny+1)=1.5d0*s%yu(s%nx+1,s%ny+1)-0.5*s%yu(s%nx,s%ny+1) 01227 else 01228 xc=s%xu 01229 yc=s%yu 01230 endif 01231 01232 ! s%dsu 01233 01234 do j=1,s%ny+1 01235 do i=1,s%nx 01236 s%dsu(i,j)=((s%xz(i+1,j)-s%xz(i,j))**2+(s%yz(i+1,j)-s%yz(i,j))**2)**(0.5d0) 01237 enddo 01238 s%dsu(s%nx+1,j)=s%dsu(s%nx,j) 01239 enddo 01240 01241 ! s%dsz 01242 01243 do j=1,s%ny+1 01244 do i=2,s%nx+1 01245 s%dsz(i,j)=((s%xu(i,j)-s%xu(i-1,j))**2+(s%yu(i,j)-s%yu(i-1,j))**2)**(0.5d0) 01246 enddo 01247 s%dsz(1,j)=s%dsz(2,j) ! Robert -> was i=s%nx+1 (calculated in loop), so i=1 more likely 01248 enddo 01249 01250 ! s%dsv 01251 01252 if (s%ny>0) then 01253 do j=1,s%ny+1 01254 do i=2,s%nx+1 01255 s%dsv(i,j)=((xc(i,j)-xc(i-1,j))**2+(yc(i,j)-yc(i-1,j))**2)**(0.5d0) 01256 enddo 01257 s%dsv(1,j)=s%dsv(2,j) ! Robert, need to have this for wave advec 01258 s%dsv(s%nx+1,j)=s%dsv(s%nx,j) 01259 enddo 01260 else 01261 s%dsv=s%dsz 01262 endif 01263 01264 ! s%dsc 01265 01266 if (s%ny>0) then 01267 do j=1,s%ny+1 01268 do i=1,s%nx 01269 s%dsc(i,j)=((s%xv(i+1,j)-s%xv(i,j))**2+(s%yv(i+1,j)-s%yv(i,j))**2)**(0.5d0) 01270 enddo 01271 s%dsc(s%nx+1,j)=s%dsc(s%nx,j) 01272 enddo 01273 else 01274 s%dsc=s%dsu 01275 endif 01276 01277 ! s%dnu 01278 01279 if (s%ny>0) then 01280 do j=2,s%ny+1 01281 do i=1,s%nx+1 01282 s%dnu(i,j)=((xc(i,j)-xc(i,j-1))**2+(yc(i,j)-yc(i,j-1))**2)**(0.5d0) 01283 enddo 01284 enddo 01285 s%dnu(:,1)=s%dnu(:,2) 01286 else 01287 s%dnu=100.d0 01288 endif 01289 01290 ! s%dnz 01291 01292 if (s%ny>0) then 01293 do j=2,s%ny+1 01294 do i=1,s%nx+1 01295 s%dnz(i,j)=((s%xv(i,j)-s%xv(i,j-1))**2+(s%yv(i,j)-s%yv(i,j-1))**2)**(0.5d0) 01296 enddo 01297 enddo 01298 s%dnz(:,1)=s%dnz(:,2) 01299 else 01300 s%dnz=100.d0 01301 endif 01302 01303 ! s%dnv 01304 01305 if (s%ny>0) then 01306 do j=1,s%ny 01307 do i=1,s%nx+1 01308 s%dnv(i,j)=((s%xz(i,j+1)-s%xz(i,j))**2+(s%yz(i,j+1)-s%yz(i,j))**2)**(0.5d0) 01309 enddo 01310 enddo 01311 s%dnv(:,s%ny+1)=s%dnv(:,s%ny) 01312 else 01313 s%dnv=100.d0 01314 endif 01315 01316 ! s%dnc 01317 01318 if (s%ny>0) then 01319 do j=1,s%ny 01320 do i=1,s%nx+1 01321 s%dnc(i,j)=((s%xu(i,j+1)-s%xu(i,j))**2+(s%yu(i,j+1)-s%yu(i,j))**2)**(0.5d0) 01322 enddo 01323 enddo 01324 s%dnc(:,s%ny+1)=s%dnc(:,s%ny) 01325 else 01326 s%dnc=100.d0 01327 endif 01328 01329 01330 if (s%ny>0) then 01331 01332 ! dsdnu 01333 01334 do j=2,s%ny+1 01335 do i=1,s%nx 01336 x1=s%xv(i ,j ) - s%xv(i ,j-1) 01337 x3=s%xv(i+1,j-1) - s%xv(i ,j-1) 01338 x2=s%xv(i+1,j ) - s%xv(i+1,j-1) 01339 x4=s%xv(i+1,j ) - s%xv(i ,j ) 01340 y1=s%yv(i ,j ) - s%yv(i ,j-1) 01341 y3=s%yv(i+1,j-1) - s%yv(i ,j-1) 01342 y2=s%yv(i+1,j ) - s%yv(i+1,j-1) 01343 y4=s%yv(i+1,j ) - s%yv(i ,j ) 01344 dsdnu=0.5d0*(abs(x1*y3-x3*y1)+abs(x2*y4-x4*y2)) 01345 s%dsdnui(i,j)=1.d0/dsdnu 01346 enddo 01347 enddo 01348 s%dsdnui(:,1)=s%dsdnui(:,2) 01349 s%dsdnui(s%nx+1,:)=s%dsdnui(s%nx,:) 01350 01351 ! dsdnv 01352 01353 do j=1,s%ny 01354 do i=2,s%nx+1 01355 x1=s%xu(i-1,j+1) - s%xu(i-1,j ) 01356 x3=s%xu(i ,j ) - s%xu(i-1,j ) 01357 x2=s%xu(i ,j+1) - s%xu(i ,j ) 01358 x4=s%xu(i ,j+1) - s%xu(i-1,j+1) 01359 y1=s%yu(i-1,j+1) - s%yu(i-1,j ) 01360 y3=s%yu(i ,j ) - s%yu(i-1,j ) 01361 y2=s%yu(i ,j+1) - s%yu(i ,j ) 01362 y4=s%yu(i ,j+1) - s%yu(i-1,j+1) 01363 dsdnv=0.5d0*(abs(x1*y3-x3*y1)+abs(x2*y4-x4*y2)) 01364 s%dsdnvi(i,j)=1.d0/dsdnv 01365 enddo 01366 enddo 01367 s%dsdnvi(:,s%ny+1)=s%dsdnvi(:,s%ny) 01368 s%dsdnvi(1,:)=s%dsdnvi(2,:) 01369 01370 ! dsdnz 01371 01372 do j=2,s%ny+1 01373 do i=2,s%nx+1 01374 x1=xc(i-1,j ) - xc(i-1,j-1) 01375 x3=xc(i ,j-1) - xc(i-1,j-1) 01376 x2=xc(i ,j ) - xc(i ,j-1) 01377 x4=xc(i ,j ) - xc(i-1,j ) 01378 y1=yc(i-1,j ) - yc(i-1,j-1) 01379 y3=yc(i ,j-1) - yc(i-1,j-1) 01380 y2=yc(i ,j ) - yc(i ,j-1) 01381 y4=yc(i ,j ) - yc(i-1,j ) 01382 dsdnz=0.5d0*(abs(x1*y3-x3*y1)+abs(x2*y4-x4*y2)) 01383 s%dsdnzi(i,j)=1.d0/dsdnz 01384 enddo 01385 enddo 01386 s%dsdnzi(:,1)=s%dsdnzi(:,2) 01387 s%dsdnzi(1,:)=s%dsdnzi(2,:) 01388 01389 else 01390 01391 s%dsdnui=1.d0/(s%dsu*s%dnu) 01392 s%dsdnvi=1.d0/(s%dsv*s%dnv) 01393 s%dsdnzi=1.d0/(s%dsz*s%dnz) 01394 01395 endif 01396 01397 ! s%alfaz, grid orientation in z-points 01398 01399 do j=1,s%ny+1 01400 do i=2,s%nx 01401 s%alfaz(i,j)=atan2(s%yz(i+1,j)-s%yz(i-1,j),s%xz(i+1,j)-s%xz(i-1,j)) 01402 enddo 01403 s%alfaz(1,j)=s%alfaz(2,j) 01404 s%alfaz(s%nx+1,j)=s%alfaz(s%nx,j) 01405 enddo 01406 01407 ! s%alfau, grid orientation in u-points 01408 01409 do j=1,s%ny+1 01410 do i=1,s%nx 01411 s%alfau(i,j)=atan2(s%yz(i+1,j)-s%yz(i,j),s%xz(i+1,j)-s%xz(i,j)) 01412 enddo 01413 s%alfau(s%nx+1,j)=s%alfau(s%nx,j) 01414 enddo 01415 01416 ! s%alfav, grid orientation in v-points 01417 01418 if (s%ny>0) then 01419 do i=1,s%nx+1 01420 do j=1,s%ny 01421 s%alfav(i,j)=atan2(s%yz(i,j+1)-s%yz(i,j),s%xz(i,j+1)-s%xz(i,j)) 01422 enddo 01423 s%alfav(i,s%ny+1)=s%alfav(i,s%ny) 01424 enddo 01425 else 01426 s%alfav=s%alfaz 01427 endif 01428 01429 do j=1,s%ny+1 01430 s%sdist(1,j)=0 01431 do i=2,s%nx+1 01432 s%sdist(i,j)=s%sdist(i-1,j)+s%dsu(i-1,j) 01433 enddo 01434 enddo 01435 01436 do i=1,s%nx+1 01437 s%ndist(i,1)=0 01438 do j=2,s%ny+1 01439 s%ndist(i,j)=s%ndist(i,j-1)+s%dnv(i,j-1) 01440 enddo 01441 enddo 01442 01443 deallocate (xc) 01444 deallocate (yc) 01445 01446 end subroutine gridprops 01447 01448 subroutine ranges_init(s) 01449 use xmpi_module 01450 implicit none 01451 type(spacepars) :: s 01452 01453 imin_ee = 2 01454 imax_ee = s%nx 01455 if (s%ny>0) then 01456 jmin_ee = 2 01457 jmax_ee = s%ny 01458 else 01459 jmin_ee = 1 01460 jmax_ee = 1 01461 endif 01462 01463 imin_uu = 2 01464 imax_uu = s%nx-1 01465 if (s%ny>0) then 01466 jmin_uu = 2 01467 jmax_uu = s%ny 01468 else 01469 jmin_uu = 1 01470 jmax_uu = 1 01471 endif 01472 01473 imin_vv = 2 01474 imax_vv = s%nx 01475 if (s%ny>0) then 01476 jmin_vv = 2 01477 jmax_vv = s%ny-1 01478 else 01479 jmin_vv = 1 01480 jmax_vv = 1 01481 endif 01482 01483 imin_zs = 2 01484 imax_zs = s%nx 01485 if (s%ny>0) then 01486 jmin_zs = 2 01487 jmax_zs = s%ny 01488 else 01489 jmin_zs = 1 01490 jmax_zs = 1 01491 endif 01492 #ifdef USEMPI 01493 01494 if (.not. xmpi_istop) then 01495 imin_ee = 3 01496 !imin_uu = 2 ! in combination with shift_ee 01497 imin_uu = 3 01498 imin_vv = 3 01499 imin_zs = 3 01500 endif 01501 01502 if (.not. xmpi_isbot) then 01503 imax_ee = s%nx-1 01504 !imax_uu = s%nx-2 01505 imax_uu = s%nx-1 ! in combination with shift_ee 01506 imax_vv = s%nx-1 01507 imax_zs = s%nx-1 01508 endif 01509 01510 if (.not. xmpi_isleft) then 01511 jmin_ee = 3 01512 jmin_uu = 3 01513 ! jmin_vv = 2 01514 jmin_vv = 3 ! in combination with shift_ee 01515 jmin_zs = 3 01516 endif 01517 01518 if (.not. xmpi_isright) then 01519 jmax_ee = s%ny-1 01520 jmax_uu = s%ny-1 01521 ! jmax_vv = s%ny-2 01522 jmax_vv = s%ny-1 ! in combination with shift_ee 01523 jmax_zs = s%ny-1 01524 endif 01525 01526 #endif 01527 end subroutine ranges_init 01528 01529 end module spaceparams