Actual source code: vector.c

petsc-main 2021-04-20
Report Typos and Errors
  1: /*
  2:      Provides the interface functions for vector operations that do NOT have PetscScalar/PetscReal in the signature
  3:    These are the vector functions the user calls.
  4: */
  5: #include <petsc/private/vecimpl.h>

  7: /* Logging support */
  8: PetscClassId  VEC_CLASSID;
  9: PetscLogEvent VEC_View, VEC_Max, VEC_Min, VEC_Dot, VEC_MDot, VEC_TDot;
 10: PetscLogEvent VEC_Norm, VEC_Normalize, VEC_Scale, VEC_Copy, VEC_Set, VEC_AXPY, VEC_AYPX, VEC_WAXPY;
 11: PetscLogEvent VEC_MTDot, VEC_MAXPY, VEC_Swap, VEC_AssemblyBegin, VEC_ScatterBegin, VEC_ScatterEnd;
 12: PetscLogEvent VEC_AssemblyEnd, VEC_PointwiseMult, VEC_SetValues, VEC_Load;
 13: PetscLogEvent VEC_SetRandom, VEC_ReduceArithmetic, VEC_ReduceCommunication,VEC_ReduceBegin,VEC_ReduceEnd,VEC_Ops;
 14: PetscLogEvent VEC_DotNorm2, VEC_AXPBYPCZ;
 15: PetscLogEvent VEC_ViennaCLCopyFromGPU, VEC_ViennaCLCopyToGPU;
 16: PetscLogEvent VEC_CUDACopyFromGPU, VEC_CUDACopyToGPU;
 17: PetscLogEvent VEC_CUDACopyFromGPUSome, VEC_CUDACopyToGPUSome;
 18: PetscLogEvent VEC_HIPCopyFromGPU, VEC_HIPCopyToGPU;
 19: PetscLogEvent VEC_HIPCopyFromGPUSome, VEC_HIPCopyToGPUSome;

 21: /*@
 22:    VecStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
 23:        to be communicated to other processors during the VecAssemblyBegin/End() process

 25:     Not collective

 27:    Input Parameter:
 28: .   vec - the vector

 30:    Output Parameters:
 31: +   nstash   - the size of the stash
 32: .   reallocs - the number of additional mallocs incurred.
 33: .   bnstash   - the size of the block stash
 34: -   breallocs - the number of additional mallocs incurred.in the block stash

 36:    Level: advanced

 38: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), Vec, VecStashSetInitialSize(), VecStashView()

 40: @*/
 41: PetscErrorCode  VecStashGetInfo(Vec vec,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
 42: {

 46:   VecStashGetInfo_Private(&vec->stash,nstash,reallocs);
 47:   VecStashGetInfo_Private(&vec->bstash,bnstash,breallocs);
 48:   return(0);
 49: }

 51: /*@
 52:    VecSetLocalToGlobalMapping - Sets a local numbering to global numbering used
 53:    by the routine VecSetValuesLocal() to allow users to insert vector entries
 54:    using a local (per-processor) numbering.

 56:    Logically Collective on Vec

 58:    Input Parameters:
 59: +  x - vector
 60: -  mapping - mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()

 62:    Notes:
 63:    All vectors obtained with VecDuplicate() from this vector inherit the same mapping.

 65:    Level: intermediate

 67: seealso:  VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesLocal(),
 68:            VecSetLocalToGlobalMapping(), VecSetValuesBlockedLocal()
 69: @*/
 70: PetscErrorCode  VecSetLocalToGlobalMapping(Vec x,ISLocalToGlobalMapping mapping)
 71: {


 78:   if (x->ops->setlocaltoglobalmapping) {
 79:     (*x->ops->setlocaltoglobalmapping)(x,mapping);
 80:   } else {
 81:     PetscLayoutSetISLocalToGlobalMapping(x->map,mapping);
 82:   }
 83:   return(0);
 84: }

 86: /*@
 87:    VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by VecSetLocalToGlobalMapping()

 89:    Not Collective

 91:    Input Parameter:
 92: .  X - the vector

 94:    Output Parameter:
 95: .  mapping - the mapping

 97:    Level: advanced


100: .seealso:  VecSetValuesLocal()
101: @*/
102: PetscErrorCode VecGetLocalToGlobalMapping(Vec X,ISLocalToGlobalMapping *mapping)
103: {
108:   *mapping = X->map->mapping;
109:   return(0);
110: }

112: /*@
113:    VecAssemblyBegin - Begins assembling the vector.  This routine should
114:    be called after completing all calls to VecSetValues().

116:    Collective on Vec

118:    Input Parameter:
119: .  vec - the vector

121:    Level: beginner

123: .seealso: VecAssemblyEnd(), VecSetValues()
124: @*/
125: PetscErrorCode  VecAssemblyBegin(Vec vec)
126: {

132:   VecStashViewFromOptions(vec,NULL,"-vec_view_stash");
133:   PetscLogEventBegin(VEC_AssemblyBegin,vec,0,0,0);
134:   if (vec->ops->assemblybegin) {
135:     (*vec->ops->assemblybegin)(vec);
136:   }
137:   PetscLogEventEnd(VEC_AssemblyBegin,vec,0,0,0);
138:   PetscObjectStateIncrease((PetscObject)vec);
139:   return(0);
140: }

142: /*@
143:    VecAssemblyEnd - Completes assembling the vector.  This routine should
144:    be called after VecAssemblyBegin().

146:    Collective on Vec

148:    Input Parameter:
149: .  vec - the vector

151:    Options Database Keys:
152: +  -vec_view - Prints vector in ASCII format
153: .  -vec_view ::ascii_matlab - Prints vector in ASCII MATLAB format to stdout
154: .  -vec_view matlab:filename - Prints vector in MATLAB format to matlaboutput.mat
155: .  -vec_view draw - Activates vector viewing using drawing tools
156: .  -display <name> - Sets display name (default is host)
157: .  -draw_pause <sec> - Sets number of seconds to pause after display
158: -  -vec_view socket - Activates vector viewing using a socket

160:    Level: beginner

162: .seealso: VecAssemblyBegin(), VecSetValues()
163: @*/
164: PetscErrorCode  VecAssemblyEnd(Vec vec)
165: {

170:   PetscLogEventBegin(VEC_AssemblyEnd,vec,0,0,0);
172:   if (vec->ops->assemblyend) {
173:     (*vec->ops->assemblyend)(vec);
174:   }
175:   PetscLogEventEnd(VEC_AssemblyEnd,vec,0,0,0);
176:   VecViewFromOptions(vec,NULL,"-vec_view");
177:   return(0);
178: }

180: /*@
181:    VecPointwiseMax - Computes the componentwise maximum w_i = max(x_i, y_i).

183:    Logically Collective on Vec

185:    Input Parameters:
186: .  x, y  - the vectors

188:    Output Parameter:
189: .  w - the result

191:    Level: advanced

193:    Notes:
194:     any subset of the x, y, and w may be the same vector.
195:           For complex numbers compares only the real part

197: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
198: @*/
199: PetscErrorCode  VecPointwiseMax(Vec w,Vec x,Vec y)
200: {

212:   VecCheckSameSize(w,1,x,2);
213:   VecCheckSameSize(w,1,y,3);
214:   VecSetErrorIfLocked(w,1);
215:   (*w->ops->pointwisemax)(w,x,y);
216:   PetscObjectStateIncrease((PetscObject)w);
217:   return(0);
218: }

220: /*@
221:    VecPointwiseMin - Computes the componentwise minimum w_i = min(x_i, y_i).

223:    Logically Collective on Vec

225:    Input Parameters:
226: .  x, y  - the vectors

228:    Output Parameter:
229: .  w - the result

231:    Level: advanced

233:    Notes:
234:     any subset of the x, y, and w may be the same vector.
235:           For complex numbers compares only the real part

237: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
238: @*/
239: PetscErrorCode  VecPointwiseMin(Vec w,Vec x,Vec y)
240: {

252:   VecCheckSameSize(w,1,x,2);
253:   VecCheckSameSize(w,1,y,3);
254:   VecSetErrorIfLocked(w,1);
255:   (*w->ops->pointwisemin)(w,x,y);
256:   PetscObjectStateIncrease((PetscObject)w);
257:   return(0);
258: }

260: /*@
261:    VecPointwiseMaxAbs - Computes the componentwise maximum of the absolute values w_i = max(abs(x_i), abs(y_i)).

263:    Logically Collective on Vec

265:    Input Parameters:
266: .  x, y  - the vectors

268:    Output Parameter:
269: .  w - the result

271:    Level: advanced

273:    Notes:
274:     any subset of the x, y, and w may be the same vector.

276: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMin(), VecPointwiseMax(), VecMaxPointwiseDivide()
277: @*/
278: PetscErrorCode  VecPointwiseMaxAbs(Vec w,Vec x,Vec y)
279: {

291:   VecCheckSameSize(w,1,x,2);
292:   VecCheckSameSize(w,1,y,3);
293:   VecSetErrorIfLocked(w,1);
294:   (*w->ops->pointwisemaxabs)(w,x,y);
295:   PetscObjectStateIncrease((PetscObject)w);
296:   return(0);
297: }

299: /*@
300:    VecPointwiseDivide - Computes the componentwise division w = x/y.

302:    Logically Collective on Vec

304:    Input Parameters:
305: .  x, y  - the vectors

307:    Output Parameter:
308: .  w - the result

310:    Level: advanced

312:    Notes:
313:     any subset of the x, y, and w may be the same vector.

315: .seealso: VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
316: @*/
317: PetscErrorCode  VecPointwiseDivide(Vec w,Vec x,Vec y)
318: {

330:   VecCheckSameSize(w,1,x,2);
331:   VecCheckSameSize(w,1,y,3);
332:   VecSetErrorIfLocked(w,1);
333:   (*w->ops->pointwisedivide)(w,x,y);
334:   PetscObjectStateIncrease((PetscObject)w);
335:   return(0);
336: }


339: /*@
340:    VecDuplicate - Creates a new vector of the same type as an existing vector.

342:    Collective on Vec

344:    Input Parameters:
345: .  v - a vector to mimic

347:    Output Parameter:
348: .  newv - location to put new vector

350:    Notes:
351:    VecDuplicate() DOES NOT COPY the vector entries, but rather allocates storage
352:    for the new vector.  Use VecCopy() to copy a vector.

354:    Use VecDestroy() to free the space. Use VecDuplicateVecs() to get several
355:    vectors.

357:    Level: beginner

359: .seealso: VecDestroy(), VecDuplicateVecs(), VecCreate(), VecCopy()
360: @*/
361: PetscErrorCode  VecDuplicate(Vec v,Vec *newv)
362: {

369:   (*v->ops->duplicate)(v,newv);
370:   PetscObjectStateIncrease((PetscObject)*newv);
371:   return(0);
372: }

374: /*@C
375:    VecDestroy - Destroys a vector.

377:    Collective on Vec

379:    Input Parameters:
380: .  v  - the vector

382:    Level: beginner

384: .seealso: VecDuplicate(), VecDestroyVecs()
385: @*/
386: PetscErrorCode  VecDestroy(Vec *v)
387: {

391:   if (!*v) return(0);
393:   if (--((PetscObject)(*v))->refct > 0) {*v = NULL; return(0);}

395:   PetscObjectSAWsViewOff((PetscObject)*v);
396:   /* destroy the internal part */
397:   if ((*v)->ops->destroy) {
398:     (*(*v)->ops->destroy)(*v);
399:   }
400:   PetscFree((*v)->defaultrandtype);
401:   /* destroy the external/common part */
402:   PetscLayoutDestroy(&(*v)->map);
403:   PetscHeaderDestroy(v);
404:   return(0);
405: }

407: /*@C
408:    VecDuplicateVecs - Creates several vectors of the same type as an existing vector.

410:    Collective on Vec

412:    Input Parameters:
413: +  m - the number of vectors to obtain
414: -  v - a vector to mimic

416:    Output Parameter:
417: .  V - location to put pointer to array of vectors

419:    Notes:
420:    Use VecDestroyVecs() to free the space. Use VecDuplicate() to form a single
421:    vector.

423:    Fortran Note:
424:    The Fortran interface is slightly different from that given below, it
425:    requires one to pass in V a Vec (integer) array of size at least m.
426:    See the Fortran chapter of the users manual and petsc/src/vec/vec/examples for details.

428:    Level: intermediate

430: .seealso:  VecDestroyVecs(), VecDuplicate(), VecCreate(), VecDuplicateVecsF90()
431: @*/
432: PetscErrorCode  VecDuplicateVecs(Vec v,PetscInt m,Vec *V[])
433: {

440:   (*v->ops->duplicatevecs)(v,m,V);
441:   return(0);
442: }

444: /*@C
445:    VecDestroyVecs - Frees a block of vectors obtained with VecDuplicateVecs().

447:    Collective on Vec

449:    Input Parameters:
450: +  vv - pointer to pointer to array of vector pointers, if NULL no vectors are destroyed
451: -  m - the number of vectors previously obtained, if zero no vectors are destroyed

453:    Fortran Note:
454:    The Fortran interface is slightly different from that given below.
455:    See the Fortran chapter of the users manual

457:    Level: intermediate

459: .seealso: VecDuplicateVecs(), VecDestroyVecsf90()
460: @*/
461: PetscErrorCode  VecDestroyVecs(PetscInt m,Vec *vv[])
462: {

467:   if (m < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of vectors %D",m);
468:   if (!m || !*vv) {*vv  = NULL; return(0);}
471:   (*(**vv)->ops->destroyvecs)(m,*vv);
472:   *vv  = NULL;
473:   return(0);
474: }

476: /*@C
477:    VecViewFromOptions - View from Options

479:    Collective on Vec

481:    Input Parameters:
482: +  A - the vector
483: .  obj - Optional object
484: -  name - command line option

486:    Level: intermediate
487: .seealso:  Vec, VecView, PetscObjectViewFromOptions(), VecCreate()
488: @*/
489: PetscErrorCode  VecViewFromOptions(Vec A,PetscObject obj,const char name[])
490: {

495:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
496:   return(0);
497: }

499: /*@C
500:    VecView - Views a vector object.

502:    Collective on Vec

504:    Input Parameters:
505: +  vec - the vector
506: -  viewer - an optional visualization context

508:    Notes:
509:    The available visualization contexts include
510: +     PETSC_VIEWER_STDOUT_SELF - for sequential vectors
511: .     PETSC_VIEWER_STDOUT_WORLD - for parallel vectors created on PETSC_COMM_WORLD
512: -     PETSC_VIEWER_STDOUT_(comm) - for parallel vectors created on MPI communicator comm

514:    You can change the format the vector is printed using the
515:    option PetscViewerPushFormat().

517:    The user can open alternative viewers with
518: +    PetscViewerASCIIOpen() - Outputs vector to a specified file
519: .    PetscViewerBinaryOpen() - Outputs vector in binary to a
520:          specified file; corresponding input uses VecLoad()
521: .    PetscViewerDrawOpen() - Outputs vector to an X window display
522: .    PetscViewerSocketOpen() - Outputs vector to Socket viewer
523: -    PetscViewerHDF5Open() - Outputs vector to HDF5 file viewer

525:    The user can call PetscViewerPushFormat() to specify the output
526:    format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
527:    PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen).  Available formats include
528: +    PETSC_VIEWER_DEFAULT - default, prints vector contents
529: .    PETSC_VIEWER_ASCII_MATLAB - prints vector contents in MATLAB format
530: .    PETSC_VIEWER_ASCII_INDEX - prints vector contents, including indices of vector elements
531: -    PETSC_VIEWER_ASCII_COMMON - prints vector contents, using a
532:          format common among all vector types

534:    Notes:
535:     You can pass any number of vector objects, or other PETSc objects to the same viewer.

537:     In the debugger you can do "call VecView(v,0)" to display the vector. (The same holds for any PETSc object viewer).

539:    Notes for binary viewer:
540:      If you pass multiple vectors to a binary viewer you can read them back in in the same order
541:      with VecLoad().

543:      If the blocksize of the vector is greater than one then you must provide a unique prefix to
544:      the vector with PetscObjectSetOptionsPrefix((PetscObject)vec,"uniqueprefix"); BEFORE calling VecView() on the
545:      vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
546:      information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
547:      filename. If you copy the binary file, make sure you copy the associated .info file with it.

549:      See the manual page for VecLoad() on the exact format the binary viewer stores
550:      the values in the file.


553:    Notes for HDF5 Viewer:
554:      The name of the Vec (given with PetscObjectSetName() is the name that is used
555:      for the object in the HDF5 file. If you wish to store the same Vec into multiple
556:      datasets in the same file (typically with different values), you must change its
557:      name each time before calling the VecView(). To load the same vector,
558:      the name of the Vec object passed to VecLoad() must be the same.

560:      If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
561:      If the function PetscViewerHDF5SetBaseDimension2()is called then even if the block size is one it will
562:      be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
563:      See also PetscViewerHDF5SetTimestep() which adds an additional complication to reading and writing Vecs
564:      with the HDF5 viewer.

566:    Level: beginner


569: .seealso: PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscDrawLGCreate(),
570:           PetscViewerSocketOpen(), PetscViewerBinaryOpen(), VecLoad(), PetscViewerCreate(),
571:           PetscRealView(), PetscScalarView(), PetscIntView(), PetscViewerHDF5SetTimestep()
572: @*/
573: PetscErrorCode  VecView(Vec vec,PetscViewer viewer)
574: {
575:   PetscErrorCode    ierr;
576:   PetscBool         iascii;
577:   PetscViewerFormat format;
578:   PetscMPIInt       size;

583:   if (!viewer) {PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec),&viewer);}
585:   PetscViewerGetFormat(viewer,&format);
586:   MPI_Comm_size(PetscObjectComm((PetscObject)vec),&size);
587:   if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) return(0);

