Beispiel #1
0
def create_grid(**mesh_kwargs):
    """
    Create a grid bucket containing grids from gmsh.

    NOTE: The line setting 'path_to_gmsh' *must* be modified for this to work.

    Parameters concerning mesh size, domain size etc. may also be changed, see
    below.

    Returns:
        grid_bucket: A grid_bucket containing the full hierarchy of grids.

    """
    num_fracs = mesh_kwargs.get('num_fracs', 39)

    # If the
    # Don't change the path, or move the file
    data = _soultz_data()
    data = data[:num_fracs, :]

    # Data format of the data file is (frac_num, fracture center_xyz, major
    # axis, minor axis, dip direction, dip angle)
    centers = data[:, 1:4]
    major_axis = data[:, 4]
    minor_axis = data[:, 5]

    dip_direction = data[:, 6] / 180 * np.pi
    dip_angle = data[:, 7] / 180 * np.pi

    # We will define the fractures as elliptic fractures. For this we need
    # strike angle, rather than dip direction.
    strike_angle = dip_direction + np.pi / 2

    # Modifications of the fracture definition:
    # These are carried out to ease the gridding; without these, we will end up
    # with gridding polygons that have very close points. The result may be

    # Minor axis angle. This is specified as zero (the fractures are
    # interpreted as circles), but we rotate them in an attempt to avoid close
    # points in the fracture specification.
    # Also note that since the fractures are defined as circles, any
    # orientation of the approximating polygon is equally correct
    major_axis_angle = np.zeros(num_fracs)
    #   major_axis_angle[14] = 5 * np.pi / 180
    ##    major_axis_angle[24] = 5 * np.pi / 180
    #    major_axis_angle[26] = 5 * np.pi / 180
    ##    major_axis_angle[32-1] = 5 * np.pi / 180

    # Also modify some centers. This may potentially have some impact on the
    # properties of the fracture network, but they been selected as to not
    # modify the fracture network properties.
    #   centers[3, 2] += 30
    if num_fracs > 10:
        centers[11, 2] += 15


#    centers[8, 2] -= 10
#    centers[19, 2] -= 20
#    centers[22, 2] -= 10
#    centers[23, 1:3] -= 15
#    centers[24, 2] += 30
#    centers[25, 2] += 10
#    centers[29, 2] -= 30
#    centers[30, 2] += 30
#    centers[31, 2] += 30
#    centers[34, 2] -= 10
#    centers[38, 2] -= 10

# Create a set of fractures
    frac_list = []
    num_points = mesh_kwargs.get('num_points', 16)
    for fi in range(data.shape[0]):
        frac_new = EllipticFracture(centers[fi],
                                    major_axis[fi],
                                    minor_axis[fi],
                                    major_axis_angle[fi],
                                    strike_angle[fi],
                                    dip_angle[fi],
                                    num_points=num_points)
        frac_list.append(frac_new)

    # Create the network, dump to vtu
    network = FractureNetwork(frac_list, verbose=1, tol=1e-4)
    network.to_vtk('soultz_fractures_full.vtu')

    # Impose domain boundaries. These are set large enough to not be in
    # conflict with the network.
    # This may be changed if desirable.
    domain = {
        'xmin': -4000,
        'xmax': 4000,
        'ymin': -3000,
        'ymax': 3000,
        'zmin': 0,
        'zmax': 8000
    }
    domain = mesh_kwargs.get('domain', domain)
    network.impose_external_boundary(domain)

    # Find intersections, and split these
    network.find_intersections()
    network.split_intersections()

    # This may be changed, if desirable.
    if mesh_kwargs is None:
        mesh_size = {'mode': 'constant', 'value': 150, 'bound_value': 500}
        mesh_kwargs = {'mesh_size': mesh_size, 'file_name': 'soultz_fracs'}
    # Since we have a ready network (and may want to take this file into
    # jupyter and study the network before gridding), we abuse the workflow
    # slightly by calling simplex_tetrahedral directly, rather than to go the
    # way through meshing.simplex_grid (the latter is, for now, restricted to
    # specifying the grid by individual fractures, rather than networks).
    grids = simplex.tetrahedral_grid(network=network, **mesh_kwargs)

    # Convert the grids into a bucket
    meshing.tag_faces(grids)
    gb = meshing.assemble_in_bucket(grids)
    gb.compute_geometry()

    split_grid.split_fractures(gb)
    return gb
Beispiel #2
0
def network_3d_from_csv(file_name, has_domain=True, tol=1e-4):
    """
    Create the fracture network from a set of 3d fractures stored in a csv file and
    domain. In the csv file, we assume the following structure
    - first line (optional) describes the domain as a rectangle with
      X_MIN, Y_MIN, Z_MIN, X_MAX, Y_MAX, Z_MAX
    - the other lines descibe the N fractures as a list of points
      P0_X, P0_Y, P0_Z, ...,PN_X, PN_Y, PN_Z

    Parameters:
        file_name: name of the file
        has_domain: if the first line in the csv file specify the domain
        tol: (optional) tolerance for the methods

    Return:
        frac_list: the list of fractures
        network: the fracture network
        domain: (optional, returned if has_domain==True) the domain
    """

    # The first line of the csv file defines the bounding box for the domain

    frac_list = []
    # Extract the data from the csv file
    with open(file_name, 'r') as csv_file:
        spam_reader = csv.reader(csv_file, delimiter=',')

        # Read the domain first
        if has_domain:
            domain = np.asarray(next(spam_reader), dtype=np.float)
            assert domain.size == 6
            domain = {
                'xmin': domain[0],
                'xmax': domain[3],
                'ymin': domain[1],
                'ymax': domain[4],
                'zmin': domain[2],
                'zmax': domain[5]
            }

        for row in spam_reader:
            # Read the points
            pts = np.asarray(row, dtype=np.float)
            assert pts.size % 3 == 0
            frac_list.append(Fracture(pts.reshape((3, -1), order='F')))

    # Create the network
    network = FractureNetwork(frac_list, tol=tol)

    # Cut the fractures due to the domain
    if has_domain:
        network.impose_external_boundary(domain)

    # Find intersections, and split these
    network.find_intersections()
    network.split_intersections()

    if has_domain:
        return frac_list, network, domain
    else:
        return frac_list, network