This function allows the registering of custom multi-stage time integration methods and using it with PETSc. More than one method may be provided, each with a unique name (the name must not conflict with the names of existing methods in PETSc). The methods should be provided in a file "time_method.inp", and the following must be provided:
The method can then be used by invoking it by its name. For example, if a custom ARKIMEX method "foo" is provided through "time_method.inp", it can be used by specifying "-ts_type arkimex -ts_arkimex_type foo" in the command line or ".petscrc" file.
Currently supported classes of time integrators for which custom methods can be provided:
56 in = fopen(
"time_method.inp",
"r");
59 ierr2 = fscanf(in,
"%d",&N);
if (ierr2 != 1)
return(1);
60 for (n = 0; n < N; n++) {
64 PetscReal *A , *b, *c;
65 PetscReal *At, *bt, *ct;
66 PetscReal *bemb, *bembt;
68 PetscReal *bint,*bintt;
72 s = order = pinterp = 0;
80 ierr2 = fscanf(in,
"%s",word);
if (ierr2 != 1)
return(1);
81 if (!strcmp(word,
"begin")) {
82 while (strcmp(word,
"end")) {
83 ierr2 = fscanf(in,
"%s",word);
if (ierr2 != 1)
return(1);
84 if (!strcmp(word,
"name")) { ierr2 = fscanf(in,
"%s",name);
if (ierr2 != 1)
return(1); }
85 else if (!strcmp(word,
"class")) { ierr2 = fscanf(in,
"%s",type);
if (ierr2 != 1)
return(1); }
86 else if (!strcmp(word,
"nstages")) { ierr2 = fscanf(in,
"%d",&s);
if (ierr2 != 1)
return(1); }
87 else if (!strcmp(word,
"order")) { ierr2 = fscanf(in,
"%d",&order);
if (ierr2 != 1)
return(1); }
88 else if (!strcmp(word,
"pinterp")) { ierr2 = fscanf(in,
"%d",&pinterp);
if (ierr2 != 1)
return(1); }
89 else if (!strcmp(word,
"At")) {
91 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
92 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
95 At = (PetscReal*) calloc (s*s,
sizeof(PetscReal));
97 for (i = 0; i < s; i++) {
98 for (j = 0; j < s; j++) {
99 ierr2 = fscanf(in,
"%lf",&At[i*s+j]);
if (ierr2 != 1)
return(1);
103 }
else if (!strcmp(word,
"A")) {
105 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
106 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
109 A = (PetscReal*) calloc (s*s,
sizeof(PetscReal));
111 for (i = 0; i < s; i++) {
112 for (j = 0; j < s; j++) {
113 ierr2 = fscanf(in,
"%lf",&A[i*s+j]);
if (ierr2 != 1)
return(1);
117 }
else if (!strcmp(word,
"bt")) {
119 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
120 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
123 bt = (PetscReal*) calloc (s,
sizeof(PetscReal));
125 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&bt[i]);
if (ierr2 != 1)
return(1);
127 }
else if (!strcmp(word,
"b")) {
129 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
130 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
133 b = (PetscReal*) calloc (s,
sizeof(PetscReal));
135 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&b[i]);
if (ierr2 != 1)
return(1);
137 }
else if (!strcmp(word,
"ct")) {
139 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
140 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
143 ct = (PetscReal*) calloc (s,
sizeof(PetscReal));
145 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&ct[i]);
if (ierr2 != 1)
return(1);
147 }
else if (!strcmp(word,
"c")) {
149 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
150 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
153 c = (PetscReal*) calloc (s,
sizeof(PetscReal));
155 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&c[i]);
if (ierr2 != 1)
return(1);
157 }
else if (!strcmp(word,
"bembt")) {
159 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
160 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
163 bembt = (PetscReal*) calloc (s,
sizeof(PetscReal));
165 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&bembt[i]);
if (ierr2 != 1)
return(1);
167 }
else if (!strcmp(word,
"bemb")) {
169 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages must be defined ");
170 if (!rank) fprintf(stderr,
"before specifying the Butcher tableaux entries.\n" );
173 bemb = (PetscReal*) calloc (s,
sizeof(PetscReal));
175 for (i = 0; i < s; i++) ierr2 = fscanf(in,
"%lf",&bemb[i]);
if (ierr2 != 1)
return(1);
177 }
else if (!strcmp(word,
"bintt")) {
178 if (s == 0 || pinterp == 0) {
179 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages and pinterp must be " );
180 if (!rank) fprintf(stderr,
"defined as positive values before specifying interpolation coeffs.\n");
183 bintt = (PetscReal*) calloc (s*pinterp,
sizeof(PetscReal));
185 for (i = 0; i < s; i++) {
186 for (j = 0; j < pinterp; j++) {
187 ierr2 = fscanf(in,
"%lf",&bintt[i*s+j]);
if (ierr2 != 1)
return(1);
191 }
else if (!strcmp(word,
"bint")) {
192 if (s == 0 || pinterp == 0) {
193 if (!rank) fprintf(stderr,
"Error in PetscRegisterTIMethods(): nstages and pinterp must be " );
194 if (!rank) fprintf(stderr,
"defined as positive values before specifying interpolation coeffs.\n");
197 bint = (PetscReal*) calloc (s*pinterp,
sizeof(PetscReal));
199 for (i = 0; i < s; i++) {
200 for (j = 0; j < pinterp; j++) {
201 ierr2 = fscanf(in,
"%lf",&bint[i*s+j]);
if (ierr2 != 1)
return(1);
208 if (!rank) fprintf(stderr,
"Error: Illegal format in file \"time_method.inp\" (expected keyword \"begin\").\n");
213 if (!strcmp(type,
"arkimex")) {
215 ierr = TSARKIMEXRegister(name,order,s,At,bt,ct,A,b,c,bembt,bemb,pinterp,bintt,bint); CHKERRQ(ierr);
217 printf(
"\nRegistered custom ARKIMEX scheme \"%s\" with the following Butcher tableaux:-\n",name);
219 for (i = 0; i < s; i++) {
220 if (c) printf(
" %+1.5lf |",c[i]);
222 for (j = 0; j < s; j++) printf (
" %+1.5lf :",A[i*s+j]);
224 if (ct) printf(
"%+1.5lf |",ct[i]);
226 for (j = 0; j < s; j++) printf (
" %+1.5lf :",At[i*s+j]);
229 printf(
" ---------|");
230 for (j = 0; j < s; j++) printf(
"-----------");
232 printf(
"---------|");
233 for (j = 0; j < s; j++) printf(
"-----------");
236 if (b)
for (j = 0; j < s; j++) printf(
" %+1.5lf :",b[j]);
237 else for (j = 0; j < s; j++) printf(
" :");
240 if (bt)
for (j = 0; j < s; j++) printf(
" %+1.5lf :",bt[j]);
241 else for (j = 0; j < s; j++) printf(
" :");
246 fprintf(stderr,
"Warning in PetscRegisterTIMethods(): Failed to register method ");
247 fprintf(stderr,
"(A or At not defined).\n");
250 }
else if (!strcmp(type,
"rk")) {
252 ierr = TSRKRegister(name,order,s,A,b,c,bemb,pinterp,bint); CHKERRQ(ierr);
254 printf(
"\nRegistered custom RK scheme \"%s\" with the following Butcher tableaux:-\n",name);
256 for (i = 0; i < s; i++) {
257 if (c) printf(
" %+1.5lf |",c[i]);
259 for (j = 0; j < s; j++) printf (
" %+1.5lf :",A[i*s+j]);
262 printf(
" ---------|");
263 for (j = 0; j < s; j++) printf(
"-----------");
266 if (b)
for (j = 0; j < s; j++) printf(
" %+1.5lf :",b[j]);
267 else for (j = 0; j < s; j++) printf(
" :");
272 fprintf(stderr,
"Warning in PetscRegisterTIMethods(): Failed to register method ");
273 fprintf(stderr,
"(A not defined).\n");
278 fprintf(stderr,
"Error in PetscRegisterTIMethods(): %s class of time-integration schemes ",type);
279 fprintf(stderr,
"does not support custom method registration and usage.\n");
290 if (bembt) free(bembt);
291 if (bemb) free(bemb);
292 if (bintt) free(bintt);
293 if (bint) free(bint);
297 PetscFunctionReturn(0);
#define _MAX_STRING_SIZE_