1 2 /* 3 Some useful vector utility functions. 4 */ 5 #include <petsc-private/vecimpl.h> /*I "petscvec.h" I*/ 6 #include <../src/vec/vec/impls/mpi/pvecimpl.h> 7 extern MPI_Op VecMax_Local_Op; 8 extern MPI_Op VecMin_Local_Op; 9 10 #undef __FUNCT__ 11 #define __FUNCT__ "VecStrideSet" 12 /*@ 13 VecStrideSet - Sets a subvector of a vector defined 14 by a starting point and a stride with a given value 15 16 Logically Collective on Vec 17 18 Input Parameter: 19 + v - the vector 20 . start - starting point of the subvector (defined by a stride) 21 - s - value to multiply each subvector entry by 22 23 Notes: 24 One must call VecSetBlockSize() before this routine to set the stride 25 information, or use a vector created from a multicomponent DMDA. 26 27 This will only work if the desire subvector is a stride subvector 28 29 Level: advanced 30 31 Concepts: scale^on stride of vector 32 Concepts: stride^scale 33 34 .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideScale() 35 @*/ 36 PetscErrorCode VecStrideSet(Vec v,PetscInt start,PetscScalar s) 37 { 38 PetscErrorCode ierr; 39 PetscInt i,n,bs; 40 PetscScalar *x; 41 42 PetscFunctionBegin; 43 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 44 PetscValidLogicalCollectiveInt(v,start,2); 45 PetscValidLogicalCollectiveScalar(v,s,3); 46 47 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 48 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 49 bs = v->map->bs; 50 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 51 else if (start >= bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs); 52 x += start; 53 54 for (i=0; i<n; i+=bs) { 55 x[i] = s; 56 } 57 x -= start; 58 59 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 60 PetscFunctionReturn(0); 61 } 62 63 #undef __FUNCT__ 64 #define __FUNCT__ "VecStrideScale" 65 /*@ 66 VecStrideScale - Scales a subvector of a vector defined 67 by a starting point and a stride. 68 69 Logically Collective on Vec 70 71 Input Parameter: 72 + v - the vector 73 . start - starting point of the subvector (defined by a stride) 74 - scale - value to multiply each subvector entry by 75 76 Notes: 77 One must call VecSetBlockSize() before this routine to set the stride 78 information, or use a vector created from a multicomponent DMDA. 79 80 This will only work if the desire subvector is a stride subvector 81 82 Level: advanced 83 84 Concepts: scale^on stride of vector 85 Concepts: stride^scale 86 87 .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideScale() 88 @*/ 89 PetscErrorCode VecStrideScale(Vec v,PetscInt start,PetscScalar scale) 90 { 91 PetscErrorCode ierr; 92 PetscInt i,n,bs; 93 PetscScalar *x; 94 95 PetscFunctionBegin; 96 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 97 PetscValidLogicalCollectiveInt(v,start,2); 98 PetscValidLogicalCollectiveScalar(v,scale,3); 99 100 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 101 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 102 bs = v->map->bs; 103 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 104 else if (start >= bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs); 105 x += start; 106 107 for (i=0; i<n; i+=bs) { 108 x[i] *= scale; 109 } 110 x -= start; 111 112 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 113 PetscFunctionReturn(0); 114 } 115 116 #undef __FUNCT__ 117 #define __FUNCT__ "VecStrideNorm" 118 /*@ 119 VecStrideNorm - Computes the norm of subvector of a vector defined 120 by a starting point and a stride. 121 122 Collective on Vec 123 124 Input Parameter: 125 + v - the vector 126 . start - starting point of the subvector (defined by a stride) 127 - ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY 128 129 Output Parameter: 130 . norm - the norm 131 132 Notes: 133 One must call VecSetBlockSize() before this routine to set the stride 134 information, or use a vector created from a multicomponent DMDA. 135 136 If x is the array representing the vector x then this computes the norm 137 of the array (x[start],x[start+stride],x[start+2*stride], ....) 138 139 This is useful for computing, say the norm of the pressure variable when 140 the pressure is stored (interlaced) with other variables, say density etc. 141 142 This will only work if the desire subvector is a stride subvector 143 144 Level: advanced 145 146 Concepts: norm^on stride of vector 147 Concepts: stride^norm 148 149 .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax() 150 @*/ 151 PetscErrorCode VecStrideNorm(Vec v,PetscInt start,NormType ntype,PetscReal *nrm) 152 { 153 PetscErrorCode ierr; 154 PetscInt i,n,bs; 155 PetscScalar *x; 156 PetscReal tnorm; 157 MPI_Comm comm; 158 159 PetscFunctionBegin; 160 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 161 PetscValidRealPointer(nrm,3); 162 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 163 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 164 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 165 166 bs = v->map->bs; 167 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 168 else if (start >= bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs); 169 x += start; 170 171 if (ntype == NORM_2) { 172 PetscScalar sum = 0.0; 173 for (i=0; i<n; i+=bs) { 174 sum += x[i]*(PetscConj(x[i])); 175 } 176 tnorm = PetscRealPart(sum); 177 ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPIU_SUM,comm);CHKERRQ(ierr); 178 *nrm = PetscSqrtReal(*nrm); 179 } else if (ntype == NORM_1) { 180 tnorm = 0.0; 181 for (i=0; i<n; i+=bs) { 182 tnorm += PetscAbsScalar(x[i]); 183 } 184 ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPIU_SUM,comm);CHKERRQ(ierr); 185 } else if (ntype == NORM_INFINITY) { 186 PetscReal tmp; 187 tnorm = 0.0; 188 189 for (i=0; i<n; i+=bs) { 190 if ((tmp = PetscAbsScalar(x[i])) > tnorm) tnorm = tmp; 191 /* check special case of tmp == NaN */ 192 if (tmp != tmp) {tnorm = tmp; break;} 193 } 194 ierr = MPI_Allreduce(&tnorm,nrm,1,MPIU_REAL,MPIU_MAX,comm);CHKERRQ(ierr); 195 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown norm type"); 196 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 197 PetscFunctionReturn(0); 198 } 199 200 #undef __FUNCT__ 201 #define __FUNCT__ "VecStrideMax" 202 /*@ 203 VecStrideMax - Computes the maximum of subvector of a vector defined 204 by a starting point and a stride and optionally its location. 205 206 Collective on Vec 207 208 Input Parameter: 209 + v - the vector 210 - start - starting point of the subvector (defined by a stride) 211 212 Output Parameter: 213 + index - the location where the maximum occurred (pass PETSC_NULL if not required) 214 - nrm - the max 215 216 Notes: 217 One must call VecSetBlockSize() before this routine to set the stride 218 information, or use a vector created from a multicomponent DMDA. 219 220 If xa is the array representing the vector x, then this computes the max 221 of the array (xa[start],xa[start+stride],xa[start+2*stride], ....) 222 223 This is useful for computing, say the maximum of the pressure variable when 224 the pressure is stored (interlaced) with other variables, e.g., density, etc. 225 This will only work if the desire subvector is a stride subvector. 226 227 Level: advanced 228 229 Concepts: maximum^on stride of vector 230 Concepts: stride^maximum 231 232 .seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin() 233 @*/ 234 PetscErrorCode VecStrideMax(Vec v,PetscInt start,PetscInt *idex,PetscReal *nrm) 235 { 236 PetscErrorCode ierr; 237 PetscInt i,n,bs,id; 238 PetscScalar *x; 239 PetscReal max,tmp; 240 MPI_Comm comm; 241 242 PetscFunctionBegin; 243 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 244 PetscValidRealPointer(nrm,3); 245 246 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 247 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 248 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 249 250 bs = v->map->bs; 251 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 252 else if (start >= bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs); 253 x += start; 254 255 id = -1; 256 if (!n) { 257 max = PETSC_MIN_REAL; 258 } else { 259 id = 0; 260 max = PetscRealPart(x[0]); 261 for (i=bs; i<n; i+=bs) { 262 if ((tmp = PetscRealPart(x[i])) > max) { max = tmp; id = i;} 263 } 264 } 265 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 266 267 if (!idex) { 268 ierr = MPI_Allreduce(&max,nrm,1,MPIU_REAL,MPIU_MAX,comm);CHKERRQ(ierr); 269 } else { 270 PetscReal in[2],out[2]; 271 PetscInt rstart; 272 273 ierr = VecGetOwnershipRange(v,&rstart,PETSC_NULL);CHKERRQ(ierr); 274 in[0] = max; 275 in[1] = rstart+id+start; 276 ierr = MPI_Allreduce(in,out,2,MPIU_REAL,VecMax_Local_Op,((PetscObject)v)->comm);CHKERRQ(ierr); 277 *nrm = out[0]; 278 *idex = (PetscInt)out[1]; 279 } 280 281 PetscFunctionReturn(0); 282 } 283 284 #undef __FUNCT__ 285 #define __FUNCT__ "VecStrideMin" 286 /*@ 287 VecStrideMin - Computes the minimum of subvector of a vector defined 288 by a starting point and a stride and optionally its location. 289 290 Collective on Vec 291 292 Input Parameter: 293 + v - the vector 294 - start - starting point of the subvector (defined by a stride) 295 296 Output Parameter: 297 + idex - the location where the minimum occurred. (pass PETSC_NULL if not required) 298 - nrm - the min 299 300 Level: advanced 301 302 Notes: 303 One must call VecSetBlockSize() before this routine to set the stride 304 information, or use a vector created from a multicomponent DMDA. 305 306 If xa is the array representing the vector x, then this computes the min 307 of the array (xa[start],xa[start+stride],xa[start+2*stride], ....) 308 309 This is useful for computing, say the minimum of the pressure variable when 310 the pressure is stored (interlaced) with other variables, e.g., density, etc. 311 This will only work if the desire subvector is a stride subvector. 312 313 Concepts: minimum^on stride of vector 314 Concepts: stride^minimum 315 316 .seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax() 317 @*/ 318 PetscErrorCode VecStrideMin(Vec v,PetscInt start,PetscInt *idex,PetscReal *nrm) 319 { 320 PetscErrorCode ierr; 321 PetscInt i,n,bs,id; 322 PetscScalar *x; 323 PetscReal min,tmp; 324 MPI_Comm comm; 325 326 PetscFunctionBegin; 327 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 328 PetscValidRealPointer(nrm,4); 329 330 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 331 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 332 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 333 334 bs = v->map->bs; 335 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 336 else if (start >= bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Start of stride subvector (%D) is too large for stride\nHave you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,bs); 337 x += start; 338 339 id = -1; 340 if (!n) { 341 min = PETSC_MAX_REAL; 342 } else { 343 id = 0; 344 min = PetscRealPart(x[0]); 345 for (i=bs; i<n; i+=bs) { 346 if ((tmp = PetscRealPart(x[i])) < min) { min = tmp; id = i;} 347 } 348 } 349 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 350 351 if (!idex) { 352 ierr = MPI_Allreduce(&min,nrm,1,MPIU_REAL,MPIU_MIN,comm);CHKERRQ(ierr); 353 } else { 354 PetscReal in[2],out[2]; 355 PetscInt rstart; 356 357 ierr = VecGetOwnershipRange(v,&rstart,PETSC_NULL);CHKERRQ(ierr); 358 in[0] = min; 359 in[1] = rstart+id; 360 ierr = MPI_Allreduce(in,out,2,MPIU_REAL,VecMin_Local_Op,((PetscObject)v)->comm);CHKERRQ(ierr); 361 *nrm = out[0]; 362 *idex = (PetscInt)out[1]; 363 } 364 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "VecStrideScaleAll" 370 /*@ 371 VecStrideScaleAll - Scales the subvectors of a vector defined 372 by a starting point and a stride. 373 374 Logically Collective on Vec 375 376 Input Parameter: 377 + v - the vector 378 - scales - values to multiply each subvector entry by 379 380 Notes: 381 One must call VecSetBlockSize() before this routine to set the stride 382 information, or use a vector created from a multicomponent DMDA. 383 384 385 Level: advanced 386 387 Concepts: scale^on stride of vector 388 Concepts: stride^scale 389 390 .seealso: VecNorm(), VecStrideScale(), VecScale(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax() 391 @*/ 392 PetscErrorCode VecStrideScaleAll(Vec v,const PetscScalar *scales) 393 { 394 PetscErrorCode ierr; 395 PetscInt i,j,n,bs; 396 PetscScalar *x; 397 398 PetscFunctionBegin; 399 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 400 PetscValidScalarPointer(scales,2); 401 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 402 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 403 404 bs = v->map->bs; 405 406 /* need to provide optimized code for each bs */ 407 for (i=0; i<n; i+=bs) { 408 for (j=0; j<bs; j++) { 409 x[i+j] *= scales[j]; 410 } 411 } 412 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 413 PetscFunctionReturn(0); 414 } 415 416 #undef __FUNCT__ 417 #define __FUNCT__ "VecStrideNormAll" 418 /*@ 419 VecStrideNormAll - Computes the norms subvectors of a vector defined 420 by a starting point and a stride. 421 422 Collective on Vec 423 424 Input Parameter: 425 + v - the vector 426 - ntype - type of norm, one of NORM_1, NORM_2, NORM_INFINITY 427 428 Output Parameter: 429 . nrm - the norms 430 431 Notes: 432 One must call VecSetBlockSize() before this routine to set the stride 433 information, or use a vector created from a multicomponent DMDA. 434 435 If x is the array representing the vector x then this computes the norm 436 of the array (x[start],x[start+stride],x[start+2*stride], ....) 437 438 This is useful for computing, say the norm of the pressure variable when 439 the pressure is stored (interlaced) with other variables, say density etc. 440 441 This will only work if the desire subvector is a stride subvector 442 443 Level: advanced 444 445 Concepts: norm^on stride of vector 446 Concepts: stride^norm 447 448 .seealso: VecNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin(), VecStrideMax() 449 @*/ 450 PetscErrorCode VecStrideNormAll(Vec v,NormType ntype,PetscReal nrm[]) 451 { 452 PetscErrorCode ierr; 453 PetscInt i,j,n,bs; 454 PetscScalar *x; 455 PetscReal tnorm[128]; 456 MPI_Comm comm; 457 458 PetscFunctionBegin; 459 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 460 PetscValidRealPointer(nrm,3); 461 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 462 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 463 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 464 465 bs = v->map->bs; 466 if (bs > 128) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently supports only blocksize up to 128"); 467 468 if (ntype == NORM_2) { 469 PetscScalar sum[128]; 470 for (j=0; j<bs; j++) sum[j] = 0.0; 471 for (i=0; i<n; i+=bs) { 472 for (j=0; j<bs; j++) { 473 sum[j] += x[i+j]*(PetscConj(x[i+j])); 474 } 475 } 476 for (j=0; j<bs; j++) { 477 tnorm[j] = PetscRealPart(sum[j]); 478 } 479 ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPIU_SUM,comm);CHKERRQ(ierr); 480 for (j=0; j<bs; j++) { 481 nrm[j] = PetscSqrtReal(nrm[j]); 482 } 483 } else if (ntype == NORM_1) { 484 for (j=0; j<bs; j++) { 485 tnorm[j] = 0.0; 486 } 487 for (i=0; i<n; i+=bs) { 488 for (j=0; j<bs; j++) { 489 tnorm[j] += PetscAbsScalar(x[i+j]); 490 } 491 } 492 ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPIU_SUM,comm);CHKERRQ(ierr); 493 } else if (ntype == NORM_INFINITY) { 494 PetscReal tmp; 495 for (j=0; j<bs; j++) { 496 tnorm[j] = 0.0; 497 } 498 499 for (i=0; i<n; i+=bs) { 500 for (j=0; j<bs; j++) { 501 if ((tmp = PetscAbsScalar(x[i+j])) > tnorm[j]) tnorm[j] = tmp; 502 /* check special case of tmp == NaN */ 503 if (tmp != tmp) {tnorm[j] = tmp; break;} 504 } 505 } 506 ierr = MPI_Allreduce(tnorm,nrm,bs,MPIU_REAL,MPIU_MAX,comm);CHKERRQ(ierr); 507 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown norm type"); 508 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 509 PetscFunctionReturn(0); 510 } 511 512 #undef __FUNCT__ 513 #define __FUNCT__ "VecStrideMaxAll" 514 /*@ 515 VecStrideMaxAll - Computes the maximums of subvectors of a vector defined 516 by a starting point and a stride and optionally its location. 517 518 Collective on Vec 519 520 Input Parameter: 521 . v - the vector 522 523 Output Parameter: 524 + index - the location where the maximum occurred (not supported, pass PETSC_NULL, 525 if you need this, send mail to petsc-maint@mcs.anl.gov to request it) 526 - nrm - the maximums 527 528 Notes: 529 One must call VecSetBlockSize() before this routine to set the stride 530 information, or use a vector created from a multicomponent DMDA. 531 532 This is useful for computing, say the maximum of the pressure variable when 533 the pressure is stored (interlaced) with other variables, e.g., density, etc. 534 This will only work if the desire subvector is a stride subvector. 535 536 Level: advanced 537 538 Concepts: maximum^on stride of vector 539 Concepts: stride^maximum 540 541 .seealso: VecMax(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMin() 542 @*/ 543 PetscErrorCode VecStrideMaxAll(Vec v,PetscInt idex[],PetscReal nrm[]) 544 { 545 PetscErrorCode ierr; 546 PetscInt i,j,n,bs; 547 PetscScalar *x; 548 PetscReal max[128],tmp; 549 MPI_Comm comm; 550 551 PetscFunctionBegin; 552 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 553 PetscValidRealPointer(nrm,3); 554 if (idex) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it"); 555 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 556 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 557 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 558 559 bs = v->map->bs; 560 if (bs > 128) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently supports only blocksize up to 128"); 561 562 if (!n) { 563 for (j=0; j<bs; j++) { 564 max[j] = PETSC_MIN_REAL; 565 } 566 } else { 567 for (j=0; j<bs; j++) { 568 max[j] = PetscRealPart(x[j]); 569 } 570 for (i=bs; i<n; i+=bs) { 571 for (j=0; j<bs; j++) { 572 if ((tmp = PetscRealPart(x[i+j])) > max[j]) { max[j] = tmp;} 573 } 574 } 575 } 576 ierr = MPI_Allreduce(max,nrm,bs,MPIU_REAL,MPIU_MAX,comm);CHKERRQ(ierr); 577 578 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 579 PetscFunctionReturn(0); 580 } 581 582 #undef __FUNCT__ 583 #define __FUNCT__ "VecStrideMinAll" 584 /*@ 585 VecStrideMinAll - Computes the minimum of subvector of a vector defined 586 by a starting point and a stride and optionally its location. 587 588 Collective on Vec 589 590 Input Parameter: 591 . v - the vector 592 593 Output Parameter: 594 + idex - the location where the minimum occurred (not supported, pass PETSC_NULL, 595 if you need this, send mail to petsc-maint@mcs.anl.gov to request it) 596 - nrm - the minimums 597 598 Level: advanced 599 600 Notes: 601 One must call VecSetBlockSize() before this routine to set the stride 602 information, or use a vector created from a multicomponent DMDA. 603 604 This is useful for computing, say the minimum of the pressure variable when 605 the pressure is stored (interlaced) with other variables, e.g., density, etc. 606 This will only work if the desire subvector is a stride subvector. 607 608 Concepts: minimum^on stride of vector 609 Concepts: stride^minimum 610 611 .seealso: VecMin(), VecStrideNorm(), VecStrideGather(), VecStrideScatter(), VecStrideMax() 612 @*/ 613 PetscErrorCode VecStrideMinAll(Vec v,PetscInt idex[],PetscReal nrm[]) 614 { 615 PetscErrorCode ierr; 616 PetscInt i,n,bs,j; 617 PetscScalar *x; 618 PetscReal min[128],tmp; 619 MPI_Comm comm; 620 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 623 PetscValidRealPointer(nrm,3); 624 if (idex) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support yet for returning index; send mail to petsc-maint@mcs.anl.gov asking for it"); 625 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 626 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 627 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 628 629 bs = v->map->bs; 630 if (bs > 128) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently supports only blocksize up to 128"); 631 632 if (!n) { 633 for (j=0; j<bs; j++) { 634 min[j] = PETSC_MAX_REAL; 635 } 636 } else { 637 for (j=0; j<bs; j++) { 638 min[j] = PetscRealPart(x[j]); 639 } 640 for (i=bs; i<n; i+=bs) { 641 for (j=0; j<bs; j++) { 642 if ((tmp = PetscRealPart(x[i+j])) < min[j]) { min[j] = tmp;} 643 } 644 } 645 } 646 ierr = MPI_Allreduce(min,nrm,bs,MPIU_REAL,MPIU_MIN,comm);CHKERRQ(ierr); 647 648 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 649 PetscFunctionReturn(0); 650 } 651 652 /*----------------------------------------------------------------------------------------------*/ 653 #undef __FUNCT__ 654 #define __FUNCT__ "VecStrideGatherAll" 655 /*@ 656 VecStrideGatherAll - Gathers all the single components from a multi-component vector into 657 separate vectors. 658 659 Collective on Vec 660 661 Input Parameter: 662 + v - the vector 663 - addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES 664 665 Output Parameter: 666 . s - the location where the subvectors are stored 667 668 Notes: 669 One must call VecSetBlockSize() before this routine to set the stride 670 information, or use a vector created from a multicomponent DMDA. 671 672 If x is the array representing the vector x then this gathers 673 the arrays (x[start],x[start+stride],x[start+2*stride], ....) 674 for start=0,1,2,...bs-1 675 676 The parallel layout of the vector and the subvector must be the same; 677 i.e., nlocal of v = stride*(nlocal of s) 678 679 Not optimized; could be easily 680 681 Level: advanced 682 683 Concepts: gather^into strided vector 684 685 .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(), 686 VecStrideScatterAll() 687 @*/ 688 PetscErrorCode VecStrideGatherAll(Vec v,Vec s[],InsertMode addv) 689 { 690 PetscErrorCode ierr; 691 PetscInt i,n,n2,bs,j,k,*bss = PETSC_NULL,nv,jj,nvc; 692 PetscScalar *x,**y; 693 694 PetscFunctionBegin; 695 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 696 PetscValidPointer(s,2); 697 PetscValidHeaderSpecific(*s,VEC_CLASSID,2); 698 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 699 ierr = VecGetLocalSize(s[0],&n2);CHKERRQ(ierr); 700 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 701 bs = v->map->bs; 702 if (bs < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Input vector does not have a valid blocksize set"); 703 704 ierr = PetscMalloc2(bs,PetscReal*,&y,bs,PetscInt,&bss);CHKERRQ(ierr); 705 nv = 0; 706 nvc = 0; 707 for (i=0; i<bs; i++) { 708 ierr = VecGetBlockSize(s[i],&bss[i]);CHKERRQ(ierr); 709 if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1 Re: [PETSC #8241] VecStrideGatherAll */ 710 ierr = VecGetArray(s[i],&y[i]);CHKERRQ(ierr); 711 nvc += bss[i]; 712 nv++; 713 if (nvc > bs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subvectors in subvectors > number of vectors in main vector"); 714 if (nvc == bs) break; 715 } 716 717 n = n/bs; 718 719 jj = 0; 720 if (addv == INSERT_VALUES) { 721 for (j=0; j<nv; j++) { 722 for (k=0; k<bss[j]; k++) { 723 for (i=0; i<n; i++) { 724 y[j][i*bss[j] + k] = x[bs*i+jj+k]; 725 } 726 } 727 jj += bss[j]; 728 } 729 } else if (addv == ADD_VALUES) { 730 for (j=0; j<nv; j++) { 731 for (k=0; k<bss[j]; k++) { 732 for (i=0; i<n; i++) { 733 y[j][i*bss[j] + k] += x[bs*i+jj+k]; 734 } 735 } 736 jj += bss[j]; 737 } 738 #if !defined(PETSC_USE_COMPLEX) 739 } else if (addv == MAX_VALUES) { 740 for (j=0; j<nv; j++) { 741 for (k=0; k<bss[j]; k++) { 742 for (i=0; i<n; i++) { 743 y[j][i*bss[j] + k] = PetscMax(y[j][i*bss[j] + k],x[bs*i+jj+k]); 744 } 745 } 746 jj += bss[j]; 747 } 748 #endif 749 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type"); 750 751 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 752 for (i=0; i<nv; i++) { 753 ierr = VecRestoreArray(s[i],&y[i]);CHKERRQ(ierr); 754 } 755 756 ierr = PetscFree2(y,bss);CHKERRQ(ierr); 757 PetscFunctionReturn(0); 758 } 759 760 #undef __FUNCT__ 761 #define __FUNCT__ "VecStrideScatterAll" 762 /*@ 763 VecStrideScatterAll - Scatters all the single components from separate vectors into 764 a multi-component vector. 765 766 Collective on Vec 767 768 Input Parameter: 769 + s - the location where the subvectors are stored 770 - addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES 771 772 Output Parameter: 773 . v - the multicomponent vector 774 775 Notes: 776 One must call VecSetBlockSize() before this routine to set the stride 777 information, or use a vector created from a multicomponent DMDA. 778 779 The parallel layout of the vector and the subvector must be the same; 780 i.e., nlocal of v = stride*(nlocal of s) 781 782 Not optimized; could be easily 783 784 Level: advanced 785 786 Concepts: scatter^into strided vector 787 788 .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGather(), 789 VecStrideScatterAll() 790 @*/ 791 PetscErrorCode VecStrideScatterAll(Vec s[],Vec v,InsertMode addv) 792 { 793 PetscErrorCode ierr; 794 PetscInt i,n,n2,bs,j,jj,k,*bss = PETSC_NULL,nv,nvc; 795 PetscScalar *x,**y; 796 797 PetscFunctionBegin; 798 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 799 PetscValidPointer(s,2); 800 PetscValidHeaderSpecific(*s,VEC_CLASSID,2); 801 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 802 ierr = VecGetLocalSize(s[0],&n2);CHKERRQ(ierr); 803 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 804 bs = v->map->bs; 805 if (bs < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Input vector does not have a valid blocksize set"); 806 807 ierr = PetscMalloc2(bs,PetscScalar**,&y,bs,PetscInt,&bss);CHKERRQ(ierr); 808 nv = 0; 809 nvc = 0; 810 for (i=0; i<bs; i++) { 811 ierr = VecGetBlockSize(s[i],&bss[i]);CHKERRQ(ierr); 812 if (bss[i] < 1) bss[i] = 1; /* if user never set it then assume 1 Re: [PETSC #8241] VecStrideGatherAll */ 813 ierr = VecGetArray(s[i],&y[i]);CHKERRQ(ierr); 814 nvc += bss[i]; 815 nv++; 816 if (nvc > bs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of subvectors in subvectors > number of vectors in main vector"); 817 if (nvc == bs) break; 818 } 819 820 n = n/bs; 821 822 jj = 0; 823 if (addv == INSERT_VALUES) { 824 for (j=0; j<nv; j++) { 825 for (k=0; k<bss[j]; k++) { 826 for (i=0; i<n; i++) { 827 x[bs*i+jj+k] = y[j][i*bss[j] + k]; 828 } 829 } 830 jj += bss[j]; 831 } 832 } else if (addv == ADD_VALUES) { 833 for (j=0; j<nv; j++) { 834 for (k=0; k<bss[j]; k++) { 835 for (i=0; i<n; i++) { 836 x[bs*i+jj+k] += y[j][i*bss[j] + k]; 837 } 838 } 839 jj += bss[j]; 840 } 841 #if !defined(PETSC_USE_COMPLEX) 842 } else if (addv == MAX_VALUES) { 843 for (j=0; j<nv; j++) { 844 for (k=0; k<bss[j]; k++) { 845 for (i=0; i<n; i++) { 846 x[bs*i+jj+k] = PetscMax(x[bs*i+jj+k],y[j][i*bss[j] + k]); 847 } 848 } 849 jj += bss[j]; 850 } 851 #endif 852 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type"); 853 854 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 855 for (i=0; i<nv; i++) { 856 ierr = VecRestoreArray(s[i],&y[i]);CHKERRQ(ierr); 857 } 858 ierr = PetscFree2(y,bss);CHKERRQ(ierr); 859 PetscFunctionReturn(0); 860 } 861 862 #undef __FUNCT__ 863 #define __FUNCT__ "VecStrideGather" 864 /*@ 865 VecStrideGather - Gathers a single component from a multi-component vector into 866 another vector. 867 868 Collective on Vec 869 870 Input Parameter: 871 + v - the vector 872 . start - starting point of the subvector (defined by a stride) 873 - addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES 874 875 Output Parameter: 876 . s - the location where the subvector is stored 877 878 Notes: 879 One must call VecSetBlockSize() before this routine to set the stride 880 information, or use a vector created from a multicomponent DMDA. 881 882 If x is the array representing the vector x then this gathers 883 the array (x[start],x[start+stride],x[start+2*stride], ....) 884 885 The parallel layout of the vector and the subvector must be the same; 886 i.e., nlocal of v = stride*(nlocal of s) 887 888 Not optimized; could be easily 889 890 Level: advanced 891 892 Concepts: gather^into strided vector 893 894 .seealso: VecStrideNorm(), VecStrideScatter(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(), 895 VecStrideScatterAll() 896 @*/ 897 PetscErrorCode VecStrideGather(Vec v,PetscInt start,Vec s,InsertMode addv) 898 { 899 PetscErrorCode ierr; 900 901 PetscFunctionBegin; 902 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 903 PetscValidHeaderSpecific(s,VEC_CLASSID,3); 904 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 905 if (start >= v->map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,v->map->bs); 906 if (!v->ops->stridegather) SETERRQ(((PetscObject)s)->comm,PETSC_ERR_SUP,"Not implemented for this Vec class"); 907 ierr = (*v->ops->stridegather)(v,start,s,addv);CHKERRQ(ierr); 908 PetscFunctionReturn(0); 909 } 910 911 #undef __FUNCT__ 912 #define __FUNCT__ "VecStrideScatter" 913 /*@ 914 VecStrideScatter - Scatters a single component from a vector into a multi-component vector. 915 916 Collective on Vec 917 918 Input Parameter: 919 + s - the single-component vector 920 . start - starting point of the subvector (defined by a stride) 921 - addv - one of ADD_VALUES,INSERT_VALUES,MAX_VALUES 922 923 Output Parameter: 924 . v - the location where the subvector is scattered (the multi-component vector) 925 926 Notes: 927 One must call VecSetBlockSize() on the multi-component vector before this 928 routine to set the stride information, or use a vector created from a multicomponent DMDA. 929 930 The parallel layout of the vector and the subvector must be the same; 931 i.e., nlocal of v = stride*(nlocal of s) 932 933 Not optimized; could be easily 934 935 Level: advanced 936 937 Concepts: scatter^into strided vector 938 939 .seealso: VecStrideNorm(), VecStrideGather(), VecStrideMin(), VecStrideMax(), VecStrideGatherAll(), 940 VecStrideScatterAll() 941 @*/ 942 PetscErrorCode VecStrideScatter(Vec s,PetscInt start,Vec v,InsertMode addv) 943 { 944 PetscErrorCode ierr; 945 946 PetscFunctionBegin; 947 PetscValidHeaderSpecific(s,VEC_CLASSID,1); 948 PetscValidHeaderSpecific(v,VEC_CLASSID,3); 949 if (start < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative start %D",start); 950 if (start >= v->map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Start of stride subvector (%D) is too large for stride\n Have you set the vector blocksize (%D) correctly with VecSetBlockSize()?",start,v->map->bs); 951 if (!v->ops->stridescatter) SETERRQ(((PetscObject)s)->comm,PETSC_ERR_SUP,"Not implemented for this Vec class"); 952 ierr = (*v->ops->stridescatter)(s,start,v,addv);CHKERRQ(ierr); 953 PetscFunctionReturn(0); 954 } 955 956 #undef __FUNCT__ 957 #define __FUNCT__ "VecStrideGather_Default" 958 PetscErrorCode VecStrideGather_Default(Vec v,PetscInt start,Vec s,InsertMode addv) 959 { 960 PetscErrorCode ierr; 961 PetscInt i,n,bs,ns; 962 PetscScalar *x,*y; 963 964 PetscFunctionBegin; 965 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 966 ierr = VecGetLocalSize(s,&ns);CHKERRQ(ierr); 967 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 968 ierr = VecGetArray(s,&y);CHKERRQ(ierr); 969 970 bs = v->map->bs; 971 if (n != ns*bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subvector length * blocksize %D not correct for gather from original vector %D",ns*bs,n); 972 x += start; 973 n = n/bs; 974 975 if (addv == INSERT_VALUES) { 976 for (i=0; i<n; i++) { 977 y[i] = x[bs*i]; 978 } 979 } else if (addv == ADD_VALUES) { 980 for (i=0; i<n; i++) { 981 y[i] += x[bs*i]; 982 } 983 #if !defined(PETSC_USE_COMPLEX) 984 } else if (addv == MAX_VALUES) { 985 for (i=0; i<n; i++) { 986 y[i] = PetscMax(y[i],x[bs*i]); 987 } 988 #endif 989 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type"); 990 991 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 992 ierr = VecRestoreArray(s,&y);CHKERRQ(ierr); 993 PetscFunctionReturn(0); 994 } 995 996 #undef __FUNCT__ 997 #define __FUNCT__ "VecStrideScatter_Default" 998 PetscErrorCode VecStrideScatter_Default(Vec s,PetscInt start,Vec v,InsertMode addv) 999 { 1000 PetscErrorCode ierr; 1001 PetscInt i,n,bs,ns; 1002 PetscScalar *x,*y; 1003 1004 PetscFunctionBegin; 1005 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1006 ierr = VecGetLocalSize(s,&ns);CHKERRQ(ierr); 1007 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1008 ierr = VecGetArray(s,&y);CHKERRQ(ierr); 1009 1010 bs = v->map->bs; 1011 if (n != ns*bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Subvector length * blocksize %D not correct for scatter to multicomponent vector %D",ns*bs,n); 1012 x += start; 1013 n = n/bs; 1014 1015 if (addv == INSERT_VALUES) { 1016 for (i=0; i<n; i++) { 1017 x[bs*i] = y[i]; 1018 } 1019 } else if (addv == ADD_VALUES) { 1020 for (i=0; i<n; i++) { 1021 x[bs*i] += y[i]; 1022 } 1023 #if !defined(PETSC_USE_COMPLEX) 1024 } else if (addv == MAX_VALUES) { 1025 for (i=0; i<n; i++) { 1026 x[bs*i] = PetscMax(y[i],x[bs*i]); 1027 } 1028 #endif 1029 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown insert type"); 1030 1031 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1032 ierr = VecRestoreArray(s,&y);CHKERRQ(ierr); 1033 PetscFunctionReturn(0); 1034 } 1035 1036 #undef __FUNCT__ 1037 #define __FUNCT__ "VecReciprocal_Default" 1038 PetscErrorCode VecReciprocal_Default(Vec v) 1039 { 1040 PetscErrorCode ierr; 1041 PetscInt i,n; 1042 PetscScalar *x; 1043 1044 PetscFunctionBegin; 1045 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1046 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1047 for (i=0; i<n; i++) { 1048 if (x[i] != (PetscScalar)0.0) x[i] = (PetscScalar)1.0/x[i]; 1049 } 1050 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1051 PetscFunctionReturn(0); 1052 } 1053 1054 #undef __FUNCT__ 1055 #define __FUNCT__ "VecExp" 1056 /*@ 1057 VecExp - Replaces each component of a vector by e^x_i 1058 1059 Not collective 1060 1061 Input Parameter: 1062 . v - The vector 1063 1064 Output Parameter: 1065 . v - The vector of exponents 1066 1067 Level: beginner 1068 1069 .seealso: VecLog(), VecAbs(), VecSqrtAbs(), VecReciprocal() 1070 1071 .keywords: vector, sqrt, square root 1072 @*/ 1073 PetscErrorCode VecExp(Vec v) 1074 { 1075 PetscScalar *x; 1076 PetscInt i, n; 1077 PetscErrorCode ierr; 1078 1079 PetscFunctionBegin; 1080 PetscValidHeaderSpecific(v, VEC_CLASSID,1); 1081 if (v->ops->exp) { 1082 ierr = (*v->ops->exp)(v);CHKERRQ(ierr); 1083 } else { 1084 ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 1085 ierr = VecGetArray(v, &x);CHKERRQ(ierr); 1086 for (i = 0; i < n; i++) { 1087 x[i] = PetscExpScalar(x[i]); 1088 } 1089 ierr = VecRestoreArray(v, &x);CHKERRQ(ierr); 1090 } 1091 PetscFunctionReturn(0); 1092 } 1093 1094 #undef __FUNCT__ 1095 #define __FUNCT__ "VecLog" 1096 /*@ 1097 VecLog - Replaces each component of a vector by log(x_i), the natural logarithm 1098 1099 Not collective 1100 1101 Input Parameter: 1102 . v - The vector 1103 1104 Output Parameter: 1105 . v - The vector of logs 1106 1107 Level: beginner 1108 1109 .seealso: VecExp(), VecAbs(), VecSqrtAbs(), VecReciprocal() 1110 1111 .keywords: vector, sqrt, square root 1112 @*/ 1113 PetscErrorCode VecLog(Vec v) 1114 { 1115 PetscScalar *x; 1116 PetscInt i, n; 1117 PetscErrorCode ierr; 1118 1119 PetscFunctionBegin; 1120 PetscValidHeaderSpecific(v, VEC_CLASSID,1); 1121 if (v->ops->log) { 1122 ierr = (*v->ops->log)(v);CHKERRQ(ierr); 1123 } else { 1124 ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 1125 ierr = VecGetArray(v, &x);CHKERRQ(ierr); 1126 for (i = 0; i < n; i++) { 1127 x[i] = PetscLogScalar(x[i]); 1128 } 1129 ierr = VecRestoreArray(v, &x);CHKERRQ(ierr); 1130 } 1131 PetscFunctionReturn(0); 1132 } 1133 1134 #undef __FUNCT__ 1135 #define __FUNCT__ "VecSqrtAbs" 1136 /*@ 1137 VecSqrtAbs - Replaces each component of a vector by the square root of its magnitude. 1138 1139 Not collective 1140 1141 Input Parameter: 1142 . v - The vector 1143 1144 Output Parameter: 1145 . v - The vector square root 1146 1147 Level: beginner 1148 1149 Note: The actual function is sqrt(|x_i|) 1150 1151 .seealso: VecLog(), VecExp(), VecReciprocal(), VecAbs() 1152 1153 .keywords: vector, sqrt, square root 1154 @*/ 1155 PetscErrorCode VecSqrtAbs(Vec v) 1156 { 1157 PetscScalar *x; 1158 PetscInt i, n; 1159 PetscErrorCode ierr; 1160 1161 PetscFunctionBegin; 1162 PetscValidHeaderSpecific(v, VEC_CLASSID,1); 1163 if (v->ops->sqrt) { 1164 ierr = (*v->ops->sqrt)(v);CHKERRQ(ierr); 1165 } else { 1166 ierr = VecGetLocalSize(v, &n);CHKERRQ(ierr); 1167 ierr = VecGetArray(v, &x);CHKERRQ(ierr); 1168 for (i = 0; i < n; i++) { 1169 x[i] = PetscSqrtReal(PetscAbsScalar(x[i])); 1170 } 1171 ierr = VecRestoreArray(v, &x);CHKERRQ(ierr); 1172 } 1173 PetscFunctionReturn(0); 1174 } 1175 1176 #undef __FUNCT__ 1177 #define __FUNCT__ "VecDotNorm2" 1178 /*@ 1179 VecDotNorm2 - computes the inner product of two vectors and the 2-norm squared of the second vector 1180 1181 Collective on Vec 1182 1183 Input Parameter: 1184 + s - first vector 1185 - t - second vector 1186 1187 Output Parameter: 1188 + dp - s't 1189 - nm - t't 1190 1191 Level: advanced 1192 1193 Developer Notes: Even though the second return argument is a norm and hence could be a PetscReal value it is returned as PetscScalar 1194 1195 .seealso: VecDot(), VecNorm(), VecDotBegin(), VecNormBegin(), VecDotEnd(), VecNormEnd() 1196 1197 .keywords: vector, sqrt, square root 1198 @*/ 1199 PetscErrorCode VecDotNorm2(Vec s,Vec t,PetscScalar *dp, PetscScalar *nm) 1200 { 1201 PetscScalar *sx, *tx, dpx = 0.0, nmx = 0.0,work[2],sum[2]; 1202 PetscInt i, n; 1203 PetscErrorCode ierr; 1204 1205 PetscFunctionBegin; 1206 PetscValidHeaderSpecific(s, VEC_CLASSID,1); 1207 PetscValidHeaderSpecific(t, VEC_CLASSID,2); 1208 PetscValidScalarPointer(dp,3); 1209 PetscValidScalarPointer(nm,4); 1210 PetscValidType(s,1); 1211 PetscValidType(t,2); 1212 PetscCheckSameTypeAndComm(s,1,t,2); 1213 if (s->map->N != t->map->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector global lengths"); 1214 if (s->map->n != t->map->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Incompatible vector local lengths"); 1215 1216 ierr = PetscLogEventBarrierBegin(VEC_DotNormBarrier,s,t,0,0,((PetscObject)s)->comm);CHKERRQ(ierr); 1217 if (s->ops->dotnorm2) { 1218 ierr = (*s->ops->dotnorm2)(s,t,dp,nm);CHKERRQ(ierr); 1219 } else { 1220 PetscReal tmp = 0.0; 1221 ierr = VecGetLocalSize(s, &n);CHKERRQ(ierr); 1222 ierr = VecGetArray(s, &sx);CHKERRQ(ierr); 1223 ierr = VecGetArray(t, &tx);CHKERRQ(ierr); 1224 1225 ierr = VecNorm_MPI(s,NORM_2, &tmp);CHKERRQ(ierr); 1226 ierr = VecNorm_MPI(t,NORM_2, &tmp);CHKERRQ(ierr); 1227 1228 for (i = 0; i<n; i++) { 1229 dpx += sx[i]*PetscConj(tx[i]); 1230 nmx += tx[i]*PetscConj(tx[i]); 1231 } 1232 work[0] = dpx; 1233 work[1] = nmx; 1234 ierr = MPI_Allreduce(work,sum,2,MPIU_SCALAR,MPIU_SUM,((PetscObject)s)->comm);CHKERRQ(ierr); 1235 *dp = sum[0]; 1236 *nm = sum[1]; 1237 1238 ierr = VecRestoreArray(t, &tx);CHKERRQ(ierr); 1239 ierr = VecRestoreArray(s, &sx);CHKERRQ(ierr); 1240 ierr = PetscLogFlops(4.0*n);CHKERRQ(ierr); 1241 } 1242 ierr = PetscLogEventBarrierEnd(VEC_DotNormBarrier,s,t,0,0,((PetscObject)s)->comm);CHKERRQ(ierr); 1243 PetscFunctionReturn(0); 1244 } 1245 1246 #undef __FUNCT__ 1247 #define __FUNCT__ "VecSum" 1248 /*@ 1249 VecSum - Computes the sum of all the components of a vector. 1250 1251 Collective on Vec 1252 1253 Input Parameter: 1254 . v - the vector 1255 1256 Output Parameter: 1257 . sum - the result 1258 1259 Level: beginner 1260 1261 Concepts: sum^of vector entries 1262 1263 .seealso: VecNorm() 1264 @*/ 1265 PetscErrorCode VecSum(Vec v,PetscScalar *sum) 1266 { 1267 PetscErrorCode ierr; 1268 PetscInt i,n; 1269 PetscScalar *x,lsum = 0.0; 1270 1271 PetscFunctionBegin; 1272 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 1273 PetscValidScalarPointer(sum,2); 1274 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1275 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1276 for (i=0; i<n; i++) { 1277 lsum += x[i]; 1278 } 1279 ierr = MPI_Allreduce(&lsum,sum,1,MPIU_SCALAR,MPIU_SUM,((PetscObject)v)->comm);CHKERRQ(ierr); 1280 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1281 PetscFunctionReturn(0); 1282 } 1283 1284 #undef __FUNCT__ 1285 #define __FUNCT__ "VecShift" 1286 /*@ 1287 VecShift - Shifts all of the components of a vector by computing 1288 x[i] = x[i] + shift. 1289 1290 Logically Collective on Vec 1291 1292 Input Parameters: 1293 + v - the vector 1294 - shift - the shift 1295 1296 Output Parameter: 1297 . v - the shifted vector 1298 1299 Level: intermediate 1300 1301 Concepts: vector^adding constant 1302 1303 @*/ 1304 PetscErrorCode VecShift(Vec v,PetscScalar shift) 1305 { 1306 PetscErrorCode ierr; 1307 PetscInt i,n; 1308 PetscScalar *x; 1309 1310 PetscFunctionBegin; 1311 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 1312 PetscValidLogicalCollectiveScalar(v,shift,2); 1313 if (v->ops->shift) { 1314 ierr = (*v->ops->shift)(v);CHKERRQ(ierr); 1315 } else { 1316 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1317 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1318 for (i=0; i<n; i++) { 1319 x[i] += shift; 1320 } 1321 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1322 } 1323 PetscFunctionReturn(0); 1324 } 1325 1326 #undef __FUNCT__ 1327 #define __FUNCT__ "VecAbs" 1328 /*@ 1329 VecAbs - Replaces every element in a vector with its absolute value. 1330 1331 Logically Collective on Vec 1332 1333 Input Parameters: 1334 . v - the vector 1335 1336 Level: intermediate 1337 1338 Concepts: vector^absolute value 1339 1340 @*/ 1341 PetscErrorCode VecAbs(Vec v) 1342 { 1343 PetscErrorCode ierr; 1344 PetscInt i,n; 1345 PetscScalar *x; 1346 1347 PetscFunctionBegin; 1348 PetscValidHeaderSpecific(v,VEC_CLASSID,1); 1349 if (v->ops->abs) { 1350 ierr = (*v->ops->abs)(v);CHKERRQ(ierr); 1351 } else { 1352 ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1353 ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1354 for (i=0; i<n; i++) { 1355 x[i] = PetscAbsScalar(x[i]); 1356 } 1357 ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 1358 } 1359 PetscFunctionReturn(0); 1360 } 1361 1362 #undef __FUNCT__ 1363 #define __FUNCT__ "VecPermute" 1364 /*@ 1365 VecPermute - Permutes a vector in place using the given ordering. 1366 1367 Input Parameters: 1368 + vec - The vector 1369 . order - The ordering 1370 - inv - The flag for inverting the permutation 1371 1372 Level: beginner 1373 1374 Note: This function does not yet support parallel Index Sets with non-local permutations 1375 1376 .seealso: MatPermute() 1377 .keywords: vec, permute 1378 @*/ 1379 PetscErrorCode VecPermute(Vec x, IS row, PetscBool inv) 1380 { 1381 PetscScalar *array, *newArray; 1382 const PetscInt *idx; 1383 PetscInt i,rstart,rend; 1384 PetscErrorCode ierr; 1385 1386 PetscFunctionBegin; 1387 ierr = VecGetOwnershipRange(x,&rstart,&rend);CHKERRQ(ierr); 1388 ierr = ISGetIndices(row, &idx);CHKERRQ(ierr); 1389 ierr = VecGetArray(x, &array);CHKERRQ(ierr); 1390 ierr = PetscMalloc(x->map->n*sizeof(PetscScalar), &newArray);CHKERRQ(ierr); 1391 #ifdef PETSC_USE_DEBUG 1392 for (i = 0; i < x->map->n; i++) { 1393 if ((idx[i] < rstart) || (idx[i] >= rend)) { 1394 SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT, "Permutation index %D is out of bounds: %D", i, idx[i]); 1395 } 1396 } 1397 #endif 1398 if (!inv) { 1399 for (i = 0; i < x->map->n; i++) newArray[i] = array[idx[i]-rstart]; 1400 } else { 1401 for (i = 0; i < x->map->n; i++) newArray[idx[i]-rstart] = array[i]; 1402 } 1403 ierr = VecRestoreArray(x, &array);CHKERRQ(ierr); 1404 ierr = ISRestoreIndices(row, &idx);CHKERRQ(ierr); 1405 ierr = VecReplaceArray(x, newArray);CHKERRQ(ierr); 1406 PetscFunctionReturn(0); 1407 } 1408 1409 #undef __FUNCT__ 1410 #define __FUNCT__ "VecEqual" 1411 /*@ 1412 VecEqual - Compares two vectors. 1413 1414 Collective on Vec 1415 1416 Input Parameters: 1417 + vec1 - the first vector 1418 - vec2 - the second vector 1419 1420 Output Parameter: 1421 . flg - PETSC_TRUE if the vectors are equal; PETSC_FALSE otherwise. 1422 1423 Level: intermediate 1424 1425 Concepts: equal^two vectors 1426 Concepts: vector^equality 1427 1428 @*/ 1429 PetscErrorCode VecEqual(Vec vec1,Vec vec2,PetscBool *flg) 1430 { 1431 PetscScalar *v1,*v2; 1432 PetscErrorCode ierr; 1433 PetscInt n1,n2,N1,N2; 1434 PetscInt state1,state2; 1435 PetscBool flg1; 1436 1437 PetscFunctionBegin; 1438 PetscValidHeaderSpecific(vec1,VEC_CLASSID,1); 1439 PetscValidHeaderSpecific(vec2,VEC_CLASSID,2); 1440 PetscValidPointer(flg,3); 1441 if (vec1 == vec2) { 1442 *flg = PETSC_TRUE; 1443 } else { 1444 ierr = VecGetSize(vec1,&N1);CHKERRQ(ierr); 1445 ierr = VecGetSize(vec2,&N2);CHKERRQ(ierr); 1446 if (N1 != N2) { 1447 flg1 = PETSC_FALSE; 1448 } else { 1449 ierr = VecGetLocalSize(vec1,&n1);CHKERRQ(ierr); 1450 ierr = VecGetLocalSize(vec2,&n2);CHKERRQ(ierr); 1451 if (n1 != n2) { 1452 flg1 = PETSC_FALSE; 1453 } else { 1454 ierr = PetscObjectStateQuery((PetscObject) vec1,&state1);CHKERRQ(ierr); 1455 ierr = PetscObjectStateQuery((PetscObject) vec2,&state2);CHKERRQ(ierr); 1456 ierr = VecGetArray(vec1,&v1);CHKERRQ(ierr); 1457 ierr = VecGetArray(vec2,&v2);CHKERRQ(ierr); 1458 #if defined(PETSC_USE_COMPLEX) 1459 { 1460 PetscInt k; 1461 flg1 = PETSC_TRUE; 1462 for (k=0; k<n1; k++){ 1463 if (PetscRealPart(v1[k]) != PetscRealPart(v2[k]) || PetscImaginaryPart(v1[k]) != PetscImaginaryPart(v2[k])){ 1464 flg1 = PETSC_FALSE; 1465 break; 1466 } 1467 } 1468 } 1469 #else 1470 ierr = PetscMemcmp(v1,v2,n1*sizeof(PetscScalar),&flg1);CHKERRQ(ierr); 1471 #endif 1472 ierr = VecRestoreArray(vec1,&v1);CHKERRQ(ierr); 1473 ierr = VecRestoreArray(vec2,&v2);CHKERRQ(ierr); 1474 ierr = PetscObjectSetState((PetscObject) vec1,state1);CHKERRQ(ierr); 1475 ierr = PetscObjectSetState((PetscObject) vec2,state2);CHKERRQ(ierr); 1476 } 1477 } 1478 /* combine results from all processors */ 1479 ierr = MPI_Allreduce(&flg1,flg,1,MPIU_BOOL,MPI_MIN,((PetscObject)vec1)->comm);CHKERRQ(ierr); 1480 } 1481 PetscFunctionReturn(0); 1482 } 1483 1484 1485 1486