589:   if (vec->stash.n || vec->bstash.n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call VecAssemblyBegin/End() before viewing this vector");

591:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
592:   if (iascii) {
593:     PetscInt rows,bs;

595:     PetscObjectPrintClassNamePrefixType((PetscObject)vec,viewer);
596:     if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
597:       PetscViewerASCIIPushTab(viewer);
598:       VecGetSize(vec,&rows);
599:       VecGetBlockSize(vec,&bs);
600:       if (bs != 1) {
601:         PetscViewerASCIIPrintf(viewer,"length=%D, bs=%D\n",rows,bs);
602:       } else {
603:         PetscViewerASCIIPrintf(viewer,"length=%D\n",rows);
604:       }
605:       PetscViewerASCIIPopTab(viewer);
606:     }
607:   }
608:   VecLockReadPush(vec);
609:   PetscLogEventBegin(VEC_View,vec,viewer,0,0);
610:   if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
611:     (*vec->ops->viewnative)(vec,viewer);
612:   } else {
613:     (*vec->ops->view)(vec,viewer);
614:   }
615:   VecLockReadPop(vec);
616:   PetscLogEventEnd(VEC_View,vec,viewer,0,0);
617:   return(0);
618: }

620: #if defined(PETSC_USE_DEBUG)
621: #include <../src/sys/totalview/tv_data_display.h>
622: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
623: {
624:   const PetscScalar *values;
625:   char              type[32];
626:   PetscErrorCode    ierr;


629:   TV_add_row("Local rows", "int", &v->map->n);
630:   TV_add_row("Global rows", "int", &v->map->N);
631:   TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
632:   VecGetArrayRead((Vec)v,&values);
633:   PetscSNPrintf(type,32,"double[%d]",v->map->n);
634:   TV_add_row("values",type, values);
635:   VecRestoreArrayRead((Vec)v,&values);
636:   return TV_format_OK;
637: }
638: #endif

