xref: /petsc/src/ts/trajectory/impls/basic/trajbasic.c (revision 9566063d113dddea24716c546802770db7481bc0)
1bc952696SBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/tsimpl.h>        /*I "petscts.h"  I*/
3bc952696SBarry Smith 
4f3334a03SStefano Zampini typedef struct {
5f3334a03SStefano Zampini   PetscViewer viewer;
6f3334a03SStefano Zampini } TSTrajectory_Basic;
7533251d3SHong Zhang /*
8533251d3SHong Zhang   For n-th time step, TSTrajectorySet_Basic always saves the solution X(t_n) and the current time t_n,
9533251d3SHong Zhang   and optionally saves the stage values Y[] between t_{n-1} and t_n, the previous time t_{n-1}, and
10533251d3SHong Zhang   forward stage sensitivities S[] = dY[]/dp.
11533251d3SHong Zhang */
12560360afSLisandro Dalcin static PetscErrorCode TSTrajectorySet_Basic(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X)
13bc952696SBarry Smith {
14f3334a03SStefano Zampini   TSTrajectory_Basic *tjbasic = (TSTrajectory_Basic*)tj->data;
159afe7f3eSBarry Smith   char               filename[PETSC_MAX_PATH_LEN];
166affb6f8SHong Zhang   PetscInt           ns,i;
176cd0a353SHong Zhang 
1822a86ba0SHong Zhang   PetscFunctionBegin;
19*9566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),tj->dirfiletemplate,stepnum));
20*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetName(tjbasic->viewer,filename)); /* this triggers PetscViewer to be set up again */
21*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(tjbasic->viewer));
22*9566063dSJacob Faibussowitsch   PetscCall(VecView(X,tjbasic->viewer));
23*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWrite(tjbasic->viewer,&time,1,PETSC_REAL));
24f3334a03SStefano Zampini   if (stepnum && !tj->solution_only) {
25f3334a03SStefano Zampini     Vec       *Y;
26f3334a03SStefano Zampini     PetscReal tprev;
27*9566063dSJacob Faibussowitsch     PetscCall(TSGetStages(ts,&ns,&Y));
28bc952696SBarry Smith     for (i=0; i<ns; i++) {
29533251d3SHong Zhang       /* For stiffly accurate TS methods, the last stage Y[ns-1] is the same as the solution X, thus does not need to be saved again. */
30533251d3SHong Zhang       if (ts->stifflyaccurate && i == ns-1) continue;
31*9566063dSJacob Faibussowitsch       PetscCall(VecView(Y[i],tjbasic->viewer));
32f3334a03SStefano Zampini     }
33*9566063dSJacob Faibussowitsch     PetscCall(TSGetPrevTime(ts,&tprev));
34*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(tjbasic->viewer,&tprev,1,PETSC_REAL));
35f3334a03SStefano Zampini   }
366affb6f8SHong Zhang   /* Tangent linear sensitivities needed by second-order adjoint */
376affb6f8SHong Zhang   if (ts->forward_solve) {
386affb6f8SHong Zhang     Mat A,*S;
396affb6f8SHong Zhang 
40*9566063dSJacob Faibussowitsch     PetscCall(TSForwardGetSensitivities(ts,NULL,&A));
41*9566063dSJacob Faibussowitsch     PetscCall(MatView(A,tjbasic->viewer));
426affb6f8SHong Zhang     if (stepnum) {
43*9566063dSJacob Faibussowitsch       PetscCall(TSForwardGetStages(ts,&ns,&S));
446affb6f8SHong Zhang       for (i=0; i<ns; i++) {
45*9566063dSJacob Faibussowitsch         PetscCall(MatView(S[i],tjbasic->viewer));
466affb6f8SHong Zhang       }
476affb6f8SHong Zhang     }
486affb6f8SHong Zhang   }
49f3334a03SStefano Zampini   PetscFunctionReturn(0);
50bc952696SBarry Smith }
51bc952696SBarry Smith 
52f3334a03SStefano Zampini static PetscErrorCode TSTrajectorySetFromOptions_Basic(PetscOptionItems *PetscOptionsObject,TSTrajectory tj)
53f3334a03SStefano Zampini {
54f3334a03SStefano Zampini   PetscFunctionBegin;
55*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHead(PetscOptionsObject,"TS trajectory options for Basic type"));
56*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsTail());
57bc952696SBarry Smith   PetscFunctionReturn(0);
58bc952696SBarry Smith }
59bc952696SBarry Smith 
60560360afSLisandro Dalcin static PetscErrorCode TSTrajectoryGet_Basic(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal *t)
61bc952696SBarry Smith {
62bc952696SBarry Smith   PetscViewer    viewer;
639afe7f3eSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
64f3334a03SStefano Zampini   Vec            Sol;
656affb6f8SHong Zhang   PetscInt       ns,i;
666cd0a353SHong Zhang 
6722a86ba0SHong Zhang   PetscFunctionBegin;
68*9566063dSJacob Faibussowitsch   PetscCall(PetscSNPrintf(filename,sizeof(filename),tj->dirfiletemplate,stepnum));
69*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryOpen(PetscObjectComm((PetscObject)tj),filename,FILE_MODE_READ,&viewer));
70*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_NATIVE));
71*9566063dSJacob Faibussowitsch   PetscCall(TSGetSolution(ts,&Sol));
72*9566063dSJacob Faibussowitsch   PetscCall(VecLoad(Sol,viewer));
73*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,t,1,NULL,PETSC_REAL));
74ac1a7491SHong Zhang   if (stepnum && !tj->solution_only) {
75f3334a03SStefano Zampini     Vec       *Y;
76f3334a03SStefano Zampini     PetscReal timepre;
77*9566063dSJacob Faibussowitsch     PetscCall(TSGetStages(ts,&ns,&Y));
786affb6f8SHong Zhang     for (i=0; i<ns; i++) {
79533251d3SHong Zhang       /* For stiffly accurate TS methods, the last stage Y[ns-1] is the same as the solution X, thus does not need to be loaded again. */
80533251d3SHong Zhang       if (ts->stifflyaccurate && i == ns-1) continue;
81*9566063dSJacob Faibussowitsch       PetscCall(VecLoad(Y[i],viewer));
82bc952696SBarry Smith     }
83*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,&timepre,1,NULL,PETSC_REAL));
84f3334a03SStefano Zampini     if (tj->adjoint_solve_mode) {
85*9566063dSJacob Faibussowitsch       PetscCall(TSSetTimeStep(ts,-(*t)+timepre));
8626656371SHong Zhang     }
87f3334a03SStefano Zampini   }
886affb6f8SHong Zhang   /* Tangent linear sensitivities needed by second-order adjoint */
896affb6f8SHong Zhang   if (ts->forward_solve) {
906affb6f8SHong Zhang 
91cc4f23bcSHong Zhang     if (!ts->stifflyaccurate) {
92cc4f23bcSHong Zhang       Mat A;
93*9566063dSJacob Faibussowitsch       PetscCall(TSForwardGetSensitivities(ts,NULL,&A));
94*9566063dSJacob Faibussowitsch       PetscCall(MatLoad(A,viewer));
95cc4f23bcSHong Zhang     }
966affb6f8SHong Zhang     if (stepnum) {
97cc4f23bcSHong Zhang       Mat *S;
98*9566063dSJacob Faibussowitsch       PetscCall(TSForwardGetStages(ts,&ns,&S));
996affb6f8SHong Zhang       for (i=0; i<ns; i++) {
100*9566063dSJacob Faibussowitsch         PetscCall(MatLoad(S[i],viewer));
1016affb6f8SHong Zhang       }
1026affb6f8SHong Zhang     }
1036affb6f8SHong Zhang   }
104*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&viewer));
105bc952696SBarry Smith   PetscFunctionReturn(0);
106bc952696SBarry Smith }
107bc952696SBarry Smith 
1088a10d460SHong Zhang PetscErrorCode TSTrajectorySetUp_Basic(TSTrajectory tj,TS ts)
109f3334a03SStefano Zampini {
110f3334a03SStefano Zampini   MPI_Comm       comm;
111f3334a03SStefano Zampini   PetscMPIInt    rank;
112f3334a03SStefano Zampini 
113f3334a03SStefano Zampini   PetscFunctionBegin;
114*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)tj,&comm));
115*9566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
116dd400576SPatrick Sanan   if (rank == 0) {
1178a10d460SHong Zhang     char      *dir = tj->dirname;
118f3334a03SStefano Zampini     PetscBool flg;
119f3334a03SStefano Zampini 
1208a10d460SHong Zhang     if (!dir) {
1218a10d460SHong Zhang       char dtempname[16] = "TS-data-XXXXXX";
122*9566063dSJacob Faibussowitsch       PetscCall(PetscMkdtemp(dtempname));
123*9566063dSJacob Faibussowitsch       PetscCall(PetscStrallocpy(dtempname,&tj->dirname));
1248a10d460SHong Zhang     } else {
125*9566063dSJacob Faibussowitsch       PetscCall(PetscTestDirectory(dir,'w',&flg));
126f3334a03SStefano Zampini       if (!flg) {
127*9566063dSJacob Faibussowitsch         PetscCall(PetscTestFile(dir,'r',&flg));
1283c633725SBarry Smith         PetscCheck(!flg,PETSC_COMM_SELF,PETSC_ERR_USER,"Specified path is a file - not a dir: %s",dir);
129*9566063dSJacob Faibussowitsch         PetscCall(PetscMkdir(dir));
13098921bdaSJacob Faibussowitsch       } else SETERRQ(comm,PETSC_ERR_SUP,"Directory %s not empty",tj->dirname);
131f3334a03SStefano Zampini     }
1328a10d460SHong Zhang   }
133*9566063dSJacob Faibussowitsch   PetscCall(PetscBarrier((PetscObject)tj));
134f3334a03SStefano Zampini   PetscFunctionReturn(0);
135f3334a03SStefano Zampini }
136f3334a03SStefano Zampini 
13764fc91eeSBarry Smith static PetscErrorCode TSTrajectoryDestroy_Basic(TSTrajectory tj)
13864fc91eeSBarry Smith {
139f3334a03SStefano Zampini   TSTrajectory_Basic *tjbasic = (TSTrajectory_Basic*)tj->data;
14064fc91eeSBarry Smith 
14164fc91eeSBarry Smith   PetscFunctionBegin;
142*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&tjbasic->viewer));
143*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(tjbasic));
14464fc91eeSBarry Smith   PetscFunctionReturn(0);
14564fc91eeSBarry Smith }
14664fc91eeSBarry Smith 
147bc952696SBarry Smith /*MC
14878fbdcc8SBarry Smith       TSTRAJECTORYBASIC - Stores each solution of the ODE/DAE in a file
14978fbdcc8SBarry Smith 
1508e5aa403SBarry Smith       Saves each timestep into a separate file named TS-data-XXXXXX/TS-%06d.bin. The file name can be changed.
15178fbdcc8SBarry Smith 
15278fbdcc8SBarry Smith       This version saves the solutions at all the stages
15378fbdcc8SBarry Smith 
15478fbdcc8SBarry Smith       $PETSC_DIR/share/petsc/matlab/PetscReadBinaryTrajectory.m can read in files created with this format
155bc952696SBarry Smith 
156bc952696SBarry Smith   Level: intermediate
157bc952696SBarry Smith 
15864e38db7SHong Zhang .seealso:  TSTrajectoryCreate(), TS, TSTrajectorySetType(), TSTrajectorySetDirname(), TSTrajectorySetFile()
159bc952696SBarry Smith 
160bc952696SBarry Smith M*/
161c3df6c96SHong Zhang PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Basic(TSTrajectory tj,TS ts)
162bc952696SBarry Smith {
163f3334a03SStefano Zampini   TSTrajectory_Basic *tjbasic;
164f3334a03SStefano Zampini 
165bc952696SBarry Smith   PetscFunctionBegin;
166*9566063dSJacob Faibussowitsch   PetscCall(PetscNew(&tjbasic));
167f3334a03SStefano Zampini 
168*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)tj),&tjbasic->viewer));
169*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(tjbasic->viewer,PETSCVIEWERBINARY));
170*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerPushFormat(tjbasic->viewer,PETSC_VIEWER_NATIVE));
171*9566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileSetMode(tjbasic->viewer,FILE_MODE_WRITE));
172f3334a03SStefano Zampini   tj->data = tjbasic;
173f3334a03SStefano Zampini 
17452fbb9a2SHong Zhang   tj->ops->set            = TSTrajectorySet_Basic;
17552fbb9a2SHong Zhang   tj->ops->get            = TSTrajectoryGet_Basic;
176f3334a03SStefano Zampini   tj->ops->setup          = TSTrajectorySetUp_Basic;
17764fc91eeSBarry Smith   tj->ops->destroy        = TSTrajectoryDestroy_Basic;
178f3334a03SStefano Zampini   tj->ops->setfromoptions = TSTrajectorySetFromOptions_Basic;
179bc952696SBarry Smith   PetscFunctionReturn(0);
180bc952696SBarry Smith }
181