33 #ifdef USE_RUNTIME_LOADING
39 #include "ac/getopt.h"
56 struct integration_data {
65 static int method_multistep(
const char*, integration_data*,
void*,
const char*);
66 static int method_hope(
const char*, integration_data*,
void*,
const char*);
67 static int method_cubic(
const char*, integration_data*,
void*,
const char*);
68 static int method_radau_II(
const char*, integration_data*,
void*,
const char*);
69 static int method_cn(
const char*, integration_data*,
void*,
const char*);
71 static void* get_method_data(method_t,
const char*);
73 static int open_module(
const char* module);
75 static struct funcs *ff = NULL;
76 static bool print_help =
false;
77 static void* p_data = NULL;
80 main(
int argc,
char *
const argv[])
86 {
"ms", METHOD_MULTISTEP },
87 {
"hope", METHOD_HOPE },
88 {
"cubic", METHOD_CUBIC },
89 {
"radau-II", METHOD_RADAU_II },
90 {
"crank-nicolson", METHOD_CRANK_NICOLSON },
92 { NULL, METHOD_UNKNOWN }
94 method_t curr_method = METHOD_UNKNOWN;
95 const char* module =
"intg-default.so";
96 char* user_defined = NULL;
97 void* method_data = NULL;
98 integration_data d = { 0., 1., 1.e-3, 1.e-6, 10 };
101 const char optstring[] =
"i:lm:t:T:n:r:u:hH";
102 const struct option longopts[] = {
103 {
"integrator", required_argument, NULL,
int(
'i') },
104 {
"method-data", required_argument, NULL,
int(
'm') },
105 {
"timing", required_argument, NULL,
int(
't') },
106 {
"tolerance", required_argument, NULL,
int(
'T') },
107 {
"iterations", required_argument, NULL,
int(
'n') },
108 {
"rho", required_argument, NULL,
int(
'r') },
109 {
"user-defined", required_argument, NULL,
int(
'u') },
110 {
"help", no_argument, NULL,
int(
'h') },
111 {
"print-help", no_argument, NULL,
int(
'H') },
113 { NULL, no_argument, NULL,
int(0) }
119 curropt = getopt_long(argc, argv, optstring, longopts, NULL);
121 if (curropt == EOF) {
133 std::cerr <<
"missing parameter for option -"
138 std::cerr <<
"usage: int -[imtTnruh] [module]"
141 <<
" -i,--integrator : integration method"
143 <<
" -l : list available methods"
145 <<
" -m,--method-data : method-dependent data"
147 <<
" -t,--timing : ti:dt:tf" << std::endl
148 <<
" -T,--tolerance" << std::endl
149 <<
" -n,--maxiter" << std::endl
150 <<
" -r,--rho : asymptotic radius"
152 <<
" -u,--user : user-defined data"
155 <<
" -h,--help : print this message "
156 "and exit" << std::endl
158 <<
" -H,--print-help : print module's "
159 "help message" << std::endl;
168 while (p->s != NULL) {
169 if (strcmp(p->s,
optarg) == 0) {
176 std::cerr <<
"unknown integrator "
184 for (
int i = 0; s_m[i].s; i++) {
185 std::cout <<
" " << s_m[i].s << std::endl;
190 method_data = get_method_data(curr_method,
optarg);
196 d.ti = strtod(next, &next);
197 if (next[0] !=
':') {
198 std::cerr <<
"syntax: ti:dt:tf" << std::endl;
203 d.dt = strtod(next, &next);
204 if (next[0] !=
':') {
205 std::cerr <<
"syntax: ti:dt:tf" << std::endl;
210 d.tf = strtod(next, &next);
211 if (next[0] !=
'\0') {
212 std::cerr <<
"syntax: ti:dt:tf" << std::endl;
220 d.tol = strtod(
optarg, NULL);
224 d.maxiter = strtol(
optarg, NULL, 10);
228 d.rho = strtod(
optarg, NULL);
242 std::cerr <<
"need a module" << std::endl;
250 if (::ff->
size == 0) {
251 std::cerr <<
"no \"size\" func in module" << std::endl;
255 if (::ff->
func == 0) {
256 std::cerr <<
"no \"func\" func in module" << std::endl;
260 if (::ff->
grad == 0) {
261 std::cerr <<
"no \"grad\" func in module" << std::endl;
265 if (::ff->
read && ::ff->
read(&p_data, user_defined)) {
266 std::cerr <<
"unable to read(" << user_defined <<
") "
267 "data for module \"" << module <<
"\"" << std::endl;
273 ::ff->help(p_data, std::cerr);
275 std::cerr <<
"help not available for module "
276 "\"" << module <<
"\" (ignored)" << std::endl;
281 switch (curr_method) {
282 case METHOD_MULTISTEP :
283 rc = method_multistep(module, &d, method_data, user_defined);
286 rc = method_hope(module, &d, method_data, user_defined);
289 rc = method_cubic(module, &d, method_data, user_defined);
291 case METHOD_RADAU_II:
292 rc = method_radau_II(module, &d, method_data, user_defined);
294 case METHOD_CRANK_NICOLSON:
295 rc = method_cn(module, &d, method_data, user_defined);
298 std::cerr <<
"you must select an integration method" << std::endl;
303 std::cerr <<
"lt_dlexit() failed" << std::endl;
311 get_method_data(method_t curr_method,
const char*
optarg)
313 switch (curr_method) {
315 case METHOD_RADAU_II:
316 if (strcasecmp(optarg,
"linear") == 0) {
321 }
else if (strcasecmp(optarg,
"cubic") == 0) {
327 std::cerr <<
"unknown data \"" << optarg <<
"\""
334 std::cerr <<
"not implemented yet" << std::endl;
342 open_module(
const char* module)
344 const char* err = NULL;
349 std::cerr <<
"lt_dlinit() failed" << std::endl;
353 if ((handle = lt_dlopen(module)) == NULL) {
355 std::cerr <<
"lt_dlopen(\"" << module
356 <<
"\") returned \"" << err <<
"\"" << std::endl;
360 struct funcs **pf = (
struct funcs **)lt_dlsym(handle,
"ff");
363 std::cerr <<
"lt_dlsym(\"ff\") returned \"" << err <<
"\""
370 std::cerr <<
"invalid \"ff\" symbol in \"" << module <<
"\""
397 return 1 - 3*xi*xi - 2*xi*xi*xi;
403 return - 6.*xi - 6.*xi*xi;
409 return 3.*xi*xi + 2.*xi*xi*xi;
415 return 6.*xi + 6.*xi*xi;
421 return xi + 2.*xi*xi + xi*xi*xi;
427 return 1. + 4.*xi + 3.*xi*xi;
433 return xi*xi + xi*xi*xi;
439 return 2.*xi + 3.*xi*xi;
443 method_multistep(
const char* module, integration_data* d,
444 void* method_data,
const char* user_defined)
447 int size = ::ff->size(p_data);
488 int maxiter = d->maxiter;
493 (4.*rho*rho-(1.-rho)*(1.-rho))/(4.-(1.-rho)*(1.-rho));
494 doublereal delta = (1.-rho)*(1.-rho)/(2.*(4.-(1.-rho)*(1.-rho)));
505 ::ff->init(p_data, *pX, *pXP);
507 for (
int k = 1; k <=
size; k++) {
511 (*pXm1)(k) = x-dt*xp;
515 std::cout << ti <<
" " << 0. <<
" ";
517 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
520 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
526 for (
int ir = size; ir > 0; ir--) {
533 + dt*(cn0p(1.)*xPm1 + cn1p(1.)*xPm2);
536 + dt*(b0*xP + b1*xPm1 + b2*xPm2);
550 ::ff->func(p_data, *Res, *pX, *pXP, t);
553 std::cerr << j <<
" " << test << std::endl;
558 std::cerr <<
"current iteration " << j
559 <<
" exceeds max iteration number "
560 << maxiter << std::endl;
568 ::ff->grad(p_data, J, JP, *pX, *pXP, t);
569 for (
int ir = 1; ir <=
size; ir++) {
570 for (
int ic = 1; ic <=
size; ic++) {
571 (*Jac)(ir, ic) = JP(ir, ic)
578 for (
int ir = size; ir > 0; ir--) {
581 (*pX)(ir) += coef*dxP;
586 std::cout << t <<
" " << test <<
" ";
588 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
591 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
595 ::ff->destroy(&p_data);
605 method_hope(
const char* module, integration_data* d,
606 void* method_data,
const char* user_defined)
608 std::cerr << __FUNCTION__ <<
"not implemented yet!" << std::endl;
615 method_cubic(
const char* module, integration_data* d,
616 void* method_data,
const char* user_defined)
621 bool *pi = (
bool *)method_data;
627 int size = ::ff->size(p_data);
653 size*size, size, size);
655 size*size, size, size);
675 int maxiter = d->maxiter;
684 doublereal jzz = (1.+3.*rho)/(6.*rho*(1.+rho))*dt;
685 doublereal jz0 = -1./(6.*rho*(1.+rho)*(1.+rho))*dt;
686 doublereal j0z = (1.+rho)*(1.+rho)/(6.*rho)*dt;
693 ::ff->init(p_data, *pX, *pXP);
695 ::ff->func(p_data, *Res, *pX, *pXP, t);
696 for (
int k = 1; k <=
size; k++) {
700 (*pXm1)(k) = x - dt*xp;
704 std::cout << ti <<
" " << 0. <<
" ";
706 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
709 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
716 std::cerr <<
"linear predictor" << std::endl;
719 for (
int k = 1; k <=
size; k++) {
736 for (
int k = 1; k <=
size; k++) {
741 doublereal xP = (cm0p(1.)*xm1 + cm1p(1.)*xm2)/dt
742 + cn0p(1.)*xPm1 + cn1p(1.)*xPm2;
743 doublereal xPz = (cm0p(1. + z)*xm1 + cm1p(1. + z)*xm2)/dt
744 + cn0p(1. + z)*xPm1 + cn1p(1. + z)*xPm2;
745 doublereal x = xm1 + dt*(w1*xPm1 + wz*xPz + w0*xP);
746 doublereal xz = cm0(z)*x + cm1(z)*xm1 + dt*(cn0(z)*xP + cn1(z)*xPm1);
768 ::ff->func(p_data, *Res, *pX, *pXP, t);
770 ::ff->func(p_data, Resz, Xz, XPz, t + z*dt);
778 std::cerr <<
"current iteration " << j
779 <<
" exceeds max iteration number "
780 << maxiter << std::endl;
790 ::ff->grad(p_data, Jz, JPz, Xz, XPz, t + z*dt);
791 ::ff->grad(p_data, J0, JP0, *pX, *pXP, t);
793 for (
int ir = 1; ir <=
size; ir++) {
794 for (
int ic = 1; ic <=
size; ic++) {
798 (*Jac)(ir, size + ic)
800 (*Jac)(size + ir, ic)
802 (*Jac)(size + ir, size + ic)
811 for (
int ir = size; ir > 0; ir--) {
816 (*pX)(ir) += dt*(wz*dxPz + w0*dxP0);
817 Xz(ir) += dt*(cm0(z)*(wz*dxPz + w0*dxP0)+cn0(z)*dxP0);
822 std::cout << t <<
" " << test <<
" ";
824 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
827 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
831 ::ff->destroy(&p_data);
888 method_radau_II(
const char* module, integration_data* d,
889 void* method_data,
const char* user_defined)
894 bool *pi = (
bool *)method_data;
900 int size = ::ff->size(p_data);
926 size*size, size, size);
928 size*size, size, size);
948 int maxiter = d->maxiter;
969 ::ff->init(p_data, *pX, *pXP);
971 ::ff->func(p_data, *Res, *pX, *pXP, t);
972 for (
int k = 1; k <=
size; k++) {
976 (*pXm1)(k) += x - dt*xp;
980 std::cout << ti <<
" " << 0. <<
" ";
982 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
985 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
992 std::cerr <<
"linear predictor" << std::endl;
995 for (
int k = 1; k <=
size; k++) {
1012 for (
int k = 1; k <=
size; k++) {
1017 doublereal xP = (radau_II_cm0p(1.)*xm1 + radau_II_cm1p(1.)*xm2)/dt
1018 + radau_II_cn0p(1.)*xPm1 + radau_II_cn1p(1.)*xPm2;
1019 doublereal xPz = (radau_II_cm0p(1. + z)*xm1 + radau_II_cm1p(1. + z)*xm2)/dt
1020 + radau_II_cn0p(1. + z)*xPm1 + radau_II_cn1p(1. + z)*xPm2;
1021 doublereal x = xm1 + dt*(w1*xPm1 + wz*xPz + w0*xP);
1022 doublereal xz = m0*x + m1*xm1 + dt*(n0*xP + n1*xPm1);
1044 ::ff->func(p_data, *Res, *pX, *pXP, t);
1046 ::ff->func(p_data, Resz, Xz, XPz, t + z*dt);
1053 if (++j > maxiter) {
1054 std::cerr <<
"current iteration " << j
1055 <<
" exceeds max iteration number "
1056 << maxiter << std::endl;
1066 ::ff->grad(p_data, Jz, JPz, Xz, XPz, t + z*dt);
1067 ::ff->grad(p_data, J0, JP0, *pX, *pXP, t);
1069 for (
int ir = 1; ir <=
size; ir++) {
1070 for (
int ic = 1; ic <=
size; ic++) {
1074 (*Jac)(ir, size + ic)
1076 (*Jac)(size + ir, ic)
1078 (*Jac)(size + ir, size + ic)
1087 for (
int ir = size; ir > 0; ir--) {
1092 (*pX)(ir) += dt*(wz*dxPz + w0*dxP0);
1093 Xz(ir) += dt*(m0*(wz*dxPz + w0*dxP0)+n0*dxP0);
1098 std::cout << t <<
" " << test <<
" ";
1100 ::ff->out(p_data, std::cout, *pX, *pXP) << std::endl;
1103 flip(&pX, &pXP, &pXm1, &pXPm1, &pXm2, &pXPm2);
1107 ::ff->destroy(&p_data);
1116 method_cn(
const char* module, integration_data* d,
1117 void* method_data,
const char* user_defined)
1119 std::cerr << __FUNCTION__ <<
"not implemented yet!" << std::endl;
1125 #else // ! USE_RUNTIME_LOADING
1133 std::cerr <<
"Need dynamic load capabilities" << std::endl;
1137 #endif // ! USE_RUNTIME_LOADING
virtual void Reset(void)=0
virtual VectorHandler * pResHdl(void) const =0
virtual doublereal * pdGetVec(void) const =0
SolutionManager *const GetSolutionManager(integer iNLD, integer iLWS=0) const
virtual doublereal Norm(void) const
virtual MatrixHandler * pMatHdl(void) const =0
virtual void MatrReset(void)=0
virtual void Solve(void)=0
virtual VectorHandler * pSolHdl(void) const =0
static const std::vector< doublereal > v0