Example #1
0
def image2fct2D(image_select):
    """
    This function converts a 2D slice of a 3D SimpleITK image instance into a 2D FEniCS function.
    We use this function to extract a 2D 'labelmap' from a 3D segmentation image.
    :param image_select: slice id in z direction
    :return: instance of fenics.Function()
    """
    image_select_np = sitk.GetArrayFromImage(image_select)
    image_select_np_flat = image_select_np.flatten()
    origin = image_select.GetOrigin()
    spacing = image_select.GetSpacing()
    height = image_select.GetHeight()
    width = image_select.GetWidth()
    depts = image_select.GetDepth()

    # construct rectangular mesh with dofs on pixels
    p1 = fenics.Point(origin[0], origin[1])
    p2 = fenics.Point(origin[0] + spacing[0] * width,
                      origin[1] + spacing[1] * height)
    nx = int(width - 1)
    ny = int(height - 1)
    fenics.parameters["reorder_dofs_serial"] = False
    mesh_image = fenics.RectangleMesh(p1, p2, nx, ny)
    n_components = image_select.GetNumberOfComponentsPerPixel()
    if n_components == 1:
        V = fenics.FunctionSpace(mesh_image, "CG", 1)
    else:
        V = fenics.VectorFunctionSpace(mesh_image, "CG", 1)
    gdim = mesh_image.geometry().dim()
    coords = V.tabulate_dof_coordinates().reshape((-1, gdim))
    f_img = fenics.Function(V)
    f_img.vector()[:] = image_select_np_flat
    fenics.parameters["reorder_dofs_serial"] = True
    return f_img
Example #2
0
 def setUp(self):
     # Domain
     nx = ny = nz = 10
     self.mesh = fenics.RectangleMesh(fenics.Point(-2, -2),
                                      fenics.Point(2, 2), nx, ny)
     # function spaces
     self.displacement_element = fenics.VectorElement(
         "Lagrange", self.mesh.ufl_cell(), 1)
     self.concentration_element = fenics.FiniteElement(
         "Lagrange", self.mesh.ufl_cell(), 1)
     self.element = fenics.MixedElement(
         [self.displacement_element, self.concentration_element])
     subspace_names = {0: 'displacement', 1: 'concentration'}
     self.functionspace = FunctionSpace(self.mesh)
     self.functionspace.init_function_space(self.element, subspace_names)
     # subdomains
     label_funspace = fenics.FunctionSpace(self.mesh, "DG", 1)
     label_expr = fenics.Expression('(x[0]>=0) ? (1.0) : (2.0)', degree=1)
     labels = fenics.project(label_expr, label_funspace)
     self.labels = labels
     self.tissue_id_name_map = {0: 'outside', 1: 'tissue', 2: 'tumor'}
     self.parameter = {'outside': 0.0, 'tissue': 1.0, 'tumor': 0.1}
     self.boundary = Boundary()
     boundary_dict = {
         'boundary_1': self.boundary,
         'boundary_2': self.boundary
     }
     self.boundary_dict = boundary_dict
     self.subdomains = SubDomains(self.mesh)
     self.subdomains.setup_subdomains(label_function=self.labels)
     self.subdomains.setup_boundaries(tissue_map=self.tissue_id_name_map,
                                      boundary_fct_dict=self.boundary_dict)
     self.subdomains.setup_measures()
     # parameter instance
     self.params = Parameters(self.functionspace, self.subdomains)
Example #3
0
def create_fenics_function_from_image_quick(image):
    origin, size, spacing, extent, dim, vdim = get_measures_from_image(image)
    # fenics expects number of elements as input argument to Rectangle/BoxMesh
    # i.e., n_nodes - 1
    size_new = size - np.ones_like(size, dtype=int)
    # construct rectangular/box mesh with dofs on pixels
    p_min = fenics.Point(extent[0, :])
    p_max = fenics.Point(extent[1, :])
    if dim == 2:
        mesh_image = fenics.RectangleMesh(p_min, p_max, *list(size_new))
    elif dim == 3:
        mesh_image = fenics.BoxMesh(p_min, p_max, *list(size_new))
    # define value dimensionality
    if vdim == 1:
        fenics.parameters["reorder_dofs_serial"] = False
        V = fenics.FunctionSpace(mesh_image, "CG", 1)
    else:
        fenics.parameters["reorder_dofs_serial"] = True
        V = fenics.VectorFunctionSpace(mesh_image, "CG", 1)
    # get and assign values
    image_np = sitk.GetArrayFromImage(image)
    image_np_flat = image_np.flatten()
    f_img = fenics.Function(V)
    f_img.vector()[:] = image_np_flat
    fenics.parameters["reorder_dofs_serial"] = False
    return f_img
