Version:

This documentation is not for the latest stable Salvus version.

Meshing cylindrical domains

Several applications require a cylindrical geometry, for instance, to model boreholes, pipelines or the tissue/bone structure of the human limbs. In the simplest case, a cylindrical medium can be described by a 1D radial model, which is then extruded in the third dimension.
SalvusProject currently has no built-in support for such meshes, however, we can utilize external meshing tools. This mini tutorial shows how to create such meshes and how to add them to a project.
Copy
import salvus.namespace as sn
import numpy as np
import os

SALVUS_FLOW_SITE_NAME = os.environ.get("SITE_NAME", "local")
PROJECT_DIR = "project"
In this example, we model a cylindrical domain that mimics a steel pipe filled and surrounded by water. We use a dominant frequency of 5 kHz and a vertical extent of 1 m.
v_min = 1500.0
elements_per_wavelength = 4.0
frequency_in_hertz = 5e3
length_in_meters = 1.0

Mesh creation

The mesh generation proceeds in two steps. First, we create a disk-shaped 2D mesh that includes the radial model. In a second step, the mesh is extruded along the longitudinal axis. The radial profile can be specified as a bm file, which contains the material model as well as interfaces.
We consider a steel pipe with an inner diameter of 20 cm and a thickness of 2 cm, which is submerged in water. The mesh generation algorithm will automatically extract fluid and solid parts of the domain, and adjust the element size to the slowest velocity.
%%writefile radial_model.bm
NAME         radial_model
UNITS        m
COLUMNS      radius rho vp vs
    0.0   1000.0     1500.0       0.0
    0.1   1000.0     1500.0       0.0
    0.1   7710.0     5890.0    3240.0
    0.12  7710.0     5890.0    3240.0
    0.12  1000.0     1500.0       0.0
    0.5   1000.0     1500.0       0.0
Writing radial_model.bm

High-order shape transformations

Salvus supports different polynomial orders for the shape transformations of the quadrilateral or hexahedral elements. This is particularly useful when meshing curved domain, where a piecewise (bi-)linear transformation could result in a poorly approximated shape. This parameter is called tensor_order within the Salvus ecosystem, and applies to both the polynomial degree of the model as well as the shape transformation.
To demonstrate the difference, we will take a quick detour and generate two meshes for a frequency of 2 kHz and with tensor_order of 1 and 4, respectively.
mc = sn.simple_mesh.Circular2D()
mc.basic.model = "radial_model.bm"
mc.basic.min_period_in_seconds = 1 / 2e3
mc.basic.elements_per_wavelength = elements_per_wavelength
mc.validate()
mc.create_mesh()
<salvus.mesh.unstructured_mesh.UnstructuredMesh at 0x7f59080fd9d0>
We notice that the coarse mesh poorly models the concentric shape of the 1D model. Note that the element-size is chosen according to resolve the desired frequency at the specified number of elements per wavelength. However, the predominant numerical error is introduced by the poor approximation of the geometry.
When changing the tensor order to 4, the edges of the elements are defined by 4th-order Lagrange polynomials, which results in a much better shape.
mc.advanced.tensor_order = 4
mesh = mc.create_mesh()
mesh