Exemplo n.º 1
0
int main()
{
    int f = 0;
    int count = 0;

    int *matToMem   = (int *)malloc(20000000);

    to_mem(matToMem, 0);
    int t=1;

    while(count < 1000)
    {
        int random = rand()%2;
        if(random == 0)
        {
            to_mem(matToMem, t);
            t++;
        }
        else
        {
            from_mem(matToMem, f);
            if(f < t-1)
                f++;
        }
        count++;
    }    
}
Exemplo n.º 2
0
 void SundialsInterface::print_stats(IntegratorMemory* mem, ostream &stream) const {
   auto m = to_mem(mem);
   stream << "FORWARD INTEGRATION:" << endl;
   stream << "Number of steps taken by SUNDIALS: " << m->nsteps << endl;
   stream << "Number of calls to the user’s f function: " << m->nfevals << endl;
   stream << "Number of calls made to the linear solver setup function: "
          << m->nlinsetups << endl;
   stream << "Number of error test failures: " << m->netfails << endl;
   stream << "Method order used on the last internal step: "  << m->qlast << endl;
   stream << "Method order to be used on the next internal step: " << m->qcur << endl;
   stream << "Actual value of initial step size: " << m->hinused << endl;
   stream << "Step size taken on the last internal step: " << m->hlast << endl;
   stream << "Step size to be attempted on the next internal step: " << m->hcur << endl;
   stream << "Current internal time reached: " << m->tcur << endl;
   stream << "Number of nonlinear iterations performed: " << m->nniters << endl;
   stream << "Number of nonlinear convergence failures: " << m->nncfails << endl;
   if (nrx_>0) {
     stream << "BACKWARD INTEGRATION:" << endl;
     stream << "Number of steps taken by SUNDIALS: " << m->nstepsB << endl;
     stream << "Number of calls to the user’s f function: " << m->nfevalsB << endl;
     stream << "Number of calls made to the linear solver setup function: "
            << m->nlinsetupsB << endl;
     stream << "Number of error test failures: " << m->netfailsB << endl;
     stream << "Method order used on the last internal step: "  << m->qlastB << endl;
     stream << "Method order to be used on the next internal step: " << m->qcurB << endl;
     stream << "Actual value of initial step size: " << m->hinusedB << endl;
     stream << "Step size taken on the last internal step: " << m->hlastB << endl;
     stream << "Step size to be attempted on the next internal step: " << m->hcurB << endl;
     stream << "Current internal time reached: " << m->tcurB << endl;
     stream << "Number of nonlinear iterations performed: " << m->nnitersB << endl;
     stream << "Number of nonlinear convergence failures: " << m->nncfailsB << endl;
   }
   stream << endl;
 }
