Actual source code: taovec_petsc.c
1: #include "tao_general.h"
3: #ifdef TAO_USE_PETSC
5: #include "taovec_petsc.h"
6: #include "../indexset/taois_petsc.h"
8: int VecMedian(Vec, Vec, Vec, Vec);
9: int VecPointwiseMax(Vec, Vec, Vec);
10: int VecPointwiseMin(Vec, Vec, Vec);
11: int VecFischer(Vec, Vec, Vec, Vec, Vec);
12: int VecSFischer(Vec, Vec, Vec, Vec, double, Vec);
13: int VecBoundProjection(Vec, Vec, Vec, Vec, Vec);
14: int VecCreateSubVec(Vec, IS, Vec *);
15: int VecISAXPY(Vec, double, Vec, IS);
16: int VecStepMax(Vec, Vec, double*);
17: int VecStepMax2(Vec, Vec,Vec, Vec, double*);
18: int VecCompare(Vec, Vec, PetscTruth *);
19: int VecBoundStepInfo(Vec, Vec, Vec, Vec, PetscReal *, PetscReal *, PetscReal *);
20: int VecPow(Vec, double);
22: static int petscminmaxevent=0;
26: /*@C
27: TaoWrapPetscVec - Creates a new TaoVec object using an existing
28: PETSc Vec.
30: Input Parameter:
31: + V - a PETSc vector
32: - TV - the address of a pointer to a TaoVecPetsc
34: Output Parameter:
35: . TV - pointer to a new TaoVecPetsc
37: Note: A TaoVecPetsc is an object with the methods of an abstract
38: TaoVec object. A TaoVecPetsc contains an implementation of the TaoVec
39: methods. Routines using these vectors should declare a pointer to
40: a TaoVec, assign this pointer to the address of a TaoVec object,
41: use the pointer to invoke methods on the object, and use this pointer
42: as an argument when calling other routines. This usage is different
43: from the usage of a PETSc Vec. In PETSc, applications will typically
44: declare a Vec, and pass it as an argument into routines. That is,
45: applications will typically declare a pointer to a TaoVec and use the
46: pointer, or declare a Vec and use it directly.
47:
48: Note:
49: The user is responsible for destroying the Vec V, in addition to
50: to TaoVecPetsc vector TV. The Vec can be destroyed immediately
51: after this routine.
53: Level: developer
55: .seealso TaoVecGetPetscVec(), TaoVecDestroy()
57: @*/
58: int TaoWrapPetscVec( Vec V, TaoVecPetsc* *TV){
59: int info;
61: *TV = new TaoVecPetsc(V);
62: info=(*TV)->SetVec(V); CHKERRQ(info);
63: return(0);
64: }
68: TaoVecPetsc::TaoVecPetsc(Vec VV)
69: {
70: pv=0;
71: pvecviewer=0;
72: if (VV) {
73: SetVec(VV);
74: }
75: if (petscminmaxevent==0){
76: PetscLogEventRegister(&petscminmaxevent,"PointwiseMinMax",VEC_COOKIE);
77: }
78: return;
79: }
83: TaoVecPetsc::~TaoVecPetsc()
84: {
85: SetVec(0);
86: return;
87: }
91: /*@C
92: SetVec - Set or replace the underlying Vec object in this TaoVec.
94: Input Parameter:
95: . V - a PETSc vector
97: Note:
98: The user us repsonsible for destroying the Vec V, in addition to
99: to TaoVecPetsc vector TV. The Vec can be destroyed immediately
100: after this routine.
102: Level: developer
104: .seealso TaoWrapPetscVec(), TaoVecDestroy()
106: @*/
107: int TaoVecPetsc::SetVec(Vec VV){
108: int info;
110: if (VV){
112: PetscObjectReference((PetscObject)VV);
113: // info = PetscInfo(VV,"Set the PETSc Vec in a TaoVec .\n"); CHKERRQ(info);
114: }
115: if (pv) {
116: info=VecDestroy(pv); CHKERRQ(info);
117: }
118: pv=VV;
119: return(0);
120: }
124: int TaoVecPetsc::Clone(TaoVec**ntv){
125: int info;
126: TaoVecPetsc *nptv;
127: Vec npv;
129: info=VecDuplicate(pv,&npv); CHKERRQ(info);
130: info = TaoWrapPetscVec(npv,&nptv); CHKERRQ(info);
131: *ntv=nptv;
132: info = VecDestroy(npv); CHKERRQ(info);
133: nptv->pvecviewer=pvecviewer;
134: return(0);
135: }
140: int TaoVecPetsc::Compatible(TaoVec *tv, TaoTruth *flag){
141: TaoVecPetsc *vv = (TaoVecPetsc *)(tv);
142: PetscTruth flg=PETSC_TRUE;
143: int info=0;
146: if (vv==0){
147: *flag=TAO_FALSE;
148: return(0);
149: }
150: info = VecCompare(pv, vv->pv, &flg); CHKERRQ(info);
151: if (flg==PETSC_FALSE){
152: *flag=TAO_FALSE;
153: } else {
154: *flag=TAO_TRUE;
155: }
156: return(0);
157: }
161: int TaoVecPetsc::SetToConstant( double cc ){
162: int info;
163: PetscScalar c=cc;
165: info=VecSet(pv, c); CHKERRQ(info);
166: return(0);
167: }
171: int TaoVecPetsc::SetToZero(){
172: PetscScalar zero=0.0;
173: int info;
175: info=VecSet(pv, zero); CHKERRQ(info);
176: return(0);
177: }
181: int TaoVecPetsc::CopyFrom(TaoVec* tv)
182: {
183: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
184: int info;
187: info = VecCopy(mv->pv, pv); CHKERRQ(info);
188: return(0);
189: }
193: int TaoVecPetsc::ScaleCopyFrom(double a, TaoVec *tv)
194: {
195: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
196: PetscScalar alpha=a, zero=0.0;
197: int info;
199: info=VecAXPBY(pv,alpha,zero,mv->pv); CHKERRQ(info);
200: return(0);
201: }
205: int TaoVecPetsc::NormInfinity(double *vnorm){
206: int info;
207: PetscReal vv;
209: info=VecNorm(pv,NORM_INFINITY,&vv); CHKERRQ(info);
210: *vnorm=(double)vv;
211: return(0);
212: }
216: int TaoVecPetsc::Norm1(double *vnorm){
217: int info;
218: PetscReal vv;
220: info=VecNorm(pv,NORM_1,&vv); CHKERRQ(info);
221: *vnorm=(double)vv;
222: return(0);
223: }
227: int TaoVecPetsc::Norm2(double *vnorm){
228: int info;
229: PetscReal vv;
231: info=VecNorm(pv,NORM_2,&vv); CHKERRQ(info);
232: *vnorm=(double)vv;
233: return(0);
234: }
238: int TaoVecPetsc::Norm2squared(double *vnorm){
239: int info;
240: PetscReal vv;
242: info=VecNorm(pv,NORM_2,&vv); CHKERRQ(info);
243: *vnorm=(double)(vv*vv);
244: return(0);
245: }
249: int TaoVecPetsc::Scale( double alpha ){
250: int info;
251: PetscScalar aalpha=alpha;
253: info=VecScale(pv, aalpha); CHKERRQ(info);
254: return(0);
255: }
260: int TaoVecPetsc::Axpy(double alpha, TaoVec *tv)
261: {
262: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
263: PetscScalar aalpha=alpha;
264: int info;
266: info=VecAXPY(pv, aalpha, mv->pv); CHKERRQ(info);
267: return(0);
268: }
273: int TaoVecPetsc::Axpby(double alpha, TaoVec *tv, double beta)
274: {
275: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
276: PetscScalar aalpha = alpha, bbeta = beta;
277: int info;
279: info=VecAXPBY(pv,aalpha,bbeta,mv->pv); CHKERRQ(info);
280: return(0);
281: }
285: int TaoVecPetsc::Aypx(double alpha, TaoVec *tv)
286: {
287: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
288: PetscScalar aalpha = alpha;
289: int info;
291: info=VecAYPX(pv,aalpha,mv->pv); CHKERRQ(info);
292: return(0);
293: }
294:
297: int TaoVecPetsc::AddConstant( double cc )
298: {
299: int info;
300: PetscScalar c=cc;
302: info=VecShift(pv, c); CHKERRQ(info);
303: return(0);
304: }
308: int TaoVecPetsc::Dot( TaoVec* tv, double *vDotv )
309: {
310: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
311: PetscScalar c;
312: int info;
314: info=VecDot(pv, mv->pv, &c); CHKERRQ(info);
315: *vDotv=c;
316: return(0);
317: }
321: int TaoVecPetsc::Negate(){
322: PetscScalar m1=-1.0;
323: int info;
325: info=VecScale(pv, m1); CHKERRQ(info);
326: return(0);
327: }
331: int TaoVecPetsc::Reciprocal(){
332: int info;
334: info=VecReciprocal(pv); CHKERRQ(info);
335: return(0);
336: }
341: int TaoVecPetsc::Sqrt(){
342: int info;
344: info=VecSqrt(pv); CHKERRQ(info);
345: return(0);
346: }
351: int TaoVecPetsc::Pow(double p){
352: int info;
354: info=VecPow(pv, p); CHKERRQ(info);
355: return(0);
356: }
360: int TaoVecPetsc::GetDimension(int *n){
361: int info;
363: info=VecGetSize(pv,n); CHKERRQ(info);
364: return(0);
365: }
369: int TaoVecPetsc::PointwiseMultiply(TaoVec *tv, TaoVec *tw)
370: {
371: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
372: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
373: int info;
375: info=VecPointwiseMult(pv, mv->pv, mw->pv); CHKERRQ(info);
376: return(0);
377: }
382: int TaoVecPetsc::PointwiseDivide( TaoVec* tv , TaoVec* tw)
383: {
384: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
385: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
386: int info;
388: info=VecPointwiseDivide(pv, mv->pv, mw->pv); CHKERRQ(info);
389: return(0);
390: }
394: int TaoVecPetsc::Median( TaoVec* tv, TaoVec* tw, TaoVec* tx)
395: {
396: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
397: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
398: TaoVecPetsc *mx = dynamic_cast <TaoVecPetsc *> (tx);
399: int info;
401: info=PetscLogEventBegin(petscminmaxevent,0,0,0,0); CHKERRQ(info);
402: info=VecMedian(mv->pv,mw->pv,mx->pv,pv); CHKERRQ(info);
403: info=PetscLogEventEnd(petscminmaxevent,0,0,0,0); CHKERRQ(info);
404: return(0);
405: }
409: int TaoVecPetsc::PointwiseMinimum( TaoVec* tv, TaoVec* tw)
410: {
411: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
412: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
413: int info;
415: info=PetscLogEventBegin(petscminmaxevent,0,0,0,0); CHKERRQ(info);
416: info=VecPointwiseMin(pv, mv->pv, mw->pv); CHKERRQ(info);
417: info=PetscLogEventEnd(petscminmaxevent,0,0,0,0); CHKERRQ(info);
418: return(0);
419: }
423: int TaoVecPetsc::Fischer(TaoVec *tx, TaoVec *tf, TaoVec *tl, TaoVec *tu)
424: {
425: TaoVecPetsc *xx = dynamic_cast <TaoVecPetsc *> (tx);
426: TaoVecPetsc *ff = dynamic_cast <TaoVecPetsc *> (tf);
427: TaoVecPetsc *ll = dynamic_cast <TaoVecPetsc *> (tl);
428: TaoVecPetsc *uu = dynamic_cast <TaoVecPetsc *> (tu);
429: int info;
432: info=VecFischer(xx->pv, ff->pv, ll->pv, uu->pv, pv); CHKERRQ(info);
433: return(0);
434: }
438: int TaoVecPetsc::SFischer(TaoVec *tx, TaoVec *tf,
439: TaoVec *tl, TaoVec *tu, double mu)
440: {
441: TaoVecPetsc *xx = dynamic_cast <TaoVecPetsc *> (tx);
442: TaoVecPetsc *ff = dynamic_cast <TaoVecPetsc *> (tf);
443: TaoVecPetsc *ll = dynamic_cast <TaoVecPetsc *> (tl);
444: TaoVecPetsc *uu = dynamic_cast <TaoVecPetsc *> (tu);
445: int info;
448: if ((mu >= -TAO_EPSILON) && (mu <= TAO_EPSILON)) {
449: Fischer(tx, tf, tl, tu);
450: }
451: else {
452: info=VecSFischer(xx->pv, ff->pv, ll->pv, uu->pv, mu, pv); CHKERRQ(info);
453: }
454: return(0);
455: }
459: int TaoVecPetsc::PointwiseMaximum( TaoVec* tv, TaoVec* tw)
460: {
461: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
462: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
463: int info;
465: info=PetscLogEventBegin(petscminmaxevent,0,0,0,0); CHKERRQ(info);
466: info=VecPointwiseMax(pv, mv->pv, mw->pv); CHKERRQ(info);
467: info=PetscLogEventEnd(petscminmaxevent,0,0,0,0); CHKERRQ(info);
468: return(0);
469: }
474: int TaoVecPetsc::Waxpby ( double aa, TaoVec* tv, double bb, TaoVec* tw)
475: {
476: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
477: TaoVecPetsc *mw = dynamic_cast <TaoVecPetsc *> (tw);
478: int info;
479: PetscScalar a=aa, b=bb, zero=0.0;
482: if (a==1){
483: info = VecWAXPY(pv,b,mw->pv,mv->pv); CHKERRQ(info);
484: }
485: else if (b==1) {
486: info = VecWAXPY(pv,a,mv->pv,mw->pv); CHKERRQ(info);
487: }
488: else if (a==0) {
489: info = VecSet(pv, zero); CHKERRQ(info);
490: info = VecAXPY(pv, b, mw->pv); CHKERRQ(info);
491: }
492: else if (b==0) {
493: info = VecSet(pv, zero); CHKERRQ(info);
494: info = VecAXPY(pv, a, mv->pv); CHKERRQ(info);
495: }
496: else {
497: info = VecCopy(mw->pv,pv); CHKERRQ(info);
498: info = VecAXPBY(pv,a,b,mv->pv); CHKERRQ(info);
499: }
500: return(0);
501: }
505: int TaoVecPetsc::AbsoluteValue(){
506: int info;
508: info=VecAbs(pv); CHKERRQ(info);
509: return(0);
510: }
514: int TaoVecPetsc::MinElement(double*val){
515: int info, p;
516: PetscScalar a;
518: info = VecMin(pv,&p, &a);CHKERRQ(info);
519: *val=a;
520: return(0);
521: }
526: int TaoVecPetsc::GetArray(TaoScalar **dptr, int *n){
527: int info;
528: PetscScalar *pptr;
530: if (sizeof(TaoScalar)==sizeof(PetscScalar)){
531: info = VecGetLocalSize(pv,n);CHKERRQ(info);
532: info = VecGetArray(pv,&pptr);CHKERRQ(info);
533: *dptr=(TaoScalar*)pptr;
534: } else {
535: SETERRQ(1,"Incompatible data types");
536: }
537: return(0);
538: }
542: int TaoVecPetsc::RestoreArray(TaoScalar **dptr,int *n){
543: int info;
544: PetscScalar *pptr;
546: if (sizeof(TaoScalar)==sizeof(PetscScalar)){
547: pptr=(PetscScalar*)(*dptr);
548: info = VecRestoreArray(pv,&pptr); CHKERRQ(info);
549: *dptr=PETSC_NULL;
550: *n=0;
551: } else {
552: SETERRQ(1,"Incompatible data types");
553: }
554: return(0);
555: }
560: int TaoVecPetsc::SetReducedVec(TaoVec *tv, TaoIndexSet *ti)
561: {
562: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
563: TaoIndexSetPetsc *TSS = dynamic_cast <TaoIndexSetPetsc *> (ti);
565: int info,nn,nnn;
566: TaoPetscISType type;
569: info = TSS->GetSize(&nn); CHKERRQ(info);
570: info = TSS->GetReducedType(&type); CHKERRQ(info);
571: info = mv->GetDimension(&nnn); CHKERRQ(info);
572: if (type==TaoMaskFullSpace){
573: }
574: else if (type==TaoMatrixFree){
575: info = VecCopy(mv->pv,pv); CHKERRQ(info);
576: info = VecISSetToConstant(TSS->GetIS(),0.0,pv);CHKERRQ(info);
577: }
579: info=ReducedCopyFromFull(mv,TSS);CHKERRQ(info);
581: return(0);
582: }
586: int TaoVecPetsc::ReducedXPY(TaoVec *tv, TaoIndexSet *ti)
587: {
588: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
589: TaoIndexSetPetsc *TSS = dynamic_cast <TaoIndexSetPetsc *> (ti);
591: VecScatter scatterit;
592: int info;
596: info = TSS->GetReducedVecScatter(mv->pv,pv, &scatterit);CHKERRQ(info);
597:
598: info = VecScatterBegin(scatterit,mv->pv,pv,ADD_VALUES,SCATTER_REVERSE);
599: CHKERRQ(info);
600: info = VecScatterEnd(scatterit,mv->pv,pv,ADD_VALUES,SCATTER_REVERSE);
601: CHKERRQ(info);
603: return(0);
604: }
608: int TaoVecPetsc::ReducedCopyFromFull(TaoVec *tv, TaoIndexSet *ti)
609: {
610: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
611: TaoIndexSetPetsc *TSS = dynamic_cast <TaoIndexSetPetsc *> (ti);
613: int info;
614: PetscScalar zero=0.0;
615: VecScatter scatterit;
619: info = VecSet(pv, zero); CHKERRQ(info);
620: info = TSS->GetReducedVecScatter(mv->pv,pv, &scatterit);CHKERRQ(info);
621: info = VecScatterBegin(scatterit,mv->pv,pv,INSERT_VALUES,SCATTER_FORWARD);
622: CHKERRQ(info);
623: info = VecScatterEnd(scatterit,mv->pv,pv,INSERT_VALUES,SCATTER_FORWARD);
624: CHKERRQ(info);
626: return(0);
627: }
633: int TaoVecPetsc::StepMax(TaoVec *tv, double *step)
634: {
635: TaoVecPetsc *mv = dynamic_cast <TaoVecPetsc *> (tv);
636: PetscReal pstep;
637: int info;
639: info = VecStepMax(pv, mv->pv, &pstep);CHKERRQ(info);
640: *step=pstep;
641: return(0);
642: }
646: int TaoVecPetsc::StepBoundInfo(TaoVec *txl ,TaoVec *txu, TaoVec *ts,
647: double *bmin1, double *bmin2, double *bmax)
648: {
649: TaoVecPetsc *mxl = dynamic_cast <TaoVecPetsc *> (txl);
650: TaoVecPetsc *mxu = dynamic_cast <TaoVecPetsc *> (txu);
651: TaoVecPetsc *ms = dynamic_cast <TaoVecPetsc *> (ts);
653: int info;
654: PetscReal p1,p2,p3;
656: info=VecBoundStepInfo(pv,mxl->pv,mxu->pv,ms->pv,&p1,&p2,&p3); CHKERRQ(info);
657: *bmin1=p1; *bmin2=p2; *bmax=p3;
658: return(0);
659: }
663: /*@C
664: SetPetscViewer
666: Input Parameter:
667: . viewer - a viewer object to be used with View() and VecView()
669: Level: advanced
671: @*/
672: int TaoVecPetsc::SetPetscViewer(PetscViewer viewer)
673: {
675: pvecviewer= viewer;
676: return(0);
677: }
682: int TaoVecPetsc::View()
683: {
684: int info;
686: info=VecView(pv,pvecviewer);CHKERRQ(info);
687: return(0);
688: }
692: int TaoVecPetsc::BoundGradientProjection(TaoVec *tg, TaoVec *txl,
693: TaoVec *tx, TaoVec *txu)
694: {
695: TaoVecPetsc *mg = dynamic_cast <TaoVecPetsc *> (tg);
696: TaoVecPetsc *mx = dynamic_cast <TaoVecPetsc *> (tx);
697: TaoVecPetsc *mxl = dynamic_cast <TaoVecPetsc *> (txl);
698: TaoVecPetsc *mxu = dynamic_cast <TaoVecPetsc *> (txu);
699: int info;
701: info = PetscLogEventBegin(petscminmaxevent,0,0,0,0);CHKERRQ(info);
702: info = VecBoundProjection(mg->pv,mx->pv,mxl->pv,mxu->pv,pv);CHKERRQ(info);
703: info = PetscLogEventEnd(petscminmaxevent,0,0,0,0);CHKERRQ(info);
704: return(0);
705: }
709: int TaoVecPetsc::CreateIndexSet(TaoIndexSet**SSS)
710: {
711: TaoIndexSetPetsc *SS;
714: SS = new TaoIndexSetPetsc(pv);
715: *SSS=SS;
716: return(0);
717: }
720: #endif