def METHOD_NAME(demand, W, solver, iterations=30):
    cs, ks, patterns = create_base_cutting_stock(demand, W)
    if '_persistent' not in solver:
        raise RuntimeError(
            'solver must be a string for pyo.SolverFactory and persistent'
        )
    cs_s = pyo.SolverFactory(solver)
    ks_s = pyo.SolverFactory(solver)
    cs_s.set_instance(cs)
    ks_s.set_instance(ks)
    for _ in range(iterations):
        cs_s.solve()
        duals = {width: cs.dual[cs.demand[width]] for width in demand}
        ks.obj.expr = sum(duals[width] * ks.widths[width] for width in demand)
        ks_s.set_objective(ks.obj)
        ks_s.solve()
        if pyo.value(ks.obj) <= 1:
            # no better column
            break
        # else we'll add the column from ks
        new_pattern_var = cs.pattern.add()
        np_widths = []
        np_constraints = []
        pattern = dict()
        for width, var in ks.widths.items():
            cut_number = int(round(pyo.value(var)))
            if cut_number == 0:
                continue
            np_widths.append(cut_number)
            np_constraints.append(cs.demand[width])
            pattern[width] = cut_number
        patterns[len(cs.pattern)] = pattern
        cs_s.add_column(cs, new_pattern_var, 1.0, np_constraints, np_widths)
    # heuristically solve the cutting stock problem with integer restrictions
    # to get an integer feasible solution
    cs.pattern.domain = pyo.NonNegativeIntegers
    for var in cs.pattern.values():
        cs_s.update_var(var)
    del cs.dual
    cs_s.solve()
    return cs, patterns