Example #4
0
 def setUp(self):
     # Domain
     nx = ny = nz = 10
     mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2),
                                 nx, ny)
     # function spaces
     displacement_element = fenics.VectorElement("Lagrange",
                                                 mesh.ufl_cell(), 1)
     concentration_element = fenics.FiniteElement("Lagrange",
                                                  mesh.ufl_cell(), 1)
     element = fenics.MixedElement(
         [displacement_element, concentration_element])
     subspace_names = {0: 'displacement', 1: 'concentration'}
     functionspace = FunctionSpace(mesh)
     functionspace.init_function_space(element, subspace_names)
     # build a 'solution' function
     u_0_conc_expr = fenics.Expression(
         'sqrt(pow(x[0]-x0,2)+pow(x[1]-y0,2)) < 0.1 ? (1.0) : (0.0)',
         degree=1,
         x0=0.25,
         y0=0.5)
     u_0_disp_expr = fenics.Constant((0.0, 0.0))
     self.U = functionspace.project_over_space(function_expr={
         0: u_0_disp_expr,
         1: u_0_conc_expr
     })
     self.tsd = TimeSeriesData(functionspace=functionspace, name='solution')
Example #5
0
    def test_project_over_subspace(self):
        from glimslib import fenics_local as fenics
        nx = ny = nz = 10
        mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2),
                                    nx, ny)
        E1 = fenics.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
        V1 = fenics.FunctionSpace(mesh, E1)
        E2 = fenics.VectorElement("Lagrange", mesh.ufl_cell(), 1)
        V2 = fenics.FunctionSpace(mesh, E2)
        expr_1 = fenics.Expression(
            ('exp(-a*pow(x[0]-x0, 2) - a*pow(x[1]-y0, 2))'),
            degree=1,
            a=1,
            x0=0.0,
            y0=0.0)
        expr_2 = fenics.Expression(('x[0]', 'x[1]'), degree=1)
        self.subspaces.set_functionspaces([V1, V2])
        f_1 = self.subspaces.project_over_subspace(expr_1, 0)
        if fenics.is_version("<2018.1.x"):
            self.assertEqual(type(f_1), fenics.functions.Function)
        else:
            self.assertEqual(type(f_1), fenics.function.function.Function)

        f_2 = self.subspaces.project_over_subspace(expr_2, 0)
        self.assertEqual(f_2, None)
        f_1 = self.subspaces.project_over_subspace(expr_1, 1)
        self.assertEqual(f_1, None)
        f_2 = self.subspaces.project_over_subspace(expr_2, 1)
        if fenics.is_version("<2018.1.x"):
            self.assertEqual(type(f_2), fenics.functions.Function)
        else:
            self.assertEqual(type(f_2), fenics.function.function.Function)
