Example #1
0
def ode_julia_naive(coords,
                    pot,
                    tol=1e-4,
                    nsteps=20000,
                    convergence_check=None,
                    solver_type=de.CVODE_BDF(),
                    rtol=1e-4,
                    atol=1e-4,
                    **kwargs):
    class feval_pot:
        """ wrapper class that interfaces base potential to functions for ode solver
        """
        def __init__(self):
            self.nfev = 0
            self.nhev = 0

        def get_negative_grad(self, x, p, t):
            """
            negative grad is f(u, p, t)
            """
            self.nfev += 1
            return -pot.getEnergyGradient(x.copy())[1]

        def get_energy_gradient(self, x):
            self.nfev += 1
            return pot.getEnergyGradient(x.copy())

        def get_jacobian(self, x, p, t):
            self.nhev += 1
            return -pot.getEnergyGradientHessian(x.copy())[2]

    function_evaluate_pot = feval_pot()
    converged = False
    n = 0
    if convergence_check == None:
        convergence_check = lambda g: np.linalg.norm(g) < tol
    # odefunc = de.ODEFunction(function_evaluate_pot.get_negative_grad, function_evaluate_pot.get_jacobian)
    # initialize ode problem
    tspan = (0, 10000.0)
    f_bound = de.ODEFunction(function_evaluate_pot.get_negative_grad)
    # f_free = de.ODEFunction(get_negative_grad,jac = get_jacobian)
    prob = de.ODEProblem(f_bound, coords, tspan)
    solver = Main.eval("CVODE_BDF(linear_solver=:GMRES)")
    integrator = de.init(prob, solver, reltol=rtol, abstol=atol)
    x_ = np.full(len(coords), np.nan)
    while not converged and n < nsteps:
        xold = x_
        de.step_b(integrator)
        x_ = integrator.u
        n += 1
        converged = convergence_check(de.get_du(integrator))
    res = Result()
    res.coords = x_
    res.energy = pot.getEnergy(x_)
    res.grad = 0
    res.nfev = function_evaluate_pot.nfev
    res.nsteps = n
    res.nhev = function_evaluate_pot.nhev
    res.success = converged
    # res.nhev = function_evaluate_pot.nhev
    return res