int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ Mat A; /* Jacobian matrix */ PetscErrorCode ierr; PetscMPIInt rank; PetscInt n = 2; PetscScalar *u; PetscInt direction=-1; PetscBool terminate=PETSC_FALSE; TSAdapt adapt; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&U,NULL);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = 1.0*rank; u[1] = 20.0; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,NULL);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,(TSIJacobian)IJacobian,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetDuration(ts,1000,30.0);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.1);CHKERRQ(ierr); ierr = TSSetEventHandler(ts,1,&direction,&terminate,EventFunction,PostEventFunction,NULL);CHKERRQ(ierr); /* The adapative time step controller could take very large timesteps resulting in the same event occuring multiple times in the same interval. A maximum step size limit is enforced here to avoid this issue. */ ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetStepLimits(adapt,0.0,0.5);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Run timestepping solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ Mat A; /* Jacobian matrix */ Mat Ap; /* dfdp */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 2; PetscScalar *u,*v; AppCtx app; PetscInt direction[1]; PetscBool terminate[1]; Vec lambda[2],mu[2]; PetscReal tend; FILE *f; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); app.mode = 1; app.lambda1 = 2.75; app.lambda2 = 0.36; tend = 0.125; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"ex1adj options","");CHKERRQ(ierr); { ierr = PetscOptionsReal("-lambda1","","",app.lambda1,&app.lambda1,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-lambda2","","",app.lambda2,&app.lambda2,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tend","","",tend,&tend,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&U,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&Ap);CHKERRQ(ierr); ierr = MatSetSizes(Ap,n,1,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(Ap,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(Ap);CHKERRQ(ierr); ierr = MatSetUp(Ap);CHKERRQ(ierr); ierr = MatZeroEntries(Ap);CHKERRQ(ierr); /* initialize to zeros */ ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = 0; u[1] = 1; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction)IFunction,&app);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,(TSIJacobian)IJacobian,&app);CHKERRQ(ierr); ierr = TSSetRHSJacobianP(ts,Ap,RHSJacobianP,&app);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Save trajectory of solution so that TSAdjointSolve() may be used - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetMaxTime(ts,tend);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,1./256.);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* Set directions and terminate flags for the two events */ direction[0] = 0; terminate[0] = PETSC_FALSE; ierr = TSSetEventHandler(ts,1,direction,terminate,EventFunction,PostEventFunction,(void*)&app);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Run timestepping solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adjoint model starts here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreateVecs(A,&lambda[0],NULL);CHKERRQ(ierr); ierr = MatCreateVecs(A,&lambda[1],NULL);CHKERRQ(ierr); /* Set initial conditions for the adjoint integration */ ierr = VecZeroEntries(lambda[0]);CHKERRQ(ierr); ierr = VecZeroEntries(lambda[1]);CHKERRQ(ierr); ierr = VecGetArray(lambda[0],&u);CHKERRQ(ierr); u[0] = 1.; ierr = VecRestoreArray(lambda[0],&u);CHKERRQ(ierr); ierr = VecGetArray(lambda[1],&u);CHKERRQ(ierr); u[1] = 1.; ierr = VecRestoreArray(lambda[1],&u);CHKERRQ(ierr); ierr = MatCreateVecs(Ap,&mu[0],NULL);CHKERRQ(ierr); ierr = MatCreateVecs(Ap,&mu[1],NULL);CHKERRQ(ierr); ierr = VecZeroEntries(mu[0]);CHKERRQ(ierr); ierr = VecZeroEntries(mu[1]);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,2,lambda,mu);CHKERRQ(ierr); ierr = TSAdjointSolve(ts);CHKERRQ(ierr); /* ierr = VecView(lambda[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(lambda[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(mu[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(mu[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ ierr = VecGetArray(mu[0],&u);CHKERRQ(ierr); ierr = VecGetArray(mu[1],&v);CHKERRQ(ierr); f = fopen("adj_mu.out", "a"); ierr = PetscFPrintf(PETSC_COMM_WORLD,f,"%20.15lf %20.15lf %20.15lf\n",tend,u[0],v[0]);CHKERRQ(ierr); ierr = VecRestoreArray(mu[0],&u);CHKERRQ(ierr); ierr = VecRestoreArray(mu[1],&v);CHKERRQ(ierr); fclose(f); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = MatDestroy(&Ap);CHKERRQ(ierr); ierr = VecDestroy(&lambda[0]);CHKERRQ(ierr); ierr = VecDestroy(&lambda[1]);CHKERRQ(ierr); ierr = VecDestroy(&mu[0]);CHKERRQ(ierr); ierr = VecDestroy(&mu[1]);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* * time_step solves for the time_dependence of the system * that was previously setup using the add_to_ham and add_lin * routines. Solver selection and parameters can be controlled via PETSc * command line options. Default solver is TSRK3BS * * Inputs: * Vec x: The density matrix, with appropriate inital conditions * double dt: initial timestep. For certain explicit methods, this timestep * can be changed, as those methods have adaptive time steps * double time_max: the maximum time to integrate to * int steps_max: max number of steps to take */ void time_step(Vec x, PetscReal init_time, PetscReal time_max,PetscReal dt,PetscInt steps_max){ PetscViewer mat_view; TS ts; /* timestepping context */ PetscInt i,j,Istart,Iend,steps,row,col; PetscScalar mat_tmp; PetscReal tmp_real; Mat AA; PetscInt nevents,direction; PetscBool terminate; operator op; int num_pop; double *populations; Mat solve_A,solve_stiff_A; PetscLogStagePop(); PetscLogStagePush(solve_stage); if (_lindblad_terms) { if (nid==0) { printf("Lindblad terms found, using Lindblad solver.\n"); } solve_A = full_A; if (_stiff_solver) { if(nid==0) printf("ERROR! Lindblad-stiff solver untested."); exit(0); } } else { if (nid==0) { printf("No Lindblad terms found, using (more efficient) Schrodinger solver.\n"); } solve_A = ham_A; solve_stiff_A = ham_stiff_A; if (_num_time_dep&&_stiff_solver) { if(nid==0) printf("ERROR! Schrodinger-stiff + timedep solver untested."); exit(0); } } /* Possibly print dense ham. No stabilization is needed? */ if (nid==0) { /* Print dense ham, if it was asked for */ if (_print_dense_ham){ FILE *fp_ham; fp_ham = fopen("ham","w"); if (nid==0){ for (i=0;i<total_levels;i++){ for (j=0;j<total_levels;j++){ fprintf(fp_ham,"%e %e ",PetscRealPart(_hamiltonian[i][j]),PetscImaginaryPart(_hamiltonian[i][j])); } fprintf(fp_ham,"\n"); } } fclose(fp_ham); for (i=0;i<total_levels;i++){ free(_hamiltonian[i]); } free(_hamiltonian); _print_dense_ham = 0; } } /* Remove stabilization if it was previously added */ if (stab_added){ if (nid==0) printf("Removing stabilization...\n"); /* * We add 1.0 in the 0th spot and every n+1 after */ if (nid==0) { row = 0; for (i=0;i<total_levels;i++){ col = i*(total_levels+1); mat_tmp = -1.0 + 0.*PETSC_i; MatSetValue(full_A,row,col,mat_tmp,ADD_VALUES); } } } MatGetOwnershipRange(solve_A,&Istart,&Iend); /* * Explicitly add 0.0 to all diagonal elements; * this fixes a 'matrix in wrong state' message that PETSc * gives if the diagonal was never initialized. */ //if (nid==0) printf("Adding 0 to diagonal elements...\n"); for (i=Istart;i<Iend;i++){ mat_tmp = 0 + 0.*PETSC_i; MatSetValue(solve_A,i,i,mat_tmp,ADD_VALUES); } if(_stiff_solver){ MatGetOwnershipRange(solve_stiff_A,&Istart,&Iend); for (i=Istart;i<Iend;i++){ mat_tmp = 0 + 0.*PETSC_i; MatSetValue(solve_stiff_A,i,i,mat_tmp,ADD_VALUES); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -* * Create the timestepping solver and set various options * *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* * Create timestepping solver context */ TSCreate(PETSC_COMM_WORLD,&ts); TSSetProblemType(ts,TS_LINEAR); /* * Set function to get information at every timestep */ if (_ts_monitor!=NULL){ TSMonitorSet(ts,_ts_monitor,_tsctx,NULL); } /* * Set up ODE system */ TSSetRHSFunction(ts,NULL,TSComputeRHSFunctionLinear,NULL); if(_stiff_solver) { /* TSSetIFunction(ts,NULL,TSComputeRHSFunctionLinear,NULL); */ if (nid==0) { printf("Stiff solver not implemented!\n"); exit(0); } if(nid==0) printf("Using stiff solver - TSROSW\n"); } if(_num_time_dep+_num_time_dep_lin) { for(i=0;i<_num_time_dep;i++){ tmp_real = 0.0; _add_ops_to_mat_ham(tmp_real,solve_A,_time_dep_list[i].num_ops,_time_dep_list[i].ops); } for(i=0;i<_num_time_dep_lin;i++){ tmp_real = 0.0; _add_ops_to_mat_lin(tmp_real,solve_A,_time_dep_list_lin[i].num_ops,_time_dep_list_lin[i].ops); } /* Tell PETSc to assemble the matrix */ MatAssemblyBegin(solve_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_A,MAT_FINAL_ASSEMBLY); if (nid==0) printf("Matrix Assembled.\n"); MatDuplicate(solve_A,MAT_COPY_VALUES,&AA); MatAssemblyBegin(AA,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(AA,MAT_FINAL_ASSEMBLY); TSSetRHSJacobian(ts,AA,AA,_RHS_time_dep_ham_p,NULL); } else { /* Tell PETSc to assemble the matrix */ MatAssemblyBegin(solve_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_A,MAT_FINAL_ASSEMBLY); if (_stiff_solver){ MatAssemblyBegin(solve_stiff_A,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(solve_stiff_A,MAT_FINAL_ASSEMBLY); /* TSSetIJacobian(ts,solve_stiff_A,solve_stiff_A,TSComputeRHSJacobianConstant,NULL); */ if (nid==0) { printf("Stiff solver not implemented!\n"); exit(0); } } if (nid==0) printf("Matrix Assembled.\n"); TSSetRHSJacobian(ts,solve_A,solve_A,TSComputeRHSJacobianConstant,NULL); } /* Print information about the matrix. */ PetscViewerASCIIOpen(PETSC_COMM_WORLD,NULL,&mat_view); PetscViewerPushFormat(mat_view,PETSC_VIEWER_ASCII_INFO); /* PetscViewerPushFormat(mat_view,PETSC_VIEWER_ASCII_MATLAB); */ /* MatView(solve_A,mat_view); */ /* PetscInt ncols; */ /* const PetscInt *cols; */ /* const PetscScalar *vals; */ /* for(i=0;i<total_levels*total_levels;i++){ */ /* MatGetRow(solve_A,i,&ncols,&cols,&vals); */ /* for (j=0;j<ncols;j++){ */ /* if(PetscAbsComplex(vals[j])>1e-5){ */ /* printf("%d %d %lf %lf\n",i,cols[j],vals[j]); */ /* } */ /* } */ /* MatRestoreRow(solve_A,i,&ncols,&cols,&vals); */ /* } */ if(_stiff_solver){ MatView(solve_stiff_A,mat_view); } PetscViewerPopFormat(mat_view); PetscViewerDestroy(&mat_view); TSSetTimeStep(ts,dt); /* * Set default options, can be changed at runtime */ TSSetMaxSteps(ts,steps_max); TSSetMaxTime(ts,time_max); TSSetTime(ts,init_time); TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER); if (_stiff_solver) { TSSetType(ts,TSROSW); } else { TSSetType(ts,TSRK); TSRKSetType(ts,TSRK3BS); } /* If we have gates to apply, set up the event handler. */ if (_num_quantum_gates > 0) { nevents = 1; //Only one event for now (did we cross a gate?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_QG_EventFunction,_QG_PostEventFunction,NULL); } if (_num_circuits > 0) { nevents = 1; //Only one event for now (did we cross a gate?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_QC_EventFunction,_QC_PostEventFunction,NULL); } if (_discrete_ec > 0) { nevents = 1; //Only one event for now (did we cross an ec step?) direction = -1; //We only want to count an event if we go from positive to negative terminate = PETSC_FALSE; //Keep time stepping after we passed our event /* Arguments are: ts context, nevents, direction of zero crossing, whether to terminate, * a function to check event status, a function to apply events, private data context. */ TSSetEventHandler(ts,nevents,&direction,&terminate,_DQEC_EventFunction,_DQEC_PostEventFunction,NULL); } /* if (_lindblad_terms) { */ /* nevents = 1; //Only one event for now (did we cross a gate?) */ /* direction = 0; //We only want to count an event if we go from positive to negative */ /* terminate = PETSC_FALSE; //Keep time stepping after we passed our event */ /* TSSetEventHandler(ts,nevents,&direction,&terminate,_Normalize_EventFunction,_Normalize_PostEventFunction,NULL); */ /* } */ TSSetFromOptions(ts); TSSolve(ts,x); TSGetStepNumber(ts,&steps); num_pop = get_num_populations(); populations = malloc(num_pop*sizeof(double)); get_populations(x,&populations); /* if(nid==0){ */ /* printf("Final populations: "); */ /* for(i=0;i<num_pop;i++){ */ /* printf(" %e ",populations[i]); */ /* } */ /* printf("\n"); */ /* } */ /* PetscPrintf(PETSC_COMM_WORLD,"Steps %D\n",steps); */ /* Free work space */ TSDestroy(&ts); if(_num_time_dep+_num_time_dep_lin){ MatDestroy(&AA); } free(populations); PetscLogStagePop(); PetscLogStagePush(post_solve_stage); return; }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U,V; /* solution will be stored here */ Vec F; /* residual vector */ Mat J; /* Jacobian matrix */ PetscMPIInt rank; PetscScalar *u,*v; AppCtx app; PetscInt direction[2]; PetscBool terminate[2]; TSAdapt adapt; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,NULL,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); app.Cd = 0.0; app.Cr = 0.9; app.bounces = 0; app.maxbounces = 10; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"ex44 options","");CHKERRQ(ierr); ierr = PetscOptionsReal("-Cd","Drag coefficient","",app.Cd,&app.Cd,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-Cr","Restitution coefficient","",app.Cr,&app.Cr,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-maxbounces","Maximum number of bounces","",app.maxbounces,&app.maxbounces,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); /*ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr);*/ ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSALPHA2);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_MAX_INT,PETSC_MAX_REAL);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,0.1);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetStepLimits(adapt,0.0,0.5);CHKERRQ(ierr); direction[0] = -1; terminate[0] = PETSC_FALSE; direction[1] = -1; terminate[1] = PETSC_TRUE; ierr = TSSetEventHandler(ts,2,direction,terminate,Event,PostEvent,&app);CHKERRQ(ierr); ierr = MatCreateAIJ(PETSC_COMM_WORLD,1,1,PETSC_DECIDE,PETSC_DECIDE,1,NULL,0,NULL,&J);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = MatSetUp(J);CHKERRQ(ierr); ierr = MatCreateVecs(J,NULL,&F);CHKERRQ(ierr); ierr = TSSetI2Function(ts,F,I2Function,&app);CHKERRQ(ierr); ierr = TSSetI2Jacobian(ts,J,J,I2Jacobian,&app);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = TSGetI2Jacobian(ts,&J,NULL,NULL,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(J,&U,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(J,&V,NULL);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); ierr = VecGetArray(V,&v);CHKERRQ(ierr); u[0] = 5.0*rank; v[0] = 20.0; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = VecRestoreArray(V,&v);CHKERRQ(ierr); ierr = TS2SetSolution(ts,U,V);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,NULL);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = VecDestroy(&V);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 2; PetscScalar *u; AppCtx app; PetscInt direction[2]; PetscBool terminate[2]; PetscBool rhs_form=PETSC_FALSE,hist=PETSC_TRUE; TSAdapt adapt; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); app.nbounces = 0; app.maxbounces = 10; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"ex40 options","");CHKERRQ(ierr); ierr = PetscOptionsInt("-maxbounces","","",app.maxbounces,&app.maxbounces,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_adapthistory","","",hist,&hist,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set ODE routines - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); /* Users are advised against the following branching and code duplication. For problems without a mass matrix like the one at hand, the RHSFunction (and companion RHSJacobian) interface is enough to support both explicit and implicit timesteppers. This tutorial example also deals with the IFunction/IJacobian interface for demonstration and testing purposes. */ ierr = PetscOptionsGetBool(NULL,NULL,"-rhs-form",&rhs_form,NULL);CHKERRQ(ierr); if (rhs_form) { ierr = TSSetRHSFunction(ts,NULL,RHSFunction,NULL);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,NULL,NULL,RHSJacobian,NULL);CHKERRQ(ierr); } else { Mat A; /* Jacobian matrix */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,NULL);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,IJacobian,NULL);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecCreate(PETSC_COMM_WORLD,&U);CHKERRQ(ierr); ierr = VecSetSizes(U,n,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(U);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = 0.0; u[1] = 20.0; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,30.0);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,0.1);CHKERRQ(ierr); /* The adapative time step controller could take very large timesteps resulting in the same event occuring multiple times in the same interval. A maximum step size limit is enforced here to avoid this issue. */ ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetStepLimits(adapt,0.0,0.5);CHKERRQ(ierr); /* Set directions and terminate flags for the two events */ direction[0] = -1; direction[1] = -1; terminate[0] = PETSC_FALSE; terminate[1] = PETSC_TRUE; ierr = TSSetEventHandler(ts,2,direction,terminate,EventFunction,PostEventFunction,(void*)&app);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Run timestepping solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); if (hist) { /* replay following history */ TSTrajectory tj; PetscReal tf,t0,dt; app.nbounces = 0; ierr = TSGetTime(ts,&tf);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,tf);CHKERRQ(ierr); ierr = TSSetStepNumber(ts,0);CHKERRQ(ierr); ierr = TSRestartStep(ts);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetType(adapt,TSADAPTHISTORY);CHKERRQ(ierr); ierr = TSGetTrajectory(ts,&tj);CHKERRQ(ierr); ierr = TSAdaptHistorySetTrajectory(adapt,tj,PETSC_FALSE);CHKERRQ(ierr); ierr = TSAdaptHistoryGetStep(adapt,0,&t0,&dt);CHKERRQ(ierr); /* this example fails with single (or smaller) precision */ #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL__FP16) ierr = TSAdaptSetType(adapt,TSADAPTBASIC);CHKERRQ(ierr); ierr = TSAdaptSetStepLimits(adapt,0.0,0.5);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); #endif ierr = TSSetTime(ts,t0);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); ierr = TSResetTrajectory(ts);CHKERRQ(ierr); ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = 0.0; u[1] = 20.0; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = TSSolve(ts,U);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }