Skip to content
This repository has been archived by the owner on Nov 13, 2023. It is now read-only.

[Feature request] Mixed dimensional embedment meshing #194

Open
BinWang0213 opened this issue Feb 18, 2021 · 10 comments
Open

[Feature request] Mixed dimensional embedment meshing #194

BinWang0213 opened this issue Feb 18, 2021 · 10 comments

Comments

@BinWang0213
Copy link

Is possible to perform mixed-dimensional meshing by embedment?
Such as: https://gitlab.onelab.info/gmsh/gmsh/blob/gmsh_4_7_1/tutorial/t15.geo

If so, we can mesh a geology model with fault and fractures, such as
image

@krober10nd
Copy link
Owner

Hey Bin, thanks for your interest! This is a intriguing idea. Firstly no, SM does not currently support mixed-dimensional embedment. I had thought about this at one point because faults are a big thing in seismology but never came up with a great solution.

It's a bit tricky. Theoretically, first thing to get this mixed-dimension embedment, we would need to immerse a 2D signed distance function in a 3D one. If that's possible, then it should also be possible to compute intersections of these mixed-dimensional geometry. And then if that's possible, it would be possible to immerse the set like I can do already in SM.

However, the problem with the 2D SDF in a 3D geometry is that the notion of "in" or "out" the domain isn't well defined anymore. In other words, implicit representation can only be used for closed surfaces.

One solution: it might be possible to mesh an open subset of a surface geometry using a second implicit function that defines the new boundaries (i.e., one SDF is used for the x-y plane and a second for the y-z plane).

As a current possible hack, what you could do is supply the points of the 2d immersed object as pfix to the generator function. This would give you the overall shape of the structure but some edges wouldn't be aligned with it.

I'll think about it more.

@krober10nd
Copy link
Owner

Hey @BinWang0213 do you have an example of a fault you'd like to constrain in a 3d domain? It'd be helpful to have a dataset to experiment with here.

@BinWang0213
Copy link
Author

BinWang0213 commented Feb 21, 2021

Thanks for your detailed explanations.

Sure. Here is an example model you can test with:
image
Box domain: [-0.6, -0.6, -0.6] -> [0.6, 0.6, 0.6]
Falults/Fractures: 4 fractures intersected together

It includes the paraview vtp files and gmsh input file:
input_files.zip

This was referenced Feb 22, 2021
@krober10nd
Copy link
Owner

I haven't forgot about this! I'm nearly finished with the geometric primitives that are necessary to embed structures like this (translation, rotation, and stretching).

@BinWang0213
Copy link
Author

Nice to hear from you! Looking forward to your updates!

@krober10nd
Copy link
Owner

krober10nd commented Mar 12, 2021

@BinWang0213 I've added translation, rotation, and stretching to all the geometric primitives in the latest release SM 3.9 which now should allow you to get creative with these faults.

For example to create a similar example to the one you showed, I computed the union of several relatively thin cubes (i.e., fault-like) each one rotated and translated to resemble the image you gave above. You can visualize your creation with the domain.show() functionality. Note that all rotations and translations are relative to the origin so best build the mesh around the origin and then translate it later on.

Using the immerse option in generate_mesh I'm able to respect these structures more or less. It's not perfect but it's a start! To smooth intersections between faults, SDFs can be intersected with a smoothing parameter, which is not implemented yet.

show_faults2
show_faults

 import meshio
 
 import SeismicMesh as sm
 
 parent = sm.Cube((-0.6, 0.6, -0.6, 0.6, -0.6, 0.6))
 
 cubes = []
 cubes.append(sm.Cube((-0.5, 0.5, -0.5, 0.5, 0.0, 0.1)))
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1), rotate=0.50 * 3.14, translate=[0.0, 0.0, 0.25]
     )
 )
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1), rotate=0.50 * 3.14, translate=[0, 0.25, -0.25]
     )
 )
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1),
         rotate=0.50 * 3.14,
         translate=[0, -0.25, -0.25],
     )
 )
 
 faults = sm.Union(cubes)
 # faults.show(samples=1e6)
 
 points, cells = sm.generate_mesh(
     domain=parent, edge_length=0.05, subdomains=[faults], verbose=2, max_iter=5
 )
 
 meshio.write_points_cells(
     "cube_with_faults.vtk",
     points,
     [("tetra", cells)],
     point_data={"sd": faults.eval(points)},
     file_format="vtk",
 )

@krober10nd
Copy link
Owner

I've added some more complexity to show how you can add mesh refinement near the immersed structures and ensure the mesh is sliver-free.

 import meshio
 
 import SeismicMesh as sm
 
 parent = sm.Cube((-0.6, 0.6, -0.6, 0.6, -0.6, 0.6))
 
 cubes = []
 cubes.append(sm.Cube((-0.5, 0.5, -0.5, 0.5, 0.0, 0.1)))
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1), rotate=0.50 * 3.14, translate=[0.0, 0.0, 0.25]
     )
 )
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1), rotate=0.50 * 3.14, translate=[0, 0.25, -0.25]
     )
 )
 cubes.append(
     sm.Cube(
         (-0.5, 0.5, -0.5, 0.5, 0.0, 0.1),
         rotate=0.50 * 3.14,
         translate=[0, -0.25, -0.25],
     )
 )
 
 faults = sm.Union(cubes)
 # faults.show(samples=1e6)
 
 
 def edge_length(x):
     return 0.05 + 0.15 * faults.eval(x)
 
 
 points, cells = sm.generate_mesh(
     domain=parent,
     h0=0.05,
     edge_length=edge_length,
     subdomains=[faults],
     verbose=2,
 )
 
 points, cells = sm.sliver_removal(
     points=points, domain=parent, h0=0.05, edge_length=edge_length, preserve=True
 )
 
 meshio.write_points_cells(
     "cube_with_faults.vtk",
     points,
     [("tetra", cells)],
     point_data={"sd": faults.eval(points)},
     file_format="vtk",
 )


@krober10nd
Copy link
Owner

Hey @BinWang0213 did you try my workaround? Using signed distance functions to define geometry constraints, this is the best we can get I think.

@BinWang0213
Copy link
Author

BinWang0213 commented Apr 5, 2021

@krober10nd Thanks a lot for your updates! I didn't have a chance to try your code as I'm working hard on my dissertation recently.

Does seismicMesh support define polygon faults/fractures below? It is not necessary a rectangle. In 3D it looks like a polyhedron slab.

image

@krober10nd
Copy link
Owner

yes, this is very similar to the case above! Wow talk about complex. We'd have to somehow describe each structure as a signed distance function, but in theory it's possible.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants