Actual source code: ex10.c
petsc-3.13.6 2020-09-29
1: static char help[] = "Simple wrapper object to solve DAE of the form:\n\
2: \\dot{U} = f(U,V)\n\
3: F(U,V) = 0\n\n";
5: #include <petscts.h>
7: /* ----------------------------------------------------------------------------*/
9: typedef struct _p_TSDAESimple *TSDAESimple;
10: struct _p_TSDAESimple {
11: MPI_Comm comm;
12: PetscErrorCode (*setfromoptions)(PetscOptionItems*,TSDAESimple);
13: PetscErrorCode (*solve)(TSDAESimple,Vec);
14: PetscErrorCode (*destroy)(TSDAESimple);
15: Vec U,V;
16: PetscErrorCode (*f)(PetscReal,Vec,Vec,Vec,void*);
17: PetscErrorCode (*F)(PetscReal,Vec,Vec,Vec,void*);
18: void *fctx,*Fctx;
19: void *data;
20: };
22: PetscErrorCode TSDAESimpleCreate(MPI_Comm comm,TSDAESimple *tsdae)
23: {
27: PetscNew(tsdae);
28: (*tsdae)->comm = comm;
29: return(0);
30: }
32: PetscErrorCode TSDAESimpleSetRHSFunction(TSDAESimple tsdae,Vec U,PetscErrorCode (*f)(PetscReal,Vec,Vec,Vec,void*),void *ctx)
33: {
37: tsdae->f = f;
38: tsdae->U = U;
39: PetscObjectReference((PetscObject)U);
40: tsdae->fctx = ctx;
41: return(0);
42: }
44: PetscErrorCode TSDAESimpleSetIFunction(TSDAESimple tsdae,Vec V,PetscErrorCode (*F)(PetscReal,Vec,Vec,Vec,void*),void *ctx)
45: {
49: tsdae->F = F;
50: tsdae->V = V;
51: PetscObjectReference((PetscObject)V);
52: tsdae->Fctx = ctx;
53: return(0);
54: }
56: PetscErrorCode TSDAESimpleDestroy(TSDAESimple *tsdae)
57: {
61: (*(*tsdae)->destroy)(*tsdae);
62: VecDestroy(&(*tsdae)->U);
63: VecDestroy(&(*tsdae)->V);
64: PetscFree(*tsdae);
65: return(0);
66: }
68: PetscErrorCode TSDAESimpleSolve(TSDAESimple tsdae,Vec Usolution)
69: {
73: (*tsdae->solve)(tsdae,Usolution);
74: return(0);
75: }
77: PetscErrorCode TSDAESimpleSetFromOptions(TSDAESimple tsdae)
78: {
82: (*tsdae->setfromoptions)(PetscOptionsObject,tsdae);
83: return(0);
84: }
86: /* ----------------------------------------------------------------------------*/
87: /*
88: Integrates the system by integrating the reduced ODE system and solving the
89: algebraic constraints at each stage with a separate SNES solve.
90: */
92: typedef struct {
93: PetscReal t;
94: TS ts;
95: SNES snes;
96: Vec U;
97: } TSDAESimple_Reduced;
99: /*
100: Defines the RHS function that is passed to the time-integrator.
102: Solves F(U,V) for V and then computes f(U,V)
104: */
105: PetscErrorCode TSDAESimple_Reduced_TSFunction(TS ts,PetscReal t,Vec U,Vec F,void *actx)
106: {
107: TSDAESimple tsdae = (TSDAESimple)actx;
108: TSDAESimple_Reduced *red = (TSDAESimple_Reduced*)tsdae->data;
109: PetscErrorCode ierr;
112: red->t = t;
113: red->U = U;
114: SNESSolve(red->snes,NULL,tsdae->V);
115: (*tsdae->f)(t,U,tsdae->V,F,tsdae->fctx);
116: return(0);
117: }
119: /*
120: Defines the nonlinear function that is passed to the nonlinear solver
122: */
123: PetscErrorCode TSDAESimple_Reduced_SNESFunction(SNES snes,Vec V,Vec F,void *actx)
124: {
125: TSDAESimple tsdae = (TSDAESimple)actx;
126: TSDAESimple_Reduced *red = (TSDAESimple_Reduced*)tsdae->data;
127: PetscErrorCode ierr;
130: (*tsdae->F)(red->t,red->U,V,F,tsdae->Fctx);
131: return(0);
132: }
135: PetscErrorCode TSDAESimpleSolve_Reduced(TSDAESimple tsdae,Vec U)
136: {
137: PetscErrorCode ierr;
138: TSDAESimple_Reduced *red = (TSDAESimple_Reduced*)tsdae->data;
141: TSSolve(red->ts,U);
142: return(0);
143: }
145: PetscErrorCode TSDAESimpleSetFromOptions_Reduced(PetscOptionItems *PetscOptionsObject,TSDAESimple tsdae)
146: {
147: PetscErrorCode ierr;
148: TSDAESimple_Reduced *red = (TSDAESimple_Reduced*)tsdae->data;
151: TSSetFromOptions(red->ts);
152: SNESSetFromOptions(red->snes);
153: return(0);
154: }
156: PetscErrorCode TSDAESimpleDestroy_Reduced(TSDAESimple tsdae)
157: {
158: PetscErrorCode ierr;
159: TSDAESimple_Reduced *red = (TSDAESimple_Reduced*)tsdae->data;
162: TSDestroy(&red->ts);
163: SNESDestroy(&red->snes);
164: PetscFree(red);
165: return(0);
166: }
168: PetscErrorCode TSDAESimpleSetUp_Reduced(TSDAESimple tsdae)
169: {
170: PetscErrorCode ierr;
171: TSDAESimple_Reduced *red;
172: Vec tsrhs;
175: PetscNew(&red);
176: tsdae->data = red;
178: tsdae->setfromoptions = TSDAESimpleSetFromOptions_Reduced;
179: tsdae->solve = TSDAESimpleSolve_Reduced;
180: tsdae->destroy = TSDAESimpleDestroy_Reduced;
182: TSCreate(tsdae->comm,&red->ts);
183: TSSetProblemType(red->ts,TS_NONLINEAR);
184: TSSetType(red->ts,TSEULER);
185: TSSetExactFinalTime(red->ts,TS_EXACTFINALTIME_STEPOVER);
186: VecDuplicate(tsdae->U,&tsrhs);
187: TSSetRHSFunction(red->ts,tsrhs,TSDAESimple_Reduced_TSFunction,tsdae);
188: VecDestroy(&tsrhs);
190: SNESCreate(tsdae->comm,&red->snes);
191: SNESSetOptionsPrefix(red->snes,"tsdaesimple_");
192: SNESSetFunction(red->snes,NULL,TSDAESimple_Reduced_SNESFunction,tsdae);
193: SNESSetJacobian(red->snes,NULL,NULL,SNESComputeJacobianDefault,tsdae);
194: return(0);
195: }
198: /* ----------------------------------------------------------------------------*/
200: /*
201: Integrates the system by integrating directly the entire DAE system
202: */
204: typedef struct {
205: TS ts;
206: Vec UV,UF,VF;
207: VecScatter scatterU,scatterV;
208: } TSDAESimple_Full;
210: /*
211: Defines the RHS function that is passed to the time-integrator.
213: f(U,V)
214: 0
216: */
217: PetscErrorCode TSDAESimple_Full_TSRHSFunction(TS ts,PetscReal t,Vec UV,Vec F,void *actx)
218: {
219: TSDAESimple tsdae = (TSDAESimple)actx;
220: TSDAESimple_Full *full = (TSDAESimple_Full*)tsdae->data;
221: PetscErrorCode ierr;
224: VecSet(F,0.0);
225: VecScatterBegin(full->scatterU,UV,tsdae->U,INSERT_VALUES,SCATTER_REVERSE);
226: VecScatterEnd(full->scatterU,UV,tsdae->U,INSERT_VALUES,SCATTER_REVERSE);
227: VecScatterBegin(full->scatterV,UV,tsdae->V,INSERT_VALUES,SCATTER_REVERSE);
228: VecScatterEnd(full->scatterV,UV,tsdae->V,INSERT_VALUES,SCATTER_REVERSE);
229: (*tsdae->f)(t,tsdae->U,tsdae->V,full->UF,tsdae->fctx);
230: VecScatterBegin(full->scatterU,full->UF,F,INSERT_VALUES,SCATTER_FORWARD);
231: VecScatterEnd(full->scatterU,full->UF,F,INSERT_VALUES,SCATTER_FORWARD);
232: return(0);
233: }
235: /*
236: Defines the nonlinear function that is passed to the nonlinear solver
238: \dot{U}
239: F(U,V)
241: */
242: PetscErrorCode TSDAESimple_Full_TSIFunction(TS ts,PetscReal t,Vec UV,Vec UVdot,Vec F,void *actx)
243: {
244: TSDAESimple tsdae = (TSDAESimple)actx;
245: TSDAESimple_Full *full = (TSDAESimple_Full*)tsdae->data;
246: PetscErrorCode ierr;
249: VecCopy(UVdot,F);
250: VecScatterBegin(full->scatterU,UV,tsdae->U,INSERT_VALUES,SCATTER_REVERSE);
251: VecScatterEnd(full->scatterU,UV,tsdae->U,INSERT_VALUES,SCATTER_REVERSE);
252: VecScatterBegin(full->scatterV,UV,tsdae->V,INSERT_VALUES,SCATTER_REVERSE);
253: VecScatterEnd(full->scatterV,UV,tsdae->V,INSERT_VALUES,SCATTER_REVERSE);
254: (*tsdae->F)(t,tsdae->U,tsdae->V,full->VF,tsdae->Fctx);
255: VecScatterBegin(full->scatterV,full->VF,F,INSERT_VALUES,SCATTER_FORWARD);
256: VecScatterEnd(full->scatterV,full->VF,F,INSERT_VALUES,SCATTER_FORWARD);
257: return(0);
258: }
261: PetscErrorCode TSDAESimpleSolve_Full(TSDAESimple tsdae,Vec U)
262: {
263: PetscErrorCode ierr;
264: TSDAESimple_Full *full = (TSDAESimple_Full*)tsdae->data;
267: VecSet(full->UV,1.0);
268: VecScatterBegin(full->scatterU,U,full->UV,INSERT_VALUES,SCATTER_FORWARD);
269: VecScatterEnd(full->scatterU,U,full->UV,INSERT_VALUES,SCATTER_FORWARD);
270: TSSolve(full->ts,full->UV);
271: VecScatterBegin(full->scatterU,full->UV,U,INSERT_VALUES,SCATTER_REVERSE);
272: VecScatterEnd(full->scatterU,full->UV,U,INSERT_VALUES,SCATTER_REVERSE);
273: return(0);
274: }
276: PetscErrorCode TSDAESimpleSetFromOptions_Full(PetscOptionItems *PetscOptionsObject,TSDAESimple tsdae)
277: {
278: PetscErrorCode ierr;
279: TSDAESimple_Full *full = (TSDAESimple_Full*)tsdae->data;
282: TSSetFromOptions(full->ts);
283: return(0);
284: }
286: PetscErrorCode TSDAESimpleDestroy_Full(TSDAESimple tsdae)
287: {
288: PetscErrorCode ierr;
289: TSDAESimple_Full *full = (TSDAESimple_Full*)tsdae->data;
292: TSDestroy(&full->ts);
293: VecDestroy(&full->UV);
294: VecDestroy(&full->UF);
295: VecDestroy(&full->VF);
296: VecScatterDestroy(&full->scatterU);
297: VecScatterDestroy(&full->scatterV);
298: PetscFree(full);
299: return(0);
300: }
302: PetscErrorCode TSDAESimpleSetUp_Full(TSDAESimple tsdae)
303: {
304: PetscErrorCode ierr;
305: TSDAESimple_Full *full;
306: Vec tsrhs;
307: PetscInt nU,nV,UVstart;
308: IS is;
311: PetscNew(&full);
312: tsdae->data = full;
314: tsdae->setfromoptions = TSDAESimpleSetFromOptions_Full;
315: tsdae->solve = TSDAESimpleSolve_Full;
316: tsdae->destroy = TSDAESimpleDestroy_Full;
318: TSCreate(tsdae->comm,&full->ts);
319: TSSetProblemType(full->ts,TS_NONLINEAR);
320: TSSetType(full->ts,TSROSW);
321: TSSetExactFinalTime(full->ts,TS_EXACTFINALTIME_STEPOVER);
322: VecDuplicate(tsdae->U,&full->UF);
323: VecDuplicate(tsdae->V,&full->VF);
325: VecGetLocalSize(tsdae->U,&nU);
326: VecGetLocalSize(tsdae->V,&nV);
327: VecCreateMPI(tsdae->comm,nU+nV,PETSC_DETERMINE,&tsrhs);
328: VecDuplicate(tsrhs,&full->UV);
330: VecGetOwnershipRange(tsrhs,&UVstart,NULL);
331: ISCreateStride(tsdae->comm,nU,UVstart,1,&is);
332: VecScatterCreate(tsdae->U,NULL,tsrhs,is,&full->scatterU);
333: ISDestroy(&is);
334: ISCreateStride(tsdae->comm,nV,UVstart+nU,1,&is);
335: VecScatterCreate(tsdae->V,NULL,tsrhs,is,&full->scatterV);
336: ISDestroy(&is);
338: TSSetRHSFunction(full->ts,tsrhs,TSDAESimple_Full_TSRHSFunction,tsdae);
339: TSSetIFunction(full->ts,NULL,TSDAESimple_Full_TSIFunction,tsdae);
340: VecDestroy(&tsrhs);
341: return(0);
342: }
345: /* ----------------------------------------------------------------------------*/
348: /*
349: Simple example: f(U,V) = U + V
351: */
352: PetscErrorCode f(PetscReal t,Vec U,Vec V,Vec F,void *ctx)
353: {
357: VecWAXPY(F,1.0,U,V);
358: return(0);
359: }
361: /*
362: Simple example: F(U,V) = U - V
364: */
365: PetscErrorCode F(PetscReal t,Vec U,Vec V,Vec F,void *ctx)
366: {
370: VecWAXPY(F,-1.0,V,U);
371: return(0);
372: }
374: int main(int argc,char **argv)
375: {
377: TSDAESimple tsdae;
378: Vec U,V,Usolution;
380: PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
381: TSDAESimpleCreate(PETSC_COMM_WORLD,&tsdae);
383: VecCreateMPI(PETSC_COMM_WORLD,1,PETSC_DETERMINE,&U);
384: VecCreateMPI(PETSC_COMM_WORLD,1,PETSC_DETERMINE,&V);
385: TSDAESimpleSetRHSFunction(tsdae,U,f,NULL);
386: TSDAESimpleSetIFunction(tsdae,V,F,NULL);
388: VecDuplicate(U,&Usolution);
389: VecSet(Usolution,1.0);
391: /* TSDAESimpleSetUp_Full(tsdae); */
392: TSDAESimpleSetUp_Reduced(tsdae);
394: TSDAESimpleSetFromOptions(tsdae);
395: TSDAESimpleSolve(tsdae,Usolution);
396: TSDAESimpleDestroy(&tsdae);
398: VecDestroy(&U);
399: VecDestroy(&Usolution);
400: VecDestroy(&V);
401: PetscFinalize();
402: return ierr;
403: }