1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
! ------------------------------------------------------------------------------
!
! Gmsh Fortran tutorial 15
!
! Embedded points, lines and surfaces
!
! ------------------------------------------------------------------------------
! By default, across geometrical dimensions meshes generated by Gmsh are only
! conformal if lower dimensional entities are on the boundary of higher
! dimensional ones (i.e. if points, curves or surfaces are part of the boundary
! of volumes).
! Embedding constraints allow to force a mesh to be conformal to other lower
! dimensional entities.
program t15
use, intrinsic :: iso_c_binding
use gmsh
implicit none
type(gmsh_t) :: gmsh
integer(c_int) :: ret, p
integer(c_int), allocatable :: tags(:,:)
real(c_double) :: lc, l
character(len=GMSH_API_MAX_STR_LEN) :: cmd
call gmsh%initialize()
! Copied from `t1.f90'...
lc = 1e-2
ret = gmsh%model%geo%addPoint(.0d0, .0d0, 0d0, lc, 1)
ret = gmsh%model%geo%addPoint(.1d0, .0d0, 0d0, lc, 2)
ret = gmsh%model%geo%addPoint(.1d0, .3d0, 0d0, lc, 3)
ret = gmsh%model%geo%addPoint(.0d0, .3d0, 0d0, lc, 4)
ret = gmsh%model%geo%addLine(1, 2, 1)
ret = gmsh%model%geo%addLine(3, 2, 2)
ret = gmsh%model%geo%addLine(3, 4, 3)
ret = gmsh%model%geo%addLine(4, 1, 4)
ret = gmsh%model%geo%addCurveLoop([4, 1, -2, 3], 1)
ret = gmsh%model%geo%addPlaneSurface([1], 1)
! We change the mesh size to generate a coarser mesh
lc = lc * 4
call gmsh%model%geo%mesh%setSize(reshape([0, 1, 0, 2, 0, 3, 0, 4], [2, 4]), lc)
! We define a new point
ret = gmsh%model%geo%addPoint(0.02d0, 0.02d0, 0.d0, lc, 5)
! We have to synchronize before embedding entites:
call gmsh%model%geo%synchronize()
! One can force this point to be included ("embedded") in the 2D mesh, using the
! `embed()' function:
call gmsh%model%mesh%embed(0, [5], 2, 1)
! In the same way, one can use `embed()' to force a curve to be embedded in the
! 2D mesh:
ret = gmsh%model%geo%addPoint(0.02d0, 0.12d0, 0.d0, lc, 6)
ret = gmsh%model%geo%addPoint(0.04d0, 0.18d0, 0.d0, lc, 7)
ret = gmsh%model%geo%addLine(6, 7, 5)
call gmsh%model%geo%synchronize()
call gmsh%model%mesh%embed(1, [5], 2, 1)
! Points and curves can also be embedded in volumes
call gmsh%model%geo%extrude(reshape([2, 1], [2, 1]), 0d0, 0d0, 0.1d0, tags)
p = gmsh%model%geo%addPoint(0.07d0, 0.15d0, 0.025d0, lc)
call gmsh%model%geo%synchronize()
call gmsh%model%mesh%embed(0, [p], 3, 1)
ret = gmsh%model%geo%addPoint(0.025d0, 0.15d0, 0.025d0, lc, p + 1)
l = gmsh%model%geo%addLine(7, p + 1)
call gmsh%model%geo%synchronize()
call gmsh%model%mesh%embed(1, [int(l)], 3, 1)
! Finally, we can also embed a surface in a volume:
ret = gmsh%model%geo%addPoint(0.02d0, 0.12d0, 0.05d0, lc, p + 2)
ret = gmsh%model%geo%addPoint(0.04d0, 0.12d0, 0.05d0, lc, p + 3)
ret = gmsh%model%geo%addPoint(0.04d0, 0.18d0, 0.05d0, lc, p + 4)
ret = gmsh%model%geo%addPoint(0.02d0, 0.18d0, 0.05d0, lc, p + 5)
ret = gmsh%model%geo%addLine(p + 2, p + 3, int(l + 1))
ret = gmsh%model%geo%addLine(p + 3, p + 4, int(l + 2))
ret = gmsh%model%geo%addLine(p + 4, p + 5, int(l + 3))
ret = gmsh%model%geo%addLine(p + 5, p + 2, int(l + 4))
ret = gmsh%model%geo%addCurveLoop([int(l) + 1, int(l) + 2, int(l) + 3, int(l) + 4])
ret = gmsh%model%geo%addPlaneSurface([ret])
call gmsh%model%geo%synchronize()
call gmsh%model%mesh%embed(2, [ret], 3, 1)
! Note that with the OpenCASCADE kernel (see `t16.f90'), when the `fragment()'
! function is applied to entities of different dimensions, the lower dimensional
! entities will be autmatically embedded in the higher dimensional entities if
! necessary.
call gmsh%model%mesh%generate(3)
call gmsh%write("t15.msh")
! Launch the GUI to see the results:
call get_command(cmd)
if (index(cmd, "-nopopup") == 0) call gmsh%fltk%run()
call gmsh%finalize()
end program t15
|