Exemplo n.º 1
0
  def __init__(self, problem, verbosity=0):
    """

    :param ProblemData problem:
    :param int verbosity:
    :return:
    """
    self.parameters = parameters["discretization"]

    self.verb = verbosity
    self.vis_folder = os.path.join(problem.out_folder, "MESH")
    self.core = problem.core
    self.G = problem.G

    if self.verb > 1: print pid+"Loading mesh"
        
    t_load = Timer("DD: Data loading")

    if not problem.mesh_module:
      if self.verb > 1: print pid + "  mesh data"
      self.mesh = Mesh(problem.mesh_files.mesh)

      if self.verb > 1: print pid + "  physical data"
      self.cell_regions_fun = MeshFunction("size_t", self.mesh, problem.mesh_files.physical_regions)

      if self.verb > 1: print pid + "  boundary data"
      self.boundaries = MeshFunction("size_t", self.mesh, problem.mesh_files.facet_regions)
    else:
      self.mesh = problem.mesh_module.mesh
      self.cell_regions_fun = problem.mesh_module.regions

      try:
        self.boundaries = problem.mesh_module.boundaries
      except AttributeError:
        self.boundaries = None

    assert self.mesh
    assert self.boundaries is None or self.boundaries.array().size > 0

    if self.verb > 2:
      print pid+"  mesh info: " + str(self.mesh)

    if self.verb > 1: print0("Defining function spaces" )

    self.t_spaces = Timer("DD: Function spaces construction")

    # Spaces that must be specified by the respective subclasses
    self.V = None     # solution space
    self.Vphi1 = None # 1-g scalar flux space
    
    # XS / TH space
    self.V0 = FunctionSpace(self.mesh, "DG", 0)
    self.ndof0 = self.V0.dim()

    dofmap = self.V0.dofmap()
    self.local_ndof0 = dofmap.local_dimension("owned")

    self.cell_regions = self.cell_regions_fun.array()
    assert self.cell_regions.size == self.local_ndof0
Exemplo n.º 2
0
def construct_A_from_mesh_functions(dim, A_expr, mesh):

    if dim == 2:
        a01 = MeshFunction("double", mesh, dim)
        a11 = MeshFunction("double", mesh, dim)

    A1 = A_expr[0]
    A2 = A_expr[1]

    a00 = MeshFunction("double", mesh, dim)

    for cell in cells(mesh):
        if cell.midpoint().x() < 0.5:
            if dim == 2:
                a00[cell] = A1[0][0]
                a11[cell] = A1[1][1]
                a01[cell] = A1[0][1]
        else:
            if dim == 2:
                a00[cell] = A2[0][0]
                a11[cell] = A2[1][1]
                a01[cell] = A2[0][1]

    # Code for C++ evaluation of conductivity
    conductivity_code = """

    class Conductivity : public Expression
    {
    public:

      // Create expression with 3 components
      Conductivity() : Expression(3) {}

      // Function for evaluating expression on each cell
      void eval(Array<double>& values, const Array<double>& x, const ufc::cell& cell) const
      {
        const uint D = cell.topological_dimension;
        const uint cell_index = cell.index;
        values[0] = (*a00)[cell_index];
        values[1] = (*a01)[cell_index];
        values[2] = (*a11)[cell_index];
      }

      // The data stored in mesh functions
      std::shared_ptr<MeshFunction<double> > a00;
      std::shared_ptr<MeshFunction<double> > a01;
      std::shared_ptr<MeshFunction<double> > a11;

    };
    """

    a = Expression(cppcode=conductivity_code)
    a.a00 = a00
    a.a01 = a01
    a.a11 = a11
    A = as_matrix(((a[0], a[1]), (a[1], a[2])))

    return A
