SICOPOLIS V3.2
 All Classes Files Functions Variables Macros
calc_vxy_ssa_matrix.F90
Go to the documentation of this file.
1 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 !
3 ! Subroutine : c a l c _ v x y _ s s a _ m a t r i x
4 !
5 !> @file
6 !!
7 !! Solution of the system of linear equations for the horizontal velocities
8 !! vx_m, vy_m in the shallow shelf approximation.
9 !!
10 !! @section Copyright
11 !!
12 !! Copyright 2009-2016 Ralf Greve, Tatsuru Sato
13 !!
14 !! @section License
15 !!
16 !! This file is part of SICOPOLIS.
17 !!
18 !! SICOPOLIS is free software: you can redistribute it and/or modify
19 !! it under the terms of the GNU General Public License as published by
20 !! the Free Software Foundation, either version 3 of the License, or
21 !! (at your option) any later version.
22 !!
23 !! SICOPOLIS is distributed in the hope that it will be useful,
24 !! but WITHOUT ANY WARRANTY; without even the implied warranty of
25 !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 !! GNU General Public License for more details.
27 !!
28 !! You should have received a copy of the GNU General Public License
29 !! along with SICOPOLIS. If not, see <http://www.gnu.org/licenses/>.
30 !<
31 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 
33 !-------------------------------------------------------------------------------
34 !> Solution of the system of linear equations for the horizontal velocities
35 !! vx_m, vy_m in the shallow shelf approximation.
36 !<------------------------------------------------------------------------------
37 subroutine calc_vxy_ssa_matrix(z_sl,dxi, deta, ii, jj, nn, m)
38 
39 use sico_types
41 use sico_vars
42 
43 implicit none
44 
45 integer(i4b), intent(in) :: ii((imax+1)*(jmax+1)), jj((imax+1)*(jmax+1))
46 integer(i4b), intent(in) :: nn(0:jmax,0:imax)
47 integer(i4b), intent(in) :: m
48 real(dp), intent(in) :: dxi, deta, z_sl
49 
50 integer(i4b) :: i, j, k, n
51 integer(i4b) :: i1, j1
52 real(dp) :: inv_dxi, inv_deta, inv_dxi_deta, inv_dxi2, inv_deta2
53 real(dp) :: factor_rhs_1, factor_rhs_2, rhosw_rho_ratio
54 real(dp) :: h_mid, zl_mid
55 real(dp), dimension(0:JMAX,0:IMAX) :: vis_int_sgxy, beta_drag
56 character(len=256) :: ch_solver_set_option
57 
58 lis_integer :: ierr
59 lis_integer :: nc, nr
60 ! LIS_INTEGER :: iter
61 lis_matrix :: lgs_a
62 lis_vector :: lgs_b, lgs_x
63 lis_solver :: solver
64 
65 lis_integer, parameter :: nmax = 2*(imax+1)*(jmax+1)
66 lis_integer, parameter :: n_sprs = 20*(imax+1)*(jmax+1)
67 lis_integer, allocatable, dimension(:) :: lgs_a_ptr, lgs_a_index
68 lis_scalar, allocatable, dimension(:) :: lgs_a_value, lgs_b_value, lgs_x_value
69 
70 !-------- Abbreviations --------
71 
72 inv_dxi = 1.0_dp/dxi
73 inv_deta = 1.0_dp/deta
74 inv_dxi_deta = 1.0_dp/(dxi*deta)
75 inv_dxi2 = 1.0_dp/(dxi*dxi)
76 inv_deta2 = 1.0_dp/(deta*deta)
77 
78 rhosw_rho_ratio = rho_sw/rho
79 factor_rhs_1 = 0.5_dp*rho*g
80 factor_rhs_2 = 0.5_dp*rho*g*(rho_sw-rho)/rho_sw
81 
82 !-------- Depth-integrated viscosity on the staggered grid
83 ! [at (i+1/2,j+1/2)] --------
84 
85 vis_int_sgxy = 0.0_dp ! initialisation
86 
87 do i=0, imax-1
88 do j=0, jmax-1
89 
90  k=0
91 
92  if ((maske(j,i)==0_i2b).or.(maske(j,i)==3_i2b)) then
93  k = k+1 ! floating or grounded ice
94  vis_int_sgxy(j,i) = vis_int_sgxy(j,i) + vis_int_g(j,i)
95  end if
96 
97  if ((maske(j,i+1)==0_i2b).or.(maske(j,i+1)==3_i2b)) then
98  k = k+1 ! floating or grounded ice
99  vis_int_sgxy(j,i) = vis_int_sgxy(j,i) + vis_int_g(j,i+1)
100  end if
101 
102  if ((maske(j+1,i)==0_i2b).or.(maske(j+1,i)==3_i2b)) then
103  k = k+1 ! floating or grounded ice
104  vis_int_sgxy(j,i) = vis_int_sgxy(j,i) + vis_int_g(j+1,i)
105  end if
106 
107  if ((maske(j+1,i+1)==0_i2b).or.(maske(j+1,i+1)==3_i2b)) then
108  k = k+1 ! floating or grounded ice
109  vis_int_sgxy(j,i) = vis_int_sgxy(j,i) + vis_int_g(j+1,i+1)
110  end if
111 
112  if (k>0) vis_int_sgxy(j,i) = vis_int_sgxy(j,i)/real(k,dp)
113 
114 end do
115 end do
116 
117 !-------- Basal drag parameter (for shelfy stream) --------
118 
119 beta_drag = 0.0_dp ! initialisation
120 
121 do i=1, imax-1
122 do j=1, jmax-1
123 
124  if (flag_shelfy_stream(j,i)) then
125 
126  if (m==1) then ! first iteration
127 
128  beta_drag(j,i) = c_drag(j,i) &
129  / sqrt(vx_b_g(j,i)**2 &
130  +vy_b_g(j,i)**2) &
131  **(1.0_dp-p_weert_inv(j,i))
132  ! computed with the SIA basal velocities
133  else
134 
135  beta_drag(j,i) = c_drag(j,i) &
136  / sqrt((0.5_dp*(vx_m(j,i)+vx_m(j,i-1)))**2 &
137  +(0.5_dp*(vy_m(j,i)+vy_m(j-1,i)))**2) &
138  **(1.0_dp-p_weert_inv(j,i))
139  ! computed with the SSA basal velocities
140  ! from the previous iteration
141  end if
142 
143  end if
144 
145 end do
146 end do
147 
148 !-------- Assembly of the system of linear equations
149 ! (matrix storage: compressed sparse row CSR) --------
150 
151 allocate(lgs_a_value(n_sprs), lgs_a_index(n_sprs), lgs_a_ptr(nmax+1))
152 allocate(lgs_b_value(nmax), lgs_x_value(nmax))
153 
154 lgs_a_value = 0.0_dp
155 lgs_a_index = 0
156 lgs_a_ptr = 0
157 
158 lgs_b_value = 0.0_dp
159 lgs_x_value = 0.0_dp
160 
161 lgs_a_ptr(1) = 1
162 
163 k = 0
164 
165 do n=1, nmax-1, 2
166 
167  i = ii((n+1)/2)
168  j = jj((n+1)/2)
169 
170 ! ------ Equations for vx_m (at (i+1/2,j))
171 
172  nr = n ! row counter
173 
174  if ( (i /= imax).and.(j /= 0).and.(j /= jmax) ) then
175  ! inner point on the staggered grid in x-direction
176 
177  h_mid = 0.50_dp*(h_c(j,i)+h_t(j,i)+h_c(j,i+1)+h_t(j,i+1))
178  zl_mid = 0.50_dp*(zl(j,i)+zl(j,i+1))
179 
180  if ( &
181  ( (maske(j,i)==3_i2b).and.(maske(j,i+1)==3_i2b) ) &
182  .or. &
183  ( flag_grounding_line_1(j,i).and.flag_grounding_line_2(j,i+1) &
184  .and.(h_mid < (z_sl-zl_mid)*rhosw_rho_ratio) ) &
185  .or. &
186  ( flag_grounding_line_2(j,i).and.flag_grounding_line_1(j,i+1) &
187  .and.(h_mid < (z_sl-zl_mid)*rhosw_rho_ratio) ) &
188  ) then
189  ! both neighbours are floating ice,
190  ! or one neighbour is floating ice and the other is grounded ice
191  ! (grounding line)
192  ! and floating conditions are satisfied;
193  ! discretisation of the x-component of the PDE
194 
195  flag_shelfy_stream_x(j,i)=.false.
196  ! make sure not to treat as shelfy stream
197 
198  nc = 2*nn(j-1,i)-1 ! smallest nc (column counter), for vx_m(j-1,i)
199  k = k+1
200  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
201  lgs_a_value(k) = inv_deta2*vis_int_sgxy(j-1,i)
202  lgs_a_index(k) = nc
203 
204  nc = 2*nn(j-1,i) ! next nc (column counter), for vy_m(j-1,i)
205  k = k+1
206  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
207  lgs_a_value(k) = inv_dxi_deta &
208  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j-1,i))
209  lgs_a_index(k) = nc
210 
211  nc = 2*nn(j,i-1)-1 ! next nc (column counter), for vx_m(j,i-1)
212  k = k+1
213  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
214  lgs_a_value(k) = 4.0_dp*inv_dxi2*vis_int_g(j,i)
215  lgs_a_index(k) = nc
216 
217  nc = 2*nn(j-1,i+1) ! next nc (column counter), for vy_m(j-1,i+1)
218  k = k+1
219  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
220  lgs_a_value(k) = -inv_dxi_deta &
221  *(2.0_dp*vis_int_g(j,i+1)+vis_int_sgxy(j-1,i))
222  lgs_a_index(k) = nc
223 
224  nc = 2*nn(j,i)-1 ! next nc (column counter), for vx_m(j,i)
225  if (nc /= nr) & ! (diagonal element)
226  stop ' calc_vxy_ssa_matrix: Check for diagonal element failed!'
227  k = k+1
228  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
229  lgs_a_value(k) = -4.0_dp*inv_dxi2 &
230  *(vis_int_g(j,i+1)+vis_int_g(j,i)) &
231  -inv_deta2 &
232  *(vis_int_sgxy(j,i)+vis_int_sgxy(j-1,i))
233  lgs_a_index(k) = nc
234 
235  nc = 2*nn(j,i) ! next nc (column counter), for vy_m(j,i)
236  k = k+1
237  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
238  lgs_a_value(k) = -inv_dxi_deta &
239  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i))
240  lgs_a_index(k) = nc
241 
242  nc = 2*nn(j,i+1)-1 ! next nc (column counter), for vx_m(j,i+1)
243  k = k+1
244  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
245  lgs_a_value(k) = 4.0_dp*inv_dxi2*vis_int_g(j,i+1)
246  lgs_a_index(k) = nc
247 
248  nc = 2*nn(j,i+1) ! next nc (column counter), for vy_m(j,i+1)
249  k = k+1
250  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
251  lgs_a_value(k) = inv_dxi_deta &
252  *(2.0_dp*vis_int_g(j,i+1)+vis_int_sgxy(j,i))
253  lgs_a_index(k) = nc
254 
255  nc = 2*nn(j+1,i)-1 ! largest nc (column counter), for vx_m(j+1,i)
256  k = k+1
257  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
258  lgs_a_value(k) = inv_deta2*vis_int_sgxy(j,i)
259  lgs_a_index(k) = nc
260 
261  lgs_b_value(nr) = factor_rhs_1 &
262  * (h_c(j,i)+h_t(j,i)+h_c(j,i+1)+h_t(j,i+1)) &
263  * dzs_dxi(j,i)
264 
265  lgs_x_value(nr) = vx_m(j,i)
266 
267  else if (flag_shelfy_stream_x(j,i)) then
268  ! shelfy stream (as determined by routine calc_vxy_sia)
269 
270  nc = 2*nn(j-1,i)-1 ! smallest nc (column counter), for vx_m(j-1,i)
271  k = k+1
272  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
273  lgs_a_value(k) = inv_deta2*vis_int_sgxy(j-1,i)
274  lgs_a_index(k) = nc
275 
276  nc = 2*nn(j-1,i) ! next nc (column counter), for vy_m(j-1,i)
277  k = k+1
278  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
279  lgs_a_value(k) = inv_dxi_deta &
280  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j-1,i))
281  lgs_a_index(k) = nc
282 
283  nc = 2*nn(j,i-1)-1 ! next nc (column counter), for vx_m(j,i-1)
284  k = k+1
285  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
286  lgs_a_value(k) = 4.0_dp*inv_dxi2*vis_int_g(j,i)
287  lgs_a_index(k) = nc
288 
289  nc = 2*nn(j-1,i+1) ! next nc (column counter), for vy_m(j-1,i+1)
290  k = k+1
291  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
292  lgs_a_value(k) = -inv_dxi_deta &
293  *(2.0_dp*vis_int_g(j,i+1)+vis_int_sgxy(j-1,i))
294  lgs_a_index(k) = nc
295 
296  nc = 2*nn(j,i)-1 ! next nc (column counter), for vx_m(j,i)
297  if (nc /= nr) & ! (diagonal element)
298  stop ' calc_vxy_ssa_matrix: Check for diagonal element failed!'
299  k = k+1
300  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
301  lgs_a_value(k) = -4.0_dp*inv_dxi2 &
302  *(vis_int_g(j,i+1)+vis_int_g(j,i)) &
303  -inv_deta2 &
304  *(vis_int_sgxy(j,i)+vis_int_sgxy(j-1,i)) &
305  -0.5_dp*(beta_drag(j,i+1)+beta_drag(j,i))
306  lgs_a_index(k) = nc
307 
308  nc = 2*nn(j,i) ! next nc (column counter), for vy_m(j,i)
309  k = k+1
310  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
311  lgs_a_value(k) = -inv_dxi_deta &
312  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i))
313  lgs_a_index(k) = nc
314 
315  nc = 2*nn(j,i+1)-1 ! next nc (column counter), for vx_m(j,i+1)
316  k = k+1
317  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
318  lgs_a_value(k) = 4.0_dp*inv_dxi2*vis_int_g(j,i+1)
319  lgs_a_index(k) = nc
320 
321  nc = 2*nn(j,i+1) ! next nc (column counter), for vy_m(j,i+1)
322  k = k+1
323  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
324  lgs_a_value(k) = inv_dxi_deta &
325  *(2.0_dp*vis_int_g(j,i+1)+vis_int_sgxy(j,i))
326  lgs_a_index(k) = nc
327 
328  nc = 2*nn(j+1,i)-1 ! largest nc (column counter), for vx_m(j+1,i)
329  k = k+1
330  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
331  lgs_a_value(k) = inv_deta2*vis_int_sgxy(j,i)
332  lgs_a_index(k) = nc
333 
334  lgs_b_value(nr) = factor_rhs_1 &
335  * (h_c(j,i)+h_t(j,i)+h_c(j,i+1)+h_t(j,i+1)) &
336  * dzs_dxi(j,i)
337 
338  lgs_x_value(nr) = vx_m(j,i)
339 
340  else if ( &
341  ( flag_grounding_line_1(j,i).and.flag_grounding_line_2(j,i+1) &
342  .and.(h_mid >= (z_sl-zl_mid)*rhosw_rho_ratio) ) &
343  .or. &
344  ( flag_grounding_line_2(j,i).and.flag_grounding_line_1(j,i+1) &
345  .and.(h_mid >= (z_sl-zl_mid)*rhosw_rho_ratio) ) &
346  ) then
347  ! one neighbour is floating ice and the other is grounded ice
348  ! (grounding line),
349  ! but floating conditions are not satisfied
350 
351  k = k+1
352  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
353  lgs_a_value(k) = 1.0_dp ! diagonal element only
354  lgs_a_index(k) = nr
355 
356  lgs_b_value(nr) = vx_m(j,i)
357  lgs_x_value(nr) = vx_m(j,i)
358 
359  else if ( &
360  ( (maske(j,i)==3_i2b).and.(maske(j,i+1)==1_i2b) ) &
361  .or. &
362  ( (maske(j,i)==1_i2b).and.(maske(j,i+1)==3_i2b) ) &
363  ) then
364  ! one neighbour is floating ice and the other is ice-free land;
365  ! velocity assumed to be zero
366 
367  k = k+1
368  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
369  lgs_a_value(k) = 1.0_dp ! diagonal element only
370  lgs_a_index(k) = nr
371 
372  lgs_b_value(nr) = 0.0_dp
373 
374  lgs_x_value(nr) = 0.0_dp
375 
376  else if ( &
377  ( flag_calving_front_1(j,i).and.flag_calving_front_2(j,i+1) ) &
378  .or. &
379  ( flag_calving_front_2(j,i).and.flag_calving_front_1(j,i+1) ) &
380  ) then
381  ! one neighbour is floating ice and the other is ocean
382  ! (calving front)
383 
384  if (maske(j,i)==3_i2b) then
385  i1 = i ! floating ice marker
386  else ! maske(j,i+1)==3_i2b
387  i1 = i+1 ! floating ice marker
388  end if
389 
390  if ( &
391  ( (maske(j,i1-1)==3_i2b).or.(maske(j,i1+1)==3_i2b) ) &
392  .or. &
393  ( (maske(j,i1-1)==0_i2b).or.(maske(j,i1+1)==0_i2b) ) &
394  .or. &
395  ( (maske(j,i1-1)==1_i2b).or.(maske(j,i1+1)==1_i2b) ) &
396  ) then
397  ! discretisation of the x-component of the BC at the calving front
398 
399  nc = 2*nn(j-1,i1) ! smallest nc (column counter), for vy_m(j-1,i1)
400  k = k+1
401  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
402  lgs_a_value(k) = -2.0_dp*inv_deta*vis_int_g(j,i1)
403  lgs_a_index(k) = nc
404 
405  nc = 2*nn(j,i1-1)-1 ! next nc (column counter), for vx_m(j,i1-1)
406  k = k+1
407  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
408  lgs_a_value(k) = -4.0_dp*inv_dxi*vis_int_g(j,i1)
409  lgs_a_index(k) = nc
410 
411  nc = 2*nn(j,i1)-1 ! next nc (column counter), for vx_m(j,i1)
412  k = k+1
413  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
414  lgs_a_value(k) = 4.0_dp*inv_dxi*vis_int_g(j,i1)
415  lgs_a_index(k) = nc
416 
417  nc = 2*nn(j,i1) ! largest nc (column counter), for vy_m(j,i1)
418  k = k+1
419  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
420  lgs_a_value(k) = 2.0_dp*inv_deta*vis_int_g(j,i1)
421  lgs_a_index(k) = nc
422 
423  lgs_b_value(nr) = factor_rhs_2 &
424  *(h_c(j,i1)+h_t(j,i1))*(h_c(j,i1)+h_t(j,i1))
425 
426  lgs_x_value(nr) = vx_m(j,i)
427 
428  else ! (maske(j,i1-1)==2_i2b).and.(maske(j,i1+1)==2_i2b);
429  ! velocity assumed to be zero
430 
431  k = k+1
432  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
433  lgs_a_value(k) = 1.0_dp ! diagonal element only
434  lgs_a_index(k) = nr
435 
436  lgs_b_value(nr) = 0.0_dp
437 
438  lgs_x_value(nr) = 0.0_dp
439 
440  end if
441 
442  else if ( (maske(j,i)==0_i2b).or.(maske(j,i+1)==0_i2b) ) then
443  ! neither neighbour is floating ice, but at least one neighbour is
444  ! grounded ice; velocity taken from the solution for grounded ice
445 
446  k = k+1
447  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
448  lgs_a_value(k) = 1.0_dp ! diagonal element only
449  lgs_a_index(k) = nr
450 
451  lgs_b_value(nr) = vx_m(j,i)
452 
453  lgs_x_value(nr) = vx_m(j,i)
454 
455  else ! neither neighbour is floating or grounded ice,
456  ! velocity assumed to be zero
457 
458  k = k+1
459  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
460  lgs_a_value(k) = 1.0_dp ! diagonal element only
461  lgs_a_index(k) = nr
462 
463  lgs_b_value(nr) = 0.0_dp
464 
465  lgs_x_value(nr) = 0.0_dp
466 
467  end if
468 
469  else ! boundary condition, velocity assumed to be zero
470 
471  k = k+1
472  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
473  lgs_a_value(k) = 1.0_dp ! diagonal element only
474  lgs_a_index(k) = nr
475 
476  lgs_b_value(nr) = 0.0_dp
477 
478  lgs_x_value(nr) = 0.0_dp
479 
480  end if
481 
482  lgs_a_ptr(nr+1) = k+1 ! row is completed, store index to next row
483 
484 ! ------ Equations for vy_m (at (i,j+1/2))
485 
486  nr = n+1 ! row counter
487 
488  if ( (j /= jmax).and.(i /= 0).and.(i /= imax) ) then
489  ! inner point on the staggered grid in y-direction
490 
491  h_mid = 0.5_dp*(h_c(j+1,i)+h_t(j+1,i)+h_c(j,i)+h_t(j,i))
492  zl_mid = 0.5_dp*(zl(j+1,i)+zl(j,i))
493 
494  if ( &
495  ( (maske(j,i)==3_i2b).and.(maske(j+1,i)==3_i2b) ) &
496  .or. &
497  ( flag_grounding_line_1(j,i).and.flag_grounding_line_2(j+1,i) &
498  .and.(h_mid < (z_sl-zl_mid)*rhosw_rho_ratio) ) &
499  .or. &
500  ( flag_grounding_line_2(j,i).and.flag_grounding_line_1(j+1,i) &
501  .and.(h_mid < (z_sl-zl_mid)*rhosw_rho_ratio) ) &
502  ) then
503  ! both neighbours are floating ice,
504  ! or one neighbour is floating ice and the other is grounded ice
505  ! (grounding line)
506  ! and floating conditions are satisfied;
507  ! discretisation of the x-component of the PDE
508 
509  flag_shelfy_stream_y(j,i)=.false.
510  ! make sure not to treat as shelfy stream
511 
512  nc = 2*nn(j-1,i) ! smallest nc (column counter), for vy_m(j-1,i)
513  k = k+1
514  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
515  lgs_a_value(k) = 4.0_dp*inv_deta2*vis_int_g(j,i)
516  lgs_a_index(k) = nc
517 
518  nc = 2*nn(j,i-1)-1 ! next nc (column counter), for vx_m(j,i-1)
519  k = k+1
520  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
521  lgs_a_value(k) = inv_dxi_deta &
522  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i-1))
523  lgs_a_index(k) = nc
524 
525  nc = 2*nn(j,i-1) ! next nc (column counter), for vy_m(j,i-1)
526  k = k+1
527  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
528  lgs_a_value(k) = inv_dxi2*vis_int_sgxy(j,i-1)
529  lgs_a_index(k) = nc
530 
531  nc = 2*nn(j,i)-1 ! next nc (column counter), for vx_m(j,i)
532  k = k+1
533  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
534  lgs_a_value(k) = -inv_dxi_deta &
535  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i))
536  lgs_a_index(k) = nc
537 
538  nc = 2*nn(j,i) ! next nc (column counter), for vy_m(j,i)
539  if (nc /= nr) & ! (diagonal element)
540  stop ' calc_vxy_ssa_matrix: Check for diagonal element failed!'
541  k = k+1
542  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
543  lgs_a_value(k) = -4.0_dp*inv_deta2 &
544  *(vis_int_g(j+1,i)+vis_int_g(j,i)) &
545  -inv_dxi2 &
546  *(vis_int_sgxy(j,i)+vis_int_sgxy(j,i-1))
547  lgs_a_index(k) = nc
548 
549  nc = 2*nn(j+1,i-1)-1 ! next nc (column counter), for vx_m(j+1,i-1)
550  k = k+1
551  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
552  lgs_a_value(k) = -inv_dxi_deta &
553  *(2.0_dp*vis_int_g(j+1,i)+vis_int_sgxy(j,i-1))
554  lgs_a_index(k) = nc
555 
556  nc = 2*nn(j,i+1) ! next nc (column counter), for vy_m(j,i+1)
557  k = k+1
558  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
559  lgs_a_value(k) = inv_dxi2*vis_int_sgxy(j,i)
560  lgs_a_index(k) = nc
561 
562  nc = 2*nn(j+1,i)-1 ! next nc (column counter), for vx_m(j+1,i)
563  k = k+1
564  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
565  lgs_a_value(k) = inv_dxi_deta &
566  *(2.0_dp*vis_int_g(j+1,i)+vis_int_sgxy(j,i))
567  lgs_a_index(k) = nc
568 
569  nc = 2*nn(j+1,i) ! largest nc (column counter), for vy_m(j+1,i)
570  k = k+1
571  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
572  lgs_a_value(k) = 4.0_dp*inv_deta2*vis_int_g(j+1,i)
573  lgs_a_index(k) = nc
574 
575  lgs_b_value(nr) = factor_rhs_1 &
576  * (h_c(j,i)+h_t(j,i)+h_c(j+1,i)+h_t(j+1,i)) &
577  * dzs_deta(j,i)
578 
579  lgs_x_value(nr) = vy_m(j,i)
580 
581  else if (flag_shelfy_stream_y(j,i)) then
582  ! shelfy stream (as determined by routine calc_vxy_sia)
583 
584  nc = 2*nn(j-1,i) ! smallest nc (column counter), for vy_m(j-1,i)
585  k = k+1
586  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
587  lgs_a_value(k) = 4.0_dp*inv_deta2*vis_int_g(j,i)
588  lgs_a_index(k) = nc
589 
590  nc = 2*nn(j,i-1)-1 ! next nc (column counter), for vx_m(j,i-1)
591  k = k+1
592  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
593  lgs_a_value(k) = inv_dxi_deta &
594  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i-1))
595  lgs_a_index(k) = nc
596 
597  nc = 2*nn(j,i-1) ! next nc (column counter), for vy_m(j,i-1)
598  k = k+1
599  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
600  lgs_a_value(k) = inv_dxi2*vis_int_sgxy(j,i-1)
601  lgs_a_index(k) = nc
602 
603  nc = 2*nn(j,i)-1 ! next nc (column counter), for vx_m(j,i)
604  k = k+1
605  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
606  lgs_a_value(k) = -inv_dxi_deta &
607  *(2.0_dp*vis_int_g(j,i)+vis_int_sgxy(j,i))
608  lgs_a_index(k) = nc
609 
610  nc = 2*nn(j,i) ! next nc (column counter), for vy_m(j,i)
611  if (nc /= nr) & ! (diagonal element)
612  stop ' calc_vxy_ssa_matrix: Check for diagonal element failed!'
613  k = k+1
614  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
615  lgs_a_value(k) = -4.0_dp*inv_deta2 &
616  *(vis_int_g(j+1,i)+vis_int_g(j,i)) &
617  -inv_dxi2 &
618  *(vis_int_sgxy(j,i)+vis_int_sgxy(j,i-1)) &
619  -0.5_dp*(beta_drag(j+1,i)+beta_drag(j,i))
620  lgs_a_index(k) = nc
621 
622  nc = 2*nn(j+1,i-1)-1 ! next nc (column counter), for vx_m(j+1,i-1)
623  k = k+1
624  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
625  lgs_a_value(k) = -inv_dxi_deta &
626  *(2.0_dp*vis_int_g(j+1,i)+vis_int_sgxy(j,i-1))
627  lgs_a_index(k) = nc
628 
629  nc = 2*nn(j,i+1) ! next nc (column counter), for vy_m(j,i+1)
630  k = k+1
631  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
632  lgs_a_value(k) = inv_dxi2*vis_int_sgxy(j,i)
633  lgs_a_index(k) = nc
634 
635  nc = 2*nn(j+1,i)-1 ! next nc (column counter), for vx_m(j+1,i)
636  k = k+1
637  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
638  lgs_a_value(k) = inv_dxi_deta &
639  *(2.0_dp*vis_int_g(j+1,i)+vis_int_sgxy(j,i))
640  lgs_a_index(k) = nc
641 
642  nc = 2*nn(j+1,i) ! largest nc (column counter), for vy_m(j+1,i)
643  k = k+1
644  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
645  lgs_a_value(k) = 4.0_dp*inv_deta2*vis_int_g(j+1,i)
646  lgs_a_index(k) = nc
647 
648  lgs_b_value(nr) = factor_rhs_1 &
649  * (h_c(j,i)+h_t(j,i)+h_c(j+1,i)+h_t(j+1,i)) &
650  * dzs_deta(j,i)
651 
652  lgs_x_value(nr) = vy_m(j,i)
653 
654  else if ( &
655  ( flag_grounding_line_1(j,i).and.flag_grounding_line_2(j+1,i) &
656  .and.(h_mid >= (z_sl-zl_mid)*rhosw_rho_ratio) ) &
657  .or. &
658  ( flag_grounding_line_2(j,i).and.flag_grounding_line_1(j+1,i) &
659  .and.(h_mid >= (z_sl-zl_mid)*rhosw_rho_ratio) ) &
660  ) then
661  ! one neighbour is floating ice and the other is grounded ice
662  ! (grounding line),
663  ! but floating conditions are not satisfied
664 
665  k = k+1
666  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
667  lgs_a_value(k) = 1.0_dp ! diagonal element only
668  lgs_a_index(k) = nr
669 
670  lgs_b_value(nr) = vy_m(j,i)
671  lgs_x_value(nr) = vy_m(j,i)
672 
673  else if ( &
674  ( (maske(j,i)==3_i2b).and.(maske(j+1,i)==1_i2b) ) &
675  .or. &
676  ( (maske(j,i)==1_i2b).and.(maske(j+1,i)==3_i2b) ) &
677  ) then
678  ! one neighbour is floating ice and the other is ice-free land;
679  ! velocity assumed to be zero
680 
681  k = k+1
682  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
683  lgs_a_value(k) = 1.0_dp ! diagonal element only
684  lgs_a_index(k) = nr
685 
686  lgs_b_value(nr) = 0.0_dp
687 
688  lgs_x_value(nr) = 0.0_dp
689 
690  else if ( &
691  ( flag_calving_front_1(j,i).and.flag_calving_front_2(j+1,i) ) &
692  .or. &
693  ( flag_calving_front_2(j,i).and.flag_calving_front_1(j+1,i) ) &
694  ) then
695  ! one neighbour is floating ice and the other is ocean
696  ! (calving front)
697 
698  if (maske(j,i)==3_i2b) then
699  j1 = j ! floating ice marker
700  else ! maske(j+1,i)==3_i2b
701  j1 = j+1 ! floating ice marker
702  end if
703 
704  if ( &
705  ( (maske(j1-1,i)==3_i2b).or.(maske(j1+1,i)==3_i2b) ) &
706  .or. &
707  ( (maske(j1-1,i)==0_i2b).or.(maske(j1+1,i)==0_i2b) ) &
708  .or. &
709  ( (maske(j1-1,i)==1_i2b).or.(maske(j1+1,i)==1_i2b) ) &
710  ) then
711  ! discretisation of the y-component of the BC at the calving front
712 
713  nc = 2*nn(j1-1,i) ! smallest nc (column counter), for vy_m(j1-1,i)
714  k = k+1
715  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
716  lgs_a_value(k) = -4.0_dp*inv_deta*vis_int_g(j1,i)
717  lgs_a_index(k) = nc
718 
719  nc = 2*nn(j1,i-1)-1 ! next nc (column counter), for vx_m(j1,i-1)
720  k = k+1
721  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
722  lgs_a_value(k) = -2.0_dp*inv_dxi*vis_int_g(j1,i)
723  lgs_a_index(k) = nc
724 
725  nc = 2*nn(j1,i)-1 ! next nc (column counter), for vx_m(j1,i)
726  k = k+1
727  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
728  lgs_a_value(k) = 2.0_dp*inv_dxi*vis_int_g(j1,i)
729  lgs_a_index(k) = nc
730 
731  nc = 2*nn(j1,i) ! largest nc (column counter), for vy_m(j1,i)
732  k = k+1
733  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
734  lgs_a_value(k) = 4.0_dp*inv_deta*vis_int_g(j1,i)
735  lgs_a_index(k) = nc
736 
737  lgs_b_value(nr) = factor_rhs_2 &
738  *(h_c(j1,i)+h_t(j1,i))*(h_c(j1,i)+h_t(j1,i))
739 
740  lgs_x_value(nr) = vy_m(j,i)
741 
742  else ! (maske(j1-1,i)==2_i2b).and.(maske(j1+1,i)==2_i2b);
743  ! velocity assumed to be zero
744 
745  k = k+1
746  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
747  lgs_a_value(k) = 1.0_dp ! diagonal element only
748  lgs_a_index(k) = nr
749 
750  lgs_b_value(nr) = 0.0_dp
751 
752  lgs_x_value(nr) = 0.0_dp
753 
754  end if
755 
756  else if ( (maske(j,i)==0_i2b).or.(maske(j+1,i)==0_i2b) ) then
757  ! neither neighbour is floating ice, but at least one neighbour is
758  ! grounded ice; velocity taken from the solution for grounded ice
759 
760  k = k+1
761  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
762  lgs_a_value(k) = 1.0_dp ! diagonal element only
763  lgs_a_index(k) = nr
764 
765  lgs_b_value(nr) = vy_m(j,i)
766 
767  lgs_x_value(nr) = vy_m(j,i)
768 
769  else ! neither neighbour is floating or grounded ice,
770  ! velocity assumed to be zero
771 
772  k = k+1
773  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
774  lgs_a_value(k) = 1.0_dp ! diagonal element only
775  lgs_a_index(k) = nr
776 
777  lgs_b_value(nr) = 0.0_dp
778  lgs_x_value(nr) = 0.0_dp
779 
780  end if
781 
782  else ! boundary condition, velocity assumed to be zero
783 
784  k = k+1
785  ! if (k > n_sprs) stop ' calc_vxy_ssa_matrix: n_sprs too small!'
786  lgs_a_value(k) = 1.0_dp ! diagonal element only
787  lgs_a_index(k) = nr
788 
789  lgs_b_value(nr) = 0.0_dp
790  lgs_x_value(nr) = 0.0_dp
791 
792  end if
793 
794  lgs_a_ptr(nr+1) = k+1 ! row is completed, store index to next row
795 
796 end do
797 
798 !-------- Settings for Lis --------
799 
800 call lis_matrix_create(lis_comm_world, lgs_a, ierr)
801 call lis_vector_create(lis_comm_world, lgs_b, ierr)
802 call lis_vector_create(lis_comm_world, lgs_x, ierr)
803 
804 call lis_matrix_set_size(lgs_a, 0, nmax, ierr)
805 call lis_vector_set_size(lgs_b, 0, nmax, ierr)
806 call lis_vector_set_size(lgs_x, 0, nmax, ierr)
807 
808 do nr=1, nmax
809 
810  do nc=lgs_a_ptr(nr), lgs_a_ptr(nr+1)-1
811  call lis_matrix_set_value(lis_ins_value, nr, lgs_a_index(nc), &
812  lgs_a_value(nc), lgs_a, ierr)
813  end do
814 
815  call lis_vector_set_value(lis_ins_value, nr, lgs_b_value(nr), lgs_b, ierr)
816  call lis_vector_set_value(lis_ins_value, nr, lgs_x_value(nr), lgs_x, ierr)
817 
818 end do
819 
820 call lis_matrix_set_type(lgs_a, lis_matrix_csr, ierr)
821 call lis_matrix_assemble(lgs_a, ierr)
822 
823 !-------- Solution of the system of linear equations with Lis --------
824 
825 call lis_solver_create(solver, ierr)
826 
827 ch_solver_set_option = '-i bicgstabl -p ilu '// &
828  '-maxiter 1000 -tol 1.0e-11 -initx_zeros false'
829 call lis_solver_set_option(trim(ch_solver_set_option), solver, ierr)
830 
831 call lis_solve(lgs_a, lgs_b, lgs_x, solver, ierr)
832 
833 ! call lis_solver_get_iters(solver, iter, ierr)
834 ! write(6,'(11x,a,i5)') 'calc_vxy_ssa_matrix: iter = ', iter
835 
836 lgs_x_value = 0.0_dp
837 call lis_vector_gather(lgs_x, lgs_x_value, ierr)
838 call lis_matrix_destroy(lgs_a, ierr)
839 call lis_vector_destroy(lgs_b, ierr)
840 call lis_vector_destroy(lgs_x, ierr)
841 call lis_solver_destroy(solver, ierr)
842 
843 do n=1, nmax-1, 2
844 
845  i = ii((n+1)/2)
846  j = jj((n+1)/2)
847 
848  nr = n
849  vx_m(j,i) = lgs_x_value(nr)
850 
851  nr = n+1
852  vy_m(j,i) = lgs_x_value(nr)
853 
854 end do
855 
856 deallocate(lgs_a_value, lgs_a_index, lgs_a_ptr)
857 deallocate(lgs_b_value, lgs_x_value)
858 
859 end subroutine calc_vxy_ssa_matrix
860 !
subroutine calc_vxy_ssa_matrix(z_sl, dxi, deta, ii, jj, nn, m)
Solution of the system of linear equations for the horizontal velocities vx_m, vy_m in the shallow sh...
Declarations of kind types for SICOPOLIS.
Definition: sico_types.F90:35
Declarations of global variables for SICOPOLIS (for the ANT domain).
Definition: sico_vars.F90:35
Declarations of global variables for SICOPOLIS.