def optimise_positions(self, fmax=0.01, use_precon=None, use_armijo=None): """ Relax atoms positions with the fixed cell to a given force threshold """ if use_precon is None: use_precon = self.parameters.use_precon if use_armijo is None: use_armijo = self.parameters.use_armijo if use_precon: precon = Exp(A=3, use_pyamg=False) else: precon = None if self.parameters.optimizer == 'BFGS': relax = BFGS(self.atoms) elif self.parameters.optimizer == 'FIRE': relax = PreconFIRE(self.atoms, precon=precon) elif self.parameters.optimizer == 'ase-FIRE': relax = ASEFIRE(self.atoms) elif self.parameters.optimizer == 'LBFGS': relax = PreconLBFGS(self.atoms, precon=precon, use_armijo=use_armijo) elif self.parameters.optimizer == 'ase-LBFGS': relax = ASELBFGS(self.atoms) else: parprint("ERROR: unknown optimizer {}. " "Reverting to BFGS".format(self.parameters.optimizer)) relax = BFGS(self.atoms) name = self.atoms.get_chemical_formula() relax.attach( lambda: self.atoms.calc.write(name + '_relax.gpw', mode='all')) relax.attach(lambda: write_atat_input(self.atoms, 'str_last.out')) relax.run(fmax=fmax, steps=100) if not relax.converged(): relax = ASELBFGS(self.atoms) relax.run(fmax=fmax, steps=100) if not relax.converged(): max_force = self.atoms.get_forces() max_force = np.sqrt((max_force**2).sum(axis=1).max()) print('WARNING: optimisation not converged.' + ' Maximum force: %.4f' % max_force)