Actual source code: dmksp.c
petsc-3.3-p7 2013-05-11
1: #include <petsc-private/kspimpl.h> /*I "petscksp.h" I*/
2: #include <petscdm.h> /*I "petscdm.h" I*/
6: static PetscErrorCode PetscContainerDestroy_KSPDM(void *ctx)
7: {
9: KSPDM kdm = (KSPDM)ctx;
12: if (kdm->destroy) {(*kdm->destroy)(kdm);}
13: PetscFree(kdm);
14: return(0);
15: }
19: /* Attaches the KSPDM to the coarse level.
20: * Under what conditions should we copy versus duplicate?
21: */
22: static PetscErrorCode DMCoarsenHook_KSPDM(DM dm,DM dmc,void *ctx)
23: {
27: DMKSPCopyContext(dm,dmc);
28: return(0);
29: }
33: /*@C
34: DMKSPGetContext - get read-only private KSPDM context from a DM
36: Not Collective
38: Input Argument:
39: . dm - DM to be used with KSP
41: Output Argument:
42: . snesdm - private KSPDM context
44: Level: developer
46: Notes:
47: Use DMKSPGetContextWrite() if write access is needed. The DMKSPSetXXX API should be used wherever possible.
49: .seealso: DMKSPGetContextWrite()
50: @*/
51: PetscErrorCode DMKSPGetContext(DM dm,KSPDM *snesdm)
52: {
54: PetscContainer container;
55: KSPDM kdm;
59: PetscObjectQuery((PetscObject)dm,"KSPDM",(PetscObject*)&container);
60: if (container) {
61: PetscContainerGetPointer(container,(void**)snesdm);
62: } else {
63: PetscInfo(dm,"Creating new KSPDM\n");
64: PetscContainerCreate(((PetscObject)dm)->comm,&container);
65: PetscNewLog(dm,struct _n_KSPDM,&kdm);
66: PetscContainerSetPointer(container,kdm);
67: PetscContainerSetUserDestroy(container,PetscContainerDestroy_KSPDM);
68: PetscObjectCompose((PetscObject)dm,"KSPDM",(PetscObject)container);
69: DMCoarsenHookAdd(dm,DMCoarsenHook_KSPDM,PETSC_NULL,PETSC_NULL);
70: PetscContainerGetPointer(container,(void**)snesdm);
71: PetscContainerDestroy(&container);
72: }
73: return(0);
74: }
78: /*@C
79: DMKSPGetContextWrite - get write access to private KSPDM context from a DM
81: Not Collective
83: Input Argument:
84: . dm - DM to be used with KSP
86: Output Argument:
87: . snesdm - private KSPDM context
89: Level: developer
91: .seealso: DMKSPGetContext()
92: @*/
93: PetscErrorCode DMKSPGetContextWrite(DM dm,KSPDM *snesdm)
94: {
96: KSPDM kdm;
100: DMKSPGetContext(dm,&kdm);
101: if (!kdm->originaldm) kdm->originaldm = dm;
102: if (kdm->originaldm != dm) { /* Copy on write */
103: PetscContainer container;
104: KSPDM oldsdm = kdm;
105: PetscInfo(dm,"Copying KSPDM due to write\n");
106: PetscContainerCreate(((PetscObject)dm)->comm,&container);
107: PetscNewLog(dm,struct _n_KSPDM,&kdm);
108: PetscMemcpy(kdm,oldsdm,sizeof *kdm);
109: PetscContainerSetPointer(container,kdm);
110: PetscContainerSetUserDestroy(container,PetscContainerDestroy_KSPDM);
111: PetscObjectCompose((PetscObject)dm,"KSPDM",(PetscObject)container);
112: PetscContainerDestroy(&container);
113: }
114: *snesdm = kdm;
115: return(0);
116: }
120: /*@C
121: DMKSPCopyContext - copies a DM context to a new DM
123: Logically Collective
125: Input Arguments:
126: + dmsrc - DM to obtain context from
127: - dmdest - DM to add context to
129: Level: developer
131: Note:
132: The context is copied by reference. This function does not ensure that a context exists.
134: .seealso: DMKSPGetContext(), KSPSetDM()
135: @*/
136: PetscErrorCode DMKSPCopyContext(DM dmsrc,DM dmdest)
137: {
139: PetscContainer container;
144: PetscObjectQuery((PetscObject)dmsrc,"KSPDM",(PetscObject*)&container);
145: if (container) {
146: PetscObjectCompose((PetscObject)dmdest,"KSPDM",(PetscObject)container);
147: DMCoarsenHookAdd(dmdest,DMCoarsenHook_KSPDM,PETSC_NULL,PETSC_NULL);
148: }
149: return(0);
150: }
154: /*@C
155: DMKSPSetComputeOperators - set KSP matrix evaluation function
157: Not Collective
159: Input Argument:
160: + dm - DM to be used with KSP
161: . func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
162: - ctx - context for matrix evaluation
164: Level: advanced
166: Note:
167: KSPSetComputeOperators() is normally used, but it calls this function internally because the user context is actually
168: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
169: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
171: .seealso: DMKSPSetContext(), DMKSPGetComputeOperators(), KSPSetOperators()
172: @*/
173: PetscErrorCode DMKSPSetComputeOperators(DM dm,PetscErrorCode (*func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
174: {
176: KSPDM kdm;
180: DMKSPGetContextWrite(dm,&kdm);
181: if (func) kdm->computeoperators = func;
182: if (ctx) kdm->operatorsctx = ctx;
183: return(0);
184: }
188: /*@C
189: DMKSPGetComputeOperators - get KSP matrix evaluation function
191: Not Collective
193: Input Argument:
194: . dm - DM to be used with KSP
196: Output Arguments:
197: + func - matrix evaluation function, see KSPSetComputeOperators() for calling sequence
198: - ctx - context for matrix evaluation
200: Level: advanced
202: .seealso: DMKSPSetContext(), KSPSetComputeOperators(), DMKSPSetComputeOperators()
203: @*/
204: PetscErrorCode DMKSPGetComputeOperators(DM dm,PetscErrorCode (**func)(KSP,Mat,Mat,MatStructure*,void*),void *ctx)
205: {
207: KSPDM kdm;
211: DMKSPGetContext(dm,&kdm);
212: if (func) *func = kdm->computeoperators;
213: if (ctx) *(void**)ctx = kdm->operatorsctx;
214: return(0);
215: }
219: /*@C
220: DMKSPSetComputeRHS - set KSP matrix evaluation function
222: Not Collective
224: Input Argument:
225: + dm - DM to be used with KSP
226: . func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
227: - ctx - context for right hand side evaluation
229: Level: advanced
231: Note:
232: KSPSetComputeRHS() is normally used, but it calls this function internally because the user context is actually
233: associated with the DM. This makes the interface consistent regardless of whether the user interacts with a DM or
234: not. If DM took a more central role at some later date, this could become the primary method of setting the matrix.
236: .seealso: DMKSPSetContext(), DMKSPGetComputeRHS(), KSPSetRHS()
237: @*/
238: PetscErrorCode DMKSPSetComputeRHS(DM dm,PetscErrorCode (*func)(KSP,Vec,void*),void *ctx)
239: {
241: KSPDM kdm;
245: DMKSPGetContextWrite(dm,&kdm);
246: if (func) kdm->computerhs = func;
247: if (ctx) kdm->rhsctx = ctx;
248: return(0);
249: }
253: /*@C
254: DMKSPGetComputeRHS - get KSP matrix evaluation function
256: Not Collective
258: Input Argument:
259: . dm - DM to be used with KSP
261: Output Arguments:
262: + func - right hand side evaluation function, see KSPSetComputeRHS() for calling sequence
263: - ctx - context for right hand side evaluation
265: Level: advanced
267: .seealso: DMKSPSetContext(), KSPSetComputeRHS(), DMKSPSetComputeRHS()
268: @*/
269: PetscErrorCode DMKSPGetComputeRHS(DM dm,PetscErrorCode (**func)(KSP,Vec,void*),void *ctx)
270: {
272: KSPDM kdm;
276: DMKSPGetContext(dm,&kdm);
277: if (func) *func = kdm->computerhs;
278: if (ctx) *(void**)ctx = kdm->rhsctx;
279: return(0);
280: }