xref: /petsc/src/ts/event/tests/ex1.c (revision fa9584fb611836aca54f08ab8720e6338ac4bd38)
1*fa9584fbSIlya Fursov static char help[] = "Solves the trivial ODE du/dt = 1, u(0) = 0. \n\n";
2*fa9584fbSIlya Fursov 
3*fa9584fbSIlya Fursov #include <petscts.h>
4*fa9584fbSIlya Fursov #include <petscpc.h>
5*fa9584fbSIlya Fursov 
6*fa9584fbSIlya Fursov static PetscErrorCode RHSFunction(TS, PetscReal, Vec, Vec, void *);
7*fa9584fbSIlya Fursov static PetscErrorCode RHSJacobian(TS, PetscReal, Vec, Mat, Mat, void *);
8*fa9584fbSIlya Fursov 
9*fa9584fbSIlya Fursov static PetscErrorCode PreStep(TS);
10*fa9584fbSIlya Fursov static PetscErrorCode PostStep(TS);
11*fa9584fbSIlya Fursov static PetscErrorCode Monitor(TS, PetscInt, PetscReal, Vec, void *);
12*fa9584fbSIlya Fursov static PetscErrorCode Event(TS, PetscReal, Vec, PetscReal *, void *);
13*fa9584fbSIlya Fursov static PetscErrorCode PostEvent(TS, PetscInt, PetscInt[], PetscReal, Vec, PetscBool, void *);
14*fa9584fbSIlya Fursov static PetscErrorCode TransferSetUp(TS, PetscInt, PetscReal, Vec, PetscBool *, void *);
15*fa9584fbSIlya Fursov static PetscErrorCode Transfer(TS, PetscInt, Vec[], Vec[], void *);
16*fa9584fbSIlya Fursov 
17*fa9584fbSIlya Fursov int main(int argc, char **argv)
18*fa9584fbSIlya Fursov {
19*fa9584fbSIlya Fursov   TS              ts;
20*fa9584fbSIlya Fursov   PetscInt        n, ntransfer = 2;
21*fa9584fbSIlya Fursov   const PetscInt  n_end = 11;
22*fa9584fbSIlya Fursov   PetscReal       t;
23*fa9584fbSIlya Fursov   const PetscReal t_end = 11;
24*fa9584fbSIlya Fursov   Vec             x;
25*fa9584fbSIlya Fursov   Vec             f;
26*fa9584fbSIlya Fursov   Mat             A;
27*fa9584fbSIlya Fursov 
28*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
29*fa9584fbSIlya Fursov   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
30*fa9584fbSIlya Fursov 
31*fa9584fbSIlya Fursov   PetscCall(TSCreate(PETSC_COMM_WORLD, &ts));
32*fa9584fbSIlya Fursov 
33*fa9584fbSIlya Fursov   PetscCall(VecCreate(PETSC_COMM_WORLD, &f));
34*fa9584fbSIlya Fursov   PetscCall(VecSetSizes(f, 1, PETSC_DECIDE));
35*fa9584fbSIlya Fursov   PetscCall(VecSetFromOptions(f));
36*fa9584fbSIlya Fursov   PetscCall(VecSetUp(f));
37*fa9584fbSIlya Fursov   PetscCall(TSSetRHSFunction(ts, f, RHSFunction, NULL));
38*fa9584fbSIlya Fursov   PetscCall(VecDestroy(&f));
39*fa9584fbSIlya Fursov 
40*fa9584fbSIlya Fursov   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
41*fa9584fbSIlya Fursov   PetscCall(MatSetSizes(A, 1, 1, PETSC_DECIDE, PETSC_DECIDE));
42*fa9584fbSIlya Fursov   PetscCall(MatSetFromOptions(A));
43*fa9584fbSIlya Fursov   PetscCall(MatSetUp(A));
44*fa9584fbSIlya Fursov   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
45*fa9584fbSIlya Fursov   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
46*fa9584fbSIlya Fursov   /* ensure that the Jacobian matrix has diagonal entries since that is required by TS */
47*fa9584fbSIlya Fursov   PetscCall(MatShift(A, (PetscReal)1));
48*fa9584fbSIlya Fursov   PetscCall(MatShift(A, (PetscReal)-1));
49*fa9584fbSIlya Fursov   PetscCall(TSSetRHSJacobian(ts, A, A, RHSJacobian, NULL));
50*fa9584fbSIlya Fursov   PetscCall(MatDestroy(&A));
51*fa9584fbSIlya Fursov 
52*fa9584fbSIlya Fursov   PetscCall(VecCreate(PETSC_COMM_WORLD, &x));
53*fa9584fbSIlya Fursov   PetscCall(VecSetSizes(x, 1, PETSC_DECIDE));
54*fa9584fbSIlya Fursov   PetscCall(VecSetFromOptions(x));
55*fa9584fbSIlya Fursov   PetscCall(VecSetUp(x));
56*fa9584fbSIlya Fursov   PetscCall(TSSetSolution(ts, x));
57*fa9584fbSIlya Fursov   PetscCall(VecDestroy(&x));
58*fa9584fbSIlya Fursov 
59*fa9584fbSIlya Fursov   PetscCall(TSMonitorSet(ts, Monitor, NULL, NULL));
60*fa9584fbSIlya Fursov   PetscCall(TSSetPreStep(ts, PreStep));
61*fa9584fbSIlya Fursov   PetscCall(TSSetPostStep(ts, PostStep));
62*fa9584fbSIlya Fursov 
63*fa9584fbSIlya Fursov   {
64*fa9584fbSIlya Fursov     TSAdapt adapt;
65*fa9584fbSIlya Fursov     PetscCall(TSGetAdapt(ts, &adapt));
66*fa9584fbSIlya Fursov     PetscCall(TSAdaptSetType(adapt, TSADAPTNONE));
67*fa9584fbSIlya Fursov   }
68*fa9584fbSIlya Fursov   {
69*fa9584fbSIlya Fursov     PetscInt  direction[3];
70*fa9584fbSIlya Fursov     PetscBool terminate[3];
71*fa9584fbSIlya Fursov     direction[0] = +1;
72*fa9584fbSIlya Fursov     terminate[0] = PETSC_FALSE;
73*fa9584fbSIlya Fursov     direction[1] = -1;
74*fa9584fbSIlya Fursov     terminate[1] = PETSC_FALSE;
75*fa9584fbSIlya Fursov     direction[2] = 0;
76*fa9584fbSIlya Fursov     terminate[2] = PETSC_FALSE;
77*fa9584fbSIlya Fursov     PetscCall(TSSetTimeStep(ts, 1));
78*fa9584fbSIlya Fursov     PetscCall(TSSetEventHandler(ts, 3, direction, terminate, Event, PostEvent, NULL));
79*fa9584fbSIlya Fursov   }
80*fa9584fbSIlya Fursov   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER));
81*fa9584fbSIlya Fursov   PetscCall(TSSetResize(ts, TransferSetUp, Transfer, &ntransfer));
82*fa9584fbSIlya Fursov   PetscCall(TSSetFromOptions(ts));
83*fa9584fbSIlya Fursov 
84*fa9584fbSIlya Fursov   /* --- First Solve --- */
85*fa9584fbSIlya Fursov 
86*fa9584fbSIlya Fursov   PetscCall(TSSetStepNumber(ts, 0));
87*fa9584fbSIlya Fursov   PetscCall(TSSetTimeStep(ts, 1));
88*fa9584fbSIlya Fursov   PetscCall(TSSetTime(ts, 0));
89*fa9584fbSIlya Fursov   PetscCall(TSSetMaxTime(ts, PETSC_MAX_REAL));
90*fa9584fbSIlya Fursov   PetscCall(TSSetMaxSteps(ts, 3));
91*fa9584fbSIlya Fursov 
92*fa9584fbSIlya Fursov   PetscCall(TSGetTime(ts, &t));
93*fa9584fbSIlya Fursov   PetscCall(TSGetSolution(ts, &x));
94*fa9584fbSIlya Fursov   PetscCall(VecSet(x, t));
95*fa9584fbSIlya Fursov   while (t < t_end) {
96*fa9584fbSIlya Fursov     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n"));
97*fa9584fbSIlya Fursov     PetscCall(TSSolve(ts, NULL));
98*fa9584fbSIlya Fursov     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n"));
99*fa9584fbSIlya Fursov     PetscCall(TSGetTime(ts, &t));
100*fa9584fbSIlya Fursov     PetscCall(TSGetStepNumber(ts, &n));
101*fa9584fbSIlya Fursov     PetscCall(TSSetMaxSteps(ts, PetscMin(n + 3, n_end)));
102*fa9584fbSIlya Fursov   }
103*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n"));
104*fa9584fbSIlya Fursov   PetscCall(TSSolve(ts, NULL));
105*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n"));
106*fa9584fbSIlya Fursov 
107*fa9584fbSIlya Fursov   /* --- Second Solve --- */
108*fa9584fbSIlya Fursov 
109*fa9584fbSIlya Fursov   PetscCall(TSSetStepNumber(ts, 0));
110*fa9584fbSIlya Fursov   PetscCall(TSSetTimeStep(ts, 1));
111*fa9584fbSIlya Fursov   PetscCall(TSSetTime(ts, 0));
112*fa9584fbSIlya Fursov   PetscCall(TSSetMaxTime(ts, 3));
113*fa9584fbSIlya Fursov   PetscCall(TSSetMaxSteps(ts, PETSC_MAX_INT));
114*fa9584fbSIlya Fursov 
115*fa9584fbSIlya Fursov   PetscCall(TSGetTime(ts, &t));
116*fa9584fbSIlya Fursov   PetscCall(TSGetSolution(ts, &x));
117*fa9584fbSIlya Fursov   PetscCall(VecSet(x, t));
118*fa9584fbSIlya Fursov   while (t < t_end) {
119*fa9584fbSIlya Fursov     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n"));
120*fa9584fbSIlya Fursov     PetscCall(TSSolve(ts, NULL));
121*fa9584fbSIlya Fursov     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n"));
122*fa9584fbSIlya Fursov     PetscCall(TSGetTime(ts, &t));
123*fa9584fbSIlya Fursov     PetscCall(TSSetMaxTime(ts, PetscMin(t + 3, t_end)));
124*fa9584fbSIlya Fursov   }
125*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: Begin\n"));
126*fa9584fbSIlya Fursov   PetscCall(TSSolve(ts, NULL));
127*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "TSSolve: End\n\n"));
128*fa9584fbSIlya Fursov 
129*fa9584fbSIlya Fursov   /* --- */
130*fa9584fbSIlya Fursov 
131*fa9584fbSIlya Fursov   PetscCall(TSDestroy(&ts));
132*fa9584fbSIlya Fursov 
133*fa9584fbSIlya Fursov   PetscCall(PetscFinalize());
134*fa9584fbSIlya Fursov   return 0;
135*fa9584fbSIlya Fursov }
136*fa9584fbSIlya Fursov 
137*fa9584fbSIlya Fursov /* -------------------------------------------------------------------*/
138*fa9584fbSIlya Fursov 
139*fa9584fbSIlya Fursov PetscErrorCode RHSFunction(TS ts, PetscReal t, Vec x, Vec f, void *ctx)
140*fa9584fbSIlya Fursov {
141*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
142*fa9584fbSIlya Fursov   PetscCall(VecSet(f, (PetscReal)1));
143*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
144*fa9584fbSIlya Fursov }
145*fa9584fbSIlya Fursov 
146*fa9584fbSIlya Fursov PetscErrorCode RHSJacobian(TS ts, PetscReal t, Vec x, Mat A, Mat B, void *ctx)
147*fa9584fbSIlya Fursov {
148*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
149*fa9584fbSIlya Fursov   PetscCall(MatZeroEntries(B));
150*fa9584fbSIlya Fursov   if (B != A) PetscCall(MatZeroEntries(A));
151*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
152*fa9584fbSIlya Fursov }
153*fa9584fbSIlya Fursov 
154*fa9584fbSIlya Fursov PetscErrorCode PreStep(TS ts)
155*fa9584fbSIlya Fursov {
156*fa9584fbSIlya Fursov   PetscInt           n;
157*fa9584fbSIlya Fursov   PetscReal          t;
158*fa9584fbSIlya Fursov   Vec                x;
159*fa9584fbSIlya Fursov   const PetscScalar *a;
160*fa9584fbSIlya Fursov 
161*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
162*fa9584fbSIlya Fursov   PetscCall(TSGetStepNumber(ts, &n));
163*fa9584fbSIlya Fursov   PetscCall(TSGetTime(ts, &t));
164*fa9584fbSIlya Fursov   PetscCall(TSGetSolution(ts, &x));
165*fa9584fbSIlya Fursov   PetscCall(VecGetArrayRead(x, &a));
166*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0])));
167*fa9584fbSIlya Fursov   PetscCall(VecRestoreArrayRead(x, &a));
168*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
169*fa9584fbSIlya Fursov }
170*fa9584fbSIlya Fursov 
171*fa9584fbSIlya Fursov PetscErrorCode PostStep(TS ts)
172*fa9584fbSIlya Fursov {
173*fa9584fbSIlya Fursov   PetscInt           n;
174*fa9584fbSIlya Fursov   PetscReal          t;
175*fa9584fbSIlya Fursov   Vec                x;
176*fa9584fbSIlya Fursov   const PetscScalar *a;
177*fa9584fbSIlya Fursov 
178*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
179*fa9584fbSIlya Fursov   PetscCall(TSGetStepNumber(ts, &n));
180*fa9584fbSIlya Fursov   PetscCall(TSGetTime(ts, &t));
181*fa9584fbSIlya Fursov   PetscCall(TSGetSolution(ts, &x));
182*fa9584fbSIlya Fursov   PetscCall(VecGetArrayRead(x, &a));
183*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0])));
184*fa9584fbSIlya Fursov   PetscCall(VecRestoreArrayRead(x, &a));
185*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
186*fa9584fbSIlya Fursov }
187*fa9584fbSIlya Fursov 
188*fa9584fbSIlya Fursov PetscErrorCode Monitor(TS ts, PetscInt n, PetscReal t, Vec x, void *ctx)
189*fa9584fbSIlya Fursov {
190*fa9584fbSIlya Fursov   const PetscScalar *a;
191*fa9584fbSIlya Fursov 
192*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
193*fa9584fbSIlya Fursov   PetscCall(VecGetArrayRead(x, &a));
194*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, n, (double)t, (double)PetscRealPart(a[0])));
195*fa9584fbSIlya Fursov   PetscCall(VecRestoreArrayRead(x, &a));
196*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
197*fa9584fbSIlya Fursov }
198*fa9584fbSIlya Fursov 
199*fa9584fbSIlya Fursov PetscErrorCode Event(TS ts, PetscReal t, Vec x, PetscReal *fvalue, void *ctx)
200*fa9584fbSIlya Fursov {
201*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
202*fa9584fbSIlya Fursov   fvalue[0] = t - 5;
203*fa9584fbSIlya Fursov   fvalue[1] = 7 - t;
204*fa9584fbSIlya Fursov   fvalue[2] = t - 9;
205*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
206*fa9584fbSIlya Fursov }
207*fa9584fbSIlya Fursov 
208*fa9584fbSIlya Fursov PetscErrorCode PostEvent(TS ts, PetscInt nevents, PetscInt event_list[], PetscReal t, Vec x, PetscBool forwardsolve, void *ctx)
209*fa9584fbSIlya Fursov {
210*fa9584fbSIlya Fursov   PetscInt           i;
211*fa9584fbSIlya Fursov   const PetscScalar *a;
212*fa9584fbSIlya Fursov 
213*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
214*fa9584fbSIlya Fursov   PetscCall(TSGetStepNumber(ts, &i));
215*fa9584fbSIlya Fursov   PetscCall(VecGetArrayRead(x, &a));
216*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " time %g value %g\n", PETSC_FUNCTION_NAME, i, (double)t, (double)PetscRealPart(a[0])));
217*fa9584fbSIlya Fursov   PetscCall(VecRestoreArrayRead(x, &a));
218*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
219*fa9584fbSIlya Fursov }
220*fa9584fbSIlya Fursov 
221*fa9584fbSIlya Fursov PetscErrorCode TransferSetUp(TS ts, PetscInt n, PetscReal t, Vec x, PetscBool *flg, void *ctx)
222*fa9584fbSIlya Fursov {
223*fa9584fbSIlya Fursov   PetscInt *nt = (PetscInt *)ctx;
224*fa9584fbSIlya Fursov 
225*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
226*fa9584fbSIlya Fursov   *flg = (PetscBool)(*nt && n && n % (*nt) == 0);
227*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
228*fa9584fbSIlya Fursov }
229*fa9584fbSIlya Fursov 
230*fa9584fbSIlya Fursov PetscErrorCode Transfer(TS ts, PetscInt nv, Vec vin[], Vec vout[], void *ctx)
231*fa9584fbSIlya Fursov {
232*fa9584fbSIlya Fursov   PetscInt i;
233*fa9584fbSIlya Fursov 
234*fa9584fbSIlya Fursov   PetscFunctionBeginUser;
235*fa9584fbSIlya Fursov   PetscCall(TSGetStepNumber(ts, &i));
236*fa9584fbSIlya Fursov   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)ts), "%-10s-> step %" PetscInt_FMT " nv %" PetscInt_FMT "\n", PETSC_FUNCTION_NAME, i, nv));
237*fa9584fbSIlya Fursov   for (i = 0; i < nv; i++) {
238*fa9584fbSIlya Fursov     PetscCall(VecDuplicate(vin[i], &vout[i]));
239*fa9584fbSIlya Fursov     PetscCall(VecCopy(vin[i], vout[i]));
240*fa9584fbSIlya Fursov   }
241*fa9584fbSIlya Fursov   PetscFunctionReturn(PETSC_SUCCESS);
242*fa9584fbSIlya Fursov }
243*fa9584fbSIlya Fursov 
244*fa9584fbSIlya Fursov /*TEST
245*fa9584fbSIlya Fursov 
246*fa9584fbSIlya Fursov     test:
247*fa9584fbSIlya Fursov       suffix: euler
248*fa9584fbSIlya Fursov       diff_args: -j
249*fa9584fbSIlya Fursov       args: -ts_type euler
250*fa9584fbSIlya Fursov       output_file: output/ex1.out
251*fa9584fbSIlya Fursov 
252*fa9584fbSIlya Fursov     test:
253*fa9584fbSIlya Fursov       suffix: ssp
254*fa9584fbSIlya Fursov       diff_args: -j
255*fa9584fbSIlya Fursov       args: -ts_type ssp
256*fa9584fbSIlya Fursov       output_file: output/ex1.out
257*fa9584fbSIlya Fursov 
258*fa9584fbSIlya Fursov     test:
259*fa9584fbSIlya Fursov       suffix: rk
260*fa9584fbSIlya Fursov       diff_args: -j
261*fa9584fbSIlya Fursov       args: -ts_type rk
262*fa9584fbSIlya Fursov       output_file: output/ex1.out
263*fa9584fbSIlya Fursov 
264*fa9584fbSIlya Fursov     test:
265*fa9584fbSIlya Fursov       suffix: beuler
266*fa9584fbSIlya Fursov       diff_args: -j
267*fa9584fbSIlya Fursov       args: -ts_type beuler
268*fa9584fbSIlya Fursov       output_file: output/ex1.out
269*fa9584fbSIlya Fursov 
270*fa9584fbSIlya Fursov     test:
271*fa9584fbSIlya Fursov       suffix: cn
272*fa9584fbSIlya Fursov       diff_args: -j
273*fa9584fbSIlya Fursov       args: -ts_type cn
274*fa9584fbSIlya Fursov       output_file: output/ex1.out
275*fa9584fbSIlya Fursov 
276*fa9584fbSIlya Fursov     test:
277*fa9584fbSIlya Fursov       suffix: theta
278*fa9584fbSIlya Fursov       args: -ts_type theta
279*fa9584fbSIlya Fursov       diff_args: -j
280*fa9584fbSIlya Fursov       output_file: output/ex1.out
281*fa9584fbSIlya Fursov 
282*fa9584fbSIlya Fursov     test:
283*fa9584fbSIlya Fursov       suffix: bdf
284*fa9584fbSIlya Fursov       diff_args: -j
285*fa9584fbSIlya Fursov       args: -ts_type bdf
286*fa9584fbSIlya Fursov       output_file: output/ex1_bdf.out
287*fa9584fbSIlya Fursov 
288*fa9584fbSIlya Fursov     test:
289*fa9584fbSIlya Fursov       suffix: alpha
290*fa9584fbSIlya Fursov       diff_args: -j
291*fa9584fbSIlya Fursov       args: -ts_type alpha
292*fa9584fbSIlya Fursov       output_file: output/ex1.out
293*fa9584fbSIlya Fursov 
294*fa9584fbSIlya Fursov     test:
295*fa9584fbSIlya Fursov       suffix: rosw
296*fa9584fbSIlya Fursov       diff_args: -j
297*fa9584fbSIlya Fursov       args: -ts_type rosw
298*fa9584fbSIlya Fursov       output_file: output/ex1.out
299*fa9584fbSIlya Fursov 
300*fa9584fbSIlya Fursov     test:
301*fa9584fbSIlya Fursov       suffix: arkimex
302*fa9584fbSIlya Fursov       diff_args: -j
303*fa9584fbSIlya Fursov       args: -ts_type arkimex
304*fa9584fbSIlya Fursov       output_file: output/ex1.out
305*fa9584fbSIlya Fursov 
306*fa9584fbSIlya Fursov TEST*/
307