{
    "componentChunkName": "component---src-templates-markdown-doc-tsx",
    "path": "/2025.1.3/knowledge_base/mesh_generation",
    "result": {"data":{"mdx":{"id":"b1283dd3-45f6-5884-990b-879397b4e03e","frontmatter":{"title":"Mesh Generation","images":[{"publicURL":"/static/6bc44a9de64f676771f7a8054184c815/discretization_layers.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/6bc44a9de64f676771f7a8054184c815/000b8/discretization_layers.png","srcSet":"/static/6bc44a9de64f676771f7a8054184c815/22dcc/discretization_layers.png 150w,\n/static/6bc44a9de64f676771f7a8054184c815/6848d/discretization_layers.png 300w,\n/static/6bc44a9de64f676771f7a8054184c815/000b8/discretization_layers.png 600w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/6bc44a9de64f676771f7a8054184c815/2ee58/discretization_layers.webp 150w,\n/static/6bc44a9de64f676771f7a8054184c815/a951c/discretization_layers.webp 300w,\n/static/6bc44a9de64f676771f7a8054184c815/3a7dd/discretization_layers.webp 600w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":811}}},{"publicURL":"/static/16e3dc839cd58dc889154184bde4ba7a/tri-quad.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/16e3dc839cd58dc889154184bde4ba7a/8cae6/tri-quad.png","srcSet":"/static/16e3dc839cd58dc889154184bde4ba7a/82a03/tri-quad.png 150w,\n/static/16e3dc839cd58dc889154184bde4ba7a/f7cdc/tri-quad.png 300w,\n/static/16e3dc839cd58dc889154184bde4ba7a/8cae6/tri-quad.png 600w,\n/static/16e3dc839cd58dc889154184bde4ba7a/bb8ee/tri-quad.png 1200w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/16e3dc839cd58dc889154184bde4ba7a/6689f/tri-quad.webp 150w,\n/static/16e3dc839cd58dc889154184bde4ba7a/dc425/tri-quad.webp 300w,\n/static/16e3dc839cd58dc889154184bde4ba7a/381e5/tri-quad.webp 600w,\n/static/16e3dc839cd58dc889154184bde4ba7a/edb28/tri-quad.webp 1200w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":338}}},{"publicURL":"/static/b88366d9445980be9f84cf81e9e7f6f5/tet-hex.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/b88366d9445980be9f84cf81e9e7f6f5/8cae6/tet-hex.png","srcSet":"/static/b88366d9445980be9f84cf81e9e7f6f5/82a03/tet-hex.png 150w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/f7cdc/tet-hex.png 300w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/8cae6/tet-hex.png 600w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/bb8ee/tet-hex.png 1200w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/b88366d9445980be9f84cf81e9e7f6f5/6689f/tet-hex.webp 150w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/dc425/tet-hex.webp 300w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/381e5/tet-hex.webp 600w,\n/static/b88366d9445980be9f84cf81e9e7f6f5/edb28/tet-hex.webp 1200w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":338}}},{"publicURL":"/static/b8c56045eb56be1018f249bb28df96ef/conforming_example.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/b8c56045eb56be1018f249bb28df96ef/c6937/conforming_example.png","srcSet":"/static/b8c56045eb56be1018f249bb28df96ef/2adbe/conforming_example.png 150w,\n/static/b8c56045eb56be1018f249bb28df96ef/726b4/conforming_example.png 300w,\n/static/b8c56045eb56be1018f249bb28df96ef/c6937/conforming_example.png 600w,\n/static/b8c56045eb56be1018f249bb28df96ef/a4a5e/conforming_example.png 1200w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/b8c56045eb56be1018f249bb28df96ef/cbe06/conforming_example.webp 150w,\n/static/b8c56045eb56be1018f249bb28df96ef/14d94/conforming_example.webp 300w,\n/static/b8c56045eb56be1018f249bb28df96ef/4a504/conforming_example.webp 600w,\n/static/b8c56045eb56be1018f249bb28df96ef/e5a44/conforming_example.webp 1200w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":297}}},{"publicURL":"/static/e12417874c4e8b0d98aad1a4c817a034/overlapping_example.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/e12417874c4e8b0d98aad1a4c817a034/34db6/overlapping_example.png","srcSet":"/static/e12417874c4e8b0d98aad1a4c817a034/e4932/overlapping_example.png 150w,\n/static/e12417874c4e8b0d98aad1a4c817a034/e4fe0/overlapping_example.png 300w,\n/static/e12417874c4e8b0d98aad1a4c817a034/34db6/overlapping_example.png 600w,\n/static/e12417874c4e8b0d98aad1a4c817a034/3e1c4/overlapping_example.png 1200w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/e12417874c4e8b0d98aad1a4c817a034/1a4e6/overlapping_example.webp 150w,\n/static/e12417874c4e8b0d98aad1a4c817a034/94045/overlapping_example.webp 300w,\n/static/e12417874c4e8b0d98aad1a4c817a034/fabc4/overlapping_example.webp 600w,\n/static/e12417874c4e8b0d98aad1a4c817a034/2a301/overlapping_example.webp 1200w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":191}}},{"publicURL":"/static/c54a02446fe530b3d5a1fa5abf63d3ee/small_features.png","childImageSharp":{"gatsbyImageData":{"layout":"constrained","backgroundColor":"#e8e8e8","images":{"fallback":{"src":"/static/c54a02446fe530b3d5a1fa5abf63d3ee/e916b/small_features.png","srcSet":"/static/c54a02446fe530b3d5a1fa5abf63d3ee/a177f/small_features.png 150w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/912d0/small_features.png 300w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/e916b/small_features.png 600w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/e4104/small_features.png 1200w","sizes":"(min-width: 600px) 600px, 100vw"},"sources":[{"srcSet":"/static/c54a02446fe530b3d5a1fa5abf63d3ee/2f13a/small_features.webp 150w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/e35c0/small_features.webp 300w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/0483b/small_features.webp 600w,\n/static/c54a02446fe530b3d5a1fa5abf63d3ee/6d8dd/small_features.webp 1200w","type":"image/webp","sizes":"(min-width: 600px) 600px, 100vw"}]},"width":600,"height":200}}}]},"body":"var _excluded = [\"components\"];\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"Mesh Generation\",\n  \"images\": [\"../images/discretization_layers.png\", \"../images/tri-quad.png\", \"../images/tet-hex.png\", \"../images/conforming_example.png\", \"../images/overlapping_example.png\", \"../images/small_features.png\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"h1\", null, \"Mesh Generation\"), mdx(\"p\", null, \"Generating meshes for efficient waveform simulations in heterogeneous media\\nwith complex topography or internal structures has long been considered a\\ndifficult and time-consuming task.  SalvusMesh is a powerful tool to automate\\nor at least prototype the generation of highly efficient spectral-element\\nmeshes.\"), mdx(\"p\", null, \"Throughout this article, we describe requirements, design criteria, and\\npotential pitfalls of generating meshes.\"), mdx(\"h2\", null, \"Discrete representations of domains, models, and wavefields\"), mdx(\"p\", null, \"Before Salvus can crunch some numbers, all physics need to be represented by a\\nfinite set of values. In particular, there are three different entities that\\nneed to be discretized:\"), mdx(\"table\", null, mdx(\"thead\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"thead\"\n  }, mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Entity\"), mdx(\"th\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Description\"))), mdx(\"tbody\", {\n    parentName: \"table\"\n  }, mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Domain\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Outer bounds of the object through which the waves propagate\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Model\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Medium properties that describe how the density and velocity vary within the domain\")), mdx(\"tr\", {\n    parentName: \"tbody\"\n  }, mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Wavefield\"), mdx(\"td\", {\n    parentName: \"tr\",\n    \"align\": \"center\"\n  }, \"Space- and time-dependent solution of the wave equation\")))), mdx(\"p\", null, \"One can envision each of these entities as something like the following:\"), mdx(props.images.Img1, null), mdx(\"p\", null, \"Here, we focus on discrete representations using finite-element meshes of\\nvariable polynomial order. Note that the discrete representation of all\\nentities involves polynomials, describing:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"the shape transformation of the elements to characterize the domain,\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"the interpolation of the medium parameters for the model, and\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"the discrete spatial representation of the wavefield.\")), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"Talking about the polynomial order might be ambiguous. In principle, a different degree might be used for domain, model, and wavefield. In Salvus, however, we currently only distinguish between the 'tensor_order', which is the polynomial degree used for the domain and the model, and the degree of the wavefield, which for simplicity, we continue to call 'polynomial_degree'.\")),\n    mdxType: \"Message\"\n  }), mdx(\"h2\", null, \"Mesh generation tools\"), mdx(\"p\", null, \"Salvus contains many powerful meshing tools that allow for the design of\\nsimulation-ready discretizations.  Some examples of meshes that Salvus can\\nnatively construct include (but are certainly not limited to):\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/examples/tutorials/models_and_topo/marmousi/tutorial\"\n  }, \"Rectilinear meshes\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/examples/tutorials/models_and_topo/3d_surface_topography/tutorial\"\n  }, \"Complex topographic models\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/examples/tutorials/meshing/layered_meshing/01_basics\"\n  }, \"Layered models\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/examples/applications/seismology/australia/tutorial\"\n  }, \"Spherical or spherical chunk domains\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/examples/tutorials/meshing/cylindrical_meshes/tutorial\"\n  }, \"Extrusion of 2D surfaces to 3D volumes\"))), mdx(\"p\", null, \"Apart from these native meshing interfaces, it is additionally possible to\\nimport external meshes that have been constructed in third-party meshing\\nsoftware. Examples of tools that can be used to construct these types of\\ndiscrete models (but which do \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"not\"), \" come bundled with Salvus) include meshing\\nsoftware such as \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://gmsh.info/\"\n  }, \"Gmsh\"), \" or \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://coreform.com/coreform-cubit/\"\n  }, \"Coreform\\nCubit\"), \".\"), mdx(\"h2\", null, \"Quadrilateral and hexahedral meshes\"), mdx(\"p\", null, \"The spectral-element method benefits significantly from the use of\\nquadrilateral (2D) and hexahedral (3D) elements.  In fact, the computational\\npenalty of using triangular (2D) or tetrahedral (3D) meshes is so severe that\\nSalvus does not currently allow for users to provide meshes that contain\\nanything \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"other\"), \" than quadrilateral or hexahedral elements.\"), mdx(props.images.Img2, null), mdx(props.images.Img3, null), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"All meshes used in Salvus must consist exclusively of either quadrilateral elements (2D) or hexahedral elements (3D).\")),\n    mdxType: \"Message\"\n  }), mdx(\"p\", null, \"These computational penalties would be incurred with even a single triangular\\nor tetrahedral element within the computational mesh.  Thus, hybrid meshes\\n(meshes that consist partly of triangular + quadrilateral elements or\\ntetrahedral + hexahedral elements) are currently not permitted in Salvus.\"), mdx(Message, {\n    color: \"orange\",\n    header: \"Theoretical Note\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"There are two key benefits to using quadrilateral or hexahedral elements in the spectral-element method:\", mdx(\"ol\", null, mdx(\"li\", null, \"The mass matrix is diagonal by construction when using quadrilateral and hexahedral elements; this diagonality tends to be lost when using triangular or tetrahedral elements.  Inverting the mass matrix is normally very computationally demanding and typically accounts for a significant portion of the compute cost associated with finite-element methods.  However, this operation becomes trivial in the case where the mass matrix is diagonal.\"), mdx(\"li\", null, \"The type of numerical quadrature that the spectral-element method uses allows for sparse operations to be performed on quadrilateral and hexahedral elements.  Using triangular or tetrahedral elements would instead require these operations to be dense, thus incurring further computational penalties.\")))),\n    mdxType: \"Message\"\n  }), mdx(\"h2\", null, \"Conforming interfaces\"), mdx(\"p\", null, \"Interfaces between different materials need to be conforming in order for waves\\nto be able to propagate from one part of the medium to the other.  This means\\nthat the nodes on one side of the interface must be connected to the nodes on\\nthe other side of the interface.  \"), mdx(\"p\", null, \"Here's an example of what this looks like:\"), mdx(props.images.Img4, null), mdx(\"p\", null, \"In the above example, the mesh on the left is non-conforming since the nodes on\\nthe circular boundary (which separates the white and gray regions) are not\\nshared by both parts of the mesh.  That is, the blue nodes on the circular\\nboundary in the (finer) inner region do not coincide with the red nodes on the\\ncircular boundary in the (coarser) outer region.\"), mdx(\"p\", null, \"This is in contrast to the conforming case, as seen on the right-hand-side,\\nwhere the nodes on the circular boundary are shared by both discrete regions.\\nThis allows for the transfer of information between both regions, thus enabling\\nthe propagation of waves between both areas.\"), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"When discretizing CAD geometries in third-party meshing tools for use in Salvus, one can often ensure that the mesh is conforming by imprinting and/or merging the shared curves or surfaces between adjacent pieces of geometry.  This tends to indicate to these types of meshing tools that element boundaries are to be shared between these distinct geometric entities.\")),\n    mdxType: \"Message\"\n  }), mdx(\"h2\", null, \"Avoiding overlapping geometry\"), mdx(\"p\", null, \"Geometry that contains overlap between different entities leads to many of the\\nsame issues as in non-conforming meshes.  In particular, elements between\\noverlapping regions tend not to be linked and, thus, prevent the propagation\\nof waves between these disjoint regions.  Here is an example of\\nintersections that one should aim to avoid:\"), mdx(props.images.Img5, null), mdx(\"p\", null, \"The above mesh, which was constructed using the meshing software \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://coreform.com/coreform-cubit/\"\n  }, \"Coreform\\nCubit\"), \", should have the two overlapping\\nregions merged in order to ensure that the waves are able to propagate\\nthroughout both parts of the domain.\"), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"When preparing the geometries in third-party CAD software, one can often take advantage of boolean operations in order to \\\"cut\\\" one piece of geometry with another.\")),\n    mdxType: \"Message\"\n  }), mdx(\"h2\", null, \"Frequency matters\"), mdx(\"p\", null, \"The highest resolvable frequency \\u2014 or the shortest period \\u2014 is the main\\nexternal driver governing the mesh generation.  In order to be able to resolve\\nhigher frequency waves, it is necessary to use a finer discretization.\\nHowever, finer discretizations (i.e., smaller elements in the mesh) generally\\nresults in a smaller global time step.\"), mdx(\"p\", null, \"This means that increasing the frequency of the simulation has two effects that\\nincrease the compute cost of the wave simulation:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"The mesh must be finer to model the shorter wavelengths.  This results in an\\nincrease in the number of elements within the mesh.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"In order to ensure stability in the \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/knowledge_base/spectral_element_modelling/hp_refinement#how-to-determine-the-element-size\"\n  }, \"CFL\\ncriterion\"), \",\\nthe time step must also become smaller.  This results in an increase in the\\nnumber of time steps that need to be computed.\")), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"It is recommended to prototype simulations at lower frequencies (computationally inexpensive) before subsequently performing higher frequency simulations (computationally demanding).\")),\n    mdxType: \"Message\"\n  }), mdx(\"h2\", null, \"Locally constricted elements\"), mdx(\"p\", null, \"A vital consideration that one needs to be mindful of when discretizing the\\ndomain is to avoid locally constricted elements.  As was noted earlier in this\\narticle, the global time step of the simulation is proportional to the smallest\\nelement within the domain.  This means that if the spectral-element mesh\\ncontains even a single element that is abnormally small, one will experience a\\nsignificant penalty in the global time step.\"), mdx(\"p\", null, \"Here's an example of such a mesh that contains locally constricted elements:\"), mdx(props.images.Img6, null), mdx(\"p\", null, \"The mesh on the left contains extremely small elements near the tip of the\\ntriangle, given that there are exceedingly small features within the geometry\\nthat the mesh is attempting to comply with.  This mesh would result in a very\\nsmall global time step for the simulation, meaning that the overall compute\\ncost of performing the wave simulation would increase dramatically.\"), mdx(\"p\", null, \"There are certainly some instances when it is desirable to resolve these types\\nof small features.  However, one generally needs to evaluate whether these\\nsmall features will have any meaningful influence on the resulting wavefield.\\nThis is generally a choice that is problem-dependent and must be assessed on a\\ncase-by-case basis.\"), mdx(Message, {\n    color: \"violet\",\n    header: \"Practical Advice\",\n    content: mdx(\"div\", null, mdx(\"p\", null, \"Resolving these types of locally constricted elements as a post-processing step is generally non-trivial.  While there exist refinement strategies for hexahedral meshes (uniform refinements are also natively supported in Salvus), similarly general coarsening strategies are comparatively limited.  Thus, when attempting to correct for locally constricted elements, it is typically recommended to re-mesh the domain with a revised meshing strategy as opposed to trying to coarsen these problematic elements explicitly.\")),\n    mdxType: \"Message\"\n  }));\n}\n;\nMDXContent.isMDXComponent = true;"},"site":{"siteMetadata":{"salvusDocVersions":{"current":"2026.5.0"}}}},"pageContext":{"id":"b1283dd3-45f6-5884-990b-879397b4e03e"}},
    "staticQueryHashes": ["1756726491","1865182279","3419370438","3597190305","4112489441","519097329"]}