640: /*@
641:    VecGetSize - Returns the global number of elements of the vector.

643:    Not Collective

645:    Input Parameter:
646: .  x - the vector

648:    Output Parameters:
649: .  size - the global length of the vector

651:    Level: beginner

653: .seealso: VecGetLocalSize()
654: @*/
655: PetscErrorCode  VecGetSize(Vec x,PetscInt *size)
656: {

663:   (*x->ops->getsize)(x,size);
664:   return(0);
665: }

667: /*@
668:    VecGetLocalSize - Returns the number of elements of the vector stored
669:    in local memory.

671:    Not Collective

673:    Input Parameter:
674: .  x - the vector

676:    Output Parameter:
677: .  size - the length of the local piece of the vector

679:    Level: beginner

681: .seealso: VecGetSize()
682: @*/
683: PetscErrorCode  VecGetLocalSize(Vec x,PetscInt *size)
684: {

691:   (*x->ops->getlocalsize)(x,size);
692:   return(0);
693: }

695: /*@C
696:    VecGetOwnershipRange - Returns the range of indices owned by
697:    this processor, assuming that the vectors are laid out with the
698:    first n1 elements on the first processor, next n2 elements on the
699:    second, etc.  For certain parallel layouts this range may not be
700:    well defined.

702:    Not Collective

704:    Input Parameter:
705: .  x - the vector

707:    Output Parameters:
708: +  low - the first local element, pass in NULL if not interested
709: -  high - one more than the last local element, pass in NULL if not interested

711:    Note:
712:    The high argument is one more than the last element stored locally.

714:    Fortran: PETSC_NULL_INTEGER should be used instead of NULL

716:    Level: beginner

718: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRanges(), VecGetOwnershipRanges()
719: @*/
720: PetscErrorCode  VecGetOwnershipRange(Vec x,PetscInt *low,PetscInt *high)
721: {
727:   if (low)  *low  = x->map->rstart;
728:   if (high) *high = x->map->rend;
729:   return(0);
730: }