Example #6
0
 def setUp(self):
     self.nx = 40
     self.ny = 20
     mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2), self.nx, self.ny)
     # function spaces
     U = fenics.VectorFunctionSpace(mesh, "Lagrange", 1)
     V = fenics.FunctionSpace(mesh, "Lagrange", 1)
     u_0_conc_expr = fenics.Expression('sqrt(pow(x[0]-x0,2)+pow(x[1]-y0,2)) < 1 ? (1.0) : (0.0)', degree=1,
                                       x0=1,
                                       y0=1)
     u_0_disp_expr = fenics.Constant((1.0, 1.0))
     self.conc = fenics.project(u_0_conc_expr, V)
     self.disp = fenics.project(u_0_disp_expr, U)
     # 3D
     mesh3d = fenics.BoxMesh(fenics.Point(-2, -2, -2), fenics.Point(2, 2, 2), 10, 20, 30)
     # function spaces
     U3 = fenics.VectorFunctionSpace(mesh3d, "Lagrange", 1)
     V3 = fenics.FunctionSpace(mesh3d, "Lagrange", 1)
     u_0_conc_expr = fenics.Expression('sqrt(pow(x[0]-x0,2)+pow(x[1]-y0,2)+pow(x[2]-z0,2)) < 1 ? (1.0) : (0.0)', degree=1,
                                       x0=1, y0=1, z0=1            )
     u_0_disp_expr = fenics.Constant((1.0, 1.0, 1.0))
     self.conc3 = fenics.project(u_0_conc_expr, V3)
     self.disp3 = fenics.project(u_0_disp_expr, U3)
     self.test_path = os.path.join(config.output_dir_testing, 'test_data_io')
     fu.ensure_dir_exists(self.test_path)
    def setUp(self):
        # Domain
        nx = ny = nz = 10
        self.mesh = fenics.RectangleMesh(fenics.Point(-2, -2),
                                         fenics.Point(2, 2), nx, ny)
        self.sim = TumorGrowth(self.mesh)
        label_funspace = fenics.FunctionSpace(self.mesh, "DG", 1)
        label_expr = fenics.Expression('(x[0]>=0.5) ? (1.0) : (2.0)', degree=1)
        self.labels = fenics.project(label_expr, label_funspace)
        self.tissue_map = {0: 'outside', 1: 'tissue', 2: 'tumor'}
        boundary = Boundary()
        self.boundary_dict = {'boundary_1': boundary, 'boundary_2': boundary}
        self.dirichlet_bcs = {
            'clamped_0': {
                'bc_value': fenics.Constant((0.0, 0.0)),
                'boundary': Boundary(),
                'subspace_id': 0
            },
            'clamped_1': {
                'bc_value': fenics.Constant((0.0, 0.0)),
                'boundary_id': 0,
                'subspace_id': 0
            },
            'clamped_2': {
                'bc_value': fenics.Constant((0.0, 0.0)),
                'boundary_name': 'boundary_1',
                'subspace_id': 0
            }
        }
        self.von_neuman_bcs = {
            'no_flux': {
                'bc_value': fenics.Constant(0.0),
                'boundary_id': 0,
                'subspace_id': 1
            },
            'no_flux_2': {
                'bc_value': fenics.Constant(0.0),
                'boundary_name': 'boundary_1',
                'subspace_id': 1
            },
        }
        self.u_0_conc_expr = fenics.Expression(
            'sqrt(pow(x[0]-x0,2)+pow(x[1]-y0,2)) < 0.1 ? (1.0) : (0.0)',
            degree=1,
            x0=0.25,
            y0=0.5)
        self.u_0_disp_expr = fenics.Constant((0.0, 0.0))

        self.youngmod = {'outside': 10E6, 'tissue': 1, 'tumor': 1000}
        self.poisson = {'outside': 0.4, 'tissue': 0.4, 'tumor': 0.49}
        self.diffusion = {'outside': 0.0, 'tissue': 1.0, 'tumor': 0.1}
        self.prolif = {'outside': 0.0, 'tissue': 0.1, 'tumor': 1.0}
        self.coupling = {'outside': 0.0, 'tissue': 0.0, 'tumor': 0.5}
Example #8
0
def create_image_from_fenics_function(fenics_function, size_new=None):
    # When creating a sitk image from np.array, indexing order changes
    # i.e. np[z, y, x] <-> sitk[x, y, z]
    origin, size, spacing, extent, dim, vdim = get_measures_from_function(
        fenics_function)
    linspaces = []
    if size_new is None:
        size_new = size
    spacing_new = np.zeros(dim, dtype=float)
    for i in range(0, dim):
        linspace = np.linspace(extent[0, i], extent[1, i], size_new[i])
        linspaces.append(linspace)
        spacing_new[i] = compute_spacing(linspace)
    meshgrid_tuple = np.meshgrid(*linspaces, indexing='ij')
    # populate new data array
    if vdim == 1:
        data_array = np.ones(size_new) * np.nan
        is_rgb_data = False
    else:  # create
        data_array = np.ones((*size_new, vdim)) * np.nan
        is_rgb_data = True
    if dim == 2:
        xv, yv = meshgrid_tuple
        #print(xv, yv)
        for i in range(size_new[0]):
            for j in range(size_new[1]):
                #print(i, j)
                #print(xv[i, j], yv[i, j])
                p = fenics.Point(xv[i, j], yv[i, j])
                val = fenics_function(p)
                if vdim == 1:
                    data_array[i, j] = val
                else:
                    data_array[i, j, :] = val
        data_array = np.swapaxes(data_array, 0, 1)  #swap x, y
    elif dim == 3:
        xv, yv, zv = meshgrid_tuple
        for i in range(size_new[0]):
            for j in range(size_new[1]):
                for k in range(size_new[2]):
                    p = fenics.Point(xv[i, j, k], yv[i, j, k], zv[i, j, k])
                    if vdim == 1:
                        data_array[i, j, k] = fenics_function(p)
                    else:
                        data_array[i, j, k, :] = fenics_function(p)
        data_array = np.swapaxes(data_array, 0, 2)  #swap x, z
    # compose image
    img = sitk.GetImageFromArray(data_array, isVector=is_rgb_data)
    img.SetOrigin(list(origin))
    img.SetSpacing(list(spacing_new))
    return img
