コード例 #1
0
    def test_newton(self):
        # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        class QuadraticModelEvaluator:
            '''Simple model evalator for f(x) = x^2 - 2.'''
            def __init__(self):
                self.dtype = float

            def compute_f(self, x):
                return x**2 - 2.0

            def get_jacobian(self, x0):
                return 2.0 * x0

            def get_preconditioner(self, x0):
                return None

            def get_preconditioner_inverse(self, x0):
                return None

            def inner_product(self, x, y):
                return np.dot(x.T.conj(), y)

        # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        qmodeleval = QuadraticModelEvaluator()
        x0 = np.array([[1.0]])
        tol = 1.0e-10
        out = nm.newton(x0, qmodeleval, nonlinear_tol=tol)
        self.assertEqual(out['info'], 0)
        self.assertAlmostEqual(out['x'][0, 0], np.sqrt(2.0), delta=tol)
コード例 #2
0
ファイル: newton.py プロジェクト: nschloe/pynosh
def my_newton(args, modeleval, psi0, g, mu, yaml_emitter=None, debug=True):
    """Solve with Newton.
    """

    recycling_solver_kwargs = {
        "explicit_residual": args.resexp,
        "maxiter": 200
    }
    if args.krylov_method == "cg":
        RecyclingSolver = krypy.recycling.RecyclingCg
    elif args.krylov_method == "minres":
        RecyclingSolver = krypy.recycling.RecyclingMinres
    elif args.krylov_method == "minresfo":
        RecyclingSolver = krypy.recycling.RecyclingMinres
        recycling_solver_kwargs["ortho"] = "mgs"
    elif args.krylov_method == "gmres":
        RecyclingSolver = krypy.recycling.RecyclingGmres
    else:
        raise ValueError("Unknown Krylov solver "
                         "%s"
                         "." % args.krylov_method)

    def vector_factory_generator(x):
        """Generates the vector factory with i*x if requested."""
        if not args.defl_include_ix and args.defl_num_ritz_vectors == 0:
            # no deflation
            return None
        else:
            ritz_factory = krypy.recycling.factories.RitzFactorySimple(
                n_vectors=args.defl_num_ritz_vectors, which="sm")
            if args.defl_include_ix:
                return krypy.recycling.factories.UnionFactory(
                    [ritz_factory, IxFactory(x)])
            return ritz_factory

    # perform newton iteration
    yaml_emitter.add_key("Newton results")
    newton_out = nm.newton(
        psi0,
        modeleval,
        RecyclingSolver=RecyclingSolver,
        recycling_solver_kwargs=recycling_solver_kwargs,
        vector_factory_generator=vector_factory_generator,
        nonlinear_tol=1.0e-10,
        eta0=args.eta,
        forcing_term="constant",
        compute_f_extra_args={
            "g": g,
            "mu": mu
        },
        debug=debug,
        yaml_emitter=yaml_emitter,
        newton_maxiter=30,
    )
    yaml_emitter.add_comment("done.")
    # assert( newton_out['info'] == 0 )
    return newton_out
コード例 #3
0
def my_newton(args, modeleval, psi0, g, mu, yaml_emitter=None, debug=True):
    '''Solve with Newton.
    '''

    recycling_solver_kwargs = {
        'explicit_residual': args.resexp,
        'maxiter': 200
        }
    if args.krylov_method == 'cg':
        RecyclingSolver = krypy.recycling.RecyclingCg
    elif args.krylov_method == 'minres':
        RecyclingSolver = krypy.recycling.RecyclingMinres
    elif args.krylov_method == 'minresfo':
        RecyclingSolver = krypy.recycling.RecyclingMinres
        recycling_solver_kwargs['ortho'] = 'mgs'
    elif args.krylov_method == 'gmres':
        RecyclingSolver = krypy.recycling.RecyclingGmres
    else:
        raise ValueError('Unknown Krylov solver ''%s''.' % args.krylov_method)

    def vector_factory_generator(x):
        '''Generates the vector factory with i*x if requested.'''
        if not args.defl_include_ix and args.defl_num_ritz_vectors == 0:
            # no deflation
            return None
        else:
            ritz_factory = krypy.recycling.factories.RitzFactorySimple(
                n_vectors=args.defl_num_ritz_vectors,
                which='sm'
                )
            if args.defl_include_ix:
                return krypy.recycling.factories.UnionFactory(
                    [ritz_factory, IxFactory(x)])
            return ritz_factory

    # perform newton iteration
    yaml_emitter.add_key('Newton results')
    newton_out = nm.newton(psi0,
                           modeleval,
                           RecyclingSolver=RecyclingSolver,
                           recycling_solver_kwargs=recycling_solver_kwargs,
                           vector_factory_generator=vector_factory_generator,
                           nonlinear_tol=1.0e-10,
                           eta0=args.eta,
                           forcing_term='constant',
                           compute_f_extra_args={'g': g, 'mu': mu},
                           debug=debug,
                           yaml_emitter=yaml_emitter,
                           newton_maxiter=30
                           )
    yaml_emitter.add_comment('done.')
    #assert( newton_out['info'] == 0 )
    return newton_out
