| 1 | /*BHEADER**********************************************************************
|
|---|
| 2 | * Copyright (c) 2008, Lawrence Livermore National Security, LLC.
|
|---|
| 3 | * Produced at the Lawrence Livermore National Laboratory.
|
|---|
| 4 | * This file is part of HYPRE. See file COPYRIGHT for details.
|
|---|
| 5 | *
|
|---|
| 6 | * HYPRE is free software; you can redistribute it and/or modify it under the
|
|---|
| 7 | * terms of the GNU Lesser General Public License (as published by the Free
|
|---|
| 8 | * Software Foundation) version 2.1 dated February 1999.
|
|---|
| 9 | *
|
|---|
| 10 | * $Revision: 2.4 $
|
|---|
| 11 | ***********************************************************************EHEADER*/
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 | #include "headers.h"
|
|---|
| 17 |
|
|---|
| 18 | /*--------------------------------------------------------------------------
|
|---|
| 19 | * hypre_GenerateDifConv
|
|---|
| 20 | *--------------------------------------------------------------------------*/
|
|---|
| 21 |
|
|---|
| 22 | HYPRE_ParCSRMatrix
|
|---|
| 23 | GenerateDifConv( MPI_Comm comm,
|
|---|
| 24 | int nx,
|
|---|
| 25 | int ny,
|
|---|
| 26 | int nz,
|
|---|
| 27 | int P,
|
|---|
| 28 | int Q,
|
|---|
| 29 | int R,
|
|---|
| 30 | int p,
|
|---|
| 31 | int q,
|
|---|
| 32 | int r,
|
|---|
| 33 | double *value )
|
|---|
| 34 | {
|
|---|
| 35 | hypre_ParCSRMatrix *A;
|
|---|
| 36 | hypre_CSRMatrix *diag;
|
|---|
| 37 | hypre_CSRMatrix *offd;
|
|---|
| 38 |
|
|---|
| 39 | int *diag_i;
|
|---|
| 40 | int *diag_j;
|
|---|
| 41 | double *diag_data;
|
|---|
| 42 |
|
|---|
| 43 | int *offd_i;
|
|---|
| 44 | int *offd_j;
|
|---|
| 45 | double *offd_data;
|
|---|
| 46 |
|
|---|
| 47 | int *global_part;
|
|---|
| 48 | int ix, iy, iz;
|
|---|
| 49 | int cnt, o_cnt;
|
|---|
| 50 | int local_num_rows;
|
|---|
| 51 | int *col_map_offd;
|
|---|
| 52 | int row_index;
|
|---|
| 53 | int i,j;
|
|---|
| 54 |
|
|---|
| 55 | int nx_local, ny_local, nz_local;
|
|---|
| 56 | int nx_size, ny_size, nz_size;
|
|---|
| 57 | int num_cols_offd;
|
|---|
| 58 | int grid_size;
|
|---|
| 59 |
|
|---|
| 60 | int *nx_part;
|
|---|
| 61 | int *ny_part;
|
|---|
| 62 | int *nz_part;
|
|---|
| 63 |
|
|---|
| 64 | int num_procs, my_id;
|
|---|
| 65 | int P_busy, Q_busy, R_busy;
|
|---|
| 66 |
|
|---|
| 67 | MPI_Comm_size(comm,&num_procs);
|
|---|
| 68 | MPI_Comm_rank(comm,&my_id);
|
|---|
| 69 |
|
|---|
| 70 | grid_size = nx*ny*nz;
|
|---|
| 71 |
|
|---|
| 72 | hypre_GeneratePartitioning(nx,P,&nx_part);
|
|---|
| 73 | hypre_GeneratePartitioning(ny,Q,&ny_part);
|
|---|
| 74 | hypre_GeneratePartitioning(nz,R,&nz_part);
|
|---|
| 75 |
|
|---|
| 76 | global_part = hypre_CTAlloc(int,P*Q*R+1);
|
|---|
| 77 |
|
|---|
| 78 | global_part[0] = 0;
|
|---|
| 79 | cnt = 1;
|
|---|
| 80 | for (iz = 0; iz < R; iz++)
|
|---|
| 81 | {
|
|---|
| 82 | nz_size = nz_part[iz+1]-nz_part[iz];
|
|---|
| 83 | for (iy = 0; iy < Q; iy++)
|
|---|
| 84 | {
|
|---|
| 85 | ny_size = ny_part[iy+1]-ny_part[iy];
|
|---|
| 86 | for (ix = 0; ix < P; ix++)
|
|---|
| 87 | {
|
|---|
| 88 | nx_size = nx_part[ix+1] - nx_part[ix];
|
|---|
| 89 | global_part[cnt] = global_part[cnt-1];
|
|---|
| 90 | global_part[cnt++] += nx_size*ny_size*nz_size;
|
|---|
| 91 | }
|
|---|
| 92 | }
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 | nx_local = nx_part[p+1] - nx_part[p];
|
|---|
| 96 | ny_local = ny_part[q+1] - ny_part[q];
|
|---|
| 97 | nz_local = nz_part[r+1] - nz_part[r];
|
|---|
| 98 |
|
|---|
| 99 | my_id = r*(P*Q) + q*P + p;
|
|---|
| 100 | num_procs = P*Q*R;
|
|---|
| 101 |
|
|---|
| 102 | local_num_rows = nx_local*ny_local*nz_local;
|
|---|
| 103 | diag_i = hypre_CTAlloc(int, local_num_rows+1);
|
|---|
| 104 | offd_i = hypre_CTAlloc(int, local_num_rows+1);
|
|---|
| 105 |
|
|---|
| 106 | P_busy = hypre_min(nx,P);
|
|---|
| 107 | Q_busy = hypre_min(ny,Q);
|
|---|
| 108 | R_busy = hypre_min(nz,R);
|
|---|
| 109 |
|
|---|
| 110 | num_cols_offd = 0;
|
|---|
| 111 | if (p) num_cols_offd += ny_local*nz_local;
|
|---|
| 112 | if (p < P_busy-1) num_cols_offd += ny_local*nz_local;
|
|---|
| 113 | if (q) num_cols_offd += nx_local*nz_local;
|
|---|
| 114 | if (q < Q_busy-1) num_cols_offd += nx_local*nz_local;
|
|---|
| 115 | if (r) num_cols_offd += nx_local*ny_local;
|
|---|
| 116 | if (r < R_busy-1) num_cols_offd += nx_local*ny_local;
|
|---|
| 117 |
|
|---|
| 118 | if (!local_num_rows) num_cols_offd = 0;
|
|---|
| 119 |
|
|---|
| 120 | col_map_offd = hypre_CTAlloc(int, num_cols_offd);
|
|---|
| 121 |
|
|---|
| 122 | cnt = 1;
|
|---|
| 123 | o_cnt = 1;
|
|---|
| 124 | diag_i[0] = 0;
|
|---|
| 125 | offd_i[0] = 0;
|
|---|
| 126 | for (iz = nz_part[r]; iz < nz_part[r+1]; iz++)
|
|---|
| 127 | {
|
|---|
| 128 | for (iy = ny_part[q]; iy < ny_part[q+1]; iy++)
|
|---|
| 129 | {
|
|---|
| 130 | for (ix = nx_part[p]; ix < nx_part[p+1]; ix++)
|
|---|
| 131 | {
|
|---|
| 132 | diag_i[cnt] = diag_i[cnt-1];
|
|---|
| 133 | offd_i[o_cnt] = offd_i[o_cnt-1];
|
|---|
| 134 | diag_i[cnt]++;
|
|---|
| 135 | if (iz > nz_part[r])
|
|---|
| 136 | diag_i[cnt]++;
|
|---|
| 137 | else
|
|---|
| 138 | {
|
|---|
| 139 | if (iz)
|
|---|
| 140 | {
|
|---|
| 141 | offd_i[o_cnt]++;
|
|---|
| 142 | }
|
|---|
| 143 | }
|
|---|
| 144 | if (iy > ny_part[q])
|
|---|
| 145 | diag_i[cnt]++;
|
|---|
| 146 | else
|
|---|
| 147 | {
|
|---|
| 148 | if (iy)
|
|---|
| 149 | {
|
|---|
| 150 | offd_i[o_cnt]++;
|
|---|
| 151 | }
|
|---|
| 152 | }
|
|---|
| 153 | if (ix > nx_part[p])
|
|---|
| 154 | diag_i[cnt]++;
|
|---|
| 155 | else
|
|---|
| 156 | {
|
|---|
| 157 | if (ix)
|
|---|
| 158 | {
|
|---|
| 159 | offd_i[o_cnt]++;
|
|---|
| 160 | }
|
|---|
| 161 | }
|
|---|
| 162 | if (ix+1 < nx_part[p+1])
|
|---|
| 163 | diag_i[cnt]++;
|
|---|
| 164 | else
|
|---|
| 165 | {
|
|---|
| 166 | if (ix+1 < nx)
|
|---|
| 167 | {
|
|---|
| 168 | offd_i[o_cnt]++;
|
|---|
| 169 | }
|
|---|
| 170 | }
|
|---|
| 171 | if (iy+1 < ny_part[q+1])
|
|---|
| 172 | diag_i[cnt]++;
|
|---|
| 173 | else
|
|---|
| 174 | {
|
|---|
| 175 | if (iy+1 < ny)
|
|---|
| 176 | {
|
|---|
| 177 | offd_i[o_cnt]++;
|
|---|
| 178 | }
|
|---|
| 179 | }
|
|---|
| 180 | if (iz+1 < nz_part[r+1])
|
|---|
| 181 | diag_i[cnt]++;
|
|---|
| 182 | else
|
|---|
| 183 | {
|
|---|
| 184 | if (iz+1 < nz)
|
|---|
| 185 | {
|
|---|
| 186 | offd_i[o_cnt]++;
|
|---|
| 187 | }
|
|---|
| 188 | }
|
|---|
| 189 | cnt++;
|
|---|
| 190 | o_cnt++;
|
|---|
| 191 | }
|
|---|
| 192 | }
|
|---|
| 193 | }
|
|---|
| 194 |
|
|---|
| 195 | diag_j = hypre_CTAlloc(int, diag_i[local_num_rows]);
|
|---|
| 196 | diag_data = hypre_CTAlloc(double, diag_i[local_num_rows]);
|
|---|
| 197 |
|
|---|
| 198 | if (num_procs > 1)
|
|---|
| 199 | {
|
|---|
| 200 | offd_j = hypre_CTAlloc(int, offd_i[local_num_rows]);
|
|---|
| 201 | offd_data = hypre_CTAlloc(double, offd_i[local_num_rows]);
|
|---|
| 202 | }
|
|---|
| 203 |
|
|---|
| 204 | row_index = 0;
|
|---|
| 205 | cnt = 0;
|
|---|
| 206 | o_cnt = 0;
|
|---|
| 207 | for (iz = nz_part[r]; iz < nz_part[r+1]; iz++)
|
|---|
| 208 | {
|
|---|
| 209 | for (iy = ny_part[q]; iy < ny_part[q+1]; iy++)
|
|---|
| 210 | {
|
|---|
| 211 | for (ix = nx_part[p]; ix < nx_part[p+1]; ix++)
|
|---|
| 212 | {
|
|---|
| 213 | diag_j[cnt] = row_index;
|
|---|
| 214 | diag_data[cnt++] = value[0];
|
|---|
| 215 | if (iz > nz_part[r])
|
|---|
| 216 | {
|
|---|
| 217 | diag_j[cnt] = row_index-nx_local*ny_local;
|
|---|
| 218 | diag_data[cnt++] = value[3];
|
|---|
| 219 | }
|
|---|
| 220 | else
|
|---|
| 221 | {
|
|---|
| 222 | if (iz)
|
|---|
| 223 | {
|
|---|
| 224 | offd_j[o_cnt] = hypre_map(ix,iy,iz-1,p,q,r-1,P,Q,R,
|
|---|
| 225 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 226 | offd_data[o_cnt++] = value[3];
|
|---|
| 227 | }
|
|---|
| 228 | }
|
|---|
| 229 | if (iy > ny_part[q])
|
|---|
| 230 | {
|
|---|
| 231 | diag_j[cnt] = row_index-nx_local;
|
|---|
| 232 | diag_data[cnt++] = value[2];
|
|---|
| 233 | }
|
|---|
| 234 | else
|
|---|
| 235 | {
|
|---|
| 236 | if (iy)
|
|---|
| 237 | {
|
|---|
| 238 | offd_j[o_cnt] = hypre_map(ix,iy-1,iz,p,q-1,r,P,Q,R,
|
|---|
| 239 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 240 | offd_data[o_cnt++] = value[2];
|
|---|
| 241 | }
|
|---|
| 242 | }
|
|---|
| 243 | if (ix > nx_part[p])
|
|---|
| 244 | {
|
|---|
| 245 | diag_j[cnt] = row_index-1;
|
|---|
| 246 | diag_data[cnt++] = value[1];
|
|---|
| 247 | }
|
|---|
| 248 | else
|
|---|
| 249 | {
|
|---|
| 250 | if (ix)
|
|---|
| 251 | {
|
|---|
| 252 | offd_j[o_cnt] = hypre_map(ix-1,iy,iz,p-1,q,r,P,Q,R,
|
|---|
| 253 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 254 | offd_data[o_cnt++] = value[1];
|
|---|
| 255 | }
|
|---|
| 256 | }
|
|---|
| 257 | if (ix+1 < nx_part[p+1])
|
|---|
| 258 | {
|
|---|
| 259 | diag_j[cnt] = row_index+1;
|
|---|
| 260 | diag_data[cnt++] = value[4];
|
|---|
| 261 | }
|
|---|
| 262 | else
|
|---|
| 263 | {
|
|---|
| 264 | if (ix+1 < nx)
|
|---|
| 265 | {
|
|---|
| 266 | offd_j[o_cnt] = hypre_map(ix+1,iy,iz,p+1,q,r,P,Q,R,
|
|---|
| 267 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 268 | offd_data[o_cnt++] = value[4];
|
|---|
| 269 | }
|
|---|
| 270 | }
|
|---|
| 271 | if (iy+1 < ny_part[q+1])
|
|---|
| 272 | {
|
|---|
| 273 | diag_j[cnt] = row_index+nx_local;
|
|---|
| 274 | diag_data[cnt++] = value[5];
|
|---|
| 275 | }
|
|---|
| 276 | else
|
|---|
| 277 | {
|
|---|
| 278 | if (iy+1 < ny)
|
|---|
| 279 | {
|
|---|
| 280 | offd_j[o_cnt] = hypre_map(ix,iy+1,iz,p,q+1,r,P,Q,R,
|
|---|
| 281 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 282 | offd_data[o_cnt++] = value[5];
|
|---|
| 283 | }
|
|---|
| 284 | }
|
|---|
| 285 | if (iz+1 < nz_part[r+1])
|
|---|
| 286 | {
|
|---|
| 287 | diag_j[cnt] = row_index+nx_local*ny_local;
|
|---|
| 288 | diag_data[cnt++] = value[6];
|
|---|
| 289 | }
|
|---|
| 290 | else
|
|---|
| 291 | {
|
|---|
| 292 | if (iz+1 < nz)
|
|---|
| 293 | {
|
|---|
| 294 | offd_j[o_cnt] = hypre_map(ix,iy,iz+1,p,q,r+1,P,Q,R,
|
|---|
| 295 | nx_part,ny_part,nz_part,global_part, &col_map_offd[o_cnt]);
|
|---|
| 296 | offd_data[o_cnt++] = value[6];
|
|---|
| 297 | }
|
|---|
| 298 | }
|
|---|
| 299 | row_index++;
|
|---|
| 300 | }
|
|---|
| 301 | }
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | if (num_procs > 1)
|
|---|
| 305 | {
|
|---|
| 306 | for (i=0; i < num_cols_offd; i++)
|
|---|
| 307 | col_map_offd[i] = offd_j[i];
|
|---|
| 308 |
|
|---|
| 309 | qsort0(col_map_offd, 0, num_cols_offd-1);
|
|---|
| 310 |
|
|---|
| 311 | for (i=0; i < num_cols_offd; i++)
|
|---|
| 312 | for (j=0; j < num_cols_offd; j++)
|
|---|
| 313 | if (offd_j[i] == col_map_offd[j])
|
|---|
| 314 | {
|
|---|
| 315 | offd_j[i] = j;
|
|---|
| 316 | break;
|
|---|
| 317 | }
|
|---|
| 318 | }
|
|---|
| 319 |
|
|---|
| 320 | A = hypre_ParCSRMatrixCreate(comm, grid_size, grid_size,
|
|---|
| 321 | global_part, global_part, num_cols_offd,
|
|---|
| 322 | diag_i[local_num_rows],
|
|---|
| 323 | offd_i[local_num_rows]);
|
|---|
| 324 |
|
|---|
| 325 | hypre_ParCSRMatrixColMapOffd(A) = col_map_offd;
|
|---|
| 326 |
|
|---|
| 327 | diag = hypre_ParCSRMatrixDiag(A);
|
|---|
| 328 | hypre_CSRMatrixI(diag) = diag_i;
|
|---|
| 329 | hypre_CSRMatrixJ(diag) = diag_j;
|
|---|
| 330 | hypre_CSRMatrixData(diag) = diag_data;
|
|---|
| 331 |
|
|---|
| 332 | offd = hypre_ParCSRMatrixOffd(A);
|
|---|
| 333 | hypre_CSRMatrixI(offd) = offd_i;
|
|---|
| 334 | if (num_cols_offd)
|
|---|
| 335 | {
|
|---|
| 336 | hypre_CSRMatrixJ(offd) = offd_j;
|
|---|
| 337 | hypre_CSRMatrixData(offd) = offd_data;
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | hypre_TFree(nx_part);
|
|---|
| 341 | hypre_TFree(ny_part);
|
|---|
| 342 | hypre_TFree(nz_part);
|
|---|
| 343 |
|
|---|
| 344 | return (HYPRE_ParCSRMatrix) A;
|
|---|
| 345 | }
|
|---|
| 346 |
|
|---|