732: /*@C
733:    VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
734:    assuming that the vectors are laid out with the
735:    first n1 elements on the first processor, next n2 elements on the
736:    second, etc.  For certain parallel layouts this range may not be
737:    well defined.

739:    Not Collective

741:    Input Parameter:
742: .  x - the vector

744:    Output Parameters:
745: .  range - array of length size+1 with the start and end+1 for each process

747:    Note:
748:    The high argument is one more than the last element stored locally.

750:    Fortran: You must PASS in an array of length size+1

752:    If the ranges are used after all vectors that share the ranges has been destroyed then the program will crash accessing ranges[].

754:    Level: beginner

756: .seealso:   MatGetOwnershipRange(), MatGetOwnershipRanges(), VecGetOwnershipRange()
757: @*/
758: PetscErrorCode  VecGetOwnershipRanges(Vec x,const PetscInt *ranges[])
759: {

765:   PetscLayoutGetRanges(x->map,ranges);
766:   return(0);
767: }

769: /*@
770:    VecSetOption - Sets an option for controling a vector's behavior.

772:    Collective on Vec

774:    Input Parameter:
775: +  x - the vector
776: .  op - the option
777: -  flag - turn the option on or off

779:    Supported Options:
780: +     VEC_IGNORE_OFF_PROC_ENTRIES, which causes VecSetValues() to ignore
781:           entries destined to be stored on a separate processor. This can be used
782:           to eliminate the global reduction in the VecAssemblyXXXX() if you know
783:           that you have only used VecSetValues() to set local elements
784: .     VEC_IGNORE_NEGATIVE_INDICES, which means you can pass negative indices
785:           in ix in calls to VecSetValues() or VecGetValues(). These rows are simply
786:           ignored.
787: -     VEC_SUBSET_OFF_PROC_ENTRIES, which causes VecAssemblyBegin() to assume that the off-process
788:           entries will always be a subset (possibly equal) of the off-process entries set on the
789:           first assembly which had a true VEC_SUBSET_OFF_PROC_ENTRIES and the vector has not
790:           changed this flag afterwards. If this assembly is not such first assembly, then this
791:           assembly can reuse the communication pattern setup in that first assembly, thus avoiding
792:           a global reduction. Subsequent assemblies setting off-process values should use the same
793:           InsertMode as the first assembly.

795:    Developer Note:
796:    The InsertMode restriction could be removed by packing the stash messages out of place.

798:    Level: intermediate

800: @*/
801: PetscErrorCode  VecSetOption(Vec x,VecOption op,PetscBool flag)
802: {

808:   if (x->ops->setoption) {
809:     (*x->ops->setoption)(x,op,flag);
810:   }
811:   return(0);
812: }

814: /* Default routines for obtaining and releasing; */
815: /* may be used by any implementation */
816: PetscErrorCode VecDuplicateVecs_Default(Vec w,PetscInt m,Vec *V[])
817: {
819:   PetscInt       i;

824:   if (m <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"m must be > 0: m = %D",m);
825:   PetscMalloc1(m,V);
826:   for (i=0; i<m; i++) {VecDuplicate(w,*V+i);}
827:   return(0);
828: }

830: PetscErrorCode VecDestroyVecs_Default(PetscInt m,Vec v[])
831: {
833:   PetscInt       i;

837:   for (i=0; i<m; i++) {VecDestroy(&v[i]);}
838:   PetscFree(v);
839:   return(0);
840: }

842: /*@
843:    VecResetArray - Resets a vector to use its default memory. Call this
844:    after the use of VecPlaceArray().

846:    Not Collective

848:    Input Parameters:
849: .  vec - the vector

851:    Level: developer

853: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray()

855: @*/
856: PetscErrorCode  VecResetArray(Vec vec)
857: {

863:   if (vec->ops->resetarray) {
864:     (*vec->ops->resetarray)(vec);
865:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot reset array in this type of vector");
866:   PetscObjectStateIncrease((PetscObject)vec);
867:   return(0);
868: }

870: /*@C
871:   VecLoad - Loads a vector that has been stored in binary or HDF5 format
872:   with VecView().

874:   Collective on PetscViewer

876:   Input Parameters:
877: + vec - the newly loaded vector, this needs to have been created with VecCreate() or
878:            some related function before a call to VecLoad().
879: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
880:            HDF5 file viewer, obtained from PetscViewerHDF5Open()

882:    Level: intermediate

884:   Notes:
885:   Defaults to the standard Seq or MPI Vec, if you want some other type of Vec call VecSetFromOptions()
886:   before calling this.

888:   The input file must contain the full global vector, as
889:   written by the routine VecView().

891:   If the type or size of vec is not set before a call to VecLoad, PETSc
892:   sets the type and the local and global sizes. If type and/or
893:   sizes are already set, then the same are used.

895:   If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
896:   the vector with PetscObjectSetOptionsPrefix((PetscObject)vec,"uniqueprefix"); BEFORE calling VecView() on the
897:   vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
898:   information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
899:   filename. If you copy the binary file, make sure you copy the associated .info file with it.

901:   If using HDF5, you must assign the Vec the same name as was used in the Vec
902:   that was stored in the file using PetscObjectSetName(). Otherwise you will
903:   get the error message: "Cannot H5DOpen2() with Vec name NAMEOFOBJECT".

905:   If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
906:   in loading the vector. Hence, for example, using Matlab notation h5create('vector.dat','/Test_Vec',[27 1]);
907:   will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
908:   vectors communicator and the rest of the processes having zero entries

910:   Notes for advanced users when using the binary viewer:
911:   Most users should not need to know the details of the binary storage
912:   format, since VecLoad() and VecView() completely hide these details.
913:   But for anyone who's interested, the standard binary vector storage
914:   format is
915: .vb
916:      PetscInt    VEC_FILE_CLASSID
917:      PetscInt    number of rows
918:      PetscScalar *values of all entries
919: .ve

921:    In addition, PETSc automatically uses byte swapping to work on all machines; the files
922:    are written ALWAYS using big-endian ordering. On small-endian machines the numbers
923:    are converted to the small-endian format when they are read in from the file.
924:    See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.

926: .seealso: PetscViewerBinaryOpen(), VecView(), MatLoad(), VecLoad()
927: @*/
928: PetscErrorCode  VecLoad(Vec vec, PetscViewer viewer)
929: {
930:   PetscErrorCode    ierr;
931:   PetscBool         isbinary,ishdf5,isadios,isexodusii;
932:   PetscViewerFormat format;

938:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
939:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
940:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERADIOS,&isadios);
941:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWEREXODUSII,&isexodusii);
942:   if (!isbinary && !ishdf5 && !isadios && !isexodusii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");


945:   VecSetErrorIfLocked(vec,1);
946:   if (!((PetscObject)vec)->type_name && !vec->ops->create) {
947:     VecSetType(vec, VECSTANDARD);
948:   }
949:   PetscLogEventBegin(VEC_Load,viewer,0,0,0);
950:   PetscViewerGetFormat(viewer,&format);
951:   if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
952:     (*vec->ops->loadnative)(vec,viewer);
953:   } else {
954:     (*vec->ops->load)(vec,viewer);
955:   }
956:   PetscLogEventEnd(VEC_Load,viewer,0,0,0);
957:   return(0);
958: }


