Ejemplo n.º 1
0
    def solve(self, parameters=default_parameters()):
        "Solve and return computed solution (u_F, p_F, U_S, P_S, U_M, P_M)"

        # Create submeshes and mappings (only first time)
        if self.Omega is None:

            # Refine original mesh
            mesh = self._original_mesh
            for i in range(parameters["num_initial_refinements"]):
                mesh = refine(mesh)

            # Initialize meshes
            self.init_meshes(mesh, parameters)

        # Create solver
        solver = FSISolver(self)

        # Solve
        return solver.solve(parameters)
Ejemplo n.º 2
0
class FixedPointFSI(CBCProblem):
    """Basic problem class for fixedpoint FSI """

    def __init__(self, mesh):
        "Create FSI problem"
        if dolfin.__version__ > 1:
            print "CBC Swing has not been updated beyond dolfin version 1.0.0, use at your own risk. Press any key to continue"
            foo = raw_input()

        # Initialize base class
        CBCProblem.__init__(self)

        # Store original mesh
        self._original_mesh = mesh
        self.Omega = None

    def solve(self, parameters=default_parameters()):
        "Solve and return computed solution (u_F, p_F, U_S, P_S, U_M, P_M)"

        # Store parameters
        store_parameters(parameters)

        # Create submeshes and mappings (only first time)
        if self.Omega is None:

            # Refine original mesh
            mesh = self._original_mesh
            for i in range(parameters["num_initial_refinements"]):
                mesh = refine(mesh)

            # Initialize meshes
            self.init_meshes(mesh, parameters)

        # Create solver
        self.solver = FSISolver(self)

        # Solve
        return self.solver.solve(parameters)

    def init_meshes(self, Omega, parameters):
        "Create mappings between submeshes"

        info("Extracting fluid and structure submeshes")

        # Set global mesh
        self.Omega = Omega

        # Create cell markers (0 = fluid, 1 = structure)
        D = Omega.topology().dim()
        cell_domains = MeshFunction("uint", self.Omega, D)
        cell_domains.set_all(0)
        structure = self.structure()
        structure.mark(cell_domains, 1)

        # Extract submeshes for fluid and structure
        Omega_F = SubMesh(self.Omega, cell_domains, 0)
        Omega_S = SubMesh(self.Omega, cell_domains, 1)

        info("Computing mappings between submeshes")

        # Extract matching indices for fluid and structure
        fluid_to_structure_v = compute_vertex_map(Omega_F, Omega_S)
        fluid_to_structure_e = compute_edge_map(Omega_F, Omega_S)

        # Extract matching vertex indices for fluid and structure
        v_F = array([i for i in fluid_to_structure_v.iterkeys()])
        v_S = array([i for i in fluid_to_structure_v.itervalues()])

        # Extract matching edge indices for fluid and structure
        e_F = array([i for i in fluid_to_structure_e.iterkeys()])
        e_S = array([i for i in fluid_to_structure_e.itervalues()])

        # Extract matching dofs for fluid and structure
        structure_element_degree = parameters["structure_element_degree"]
        Nv_F = Omega_F.num_vertices()
        Nv_S = Omega_S.num_vertices()
        Ne_F = Omega_F.num_edges()
        Ne_S = Omega_S.num_edges()
        if structure_element_degree == 1:
            fdofs = append(v_F, v_F + Nv_F)
            sdofs = append(v_S, v_S + Nv_S)
        elif structure_element_degree == 2:
            fdofs = append(append(v_F, Nv_F + e_F), append((Nv_F + Ne_F) + v_F, (Nv_F + Ne_F + Nv_F) + e_F))
            sdofs = append(append(v_S, Nv_S + e_S), append((Nv_S + Ne_S) + v_S, (Nv_S + Ne_S + Nv_S) + e_S))
        else:
            error("Only know how to map dofs for P1 and P2 elements.")

        # Extract map from vertices in Omega to vertices in Omega_F
        vertex_map_to_fluid = {}
        vertex_map_from_fluid = Omega_F.data().mesh_function("parent_vertex_indices")
        for i in range(vertex_map_from_fluid.size()):
            vertex_map_to_fluid[vertex_map_from_fluid[i]] = i

        # Extract map from vertices in Omega to vertices in Omega_S
        vertex_map_to_structure = {}
        vertex_map_from_structure = Omega_S.data().mesh_function("parent_vertex_indices")
        for i in range(vertex_map_from_structure.size()):
            vertex_map_to_structure[vertex_map_from_structure[i]] = i

        info("Computing FSI boundary and orientation markers")

        # Initialize FSI boundary and orientation markers on Omega
        Omega.init(D - 1, D)
        fsi_boundary = FacetFunction("uint", Omega, D - 1)
        fsi_boundary.set_all(0)
        fsi_orientation = Omega.data().create_mesh_function("facet_orientation", D - 1)
        fsi_orientation.set_all(0)

        # Initialize FSI boundary on Omega_F
        Omega_F.init(D - 1, D)
        Omega_F.init(0, 1)
        fsi_boundary_F = MeshFunction("uint", Omega_F, D - 1)
        fsi_boundary_F.set_all(0)

        # Initialize FSI boundary on Omega_S
        Omega_S.init(D - 1, D)
        Omega_S.init(0, 1)
        fsi_boundary_S = MeshFunction("uint", Omega_S, D - 1)
        fsi_boundary_S.set_all(0)

        # Compute FSI boundary and orientation markers on Omega
        for facet in facets(Omega):

            # Handle facets on the boundary
            cells = facet.entities(D)
            if len(cells) == 1:

                # Create cell and midpoint
                c = cells[0]
                cell = Cell(Omega, c)
                p = cell.midpoint()

                # Check whether point is inside structure domain
                facet_index = facet.index()
                if structure.inside(p0, True):

                    # On structure boundary
                    fsi_boundary[facet_index] = 1
                    fsi_orientation[facet_index] = c

                else:

                    # On fluid boundary
                    fsi_boundary[facet_index] = 0
                    fsi_orientation[facet_index] = c

                continue

            # Sanity check
            if len(cells) != 2:
                error("Strange, expecting one or two facets!")

            # Create the two cells
            c0, c1 = cells
            cell0 = Cell(Omega, c0)
            cell1 = Cell(Omega, c1)

            # Get the two midpoints
            p0 = cell0.midpoint()
            p1 = cell1.midpoint()

            # Check if the points are inside
            p0_inside = structure.inside(p0, False)
            p1_inside = structure.inside(p1, False)

            # Just set c0, will be set only for FSI facets below
            fsi_orientation[facet.index()] = c0

            # Markers:
            #
            # 0 = fluid
            # 1 = structure
            # 2 = FSI boundary

            # Look for points where exactly one is inside the structure
            facet_index = facet.index()
            if p0_inside and not p1_inside:

                # On FSI boundary
                fsi_boundary[facet_index] = 2
                fsi_orientation[facet_index] = c1
                fsi_boundary_F[_map_to_facet(facet_index, Omega, Omega_F, vertex_map_to_fluid)] = 2
                fsi_boundary_S[_map_to_facet(facet_index, Omega, Omega_S, vertex_map_to_structure)] = 2
            elif p1_inside and not p0_inside:

                # On FSI boundary
                fsi_boundary[facet_index] = 2
                fsi_orientation[facet_index] = c0
                fsi_boundary_F[_map_to_facet(facet_index, Omega, Omega_F, vertex_map_to_fluid)] = 2
                fsi_boundary_S[_map_to_facet(facet_index, Omega, Omega_S, vertex_map_to_structure)] = 2
            elif p0_inside and p1_inside:

                # Inside structure domain
                fsi_boundary[facet_index] = 1
            else:

                # Inside fluid domain
                fsi_boundary[facet_index] = 0

        # Initialize global edge indices (used in read_primal_data)
        init_parent_edge_indices(Omega_F, Omega)
        init_parent_edge_indices(Omega_S, Omega)

        # Store data
        self.Omega_F = Omega_F
        self.Omega_S = Omega_S
        self.cell_domains = cell_domains
        self.fdofs = fdofs
        self.sdofs = sdofs
        self.fsi_boundary = fsi_boundary
        self.fsi_orientation = fsi_orientation
        self.fsi_boundary_F = fsi_boundary_F
        self.fsi_boundary_S = fsi_boundary_S

    def mesh(self):
        "Return mesh for full domain"
        return self.Omega

    def fluid_mesh(self):
        "Return mesh for fluid domain"
        return self.Omega_F

    def structure_mesh(self):
        "Return mesh for structure domain"
        return self.Omega_S

    def add_f2s(self, xs, xf):
        "Compute xs += xf for corresponding indices"
        xs_array = xs.array()
        xf_array = xf.array()
        xs_array[self.sdofs] += xf_array[self.fdofs]
        xs[:] = xs_array

    def add_s2f(self, xf, xs):
        "Compute xf += xs for corresponding indices"
        xf_array = xf.array()
        xs_array = xs.array()
        xf_array[self.fdofs] += xs_array[self.sdofs]
        xf[:] = xf_array

    #--- Optional functions ---

    def update(self, t0, t1, dt):
        return []

    def fluid_body_force(self):
        return []

    def structure_body_force(self):
        return []

    def structure_boundary_traction_extra(self):
        return Constant((0, 0))

    def mesh_right_hand_side(self):
        return Constant((0, 0))

    def exact_solution(self):
        return None

    #Goal Functional
    def evaluate_functional(self, u_F, p_F, U_S, P_S, U_M, dx_F, dx_S, dx_M):
        return inner(u_F,u_F)*dx
