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