Names and colors

Edges and faces carry properties: a name, a color col, and mesh sizes such as maxh and hpref. They are given with the drawing calls, as in Line(2.2, name="wall"), or set later. They survive Boolean operations, cleanup and export, so a boundary named in the drawing can be found again in the CAD model or in the mesh, for example to set a boundary condition. face.edges(name="wall") selects the edges with a name, and the selection takes properties for all of them at once. See Boxes, crossings and open ends for more ways to select.

[1]:
import math
import planex as px

A channel named for a simulation

The example is the channel of the flow around a cylinder benchmark (Schäfer and Turek), 2.2 long and 0.41 high, with a cylinder of radius 0.05 (Figure 1). Its boundaries are named as a solver needs them: the walls, the inlet, the outlet and the cylinder cyl. The cylinder also gets a finer mesh size, maxh=0.01.

[3]:
sketch = px.QuickSketch().Line(2.2, name="wall").Line(0, 0.41, name="outlet")
channel = sketch.Line(-2.2, 0, name="wall").Close(name="inlet").Face()
cylinder = px.QuickSketch().Circle(0.2, 0.2, 0.05, name="cyl", maxh=0.01).Face()

fluid = channel - cylinder
fluid.name = "fluid"
print(sorted({e.name for e in fluid.edges}))
['cyl', 'inlet', 'outlet', 'wall']
The channel, with the edges named wall in cyan
Figure 1: The channel, with the edges named wall in cyan

Through Boolean operations

The names come through the difference. A difference keeps the name of its first face, so the result is still fluid. The edges of the cylinder keep their own names, and the pieces of the walls keep the name of the wall.

[5]:
print(fluid.name, "area", fluid.mass, "exact", 2.2 * 0.41 - math.pi * 0.05**2)
fluid area 0.8941460183660256 exact 0.8941460183660256

Colors

Colors are set the same way, here on the inlet in blue and the outlet in orange. px.Plot(fluid, line_col="property") draws the edges in their own colors (Figure 2):

[6]:
fluid.edges(name="inlet").col = (0.1, 0.4, 0.9)
fluid.edges(name="outlet").col = (0.9, 0.3, 0.1)
The channel drawn in its edges' colors: inlet blue, outlet orange
Figure 2: The channel drawn in its edges' colors: inlet blue, outlet orange

On all edges at once

Assigning a property through edges itself sets it on every edge of an object:

[8]:
obstacle = px.QuickSketch().Circle(0.2, 0.2, 0.05).Face()
obstacle.edges.name = "cyl"
print(obstacle.edges.name)
cyl

Mesh sizes

maxh, hpref and layer work the same way as names and colors. netgen uses maxh as the largest element size along an edge or in a face, and hpref for geometric refinement toward it. See Naming and marking for details.

Vertices

Where edges meet, a vertex can carry a name, a maxh and an hpref: for a named point in the mesh, a local mesh size, or geometric refinement toward a corner. vertices lists the vertices of every wire, face and shape.

In a sketch, vertex properties are set on its points. Vertex("corner") places a point with the id corner at the pen’s position, and s("corner").maxh = 1 sets a property on it. s(kind="point", near=(12, 12)) selects the point nearest to a location instead. The example marks the re-entrant corner of an L bracket, 60 × 40 with legs 12 thick, where the stress in a part like this peaks (Figure 3).

[9]:
s = px.QuickSketch().Line(60).Turn(90).Line(12).Turn(90).Line(48).Vertex("corner")
s.Turn(-90).Line(28).Turn(90).Line(12).Close()
s("corner").name = "corner"
s("corner").hpref = 1
s("corner").maxh = 1
bracket = s.Face()
An L bracket, its re-entrant corner named
Figure 3: An L bracket, its re-entrant corner named

The face’s vertices can be selected by name like its edges:

[11]:
corner = bracket.vertices(name="corner")
print(len(bracket.vertices), "vertices")
print("corner: hpref", corner.hpref, "maxh", corner.maxh, "at", corner.center)
6 vertices
corner: hpref 1.0 maxh 1.0 at (12.0, 12.0, 0.0)

Vertex properties survive Boolean operations, gluing, splitting and motions, and they reach the OpenCASCADE vertices of the export. See netgen and NGSolve for meshing with them.