def main():
    atoms = bulk("Al", cubic=True)
    atoms = atoms * (3, 3, 3)
    for i in range(int(len(atoms) / 5)):
        atoms[i].symbol = "Mg"

    atoms.rattle(stdev=0.005)

    calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=(4, 4, 4), nbands="120%")
    atoms.set_calculator(calc)

    logfile = "relax250.log"
    traj = "relax250.traj"
    trajObj = Trajectory(traj, 'w', atoms)

    precon = Exp(mu=1)
    relaxer = PreconLBFGS(atoms,
                          logfile=logfile,
                          use_armijo=True,
                          precon=precon,
                          memory=50)
    #relaxer = PreconFIRE( atoms, logfile=logfile, use_armijo=True, precon=precon )
    relaxer.attach(trajObj)
    try:
        relaxer.run(fmax=0.05)
    except Exception as exc:
        print(exc)
Beispiel #2
0
def main(argv):
    n_mg = int(argv[0])
    atoms = bulk("Al")
    atoms = atoms * (4, 4, 4)
    for i in range(n_mg):
        atoms[i].symbol = "Mg"

    atoms.rattle(stdev=0.005)

    calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=(4, 4, 4), nbands="120%")
    atoms.set_calculator(calc)

    logfile = "preconTest%d.log" % (n_mg)
    traj = "preconTest%d.traj" % (n_mg)
    trajObj = Trajectory(traj, 'w', atoms)

    precon = Exp(mu=1)
    relaxer = PreconLBFGS(atoms,
                          logfile=logfile,
                          use_armijo=True,
                          precon=precon)
    relaxer.attach(trajObj)
    try:
        relaxer.run(fmax=0.05)
    except:
        pass
    print("Mu: %.2E" % (relaxer.precon.mu))
Beispiel #3
0
def do_lattice(bulk, elastic=True):
    tol = 1e-3  # max force tol for relaxation
    n_E_vs_V_steps = 10

    # use one of the routines from utilities module to relax the initial
    # unit cell and atomic positions
    bulk = relax_atoms_cell(bulk, tol=tol, traj_file=None, symmetrize=True)

    print("relaxed bulk")
    ase.io.write(sys.stdout, bulk, format='extxyz')

    if elastic:
        # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w
        calc = bulk.get_calculator().calc
        bulk.set_calculator(calc)
        precon = Exp(3.0)
        opt = lambda atoms, **kwargs: PreconLBFGS(
            atoms, precon=precon, **kwargs)
        elastic_consts = matscipy.elasticity.fit_elastic_constants(
            bulk, symmetry='cubic', optimizer=opt)
        c11 = elastic_consts[0][0, 0] / GPa
        c12 = elastic_consts[0][0, 1] / GPa
        c44 = elastic_consts[0][3, 3] / GPa

    V0 = bulk.get_volume()
    E_vs_V = []

    f = open("relaxed_E_vs_V_configs.xyz", "w")
    cell_scalings = np.linspace(0.90**(1.0 / 3.0), 1.1**(1.0 / 3.0), 30)
    for cell_scaling in cell_scalings:
        scaled_bulk = bulk.copy()
        scaled_bulk.set_calculator(bulk.get_calculator())
        scaled_bulk.set_cell(scaled_bulk.get_cell() * cell_scaling,
                             scale_atoms=True)
        scaled_bulk = relax_atoms_cell(scaled_bulk,
                                       tol=tol,
                                       traj_file=None,
                                       constant_volume=True,
                                       method='fire',
                                       symmetrize=True)
        # evaluate(scaled_bulk)
        ase.io.write(f, scaled_bulk, format='extxyz')
        E_vs_V.insert(0, (scaled_bulk.get_volume() / len(scaled_bulk),
                          scaled_bulk.get_potential_energy() / len(bulk)))

    for (V, E) in E_vs_V:
        print("EV_final ", V, E)

    if elastic:
        return (c11, c12, c44, E_vs_V)
    else:
        return (E_vs_V)