961: /*@
962:    VecReciprocal - Replaces each component of a vector by its reciprocal.

964:    Logically Collective on Vec

966:    Input Parameter:
967: .  vec - the vector

969:    Output Parameter:
970: .  vec - the vector reciprocal

972:    Level: intermediate

974: .seealso: VecLog(), VecExp(), VecSqrtAbs()

976: @*/
977: PetscErrorCode  VecReciprocal(Vec vec)
978: {

984:   if (vec->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
985:   if (!vec->ops->reciprocal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Vector does not support reciprocal operation");
986:   VecSetErrorIfLocked(vec,1);
987:   (*vec->ops->reciprocal)(vec);
988:   PetscObjectStateIncrease((PetscObject)vec);
989:   return(0);
990: }

992: /*@C
993:     VecSetOperation - Allows user to set a vector operation.

995:    Logically Collective on Vec

997:     Input Parameters:
998: +   vec - the vector
999: .   op - the name of the operation
1000: -   f - the function that provides the operation.

1002:    Level: advanced

1004:     Usage:
1005: $      PetscErrorCode userview(Vec,PetscViewer);
1006: $      VecCreateMPI(comm,m,M,&x);
1007: $      VecSetOperation(x,VECOP_VIEW,(void(*)(void))userview);

1009:     Notes:
1010:     See the file include/petscvec.h for a complete list of matrix
1011:     operations, which all have the form VECOP_<OPERATION>, where
1012:     <OPERATION> is the name (in all capital letters) of the
1013:     user interface routine (e.g., VecView() -> VECOP_VIEW).

1015:     This function is not currently available from Fortran.

1017: .seealso: VecCreate(), MatShellSetOperation()
1018: @*/
1019: PetscErrorCode VecSetOperation(Vec vec,VecOperation op, void (*f)(void))
1020: {
1023:   if (op == VECOP_VIEW && !vec->ops->viewnative) {
1024:     vec->ops->viewnative = vec->ops->view;
1025:   } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1026:     vec->ops->loadnative = vec->ops->load;
1027:   }
1028:   (((void(**)(void))vec->ops)[(int)op]) = f;
1029:   return(0);
1030: }


1033: /*@
1034:    VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1035:    used during the assembly process to store values that belong to
1036:    other processors.

1038:    Not Collective, different processes can have different size stashes

1040:    Input Parameters:
1041: +  vec   - the vector
1042: .  size  - the initial size of the stash.
1043: -  bsize - the initial size of the block-stash(if used).

1045:    Options Database Keys:
1046: +   -vecstash_initial_size <size> or <size0,size1,...sizep-1>
1047: -   -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>

1049:    Level: intermediate

1051:    Notes:
1052:      The block-stash is used for values set with VecSetValuesBlocked() while
1053:      the stash is used for values set with VecSetValues()

1055:      Run with the option -info and look for output of the form
1056:      VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1057:      to determine the appropriate value, MM, to use for size and
1058:      VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1059:      to determine the value, BMM to use for bsize


1062: .seealso: VecSetBlockSize(), VecSetValues(), VecSetValuesBlocked(), VecStashView()

1064: @*/
1065: PetscErrorCode  VecStashSetInitialSize(Vec vec,PetscInt size,PetscInt bsize)
1066: {

1071:   VecStashSetInitialSize_Private(&vec->stash,size);
1072:   VecStashSetInitialSize_Private(&vec->bstash,bsize);
1073:   return(0);
1074: }

1076: /*@
1077:    VecConjugate - Conjugates a vector.

1079:    Logically Collective on Vec

1081:    Input Parameters:
1082: .  x - the vector

1084:    Level: intermediate

1086: @*/
1087: PetscErrorCode  VecConjugate(Vec x)
1088: {
1089: #if defined(PETSC_USE_COMPLEX)

1095:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
1096:   VecSetErrorIfLocked(x,1);
1097:   (*x->ops->conjugate)(x);
1098:   /* we need to copy norms here */
1099:   PetscObjectStateIncrease((PetscObject)x);
1100:   return(0);
1101: #else
1102:   return(0);
1103: #endif
1104: }

1106: /*@
1107:    VecPointwiseMult - Computes the componentwise multiplication w = x*y.

1109:    Logically Collective on Vec

1111:    Input Parameters:
1112: .  x, y  - the vectors

1114:    Output Parameter:
1115: .  w - the result

1117:    Level: advanced

1119:    Notes:
1120:     any subset of the x, y, and w may be the same vector.

1122: .seealso: VecPointwiseDivide(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs(), VecMaxPointwiseDivide()
1123: @*/
1124: PetscErrorCode  VecPointwiseMult(Vec w, Vec x,Vec y)
1125: {

1137:   VecCheckSameSize(w,1,x,2);
1138:   VecCheckSameSize(w,2,y,3);
1139:   VecSetErrorIfLocked(w,1);
1140:   PetscLogEventBegin(VEC_PointwiseMult,x,y,w,0);
1141:   (*w->ops->pointwisemult)(w,x,y);
1142:   PetscLogEventEnd(VEC_PointwiseMult,x,y,w,0);
1143:   PetscObjectStateIncrease((PetscObject)w);
1144:   return(0);
1145: }

1147: /*@
1148:    VecSetRandom - Sets all components of a vector to random numbers.

1150:    Logically Collective on Vec

1152:    Input Parameters:
1153: +  x  - the vector
1154: -  rctx - the random number context, formed by PetscRandomCreate(), or NULL and
1155:           it will create one internally.

1157:    Output Parameter:
1158: .  x  - the vector

1160:    Example of Usage:
1161: .vb
1162:      PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1163:      VecSetRandom(x,rctx);
1164:      PetscRandomDestroy(&rctx);
1165: .ve

1167:    Level: intermediate

1169: .seealso: VecSet(), VecSetValues(), PetscRandomCreate(), PetscRandomDestroy()
1170: @*/
1171: PetscErrorCode  VecSetRandom(Vec x,PetscRandom rctx)
1172: {
1174:   PetscRandom    randObj = NULL;

1180:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
1181:   VecSetErrorIfLocked(x,1);

1183:   if (!rctx) {
1184:     PetscRandomCreate(PetscObjectComm((PetscObject)x),&randObj);
1185:     PetscRandomSetType(randObj,x->defaultrandtype);
1186:     PetscRandomSetFromOptions(randObj);
1187:     rctx = randObj;
1188:   }

1190:   PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
1191:   (*x->ops->setrandom)(x,rctx);
1192:   PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);

1194:   PetscRandomDestroy(&randObj);
1195:   PetscObjectStateIncrease((PetscObject)x);
1196:   return(0);
1197: }

1199: /*@
1200:   VecZeroEntries - puts a 0.0 in each element of a vector

1202:   Logically Collective on Vec

1204:   Input Parameter:
1205: . vec - The vector

1207:   Level: beginner

1209: .seealso: VecCreate(),  VecSetOptionsPrefix(), VecSet(), VecSetValues()
1210: @*/
1211: PetscErrorCode  VecZeroEntries(Vec vec)
1212: {

1216:   VecSet(vec,0);
1217:   return(0);
1218: }

1220: /*
1221:   VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1222:   processor and a PETSc MPI vector on more than one processor.

1224:   Collective on Vec

1226:   Input Parameter:
1227: . vec - The vector

1229:   Level: intermediate

1231: .seealso: VecSetFromOptions(), VecSetType()
1232: */
1233: static PetscErrorCode VecSetTypeFromOptions_Private(PetscOptionItems *PetscOptionsObject,Vec vec)
1234: {
1235:   PetscBool      opt;
1236:   VecType        defaultType;
1237:   char           typeName[256];
1238:   PetscMPIInt    size;

1242:   if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1243:   else {
1244:     MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size);
1245:     if (size > 1) defaultType = VECMPI;
1246:     else defaultType = VECSEQ;
1247:   }