Exemplo n.º 3
0
  int IdasInterface::rhsQB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz,
                                  N_Vector rxzdot, N_Vector rqdot, void *user_data) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = NV_DATA_S(rxz);
      m->arg[1] = NV_DATA_S(rxz)+s.nrx_;
      m->arg[2] = m->rp;
      m->arg[3] = NV_DATA_S(xz);
      m->arg[4] = NV_DATA_S(xz)+s.nx_;
      m->arg[5] = m->p;
      m->arg[6] = &t;
      m->res[0] = NV_DATA_S(rqdot);
      s.calc_function(m, "quadB");

      // Negate (note definition of g)
      casadi_scal(s.nrq_, -1., NV_DATA_S(rqdot));

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "resQB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 4
0
  int IdasInterface::resB(double t, N_Vector xz, N_Vector xzdot, N_Vector rxz,
                                 N_Vector rxzdot, N_Vector rr, void *user_data) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = NV_DATA_S(rxz);
      m->arg[1] = NV_DATA_S(rxz)+s.nrx_;
      m->arg[2] = m->rp;
      m->arg[3] = NV_DATA_S(xz);
      m->arg[4] = NV_DATA_S(xz)+s.nx_;
      m->arg[5] = m->p;
      m->arg[6] = &t;
      m->res[0] = NV_DATA_S(rr);
      m->res[1] = NV_DATA_S(rr)+s.nrx_;
      s.calc_function(m, "daeB");

      // Subtract state derivative to get residual
      casadi_axpy(s.nrx_, 1., NV_DATA_S(rxzdot), NV_DATA_S(rr));

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "resB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 5
0
  int IdasInterface::lsolve(IDAMem IDA_mem, N_Vector b, N_Vector weight, N_Vector xz,
                                   N_Vector xzdot, N_Vector rr) {
    try {
      auto m = to_mem(IDA_mem->ida_lmem);
      auto& s = m->self;

      // Current time
      double t = IDA_mem->ida_tn;

      // Multiple of df_dydot to be added to the matrix
      double cj = IDA_mem->ida_cj;

      // Accuracy
      double delta = 0.0;

      // Call the preconditioner solve function (which solves the linear system)
      if (psolve(t, xz, xzdot, rr, b, b, cj,
        delta, static_cast<void*>(m), 0)) return 1;

      // Scale the correction to account for change in cj
      if (s.cj_scaling_) {
        double cjratio = IDA_mem->ida_cjratio;
        if (cjratio != 1.0) N_VScale(2.0/(1.0 + cjratio), b, b);
      }

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "lsolve failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 6
0
  int IdasInterface::psetupB(double t, N_Vector xz, N_Vector xzdot,
                                    N_Vector rxz, N_Vector rxzdot,
                                    N_Vector rresval, double cj, void *user_data,
                                    N_Vector tmp1B, N_Vector tmp2B, N_Vector tmp3B) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = &t;
      m->arg[1] = NV_DATA_S(rxz);
      m->arg[2] = NV_DATA_S(rxz)+s.nrx_;
      m->arg[3] = m->rp;
      m->arg[4] = NV_DATA_S(xz);
      m->arg[5] = NV_DATA_S(xz)+s.nx_;
      m->arg[6] = m->p;
      m->arg[7] = &cj;
      m->res[0] = m->jacB;
      s.calc_function(m, "jacB");

      // Factorize the linear system
      s.linsolB_.factorize(m->jacB);

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "psetupB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 7
0
  void IdasInterface::retreat(IntegratorMemory* mem, double t, double* rx,
                              double* rz, double* rq) const {
    auto m = to_mem(mem);

    // Integrate, unless already at desired time
    if (t<m->t) {
      THROWING(IDASolveB, m->mem, t, IDA_NORMAL);
      THROWING(IDAGetB, m->mem, m->whichB, &m->t, m->rxz, m->rxzdot);
      if (nrq_>0) {
        THROWING(IDAGetQuadB, m->mem, m->whichB, &m->t, m->rq);
      }
    }

    // Save outputs
    casadi_copy(NV_DATA_S(m->rxz), nrx_, rx);
    casadi_copy(NV_DATA_S(m->rxz)+nrx_, nrz_, rz);
    casadi_copy(NV_DATA_S(m->rq), nrq_, rq);

    // Get stats
    IDAMem IDA_mem = IDAMem(m->mem);
    IDAadjMem IDAADJ_mem = IDA_mem->ida_adj_mem;
    IDABMem IDAB_mem = IDAADJ_mem->IDAB_mem;
    THROWING(IDAGetIntegratorStats, IDAB_mem->IDA_mem, &m->nstepsB, &m->nfevalsB,
             &m->nlinsetupsB, &m->netfailsB, &m->qlastB, &m->qcurB, &m->hinusedB,
             &m->hlastB, &m->hcurB, &m->tcurB);
  }
Exemplo n.º 8
0
  int IdasInterface::jtimesB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB,
                                    N_Vector xzdotB, N_Vector resvalB, N_Vector vB, N_Vector JvB,
                                    double cjB, void *user_data,
                                    N_Vector tmp1B, N_Vector tmp2B) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = &t;
      m->arg[1] = NV_DATA_S(xz);
      m->arg[2] = NV_DATA_S(xz)+s.nx_;
      m->arg[3] = m->p;
      m->arg[4] = NV_DATA_S(xzB);
      m->arg[5] = NV_DATA_S(xzB)+s.nrx_;
      m->arg[6] = m->rp;
      m->arg[7] = NV_DATA_S(vB);
      m->arg[8] = NV_DATA_S(vB)+s.nrx_;
      m->res[0] = NV_DATA_S(JvB);
      m->res[1] = NV_DATA_S(JvB) + s.nrx_;
      s.calc_function(m, "jtimesB");

      // Subtract state derivative to get residual
      casadi_axpy(s.nrx_, cjB, NV_DATA_S(vB), NV_DATA_S(JvB));

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "jtimesB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 9
0
  void IdasInterface::reset(IntegratorMemory* mem, double t, const double* _x,
                            const double* _z, const double* _p) const {
    log("IdasInterface::reset", "begin");
    auto m = to_mem(mem);

    // Reset the base classes
    SundialsInterface::reset(mem, t, _x, _z, _p);

    // Re-initialize
    copy(init_xdot_.begin(), init_xdot_.end(), NV_DATA_S(m->xzdot));
    THROWING(IDAReInit, m->mem, grid_.front(), m->xz, m->xzdot);

    // Re-initialize quadratures
    if (nq_>0) THROWING(IDAQuadReInit, m->mem, m->q);

    // Correct initial conditions, if necessary
    if (calc_ic_) {
      THROWING(IDACalcIC, m->mem, IDA_YA_YDP_INIT , first_time_);
      THROWING(IDAGetConsistentIC, m->mem, m->xz, m->xzdot);
    }

    // Re-initialize backward integration
    if (nrx_>0) THROWING(IDAAdjReInit, m->mem);

    // Set the stop time of the integration -- don't integrate past this point
    if (stop_at_end_) setStopTime(m, grid_.back());

    log("IdasInterface::reset", "end");
  }
Exemplo n.º 10
0
  int IdasInterface::lsolveB(IDAMem IDA_mem, N_Vector b, N_Vector weight, N_Vector xzB,
                                    N_Vector xzdotB, N_Vector rrB) {
    try {
      auto m = to_mem(IDA_mem->ida_lmem);
      auto& s = m->self;
      IDAadjMem IDAADJ_mem;
      //IDABMem IDAB_mem;
      int flag;

      // Current time
      double t = IDA_mem->ida_tn; // TODO(Joel): is this correct?
      // Multiple of df_dydot to be added to the matrix
      double cj = IDA_mem->ida_cj;
      double cjratio = IDA_mem->ida_cjratio;

      IDA_mem = (IDAMem) IDA_mem->ida_user_data;

      IDAADJ_mem = IDA_mem->ida_adj_mem;
      //IDAB_mem = IDAADJ_mem->ia_bckpbCrt;

      // Get FORWARD solution from interpolation.
      if (IDAADJ_mem->ia_noInterp==FALSE) {
        flag = IDAADJ_mem->ia_getY(IDA_mem, t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp,
                                   NULL, NULL);
        if (flag != IDA_SUCCESS) casadi_error("Could not interpolate forward states");
      }

      // Accuracy
      double delta = 0.0;

      // Call the preconditioner solve function (which solves the linear system)
      if (psolveB(t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp, xzB, xzdotB,
        rrB, b, b, cj, delta, static_cast<void*>(m), 0)) return 1;

      // Scale the correction to account for change in cj
      if (s.cj_scaling_) {
        if (cjratio != 1.0) N_VScale(2.0/(1.0 + cjratio), b, b);
      }
      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "lsolveB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 11
0
  int IdasInterface::rhsQ(double t, N_Vector xz, N_Vector xzdot, N_Vector rhsQ,
                                 void *user_data) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;
      m->arg[0] = NV_DATA_S(xz);
      m->arg[1] = NV_DATA_S(xz)+s.nx_;
      m->arg[2] = m->p;
      m->arg[3] = &t;
      m->res[0] = NV_DATA_S(rhsQ);
      s.calc_function(m, "quadF");

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "rhsQ failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 12
0
  void IdasInterface::
  advance(IntegratorMemory* mem, double t, double* x, double* z, double* q) const {
    auto m = to_mem(mem);

    casadi_assert_message(t>=grid_.front(), "IdasInterface::integrate(" << t << "): "
                          "Cannot integrate to a time earlier than t0 (" << grid_.front() << ")");
    casadi_assert_message(t<=grid_.back() || !stop_at_end_, "IdasInterface::integrate("
                          << t << "): "
                          "Cannot integrate past a time later than tf (" << grid_.back() << ") "
                          "unless stop_at_end is set to False.");

    // Integrate, unless already at desired time
    double ttol = 1e-9;   // tolerance
    if (fabs(m->t-t)>=ttol) {
      // Integrate forward ...
      if (nrx_>0) { // ... with taping
        THROWING(IDASolveF, m->mem, t, &m->t, m->xz, m->xzdot, IDA_NORMAL, &m->ncheck);
      } else { // ... without taping
        THROWING(IDASolve, m->mem, t, &m->t, m->xz, m->xzdot, IDA_NORMAL);
      }

      // Get quadratures
      if (nq_>0) {
        double tret;
        THROWING(IDAGetQuad, m->mem, &tret, m->q);
      }
    }

    // Set function outputs
    casadi_copy(NV_DATA_S(m->xz), nx_, x);
    casadi_copy(NV_DATA_S(m->xz)+nx_, nz_, z);
    casadi_copy(NV_DATA_S(m->q), nq_, q);

    // Get stats
    THROWING(IDAGetIntegratorStats, m->mem, &m->nsteps, &m->nfevals, &m->nlinsetups,
             &m->netfails, &m->qlast, &m->qcur, &m->hinused,
             &m->hlast, &m->hcur, &m->tcur);

    THROWING(IDAGetNonlinSolvStats, m->mem, &m->nniters, &m->nncfails);

  }
Exemplo n.º 13
0
  int IdasInterface::lsetupB(IDAMem IDA_mem, N_Vector xzB, N_Vector xzdotB, N_Vector respB,
                                     N_Vector vtemp1B, N_Vector vtemp2B, N_Vector vtemp3B) {
    try {
      auto m = to_mem(IDA_mem->ida_lmem);
      //auto& s = m->self;
      IDAadjMem IDAADJ_mem;
      //IDABMem IDAB_mem;

      // Current time
      double t = IDA_mem->ida_tn; // TODO(Joel): is this correct?
      // Multiple of df_dydot to be added to the matrix
      double cj = IDA_mem->ida_cj;

      IDA_mem = static_cast<IDAMem>(IDA_mem->ida_user_data);

      IDAADJ_mem = IDA_mem->ida_adj_mem;
      //IDAB_mem = IDAADJ_mem->ia_bckpbCrt;

      // Get FORWARD solution from interpolation.
      if (IDAADJ_mem->ia_noInterp==FALSE) {
        int flag = IDAADJ_mem->ia_getY(IDA_mem, t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp,
                                   NULL, NULL);
        if (flag != IDA_SUCCESS) casadi_error("Could not interpolate forward states");
      }
      // Call the preconditioner setup function (which sets up the linear solver)
      if (psetupB(t, IDAADJ_mem->ia_yyTmp, IDAADJ_mem->ia_ypTmp,
        xzB, xzdotB, 0, cj, static_cast<void*>(m), vtemp1B, vtemp1B, vtemp3B)) return 1;

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "lsetupB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 14
0
  int IdasInterface::psolveB(double t, N_Vector xz, N_Vector xzdot, N_Vector xzB,
                                    N_Vector xzdotB, N_Vector resvalB, N_Vector rvecB,
                                    N_Vector zvecB, double cjB, double deltaB,
                                    void *user_data, N_Vector tmpB) {
    try {
      auto m = to_mem(user_data);
      auto& s = m->self;

      // Get right-hand sides in m->v1, ordered by sensitivity directions
      double* vx = NV_DATA_S(rvecB);
      double* vz = vx + s.nrx_;
      double* v_it = m->v1;
      for (int d=0; d<=s.ns_; ++d) {
        casadi_copy(vx + d*s.nrx1_, s.nrx1_, v_it);
        v_it += s.nrx1_;
        casadi_copy(vz + d*s.nrz1_, s.nrz1_, v_it);
        v_it += s.nrz1_;
      }

      // Solve for undifferentiated right-hand-side, save to output
      s.linsolB_.solve(m->v1, 1);
      vx = NV_DATA_S(zvecB); // possibly different from rvecB
      vz = vx + s.nrx_;
      casadi_copy(m->v1, s.nrx1_, vx);
      casadi_copy(m->v1 + s.nrx1_, s.nrz1_, vz);

      // Sensitivity equations
      if (s.ns_>0) {
        // Second order correction
        if (s.second_order_correction_) {
          // The outputs will double as seeds for jtimesB
          casadi_fill(vx + s.nrx1_, s.nrx_ - s.nrx1_, 0.);
          casadi_fill(vz + s.nrz1_, s.nrz_ - s.nrz1_, 0.);

          // Get second-order-correction, save to m->v2
          m->arg[0] = &t; // t
          m->arg[1] = NV_DATA_S(xz); // x
          m->arg[2] = NV_DATA_S(xz)+s.nx_; // z
          m->arg[3] = m->p; // p
          m->arg[4] = NV_DATA_S(xzB); // rx
          m->arg[5] = NV_DATA_S(xzB)+s.nrx_; // rz
          m->arg[6] = m->rp; // rp
          m->arg[7] = vx; // fwd:rx
          m->arg[8] = vz; // fwd:rz
          m->res[0] = m->v2; // fwd:rode
          m->res[1] = m->v2 + s.nrx_; // fwd:ralg
          s.calc_function(m, "jtimesB");

          // Subtract m->v2 (reordered) from m->v1
          v_it = m->v1 + s.nrx1_ + s.nrz1_;
          for (int d=1; d<=s.ns_; ++d) {
            casadi_axpy(s.nrx1_, -1., m->v2 + d*s.nrx1_, v_it);
            v_it += s.nrx1_;
            casadi_axpy(s.nrz1_, -1., m->v2 + s.nrx_ + d*s.nrz1_, v_it);
            v_it += s.nrz1_;
          }
        }

        // Solve for sensitivity right-hand-sides
        s.linsolB_.solve(m->v1 + s.nrx1_ + s.nrz1_, s.ns_);

        // Save to output, reordered
        v_it = m->v1 + s.nrx1_ + s.nrz1_;
        for (int d=1; d<=s.ns_; ++d) {
          casadi_copy(v_it, s.nrx1_, vx + d*s.nrx1_);
          v_it += s.nrx1_;
          casadi_copy(v_it, s.nrz1_, vz + d*s.nrz1_);
          v_it += s.nrz1_;
        }
      }

      return 0;
    } catch(int flag) { // recoverable error
      return flag;
    } catch(exception& e) { // non-recoverable error
      userOut<true, PL_WARN>() << "psolveB failed: " << e.what() << endl;
      return -1;
    }
  }
Exemplo n.º 15
0
 void IdasInterface::setStopTime(IntegratorMemory* mem, double tf) const {
   // Set the stop time of the integration -- don't integrate past this point
   auto m = to_mem(mem);
   //auto& s = m->self;
   THROWING(IDASetStopTime, m->mem, tf);
 }
Exemplo n.º 16
0
  void IdasInterface::resetB(IntegratorMemory* mem, double t, const double* rx,
                             const double* rz, const double* rp) const {
    log("IdasInterface::resetB", "begin");
    auto m = to_mem(mem);

    // Reset the base classes
    SundialsInterface::resetB(mem, t, rx, rz, rp);

    if (m->first_callB) {
      // Create backward problem
      THROWING(IDACreateB, m->mem, &m->whichB);
      THROWING(IDAInitB, m->mem, m->whichB, resB, grid_.back(), m->rxz, m->rxzdot);
      THROWING(IDASStolerancesB, m->mem, m->whichB, reltol_, abstol_);
      THROWING(IDASetUserDataB, m->mem, m->whichB, m);
      THROWING(IDASetMaxNumStepsB, m->mem, m->whichB, max_num_steps_);

      // Set algebraic components
      N_Vector id = N_VNew_Serial(nrx_+nrz_);
      fill_n(NV_DATA_S(id), nrx_, 1);
      fill_n(NV_DATA_S(id)+nrx_, nrz_, 0);
      THROWING(IDASetIdB, m->mem, m->whichB, id);
      N_VDestroy_Serial(id);

      // attach linear solver
      if (newton_scheme_==SD_DIRECT) {
        // Direct scheme
        IDAMem IDA_mem = IDAMem(m->mem);
        IDAadjMem IDAADJ_mem = IDA_mem->ida_adj_mem;
        IDABMem IDAB_mem = IDAADJ_mem->IDAB_mem;
        IDAB_mem->ida_lmem   = m;
        IDAB_mem->IDA_mem->ida_lmem = m;
        IDAB_mem->IDA_mem->ida_lsetup = lsetupB;
        IDAB_mem->IDA_mem->ida_lsolve = lsolveB;
        IDAB_mem->IDA_mem->ida_setupNonNull = TRUE;
      } else {
        // Iterative scheme
        switch (newton_scheme_) {
        case SD_DIRECT: casadi_assert(0);
        case SD_GMRES: THROWING(IDASpgmrB, m->mem, m->whichB, max_krylov_); break;
        case SD_BCGSTAB: THROWING(IDASpbcgB, m->mem, m->whichB, max_krylov_); break;
        case SD_TFQMR: THROWING(IDASptfqmrB, m->mem, m->whichB, max_krylov_); break;
        }
        THROWING(IDASpilsSetJacTimesVecFnB, m->mem, m->whichB, jtimesB);
        if (use_precon_) THROWING(IDASpilsSetPreconditionerB, m->mem, m->whichB, psetupB, psolveB);
      }

      // Quadratures for the adjoint problem
      THROWING(IDAQuadInitB, m->mem, m->whichB, rhsQB, m->rq);
      if (quad_err_con_) {
        THROWING(IDASetQuadErrConB, m->mem, m->whichB, true);
        THROWING(IDAQuadSStolerancesB, m->mem, m->whichB, reltol_, abstol_);
      }

      // Mark initialized
      m->first_callB = false;
    } else {
      // Re-initialize
      THROWING(IDAReInitB, m->mem, m->whichB, grid_.back(), m->rxz, m->rxzdot);
      if (nrq_>0) {
        // Workaround (bug in SUNDIALS)
        // THROWING(IDAQuadReInitB, m->mem, m->whichB[dir], m->rq[dir]);
        void* memB = IDAGetAdjIDABmem(m->mem, m->whichB);
        THROWING(IDAQuadReInit, memB, m->rq);
      }
    }

    // Correct initial values for the integration if necessary
    if (calc_icB_) {
      THROWING(IDACalcICB, m->mem, m->whichB, grid_.front(), m->xz, m->xzdot);
      THROWING(IDAGetConsistentICB, m->mem, m->whichB, m->rxz, m->rxzdot);
    }

    log("IdasInterface::resetB", "end");

  }
Exemplo n.º 17
0
  void IdasInterface::init_memory(void* mem) const {
    SundialsInterface::init_memory(mem);
    auto m = to_mem(mem);

    // Create IDAS memory block
    m->mem = IDACreate();
    casadi_assert_message(m->mem!=0, "IDACreate: Creation failed");

    // Set error handler function
    THROWING(IDASetErrHandlerFn, m->mem, ehfun, m);

    // Set user data
    THROWING(IDASetUserData, m->mem, m);

    // Allocate n-vectors for ivp
    m->xzdot = N_VNew_Serial(nx_+nz_);

    // Initialize Idas
    double t0 = 0;
    N_VConst(0.0, m->xz);
    N_VConst(0.0, m->xzdot);
    IDAInit(m->mem, res, t0, m->xz, m->xzdot);
    log("IdasInterface::init", "IDA initialized");

    // Include algebraic variables in error testing
    THROWING(IDASetSuppressAlg, m->mem, suppress_algebraic_);

    // Maxinum order for the multistep method
    THROWING(IDASetMaxOrd, m->mem, max_multistep_order_);

    // Set maximum step size
    THROWING(IDASetMaxStep, m->mem, max_step_size_);

    // Initial step size
    if (step0_) THROWING(IDASetInitStep, m->mem, step0_);

    // Maximum order of method
    if (max_order_) THROWING(IDASetMaxOrd, m->mem, max_order_);

    // Coeff. in the nonlinear convergence test
    if (nonlin_conv_coeff_) THROWING(IDASetNonlinConvCoef, m->mem, nonlin_conv_coeff_);

    if (!abstolv_.empty()) {
      // Vector absolute tolerances
      N_Vector nv_abstol = N_VNew_Serial(abstolv_.size());
      copy(abstolv_.begin(), abstolv_.end(), NV_DATA_S(nv_abstol));
      THROWING(IDASVtolerances, m->mem, reltol_, nv_abstol);
      N_VDestroy_Serial(nv_abstol);
    } else {
      // Scalar absolute tolerances
      THROWING(IDASStolerances, m->mem, reltol_, abstol_);
    }

    // Maximum number of steps
    THROWING(IDASetMaxNumSteps, m->mem, max_num_steps_);

    // Set algebraic components
    N_Vector id = N_VNew_Serial(nx_+nz_);
    fill_n(NV_DATA_S(id), nx_, 1);
    fill_n(NV_DATA_S(id)+nx_, nz_, 0);

    // Pass this information to IDAS
    THROWING(IDASetId, m->mem, id);

    // Delete the allocated memory
    N_VDestroy_Serial(id);

    // attach a linear solver
    if (newton_scheme_==SD_DIRECT) {
      // Direct scheme
      IDAMem IDA_mem = IDAMem(m->mem);
      IDA_mem->ida_lmem   = m;
      IDA_mem->ida_lsetup = lsetup;
      IDA_mem->ida_lsolve = lsolve;
      IDA_mem->ida_setupNonNull = TRUE;
    } else {
      // Iterative scheme
      switch (newton_scheme_) {
      case SD_DIRECT: casadi_assert(0);
      case SD_GMRES: THROWING(IDASpgmr, m->mem, max_krylov_); break;
      case SD_BCGSTAB: THROWING(IDASpbcg, m->mem, max_krylov_); break;
      case SD_TFQMR: THROWING(IDASptfqmr, m->mem, max_krylov_); break;
      }
      THROWING(IDASpilsSetJacTimesVecFn, m->mem, jtimes);
      if (use_precon_) THROWING(IDASpilsSetPreconditioner, m->mem, psetup, psolve);
    }

    // Quadrature equations
    if (nq_>0) {

      // Initialize quadratures in IDAS
      THROWING(IDAQuadInit, m->mem, rhsQ, m->q);

      // Should the quadrature errors be used for step size control?
      if (quad_err_con_) {
        THROWING(IDASetQuadErrCon, m->mem, true);

        // Quadrature error tolerances
        // TODO(Joel): vector absolute tolerances
        THROWING(IDAQuadSStolerances, m->mem, reltol_, abstol_);
      }
    }

    log("IdasInterface::init", "attached linear solver");

    // Adjoint sensitivity problem
    if (nrx_>0) {
      m->rxzdot = N_VNew_Serial(nrx_+nrz_);
      N_VConst(0.0, m->rxz);
      N_VConst(0.0, m->rxzdot);
    }
    log("IdasInterface::init", "initialized adjoint sensitivities");

    // Initialize adjoint sensitivities
    if (nrx_>0) {
      int interpType = interp_==SD_HERMITE ? IDA_HERMITE : IDA_POLYNOMIAL;
      THROWING(IDAAdjInit, m->mem, steps_per_checkpoint_, interpType);
    }

    m->first_callB = true;
  }