Example #9
0
def fct2image2D(function, nx, ny):
    """
    This function interpolates a fenics.Function over a 2D grid with nx x ny elements.
    :param function: fenics.Function
    :param nx: number of elements in x direction
    :param ny: number of elements in y direction
    :return: SimpleITK image
    """
    mesh = function.function_space().mesh()
    coords = mesh.coordinates()
    x_min = min(coords[:, 0])
    x_max = max(coords[:, 0])
    y_min = min(coords[:, 1])
    y_max = max(coords[:, 1])
    x_lin = np.linspace(x_min, x_max, nx + 1)
    y_lin = np.linspace(y_min, y_max, ny + 1)
    xv, yv = np.meshgrid(x_lin, y_lin)
    array = np.ones((nx, ny)) * np.nan
    for i in range(nx):
        for j in range(ny):
            p = fenics.Point(xv[i, j], yv[i, j])
            array[i, j] = function(p)
    # compose image
    img = sitk.GetImageFromArray(array)
    origin = function.function_space().mesh().coordinates().min(axis=0)
    img.SetOrigin(origin)
    spacing_x = abs(x_lin[1] - x_lin[0])
    spacing_y = abs(y_lin[1] - y_lin[0])
    img.SetSpacing((spacing_x, spacing_y))
    return img
Example #10
0
def create_fenics_function_from_image(image):
    origin, size, spacing, extent, dim, vdim = get_measures_from_image(image)
    # fenics expects number of elements as input argument to Rectangle/BoxMesh
    # i.e., n_nodes - 1
    size_new = size - np.ones_like(size, dtype=int)
    # construct rectangular/box mesh with dofs on pixels
    p_min = fenics.Point(extent[0, :])
    p_max = fenics.Point(extent[1, :])
    if dim == 2:
        mesh_image = fenics.RectangleMesh(p_min, p_max, *list(size_new))
    elif dim == 3:
        mesh_image = fenics.BoxMesh(p_min, p_max, *list(size_new))
    # define value dimensionality
    if vdim == 1:
        V = fenics.FunctionSpace(mesh_image, "CG", 1)
    else:
        V = fenics.VectorFunctionSpace(mesh_image, "CG", 1, dim=2)
    # get and assign values
    f_img = fenics.Function(V)
    coord_array, value_array = get_coord_value_array_for_image(image,
                                                               flat=True)
    unasigned_coords = assign_values_to_fenics_function(
        f_img, coord_array, value_array)
    return f_img
    def setUp(self):
        nx = ny = nz = 5
        self.ny = ny
        self.nx = nx
        mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2),
                                    nx, ny)
        self.subdomains = SubDomains(mesh)
        # 'LabelMap'
        label_funspace = fenics.FunctionSpace(mesh, "DG", 1)
        label_expr = fenics.Expression('(x[0]>=0) ? (1.0) : (2.0)', degree=1)
        labels = fenics.project(label_expr, label_funspace)
        self.labels = labels
        # tissue_id_name_map
        self.tissue_id_name_map = {0: 'outside', 1: 'tissue', 2: 'tumor'}
        self.parameter = {'outside': 0.0, 'tissue': 1.0, 'tumor': 0.1}

        class Boundary(fenics.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary

        self.boundary = Boundary()

        boundary_dict = {'boundary_1': self.boundary}
        self.boundary_dict = boundary_dict
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO)
fenics.set_log_level(fenics.PROGRESS)

# ==============================================================================
# Problem Settings
# ==============================================================================


