Actual source code: dm.c
1:
2: #include <private/dmimpl.h> /*I "petscdm.h" I*/
4: PetscClassId DM_CLASSID;
5: PetscLogEvent DM_Convert, DM_GlobalToLocal, DM_LocalToGlobal;
9: /*@
10: DMCreate - Creates an empty vector object. The type can then be set with DMetType().
12: If you never call DMSetType() it will generate an
13: error when you try to use the vector.
15: Collective on MPI_Comm
17: Input Parameter:
18: . comm - The communicator for the DM object
20: Output Parameter:
21: . dm - The DM object
23: Level: beginner
25: .seealso: DMSetType(), DMDA, DMSLICED, DMCOMPOSITE
26: @*/
27: PetscErrorCode DMCreate(MPI_Comm comm,DM *dm)
28: {
29: DM v;
34: *dm = PETSC_NULL;
35: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
36: DMInitializePackage(PETSC_NULL);
37: #endif
39: PetscHeaderCreate(v, _p_DM, struct _DMOps, DM_CLASSID, -1, "DM", "Distribution Manager", "DM", comm, DMDestroy, DMView);
40: PetscMemzero(v->ops, sizeof(struct _DMOps));
42: v->ltogmap = PETSC_NULL;
43: v->ltogmapb = PETSC_NULL;
44: v->bs = 1;
46: *dm = v;
47: return(0);
48: }
53: /*@C
54: DMSetVecType - Sets the type of vector created with DMCreateLocalVector() and DMCreateGlobalVector()
56: Logically Collective on DMDA
58: Input Parameter:
59: + da - initial distributed array
60: . ctype - the vector type, currently either VECSTANDARD or VECCUSP
62: Options Database:
63: . -da_vec_type ctype
65: Level: intermediate
67: .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType, VecType
68: @*/
69: PetscErrorCode DMSetVecType(DM da,const VecType ctype)
70: {
75: PetscFree(da->vectype);
76: PetscStrallocpy(ctype,&da->vectype);
77: return(0);
78: }
82: /*@C
83: DMSetOptionsPrefix - Sets the prefix used for searching for all
84: DMDA options in the database.
86: Logically Collective on DMDA
88: Input Parameter:
89: + da - the DMDA context
90: - prefix - the prefix to prepend to all option names
92: Notes:
93: A hyphen (-) must NOT be given at the beginning of the prefix name.
94: The first character of all runtime options is AUTOMATICALLY the hyphen.
96: Level: advanced
98: .keywords: DMDA, set, options, prefix, database
100: .seealso: DMSetFromOptions()
101: @*/
102: PetscErrorCode DMSetOptionsPrefix(DM dm,const char prefix[])
103: {
108: PetscObjectSetOptionsPrefix((PetscObject)dm,prefix);
109: return(0);
110: }
114: /*@
115: DMDestroy - Destroys a vector packer or DMDA.
117: Collective on DM
119: Input Parameter:
120: . dm - the DM object to destroy
122: Level: developer
124: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
126: @*/
127: PetscErrorCode DMDestroy(DM *dm)
128: {
129: PetscInt i, cnt = 0;
133: if (!*dm) return(0);
136: /* count all the circular references of DM and its contained Vecs */
137: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
138: if ((*dm)->localin[i]) {cnt++;}
139: if ((*dm)->globalin[i]) {cnt++;}
140: }
141: if ((*dm)->x) {
142: PetscObject obj;
143: PetscObjectQuery((PetscObject)(*dm)->x,"DM",&obj);
144: if (obj == (PetscObject)*dm) cnt++;
145: }
147: if (--((PetscObject)(*dm))->refct - cnt > 0) {*dm = 0; return(0);}
148: /*
149: Need this test because the dm references the vectors that
150: reference the dm, so destroying the dm calls destroy on the
151: vectors that cause another destroy on the dm
152: */
153: if (((PetscObject)(*dm))->refct < 0) return(0);
154: ((PetscObject) (*dm))->refct = 0;
155: for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
156: if ((*dm)->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Destroying a DM that has a local vector obtained with DMGetLocalVector()");
157: VecDestroy(&(*dm)->localin[i]);
158: }
159: VecDestroy(&(*dm)->x);
160: MatFDColoringDestroy(&(*dm)->fd);
161: DMClearGlobalVectors(*dm);
162: ISLocalToGlobalMappingDestroy(&(*dm)->ltogmap);
163: ISLocalToGlobalMappingDestroy(&(*dm)->ltogmapb);
164: PetscFree((*dm)->vectype);
165: PetscFree((*dm)->mattype);
166: /* if memory was published with AMS then destroy it */
167: PetscObjectDepublish(*dm);
169: (*(*dm)->ops->destroy)(*dm);
170: PetscFree((*dm)->data);
171: PetscHeaderDestroy(dm);
172: return(0);
173: }
177: /*@
178: DMSetUp - sets up the data structures inside a DM object
180: Collective on DM
182: Input Parameter:
183: . dm - the DM object to setup
185: Level: developer
187: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
189: @*/
190: PetscErrorCode DMSetUp(DM dm)
191: {
195: if (dm->setupcalled) return(0);
196: if (dm->ops->setup) {
197: (*dm->ops->setup)(dm);
198: }
199: dm->setupcalled = PETSC_TRUE;
200: return(0);
201: }
205: /*@
206: DMSetFromOptions - sets parameters in a DM from the options database
208: Collective on DM
210: Input Parameter:
211: . dm - the DM object to set options for
213: Options Database:
214: . -dm_preallocate_only: Only preallocate the matrix for DMGetMatrix(), but do not fill it with zeros
216: Level: developer
218: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
220: @*/
221: PetscErrorCode DMSetFromOptions(DM dm)
222: {
223: PetscBool flg1 = PETSC_FALSE,flg;
225: char mtype[256] = MATAIJ;
228: if (dm->ops->setfromoptions) {
229: (*dm->ops->setfromoptions)(dm);
230: }
231: PetscObjectOptionsBegin((PetscObject)dm);
232: PetscOptionsBool("-dm_view", "Information on DM", "DMView", flg1, &flg1, PETSC_NULL);
233: PetscOptionsBool("-dm_preallocate_only","only preallocate matrix, but do not set column indices","DMSetMatrixPreallocateOnly",dm->prealloc_only,&dm->prealloc_only,PETSC_NULL);
234: PetscOptionsList("-dm_mat_type","Matrix type","MatSetType",MatList,mtype,mtype,sizeof mtype,&flg);
235: if (flg) {
236: PetscFree(dm->mattype);
237: PetscStrallocpy(mtype,&dm->mattype);
238: }
239: PetscOptionsEnd();
240: if (flg1) {
241: DMView(dm, PETSC_VIEWER_STDOUT_WORLD);
242: }
243: return(0);
244: }
248: /*@C
249: DMView - Views a vector packer or DMDA.
251: Collective on DM
253: Input Parameter:
254: + dm - the DM object to view
255: - v - the viewer
257: Level: developer
259: .seealso DMDestroy(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
261: @*/
262: PetscErrorCode DMView(DM dm,PetscViewer v)
263: {
267: if (!v) {
268: PetscViewerASCIIGetStdout(((PetscObject)dm)->comm,&v);
269: }
270: if (dm->ops->view) {
271: (*dm->ops->view)(dm,v);
272: }
273: return(0);
274: }
278: /*@
279: DMCreateGlobalVector - Creates a global vector from a DMDA or DMComposite object
281: Collective on DM
283: Input Parameter:
284: . dm - the DM object
286: Output Parameter:
287: . vec - the global vector
289: Level: beginner
291: .seealso DMDestroy(), DMView(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
293: @*/
294: PetscErrorCode DMCreateGlobalVector(DM dm,Vec *vec)
295: {
299: (*dm->ops->createglobalvector)(dm,vec);
300: return(0);
301: }
305: /*@
306: DMCreateLocalVector - Creates a local vector from a DMDA or DMComposite object
308: Not Collective
310: Input Parameter:
311: . dm - the DM object
313: Output Parameter:
314: . vec - the local vector
316: Level: beginner
318: .seealso DMDestroy(), DMView(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix()
320: @*/
321: PetscErrorCode DMCreateLocalVector(DM dm,Vec *vec)
322: {
326: (*dm->ops->createlocalvector)(dm,vec);
327: return(0);
328: }
332: /*@
333: DMGetLocalToGlobalMapping - Accesses the local-to-global mapping in a DM.
335: Collective on DM
337: Input Parameter:
338: . dm - the DM that provides the mapping
340: Output Parameter:
341: . ltog - the mapping
343: Level: intermediate
345: Notes:
346: This mapping can then be used by VecSetLocalToGlobalMapping() or
347: MatSetLocalToGlobalMapping().
349: .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMappingBlock()
350: @*/
351: PetscErrorCode DMGetLocalToGlobalMapping(DM dm,ISLocalToGlobalMapping *ltog)
352: {
358: if (!dm->ltogmap) {
359: if (!dm->ops->createlocaltoglobalmapping) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMapping");
360: (*dm->ops->createlocaltoglobalmapping)(dm);
361: }
362: *ltog = dm->ltogmap;
363: return(0);
364: }
368: /*@
369: DMGetLocalToGlobalMappingBlock - Accesses the blocked local-to-global mapping in a DM.
371: Collective on DM
373: Input Parameter:
374: . da - the distributed array that provides the mapping
376: Output Parameter:
377: . ltog - the block mapping
379: Level: intermediate
381: Notes:
382: This mapping can then be used by VecSetLocalToGlobalMappingBlock() or
383: MatSetLocalToGlobalMappingBlock().
385: .seealso: DMCreateLocalVector(), DMGetLocalToGlobalMapping(), DMGetBlockSize(), VecSetBlockSize(), MatSetBlockSize()
386: @*/
387: PetscErrorCode DMGetLocalToGlobalMappingBlock(DM dm,ISLocalToGlobalMapping *ltog)
388: {
394: if (!dm->ltogmapb) {
395: PetscInt bs;
396: DMGetBlockSize(dm,&bs);
397: if (bs > 1) {
398: if (!dm->ops->createlocaltoglobalmappingblock) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"DM can not create LocalToGlobalMappingBlock");
399: (*dm->ops->createlocaltoglobalmappingblock)(dm);
400: } else {
401: DMGetLocalToGlobalMapping(dm,&dm->ltogmapb);
402: PetscObjectReference((PetscObject)dm->ltogmapb);
403: }
404: }
405: *ltog = dm->ltogmapb;
406: return(0);
407: }
411: /*@
412: DMGetBlockSize - Gets the inherent block size associated with a DM
414: Not Collective
416: Input Parameter:
417: . dm - the DM with block structure
419: Output Parameter:
420: . bs - the block size, 1 implies no exploitable block structure
422: Level: intermediate
424: .seealso: ISCreateBlock(), VecSetBlockSize(), MatSetBlockSize(), DMGetLocalToGlobalMappingBlock()
425: @*/
426: PetscErrorCode DMGetBlockSize(DM dm,PetscInt *bs)
427: {
431: if (dm->bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"DM does not have enough information to provide a block size yet");
432: *bs = dm->bs;
433: return(0);
434: }
438: /*@
439: DMGetInterpolation - Gets interpolation matrix between two DMDA or DMComposite objects
441: Collective on DM
443: Input Parameter:
444: + dm1 - the DM object
445: - dm2 - the second, finer DM object
447: Output Parameter:
448: + mat - the interpolation
449: - vec - the scaling (optional)
451: Level: developer
453: Notes: For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
454: DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the interpolation.
456: For DMDA objects you can use this interpolation (more precisely the interpolation from the DMDAGetCoordinateDA()) to interpolate the mesh coordinate vectors
457: EXCEPT in the periodic case where it does not make sense since the coordinate vectors are not periodic.
458:
460: .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetColoring(), DMGetMatrix(), DMRefine(), DMCoarsen()
462: @*/
463: PetscErrorCode DMGetInterpolation(DM dm1,DM dm2,Mat *mat,Vec *vec)
464: {
468: (*dm1->ops->getinterpolation)(dm1,dm2,mat,vec);
469: return(0);
470: }
474: /*@
475: DMGetInjection - Gets injection matrix between two DMDA or DMComposite objects
477: Collective on DM
479: Input Parameter:
480: + dm1 - the DM object
481: - dm2 - the second, finer DM object
483: Output Parameter:
484: . ctx - the injection
486: Level: developer
488: Notes: For DMDA objects this only works for "uniform refinement", that is the refined mesh was obtained DMRefine() or the coarse mesh was obtained by
489: DMCoarsen(). The coordinates set into the DMDA are completely ignored in computing the injection.
491: .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetColoring(), DMGetMatrix(), DMGetInterpolation()
493: @*/
494: PetscErrorCode DMGetInjection(DM dm1,DM dm2,VecScatter *ctx)
495: {
499: (*dm1->ops->getinjection)(dm1,dm2,ctx);
500: return(0);
501: }
505: /*@C
506: DMGetColoring - Gets coloring for a DMDA or DMComposite
508: Collective on DM
510: Input Parameter:
511: + dm - the DM object
512: . ctype - IS_COLORING_GHOSTED or IS_COLORING_GLOBAL
513: - matype - either MATAIJ or MATBAIJ
515: Output Parameter:
516: . coloring - the coloring
518: Level: developer
520: .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetMatrix()
522: @*/
523: PetscErrorCode DMGetColoring(DM dm,ISColoringType ctype,const MatType mtype,ISColoring *coloring)
524: {
528: if (!dm->ops->getcoloring) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No coloring for this type of DM yet");
529: (*dm->ops->getcoloring)(dm,ctype,mtype,coloring);
530: return(0);
531: }
535: /*@C
536: DMGetMatrix - Gets empty Jacobian for a DMDA or DMComposite
538: Collective on DM
540: Input Parameter:
541: + dm - the DM object
542: - mtype - Supported types are MATSEQAIJ, MATMPIAIJ, MATSEQBAIJ, MATMPIBAIJ, or
543: any type which inherits from one of these (such as MATAIJ)
545: Output Parameter:
546: . mat - the empty Jacobian
548: Level: beginner
550: Notes: This properly preallocates the number of nonzeros in the sparse matrix so you
551: do not need to do it yourself.
553: By default it also sets the nonzero structure and puts in the zero entries. To prevent setting
554: the nonzero pattern call DMDASetMatPreallocateOnly()
556: For structured grid problems, when you call MatView() on this matrix it is displayed using the global natural ordering, NOT in the ordering used
557: internally by PETSc.
559: For structured grid problems, in general it is easiest to use MatSetValuesStencil() or MatSetValuesLocal() to put values into the matrix because MatSetValues() requires
560: the indices for the global numbering for DMDAs which is complicated.
562: .seealso DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
564: @*/
565: PetscErrorCode DMGetMatrix(DM dm,const MatType mtype,Mat *mat)
566: {
570: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
571: MatInitializePackage(PETSC_NULL);
572: #endif
575: if (dm->mattype) {
576: (*dm->ops->getmatrix)(dm,dm->mattype,mat);
577: } else {
578: (*dm->ops->getmatrix)(dm,mtype,mat);
579: }
580: return(0);
581: }
585: /*@
586: DMSetMatrixPreallocateOnly - When DMGetMatrix() is called the matrix will be properly
587: preallocated but the nonzero structure and zero values will not be set.
589: Logically Collective on DMDA
591: Input Parameter:
592: + dm - the DM
593: - only - PETSC_TRUE if only want preallocation
595: Level: developer
596: .seealso DMGetMatrix()
597: @*/
598: PetscErrorCode DMSetMatrixPreallocateOnly(DM dm, PetscBool only)
599: {
602: dm->prealloc_only = only;
603: return(0);
604: }
608: /*@
609: DMRefine - Refines a DM object
611: Collective on DM
613: Input Parameter:
614: + dm - the DM object
615: - comm - the communicator to contain the new DM object (or PETSC_NULL)
617: Output Parameter:
618: . dmf - the refined DM
620: Level: developer
622: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
624: @*/
625: PetscErrorCode DMRefine(DM dm,MPI_Comm comm,DM *dmf)
626: {
631: (*dm->ops->refine)(dm,comm,dmf);
632: (*dmf)->ops->initialguess = dm->ops->initialguess;
633: (*dmf)->ops->function = dm->ops->function;
634: (*dmf)->ops->functionj = dm->ops->functionj;
635: if (dm->ops->jacobian != DMComputeJacobianDefault) {
636: (*dmf)->ops->jacobian = dm->ops->jacobian;
637: }
638: PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmf);
639: (*dmf)->ctx = dm->ctx;
640: (*dmf)->levelup = dm->levelup + 1;
641: return(0);
642: }
646: /*@
647: DMGetRefineLevel - Get's the number of refinements that have generated this DM.
649: Not Collective
651: Input Parameter:
652: . dm - the DM object
654: Output Parameter:
655: . level - number of refinements
657: Level: developer
659: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
661: @*/
662: PetscErrorCode DMGetRefineLevel(DM dm,PetscInt *level)
663: {
666: *level = dm->levelup;
667: return(0);
668: }
672: /*@
673: DMGlobalToLocalBegin - Begins updating local vectors from global vector
675: Neighbor-wise Collective on DM
677: Input Parameters:
678: + dm - the DM object
679: . g - the global vector
680: . mode - INSERT_VALUES or ADD_VALUES
681: - l - the local vector
684: Level: beginner
686: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
688: @*/
689: PetscErrorCode DMGlobalToLocalBegin(DM dm,Vec g,InsertMode mode,Vec l)
690: {
694: (*dm->ops->globaltolocalbegin)(dm,g,mode,l);
695: return(0);
696: }
700: /*@
701: DMGlobalToLocalEnd - Ends updating local vectors from global vector
703: Neighbor-wise Collective on DM
705: Input Parameters:
706: + dm - the DM object
707: . g - the global vector
708: . mode - INSERT_VALUES or ADD_VALUES
709: - l - the local vector
712: Level: beginner
714: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMLocalToGlobalBegin()
716: @*/
717: PetscErrorCode DMGlobalToLocalEnd(DM dm,Vec g,InsertMode mode,Vec l)
718: {
722: (*dm->ops->globaltolocalend)(dm,g,mode,l);
723: return(0);
724: }
728: /*@
729: DMLocalToGlobalBegin - updates global vectors from local vectors
731: Neighbor-wise Collective on DM
733: Input Parameters:
734: + dm - the DM object
735: . l - the local vector
736: . mode - if INSERT_VALUES then no parallel communication is used, if ADD_VALUES then all ghost points from the same base point accumulate into that
737: base point.
738: - - the global vector
740: Notes: In the ADD_VALUES case you normally would zero the receiving vector before beginning this operation. If you would like to simply add the non-ghosted values in the local
741: array into the global array you need to either (1) zero the ghosted locations and use ADD_VALUES or (2) use INSERT_VALUES into a work global array and then add the work
742: global array to the final global array with VecAXPY().
744: Level: beginner
746: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalBegin()
748: @*/
749: PetscErrorCode DMLocalToGlobalBegin(DM dm,Vec l,InsertMode mode,Vec g)
750: {
754: (*dm->ops->localtoglobalbegin)(dm,l,mode,g);
755: return(0);
756: }
760: /*@
761: DMLocalToGlobalEnd - updates global vectors from local vectors
763: Neighbor-wise Collective on DM
765: Input Parameters:
766: + dm - the DM object
767: . l - the local vector
768: . mode - INSERT_VALUES or ADD_VALUES
769: - g - the global vector
772: Level: beginner
774: .seealso DMCoarsen(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGlobalToLocalEnd(), DMGlobalToLocalEnd()
776: @*/
777: PetscErrorCode DMLocalToGlobalEnd(DM dm,Vec l,InsertMode mode,Vec g)
778: {
782: (*dm->ops->localtoglobalend)(dm,l,mode,g);
783: return(0);
784: }
788: /*@
789: DMComputeJacobianDefault - computes the Jacobian using the DMComputeFunction() if Jacobian computer is not provided
791: Collective on DM
793: Input Parameter:
794: + dm - the DM object
795: . x - location to compute Jacobian at; may be ignored for linear problems
796: . A - matrix that defines the operator for the linear solve
797: - B - the matrix used to construct the preconditioner
799: Level: developer
801: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
802: DMSetFunction()
804: @*/
805: PetscErrorCode DMComputeJacobianDefault(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
806: {
809: *stflag = SAME_NONZERO_PATTERN;
810: MatFDColoringApply(B,dm->fd,x,stflag,dm);
811: if (A != B) {
812: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
813: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
814: }
815: return(0);
816: }
820: /*@
821: DMCoarsen - Coarsens a DM object
823: Collective on DM
825: Input Parameter:
826: + dm - the DM object
827: - comm - the communicator to contain the new DM object (or PETSC_NULL)
829: Output Parameter:
830: . dmc - the coarsened DM
832: Level: developer
834: .seealso DMRefine(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
836: @*/
837: PetscErrorCode DMCoarsen(DM dm, MPI_Comm comm, DM *dmc)
838: {
842: (*dm->ops->coarsen)(dm, comm, dmc);
843: (*dmc)->ops->initialguess = dm->ops->initialguess;
844: (*dmc)->ops->function = dm->ops->function;
845: (*dmc)->ops->functionj = dm->ops->functionj;
846: if (dm->ops->jacobian != DMComputeJacobianDefault) {
847: (*dmc)->ops->jacobian = dm->ops->jacobian;
848: }
849: PetscObjectCopyFortranFunctionPointers((PetscObject)dm,(PetscObject)*dmc);
850: (*dmc)->ctx = dm->ctx;
851: (*dmc)->leveldown = dm->leveldown + 1;
852: return(0);
853: }
857: /*@C
858: DMRefineHierarchy - Refines a DM object, all levels at once
860: Collective on DM
862: Input Parameter:
863: + dm - the DM object
864: - nlevels - the number of levels of refinement
866: Output Parameter:
867: . dmf - the refined DM hierarchy
869: Level: developer
871: .seealso DMCoarsenHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
873: @*/
874: PetscErrorCode DMRefineHierarchy(DM dm,PetscInt nlevels,DM dmf[])
875: {
879: if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
880: if (nlevels == 0) return(0);
881: if (dm->ops->refinehierarchy) {
882: (*dm->ops->refinehierarchy)(dm,nlevels,dmf);
883: } else if (dm->ops->refine) {
884: PetscInt i;
886: DMRefine(dm,((PetscObject)dm)->comm,&dmf[0]);
887: for (i=1; i<nlevels; i++) {
888: DMRefine(dmf[i-1],((PetscObject)dm)->comm,&dmf[i]);
889: }
890: } else {
891: SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No RefineHierarchy for this DM yet");
892: }
893: return(0);
894: }
898: /*@C
899: DMCoarsenHierarchy - Coarsens a DM object, all levels at once
901: Collective on DM
903: Input Parameter:
904: + dm - the DM object
905: - nlevels - the number of levels of coarsening
907: Output Parameter:
908: . dmc - the coarsened DM hierarchy
910: Level: developer
912: .seealso DMRefineHierarchy(), DMDestroy(), DMView(), DMCreateGlobalVector(), DMGetInterpolation()
914: @*/
915: PetscErrorCode DMCoarsenHierarchy(DM dm, PetscInt nlevels, DM dmc[])
916: {
920: if (nlevels < 0) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative");
921: if (nlevels == 0) return(0);
923: if (dm->ops->coarsenhierarchy) {
924: (*dm->ops->coarsenhierarchy)(dm, nlevels, dmc);
925: } else if (dm->ops->coarsen) {
926: PetscInt i;
928: DMCoarsen(dm,((PetscObject)dm)->comm,&dmc[0]);
929: for (i=1; i<nlevels; i++) {
930: DMCoarsen(dmc[i-1],((PetscObject)dm)->comm,&dmc[i]);
931: }
932: } else {
933: SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"No CoarsenHierarchy for this DM yet");
934: }
935: return(0);
936: }
940: /*@
941: DMGetAggregates - Gets the aggregates that map between
942: grids associated with two DMs.
944: Collective on DM
946: Input Parameters:
947: + dmc - the coarse grid DM
948: - dmf - the fine grid DM
950: Output Parameters:
951: . rest - the restriction matrix (transpose of the projection matrix)
953: Level: intermediate
955: .keywords: interpolation, restriction, multigrid
957: .seealso: DMRefine(), DMGetInjection(), DMGetInterpolation()
958: @*/
959: PetscErrorCode DMGetAggregates(DM dmc, DM dmf, Mat *rest)
960: {
964: (*dmc->ops->getaggregates)(dmc, dmf, rest);
965: return(0);
966: }
970: /*@
971: DMSetApplicationContext - Set a user context into a DM object
973: Not Collective
975: Input Parameters:
976: + dm - the DM object
977: - ctx - the user context
979: Level: intermediate
981: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext()
983: @*/
984: PetscErrorCode DMSetApplicationContext(DM dm,void *ctx)
985: {
987: dm->ctx = ctx;
988: return(0);
989: }
993: /*@
994: DMGetApplicationContext - Gets a user context from a DM object
996: Not Collective
998: Input Parameter:
999: . dm - the DM object
1001: Output Parameter:
1002: . ctx - the user context
1004: Level: intermediate
1006: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext()
1008: @*/
1009: PetscErrorCode DMGetApplicationContext(DM dm,void *ctx)
1010: {
1012: *(void**)ctx = dm->ctx;
1013: return(0);
1014: }
1018: /*@C
1019: DMSetInitialGuess - sets a function to compute an initial guess vector entries for the solvers
1021: Logically Collective on DM
1023: Input Parameter:
1024: + dm - the DM object to destroy
1025: - f - the function to compute the initial guess
1027: Level: intermediate
1029: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1031: @*/
1032: PetscErrorCode DMSetInitialGuess(DM dm,PetscErrorCode (*f)(DM,Vec))
1033: {
1035: dm->ops->initialguess = f;
1036: return(0);
1037: }
1041: /*@C
1042: DMSetFunction - sets a function to compute the right hand side vector entries for the KSP solver or nonlinear function for SNES
1044: Logically Collective on DM
1046: Input Parameter:
1047: + dm - the DM object
1048: - f - the function to compute (use PETSC_NULL to cancel a previous function that was set)
1050: Level: intermediate
1052: Notes: This sets both the function for function evaluations and the function used to compute Jacobians via finite differences if no Jacobian
1053: computer is provided with DMSetJacobian(). Canceling cancels the function, but not the function used to compute the Jacobian.
1055: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1056: DMSetJacobian()
1058: @*/
1059: PetscErrorCode DMSetFunction(DM dm,PetscErrorCode (*f)(DM,Vec,Vec))
1060: {
1062: dm->ops->function = f;
1063: if (f) {
1064: dm->ops->functionj = f;
1065: }
1066: return(0);
1067: }
1071: /*@C
1072: DMSetJacobian - sets a function to compute the matrix entries for the KSP solver or Jacobian for SNES
1074: Logically Collective on DM
1076: Input Parameter:
1077: + dm - the DM object to destroy
1078: - f - the function to compute the matrix entries
1080: Level: intermediate
1082: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1083: DMSetFunction()
1085: @*/
1086: PetscErrorCode DMSetJacobian(DM dm,PetscErrorCode (*f)(DM,Vec,Mat,Mat,MatStructure*))
1087: {
1089: dm->ops->jacobian = f;
1090: return(0);
1091: }
1095: /*@
1096: DMComputeInitialGuess - computes an initial guess vector entries for the KSP solvers
1098: Collective on DM
1100: Input Parameter:
1101: + dm - the DM object to destroy
1102: - x - the vector to hold the initial guess values
1104: Level: developer
1106: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetRhs(), DMSetMat()
1108: @*/
1109: PetscErrorCode DMComputeInitialGuess(DM dm,Vec x)
1110: {
1113: if (!dm->ops->initialguess) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetInitialGuess()");
1114: (*dm->ops->initialguess)(dm,x);
1115: return(0);
1116: }
1120: /*@
1121: DMHasInitialGuess - does the DM object have an initial guess function
1123: Not Collective
1125: Input Parameter:
1126: . dm - the DM object to destroy
1128: Output Parameter:
1129: . flg - PETSC_TRUE if function exists
1131: Level: developer
1133: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1135: @*/
1136: PetscErrorCode DMHasInitialGuess(DM dm,PetscBool *flg)
1137: {
1139: *flg = (dm->ops->initialguess) ? PETSC_TRUE : PETSC_FALSE;
1140: return(0);
1141: }
1145: /*@
1146: DMHasFunction - does the DM object have a function
1148: Not Collective
1150: Input Parameter:
1151: . dm - the DM object to destroy
1153: Output Parameter:
1154: . flg - PETSC_TRUE if function exists
1156: Level: developer
1158: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1160: @*/
1161: PetscErrorCode DMHasFunction(DM dm,PetscBool *flg)
1162: {
1164: *flg = (dm->ops->function) ? PETSC_TRUE : PETSC_FALSE;
1165: return(0);
1166: }
1170: /*@
1171: DMHasJacobian - does the DM object have a matrix function
1173: Not Collective
1175: Input Parameter:
1176: . dm - the DM object to destroy
1178: Output Parameter:
1179: . flg - PETSC_TRUE if function exists
1181: Level: developer
1183: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetFunction(), DMSetJacobian()
1185: @*/
1186: PetscErrorCode DMHasJacobian(DM dm,PetscBool *flg)
1187: {
1189: *flg = (dm->ops->jacobian) ? PETSC_TRUE : PETSC_FALSE;
1190: return(0);
1191: }
1195: /*@
1196: DMComputeFunction - computes the right hand side vector entries for the KSP solver or nonlinear function for SNES
1198: Collective on DM
1200: Input Parameter:
1201: + dm - the DM object to destroy
1202: . x - the location where the function is evaluationed, may be ignored for linear problems
1203: - b - the vector to hold the right hand side entries
1205: Level: developer
1207: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1208: DMSetJacobian()
1210: @*/
1211: PetscErrorCode DMComputeFunction(DM dm,Vec x,Vec b)
1212: {
1215: if (!dm->ops->function) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to provide function with DMSetFunction()");
1216: PetscStackPush("DM user function");
1217: (*dm->ops->function)(dm,x,b);
1218: PetscStackPop;
1219: return(0);
1220: }
1225: /*@
1226: DMComputeJacobian - compute the matrix entries for the solver
1228: Collective on DM
1230: Input Parameter:
1231: + dm - the DM object
1232: . x - location to compute Jacobian at; will be PETSC_NULL for linear problems, for nonlinear problems if not provided then pulled from DM
1233: . A - matrix that defines the operator for the linear solve
1234: - B - the matrix used to construct the preconditioner
1236: Level: developer
1238: .seealso DMView(), DMCreateGlobalVector(), DMGetInterpolation(), DMGetColoring(), DMGetMatrix(), DMGetApplicationContext(), DMSetInitialGuess(),
1239: DMSetFunction()
1241: @*/
1242: PetscErrorCode DMComputeJacobian(DM dm,Vec x,Mat A,Mat B,MatStructure *stflag)
1243: {
1247: if (!dm->ops->jacobian) {
1248: ISColoring coloring;
1249: MatFDColoring fd;
1251: DMGetColoring(dm,IS_COLORING_GLOBAL,MATAIJ,&coloring);
1252: MatFDColoringCreate(B,coloring,&fd);
1253: ISColoringDestroy(&coloring);
1254: MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))dm->ops->functionj,dm);
1255: PetscObjectSetOptionsPrefix((PetscObject)fd,((PetscObject)dm)->prefix);
1256: MatFDColoringSetFromOptions(fd);
1258: dm->fd = fd;
1259: dm->ops->jacobian = DMComputeJacobianDefault;
1261: /* don't know why this is needed */
1262: PetscObjectDereference((PetscObject)dm);
1263: }
1264: if (!x) x = dm->x;
1265: (*dm->ops->jacobian)(dm,x,A,B,stflag);
1267: /* if matrix depends on x; i.e. nonlinear problem, keep copy of input vector since needed by multigrid methods to generate coarse grid matrices */
1268: if (x) {
1269: if (!dm->x) {
1270: DMCreateGlobalVector(dm,&dm->x);
1271: }
1272: VecCopy(x,dm->x);
1273: }
1274: if (A != B) {
1275: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
1276: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
1277: }
1278: return(0);
1279: }
1282: PetscFList DMList = PETSC_NULL;
1283: PetscBool DMRegisterAllCalled = PETSC_FALSE;
1287: /*@C
1288: DMSetType - Builds a DM, for a particular DM implementation.
1290: Collective on DM
1292: Input Parameters:
1293: + dm - The DM object
1294: - method - The name of the DM type
1296: Options Database Key:
1297: . -dm_type <type> - Sets the DM type; use -help for a list of available types
1299: Notes:
1300: See "petsc/include/petscdm.h" for available DM types (for instance, DM1D, DM2D, or DM3D).
1302: Level: intermediate
1304: .keywords: DM, set, type
1305: .seealso: DMGetType(), DMCreate()
1306: @*/
1307: PetscErrorCode DMSetType(DM dm, const DMType method)
1308: {
1309: PetscErrorCode (*r)(DM);
1310: PetscBool match;
1315: PetscTypeCompare((PetscObject) dm, method, &match);
1316: if (match) return(0);
1318: if (!DMRegisterAllCalled) {DMRegisterAll(PETSC_NULL);}
1319: PetscFListFind(DMList, ((PetscObject)dm)->comm, method,PETSC_TRUE,(void (**)(void)) &r);
1320: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown DM type: %s", method);
1322: if (dm->ops->destroy) {
1323: (*dm->ops->destroy)(dm);
1324: }
1325: (*r)(dm);
1326: PetscObjectChangeTypeName((PetscObject)dm,method);
1327: return(0);
1328: }
1332: /*@C
1333: DMGetType - Gets the DM type name (as a string) from the DM.
1335: Not Collective
1337: Input Parameter:
1338: . dm - The DM
1340: Output Parameter:
1341: . type - The DM type name
1343: Level: intermediate
1345: .keywords: DM, get, type, name
1346: .seealso: DMSetType(), DMCreate()
1347: @*/
1348: PetscErrorCode DMGetType(DM dm, const DMType *type)
1349: {
1355: if (!DMRegisterAllCalled) {
1356: DMRegisterAll(PETSC_NULL);
1357: }
1358: *type = ((PetscObject)dm)->type_name;
1359: return(0);
1360: }
1364: /*@C
1365: DMConvert - Converts a DM to another DM, either of the same or different type.
1367: Collective on DM
1369: Input Parameters:
1370: + dm - the DM
1371: - newtype - new DM type (use "same" for the same type)
1373: Output Parameter:
1374: . M - pointer to new DM
1376: Notes:
1377: Cannot be used to convert a sequential DM to parallel or parallel to sequential,
1378: the MPI communicator of the generated DM is always the same as the communicator
1379: of the input DM.
1381: Level: intermediate
1383: .seealso: DMCreate()
1384: @*/
1385: PetscErrorCode DMConvert(DM dm, const DMType newtype, DM *M)
1386: {
1387: DM B;
1388: char convname[256];
1389: PetscBool sametype, issame;
1396: PetscTypeCompare((PetscObject) dm, newtype, &sametype);
1397: PetscStrcmp(newtype, "same", &issame);
1398: {
1399: PetscErrorCode (*conv)(DM, const DMType, DM *) = PETSC_NULL;
1401: /*
1402: Order of precedence:
1403: 1) See if a specialized converter is known to the current DM.
1404: 2) See if a specialized converter is known to the desired DM class.
1405: 3) See if a good general converter is registered for the desired class
1406: 4) See if a good general converter is known for the current matrix.
1407: 5) Use a really basic converter.
1408: */
1410: /* 1) See if a specialized converter is known to the current DM and the desired class */
1411: PetscStrcpy(convname,"DMConvert_");
1412: PetscStrcat(convname,((PetscObject) dm)->type_name);
1413: PetscStrcat(convname,"_");
1414: PetscStrcat(convname,newtype);
1415: PetscStrcat(convname,"_C");
1416: PetscObjectQueryFunction((PetscObject)dm,convname,(void (**)(void))&conv);
1417: if (conv) goto foundconv;
1419: /* 2) See if a specialized converter is known to the desired DM class. */
1420: DMCreate(((PetscObject) dm)->comm, &B);
1421: DMSetType(B, newtype);
1422: PetscStrcpy(convname,"DMConvert_");
1423: PetscStrcat(convname,((PetscObject) dm)->type_name);
1424: PetscStrcat(convname,"_");
1425: PetscStrcat(convname,newtype);
1426: PetscStrcat(convname,"_C");
1427: PetscObjectQueryFunction((PetscObject)B,convname,(void (**)(void))&conv);
1428: if (conv) {
1429: DMDestroy(&B);
1430: goto foundconv;
1431: }
1433: #if 0
1434: /* 3) See if a good general converter is registered for the desired class */
1435: conv = B->ops->convertfrom;
1436: DMDestroy(&B);
1437: if (conv) goto foundconv;
1439: /* 4) See if a good general converter is known for the current matrix */
1440: if (dm->ops->convert) {
1441: conv = dm->ops->convert;
1442: }
1443: if (conv) goto foundconv;
1444: #endif
1446: /* 5) Use a really basic converter. */
1447: SETERRQ2(((PetscObject) dm)->comm, PETSC_ERR_SUP, "No conversion possible between DM types %s and %s", ((PetscObject) dm)->type_name, newtype);
1449: foundconv:
1450: PetscLogEventBegin(DM_Convert,dm,0,0,0);
1451: (*conv)(dm,newtype,M);
1452: PetscLogEventEnd(DM_Convert,dm,0,0,0);
1453: }
1454: PetscObjectStateIncrease((PetscObject) *M);
1455: return(0);
1456: }
1458: /*--------------------------------------------------------------------------------------------------------------------*/
1462: /*@C
1463: DMRegister - See DMRegisterDynamic()
1465: Level: advanced
1466: @*/
1467: PetscErrorCode DMRegister(const char sname[], const char path[], const char name[], PetscErrorCode (*function)(DM))
1468: {
1469: char fullname[PETSC_MAX_PATH_LEN];
1473: PetscStrcpy(fullname, path);
1474: PetscStrcat(fullname, ":");
1475: PetscStrcat(fullname, name);
1476: PetscFListAdd(&DMList, sname, fullname, (void (*)(void)) function);
1477: return(0);
1478: }
1481: /*--------------------------------------------------------------------------------------------------------------------*/
1484: /*@C
1485: DMRegisterDestroy - Frees the list of DM methods that were registered by DMRegister()/DMRegisterDynamic().
1487: Not Collective
1489: Level: advanced
1491: .keywords: DM, register, destroy
1492: .seealso: DMRegister(), DMRegisterAll(), DMRegisterDynamic()
1493: @*/
1494: PetscErrorCode DMRegisterDestroy(void)
1495: {
1499: PetscFListDestroy(&DMList);
1500: DMRegisterAllCalled = PETSC_FALSE;
1501: return(0);
1502: }
1504: #if defined(PETSC_HAVE_MATLAB_ENGINE)
1505: #include <mex.h>
1507: typedef struct {char *funcname; char *jacname; mxArray *ctx;} DMMatlabContext;
1511: /*
1512: DMComputeFunction_Matlab - Calls the function that has been set with
1513: DMSetFunctionMatlab().
1515: For linear problems x is null
1516:
1517: .seealso: DMSetFunction(), DMGetFunction()
1518: */
1519: PetscErrorCode DMComputeFunction_Matlab(DM dm,Vec x,Vec y)
1520: {
1521: PetscErrorCode ierr;
1522: DMMatlabContext *sctx;
1523: int nlhs = 1,nrhs = 4;
1524: mxArray *plhs[1],*prhs[4];
1525: long long int lx = 0,ly = 0,ls = 0;
1526:
1532: /* call Matlab function in ctx with arguments x and y */
1533: DMGetApplicationContext(dm,&sctx);
1534: PetscMemcpy(&ls,&dm,sizeof(dm));
1535: PetscMemcpy(&lx,&x,sizeof(x));
1536: PetscMemcpy(&ly,&y,sizeof(y));
1537: prhs[0] = mxCreateDoubleScalar((double)ls);
1538: prhs[1] = mxCreateDoubleScalar((double)lx);
1539: prhs[2] = mxCreateDoubleScalar((double)ly);
1540: prhs[3] = mxCreateString(sctx->funcname);
1541: mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeFunctionInternal");
1542: mxGetScalar(plhs[0]);
1543: mxDestroyArray(prhs[0]);
1544: mxDestroyArray(prhs[1]);
1545: mxDestroyArray(prhs[2]);
1546: mxDestroyArray(prhs[3]);
1547: mxDestroyArray(plhs[0]);
1548: return(0);
1549: }
1554: /*
1555: DMSetFunctionMatlab - Sets the function evaluation routine
1557: */
1558: PetscErrorCode DMSetFunctionMatlab(DM dm,const char *func)
1559: {
1560: PetscErrorCode ierr;
1561: DMMatlabContext *sctx;
1564: /* currently sctx is memory bleed */
1565: DMGetApplicationContext(dm,&sctx);
1566: if (!sctx) {
1567: PetscMalloc(sizeof(DMMatlabContext),&sctx);
1568: }
1569: PetscStrallocpy(func,&sctx->funcname);
1570: DMSetApplicationContext(dm,sctx);
1571: DMSetFunction(dm,DMComputeFunction_Matlab);
1572: return(0);
1573: }
1577: /*
1578: DMComputeJacobian_Matlab - Calls the function that has been set with
1579: DMSetJacobianMatlab().
1581: For linear problems x is null
1582:
1583: .seealso: DMSetFunction(), DMGetFunction()
1584: */
1585: PetscErrorCode DMComputeJacobian_Matlab(DM dm,Vec x,Mat A,Mat B,MatStructure *str)
1586: {
1587: PetscErrorCode ierr;
1588: DMMatlabContext *sctx;
1589: int nlhs = 2,nrhs = 5;
1590: mxArray *plhs[2],*prhs[5];
1591: long long int lx = 0,lA = 0,lB = 0,ls = 0;
1592:
1597: /* call MATLAB function in ctx with arguments x, A, and B */
1598: DMGetApplicationContext(dm,&sctx);
1599: PetscMemcpy(&ls,&dm,sizeof(dm));
1600: PetscMemcpy(&lx,&x,sizeof(x));
1601: PetscMemcpy(&lA,&A,sizeof(A));
1602: PetscMemcpy(&lB,&B,sizeof(B));
1603: prhs[0] = mxCreateDoubleScalar((double)ls);
1604: prhs[1] = mxCreateDoubleScalar((double)lx);
1605: prhs[2] = mxCreateDoubleScalar((double)lA);
1606: prhs[3] = mxCreateDoubleScalar((double)lB);
1607: prhs[4] = mxCreateString(sctx->jacname);
1608: mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscDMComputeJacobianInternal");
1609: *str = (MatStructure) mxGetScalar(plhs[0]);
1610: (PetscInt) mxGetScalar(plhs[1]);
1611: mxDestroyArray(prhs[0]);
1612: mxDestroyArray(prhs[1]);
1613: mxDestroyArray(prhs[2]);
1614: mxDestroyArray(prhs[3]);
1615: mxDestroyArray(prhs[4]);
1616: mxDestroyArray(plhs[0]);
1617: mxDestroyArray(plhs[1]);
1618: return(0);
1619: }
1624: /*
1625: DMSetJacobianMatlab - Sets the Jacobian function evaluation routine
1627: */
1628: PetscErrorCode DMSetJacobianMatlab(DM dm,const char *func)
1629: {
1630: PetscErrorCode ierr;
1631: DMMatlabContext *sctx;
1634: /* currently sctx is memory bleed */
1635: DMGetApplicationContext(dm,&sctx);
1636: if (!sctx) {
1637: PetscMalloc(sizeof(DMMatlabContext),&sctx);
1638: }
1639: PetscStrallocpy(func,&sctx->jacname);
1640: DMSetApplicationContext(dm,sctx);
1641: DMSetJacobian(dm,DMComputeJacobian_Matlab);
1642: return(0);
1643: }
1644: #endif
1648: /*@C
1649: DMLoad - Loads a DM that has been stored in binary or HDF5 format
1650: with DMView().
1652: Collective on PetscViewer
1654: Input Parameters:
1655: + newdm - the newly loaded DM, this needs to have been created with DMCreate() or
1656: some related function before a call to DMLoad().
1657: - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() or
1658: HDF5 file viewer, obtained from PetscViewerHDF5Open()
1660: Level: intermediate
1662: Notes:
1663: Defaults to the DM DA.
1665: Notes for advanced users:
1666: Most users should not need to know the details of the binary storage
1667: format, since DMLoad() and DMView() completely hide these details.
1668: But for anyone who's interested, the standard binary matrix storage
1669: format is
1670: .vb
1671: has not yet been determined
1672: .ve
1674: In addition, PETSc automatically does the byte swapping for
1675: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
1676: linux, Windows and the paragon; thus if you write your own binary
1677: read/write routines you have to swap the bytes; see PetscBinaryRead()
1678: and PetscBinaryWrite() to see how this may be done.
1680: Concepts: vector^loading from file
1682: .seealso: PetscViewerBinaryOpen(), DMView(), MatLoad(), VecLoad()
1683: @*/
1684: PetscErrorCode DMLoad(DM newdm, PetscViewer viewer)
1685: {
1692: if (!((PetscObject)newdm)->type_name) {
1693: DMSetType(newdm, DMDA);
1694: }
1695: (*newdm->ops->load)(newdm,viewer);
1696: return(0);
1697: }