def relax_atoms(atoms,
                tol=1e-3,
                method='lbfgs_precon',
                max_steps=1000,
                traj_file=None,
                **kwargs):
    import model
    atoms.set_calculator(model.calculator)
    if hasattr(model, 'Optimizer'):
        method = 'model_optimizer'
        opt = model.Optimizer(atoms)
        opt.run(tol, max_steps)
    elif method.startswith('lbfgs') or method == 'fire' or method == 'cg_n':
        if method == 'lbfgs_ASE':
            from ase.optimize import LBFGS
            opt = LBFGS(atoms, **kwargs)
        elif method == 'cg_n':
            from quippy import Minim
            opt = Minim(atoms,
                        relax_positions=True,
                        relax_cell=False,
                        method='cg_n')
        else:
            from ase.optimize.precon.precon import Exp
            from ase.optimize.precon.lbfgs import PreconLBFGS
            precon = None
            if method.endswith('precon'):
                precon = Exp(3.0, recalc_mu=True)
            if method.startswith('lbfgs'):
                opt = PreconLBFGS(atoms, precon=precon, **kwargs)
            else:
                opt = FIRE(atoms, **kwargs)
        if traj_file is not None and method != 'cg_n':
            traj = open(traj_file, 'w')

            def write_trajectory():
                write(traj, atoms, format='extxyz')

            opt.attach(write_trajectory)
        opt.run(tol, max_steps)
        try:
            traj.close()
        except:
            pass
    else:
        raise ValueError('unknown method %s!' % method)

    return atoms
def main(runID):
    db = connect(db_name)
    atoms = db.get_atoms(id=runID)
    N = 14
    calc = gp.GPAW(mode=gp.PW(500),
                   xc="PBE",
                   kpts=(N, N, N),
                   nbands=-50,
                   symmetry={'do_not_symmetrize_the_density': True})
    atoms.set_calculator(calc)
    precon = Exp(mu=1.0, mu_c=1.0)
    uf = UnitCellFilter(atoms, hydrostatic_strain=True)
    logfile = "al3mg2{}.log".format(runID)
    relaxer = PreconLBFGS(uf, logfile=logfile, use_armijo=True, precon=precon)
    relaxer.run(fmax=0.025, smax=0.003)
    energy = atoms.get_potential_energy()
    del db[db.get(id=runID)]
    db.write(atoms)