class Boundary(fenics.SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary


# Mesh
nx = ny = 50
mesh = fenics.RectangleMesh(fenics.Point(-5, -5), fenics.Point(5, 5), nx, ny)

# LabelMap
label_funspace = fenics.FunctionSpace(mesh, "DG", 1)
label_expr = fenics.Expression('(x[0]>=0.0) ? (1.0) : (2.0)', degree=1)
labels = fenics.project(label_expr, label_funspace)
tissue_map = {0: 'outside', 1: 'A', 2: 'B'}

# Boundaries & BCs
boundary = Boundary()
boundary_dict = {'boundary_all': boundary}
dirichlet_bcs = {
    'clamped_outside': {
        'bc_value': fenics.Constant((0.0, 0.0)),
        'named_boundary': 'boundary_all',
        'subspace_id': 0
Example #13
0
 def setUp(self):
     # Domain
     nx = ny = nz = 10
     self.nx, self.ny = nx, ny
     self.mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2), nx, ny)
     # function spaces
     self.displacement_element = fenics.VectorElement("Lagrange", self.mesh.ufl_cell(), 1)
     self.concentration_element = fenics.FiniteElement("Lagrange", self.mesh.ufl_cell(), 1)
     self.element = fenics.MixedElement([self.displacement_element, self.concentration_element])
     subspace_names = {0: 'displacement', 1: 'concentration'}
     self.functionspace = FunctionSpace(self.mesh)
     self.functionspace.init_function_space(self.element, subspace_names)
     # define 'solution' with concentration=1 everywhere
     self.conc_expr =  fenics.Constant(1.0)
     self.conc = self.functionspace.project_over_space(self.conc_expr, subspace_name='concentration')
     # subdomains
     label_funspace = fenics.FunctionSpace(self.mesh, "DG", 1)
     label_expr = fenics.Expression('(x[0]>=0) ? (1.0) : (2.0)', degree=1)
     labels = fenics.project(label_expr, label_funspace)
     self.labels = labels
     self.tissue_id_name_map = {0: 'outside',
                                1: 'tissue',
                                2: 'tumor'}
     self.parameter = {'outside': 0.0,
                       'tissue': 1.0,
                       'tumor': 0.1}
     self.boundary_pos = BoundaryPos()
     self.boundary_neg = BoundaryNeg()
     boundary_dict = {'boundary_pos': self.boundary_pos,
                      'boundary_neg': self.boundary_neg}
     self.boundary_dict = boundary_dict
     self.subdomains = SubDomains(self.mesh)
     self.subdomains.setup_subdomains(label_function=self.labels)
     self.subdomains.setup_boundaries(tissue_map=self.tissue_id_name_map,
                                      boundary_fct_dict=self.boundary_dict)
     self.subdomains.setup_measures()
     # BCs
     self.bcs = BoundaryConditions(self.functionspace, self.subdomains)
     self.dirichlet_bcs = {'clamped_0': {'bc_value': fenics.Constant((0.0, 0.0)),
                                       'boundary': BoundaryPos(),
                                       'subspace_id': 0},
                           'clamped_1': {'bc_value': fenics.Constant((0.0, 0.0)),
                                         'subdomain_boundary': 'tissue_tumor',
                                         'subspace_id': 0},
                           'clamped_pos': {'bc_value': fenics.Constant((0.0, 0.0)),
                                         'named_boundary': 'boundary_pos',
                                         'subspace_id': 0},
                           'clamped_neg': {'bc_value': fenics.Constant((0.0, 0.0)),
                                         'named_boundary': 'boundary_neg',
                                         'subspace_id': 0}
                           }
     self.von_neuman_bcs = {
                            'flux_boundary_pos': {'bc_value': fenics.Constant(1.0),
                                        'named_boundary': 'boundary_pos',
                                        'subspace_id': 1},
                             'flux_boundary_neg': {'bc_value': fenics.Constant(-5.0),
                                                   'named_boundary': 'boundary_neg',
                                                   'subspace_id': 1}
                            # 'no_flux_domain_boundary': {'bc_value': fenics.Constant(1.0),
                            #               'subdomain_boundary': 'tissue_tumor',
                            #               'subspace_id': 1},
                           }
Example #14
0
 def setUp(self):
     nx = ny = nz = 5
     self.mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2), nx, ny)
     self.displacement_element = fenics.VectorElement("Lagrange", self.mesh.ufl_cell(), 1)
     self.concentration_element = fenics.FiniteElement("Lagrange", self.mesh.ufl_cell(), 1)
     self.element = fenics.MixedElement([self.displacement_element, self.concentration_element])