1249:   VecRegisterAll();
1250:   PetscOptionsFList("-vec_type","Vector type","VecSetType",VecList,defaultType,typeName,256,&opt);
1251:   if (opt) {
1252:     VecSetType(vec, typeName);
1253:   } else {
1254:     VecSetType(vec, defaultType);
1255:   }
1256:   return(0);
1257: }

1259: /*@
1260:   VecSetFromOptions - Configures the vector from the options database.

1262:   Collective on Vec

1264:   Input Parameter:
1265: . vec - The vector

1267:   Notes:
1268:     To see all options, run your program with the -help option, or consult the users manual.
1269:           Must be called after VecCreate() but before the vector is used.

1271:   Level: beginner


1274: .seealso: VecCreate(), VecSetOptionsPrefix()
1275: @*/
1276: PetscErrorCode  VecSetFromOptions(Vec vec)
1277: {


1283:   PetscObjectOptionsBegin((PetscObject)vec);
1284:   /* Handle vector type options */
1285:   VecSetTypeFromOptions_Private(PetscOptionsObject,vec);

1287:   /* Handle specific vector options */
1288:   if (vec->ops->setfromoptions) {
1289:     (*vec->ops->setfromoptions)(PetscOptionsObject,vec);
1290:   }

1292:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1293:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)vec);
1294:   PetscOptionsEnd();
1295:   return(0);
1296: }

1298: /*@
1299:   VecSetSizes - Sets the local and global sizes, and checks to determine compatibility

1301:   Collective on Vec

1303:   Input Parameters:
1304: + v - the vector
1305: . n - the local size (or PETSC_DECIDE to have it set)
1306: - N - the global size (or PETSC_DECIDE)

1308:   Notes:
1309:   n and N cannot be both PETSC_DECIDE
1310:   If one processor calls this with N of PETSC_DECIDE then all processors must, otherwise the program will hang.

1312:   Level: intermediate

1314: .seealso: VecGetSize(), PetscSplitOwnership()
1315: @*/
1316: PetscErrorCode  VecSetSizes(Vec v, PetscInt n, PetscInt N)
1317: {

1323:   if (N >= 0 && n > N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local size %D cannot be larger than global size %D",n,N);
1324:   if ((v->map->n >= 0 || v->map->N >= 0) && (v->map->n != n || v->map->N != N)) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot change/reset vector sizes to %D local %D global after previously setting them to %D local %D global",n,N,v->map->n,v->map->N);
1325:   v->map->n = n;
1326:   v->map->N = N;
1327:   if (v->ops->create) {
1328:     (*v->ops->create)(v);
1329:     v->ops->create = NULL;
1330:   }
1331:   return(0);
1332: }

1334: /*@
1335:    VecSetBlockSize - Sets the blocksize for future calls to VecSetValuesBlocked()
1336:    and VecSetValuesBlockedLocal().

1338:    Logically Collective on Vec

1340:    Input Parameter:
1341: +  v - the vector
1342: -  bs - the blocksize

1344:    Notes:
1345:    All vectors obtained by VecDuplicate() inherit the same blocksize.

1347:    Level: advanced

1349: .seealso: VecSetValuesBlocked(), VecSetLocalToGlobalMapping(), VecGetBlockSize()

1351: @*/
1352: PetscErrorCode  VecSetBlockSize(Vec v,PetscInt bs)
1353: {

1359:   PetscLayoutSetBlockSize(v->map,bs);
1360:   v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1361:   return(0);
1362: }

1364: /*@
1365:    VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for VecSetValuesBlocked()
1366:    and VecSetValuesBlockedLocal().

1368:    Not Collective

1370:    Input Parameter:
1371: .  v - the vector

1373:    Output Parameter:
1374: .  bs - the blocksize

1376:    Notes:
1377:    All vectors obtained by VecDuplicate() inherit the same blocksize.

1379:    Level: advanced

1381: .seealso: VecSetValuesBlocked(), VecSetLocalToGlobalMapping(), VecSetBlockSize()


1384: @*/
1385: PetscErrorCode  VecGetBlockSize(Vec v,PetscInt *bs)
1386: {

1392:   PetscLayoutGetBlockSize(v->map,bs);
1393:   return(0);
1394: }

1396: /*@C
1397:    VecSetOptionsPrefix - Sets the prefix used for searching for all
1398:    Vec options in the database.

1400:    Logically Collective on Vec

1402:    Input Parameter:
1403: +  v - the Vec context
1404: -  prefix - the prefix to prepend to all option names

1406:    Notes:
1407:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1408:    The first character of all runtime options is AUTOMATICALLY the hyphen.

1410:    Level: advanced

1412: .seealso: VecSetFromOptions()
1413: @*/
1414: PetscErrorCode  VecSetOptionsPrefix(Vec v,const char prefix[])
1415: {

1420:   PetscObjectSetOptionsPrefix((PetscObject)v,prefix);
1421:   return(0);
1422: }

1424: /*@C
1425:    VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1426:    Vec options in the database.

1428:    Logically Collective on Vec

1430:    Input Parameters:
1431: +  v - the Vec context
1432: -  prefix - the prefix to prepend to all option names

1434:    Notes:
1435:    A hyphen (-) must NOT be given at the beginning of the prefix name.
1436:    The first character of all runtime options is AUTOMATICALLY the hyphen.

1438:    Level: advanced

1440: .seealso: VecGetOptionsPrefix()
1441: @*/
1442: PetscErrorCode  VecAppendOptionsPrefix(Vec v,const char prefix[])
1443: {

1448:   PetscObjectAppendOptionsPrefix((PetscObject)v,prefix);
1449:   return(0);
1450: }

1452: /*@C
1453:    VecGetOptionsPrefix - Sets the prefix used for searching for all
1454:    Vec options in the database.

1456:    Not Collective

1458:    Input Parameter:
1459: .  v - the Vec context

1461:    Output Parameter:
1462: .  prefix - pointer to the prefix string used

1464:    Notes:
1465:     On the fortran side, the user should pass in a string 'prefix' of
1466:    sufficient length to hold the prefix.

1468:    Level: advanced

1470: .seealso: VecAppendOptionsPrefix()
1471: @*/
1472: PetscErrorCode  VecGetOptionsPrefix(Vec v,const char *prefix[])
1473: {

1478:   PetscObjectGetOptionsPrefix((PetscObject)v,prefix);
1479:   return(0);
1480: }

1482: /*@
1483:    VecSetUp - Sets up the internal vector data structures for the later use.

1485:    Collective on Vec

1487:    Input Parameters:
1488: .  v - the Vec context

1490:    Notes:
1491:    For basic use of the Vec classes the user need not explicitly call
1492:    VecSetUp(), since these actions will happen automatically.

1494:    Level: advanced

1496: .seealso: VecCreate(), VecDestroy()
1497: @*/
1498: PetscErrorCode  VecSetUp(Vec v)
1499: {
1500:   PetscMPIInt    size;

1505:   if (v->map->n < 0 && v->map->N < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1506:   if (!((PetscObject)v)->type_name) {
1507:     MPI_Comm_size(PetscObjectComm((PetscObject)v), &size);
1508:     if (size == 1) {
1509:       VecSetType(v, VECSEQ);
1510:     } else {
1511:       VecSetType(v, VECMPI);
1512:     }
1513:   }
1514:   return(0);
1515: }

1517: /*
1518:     These currently expose the PetscScalar/PetscReal in updating the
1519:     cached norm. If we push those down into the implementation these
1520:     will become independent of PetscScalar/PetscReal
1521: */

1523: /*@
1524:    VecCopy - Copies a vector. y <- x

1526:    Logically Collective on Vec

1528:    Input Parameter:
1529: .  x - the vector

1531:    Output Parameter:
1532: .  y - the copy

1534:    Notes:
1535:    For default parallel PETSc vectors, both x and y must be distributed in
1536:    the same manner; local copies are done.

1538:    Developer Notes:
1540:    of the vectors to be sequential and one to be parallel so long as both have the same
1541:    local sizes. This is used in some internal functions in PETSc.

1543:    Level: beginner

1545: .seealso: VecDuplicate()
1546: @*/
1547: PetscErrorCode  VecCopy(Vec x,Vec y)
1548: {
1549:   PetscBool      flgs[4];
1550:   PetscReal      norms[4] = {0.0,0.0,0.0,0.0};
1552:   PetscInt       i;

1559:   if (x == y) return(0);
1560:   VecCheckSameLocalSize(x,1,y,2);
1561:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
1562:   VecSetErrorIfLocked(y,2);

1564: #if !defined(PETSC_USE_MIXED_PRECISION)
1565:   for (i=0; i<4; i++) {
1566:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
1567:   }
1568: #endif

1570:   PetscLogEventBegin(VEC_Copy,x,y,0,0);
1571: #if defined(PETSC_USE_MIXED_PRECISION)
1572:   extern PetscErrorCode VecGetArray(Vec,double**);
1573:   extern PetscErrorCode VecRestoreArray(Vec,double**);
1574:   extern PetscErrorCode VecGetArray(Vec,float**);
1575:   extern PetscErrorCode VecRestoreArray(Vec,float**);
1576:   extern PetscErrorCode VecGetArrayRead(Vec,const double**);
1577:   extern PetscErrorCode VecRestoreArrayRead(Vec,const double**);
1578:   extern PetscErrorCode VecGetArrayRead(Vec,const float**);
1579:   extern PetscErrorCode VecRestoreArrayRead(Vec,const float**);
1580:   if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1581:     PetscInt    i,n;
1582:     const float *xx;
1583:     double      *yy;
1584:     VecGetArrayRead(x,&xx);
1585:     VecGetArray(y,&yy);
1586:     VecGetLocalSize(x,&n);
1587:     for (i=0; i<n; i++) yy[i] = xx[i];
1588:     VecRestoreArrayRead(x,&xx);
1589:     VecRestoreArray(y,&yy);
1590:   } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1591:     PetscInt     i,n;
1592:     float        *yy;
1593:     const double *xx;
1594:     VecGetArrayRead(x,&xx);
1595:     VecGetArray(y,&yy);
1596:     VecGetLocalSize(x,&n);
1597:     for (i=0; i<n; i++) yy[i] = (float) xx[i];
1598:     VecRestoreArrayRead(x,&xx);
1599:     VecRestoreArray(y,&yy);
1600:   } else {
1601:     (*x->ops->copy)(x,y);
1602:   }
1603: #else
1604:   (*x->ops->copy)(x,y);
1605: #endif

1607:   PetscObjectStateIncrease((PetscObject)y);
1608: #if !defined(PETSC_USE_MIXED_PRECISION)
1609:   for (i=0; i<4; i++) {
1610:     if (flgs[i]) {
1611:       PetscObjectComposedDataSetReal((PetscObject)y,NormIds[i],norms[i]);
1612:     }
1613:   }
1614: #endif

1616:   PetscLogEventEnd(VEC_Copy,x,y,0,0);
1617:   return(0);
1618: }