コード例 #4
0
def _main():
    """Main function.
    """
    args = _parse_input_arguments()

    # read the mesh
    print("Reading the mesh...", end=" ")
    pynoshmesh, psi, A, field_data = mesh.mesh_io.read_mesh(args.filename)
    print("done.")

    # build the model evaluator
    mu = 8.0e-2
    ginla_modelval = gm.ModelEvaluator(pynoshmesh, A, mu)

    # initial guess
    num_nodes = len(pynoshmesh.nodes)
    psi0 = np.ones((num_nodes, 1), dtype=complex)

    nums_deflation_vectors = list(range(50))
    last_resvecs = []
    for num_deflation_vectors in nums_deflation_vectors:
        print(
            (
                "Performing Newton iteration with %d deflation vectors..."
                % num_deflation_vectors
            )
        )
        # perform newton iteration
        newton_out = nm.newton(
            psi0,
            ginla_modelval,
            linear_solver=nm.minres,
            nonlinear_tol=1.0e-10,
            eta0=1.0e-13,
            forcing_term="constant",
            use_preconditioner=True,
            deflate_ix=True,
            num_deflation_vectors=num_deflation_vectors,
        )
        print(" done.")
        assert newton_out[1] == 0, "Newton did not converge."

        last_resvecs.append(newton_out[3][-1])

    multiplot_data_series(last_resvecs)
    pp.title(
        "Residual curves for the last Newton step for %s. Darker=More deflation vectors."
        % args.filename
    )
    pp.show()
    # matplotlib2tikz.save('w-defl.tex')
    return
コード例 #5
0
ファイル: newton.py プロジェクト: nschloe/pynosh
def my_newton(args, modeleval, psi0, g, mu, yaml_emitter=None, debug=True):
    """Solve with Newton.
    """

    recycling_solver_kwargs = {"explicit_residual": args.resexp, "maxiter": 200}
    if args.krylov_method == "cg":
        RecyclingSolver = krypy.recycling.RecyclingCg
    elif args.krylov_method == "minres":
        RecyclingSolver = krypy.recycling.RecyclingMinres
    elif args.krylov_method == "minresfo":
        RecyclingSolver = krypy.recycling.RecyclingMinres
        recycling_solver_kwargs["ortho"] = "mgs"
    elif args.krylov_method == "gmres":
        RecyclingSolver = krypy.recycling.RecyclingGmres
    else:
        raise ValueError("Unknown Krylov solver " "%s" "." % args.krylov_method)

    def vector_factory_generator(x):
        """Generates the vector factory with i*x if requested."""
        if not args.defl_include_ix and args.defl_num_ritz_vectors == 0:
            # no deflation
            return None
        else:
            ritz_factory = krypy.recycling.factories.RitzFactorySimple(
                n_vectors=args.defl_num_ritz_vectors, which="sm"
            )
            if args.defl_include_ix:
                return krypy.recycling.factories.UnionFactory(
                    [ritz_factory, IxFactory(x)]
                )
            return ritz_factory

    # perform newton iteration
    yaml_emitter.add_key("Newton results")
    newton_out = nm.newton(
        psi0,
        modeleval,
        RecyclingSolver=RecyclingSolver,
        recycling_solver_kwargs=recycling_solver_kwargs,
        vector_factory_generator=vector_factory_generator,
        nonlinear_tol=1.0e-10,
        eta0=args.eta,
        forcing_term="constant",
        compute_f_extra_args={"g": g, "mu": mu},
        debug=debug,
        yaml_emitter=yaml_emitter,
        newton_maxiter=30,
    )
    yaml_emitter.add_comment("done.")
    # assert( newton_out['info'] == 0 )
    return newton_out
