00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 subroutine psmile_mg_setup (grid_id, range, tol, ierror)
00012
00013
00014
00015 use PRISM_constants
00016
00017 use PSMILe, dummy_interface => PSMILe_MG_setup
00018
00019 implicit none
00020
00021
00022
00023
00024 Integer, Intent (In) :: grid_id
00025
00026
00027
00028 Integer, Intent (In) :: range (2, ndim_3d)
00029
00030
00031
00032 Double precision, Intent (In) :: tol
00033
00034
00035
00036
00037
00038 Integer, Intent (Out) :: ierror
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 integer :: comp_id
00049
00050
00051
00052 integer :: lev, levf, ndlev
00053 integer :: levbeg
00054 integer, allocatable :: levdim (:, :)
00055 integer :: icoarse (ndim_3d)
00056 Integer :: my_range (2, ndim_3d)
00057
00058 integer :: j, len, n
00059
00060 logical :: simplified_grid
00061
00062 Type(Grid), Pointer :: gp
00063
00064
00065
00066 integer, parameter :: nerrp = 2
00067 integer :: ierrp (nerrp)
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 Character(len=len_cvs_string), save :: mycvs =
00089 '$Id: psmile_mg_setup.F90 3016 2011-03-14 15:17:02Z hanke $'
00090
00091
00092
00093 #ifdef VERBOSE
00094 print 9990, trim(ch_id), Grids(grid_id)%comp_id, range
00095
00096 call psmile_flushstd
00097 #endif /* VERBOSE */
00098
00099 #ifdef PRISM_ASSERTION
00100 if (Associated (Grids(grid_id)%mg_infos)) then
00101 call psmile_assert (__FILE__, __LINE__, &
00102 "Multigrid info's already created for this grid")
00103 endif
00104 #endif
00105
00106
00107
00108 ierror = 0
00109 gp => Grids(grid_id)
00110 my_range = range
00111
00112 comp_id = gp%comp_id
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 simplified_grid = gp%grid_type == PRISM_Gaussreduced_regvrt
00126
00127 if ( gp%grid_type == PRISM_Gaussreduced_regvrt ) then
00128
00129 my_range(1:2,1:2) = gp%gcorner_pointer%corner_shape(1:2,1:2)
00130 my_range(1:2,3) = range(1:2,3)
00131
00132
00133
00134 levbeg = 0
00135
00136 else
00137
00138
00139
00140 levbeg = 1
00141
00142 if (gp%grid_type == PRISM_Irrlonlat_regvrt) then
00143
00144 my_range (1:2, 1:ndim_2d) = gp%grid_shape (1:2, 1:ndim_2d)
00145 endif
00146
00147 endif
00148
00149
00150
00151 len = MAXVAL (my_range(2,1:ndim_3d)-my_range(1,1:ndim_3d)+1)
00152
00153 ndlev = log (dble(len)) / log (2.0d0)
00154 if (2**ndlev .lt. len) ndlev = ndlev + 1
00155 ndlev = ndlev + 1
00156
00157 #ifdef DEBUG
00158 PRINT *, TRIM(ch_id), ': psmile_mg_setup: we have ndlev', ndlev, 'to be generated'
00159 call psmile_flushstd
00160 #endif /* DEBUG */
00161
00162 Allocate (levdim(levbeg:ndim_3d, 1:ndlev), STAT = ierror)
00163 if ( ierror > 0 ) then
00164 ierrp (1) = ierror
00165 ierrp (2) = ndim_3d * (ndlev + (levbeg-1))
00166 ierror = PRISM_Error_Alloc
00167 call psmile_error ( ierror, 'levdim', &
00168 ierrp, 2, __FILE__, __LINE__ )
00169 return
00170 endif
00171
00172 Allocate (gp%mg_infos(levbeg:ndlev), STAT = ierror)
00173 if ( ierror > 0 ) then
00174 ierrp (1) = ierror
00175 ierrp (2) = ndlev + (levbeg-1)
00176 ierror = PRISM_Error_Alloc
00177 call psmile_error ( ierror, 'gp%mg_infos', &
00178 ierrp, 2, __FILE__, __LINE__ )
00179 return
00180 endif
00181
00182
00183
00184 do lev = levbeg, ndlev
00185 Nullify (gp%mg_infos(lev)%real_arrays)
00186 Nullify (gp%mg_infos(lev)%double_arrays)
00187 #if defined ( PRISM_QUAD_TYPE )
00188 Nullify (gp%mg_infos(lev)%quad_arrays)
00189 #endif
00190 end do
00191
00192 gp%nlev = ndlev
00193 gp%ijk0 (:) = my_range(1,:)
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 lev = 1
00205
00206 levdim (1:ndim_3d, lev) = my_range(2,1:ndim_3d)-my_range(1,1:ndim_3d)
00207 gp%mg_infos(lev)%levdim = levdim (1:ndim_3d, lev)
00208
00209 call psmile_mg_first_level (grid_id, my_range, &
00210 gp%mg_infos(lev), &
00211 tol, simplified_grid, ierror)
00212 if (ierror /= 0) return
00213
00214
00215
00216 do lev = 2, ndlev
00217 levf = lev - 1
00218
00219
00220
00221 icoarse (:) = 2
00222
00223 do j = 1, ndim_3d
00224 n = levdim(j,levf) + 1
00225
00226 if (n .eq. 1) then
00227 icoarse (j) = 1
00228 levdim (j,lev) = levdim (j,levf)
00229 else if ((n/2) * 2 == n) then
00230 levdim (j,lev) = n/2 - 1
00231 else
00232
00233 levdim (j,lev) = n/2
00234 endif
00235 end do
00236
00237
00238
00239 gp%mg_infos(lev)%levdim = levdim (1:ndim_3d, lev)
00240
00241 call psmile_mg_coars_level (grid_id, &
00242 gp%mg_infos(levf), &
00243 gp%mg_infos(lev), &
00244 icoarse, ierror)
00245 if (ierror /= 0) return
00246
00247
00248
00249 end do
00250
00251 #ifdef PRISM_ASSERTION
00252 if (levdim (1, ndlev) /= 0 .or. &
00253 levdim (2, ndlev) /= 0 .or. &
00254 levdim (3, ndlev) /= 0) then
00255 print *, 'ndlev', ndlev
00256 print *, 'levdim(:, 1)', levdim (:, 1)
00257 print *, 'levdim(:, n)', levdim (:, ndlev)
00258 call psmile_assert (__FILE__, __LINE__, &
00259 "incorrect coarsest levdim")
00260 endif
00261 #endif
00262
00263 Deallocate (levdim)
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 if ( gp%grid_type == PRISM_Gaussreduced_regvrt ) then
00280 lev = 0
00281
00282 my_range = gp%grid_shape
00283 my_range(2,3) = gp%grid_shape(1,3)
00284
00285 gp%mg_infos(lev)%levdim = my_range(2,1:ndim_3d)-my_range(1,1:ndim_3d)
00286 simplified_grid = .false.
00287
00288 call psmile_mg_first_level (grid_id, my_range, &
00289 gp%mg_infos(lev), &
00290 tol, simplified_grid, ierror)
00291 if (ierror /= 0) return
00292 endif
00293
00294
00295
00296
00297
00298 call psmile_mg_get_cyclic (grid_id, my_range, tol, ierror)
00299
00300
00301
00302 #ifdef VERBOSE
00303 print 9980, trim(ch_id), ierror
00304 call psmile_flushstd
00305 #endif /* VERBOSE */
00306
00307 #ifdef VERBOSE
00308
00309 9990 format (1x, a, ': psmile_mg_setup: comp_id', i3, ', range ', 6i6)
00310 9980 format (1x, a, ': psmile_mg_setup: eof ierror =', i3)
00311
00312 #endif /* VERBOSE */
00313
00314 end subroutine PSMILe_MG_setup