1620: /*@
1621:    VecSwap - Swaps the vectors x and y.

1623:    Logically Collective on Vec

1625:    Input Parameters:
1626: .  x, y  - the vectors

1628:    Level: advanced

1630: @*/
1631: PetscErrorCode  VecSwap(Vec x,Vec y)
1632: {
1633:   PetscReal      normxs[4]={0.0,0.0,0.0,0.0},normys[4]={0.0,0.0,0.0,0.0};
1634:   PetscBool      flgxs[4],flgys[4];
1636:   PetscInt       i;

1644:   VecCheckSameSize(x,1,y,2);
1645:   if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
1646:   if (y->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
1647:   VecSetErrorIfLocked(x,1);
1648:   VecSetErrorIfLocked(y,2);

1650:   PetscLogEventBegin(VEC_Swap,x,y,0,0);
1651:   for (i=0; i<4; i++) {
1652:     PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],normxs[i],flgxs[i]);
1653:     PetscObjectComposedDataGetReal((PetscObject)y,NormIds[i],normys[i],flgys[i]);
1654:   }
1655:   (*x->ops->swap)(x,y);
1656:   PetscObjectStateIncrease((PetscObject)x);
1657:   PetscObjectStateIncrease((PetscObject)y);
1658:   for (i=0; i<4; i++) {
1659:     if (flgxs[i]) {
1660:       PetscObjectComposedDataSetReal((PetscObject)y,NormIds[i],normxs[i]);
1661:     }
1662:     if (flgys[i]) {
1663:       PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],normys[i]);
1664:     }
1665:   }
1666:   PetscLogEventEnd(VEC_Swap,x,y,0,0);
1667:   return(0);
1668: }

1670: /*
1671:   VecStashViewFromOptions - Processes command line options to determine if/how an VecStash object is to be viewed.

1673:   Collective on VecStash

1675:   Input Parameters:
1676: + obj   - the VecStash object
1677: . bobj - optional other object that provides the prefix
1678: - optionname - option to activate viewing

1680:   Level: intermediate

1682:   Developer Note: This cannot use PetscObjectViewFromOptions() because it takes a Vec as an argument but does not use VecView

1684: */
1685: PetscErrorCode VecStashViewFromOptions(Vec obj,PetscObject bobj,const char optionname[])
1686: {
1687:   PetscErrorCode    ierr;
1688:   PetscViewer       viewer;
1689:   PetscBool         flg;
1690:   PetscViewerFormat format;
1691:   char              *prefix;

1694:   prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1695:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj),((PetscObject)obj)->options,prefix,optionname,&viewer,&format,&flg);
1696:   if (flg) {
1697:     PetscViewerPushFormat(viewer,format);
1698:     VecStashView(obj,viewer);
1699:     PetscViewerPopFormat(viewer);
1700:     PetscViewerDestroy(&viewer);
1701:   }
1702:   return(0);
1703: }

1705: /*@
1706:    VecStashView - Prints the entries in the vector stash and block stash.

1708:    Collective on Vec

1710:    Input Parameters:
1711: +  v - the vector
1712: -  viewer - the viewer

1714:    Level: advanced


1717: .seealso: VecSetBlockSize(), VecSetValues(), VecSetValuesBlocked()

1719: @*/
1720: PetscErrorCode  VecStashView(Vec v,PetscViewer viewer)
1721: {
1723:   PetscMPIInt    rank;
1724:   PetscInt       i,j;
1725:   PetscBool      match;
1726:   VecStash       *s;
1727:   PetscScalar    val;


1734:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&match);
1735:   if (!match) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Stash viewer only works with ASCII viewer not %s\n",((PetscObject)v)->type_name);
1736:   PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);
1737:   MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);
1738:   s    = &v->bstash;