コード例 #6
0
def _main():
    """Main function.
    """
    args = _parse_input_arguments()

    # read the mesh
    print("Reading the mesh...", end=" ")
    pynoshmesh, psi, A, field_data = mesh.mesh_io.read_mesh(args.filename)
    print("done.")

    # build the model evaluator
    mu = 8.0e-2
    ginla_modelval = gm.ModelEvaluator(pynoshmesh, A, mu)

    # initial guess
    num_nodes = len(pynoshmesh.nodes)
    psi0 = np.ones((num_nodes, 1), dtype=complex)

    nums_deflation_vectors = list(range(50))
    last_resvecs = []
    for num_deflation_vectors in nums_deflation_vectors:
        print(("Performing Newton iteration with %d deflation vectors..." %
               num_deflation_vectors))
        # perform newton iteration
        newton_out = nm.newton(
            psi0,
            ginla_modelval,
            linear_solver=nm.minres,
            nonlinear_tol=1.0e-10,
            eta0=1.0e-13,
            forcing_term="constant",
            use_preconditioner=True,
            deflate_ix=True,
            num_deflation_vectors=num_deflation_vectors,
        )
        print(" done.")
        assert newton_out[1] == 0, "Newton did not converge."

        last_resvecs.append(newton_out[3][-1])

    multiplot_data_series(last_resvecs)
    pp.title(
        "Residual curves for the last Newton step for %s. Darker=More deflation vectors."
        % args.filename)
    pp.show()
    # matplotlib2tikz.save('w-defl.tex')
    return
コード例 #7
0
 def test_newton(self):
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     class QuadraticModelEvaluator:
         '''Simple model evalator for f(x) = x^2 - 2.'''
         def __init__(self):
             self.dtype = float
         def compute_f(self, x):
             return x**2 - 2.0
         def get_jacobian(self, x0):
             return 2.0 * x0
         def get_preconditioner(self, x0):
             return None
         def get_preconditioner_inverse(self, x0):
             return None
         def inner_product(self, x, y):
             return np.dot(x.T.conj(), y)
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     qmodeleval = QuadraticModelEvaluator()
     x0 = np.array( [[1.0]] )
     tol = 1.0e-10
     out = nm.newton(x0, qmodeleval, nonlinear_tol=tol)
     self.assertEqual(out['info'], 0)
     self.assertAlmostEqual(out['x'][0,0], np.sqrt(2.0), delta=tol)
