def amg_method(amg_type="ml_amg"): """ Determine which AMG preconditioner to use. If available use the preconditioner suggested by the user (ML is default). If not available use petsc_amg. """ for pp in dl.krylov_solver_preconditioners(): if pp[0] == amg_type: return amg_type return 'petsc_amg'
def solver_parameters(solver_exclude, preconditioner_exclude): linear_solver_set = ["lu"] linear_solver_set += [e[0] for e in dolfin.krylov_solver_methods()] preconditioner_set = [e[0] for e in dolfin.krylov_solver_preconditioners()] solver_parameters_set = [] for l in linear_solver_set: if l in solver_exclude: continue for p in preconditioner_set: if p in preconditioner_exclude: continue if (l == "lu" or l == "default") and p != "none": continue solver_parameters_set.append({"linear_solver": l, "preconditioner": p}) return solver_parameters_set
def run_measurements(m, mesh, unit_length, tol, repetitions=10, H_expected=None, name="", skip=[]): S3 = df.VectorFunctionSpace(mesh, "CG", 1) m = vector_valued_function(m, S3) Ms = 1 bem, boundary_to_global = compute_bem_fk(df.BoundaryMesh(mesh, 'exterior', False)) if H_expected is not None: H = vector_valued_function(H_expected, S3) H_expected = H.vector().array() else: # use default/default as reference then. demag = fk.FKDemag() demag.precomputed_bem(bem, boundary_to_global) demag.setup(S3, m, Ms, unit_length) H_expected = demag.compute_field() del(demag) if name == "": pass else: name = name + "_" runner = create_measurement_runner(S3, m, Ms, unit_length, H_expected, tol, repetitions, bem, boundary_to_global) solvers = [s[0] for s in df.krylov_solver_methods()] preconditioners = [p[0] for p in df.krylov_solver_preconditioners()] results_1, failed_1 = runner("first linear solve", "phi_1_solver", solvers, "phi_1_preconditioner", preconditioners, skip, "{}timings_log_1.txt".format(name), "{}results_1.pickled".format(name)) results_2, failed_2 = runner("second linear solve", "phi_2_solver", solvers, "phi_2_preconditioner", preconditioners, skip, "{}timings_log_2.txt".format(name), "{}results_2.pickled".format(name)) return solvers, preconditioners, results_1, failed_1, results_2, failed_2
def run_demag_benchmark(m, mesh, unit_length, tol, repetitions=10, name="bench", H_expected=None): S3 = df.VectorFunctionSpace(mesh, "CG", 1) m = vector_valued_function(m, S3) Ms = 1 # pre-compute BEM to save time bem, boundary_to_global = compute_bem_fk( df.BoundaryMesh(mesh, 'exterior', False)) if H_expected is not None: H = vector_valued_function(H_expected, S3) H_expected = H.vector().array() else: # if no H_expected was passed, use default/default as reference demag = fk.FKDemag() demag.precomputed_bem(bem, boundary_to_global) demag.setup(S3, m, Ms, unit_length) H_expected = demag.compute_field() del (demag) # gather all solvers and preconditioners solvers = [s[0] for s in df.krylov_solver_methods()] preconditioners = [p[0] for p in df.krylov_solver_preconditioners()] benchmark = prepare_benchmark(S3, m, Ms, unit_length, H_expected, tol, repetitions, bem, boundary_to_global) results_1 = benchmark("first linear solve", "phi_1_solver", solvers, "phi_1_preconditioner", preconditioners, name=name + "_1") results_2 = benchmark("second linear solve", "phi_2_solver", solvers, "phi_2_preconditioner", preconditioners, name=name + "_2") return solvers, preconditioners, results_1, results_2
def solver_parameters(solver_exclude, preconditioner_exclude): linear_solver_set = ["lu"] linear_solver_set += [e[0] for e in dolfin.krylov_solver_methods()] preconditioner_set = [e[0] for e in dolfin.krylov_solver_preconditioners()] solver_parameters_set = [] for l in linear_solver_set: if l in solver_exclude: continue for p in preconditioner_set: if p in preconditioner_exclude: continue if (l == "lu" or l == "default") and p != "none": continue solver_parameters_set.append({ "linear_solver": l, "preconditioner": p }) return solver_parameters_set
def create_solver(solver, preconditioner="default"): """Create solver from arguments. Should be flexible to handle - strings specifying the solver and preconditioner types - PETScKrylovSolver/PETScPreconditioner objects - petsc4py.PETSC.KSP/petsc4py.PETSC.pc objects or any combination of the above """ # Create solver if isinstance(solver, str): try: linear_solvers = set(dict(linear_solver_methods()).keys()) krylov_solvers = set(dict(krylov_solver_methods()).keys()) except: linear_solvers = set(linear_solver_methods()) krylov_solvers = set(krylov_solver_methods()) direct_solvers = linear_solvers - krylov_solvers if solver in direct_solvers: s = LinearSolver(solver) return s elif solver in krylov_solvers: s = PETScKrylovSolver(solver) else: s = PETScKrylovSolver() s.ksp().setType(solver) if s.ksp().getNormType() == petsc4py.PETSc.KSP.NormType.NONE: s.ksp().setNormType(petsc4py.PETSc.KSP.NormType.PRECONDITIONED) #raise RuntimeError("Don't know how to handle solver %s" %solver) elif isinstance(solver, PETScKrylovSolver): s = solver elif isinstance(solver, petsc4py.PETSc.KSP): s = PETScKrylovSolver(solver) else: raise ValueError("Unable to create solver from argument of type %s" % type(solver)) assert isinstance(s, PETScKrylovSolver) if preconditioner == "default": return s # Create preconditioner if preconditioner in [None, "none", "None"]: pc = PETScPreconditioner("none") pc.set(s) return s elif isinstance(preconditioner, str): if preconditioner in krylov_solver_preconditioners(): pc = PETScPreconditioner(preconditioner) pc.set(s) return s elif preconditioner in ["additive_schwarz", "bjacobi", "jacobi"]: if preconditioner == "additive_schwarz": pc_type = "asm" else: pc_type = preconditioner ksp = s.ksp() pc = ksp.pc pc.setType(pc_type) return s elif isinstance(preconditioner, PETScPreconditioner): pc = preconditioner pc.set(s) return s elif isinstance(preconditioner, petsc4py.PETSc.PC): ksp = s.ksp() ksp.setPC(preconditioner) return s else: raise ValueError( "Unable to create preconditioner from argument of type %s" % type(solver)) raise RuntimeError( "Should not reach this code. The solver/preconditioner (%s/%s) failed to return a valid solver." % (str(solver), str(preconditioner)))
import dolfin as df from finmag.util.meshes import sphere from benchmark import run_demag_benchmark print "List of Krylov subspace methods.\n" for name, description in df.krylov_solver_methods(): print "{:<20} {}".format(name, description) print "\nList of preconditioners.\n" for name, description in df.krylov_solver_preconditioners(): print "{:<20} {}".format(name, description) m = len(df.krylov_solver_methods()) n = len(df.krylov_solver_preconditioners()) print "\nThere are {} solvers, {} preconditioners and thus {} diferent combinations of solver and preconditioner.".format( m, n, m * n) print "\nSolving first system.\n" ball = sphere(20.0, 1.2, directory="meshes") m_ball = df.Constant((1, 0, 0)) unit_length = 1e-9 print "The used mesh has {} vertices.".format(ball.num_vertices()) H_expected_ball = df.Constant((-1.0 / 3.0, 0.0, 0.0)) tol = 0.002 repetitions = 10 solvers, preconditioners, b1, b2 = run_demag_benchmark(m_ball, ball, unit_length, tol, repetitions, "ball", H_expected_ball)
def has_krylov_solver_preconditioner(pc): return pc in [ k_pc[0] for k_pc in dolfin.krylov_solver_preconditioners() ]
def has_krylov_solver_preconditioner(pc): return pc in [k_pc[0] for k_pc in dolfin.krylov_solver_preconditioners()]
rotation=90) ax.set_xlabel("method") ax.set_ylabel("time (ms)") ax.set_ylim((0, ymax)) ax.legend() ax.set_xticks(ind + 2 * width) xtickNames = plt.setp(ax, xticklabels=solvers) plt.setp(xtickNames, rotation=0) return fig if __name__ == "__main__": ms = 1e3 solvers = [s[0] for s in df.krylov_solver_methods()] preconditioners = [p[0] for p in df.krylov_solver_preconditioners()] ymax = [[6, 6], [6, 10]] for i, system in enumerate(["ball", "film"]): for j, potential in enumerate(["1", "2"]): results = ms * np.ma.load(system + "_" + potential + ".pickle") with open(system + "_" + potential + ".txt", "w") as f: f.write("& {} \\\\\n".format(" & ".join(solvers))) f.write("\\hline\n") for pi, p in enumerate(preconditioners): numbers = ["{:.3}".format(r) for r in results[pi]] f.write("{} & {} \\\\\n".format(p, " & ".join(numbers))) fig = column_chart(results, solvers,