Exemplo n.º 3
0
def markBoundarySubdomains(mesh, boundaries, **kwargs):
    '''Mark the boundaries of a mesh given a geometry
    
    All interior faces are marked with zero
    
    boundaries is a dictionary {label: definition of boundary}
    '''
    
    bndSubdomains = MeshFunction("size_t", mesh, mesh.geometry().dim()-1)
    bndSubdomains.set_all(0)
    
    for i in boundaries:
        class BndSubDomain(SubDomain):
            def inside(self, x, on_boundary):
                value = array([0.0])
                boundaries[i].eval(value, x)
                return (value==1.0) and on_boundary
        aux = BndSubDomain()
        aux.mark(bndSubdomains, i)
        
    # Save Dolfin XML format of the subdomains
    if 'outputXmlGz' in kwargs:
        File(kwargs['outputXmlGz']) << bndSubdomains
        
    # Save sub domains to VTK files
    if 'outputPvd' in kwargs:
        File(kwargs['outputPvd']) << bndSubdomains
        
    return bndSubdomains
    
## If there exist dirichlet boundary
#if hasDirichlet:
#    if os.path.isfile(dirichletPath):
#        dirichletSubdomain = MeshFunction("bool", mesh, dirichletPath)
#    else:
#        # Mark faces
#        dirichletSubdomain.set_all(False)
#        class Aux(SubDomain):
#            def inside(self, x, on_boundary):
#                value = array([0.0])
#                physics.dirichletBnd.eval(value, x)
#                return (value==1.0) and on_boundary
#        aux = Aux()
#        aux.mark(dirichletSubdomain, True)
#        aux.mark(bndSubdomains, 0)
Exemplo n.º 4
0
    def __init__(self, args, tc, metadata):
        self.has_analytic_solution = False
        self.problem_code = 'FACB'
        super(Problem, self).__init__(args, tc, metadata)

        self.name = 'test on real mesh'
        self.status_functional_str = 'not selected'

        # input parameters
        self.factor = args.factor
        self.scale_factor.append(self.factor)

        self.nu = 0.001 * args.nufactor  # kinematic viscosity

        # Import gmsh mesh
        self.compatible_meshes = ['bench3D_1', 'bench3D_2', 'bench3D_3']
        if args.mesh not in self.compatible_meshes:
            exit('Bad mesh, should be some from %s' %
                 str(self.compatible_meshes))

        self.mesh = Mesh("meshes/" + args.mesh + ".xml")
        self.cell_function = MeshFunction(
            "size_t", self.mesh,
            "meshes/" + args.mesh + "_physical_region.xml")
        self.facet_function = MeshFunction(
            "size_t", self.mesh, "meshes/" + args.mesh + "_facet_region.xml")
        self.dsIn = Measure("ds",
                            subdomain_id=2,
                            subdomain_data=self.facet_function)
        self.dsOut = Measure("ds",
                             subdomain_id=3,
                             subdomain_data=self.facet_function)
        self.dsWall = Measure("ds",
                              subdomain_id=1,
                              subdomain_data=self.facet_function)
        self.dsCyl = Measure("ds",
                             subdomain_id=5,
                             subdomain_data=self.facet_function)
        self.normal = FacetNormal(self.mesh)
        print("Mesh name: ", args.mesh, "    ", self.mesh)
        print("Mesh norm max: ", self.mesh.hmax())
        print("Mesh norm min: ", self.mesh.hmin())

        self.actual_time = None
        self.v_in = None
Exemplo n.º 5
0
def markBoundariesOfMesh(mesh, geo, **kwargs):
    '''Mark the boundaries of a mesh given a geometry
    
    All interior faces are marked with zero
    
    If the geometry has no marks, it will be mared using the convention:
    face[0] = 1
    face[1] = 2
    ...
    face[N] = N+1
    '''
    
    # Reference point indexes in each face
    geoBndPoints = [ face[0] for face in geo._faces ]

    # Face normals
    geoNormals = geo.getNormals()

    # Create mesh functions over the cell facets
    faceSubdomains = MeshFunction("size_t", mesh, geo._nDim-1)

    # Mark all facets of the domain as 0
    faceSubdomains.set_all(0)

    # Mark boundary faces for face elements
    for i in range(geo.getNoFaces()):
        class BndSubDomain(SubDomain):
            def inside(self, x, on_boundary):
                return near( geoNormals[i].dot(Point(x)-geo._points[geoBndPoints[i]]), 0.0 ) and on_boundary
        aSubDomain = BndSubDomain()
        label = i+1
        if hasattr(geo, 'facesMarkers'):
            label = geo.facesMarkers[i]
        aSubDomain.mark(faceSubdomains, label)
        
    # Save Dolfin XML format of the subdomains
    if 'outputXmlGz' in kwargs:
        File(kwargs['outputXmlGz']) << faceSubdomains
        
    # Save sub domains to VTK files
    if 'outputPvd' in kwargs:
        File(kwargs['outputPvd']) << faceSubdomains
        
    return faceSubdomains