コード例 #8
0
def find_beautiful_states(modeleval,
                          param_name,
                          param_range,
                          forcing_term,
                          save_doubles=True
                          ):
    '''Loop through a set of parameters/initial states and try to find
    starting points that (quickly) lead to "interesting looking" solutions.
    Such solutions are filtered out only by their energy at the moment.
    '''

    # Define search space.
    # Don't use Mu=0 as the preconditioner is singular for mu=0, psi=0.
    Alpha = np.linspace(0.2, 1.0, 5)
    Frequencies = [0.0, 0.5, 1.0, 2.0]

    # Compile the search space.
    # If all nodes sit in x-y-plane, the frequency loop in z-direction can be
    # omitted.
    if modeleval.mesh.node_coords.shape[1] == 2:
        search_space_k = [(a, b) for a in Frequencies for b in Frequencies]
    elif modeleval.mesh.node_coords.shape[1] == 3:
        search_space_k = [(a, b, c)
                          for a in Frequencies
                          for b in Frequencies
                          for c in Frequencies
                          ]
    search_space = [(a, k) for a in reversed(Alpha) for k in search_space_k]

    solution_id = 0
    for p in param_range:
        # Reset the solutions each time the problem parameters change.
        found_solutions = []
        # Loop over initial states.
        for alpha, k in search_space:
            modeleval.set_parameter(param_name, p)
            print '%s = %g; alpha = %g; k = %s' % (param_name, p, alpha, k,)
            # Set the intitial guess for Newton.
            if len(k) == 2:
                psi0 = alpha \
                    * np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0]) \
                    * np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1]) \
                    + 1j * 0
            elif len(k) == 3:
                psi0 = alpha \
                    * np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0]) \
                    * np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1]) \
                    * np.cos(k[2] * np.pi * modeleval.mesh.node_coords[:, 2]) \
                    + 1j * 0
            else:
                raise RuntimeError('Illegal k.')

            print 'Performing Newton iteration...'
            linsolve_maxiter = 500  # 2*len(psi0)
            # perform newton iteration
            newton_out = nm.newton(psi0[:, None],
                                   modeleval,
                                   linear_solver=nm.minres,
                                   linear_solver_maxiter=linsolve_maxiter,
                                   linear_solver_extra_args={},
                                   nonlinear_tol=1.0e-10,
                                   forcing_term=forcing_term,
                                   eta0=1.0e-10,
                                   use_preconditioner=True,
                                   deflation_generators=[lambda x: 1j*x],
                                   num_deflation_vectors=0,
                                   debug=True,
                                   newton_maxiter=50
                                   )
            print ' done.'

            num_krylov_iters = \
                [len(resvec) for resvec in newton_out['linear relresvecs']]
            print 'Num Krylov iterations:', num_krylov_iters
            print 'Newton residuals:', newton_out['Newton residuals']
            if newton_out['info'] == 0:
                num_newton_iters = len(newton_out['linear relresvecs'])
                psi = newton_out['x']
                # Use the energy as a measure for ruling out boring states
                # such as psi==0 or psi==1 overall.
                energy = modeleval.energy(psi)
                print 'Energy of solution state: %g.' % energy
                if energy > -0.999 and energy < -0.001:
                    # Store the file as VTU such that ParaView can loop through
                    # and display them at once. For this, also be sure to keep
                    # the file name in the format
                    # 'interesting<-krylovfails03>-01414.vtu'.
                    filename = 'interesting-'
                    num_krylov_fails = num_krylov_iters.count(linsolve_maxiter)
                    if num_krylov_fails > 0:
                        filename += 'krylovfails%s-' \
                            % repr(num_krylov_fails).rjust(2, '0')
                    filename += repr(num_newton_iters).rjust(2, '0') \
                        + repr(solution_id).rjust(3, '0') \
                        + '.vtu'
                    print('Interesting state found for %s=%g!'
                          % (param_name, p),
                          )
                    # Check if we already stored that one.
                    already_found = False
                    for state in found_solutions:
                        # Synchronize the complex argument.
                        state *= np.exp(1j *
                            (np.angle(psi[0]) - np.angle(state[0]))
                            )
                        diff = psi - state
                        if modeleval.inner_product(diff, diff) < 1.0e-10:
                            already_found = True
                            break
                    if already_found and not save_doubles:
                        print '-- But we already have that one.'
                    else:
                        found_solutions.append(psi)
                        print 'Storing in %s.' % filename
                        if len(k) == 2:
                            function_string = 'psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y)' % (alpha, k[0], k[1])
                        elif len(k) == 3:
                            function_string = 'psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y) * cos(%g*pi*z)' % (alpha, k[0], k[1], k[2])
                        else:
                            raise RuntimeError('Illegal k.')
                        modeleval.mesh.write(
                            filename,
                            point_data={'psi': psi,
                                        'psi0': psi0,
                                        'V': modeleval._V,
                                        'A': modeleval._raw_magnetic_vector_potential
                                        },
                            field_data={'g': modeleval._g,
                                        'mu': modeleval.mu,
                                        'psi0(X)': function_string
                                        }
                            )
                        solution_id += 1
            print
    return
