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