Exemplo n.º 6
0
 def loadMesh(mesh):
     """
     :param mesh: name of mesh file (without extension)
     :return: tuple mesh, facet function read from .hdf5 file
     """
     f = HDF5File(mpi_comm_world(), 'meshes/'+mesh+'.hdf5', 'r')
     mesh = Mesh()
     f.read(mesh, 'mesh', False)
     facet_function = MeshFunction("size_t", mesh)
     f.read(facet_function, 'facet_function')
     return mesh, facet_function
# Load mesh
if isfile(meshPath):
    mesh = Mesh(meshPath)
else:
    print("Mesh bndFile does not exist!")
    exit(1)
#plot(mesh, interactive=True)

###
### Mesh
###

# Here we consider 0 as a internal face
bndSubdomains = markBoundariesOfMesh(mesh, geo, outputPvd="localBoundary.pvd")
globalBndSubdomains = MeshFunction("size_t", mesh, geo._nDim - 1)

# If there exist marked boundary
if 'boundaries' in dir(physics):
    if (reutilizeBoundaryInfo and isfile(bndPath)):
        globalBndSubdomains = MeshFunction("size_t", mesh, bndPath)
    else:
        globalBndSubdomains = markBoundarySubdomains(mesh,
                                                     physics.boundaries,
                                                     outputXmlGz=bndPath,
                                                     outputPvd=bndPvd)
else:
    globalBndSubdomains.set_all(0)

# Boundary measures
ds = Measure('ds', domain=mesh, subdomain_data=bndSubdomains)
Exemplo n.º 8
0
def construct_from_mesh_functions(dim, A_expr, mesh):
    """
    :param dim: geometrical dimension
    :param A_expr: expression defining diffusion matrix
    :param mesh: mesh-discretization of the domain
    :return: cell-wise function
    """

    # Define scalar cell-wise function for dim = 1
    a00 = MeshFunction("double", mesh, dim)
    # Define function expression from the problem data (depending on how many of the conditions are discussed )
    A1 = A_expr[0]
    A2 = A_expr[1]

    # Case for dimension higher then one (symmetric case)
    if dim >= 2:
        a01 = MeshFunction("double", mesh, dim)
        a11 = MeshFunction("double", mesh, dim)
    # Case for dimension higher then two (symmetric case)
    if dim >= 3:
        a02 = MeshFunction("double", mesh, dim)
        a12 = MeshFunction("double", mesh, dim)
        a22 = MeshFunction("double", mesh, dim)

    for cell in cells(mesh):
        if cell.midpoint().x(
        ) < 0.5:  # this condition checks whethe the elements on the left part of the domain
            A = A_expr[0]
        else:
            A = A_expr[1]

        a00[cell] = A[0][0]
        if dim >= 2:
            a11[cell] = A[1][1]
            a01[cell] = A[0][1]
        if dim >= 3:
            a02[cell] = A[0][2]
            a12[cell] = A[1][2]
            a22[cell] = A[2][2]

    # Code for C++ evaluation of conductivity
    conductivity_code = """

    class Conductivity : public Expression
    {
    public:

      // Create expression with 3 components
      Conductivity() : Expression(3) {}

      // Function for evaluating expression on each cell
      void eval(Array<double>& values, const Array<double>& x, const ufc::cell& cell) const
      {
        const uint D = cell.topological_dimension;
        const uint cell_index = cell.index;
        values[0] = (*a00)[cell_index];
        values[1] = (*a01)[cell_index];
        values[2] = (*a11)[cell_index];
      }

      // The data stored in mesh functions
      std::shared_ptr<MeshFunction<double> > a00;
      std::shared_ptr<MeshFunction<double> > a01;
      std::shared_ptr<MeshFunction<double> > a11;

    };
    """
    # Define expression via C++ code
    a = Expression(cppcode=conductivity_code)
    a.a00 = a00
    if dim >= 2:
        a.a01 = a01
        a.a11 = a11
    if dim >= 3:
        a.a02 = a02
        a.a12 = a12
        a.a22 = a22
    # Define matrix depending on the dimension
    if dim == 1:
        A = a[0]
    elif dim == 2:
        # A = |a[0] a[1]|
        #     |a[1] a[2]|
        A = as_matrix(((a[0], a[1]), (a[1], a[2])))
    elif dim == 3:
        # A = |a[0] a[1] a[2]|
        #     |a[1] a[3] a[4]|
        #     |a[2] a[4] a[5]|
        A = as_matrix(
            ((a[0], a[1], a[2]), (a[1], a[3], a[4]), (a[2], a[3], a[5])))

    return A