コード例 #9
0
def find_beautiful_states(modeleval,
                          mu_range,
                          forcing_term,
                          save_doubles=True):
    """Loop through a set of parameters/initial states and try to find
    starting points that (quickly) lead to "interesting looking" solutions.
    Such solutions are filtered out only by their energy at the moment.
    """

    # Define search space.
    # Don't use Mu=0 as the preconditioner is singular for mu=0, psi=0.
    Alpha = np.linspace(0.2, 1.0, 5)
    Frequencies = [0.0, 0.5, 1.0, 2.0]

    # Compile the search space.
    # If all nodes sit in x-y-plane, the frequency loop in z-direction can be omitted.
    if modeleval.mesh.node_coords.shape[1] == 2 or np.all(
            np.abs(modeleval.mesh.node_coords[:, 2]) < 1.0e-13):
        search_space_k = [(a, b) for a in Frequencies for b in Frequencies]
    elif modeleval.mesh.node_coords.shape[1] == 3:
        search_space_k = [(a, b, c) for a in Frequencies for b in Frequencies
                          for c in Frequencies]
    search_space = [(a, k) for a in reversed(Alpha) for k in search_space_k]

    solution_id = 0
    for mu in mu_range:
        # Reset the solutions each time the problem parameters change.
        found_solutions = []
        # Loop over initial states.
        for alpha, k in search_space:
            print("mu = {}; alpha = {}; k = {}".format(mu, alpha, k))
            # Set the intitial guess for Newton.
            if len(k) == 2:
                psi0 = (
                    alpha *
                    np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0]) *
                    np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1]) +
                    1j * 0)
            elif len(k) == 3:
                psi0 = (
                    alpha *
                    np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0]) *
                    np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1]) *
                    np.cos(k[2] * np.pi * modeleval.mesh.node_coords[:, 2]) +
                    1j * 0)
            else:
                raise RuntimeError("Illegal k.")

            print("Performing Newton iteration...")
            linsolve_maxiter = 500  # 2*len(psi0)
            try:
                newton_out = nm.newton(
                    psi0[:, None],
                    modeleval,
                    nonlinear_tol=1.0e-10,
                    newton_maxiter=50,
                    compute_f_extra_args={
                        "mu": mu,
                        "g": 1.0
                    },
                    eta0=1.0e-10,
                    forcing_term=forcing_term,
                )
            except krypy.utils.ConvergenceError:
                print("Krylov convergence failure. Skip.\n")
                continue
            print(" done.")

            num_krylov_iters = [
                len(resvec) for resvec in newton_out["linear relresvecs"]
            ]
            print("Num Krylov iterations:", num_krylov_iters)
            print("Newton residuals:", newton_out["Newton residuals"])
            if newton_out["info"] == 0:
                num_newton_iters = len(newton_out["linear relresvecs"])
                psi = newton_out["x"]
                # Use the energy as a measure for ruling out boring states such as
                # psi==0 or psi==1 overall.
                energy = modeleval.energy(psi)
                print("Energy of solution state: %g." % energy)
                if energy > -0.999 and energy < -0.001:
                    # Store the file as VTU such that ParaView can loop through and
                    # display them at once. For this, also be sure to keep the file name
                    # in the format 'interesting<-krylovfails03>-01414.vtu'.
                    filename = "interesting-"
                    num_krylov_fails = num_krylov_iters.count(linsolve_maxiter)
                    if num_krylov_fails > 0:
                        filename += "krylovfails{:02d}-".format(
                            num_krylov_fails)
                    filename += "{:02d}{:03d}.vtu".format(
                        num_newton_iters, solution_id)
                    print("Interesting state found for mu={}!".format(mu))
                    # Check if we already stored that one.
                    already_found = False
                    for state in found_solutions:
                        # Synchronize the complex argument.
                        state *= np.exp(
                            1j * (np.angle(psi[0]) - np.angle(state[0])))
                        diff = psi - state
                        if modeleval.inner_product(diff, diff) < 1.0e-10:
                            already_found = True
                            break
                    if already_found and not save_doubles:
                        print("-- But we already have that one.")
                    else:
                        found_solutions.append(psi)
                        print("Storing in {}.".format(filename))
                        # if len(k) == 2:
                        #     function_string = (
                        #         "psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y)"
                        #         % (alpha, k[0], k[1])
                        #     )
                        # elif len(k) == 3:
                        #     function_string = (
                        #         "psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y) * cos(%g*pi*z)"
                        #         % (alpha, k[0], k[1], k[2])
                        #     )
                        # else:
                        #     raise RuntimeError("Illegal k.")
                        modeleval.mesh.write(
                            filename,
                            point_data={
                                "psi": np.column_stack([psi.real, psi.imag]),
                                "psi0": np.column_stack([psi0.real,
                                                         psi0.imag]),
                                "V": modeleval._V,
                                "A": modeleval._raw_magnetic_vector_potential,
                            },
                            field_data={
                                "g": np.array(1.0),
                                "mu": np.array(mu),
                                # "psi0(X)": function_string,
                            },
                        )
                        solution_id += 1
            print()
    return
