"This module provides uniform and local mesh refinement."

# Copyright (C) 2009 Anders Logg
#
# This file is part of DOLFIN.
#
# DOLFIN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DOLFIN is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
#
# First added:  2010-02-26
# Last changed: 2010-02-26

__all__ = ["refine"]

# Import C++ interface
import dolfin.cpp as cpp

def refine(mesh, cell_markers=None):
    """
    Refine given mesh and return the refined mesh.

    *Arguments*
        mesh
            the :py:class:`Mesh <dolfin.cpp.Mesh>` to be refined.
        cell_markers
            an optional argument (a boolean :py:class:`MeshFunction
            <dolfin.cpp.MeshFunctionBool>` over cells) may be given
            to specify which cells should be refined. If no cell
            markers are given, then the mesh is refined uniformly.

    *Examples of usage*

        .. code-block:: python

            mesh = refine(mesh)

        To only refine cells with too large error, define a boolean
        MeshFunction over the mesh and mark the cells to be refined
        as True.

        .. code-block:: python

            cell_markers = CellFunction("bool", mesh)
            cell_markers.set_all(False)
            for cell in cells(mesh):
                # set cell_markers[cell] = True if the cell's error
                # indicator is greater than some criterion.
            mesh = refine(mesh, cell_markers)

    """

    # This function is necessary to avoid copying in the wrapped
    # versions of the return-by-value refine functions in C++.

    # Create empty mesh
    refined_mesh = cpp.Mesh()

    # Call C++ refinement
    if cell_markers is None:
        cpp.refine(refined_mesh, mesh)
    else:
        cpp.refine(refined_mesh, mesh, cell_markers)

    return refined_mesh