1740:   /* print block stash */
1741:   PetscViewerASCIIPushSynchronized(viewer);
1742:   PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Vector Block stash size %D block size %D\n",rank,s->n,s->bs);
1743:   for (i=0; i<s->n; i++) {
1744:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %D ",rank,s->idx[i]);
1745:     for (j=0; j<s->bs; j++) {
1746:       val = s->array[i*s->bs+j];
1747: #if defined(PETSC_USE_COMPLEX)
1748:       PetscViewerASCIISynchronizedPrintf(viewer,"(%18.16e %18.16e) ",PetscRealPart(val),PetscImaginaryPart(val));
1749: #else
1750:       PetscViewerASCIISynchronizedPrintf(viewer,"%18.16e ",val);
1751: #endif
1752:     }
1753:     PetscViewerASCIISynchronizedPrintf(viewer,"\n");
1754:   }
1755:   PetscViewerFlush(viewer);

1757:   s = &v->stash;

1759:   /* print basic stash */
1760:   PetscViewerASCIISynchronizedPrintf(viewer,"[%d]Vector stash size %D\n",rank,s->n);
1761:   for (i=0; i<s->n; i++) {
1762:     val = s->array[i];
1763: #if defined(PETSC_USE_COMPLEX)
1764:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %D (%18.16e %18.16e) ",rank,s->idx[i],PetscRealPart(val),PetscImaginaryPart(val));
1765: #else
1766:     PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Element %D %18.16e\n",rank,s->idx[i],val);
1767: #endif
1768:   }
1769:   PetscViewerFlush(viewer);
1770:   PetscViewerASCIIPopSynchronized(viewer);
1771:   PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);
1772:   return(0);
1773: }

1775: PetscErrorCode PetscOptionsGetVec(PetscOptions options,const char prefix[],const char key[],Vec v,PetscBool *set)
1776: {
1777:   PetscInt       i,N,rstart,rend;
1779:   PetscScalar    *xx;
1780:   PetscReal      *xreal;
1781:   PetscBool      iset;

1784:   VecGetOwnershipRange(v,&rstart,&rend);
1785:   VecGetSize(v,&N);
1786:   PetscCalloc1(N,&xreal);
1787:   PetscOptionsGetRealArray(options,prefix,key,xreal,&N,&iset);
1788:   if (iset) {
1789:     VecGetArray(v,&xx);
1790:     for (i=rstart; i<rend; i++) xx[i-rstart] = xreal[i];
1791:     VecRestoreArray(v,&xx);
1792:   }
1793:   PetscFree(xreal);
1794:   if (set) *set = iset;
1795:   return(0);
1796: }

1798: /*@
1799:    VecGetLayout - get PetscLayout describing vector layout

1801:    Not Collective

1803:    Input Arguments:
1804: .  x - the vector

1806:    Output Arguments:
1807: .  map - the layout

1809:    Level: developer

1811: .seealso: VecGetSizes(), VecGetOwnershipRange(), VecGetOwnershipRanges()
1812: @*/
1813: PetscErrorCode VecGetLayout(Vec x,PetscLayout *map)
1814: {

1818:   *map = x->map;
1819:   return(0);
1820: }

1822: /*@
1823:    VecSetLayout - set PetscLayout describing vector layout

1825:    Not Collective

1827:    Input Arguments:
1828: +  x - the vector
1829: -  map - the layout

1831:    Notes:
1832:    It is normally only valid to replace the layout with a layout known to be equivalent.

1834:    Level: developer

1836: .seealso: VecGetLayout(), VecGetSizes(), VecGetOwnershipRange(), VecGetOwnershipRanges()
1837: @*/
1838: PetscErrorCode VecSetLayout(Vec x,PetscLayout map)
1839: {

1844:   PetscLayoutReference(map,&x->map);
1845:   return(0);
1846: }

1848: PetscErrorCode VecSetInf(Vec xin)
1849: {
1850:   PetscInt       i,n = xin->map->n;
1851:   PetscScalar    *xx;
1852:   PetscScalar    zero=0.0,one=1.0,inf=one/zero;

1856:   VecGetArrayWrite(xin,&xx);
1857:   for (i=0; i<n; i++) xx[i] = inf;
1858:   VecRestoreArrayWrite(xin,&xx);
1859:   return(0);
1860: }

1862: /*@
1863:      VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU

1865:    Input Parameters:
1866: +   v - the vector
1867: -   flg - bind to the CPU if value of PETSC_TRUE

1869:    Level: intermediate
1870: @*/
1871: PetscErrorCode VecBindToCPU(Vec v,PetscBool flg)
1872: {
1873: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)

1877:   if (v->boundtocpu == flg) return(0);
1878:   v->boundtocpu = flg;
1879:   if (v->ops->bindtocpu) {
1880:     (*v->ops->bindtocpu)(v,flg);
1881:   }
1882:   return(0);
1883: #else
1884:   return 0;
1885: #endif
1886: }

1888: /*@C
1889:   VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.

1891:   Logically Collective on Vec

1893:   Input Parameters:
1894: +  v    - the vector
1895: -  mbytes - minimum data size in bytes

1897:   Options Database Keys:

1899: . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
1900:                                   Note that this takes a PetscScalar, to accommodate large values;
1901:                                   specifying -1 ensures that pinned memory will never be used.

1903:   Level: developer

1905: .seealso: VecGetPinnedMemoryMin()
1906: @*/
1907: PetscErrorCode VecSetPinnedMemoryMin(Vec v,size_t mbytes)
1908: {
1909: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1911:   v->minimum_bytes_pinned_memory = mbytes;
1912:   return(0);
1913: #else
1914:   return 0;
1915: #endif
1916: }

1918: /*@C
1919:   VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.

1921:   Logically Collective on Vec

1923:   Input Parameters:
1924: .  v    - the vector

1926:   Output Parameters:
1927: .  mbytes - minimum data size in bytes

1929:   Level: developer

1931: .seealso: VecSetPinnedMemoryMin()
1932: @*/
1933: PetscErrorCode VecGetPinnedMemoryMin(Vec v,size_t *mbytes)
1934: {
1935: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1937:   *mbytes = v->minimum_bytes_pinned_memory;
1938:   return(0);
1939: #else
1940:   return 0;
1941: #endif
1942: }

1944: /*@
1945:   VecGetOffloadMask - Get the offload mask of a Vec.

1947:   Not Collective

1949:   Input Parameters:
1950: .   v - the vector

1952:   Output Parameters:
1953: .   mask - corresponding PetscOffloadMask enum value.

1955:    Level: intermediate

1957: .seealso: VecCreateSeqCUDA(), VecCreateSeqViennaCL(), VecGetArray(), VecGetType()
1958: @*/
1959: PetscErrorCode VecGetOffloadMask(Vec v,PetscOffloadMask* mask)
1960: {
1962:   *mask = v->offloadmask;
1963:   return(0);
1964: }


1967: #if !defined(PETSC_HAVE_VIENNACL)
1968: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v,PETSC_UINTPTR_T* ctx)
1969: {
1970:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_context");
1971: }

1973: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v,PETSC_UINTPTR_T* queue)
1974: {
1975:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
1976: }

1978: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v,PETSC_UINTPTR_T* queue)
1979: {
1980:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
1981: }

1983: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v,PETSC_UINTPTR_T* queue)
1984: {
1985:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
1986: }

1988: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v,PETSC_UINTPTR_T* queue)
1989: {
1990:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to get a Vec's cl_mem");
1991: }

1993: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
1994: {
1995:   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
1996: }
1997: #endif