LCOV - code coverage report
Current view: top level - sys/vec - veccomp.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 337 346 97.4 %
Date: 2024-12-18 00:51:33 Functions: 46 46 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : 
      11             : #include <slepc/private/vecimplslepc.h>     /*I "slepcvec.h" I*/
      12             : 
      13             : /* Private MPI datatypes and operators */
      14             : static MPI_Datatype MPIU_NORM2=0, MPIU_NORM1_AND_2=0;
      15             : static PetscBool VecCompInitialized = PETSC_FALSE;
      16             : MPI_Op MPIU_NORM2_SUM=0;
      17             : 
      18             : /* Private functions */
      19             : static inline void SumNorm2(PetscReal*,PetscReal*,PetscReal*,PetscReal*);
      20             : static inline PetscReal GetNorm2(PetscReal,PetscReal);
      21             : static inline void AddNorm2(PetscReal*,PetscReal*,PetscReal);
      22             : static PetscErrorCode VecCompSetSubVecs_Comp(Vec,PetscInt,Vec*);
      23             : static PetscErrorCode VecCompGetSubVecs_Comp(Vec,PetscInt*,const Vec**);
      24             : 
      25             : #include "veccomp0.h"
      26             : 
      27             : #define __WITH_MPI__
      28             : #include "veccomp0.h"
      29             : 
      30        7964 : static inline void SumNorm2(PetscReal *ssq0,PetscReal *scale0,PetscReal *ssq1,PetscReal *scale1)
      31             : {
      32        7964 :   PetscReal q;
      33        7964 :   if (*scale0 > *scale1) {
      34        3982 :     q = *scale1/(*scale0);
      35        3982 :     *ssq1 = *ssq0 + q*q*(*ssq1);
      36        3982 :     *scale1 = *scale0;
      37             :   } else {
      38        3982 :     q = *scale0/(*scale1);
      39        3982 :     *ssq1 += q*q*(*ssq0);
      40             :   }
      41        7964 : }
      42             : 
      43       57442 : static inline PetscReal GetNorm2(PetscReal ssq,PetscReal scale)
      44             : {
      45       57442 :   return scale*PetscSqrtReal(ssq);
      46             : }
      47             : 
      48       57454 : static inline void AddNorm2(PetscReal *ssq,PetscReal *scale,PetscReal x)
      49             : {
      50       57454 :   PetscReal absx,q;
      51       57454 :   if (x != 0.0) {
      52       57454 :     absx = PetscAbs(x);
      53       57454 :     if (*scale < absx) {
      54       57450 :       q = *scale/absx;
      55       57450 :       *ssq = 1.0 + *ssq*q*q;
      56       57450 :       *scale = absx;
      57             :     } else {
      58           4 :       q = absx/(*scale);
      59           4 :       *ssq += q*q;
      60             :     }
      61             :   }
      62       57454 : }
      63             : 
      64        7964 : SLEPC_EXTERN void MPIAPI SlepcSumNorm2_Local(void *in,void *out,PetscMPIInt *cnt,MPI_Datatype *datatype)
      65             : {
      66        7964 :   PetscInt  i,count = *cnt;
      67        7964 :   PetscReal *xin = (PetscReal*)in,*xout = (PetscReal*)out;
      68             : 
      69        7964 :   PetscFunctionBegin;
      70        7964 :   if (*datatype == MPIU_NORM2) {
      71       15924 :     for (i=0;i<count;i++) {
      72        7962 :       SumNorm2(&xin[i*2],&xin[i*2+1],&xout[i*2],&xout[i*2+1]);
      73             :     }
      74           2 :   } else if (*datatype == MPIU_NORM1_AND_2) {
      75           4 :     for (i=0;i<count;i++) {
      76           2 :       xout[i*3] += xin[i*3];
      77           2 :       SumNorm2(&xin[i*3+1],&xin[i*3+2],&xout[i*3+1],&xout[i*3+2]);
      78             :     }
      79             :   } else {
      80           0 :     (void)(*PetscErrorPrintf)("Can only handle MPIU_NORM* data types");
      81           0 :     MPI_Abort(PETSC_COMM_WORLD,1);
      82             :   }
      83        7964 :   PetscFunctionReturnVoid();
      84             : }
      85             : 
      86          36 : static PetscErrorCode VecCompNormEnd(void)
      87             : {
      88          36 :   PetscFunctionBegin;
      89          36 :   PetscCallMPI(MPI_Type_free(&MPIU_NORM2));
      90          36 :   PetscCallMPI(MPI_Type_free(&MPIU_NORM1_AND_2));
      91          36 :   PetscCallMPI(MPI_Op_free(&MPIU_NORM2_SUM));
      92          36 :   VecCompInitialized = PETSC_FALSE;
      93          36 :   PetscFunctionReturn(PETSC_SUCCESS);
      94             : }
      95             : 
      96          36 : static PetscErrorCode VecCompNormInit(void)
      97             : {
      98          36 :   PetscFunctionBegin;
      99          36 :   PetscCallMPI(MPI_Type_contiguous(2,MPIU_REAL,&MPIU_NORM2));
     100          36 :   PetscCallMPI(MPI_Type_commit(&MPIU_NORM2));
     101          36 :   PetscCallMPI(MPI_Type_contiguous(3,MPIU_REAL,&MPIU_NORM1_AND_2));
     102          36 :   PetscCallMPI(MPI_Type_commit(&MPIU_NORM1_AND_2));
     103          36 :   PetscCallMPI(MPI_Op_create(SlepcSumNorm2_Local,PETSC_TRUE,&MPIU_NORM2_SUM));
     104          36 :   PetscCall(PetscRegisterFinalize(VecCompNormEnd));
     105          36 :   PetscFunctionReturn(PETSC_SUCCESS);
     106             : }
     107             : 
     108        3680 : PetscErrorCode VecDestroy_Comp(Vec v)
     109             : {
     110        3680 :   Vec_Comp       *vs = (Vec_Comp*)v->data;
     111        3680 :   PetscInt       i;
     112             : 
     113        3680 :   PetscFunctionBegin;
     114             : #if defined(PETSC_USE_LOG)
     115        3680 :   PetscCall(PetscLogObjectState((PetscObject)v,"Length=%" PetscInt_FMT,v->map->n));
     116             : #endif
     117        7372 :   for (i=0;i<vs->nx;i++) PetscCall(VecDestroy(&vs->x[i]));
     118        3680 :   if (--vs->n->friends <= 0) PetscCall(PetscFree(vs->n));
     119        3680 :   PetscCall(PetscFree(vs->x));
     120        3680 :   PetscCall(PetscFree(vs));
     121        3680 :   PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompSetSubVecs_C",NULL));
     122        3680 :   PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompGetSubVecs_C",NULL));
     123        3680 :   PetscFunctionReturn(PETSC_SUCCESS);
     124             : }
     125             : 
     126             : static struct _VecOps DvOps = {
     127             :   PetscDesignatedInitializer(duplicate,VecDuplicate_Comp),
     128             :   PetscDesignatedInitializer(duplicatevecs,VecDuplicateVecs_Comp),
     129             :   PetscDesignatedInitializer(destroyvecs,VecDestroyVecs_Comp),
     130             :   PetscDesignatedInitializer(dot,VecDot_Comp_MPI),
     131             :   PetscDesignatedInitializer(mdot,VecMDot_Comp_MPI),
     132             :   PetscDesignatedInitializer(norm,VecNorm_Comp_MPI),
     133             :   PetscDesignatedInitializer(tdot,VecTDot_Comp_MPI),
     134             :   PetscDesignatedInitializer(mtdot,VecMTDot_Comp_MPI),
     135             :   PetscDesignatedInitializer(scale,VecScale_Comp),
     136             :   PetscDesignatedInitializer(copy,VecCopy_Comp),
     137             :   PetscDesignatedInitializer(set,VecSet_Comp),
     138             :   PetscDesignatedInitializer(swap,VecSwap_Comp),
     139             :   PetscDesignatedInitializer(axpy,VecAXPY_Comp),
     140             :   PetscDesignatedInitializer(axpby,VecAXPBY_Comp),
     141             :   PetscDesignatedInitializer(maxpy,VecMAXPY_Comp),
     142             :   PetscDesignatedInitializer(aypx,VecAYPX_Comp),
     143             :   PetscDesignatedInitializer(waxpy,VecWAXPY_Comp),
     144             :   PetscDesignatedInitializer(axpbypcz,VecAXPBYPCZ_Comp),
     145             :   PetscDesignatedInitializer(pointwisemult,VecPointwiseMult_Comp),
     146             :   PetscDesignatedInitializer(pointwisedivide,VecPointwiseDivide_Comp),
     147             :   PetscDesignatedInitializer(setvalues,NULL),
     148             :   PetscDesignatedInitializer(assemblybegin,NULL),
     149             :   PetscDesignatedInitializer(assemblyend,NULL),
     150             :   PetscDesignatedInitializer(getarray,NULL),
     151             :   PetscDesignatedInitializer(getsize,VecGetSize_Comp),
     152             :   PetscDesignatedInitializer(getlocalsize,VecGetLocalSize_Comp),
     153             :   PetscDesignatedInitializer(restorearray,NULL),
     154             :   PetscDesignatedInitializer(max,VecMax_Comp),
     155             :   PetscDesignatedInitializer(min,VecMin_Comp),
     156             :   PetscDesignatedInitializer(setrandom,VecSetRandom_Comp),
     157             :   PetscDesignatedInitializer(setoption,NULL),
     158             :   PetscDesignatedInitializer(setvaluesblocked,NULL),
     159             :   PetscDesignatedInitializer(destroy,VecDestroy_Comp),
     160             :   PetscDesignatedInitializer(view,VecView_Comp),
     161             :   PetscDesignatedInitializer(placearray,NULL),
     162             :   PetscDesignatedInitializer(replacearray,NULL),
     163             :   PetscDesignatedInitializer(dot_local,VecDot_Comp_Seq),
     164             :   PetscDesignatedInitializer(tdot_local,VecTDot_Comp_Seq),
     165             :   PetscDesignatedInitializer(norm_local,VecNorm_Comp_Seq),
     166             :   PetscDesignatedInitializer(mdot_local,VecMDot_Comp_Seq),
     167             :   PetscDesignatedInitializer(mtdot_local,VecMTDot_Comp_Seq),
     168             :   PetscDesignatedInitializer(load,NULL),
     169             :   PetscDesignatedInitializer(reciprocal,VecReciprocal_Comp),
     170             :   PetscDesignatedInitializer(conjugate,VecConjugate_Comp),
     171             :   PetscDesignatedInitializer(setlocaltoglobalmapping,NULL),
     172             :   PetscDesignatedInitializer(getlocaltoglobalmapping,NULL),
     173             :   PetscDesignatedInitializer(setvalueslocal,NULL),
     174             :   PetscDesignatedInitializer(resetarray,NULL),
     175             :   PetscDesignatedInitializer(setfromoptions,NULL),
     176             :   PetscDesignatedInitializer(maxpointwisedivide,VecMaxPointwiseDivide_Comp),
     177             :   PetscDesignatedInitializer(pointwisemax,VecPointwiseMax_Comp),
     178             :   PetscDesignatedInitializer(pointwisemaxabs,VecPointwiseMaxAbs_Comp),
     179             :   PetscDesignatedInitializer(pointwisemin,VecPointwiseMin_Comp),
     180             :   PetscDesignatedInitializer(getvalues,NULL),
     181             :   PetscDesignatedInitializer(sqrt,VecSqrtAbs_Comp),
     182             :   PetscDesignatedInitializer(abs,VecAbs_Comp),
     183             :   PetscDesignatedInitializer(exp,VecExp_Comp),
     184             :   PetscDesignatedInitializer(log,VecLog_Comp),
     185             :   PetscDesignatedInitializer(shift,VecShift_Comp),
     186             :   PetscDesignatedInitializer(create,NULL),
     187             :   PetscDesignatedInitializer(stridegather,NULL),
     188             :   PetscDesignatedInitializer(stridescatter,NULL),
     189             :   PetscDesignatedInitializer(dotnorm2,VecDotNorm2_Comp_MPI),
     190             :   PetscDesignatedInitializer(getsubvector,NULL),
     191             :   PetscDesignatedInitializer(restoresubvector,NULL),
     192             :   PetscDesignatedInitializer(getarrayread,NULL),
     193             :   PetscDesignatedInitializer(restorearrayread,NULL),
     194             :   PetscDesignatedInitializer(stridesubsetgather,NULL),
     195             :   PetscDesignatedInitializer(stridesubsetscatter,NULL),
     196             :   PetscDesignatedInitializer(viewnative,NULL),
     197             :   PetscDesignatedInitializer(loadnative,NULL),
     198             :   PetscDesignatedInitializer(getlocalvector,NULL)
     199             : };
     200             : 
     201          39 : PetscErrorCode VecDuplicateVecs_Comp(Vec w,PetscInt m,Vec *V[])
     202             : {
     203          39 :   PetscInt       i;
     204             : 
     205          39 :   PetscFunctionBegin;
     206          39 :   PetscValidHeaderSpecific(w,VEC_CLASSID,1);
     207          39 :   PetscAssertPointer(V,3);
     208          39 :   PetscCheck(m>0,PetscObjectComm((PetscObject)w),PETSC_ERR_ARG_OUTOFRANGE,"m must be > 0: m = %" PetscInt_FMT,m);
     209          39 :   PetscCall(PetscMalloc1(m,V));
     210         415 :   for (i=0;i<m;i++) PetscCall(VecDuplicate(w,*V+i));
     211          39 :   PetscFunctionReturn(PETSC_SUCCESS);
     212             : }
     213             : 
     214          39 : PetscErrorCode VecDestroyVecs_Comp(PetscInt m,Vec v[])
     215             : {
     216          39 :   PetscInt       i;
     217             : 
     218          39 :   PetscFunctionBegin;
     219          39 :   PetscAssertPointer(v,2);
     220          39 :   PetscCheck(m>0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"m must be > 0: m = %" PetscInt_FMT,m);
     221         415 :   for (i=0;i<m;i++) PetscCall(VecDestroy(&v[i]));
     222          39 :   PetscCall(PetscFree(v));
     223          39 :   PetscFunctionReturn(PETSC_SUCCESS);
     224             : }
     225             : 
     226        3680 : static PetscErrorCode VecCreate_Comp_Private(Vec v,Vec *x,PetscInt nx,PetscBool x_to_me,Vec_Comp_N *n)
     227             : {
     228        3680 :   Vec_Comp       *s;
     229        3680 :   PetscInt       N=0,lN=0,i,k;
     230             : 
     231        3680 :   PetscFunctionBegin;
     232        3680 :   if (!VecCompInitialized) {
     233          36 :     VecCompInitialized = PETSC_TRUE;
     234          36 :     PetscCall(VecRegister(VECCOMP,VecCreate_Comp));
     235          36 :     PetscCall(VecCompNormInit());
     236             :   }
     237             : 
     238             :   /* Allocate a new Vec_Comp */
     239        3680 :   if (v->data) PetscCall(PetscFree(v->data));
     240        3680 :   PetscCall(PetscNew(&s));
     241        3680 :   PetscCall(PetscMemcpy(v->ops,&DvOps,sizeof(DvOps)));
     242        3680 :   v->data        = (void*)s;
     243        3680 :   v->petscnative = PETSC_FALSE;
     244             : 
     245             :   /* Allocate the array of Vec, if it is needed to be done */
     246        3680 :   if (!x_to_me) {
     247        2202 :     if (nx) PetscCall(PetscMalloc1(nx,&s->x));
     248        2202 :     if (x) PetscCall(PetscArraycpy(s->x,x,nx));
     249        1478 :   } else s->x = x;
     250             : 
     251        3680 :   s->nx = nx;
     252             : 
     253        3680 :   if (nx && x) {
     254             :     /* Allocate the shared structure, if it is not given */
     255        3677 :     if (!n) {
     256         106 :       for (i=0;i<nx;i++) {
     257          56 :         PetscCall(VecGetSize(x[i],&k));
     258          56 :         N+= k;
     259          56 :         PetscCall(VecGetLocalSize(x[i],&k));
     260          56 :         lN+= k;
     261             :       }
     262          50 :       PetscCall(PetscNew(&n));
     263          50 :       s->n = n;
     264          50 :       n->n = nx;
     265          50 :       n->N = N;
     266          50 :       n->lN = lN;
     267          50 :       n->friends = 1;
     268             :     } else { /* If not, check in the vector in the shared structure */
     269        3627 :       s->n = n;
     270        3627 :       s->n->friends++;
     271             :     }
     272             : 
     273             :     /* Set the virtual sizes as the real sizes of the vector */
     274        3677 :     PetscCall(VecSetSizes(v,s->n->lN,s->n->N));
     275             :   }
     276             : 
     277        3680 :   PetscCall(PetscObjectChangeTypeName((PetscObject)v,VECCOMP));
     278        3680 :   PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompSetSubVecs_C",VecCompSetSubVecs_Comp));
     279        3680 :   PetscCall(PetscObjectComposeFunction((PetscObject)v,"VecCompGetSubVecs_C",VecCompGetSubVecs_Comp));
     280        3680 :   PetscFunctionReturn(PETSC_SUCCESS);
     281             : }
     282             : 
     283           3 : SLEPC_EXTERN PetscErrorCode VecCreate_Comp(Vec V)
     284             : {
     285           3 :   PetscFunctionBegin;
     286           3 :   PetscCall(VecCreate_Comp_Private(V,NULL,0,PETSC_FALSE,NULL));
     287           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     288             : }
     289             : 
     290             : /*@
     291             :    VecCreateComp - Creates a new vector containing several subvectors,
     292             :    each stored separately.
     293             : 
     294             :    Collective
     295             : 
     296             :    Input Parameters:
     297             : +  comm - communicator for the new Vec
     298             : .  Nx   - array of (initial) global sizes of child vectors
     299             : .  n    - number of child vectors
     300             : .  t    - type of the child vectors
     301             : -  Vparent - (optional) template vector
     302             : 
     303             :    Output Parameter:
     304             : .  V - new vector
     305             : 
     306             :    Notes:
     307             :    This is similar to PETSc's VecNest but customized for SLEPc's needs. In particular,
     308             :    the number of child vectors can be modified dynamically, with VecCompSetSubVecs().
     309             : 
     310             :    Level: developer
     311             : 
     312             : .seealso: VecCreateCompWithVecs(), VecCompSetSubVecs()
     313             : @*/
     314           3 : PetscErrorCode VecCreateComp(MPI_Comm comm,PetscInt Nx[],PetscInt n,VecType t,Vec Vparent,Vec *V)
     315             : {
     316           3 :   Vec            *x;
     317           3 :   PetscInt       i;
     318             : 
     319           3 :   PetscFunctionBegin;
     320           3 :   PetscCall(VecCreate(comm,V));
     321           3 :   PetscCall(PetscMalloc1(n,&x));
     322           9 :   for (i=0;i<n;i++) {
     323           6 :     PetscCall(VecCreate(comm,&x[i]));
     324           6 :     PetscCall(VecSetSizes(x[i],PETSC_DECIDE,Nx[i]));
     325           6 :     PetscCall(VecSetType(x[i],t));
     326             :   }
     327           3 :   PetscCall(VecCreate_Comp_Private(*V,x,n,PETSC_TRUE,Vparent?((Vec_Comp*)Vparent->data)->n:NULL));
     328           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     329             : }
     330             : 
     331             : /*@
     332             :    VecCreateCompWithVecs - Creates a new vector containing several subvectors,
     333             :    each stored separately, from an array of Vecs.
     334             : 
     335             :    Collective
     336             : 
     337             :    Input Parameters:
     338             : +  x - array of Vecs
     339             : .  n - number of child vectors
     340             : -  Vparent - (optional) template vector
     341             : 
     342             :    Output Parameter:
     343             : .  V - new vector
     344             : 
     345             :    Level: developer
     346             : 
     347             : .seealso: VecCreateComp()
     348             : @*/
     349        2199 : PetscErrorCode VecCreateCompWithVecs(Vec x[],PetscInt n,Vec Vparent,Vec *V)
     350             : {
     351        2199 :   PetscInt       i;
     352             : 
     353        2199 :   PetscFunctionBegin;
     354        2199 :   PetscAssertPointer(x,1);
     355        2199 :   PetscValidHeaderSpecific(*x,VEC_CLASSID,1);
     356        6597 :   PetscValidLogicalCollectiveInt(*x,n,2);
     357        2199 :   PetscCall(VecCreate(PetscObjectComm((PetscObject)x[0]),V));
     358        4401 :   for (i=0;i<n;i++) PetscCall(PetscObjectReference((PetscObject)x[i]));
     359        2199 :   PetscCall(VecCreate_Comp_Private(*V,x,n,PETSC_FALSE,Vparent?((Vec_Comp*)Vparent->data)->n:NULL));
     360        2199 :   PetscFunctionReturn(PETSC_SUCCESS);
     361             : }
     362             : 
     363        1475 : PetscErrorCode VecDuplicate_Comp(Vec win,Vec *V)
     364             : {
     365        1475 :   Vec            *x;
     366        1475 :   PetscInt       i;
     367        1475 :   Vec_Comp       *s = (Vec_Comp*)win->data;
     368             : 
     369        1475 :   PetscFunctionBegin;
     370        1475 :   SlepcValidVecComp(win,1);
     371        1475 :   PetscCall(VecCreate(PetscObjectComm((PetscObject)win),V));
     372        1475 :   PetscCall(PetscMalloc1(s->nx,&x));
     373        2953 :   for (i=0;i<s->nx;i++) {
     374        1478 :     if (s->x[i]) PetscCall(VecDuplicate(s->x[i],&x[i]));
     375           0 :     else x[i] = NULL;
     376             :   }
     377        1475 :   PetscCall(VecCreate_Comp_Private(*V,x,s->nx,PETSC_TRUE,s->n));
     378        1475 :   PetscFunctionReturn(PETSC_SUCCESS);
     379             : }
     380             : 
     381      220644 : static PetscErrorCode VecCompGetSubVecs_Comp(Vec win,PetscInt *n,const Vec **x)
     382             : {
     383      220644 :   Vec_Comp *s = (Vec_Comp*)win->data;
     384             : 
     385      220644 :   PetscFunctionBegin;
     386      220644 :   if (x) *x = s->x;
     387      220644 :   if (n) *n = s->n->n;
     388      220644 :   PetscFunctionReturn(PETSC_SUCCESS);
     389             : }
     390             : 
     391             : /*@C
     392             :    VecCompGetSubVecs - Returns the entire array of vectors defining a
     393             :    compound vector.
     394             : 
     395             :    Collective
     396             : 
     397             :    Input Parameter:
     398             : .  win - compound vector
     399             : 
     400             :    Output Parameters:
     401             : +  n - number of child vectors
     402             : -  x - array of child vectors
     403             : 
     404             :    Level: developer
     405             : 
     406             : .seealso: VecCreateComp()
     407             : @*/
     408      220644 : PetscErrorCode VecCompGetSubVecs(Vec win,PetscInt *n,const Vec **x)
     409             : {
     410      220644 :   PetscFunctionBegin;
     411      220644 :   PetscValidHeaderSpecific(win,VEC_CLASSID,1);
     412      220644 :   PetscUseMethod(win,"VecCompGetSubVecs_C",(Vec,PetscInt*,const Vec**),(win,n,x));
     413      220644 :   PetscFunctionReturn(PETSC_SUCCESS);
     414             : }
     415             : 
     416        1061 : static PetscErrorCode VecCompSetSubVecs_Comp(Vec win,PetscInt n,Vec *x)
     417             : {
     418        1061 :   Vec_Comp       *s = (Vec_Comp*)win->data;
     419        1061 :   PetscInt       i,N,nlocal;
     420        1061 :   Vec_Comp_N     *nn;
     421             : 
     422        1061 :   PetscFunctionBegin;
     423        1061 :   PetscCheck(s,PetscObjectComm((PetscObject)win),PETSC_ERR_ORDER,"Must call VecSetSizes first");
     424        1061 :   if (!s->nx) {
     425             :     /* vector has been created via VecCreate+VecSetType+VecSetSizes, so allocate data structures */
     426           3 :     PetscCall(PetscMalloc1(n,&s->x));
     427           3 :     PetscCall(VecGetSize(win,&N));
     428           3 :     PetscCheck(N%n==0,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Global dimension %" PetscInt_FMT " is not divisible by %" PetscInt_FMT,N,n);
     429           3 :     PetscCall(VecGetLocalSize(win,&nlocal));
     430           3 :     PetscCheck(nlocal%n==0,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Local dimension %" PetscInt_FMT " is not divisible by %" PetscInt_FMT,nlocal,n);
     431           3 :     s->nx = n;
     432           9 :     for (i=0;i<n;i++) {
     433           6 :       PetscCall(VecCreate(PetscObjectComm((PetscObject)win),&s->x[i]));
     434           6 :       PetscCall(VecSetSizes(s->x[i],nlocal/n,N/n));
     435           6 :       PetscCall(VecSetFromOptions(s->x[i]));
     436             :     }
     437           3 :     if (!s->n) {
     438           3 :       PetscCall(PetscNew(&nn));
     439           3 :       s->n = nn;
     440           3 :       nn->N = N;
     441           3 :       nn->lN = nlocal;
     442           3 :       nn->friends = 1;
     443             :     }
     444        1058 :   } else PetscCheck(n<=s->nx,PetscObjectComm((PetscObject)win),PETSC_ERR_SUP,"Number of child vectors cannot be larger than %" PetscInt_FMT,s->nx);
     445        1061 :   if (x) PetscCall(PetscArraycpy(s->x,x,n));
     446        1061 :   s->n->n = n;
     447        1061 :   PetscFunctionReturn(PETSC_SUCCESS);
     448             : }
     449             : 
     450             : /*@
     451             :    VecCompSetSubVecs - Resets the number of subvectors defining a compound vector,
     452             :    or replaces the subvectors.
     453             : 
     454             :    Collective
     455             : 
     456             :    Input Parameters:
     457             : +  win - compound vector
     458             : .  n - number of child vectors
     459             : -  x - array of child vectors
     460             : 
     461             :    Note:
     462             :    It is not possible to increase the number of subvectors with respect to the
     463             :    number set at its creation.
     464             : 
     465             :    Level: developer
     466             : 
     467             : .seealso: VecCreateComp(), VecCompGetSubVecs()
     468             : @*/
     469        1061 : PetscErrorCode VecCompSetSubVecs(Vec win,PetscInt n,Vec x[])
     470             : {
     471        1061 :   PetscFunctionBegin;
     472        1061 :   PetscValidHeaderSpecific(win,VEC_CLASSID,1);
     473        3183 :   PetscValidLogicalCollectiveInt(win,n,2);
     474        1061 :   PetscTryMethod(win,"VecCompSetSubVecs_C",(Vec,PetscInt,Vec*),(win,n,x));
     475        1061 :   PetscFunctionReturn(PETSC_SUCCESS);
     476             : }
     477             : 
     478       91637 : PetscErrorCode VecAXPY_Comp(Vec v,PetscScalar alpha,Vec w)
     479             : {
     480       91637 :   Vec_Comp       *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
     481       91637 :   PetscInt       i;
     482             : 
     483       91637 :   PetscFunctionBegin;
     484       91637 :   SlepcValidVecComp(v,1);
     485       91637 :   SlepcValidVecComp(w,3);
     486      183274 :   for (i=0;i<vs->n->n;i++) PetscCall(VecAXPY(vs->x[i],alpha,ws->x[i]));
     487       91637 :   PetscFunctionReturn(PETSC_SUCCESS);
     488             : }
     489             : 
     490       54122 : PetscErrorCode VecAYPX_Comp(Vec v,PetscScalar alpha,Vec w)
     491             : {
     492       54122 :   Vec_Comp       *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
     493       54122 :   PetscInt       i;
     494             : 
     495       54122 :   PetscFunctionBegin;
     496       54122 :   SlepcValidVecComp(v,1);
     497       54122 :   SlepcValidVecComp(w,3);
     498      108244 :   for (i=0;i<vs->n->n;i++) PetscCall(VecAYPX(vs->x[i],alpha,ws->x[i]));
     499       54122 :   PetscFunctionReturn(PETSC_SUCCESS);
     500             : }
     501             : 
     502           3 : PetscErrorCode VecAXPBY_Comp(Vec v,PetscScalar alpha,PetscScalar beta,Vec w)
     503             : {
     504           3 :   Vec_Comp       *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
     505           3 :   PetscInt       i;
     506             : 
     507           3 :   PetscFunctionBegin;
     508           3 :   SlepcValidVecComp(v,1);
     509           3 :   SlepcValidVecComp(w,4);
     510           9 :   for (i=0;i<vs->n->n;i++) PetscCall(VecAXPBY(vs->x[i],alpha,beta,ws->x[i]));
     511           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     512             : }
     513             : 
     514       54339 : PetscErrorCode VecMAXPY_Comp(Vec v,PetscInt n,const PetscScalar *alpha,Vec *w)
     515             : {
     516       54339 :   Vec_Comp       *vs = (Vec_Comp*)v->data;
     517       54339 :   Vec            *wx;
     518       54339 :   PetscInt       i,j;
     519             : 
     520       54339 :   PetscFunctionBegin;
     521       54339 :   SlepcValidVecComp(v,1);
     522      187439 :   for (i=0;i<n;i++) SlepcValidVecComp(w[i],4);
     523             : 
     524       54339 :   PetscCall(PetscMalloc1(n,&wx));
     525             : 
     526      108678 :   for (j=0;j<vs->n->n;j++) {
     527      187439 :     for (i=0;i<n;i++) wx[i] = ((Vec_Comp*)w[i]->data)->x[j];
     528       54339 :     PetscCall(VecMAXPY(vs->x[j],n,alpha,wx));
     529             :   }
     530             : 
     531       54339 :   PetscCall(PetscFree(wx));
     532       54339 :   PetscFunctionReturn(PETSC_SUCCESS);
     533             : }
     534             : 
     535        1463 : PetscErrorCode VecWAXPY_Comp(Vec v,PetscScalar alpha,Vec w,Vec z)
     536             : {
     537        1463 :   Vec_Comp       *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
     538        1463 :   PetscInt       i;
     539             : 
     540        1463 :   PetscFunctionBegin;
     541        1463 :   SlepcValidVecComp(v,1);
     542        1463 :   SlepcValidVecComp(w,3);
     543        1463 :   SlepcValidVecComp(z,4);
     544        2929 :   for (i=0;i<vs->n->n;i++) PetscCall(VecWAXPY(vs->x[i],alpha,ws->x[i],zs->x[i]));
     545        1463 :   PetscFunctionReturn(PETSC_SUCCESS);
     546             : }
     547             : 
     548        1463 : PetscErrorCode VecAXPBYPCZ_Comp(Vec v,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec w,Vec z)
     549             : {
     550        1463 :   Vec_Comp        *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data,*zs = (Vec_Comp*)z->data;
     551        1463 :   PetscInt        i;
     552             : 
     553        1463 :   PetscFunctionBegin;
     554        1463 :   SlepcValidVecComp(v,1);
     555        1463 :   SlepcValidVecComp(w,5);
     556        1463 :   SlepcValidVecComp(z,6);
     557        2929 :   for (i=0;i<vs->n->n;i++) PetscCall(VecAXPBYPCZ(vs->x[i],alpha,beta,gamma,ws->x[i],zs->x[i]));
     558        1463 :   PetscFunctionReturn(PETSC_SUCCESS);
     559             : }
     560             : 
     561           9 : PetscErrorCode VecGetSize_Comp(Vec v,PetscInt *size)
     562             : {
     563           9 :   Vec_Comp *vs = (Vec_Comp*)v->data;
     564             : 
     565           9 :   PetscFunctionBegin;
     566           9 :   PetscAssertPointer(size,2);
     567           9 :   if (vs->n) {
     568           6 :     SlepcValidVecComp(v,1);
     569           6 :     *size = vs->n->N;
     570           3 :   } else *size = v->map->N;
     571           9 :   PetscFunctionReturn(PETSC_SUCCESS);
     572             : }
     573             : 
     574       47353 : PetscErrorCode VecGetLocalSize_Comp(Vec v,PetscInt *size)
     575             : {
     576       47353 :   Vec_Comp *vs = (Vec_Comp*)v->data;
     577             : 
     578       47353 :   PetscFunctionBegin;
     579       47353 :   PetscAssertPointer(size,2);
     580       47353 :   if (vs->n) {
     581       47350 :     SlepcValidVecComp(v,1);
     582       47350 :     *size = vs->n->lN;
     583           3 :   } else *size = v->map->n;
     584       47353 :   PetscFunctionReturn(PETSC_SUCCESS);
     585             : }
     586             : 
     587           3 : PetscErrorCode VecMax_Comp(Vec v,PetscInt *idx,PetscReal *z)
     588             : {
     589           3 :   Vec_Comp       *vs = (Vec_Comp*)v->data;
     590           3 :   PetscInt       idxp,s=0,s0;
     591           3 :   PetscReal      zp,z0;
     592           3 :   PetscInt       i;
     593             : 
     594           3 :   PetscFunctionBegin;
     595           3 :   SlepcValidVecComp(v,1);
     596           3 :   if (!idx && !z) PetscFunctionReturn(PETSC_SUCCESS);
     597             : 
     598           6 :   if (vs->n->n > 0) PetscCall(VecMax(vs->x[0],idx?&idxp:NULL,&zp));
     599             :   else {
     600           0 :     zp = PETSC_MIN_REAL;
     601           0 :     if (idx) idxp = -1;
     602             :   }
     603           6 :   for (i=1;i<vs->n->n;i++) {
     604           3 :     PetscCall(VecGetSize(vs->x[i-1],&s0));
     605           3 :     s += s0;
     606           6 :     PetscCall(VecMax(vs->x[i],idx?&idxp:NULL,&z0));
     607           3 :     if (zp < z0) {
     608           0 :       if (idx) *idx = s+idxp;
     609           0 :       zp = z0;
     610             :     }
     611             :   }
     612           3 :   if (z) *z = zp;
     613           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     614             : }
     615             : 
     616           3 : PetscErrorCode VecMin_Comp(Vec v,PetscInt *idx,PetscReal *z)
     617             : {
     618           3 :   Vec_Comp       *vs = (Vec_Comp*)v->data;
     619           3 :   PetscInt       idxp,s=0,s0;
     620           3 :   PetscReal      zp,z0;
     621           3 :   PetscInt       i;
     622             : 
     623           3 :   PetscFunctionBegin;
     624           3 :   SlepcValidVecComp(v,1);
     625           3 :   if (!idx && !z) PetscFunctionReturn(PETSC_SUCCESS);
     626             : 
     627           6 :   if (vs->n->n > 0) PetscCall(VecMin(vs->x[0],idx?&idxp:NULL,&zp));
     628             :   else {
     629           0 :     zp = PETSC_MAX_REAL;
     630           0 :     if (idx) idxp = -1;
     631             :   }
     632           6 :   for (i=1;i<vs->n->n;i++) {
     633           3 :     PetscCall(VecGetSize(vs->x[i-1],&s0));
     634           3 :     s += s0;
     635           6 :     PetscCall(VecMin(vs->x[i],idx?&idxp:NULL,&z0));
     636           3 :     if (zp > z0) {
     637           3 :       if (idx) *idx = s+idxp;
     638           3 :       zp = z0;
     639             :     }
     640             :   }
     641           3 :   if (z) *z = zp;
     642           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     643             : }
     644             : 
     645           3 : PetscErrorCode VecMaxPointwiseDivide_Comp(Vec v,Vec w,PetscReal *m)
     646             : {
     647           3 :   Vec_Comp       *vs = (Vec_Comp*)v->data,*ws = (Vec_Comp*)w->data;
     648           3 :   PetscReal      work;
     649           3 :   PetscInt       i;
     650             : 
     651           3 :   PetscFunctionBegin;
     652           3 :   SlepcValidVecComp(v,1);
     653           3 :   SlepcValidVecComp(w,2);
     654           3 :   if (!m || vs->n->n == 0) PetscFunctionReturn(PETSC_SUCCESS);
     655           3 :   PetscCall(VecMaxPointwiseDivide(vs->x[0],ws->x[0],m));
     656           6 :   for (i=1;i<vs->n->n;i++) {
     657           3 :     PetscCall(VecMaxPointwiseDivide(vs->x[i],ws->x[i],&work));
     658           4 :     *m = PetscMax(*m,work);
     659             :   }
     660           3 :   PetscFunctionReturn(PETSC_SUCCESS);
     661             : }
     662             : 
     663             : #define __QUOTEME__(x) #x
     664             : #define __COMPOSE2__(A,B) A##B
     665             : #define __COMPOSE3__(A,B,C) A##B##C
     666             : 
     667             : #define __FUNC_TEMPLATE1__(NAME) \
     668             : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v) \
     669             : { \
     670             :   Vec_Comp        *vs = (Vec_Comp*)v->data; \
     671             :   PetscInt        i; \
     672             : \
     673             :   PetscFunctionBegin; \
     674             :   SlepcValidVecComp(v,1); \
     675             :   for (i=0;i<vs->n->n;i++) { \
     676             :     PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i])); \
     677             :   } \
     678             :   PetscFunctionReturn(PETSC_SUCCESS);\
     679             : }
     680             : 
     681       11311 : __FUNC_TEMPLATE1__(Conjugate)
     682           9 : __FUNC_TEMPLATE1__(Reciprocal)
     683           9 : __FUNC_TEMPLATE1__(SqrtAbs)
     684           9 : __FUNC_TEMPLATE1__(Abs)
     685           9 : __FUNC_TEMPLATE1__(Exp)
     686           9 : __FUNC_TEMPLATE1__(Log)
     687             : 
     688             : #define __FUNC_TEMPLATE2__(NAME,T0) \
     689             : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,T0 __a) \
     690             : { \
     691             :   Vec_Comp        *vs = (Vec_Comp*)v->data; \
     692             :   PetscInt        i; \
     693             : \
     694             :   PetscFunctionBegin; \
     695             :   SlepcValidVecComp(v,1); \
     696             :   for (i=0;i<vs->n->n;i++) { \
     697             :     PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],__a)); \
     698             :   } \
     699             :   PetscFunctionReturn(PETSC_SUCCESS);\
     700             : }
     701             : 
     702        4120 : __FUNC_TEMPLATE2__(Set,PetscScalar)
     703           9 : __FUNC_TEMPLATE2__(View,PetscViewer)
     704        3525 : __FUNC_TEMPLATE2__(Scale,PetscScalar)
     705           9 : __FUNC_TEMPLATE2__(SetRandom,PetscRandom)
     706           9 : __FUNC_TEMPLATE2__(Shift,PetscScalar)
     707             : 
     708             : #define __FUNC_TEMPLATE3__(NAME) \
     709             : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w) \
     710             : { \
     711             :   Vec_Comp        *vs = (Vec_Comp*)v->data,\
     712             :                   *ws = (Vec_Comp*)w->data; \
     713             :   PetscInt        i; \
     714             : \
     715             :   PetscFunctionBegin; \
     716             :   SlepcValidVecComp(v,1); \
     717             :   SlepcValidVecComp(w,2); \
     718             :   for (i=0;i<vs->n->n;i++) { \
     719             :     PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i])); \
     720             :   } \
     721             :   PetscFunctionReturn(PETSC_SUCCESS);\
     722             : }
     723             : 
     724       43548 : __FUNC_TEMPLATE3__(Copy)
     725           9 : __FUNC_TEMPLATE3__(Swap)
     726             : 
     727             : #define __FUNC_TEMPLATE4__(NAME) \
     728             : PetscErrorCode __COMPOSE3__(Vec,NAME,_Comp)(Vec v,Vec w,Vec z) \
     729             : { \
     730             :   Vec_Comp        *vs = (Vec_Comp*)v->data, \
     731             :                   *ws = (Vec_Comp*)w->data, \
     732             :                   *zs = (Vec_Comp*)z->data; \
     733             :   PetscInt        i; \
     734             : \
     735             :   PetscFunctionBegin; \
     736             :   SlepcValidVecComp(v,1); \
     737             :   SlepcValidVecComp(w,2); \
     738             :   SlepcValidVecComp(z,3); \
     739             :   for (i=0;i<vs->n->n;i++) { \
     740             :     PetscCall(__COMPOSE2__(Vec,NAME)(vs->x[i],ws->x[i],zs->x[i])); \
     741             :   } \
     742             :   PetscFunctionReturn(PETSC_SUCCESS);\
     743             : }
     744             : 
     745           9 : __FUNC_TEMPLATE4__(PointwiseMax)
     746           9 : __FUNC_TEMPLATE4__(PointwiseMaxAbs)
     747           9 : __FUNC_TEMPLATE4__(PointwiseMin)
     748           9 : __FUNC_TEMPLATE4__(PointwiseMult)
     749           9 : __FUNC_TEMPLATE4__(PointwiseDivide)

Generated by: LCOV version 1.14