Exemplo n.º 9
0
class Discretization(object):
  def __init__(self, problem, verbosity=0):
    """

    :param ProblemData problem:
    :param int verbosity:
    :return:
    """
    self.parameters = parameters["discretization"]

    self.verb = verbosity
    self.vis_folder = os.path.join(problem.out_folder, "MESH")
    self.core = problem.core
    self.G = problem.G

    if self.verb > 1: print pid+"Loading mesh"
        
    t_load = Timer("DD: Data loading")

    if not problem.mesh_module:
      if self.verb > 1: print pid + "  mesh data"
      self.mesh = Mesh(problem.mesh_files.mesh)

      if self.verb > 1: print pid + "  physical data"
      self.cell_regions_fun = MeshFunction("size_t", self.mesh, problem.mesh_files.physical_regions)

      if self.verb > 1: print pid + "  boundary data"
      self.boundaries = MeshFunction("size_t", self.mesh, problem.mesh_files.facet_regions)
    else:
      self.mesh = problem.mesh_module.mesh
      self.cell_regions_fun = problem.mesh_module.regions

      try:
        self.boundaries = problem.mesh_module.boundaries
      except AttributeError:
        self.boundaries = None

    assert self.mesh
    assert self.boundaries is None or self.boundaries.array().size > 0

    if self.verb > 2:
      print pid+"  mesh info: " + str(self.mesh)

    if self.verb > 1: print0("Defining function spaces" )

    self.t_spaces = Timer("DD: Function spaces construction")

    # Spaces that must be specified by the respective subclasses
    self.V = None     # solution space
    self.Vphi1 = None # 1-g scalar flux space
    
    # XS / TH space
    self.V0 = FunctionSpace(self.mesh, "DG", 0)
    self.ndof0 = self.V0.dim()

    dofmap = self.V0.dofmap()
    self.local_ndof0 = dofmap.local_dimension("owned")

    self.cell_regions = self.cell_regions_fun.array()
    assert self.cell_regions.size == self.local_ndof0

  def __create_cell_dof_mapping(self, dofmap):
    """
    Generate cell -> dof mapping for all cells of current partition.
    Note: in DG(0) space, there is one dof per element and no ghost cells.

    :param GenericDofMap dofmap: DG(0) dofmap
    """

    if self.verb > 2: print0("Constructing cell -> dof mapping")
    timer = Timer("DD: Cell->dof construction")

    code = \
    '''
      #include <dolfin/mesh/Cell.h>

      namespace dolfin
      {
        void fill_in(Array<int>& local_cell_dof_map, const Mesh& mesh, const GenericDofMap& dofmap)
        {
          std::size_t local_dof_range_start = dofmap.ownership_range().first;
          int* cell_dof_data = local_cell_dof_map.data();

          for (CellIterator c(mesh); !c.end(); ++c)
            *cell_dof_data++ = dofmap.cell_dofs(c->index())[0] - local_dof_range_start;
        }
      }
    '''

    cell_mapping_module = compile_extension_module(code)
    cell_dof_array = IntArray(self.local_ndof0)
    cell_mapping_module.fill_in(cell_dof_array, self.mesh, dofmap)
    self._local_cell_dof_map = cell_dof_array.array()

    timer.stop()

  def __create_cell_layers_mapping(self):
    """
    Generate a cell -> axial layer mapping for all cells of current partition. Note that keys are ordered by the
    associated DG(0) dof, not by the cell index in the mesh.
    """

    if self.verb > 2: print0("Constructing cell -> layer mapping")
    timer = Timer("DD: Cell->layer construction")

    code = \
    '''
      #include <dolfin/mesh/Cell.h>

      namespace dolfin
      {
        void fill_in(Array<int>& local_cell_layers,
                     const Mesh& mesh, const Array<int>& cell_dofs, const Array<double>& layer_boundaries)
        {
          std::size_t num_layers = layer_boundaries.size() - 1;
          unsigned int layer;

          for (CellIterator c(mesh); !c.end(); ++c)
          {
            double midz = c->midpoint().z();
            for (layer = 0; layer < num_layers; layer++)
              if (layer_boundaries[layer] <= midz && midz <= layer_boundaries[layer+1])
                break;

            int dof = cell_dofs[c->index()];
            local_cell_layers[dof] = layer;
          }
        }
      }
    '''

    cell_mapping_module = compile_extension_module(code)

    cell_layers_array =  IntArray(self.local_ndof0)
    cell_mapping_module.fill_in(cell_layers_array, self.mesh, self.local_cell_dof_map, self.core.layer_boundaries)
    self._local_cell_layers = cell_layers_array.array()

    timer.stop()

  def __create_cell_vol_mapping(self):
    """
    Generate cell -> volume mapping for all cells of current partition. Note that keys are ordered by the
    associated DG(0) dof, not by the cell index in the mesh.

    This map is required for calculating various densities from total region integrals (like cell power densities from
    cell-integrated powers).
    """

    if self.verb > 2: print0("Constructing cell -> volume mapping")
    timer = Timer("DD: Cell->vol construction")

    code = \
    '''
      #include <dolfin/mesh/Cell.h>

      namespace dolfin
      {
        void fill_in(Array<double>& cell_vols, const Mesh& mesh, const Array<int>& cell_dofs)
        {
          for (CellIterator c(mesh); !c.end(); ++c)
            cell_vols[cell_dofs[c->index()]] = c->volume();
        }
      }
    '''

    cell_mapping_module = compile_extension_module(code)
    cell_vol_array = DoubleArray(self.local_ndof0)
    cell_mapping_module.fill_in(cell_vol_array, self.mesh, self.local_cell_dof_map)
    self._local_cell_volumes = cell_vol_array.array()

    timer.stop()

  @property
  def local_cell_dof_map(self):
    try:
      self._local_cell_dof_map
    except AttributeError:
      self.__create_cell_dof_mapping(self.V0.dofmap())
    return self._local_cell_dof_map

  @property
  def local_cell_volumes(self):
    try:
      self._local_cell_volumes
    except AttributeError:
      self.__create_cell_vol_mapping()
    return self._local_cell_volumes

  @property
  def local_cell_layers(self):
    try:
      self._local_cell_layers
    except AttributeError:
      self.__create_cell_layers_mapping()
    return self._local_cell_layers

  def visualize_mesh_data(self):
    timer = Timer("DD: Mesh data visualization")
    if self.verb > 2: print0("Visualizing mesh data")

    File(os.path.join(self.vis_folder, "mesh.pvd"), "compressed") << self.mesh
    if self.boundaries:
      File(os.path.join(self.vis_folder, "boundaries.pvd"), "compressed") << self.boundaries
    File(os.path.join(self.vis_folder, "mesh_regions.pvd"), "compressed") << self.cell_regions_fun

    # Create MeshFunction to hold cell process rank
    processes = CellFunction('size_t', self.mesh, MPI.rank(comm))
    File(os.path.join(self.vis_folder, "mesh_partitioning.pvd"), "compressed") << processes

  def print_diagnostics(self):
    print "\nDiscretization diagnostics"

    print MPI.rank(comm), self.mesh.num_entities(self.mesh.topology().dim())

    dofmap = self.V0.dofmap()

    print MPI.rank(comm), dofmap.ownership_range()
    print MPI.rank(comm), numpy.min(dofmap.collapse(self.mesh)[1].values()), \
          numpy.max(dofmap.collapse(self.mesh)[1].values())

    print "#Owned by {}: {}".format(MPI.rank(comm), dofmap.local_dimension("owned"))
    print "#Unowned by {}: {}".format(MPI.rank(comm), dofmap.local_dimension("unowned"))