def geometric_fba(model, epsilon=<NUM_LIT>, max_tries=<NUM_LIT:200>, processes=None):
with model:<EOL><INDENT>consts = []<EOL>obj_vars = []<EOL>updating_vars_cons = []<EOL>prob = model.problem<EOL>add_pfba(model)  <EOL>model.optimize()<EOL>fva_sol = flux_variability_analysis(model, processes=processes)<EOL>mean_flux = (fva_sol["<STR_LIT>"] + fva_sol["<STR_LIT>"]).abs() / <NUM_LIT:2><EOL>for rxn in model.reactions:<EOL><INDENT>var = prob.Variable("<STR_LIT>" + rxn.id,<EOL>lb=<NUM_LIT:0>,<EOL>ub=mean_flux[rxn.id])<EOL>upper_const = prob.Constraint(rxn.flux_expression - var,<EOL>ub=mean_flux[rxn.id],<EOL>name="<STR_LIT>" +<EOL>rxn.id)<EOL>lower_const = prob.Constraint(rxn.flux_expression + var,<EOL>lb=fva_sol.at[rxn.id, "<STR_LIT>"],<EOL>name="<STR_LIT>" +<EOL>rxn.id)<EOL>updating_vars_cons.append((rxn.id, var, upper_const, lower_const))<EOL>consts.extend([var, upper_const, lower_const])<EOL>obj_vars.append(var)<EOL><DEDENT>model.add_cons_vars(consts)<EOL>model.objective = prob.Objective(Zero, sloppy=True, direction="<STR_LIT>")<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL>sol = model.optimize()<EOL>fva_sol = flux_variability_analysis(model, processes=processes)<EOL>mean_flux = (fva_sol["<STR_LIT>"] + fva_sol["<STR_LIT>"]).abs() / <NUM_LIT:2><EOL>delta = (fva_sol["<STR_LIT>"] - fva_sol["<STR_LIT>"]).max()<EOL>count = <NUM_LIT:1><EOL>LOGGER.debug("<STR_LIT>",<EOL>count, delta, sol.status)<EOL>while delta > epsilon and count < max_tries:<EOL><INDENT>for rxn_id, var, u_c, l_c in updating_vars_cons:<EOL><INDENT>var.ub = mean_flux[rxn_id]<EOL>u_c.ub = mean_flux[rxn_id]<EOL>l_c.lb = fva_sol.at[rxn_id, "<STR_LIT>"]<EOL><DEDENT>sol = model.optimize()<EOL>fva_sol = flux_variability_analysis(model, processes=processes)<EOL>mean_flux = (fva_sol["<STR_LIT>"] + fva_sol["<STR_LIT>"]).abs() / <NUM_LIT:2><EOL>delta = (fva_sol["<STR_LIT>"] - fva_sol["<STR_LIT>"]).max()<EOL>count += <NUM_LIT:1><EOL>LOGGER.debug("<STR_LIT>",<EOL>count, delta, sol.status)<EOL><DEDENT>if count == max_tries:<EOL><INDENT>raise RuntimeError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>".format(max_tries)<EOL>)<EOL><DEDENT><DEDENT>return sol<EOL>
Perform geometric FBA to obtain a unique, centered flux distribution.

Geometric FBA [1]_ formulates the problem as a polyhedron and
then solves it by bounding the convex hull of the polyhedron.
The bounding forms a box around the convex hull which reduces
with every iteration and extracts a unique solution in this way.

Parameters
----------
model: cobra.Model
    The model to perform geometric FBA on.
epsilon: float, optional
    The convergence tolerance of the model (default 1E-06).
max_tries: int, optional
    Maximum number of iterations (default 200).
processes : int, optional
    The number of parallel processes to run. If not explicitly passed,
    will be set from the global configuration singleton.

Returns
-------
cobra.Solution
    The solution object containing all the constraints required
    for geometric FBA.

References
----------
.. [1] Smallbone, Kieran & Simeonidis, Vangelis. (2009).
       Flux balance analysis: A geometric perspective.
       Journal of theoretical biology.258. 311-5.
       10.1016/j.jtbi.2009.01.027.