Ejemplo n.º 3
0
class FixedPointFSI(CBCProblem):
    """Basic problem class for fixedpoint FSI """
    def __init__(self, mesh):
        "Create FSI problem"
        if dolfin.__version__ > 1:
            print "CBC Swing has not been updated beyond dolfin version 1.0.0, use at your own risk. Press any key to continue"
            foo = raw_input()

        # Initialize base class
        CBCProblem.__init__(self)

        # Store original mesh
        self._original_mesh = mesh
        self.Omega = None

    def solve(self, parameters=default_parameters()):
        "Solve and return computed solution (u_F, p_F, U_S, P_S, U_M, P_M)"

        # Store parameters
        store_parameters(parameters)

        # Create submeshes and mappings (only first time)
        if self.Omega is None:

            # Refine original mesh
            mesh = self._original_mesh
            for i in range(parameters["num_initial_refinements"]):
                mesh = refine(mesh)

            # Initialize meshes
            self.init_meshes(mesh, parameters)

        # Create solver
        self.solver = FSISolver(self)

        # Solve
        return self.solver.solve(parameters)

    def init_meshes(self, Omega, parameters):
        "Create mappings between submeshes"

        info("Extracting fluid and structure submeshes")

        # Set global mesh
        self.Omega = Omega

        # Create cell markers (0 = fluid, 1 = structure)
        D = Omega.topology().dim()
        cell_domains = MeshFunction("uint", self.Omega, D)
        cell_domains.set_all(0)
        structure = self.structure()
        structure.mark(cell_domains, 1)

        # Extract submeshes for fluid and structure
        Omega_F = SubMesh(self.Omega, cell_domains, 0)
        Omega_S = SubMesh(self.Omega, cell_domains, 1)

        info("Computing mappings between submeshes")

        # Extract matching indices for fluid and structure
        fluid_to_structure_v = compute_vertex_map(Omega_F, Omega_S)
        fluid_to_structure_e = compute_edge_map(Omega_F, Omega_S)

        # Extract matching vertex indices for fluid and structure
        v_F = array([i for i in fluid_to_structure_v.iterkeys()])
        v_S = array([i for i in fluid_to_structure_v.itervalues()])

        # Extract matching edge indices for fluid and structure
        e_F = array([i for i in fluid_to_structure_e.iterkeys()])
        e_S = array([i for i in fluid_to_structure_e.itervalues()])

        # Extract matching dofs for fluid and structure
        structure_element_degree = parameters["structure_element_degree"]
        Nv_F = Omega_F.num_vertices()
        Nv_S = Omega_S.num_vertices()
        Ne_F = Omega_F.num_edges()
        Ne_S = Omega_S.num_edges()
        if structure_element_degree == 1:
            fdofs = append(v_F, v_F + Nv_F)
            sdofs = append(v_S, v_S + Nv_S)
        elif structure_element_degree == 2:
            fdofs = append(
                append(v_F, Nv_F + e_F),
                append((Nv_F + Ne_F) + v_F, (Nv_F + Ne_F + Nv_F) + e_F))
            sdofs = append(
                append(v_S, Nv_S + e_S),
                append((Nv_S + Ne_S) + v_S, (Nv_S + Ne_S + Nv_S) + e_S))
        else:
            error("Only know how to map dofs for P1 and P2 elements.")

        # Extract map from vertices in Omega to vertices in Omega_F
        vertex_map_to_fluid = {}
        vertex_map_from_fluid = Omega_F.data().mesh_function(
            "parent_vertex_indices")
        for i in range(vertex_map_from_fluid.size()):
            vertex_map_to_fluid[vertex_map_from_fluid[i]] = i

        # Extract map from vertices in Omega to vertices in Omega_S
        vertex_map_to_structure = {}
        vertex_map_from_structure = Omega_S.data().mesh_function(
            "parent_vertex_indices")
        for i in range(vertex_map_from_structure.size()):
            vertex_map_to_structure[vertex_map_from_structure[i]] = i

        info("Computing FSI boundary and orientation markers")

        # Initialize FSI boundary and orientation markers on Omega
        Omega.init(D - 1, D)
        fsi_boundary = FacetFunction("uint", Omega, D - 1)
        fsi_boundary.set_all(0)
        fsi_orientation = Omega.data().create_mesh_function(
            "facet_orientation", D - 1)
        fsi_orientation.set_all(0)

        # Initialize FSI boundary on Omega_F
        Omega_F.init(D - 1, D)
        Omega_F.init(0, 1)
        fsi_boundary_F = MeshFunction("uint", Omega_F, D - 1)
        fsi_boundary_F.set_all(0)

        # Initialize FSI boundary on Omega_S
        Omega_S.init(D - 1, D)
        Omega_S.init(0, 1)
        fsi_boundary_S = MeshFunction("uint", Omega_S, D - 1)
        fsi_boundary_S.set_all(0)

        # Compute FSI boundary and orientation markers on Omega
        for facet in facets(Omega):

            # Handle facets on the boundary
            cells = facet.entities(D)
            if len(cells) == 1:

                # Create cell and midpoint
                c = cells[0]
                cell = Cell(Omega, c)
                p = cell.midpoint()

                # Check whether point is inside structure domain
                facet_index = facet.index()
                if structure.inside(p0, True):

                    # On structure boundary
                    fsi_boundary[facet_index] = 1
                    fsi_orientation[facet_index] = c

                else:

                    # On fluid boundary
                    fsi_boundary[facet_index] = 0
                    fsi_orientation[facet_index] = c

                continue

            # Sanity check
            if len(cells) != 2:
                error("Strange, expecting one or two facets!")

            # Create the two cells
            c0, c1 = cells
            cell0 = Cell(Omega, c0)
            cell1 = Cell(Omega, c1)

            # Get the two midpoints
            p0 = cell0.midpoint()
            p1 = cell1.midpoint()

            # Check if the points are inside
            p0_inside = structure.inside(p0, False)
            p1_inside = structure.inside(p1, False)

            # Just set c0, will be set only for FSI facets below
            fsi_orientation[facet.index()] = c0

            # Markers:
            #
            # 0 = fluid
            # 1 = structure
            # 2 = FSI boundary

            # Look for points where exactly one is inside the structure
            facet_index = facet.index()
            if p0_inside and not p1_inside:

                # On FSI boundary
                fsi_boundary[facet_index] = 2
                fsi_orientation[facet_index] = c1
                fsi_boundary_F[_map_to_facet(facet_index, Omega, Omega_F,
                                             vertex_map_to_fluid)] = 2
                fsi_boundary_S[_map_to_facet(facet_index, Omega, Omega_S,
                                             vertex_map_to_structure)] = 2
            elif p1_inside and not p0_inside:

                # On FSI boundary
                fsi_boundary[facet_index] = 2
                fsi_orientation[facet_index] = c0
                fsi_boundary_F[_map_to_facet(facet_index, Omega, Omega_F,
                                             vertex_map_to_fluid)] = 2
                fsi_boundary_S[_map_to_facet(facet_index, Omega, Omega_S,
                                             vertex_map_to_structure)] = 2
            elif p0_inside and p1_inside:

                # Inside structure domain
                fsi_boundary[facet_index] = 1
            else:

                # Inside fluid domain
                fsi_boundary[facet_index] = 0

        # Initialize global edge indices (used in read_primal_data)
        init_parent_edge_indices(Omega_F, Omega)
        init_parent_edge_indices(Omega_S, Omega)

        # Store data
        self.Omega_F = Omega_F
        self.Omega_S = Omega_S
        self.cell_domains = cell_domains
        self.fdofs = fdofs
        self.sdofs = sdofs
        self.fsi_boundary = fsi_boundary
        self.fsi_orientation = fsi_orientation
        self.fsi_boundary_F = fsi_boundary_F
        self.fsi_boundary_S = fsi_boundary_S

    def mesh(self):
        "Return mesh for full domain"
        return self.Omega

    def fluid_mesh(self):
        "Return mesh for fluid domain"
        return self.Omega_F

    def structure_mesh(self):
        "Return mesh for structure domain"
        return self.Omega_S

    def add_f2s(self, xs, xf):
        "Compute xs += xf for corresponding indices"
        xs_array = xs.array()
        xf_array = xf.array()
        xs_array[self.sdofs] += xf_array[self.fdofs]
        xs[:] = xs_array

    def add_s2f(self, xf, xs):
        "Compute xf += xs for corresponding indices"
        xf_array = xf.array()
        xs_array = xs.array()
        xf_array[self.fdofs] += xs_array[self.sdofs]
        xf[:] = xf_array

    #--- Optional functions ---

    def update(self, t0, t1, dt):
        return []

    def fluid_body_force(self):
        return []

    def structure_body_force(self):
        return []

    def structure_boundary_traction_extra(self):
        return Constant((0, 0))

    def mesh_right_hand_side(self):
        return Constant((0, 0))

    def exact_solution(self):
        return None

    #Goal Functional
    def evaluate_functional(self, u_F, p_F, U_S, P_S, U_M, dx_F, dx_S, dx_M):
        return inner(u_F, u_F) * dx