Beispiel #6
0
def main(argv):
    relax_mode = "both"  # both, cell, positions
    system = "AlMg"
    runID = int(argv[0])
    nkpt = int(argv[1])

    single_point = False
    if (len(argv) >= 3):
        single_point = (int(argv[2]) == 1)
    print("Running job: %d" % (runID))
    db_paths = [
        "/home/ntnu/davidkl/GPAWTutorial/CE/almg_fcc_vac.db",
        "almg_fcc_vac.db", "/home/davidkl/GPAWTutorial/CE/almg_fcc_vac.db"
    ]
    for path in db_paths:
        if (os.path.isfile(path)):
            db_name = path
            break
    #db_name = "almgsi_test_db.db"
    db = ase.db.connect(db_name)
    name = db.get(id=runID).key_value_pairs["name"]
    new_run = not db.get(id=runID).key_value_pairs["started"]

    # Update the databse
    db.update(runID, started=True, converged=False)
    db.update(runID, nkpt=nkpt)

    atoms = db.get_atoms(id=runID)
    atoms = delete_vacancies(atoms)

    if (len(atoms) == 1):
        nbands = -10
    else:
        nbands = "120%"
    kpts = (nkpt, nkpt, nkpt)
    try:
        restart_name = SaveRestartFiles.restart_name(name)
        atoms, calc = gp.restart(restart_name)
    except:
        calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=kpts, nbands=nbands)
        atoms.set_calculator(calc)

    if (single_point):
        calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=kpts, nbands=nbands)
        atoms.set_calculator(calc)

    logfile = "almg_fcc_vac{}.log".format(name)
    traj = "almg_bcc{}.traj".format(name)
    db.update(runID, trajfile=traj)
    trajObj = Trajectory(traj, 'w', atoms)

    #storeBest = SaveToDB(db_name,runID,name,mode=relax_mode)
    save_calc = SaveRestartFiles(calc, name)
    update_db_info = UpdateDBInfo(db_name, runID, atoms)
    volume = atoms.get_volume()

    try:
        precon = Exp(mu=1.0, mu_c=1.0)
        fmax = 0.025
        smax = 0.003
        if (relax_mode == "both"):
            relaxer = PreconLBFGS(atoms,
                                  logfile=logfile,
                                  use_armijo=True,
                                  variable_cell=True)
        elif (relax_mode == "positions"):
            #relaxer = SciPyFminCG( atoms, logfile=logfile )
            relaxer = BFGS(atoms, logfile=logfile)
        elif (relax_mode == "cell"):
            str_f = StrainFilter(atoms, mask=[1, 1, 1, 0, 0, 0])
            relaxer = BFGS(str_f, logfile=logfile)
            fmax = smax * volume

        relaxer.attach(trajObj)
        #relaxer.attach( storeBest, interval=1, atoms=atoms )
        relaxer.attach(save_calc, interval=1)
        relaxer.attach(update_db_info, interval=1)
        if (not single_point):
            if (relax_mode == "both"):
                relaxer.run(fmax=fmax, smax=smax)
            else:
                relaxer.run(fmax=fmax)
        energy = atoms.get_potential_energy()

        orig_atoms = db.get_atoms(runID)
        single_p_calc = SinglePointCalculator(orig_atoms, energy=energy)
        orig_atoms.set_calculator(single_p_calc)
        kvp = db.get(name=name).key_value_pairs
        del db[runID]
        newID = db.write(orig_atoms, key_value_pairs=kvp)

        if (relax_mode == "positions"):
            db.update(newID, converged_force=True)
        elif (relax_mode == "cell"):
            db.update(newID, converged_stress=True)
        else:
            db.update(newID, converged_stress=True, converged_force=True)

        db.update(newID, single_point=single_point)
        db.update(newID, restart_file=SaveRestartFiles.restart_name(name))
        row = db.get(id=newID)
        conv_force = row.get("converged_force", default=0)
        conv_stress = row.get("converged_stress", default=0)
        if ((conv_force == 1) and (conv_stress == 1) and (nkpt == 4)):
            db.update(newID, converged=True)
    except Exception as exc:
        print(exc)
def relax_atoms_cell(atoms,
                     tol=1e-3,
                     stol=None,
                     method='lbfgs_precon',
                     max_steps=100,
                     mask=None,
                     traj_file=None,
                     hydrostatic_strain=False,
                     constant_volume=False,
                     precon_apply_positions=True,
                     precon_apply_cell=True,
                     symmetrize=False,
                     **kwargs):
    import model
    #print "relax_atoms_cell using method",method
    if symmetrize:
        atoms.set_calculator(SymmetrizedCalculator(model.calculator, atoms))
    else:
        atoms.set_calculator(model.calculator)
    ## print "relax_atoms_cell initial e ", atoms.get_potential_energy()
    ## print "relax_atoms_cell initial f ", atoms.get_forces()
    ## print "relax_atoms_cell initial s ", atoms.get_stress()
    if hasattr(model, 'Optimizer'):
        method = 'model_optimizer'
    if method != 'cg_n':
        atoms = UnitCellFilter(atoms,
                               mask=mask,
                               hydrostatic_strain=hydrostatic_strain,
                               constant_volume=constant_volume)
    if method.startswith('lbfgs') or method == 'fire' or method == 'cg_n':
        if method == 'cg_n':
            from quippy import Minim, fzeros
            atoms.info['Minim_Hydrostatic_Strain'] = hydrostatic_strain
            atoms.info['Minim_Constant_Volume'] = constant_volume
            if mask is not None:
                atoms.info['Minim_Lattice_Fix'] = fzeros((3, 3))
                if not mask[0]:
                    atoms.info['Minim_Lattice_Fix'][1, 1] = 1.0
                if not mask[1]:
                    atoms.info['Minim_Lattice_Fix'][2, 2] = 1.0
                if not mask[2]:
                    atoms.info['Minim_Lattice_Fix'][3, 3] = 1.0
                if not mask[3]:
                    atoms.info['Minim_Lattice_Fix'][1, 2] = 1.0
                    atoms.info['Minim_Lattice_Fix'][2, 1] = 1.0
                if not mask[4]:
                    atoms.info['Minim_Lattice_Fix'][2, 3] = 1.0
                    atoms.info['Minim_Lattice_Fix'][3, 2] = 1.0
                if not mask[5]:
                    atoms.info['Minim_Lattice_Fix'][1, 3] = 1.0
                    atoms.info['Minim_Lattice_Fix'][3, 1] = 1.0
            opt = Minim(atoms,
                        relax_positions=True,
                        relax_cell=True,
                        method='cg_n')
        else:
            from ase.optimize.precon.precon import Exp
            from ase.optimize.precon.lbfgs import PreconLBFGS
            precon = None
            if method.endswith('precon'):
                precon = Exp(3.0,
                             apply_positions=precon_apply_positions,
                             apply_cell=precon_apply_cell,
                             recalc_mu=True)
            if method.startswith('lbfgs'):
                opt = PreconLBFGS(atoms, precon=precon, **kwargs)
            else:
                opt = FIRE(atoms, **kwargs)
        if traj_file is not None:
            traj = open(traj_file, 'w')

            def write_trajectory():
                try:
                    write(traj, atoms.atoms, format='extxyz')
                except:
                    write(traj, atoms, format='extxyz')

            opt.attach(write_trajectory)
        if method != 'cg_n' and isinstance(opt, PreconLBFGS):
            opt.run(tol, max_steps, smax=stol)
        else:
            opt.run(tol, max_steps)
        if traj_file is not None:
            traj.close()
    elif method == 'model_optimizer':
        opt = model.Optimizer(atoms.atoms)
        opt.run()
    else:
        raise ValueError('unknown method %s!' % method)

    if isinstance(atoms, UnitCellFilter):
        return atoms.atoms
    else:
        return atoms