コード例 #10
0
def find_beautiful_states(modeleval, mu_range, forcing_term, save_doubles=True):
    """Loop through a set of parameters/initial states and try to find
    starting points that (quickly) lead to "interesting looking" solutions.
    Such solutions are filtered out only by their energy at the moment.
    """

    # Define search space.
    # Don't use Mu=0 as the preconditioner is singular for mu=0, psi=0.
    Alpha = np.linspace(0.2, 1.0, 5)
    Frequencies = [0.0, 0.5, 1.0, 2.0]

    # Compile the search space.
    # If all nodes sit in x-y-plane, the frequency loop in z-direction can be omitted.
    if modeleval.mesh.node_coords.shape[1] == 2 or np.all(np.abs(modeleval.mesh.node_coords[:, 2]) < 1.0e-13):
        search_space_k = [(a, b) for a in Frequencies for b in Frequencies]
    elif modeleval.mesh.node_coords.shape[1] == 3:
        search_space_k = [
            (a, b, c) for a in Frequencies for b in Frequencies for c in Frequencies
        ]
    search_space = [(a, k) for a in reversed(Alpha) for k in search_space_k]

    solution_id = 0
    for mu in mu_range:
        # Reset the solutions each time the problem parameters change.
        found_solutions = []
        # Loop over initial states.
        for alpha, k in search_space:
            print("mu = {}; alpha = {}; k = {}".format(mu, alpha, k))
            # Set the intitial guess for Newton.
            if len(k) == 2:
                psi0 = (
                    alpha
                    * np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0])
                    * np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1])
                    + 1j * 0
                )
            elif len(k) == 3:
                psi0 = (
                    alpha
                    * np.cos(k[0] * np.pi * modeleval.mesh.node_coords[:, 0])
                    * np.cos(k[1] * np.pi * modeleval.mesh.node_coords[:, 1])
                    * np.cos(k[2] * np.pi * modeleval.mesh.node_coords[:, 2])
                    + 1j * 0
                )
            else:
                raise RuntimeError("Illegal k.")

            print("Performing Newton iteration...")
            linsolve_maxiter = 500  # 2*len(psi0)
            try:
                newton_out = nm.newton(
                    psi0[:, None],
                    modeleval,
                    nonlinear_tol=1.0e-10,
                    newton_maxiter=50,
                    compute_f_extra_args={"mu": mu, "g": 1.0},
                    eta0=1.0e-10,
                    forcing_term=forcing_term,
                )
            except krypy.utils.ConvergenceError:
                print("Krylov convergence failure. Skip.\n")
                continue
            print(" done.")

            num_krylov_iters = [
                len(resvec) for resvec in newton_out["linear relresvecs"]
            ]
            print("Num Krylov iterations:", num_krylov_iters)
            print("Newton residuals:", newton_out["Newton residuals"])
            if newton_out["info"] == 0:
                num_newton_iters = len(newton_out["linear relresvecs"])
                psi = newton_out["x"]
                # Use the energy as a measure for ruling out boring states such as
                # psi==0 or psi==1 overall.
                energy = modeleval.energy(psi)
                print("Energy of solution state: %g." % energy)
                if energy > -0.999 and energy < -0.001:
                    # Store the file as VTU such that ParaView can loop through and
                    # display them at once. For this, also be sure to keep the file name
                    # in the format 'interesting<-krylovfails03>-01414.vtu'.
                    filename = "interesting-"
                    num_krylov_fails = num_krylov_iters.count(linsolve_maxiter)
                    if num_krylov_fails > 0:
                        filename += "krylovfails{:02d}-".format(num_krylov_fails)
                    filename += "{:02d}{:03d}.vtu".format(num_newton_iters, solution_id)
                    print("Interesting state found for mu={}!".format(mu))
                    # Check if we already stored that one.
                    already_found = False
                    for state in found_solutions:
                        # Synchronize the complex argument.
                        state *= np.exp(1j * (np.angle(psi[0]) - np.angle(state[0])))
                        diff = psi - state
                        if modeleval.inner_product(diff, diff) < 1.0e-10:
                            already_found = True
                            break
                    if already_found and not save_doubles:
                        print("-- But we already have that one.")
                    else:
                        found_solutions.append(psi)
                        print("Storing in {}.".format(filename))
                        # if len(k) == 2:
                        #     function_string = (
                        #         "psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y)"
                        #         % (alpha, k[0], k[1])
                        #     )
                        # elif len(k) == 3:
                        #     function_string = (
                        #         "psi0(X) = %g * cos(%g*pi*x) * cos(%g*pi*y) * cos(%g*pi*z)"
                        #         % (alpha, k[0], k[1], k[2])
                        #     )
                        # else:
                        #     raise RuntimeError("Illegal k.")
                        modeleval.mesh.write(
                            filename,
                            point_data={
                                "psi": np.column_stack([psi.real, psi.imag]),
                                "psi0": np.column_stack([psi0.real, psi0.imag]),
                                "V": modeleval._V,
                                "A": modeleval._raw_magnetic_vector_potential,
                            },
                            field_data={
                                "g": np.array(1.0),
                                "mu": np.array(mu),
                                # "psi0(X)": function_string,
                            },
                        )
                        solution_id += 1
            print()
    return