def METHOD_NAME(self, maxit=100, maxerr=1e-11, dampfactor=1,
          printing=False, callback=None, linesearch=False,
          printenergy=False, print_wrong_direction=False):
    numit = 0
    err = 1.
    a, u, w, r,uh = self.a, self.u, self.w, self.r, self.uh
    for it in range(maxit):
        numit += 1
        if printing:
            print("Newton iteration ", it)
            if printenergy:
                print("Energy: ", a.Energy(u.vec))
        a.AssembleLinearization(u.vec)
        a.Apply(u.vec, r)
        self._UpdateInverse()
        if self.rhs is not None:
            r.data -= self.rhs.vec
        if a.condense:
            r.data += a.harmonic_extension_trans * r
            w.data = self.inv * r
            w.data += a.harmonic_extension * w
            w.data += a.inner_solve * r
        else:
            w.data = self.inv * r
        err2 = InnerProduct(w,r)
        if print_wrong_direction:
            if err2 < 0:
                print("wrong direction")
        err = sqrt(abs(err2))
        if printing:
            print("err = ", err)
        tau = min(1, numit*dampfactor)
        if linesearch:
            uh.data = u.vec - tau*w
            energy = a.Energy(u.vec)
            while a.Energy(uh) > energy+(max(1e-14*abs(energy),maxerr)) and tau > 1e-10:
                tau *= 0.5
                uh.data = u.vec - tau * w
                if printing:
                    print ("tau = ", tau)
                    print ("energy uh = ", a.Energy(uh))
            u.vec.data = uh
        else:
            u.vec.data -= tau * w
        if callback is not None:
            callback(it, err)
        if abs(err) < maxerr: break
    else:
        print("Warning: Newton might not converge! Error = ", err)
        return (-1,numit)
    return (0,numit)