Beispiel #8
0
def do_lattice(bulk, use_precon=True, elastic=True, tol=1.0e-3):

    print "unrelaxed bulk"
    ase.io.write(sys.stdout, bulk, format='extxyz')

    # use one of the routines from utilities module to relax the initial
    # unit cell and atomic positions
    if use_precon:
        bulk = relax_atoms_cell(bulk,
                                tol=tol,
                                traj_file="bulk.relax.extxyz",
                                symmetrize=True)
    else:
        bulk = relax_atoms_cell(bulk,
                                tol=tol,
                                traj_file=None,
                                method='cg_n',
                                symmetrize=True)

    print "relaxed bulk"
    ase.io.write(sys.stdout, bulk, format='extxyz')

    print "calculating elastic constants"
    precon = None
    if use_precon:
        precon = Exp(3.0)
    opt = lambda atoms, **kwargs: PreconLBFGS(atoms, precon=precon, **kwargs)
    if elastic:
        # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w
        bulk.set_calculator(model.calculator)
        try:
            elastic_consts = matscipy.elasticity.fit_elastic_constants(
                bulk,
                symmetry='tetragonal_high',
                optimizer=opt,
                logfile=sys.stdout)
        except RuntimeError:
            # fallback on FIRE if we get a linesearch failure with LBFGS
            opt = FIRE
            elastic_consts = matscipy.elasticity.fit_elastic_constants(
                bulk,
                symmetry='tetragonal_high',
                optimizer=opt,
                logfile=sys.stdout)

        c11 = elastic_consts[0][0, 0] / GPa
        c33 = elastic_consts[0][2, 2] / GPa
        c12 = elastic_consts[0][0, 1] / GPa
        c13 = elastic_consts[0][0, 2] / GPa
        c44 = elastic_consts[0][3, 3] / GPa
        c66 = elastic_consts[0][5, 5] / GPa

    print "calculating E vs. V"
    V0 = bulk.get_volume()
    dV = bulk.get_volume() * 0.025
    E_vs_V = []
    scaled_bulk = bulk.copy()
    print "bulk going into E vs. V"
    ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
    f = open("relaxed_E_vs_V_configs.xyz", "w")

    scaled_bulk = bulk.copy()
    constraints = []
    # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int)
    # scaled_bulk.arrays["move_mask_3"][:,0] = 1
    # for i in range(len(scaled_bulk)):
    # constraints.append(FixedLine_forces_only(i, (0.0, 0.0, 1.0)))
    # scaled_bulk.set_constraint(constraints)
    for i in range(0, -5 - 1, -1):
        print "doing volume step", i
        vcur = scaled_bulk.get_volume()
        scaled_bulk.set_cell(scaled_bulk.get_cell() *
                             ((V0 + i * dV) / vcur)**(1.0 / 3.0),
                             scale_atoms=True)
        try:
            scaled_bulk = relax_atoms_cell(scaled_bulk,
                                           tol=tol,
                                           traj_file=None,
                                           constant_volume=True,
                                           method='cg_n',
                                           symmetrize=True,
                                           max_steps=500)
        except:
            break
        print "done relaxing step", i
        ase.io.write(f, scaled_bulk, format='extxyz')
        f.flush()
        E_vs_V.insert(0, (scaled_bulk.get_volume() / len(bulk),
                          scaled_bulk.get_potential_energy() / len(bulk)))
        evaluate(scaled_bulk)
        print "done evaluate step", i
        print "EV ", i, scaled_bulk.get_volume(
        ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress()

    scaled_bulk = bulk.copy()
    # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int)
    # scaled_bulk.arrays["move_mask_3"][:,0] = 1
    # scaled_bulk.set_constraint(constraints)
    for i in range(1, 6 + 1):
        print "doing volume step", i
        vcur = scaled_bulk.get_volume()
        scaled_bulk.set_cell(scaled_bulk.get_cell() *
                             ((V0 + i * dV) / vcur)**(1.0 / 3.0),
                             scale_atoms=True)
        try:
            scaled_bulk = relax_atoms_cell(scaled_bulk,
                                           tol=tol,
                                           traj_file=None,
                                           constant_volume=True,
                                           method='cg_n',
                                           symmetrize=True,
                                           max_steps=500)
        except:
            break
        print "done relaxing step", i
        ase.io.write(f, scaled_bulk, format='extxyz')
        f.flush()
        E_vs_V.append((scaled_bulk.get_volume() / len(bulk),
                       scaled_bulk.get_potential_energy() / len(bulk)))
        evaluate(scaled_bulk)
        print "done evaluate step", i
        print "EV ", i, scaled_bulk.get_volume(
        ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress()

    for (V, E) in E_vs_V:
        print "EV_final ", V, E

    if elastic:
        return (c11, c33, c12, c13, c44, c66, E_vs_V)
    else:
        return (E_vs_V)
def main(argv):
    relax_mode = "cell"  # both, cell, positions
    system = "AlMg"
    runID = int(argv[0])
    print("Running job: %d" % (runID))
    db_paths = [
        "/home/ntnu/davidkl/GPAWTutorial/CE/almg_217.db", "almg_217.db",
        "/home/davidkl/GPAWTutorial/CE/almg_217.db"
    ]
    for path in db_paths:
        if (os.path.isfile(path)):
            db_name = path
            break
    #db_name = "test_db.db"
    db = ase.db.connect(db_name)

    con = sq.connect(db_name)
    cur = con.cursor()
    cur.execute("SELECT value FROM text_key_values WHERE id=? AND key='name'",
                (runID, ))
    name = cur.fetchone()[0]
    con.close()

    new_run = not db.get(id=runID).key_value_pairs["started"]
    # Update the databse
    db.update(runID, started=True, converged=False)

    atoms = db.get_atoms(id=runID)

    calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=(4, 4, 4), nbands="120%")
    #calc = gp.GPAW( mode=gp.PW(500), xc="PBE", kpts=(4,4,4), nbands=-10 )
    atoms.set_calculator(calc)

    logfile = "almg_bcc%d.log" % (runID)
    traj = "almg_bcc%d.traj" % (runID)
    trajObj = Trajectory(traj, 'w', atoms)

    storeBest = SaveToDB(db_name, runID, name, mode=relax_mode)
    volume = atoms.get_volume()

    try:
        precon = Exp(mu=1.0, mu_c=1.0)
        fmax = 0.025
        smax = 0.003
        if (relax_mode == "both"):
            relaxer = PreconLBFGS(atoms,
                                  logfile=logfile,
                                  use_armijo=True,
                                  precon=precon,
                                  variable_cell=True)
        elif (relax_mode == "positions"):
            relaxer = SciPyFminCG(atoms, logfile=logfile)
            #relaxer = BFGS( atoms, logfile=logfile )
        elif (relax_mode == "cell"):
            str_f = StrainFilter(atoms, mask=[1, 1, 1, 0, 0, 0])
            relaxer = BFGS(str_f, logfile=logfile)
            fmax = smax * volume

        relaxer.attach(trajObj)
        relaxer.attach(storeBest, interval=1, atoms=atoms)
        if (relax_mode == "both"):
            relaxer.run(fmax=fmax, smax=smax)
        else:
            relaxer.run(fmax=fmax)
        energy = atoms.get_potential_energy()

        if (relax_mode == "positions"):
            db.update(storeBest.runID, converged_force=True)
        elif (relax_mode == "cell"):
            db.update(storeBest.runID, converged_stress=True)
        else:
            db.update(storeBest.runID,
                      converged_stress=True,
                      converged_force=True)

        row = db.get(id=storeBest.runID)
        conv_force = row.get("converged_force", default=0)
        conv_stress = row.get("converged_stress", default=0)
        if ((conv_force == 1) and (conv_stress == 1)):
            db.update(storeBest.runID, converged=True)
    except Exception as exc:
        print(exc)
Beispiel #10
0
def main(argv):
    relaxCell = True
    system = "AlMg"
    runID = int(argv[0])
    print("Running job: %d" % (runID))
    db_paths = [
        "/home/ntnu/davidkl/GPAWTutorial/CE/ce_hydrostatic.db",
        "ce_hydrostatic.db", "/home/davidkl/GPAWTutorial/CE/ce_hydrostatic.db"
    ]
    for path in db_paths:
        if (os.path.isfile(path)):
            db_name = path
            break
    #db_name = "/home/ntnu/davidkl/Documents/GPAWTutorials/ceTest.db"
    db = ase.db.connect(db_name)

    con = sq.connect(db_name)
    cur = con.cursor()
    cur.execute("SELECT value FROM text_key_values WHERE id=? AND key='name'",
                (runID, ))
    name = cur.fetchone()[0]
    con.close()

    new_run = not db.get(id=runID).key_value_pairs["started"]
    # Update the databse
    db.update(runID, started=True, converged=False)

    atoms = db.get_atoms(id=runID)
    if (system == "AlMg" and new_run == False):
        atoms = change_cell_composition_AlMg(atoms)

    convergence = {"density": 1E-4, "eigenstates": 4E-8}
    calc = gp.GPAW(mode=gp.PW(500),
                   xc="PBE",
                   kpts=(4, 4, 4),
                   nbands="120%",
                   convergence=convergence)
    atoms.set_calculator(calc)

    logfile = "ceTest%d.log" % (runID)
    traj = "ceTest%d.traj" % (runID)
    trajObj = Trajectory(traj, 'w', atoms)

    storeBest = SaveToDB(db_name, runID, name)

    try:
        precon = Exp(mu=1.0, mu_c=1.0)
        if (relaxCell):
            uf = UnitCellFilter(atoms, hydrostatic_strain=True)
            relaxer = PreconLBFGS(uf,
                                  logfile=logfile,
                                  use_armijo=True,
                                  precon=precon)
        else:
            relaxer = PreconFIRE(atoms, logfile=logfile, precon=precon)
            relaxer = SciPyFminCG(atoms, logfile=logfile)
        relaxer.attach(trajObj)
        relaxer.attach(storeBest, interval=1, atoms=atoms)
        if (relaxCell):
            relaxer.run(fmax=0.025, smax=0.003)
        else:
            relaxer.run(fmax=0.025)
        energy = atoms.get_potential_energy()
        db.update(storeBest.runID, converged=True)
        print("Energy: %.2E eV/atom" % (energy / len(atoms)))
        print("Preconditioner parameters")
        print("Mu:", precon.mu)
        print("Mu_c:", precon.mu_c)
    except Exception as exc:
        print(exc)