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