This action might not be possible to undo. Are you sure you want to continue?

Welcome to Scribd! Start your free trial and access books, documents and more.Find out more

**DOI 10.1007/s00158-011-0706-z
**

EDUCATIONAL ARTICLE

PolyMesher: a general-purpose mesh generator for polygonal

elements written in Matlab

Cameron Talischi · Glaucio H. Paulino ·

Anderson Pereira · Ivan F. M. Menezes

Received: 9 November 2010 / Revised: 22 February 2011 / Accepted: 26 February 2011

© Springer-Verlag 2011

Abstract We present a simple and robust Matlab code for

polygonal mesh generation that relies on an implicit descrip-

tion of the domain geometry. The mesh generator can pro-

vide, among other things, the input needed for finite element

and optimization codes that use linear convex polygons. In

topology optimization, polygonal discretizations have been

shown not to be susceptible to numerical instabilities such as

checkerboard patterns in contrast to lower order triangular

and quadrilaterial meshes. Also, the use of polygonal ele-

ments makes possible meshing of complicated geometries

with a self-contained Matlab code. The main ingredients of

the present mesh generator are the implicit description of

the domain and the centroidal Voronoi diagrams used for

its discretization. The signed distance function provides all

the essential information about the domain geometry and

offers great flexibility to construct a large class of domains

via algebraic expressions. Examples are provided to illus-

trate the capabilities of the code, which is compact and has

fewer than 135 lines.

Keywords Topology optimization · Polygonal elements ·

Centroidal Voronoi tessellations · Implicit geometries

Electronic supplementary material The online version of this article

(doi:10.1007/s00158-011-0706-z) contains supplementary material,

which is available to authorized users.

C. Talischi · G. H. Paulino (B)

Department of Civil and Environmental Engineering,

University of Illinois at Urbana-Champaign, 205 North Mathews

Avenue, Newmark Laboratory, MC-250, Urbana, IL 61801, USA

e-mail: paulino@uiuc.edu

A. Pereira · I. F. M. Menezes

Tecgraf, Pontifical Catholic University of Rio de Janeiro (PUC-Rio),

Rua Marquês de São Vicente, 225, Gávea, 22453-900 Rio de Janeiro,

RJ, Brazil

1 Introduction

Sharing and publication of educational software has become

a tradition in the topology optimization community. For

instance, in addition to the popular “99 line” code (Sigmund

2001) and its successor (Andreassen et al. 2011), Allaire and

Pantz (2006) presented a structural optimization code based

on FreeFem++. Liu et al. (2005) introduced a coupled level

set method using the FEMLAB package and Challis (2010)

presented a discrete level-set Matlab code very much in the

spirit of the “99 line” code. More recently, Suresh (2010)

developed a 199 line code for Pareto-optimal tracing with

the aid of topological derivatives. In a series of papers,

we aim to extend and complement the previous works by

presenting a Matlab implementation of topology optimiza-

tion that, among other things, features a general framework

for finite element discretization and analysis. We also hope

that the engineering community will make use of and even

contribute to this computational framework.

Many engineering applications of topology optimization

cannot be defined on a rectangular domain or solved on a

structured square mesh. The description and discretization

of the design domain geometry, specification of the bound-

ary conditions for the governing state equation, and accurate

computation of the design response may require the use of

unstructured meshes. One main goal here is to provide the

users a self-contained analysis tool in Matlab and show how

the topology optimization code should be structured so as to

separate the analysis routine from the particular formulation

used. The latter is the subject of a companion paper (Talischi

et al. 2011). We have elected to focus on polygonal dis-

cretizations in this educational effort for the following rea-

sons: (1) The concept of Voronoi diagrams offers a simple

way to discretize two-dimensional geometries with convex

polygons. We will discuss a simple and robust Voronoi mesh

C. Talischi et al.

generation scheme that relies on an implicit description of

the domain geometry; (2) Polygonal finite elements outper-

form linear triangles and quads in topology optimization

as they are not susceptible to numerical instabilities such

as checkerboard patterns (Langelaar 2007; Saxena 2008;

Talischi et al. 2009, 2010); (3) The isoparametric formu-

lation for polygonal finite elements can be viewed as exten-

sion of the common linear triangles and bilinear quads to

all convex n-gons (Sukumar and Tabarraei 2004; Sukumar

and Malsch 2006; Talischi et al. 2010). As a special case,

these codes can generate and analyze structured triangular

and quadrilateral meshes.

The main ingredients of our mesh generator are the

implicit representation of the domain and the use of Cen-

troidal Voronoi diagrams for its discretization. The signed

distance function contains all the essential information

about the meshing domain needed in our mesh algorithm.

Inspired by the work of Persson and Strang (2004), we note

that this implicit description provides great flexibility to

construct a relatively large class of domains with algebraic

expressions. A discretization of the domain is constructed

from a Centroidal Voronoi Tessellation (CVT) that incorpo-

rates an approximation to its boundary. The approximation

is obtained by including the set of reflections of the seeds

(Bolander and Saito 1998; Yip et al. 2005). The Lloyd’s

method is used to establish a uniform (optimal) distribution

of seeds and thus a high quality mesh (Talischi et al. 2010).

We remark that CVTs have been previously used for gen-

eration and analysis of triangular discretizations (see, for

example, Du and Gunzburger 2002; Du et al. 2003; Ju et al.

2006) and, in some cases, superconvergence of numerical

solutions has been observed (Huang et al. 2008).

The remainder of this paper is organized as follows: in

the next two sections, we review the main concepts and

recall the properties of signed distance functions, Voronoi

diagrams and CVTs before discussing the details of the

proposed meshing algorithm in Section 4. We explain the

Matlab implementation of this algorithm in Section 5 and

present numerical examples in Section 6. Potential exten-

sions and generalizations of the code are addressed in

Section 7. An added educational aspect of the present work

consists of demonstrating how intuitive and geometrical con-

cepts can be expressed in the language of mathematics and

ultimately linked with feasible computational algorithms.

2 Distance function and implicit representation

Let be a subset of R

2

. The signed distance function

associated with is the mapping d

: R

2

→R defined by:

d

(x) = s

(x) min

y∈∂

x −y (1)

where ∂ denotes the boundary of , · is the stan-

dard Euclidean norm in R

2

(so x −y here is the distance

between x and point y on the boundary of the domain), and

the sign function is given by:

s

(x) :=

_

−1, x ∈

+1, x ∈ R

2

\

(2)

Thus, if x lies inside the domain , d

(x) is minus the

distance of x to the closest boundary point. The following

characterizations are immediate from this definition:

=

_

x ∈ R

2

: d

(x) ≤ 0

_

,

∂ =

_

x ∈ R

2

: d

(x) = 0

_

(3)

In our meshing algorithm, we need to determine if a candi-

date point (seed) x lies in the interior of domain . With an

explicit representation of , based on parametrization of its

boundary, this may be difficult as it requires counting the

number of times a ray connecting x and some exterior point

intersects the boundary (Osher and Fedkiw 2003). Given

the signed distance function, we recover this information

by evaluating the sign of d

(x) (see Fig. 1).

Other useful information about the domain geometry is

provided by the signed distance function. Its gradient, ∇d

,

gives the direction to the nearest boundary point. If has

smooth boundary and x ∈ ∂, then ∇d

**(x) is the unit vec-
**

tor normal to the boundary. In general, for almost every

point x ∈ R

2

, we have:

∇d

(x) = 1 (4)

It is possible that the distance function exhibits kinks even

when ∂ is smooth. In particular, if x is equidistant to

more than one point of ∂, then ∇d

(x) fails to exist. As

illustrated in Fig. 2b, the variation of the distance function

changes depending on which boundary point is approached.

In such a case, numerical differentiation may result in

∇d

(x) = 1.

In the proposed algorithm, we use the property of the

gradient to find the reflection of x about the closest bound-

ary point. Denoting the reflection by R

(x), we have (cf.

Fig. 2a):

R

(x) = x −2d

(x)∇d

(x) (5)

Note that this expression is valid for both interior and

exterior points, i.e., for any x ∈ R

2

.

We can see from the discussion so far that when is

characterized by its signed distance function, a great deal

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

(a) (b) (c)

Fig. 1 a Explicit parametrization of domain boundary: the ray connecting point ˜ x to point o, known to lie outside the domain, intersects ∂ an

even number of times, indicating ˜ x / ∈ ; b Implicit representation of the domain: the sign of the distance function d

**(x) determines if x lies inside
**

the domain; c Surface plot of the signed distance function: note that ∂ is given by the zero level set of d

**of useful information about can be readily extracted. An
**

essential task then is to construct d

**for a given domain
**

that we wish to discretize. For many simple geometries,

the signed distance function can be readily identified. For

example, if is a circle of radius r centered at point x

o

, its

distance function is given by:

d

(x) = x −x

o

−r (6)

Moreover, set operations such as union, intersection, and

complementation can be used to piece together and com-

bine different geometries. Given domains

1

and

2

, the

expressions

d

1

∪

2

(x) = min

_

d

1

(x), d

2

(x)

_

d

1

∩

2

(x) = max

_

d

1

(x), d

2

(x)

_

d

R

2

\

1

(x) = −d

1

(x) (7)

capture the “sign” property of the distance function for the

combined geometry, as illustrated in Fig. 3. However, we

note that the “distance” property may not necessarily hold

(a) (b)

Fig. 2 a For x ∈ R

2

, the direction to the closest boundary point, x

b

, is given by ∇d

(x), which can be used to compute the reflection R

(x); b

The distance function exhibit kinks at points that are equidistant to more than one boundary point. Here ∇d

**(x) denotes the one-sided gradient at
**

such a point x

C. Talischi et al.

Fig. 3 Correspondence between set operations and the sign of distance

functions

everywhere.

1

A reference commonly cited in conjunction

with these equations is the work of Ricci (1973) but there the

implicit functions do not carry the distance property. In our

meshing algorithm, we require access to the distance func-

tions of the constituent domains, in part, to address this issue.

Transformations such as rotation and translation can also

be incorporated to obtain desired geometries. For example,

if T

θ

is the matrix for rotation by angle θ about the origin, the

signed distance function for rotated domain

θ

is given by:

d

θ

(x) = d

(T

−1

θ

x) (8)

Also, a signed distance function can be obtained from the

level sets of a given implicit function by solving a nonlin-

ear system of equations (cf. Persson and Strang 2004) or

more generally using marching algorithms (see, for exam-

ple, (Sussman et al. 1998; Sethian 1999; Osher and Fedkiw

2003; Zhao 2004)). We will revisit the issue of computing

distance functions in relation to our meshing algorithm and

later through examples.

3 Voronoi diagrams, CVTs, Lloyd’s algorithm

The concept of Voronoi diagrams plays a central role in

our meshing algorithm. Given a set of n distinct points or

seeds P, the Voronoi tessellation

2

of the domain ⊂ R

2

is

defined by:

T (P; ) =

_

V

y

∩ : y ∈ P

_

(9)

1

For example, consider

1

=

_

(x

1

, x

2

) ∈ R

2

: x

1

< 0

_

and

2

=

_

(x

1

, x

2

) ∈ R

2

: x

2

< 0

_

. The formula d

1

∪

2

(x) =

min

_

d

1

(x), d

2

(x)

_

has incorrect distance “value” in the third quad-

rant, i.e., for x

1

< 0, x

2

< 0. In this region, the closest boundary point

is the new corner x = (0, 0) formed by the union operation.

2

A tessellation or tiling of is a collection of open sets S

i

such that

∪

i

S

i

= and S

i

∩ S

j

= ∅ if i = j .

where V

y

is the Voronoi cell associated with point y:

V

y

=

_

x ∈ R

2

: x −y < x −z , ∀z ∈ P\ {y}

_

(10)

Therefore V

y

consists of points in the plane closer to y than

any other point in P. To simplify the notation for the mesh-

ing algorithm, we are defining the cells over the entire R

2

,

while it is common in the literature to define V

y

∩ to be

the Voronoi cell (see Fig. 4).

The properties of Voronoi diagrams have been stud-

ied extensively and we refer the reader to review paper

(Aurenhammer 1991) on the topic. One relevant property

in two dimensions is that if a Voronoi cell is bounded, it

is necessarily a convex polygon since it is formed by finite

intersection of half-planes (each of which is a convex set).

Hence, as we shall see in the next section, our meshing

algorithmproduces discretizations consisting only of convex

polygons. This is pertinent to the isoparametric formulation

for polygonal finite elements which requires convexity of

all the elements in the mesh (Sukumar and Tabarraei 2004;

Sukumar and Malsch 2006; Talischi et al. 2010).

The regularity of Voronoi diagrams is determined

entirely by the distribution of the generating point set. A

random or quasi-random set of generators may lead to a

discretization not suitable for use in finite element analy-

sis. Therefore, we restrict our attention to a special class

of Voronoi tessellations that enjoy a higher level of regular-

ity. A Voronoi tessellation T (P; ) is centroidal if for every

y ∈ P:

y = y

c

where y

c

:=

_

V

y

∩

xμ(x)dx

_

V

y

∩

μ(x)dx

(11)

and μ(x) is a given density function defined over . Hence,

in a Centroid Voronoi Tessellation (CVT), each generating

point y coincides with the centroid y

c

of the corresponding

region (i.e., V

y

∩ ).

An alternative variational characterization of a CVT is

based on the deviation of each Voronoi region from its gen-

erating seed, measured by the following energy functional:

E(P; ) =

y∈P

_

V

y

(P)∩

μ(x) x −y

2

dx (12)

Note that the energy depends on points in P not only through

the appearance of y in the integral but also the Voronoi cells

in domain of the integral. Critical points of E(P; ) are

point sets that generate CVTs since the gradient of energy

functional with respect to a given y ∈ P is given by (Du

et al. 1999; Liu et al. 2009):

∇

y

E = 2m

y

(y −y

c

) where m

y

=

_

V

y

∩

μ(x)dx (13)

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

Fig. 4 a Voronoi diagram and

its dual, the Delaunay

triangulation; b Illustrating the

difference between V

y

, defined

in (10) as the Voronoi cell, and

V

y

∩ , as the regions making

up the Voronoi tessellation of

(cf. 9)

(a) (b)

Clearly ∇

y

E = 0 when relation (11) holds. Moreover, CVTs

can be further classified based on the minimization of the

energy functional. The CVTs corresponding to saddle points

of E are called unstable while local and global minimizers

(for fixed number of seeds) of the energy functional are

known as stable and optimal CVTs, respectively (Du and

Wang 2005; Liu et al. 2009). The CVTs in the latter groups

form a more compact tessellation of the domain and due

Fig. 5 a Random initial point

set P

1

and the corresponding

Voronoi diagram; b First

iteration of Lloyd’s method: the

Voronoi diagram generated by

P

2

= L(P

1

), i.e., the centroids

of the Voronoi cells of P

1

; c

Distribution of seeds and the

diagram after 80 iterations (d)

Monotonic convergence of the

energy functional and decay in

the norm of its gradient

(a) (b)

(c)

(d)

C. Talischi et al.

to this property find many applications in areas other than

mesh generation—see Du et al. (1999) for a survey on the

topic.

Asimple but powerful method for computing CVTs is the

Lloyd’s algorithm, which iteratively replaces the given gen-

erating seeds by the centroids of the corresponding Voronoi

regions. Lloyd’s algorithm can be thought of as a fixed point

iteration for the mapping L =

_

L

y

_

T

y∈P

: R

n×2

→ R

n×2

where each component function is given by:

L

y

(P) =

_

V

y

(P)∩

xμ(x)dx

_

V

y

(P)∩

μ(x)dx

(14)

Therefore, L maps the point set P to the set of centroids

of the Voronoi cells in T (P; ). Given an initial point set

P

1

, the Lloyd’s method produces point set P

k+1

= L(P

k

)

at the kth iteration. From the above relation, it is clear that

a fixed point of this map, i.e., one that satisfies P = L(P),

forms a CVT. In Du et al. (2006), it is shown that the energy

functional decreases in consecutive iterations of Lloyd’s

algorithm, that is,

E(P

i +1

; ) ≤ E(P

i

; ) (15)

which means that the Lloyd’s algorithm can be viewed as a

descent method for the energy functional. This property is

illustrated in Fig. 5. As discussed later, Lloyd’s algorithm

is incorporated in our meshing algorithm to construct more

uniform polygonal meshes.

4 Voronoi meshing

Before discussing the details of the proposed meshing algo-

rithm, we illustrate the main ideas based on the concepts

developed so far. As shown by Bolander et al. (Bolander

and Saito 1998; Yip et al. 2005), a polygonal discretization

can be obtained from the Voronoi diagram of a given set of

seeds and their reflections.

4.1 Explanation of the approach

Assume ⊂ R

2

is a bounded convex domain with smooth

boundary and P is a given set of distinct seeds in . To

construct a polygonal discretization of , we first reflect

each point in P about the closest boundary point of and

denote the resulting set of points by R

(P):

R

(P) := {R

(y) : y ∈ P} (16)

Convexity of ensures that all of the reflected points lie

outside of . We then construct the Voronoi diagram of

the plane by including the original point set as well as its

reflection. In other words, we compute T (P ∪ R

(P); R

2

).

If the Voronoi cells of a point y and its reflection have a com-

mon edge, i.e., if V

y

∩ V

R

(y)

= ∅, then this edge is tangent

to ∂ at the y

b

(see Fig. 6). Therefore, these edges form an

approximation to the domain boundary and a reasonable dis-

cretization of is given by the collection of Voronoi cells

corresponding to the points in P. For a given point set P,

such a discretization is uniquely defined and is denoted by

M

(P). Thus, we have:

M

(P) =

_

V

y

∈ T (P ∪ R

(P); R

2

) : y ∈ P

_

(17)

We further note that the convexity of implies that the

boundary edges lie on the exterior of the domain and so the

discretization M

(P) covers .

Clearly a better approximation is obtained if the points in

P are distributed more “evenly” in . In our algorithm, we

will incorporate Lloyd’s iterations to obtain a point set P that

produces a CVT. Since optimal CVTs consist of Voronoi

cells that are congruent to a basic cell (and thus are uniform

in size) (Du and Wang 2005), it is expected ∪

V∈M

(P)

V ≈

especially for a large number of generating points. This

gives a systematic and consistent approach for discretizing

under the given assumptions.

4.2 Algorithm

The basic ideas laid out in the previous section can be

extended for discretization of more general domains, in par-

ticular those that are non-convex and have piecewise smooth

boundaries (e.g. ∂ has corner points where there is a jump

Fig. 6 Illustration of the meshing approach: the Voronoi edges shared

between seeds and their reflection approximate the boundary of the

domain. Note that the reflections of the interior seeds “far” from the

boundary (e.g. point z in the figure) do not contribute to the final mesh

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

Fig. 7 To accurately capture a corner, nearby seeds need to be reflected about both boundary segments incident on that corner

in the normal vector). These features lead to a number

of complications that require (minor) modifications of the

previous approach. For example, reflecting a point about

the nearest boundary point may not be sufficient to cap-

ture a nearby corner (see Fig. 7). We resolve this issue by

reflecting the seeds about both boundary segments incident

on the corner. Similarly, for non-convex domains, reflection

of a seed far from the boundary may land inside the domain

or interfere with the reflection of another seed (Fig. 8). We

check the sign and value of the distance function to exclude

such a scenario. Finally, as seen in Fig. 6, the reflection

of most of the seeds in the interior of the domain has no

effect on the approximation of the boundary. Thus, we add

a condition to reflect only seeds that are in a band near

Fig. 8 In this non-convex domain, the reflection R

(y) is closer to

the boundary of the domain than the seed y itself, i.e., |d

(R

(y))| <

|d

**(y)|. Not only this reflection does not contribute to the approxima-
**

tion of the boundary, it causes interference with seed z

the boundary. This significantly reduces the computational

cost and improves the robustness of algorithm by alleviating

the problem of interference, which is important in dealing

with complex non-convex domains (Fig. 9). Based on these

considerations, the following algorithm is proposed.

We consider domains that are formed by finite

union, intersection and/or difference of smooth but perhaps

unbounded regions

i

, i = 1, . . . , m. Using formulas in

(7), the distance function associated with can be written

as a function of d

i

:

d

(x) = F(d

1

(x), . . . , d

m

(x)) (18)

It is expected that

i

’s and operations represented by F are

defined in such a way that distance to the every boundary

segment of can be found among the values of d

i

.

The first step in the algorithm is to generate an initial set

of points P. Algorithm 1 shows the basic steps for obtaining

a random point set of n size. The implementation of random

seed generation is simplified by specifying a bounding box

B = [x

min

, x

max

] ×

_

y

min

, y

max

_

that contains . A random

seed y ∈ B is accepted only if it lies inside the domain and

this is determined by evaluating the sign of the d

(y).

Algorithm 1 Initial random seed placement

input: B, n %%B ⊃ is the bounding box and n is

the desired number of seeds

set P = ∅

while |P| < n do

generate random point y ∈ B

if d

(y) < 0 then

P ← P ∪ {y}

end if

end while

output: P

C. Talischi et al.

Fig. 9 In the algorithm, only the seeds in band of length α(n, ) near

the boundary (shaded area in the figure) are reflected

As discussed above, the set of reflections must be chosen

carefully in order to deal with possible non-convex and non-

smooth features of . In (17), R

**(P) may not be sufficient
**

for producing a good discretization M

**. The procedure for
**

computing the new set of reflections, denoted by R(P), is

outlined in Algorithm 2. A seed y ∈ P is reflected about

boundary segment ∂

i

provided that:

¸

¸

d

i

(y)

¸

¸

< α(n, ) (19)

where α(n, ) is a distance value proportional to the width

of an element:

α(n, ) := c

_

||

n

_

1/2

(20)

We choose the constant of proportionality c to be greater

than 1 so that α is larger than the average element width.

Note that convex corners are captured as nearby seeds are

reflected about both boundary segments incident on these

corners.

The reflection y = R

i

(y) is accepted if it lies outside the

domain, i.e., d

**(y) > 0. Moreover, the following criterion
**

is added to avoid interference with the reflection of other

seeds:

|d

(y)| > η

¸

¸

d

i

(y)

¸

¸

(21)

where 0 < η < 1 is a specified parameter to adjust for

numerical errors (round-off and numerical differentiation).

Figure 8 illustrates the idea behind this criterion. In the case

of a convex domain, |d

(y)| =

¸

¸

d

i

(y)

¸

¸

so no difficulty will

occur. In general, however, the reflection may be closer to a

boundary segment of , other than the one that generated it

(i.e.,

i

), in which case the reflection will not help with the

approximation of the boundary and may possibly interfere

with the reflection of another seed. In particular, we expect

an interference when d

(y) < −d

i

(y). Hence we exclude

this possibility by accepting only the reflections that satisfy

the condition in (21).

Algorithm 2 Reflection

input: P, α, η

R(P) = ∅

for each y ∈ P do

if |d

(y)| < α then

for i = 1 to m do %%mis the number of regions

if

¸

¸

d

i

(y)

¸

¸

< α then

let y = R

i

(y)

if d

(y) > 0 and |d

(y)| > η

¸

¸

d

i

(y)

¸

¸

then

R(P) ← R(P) ∪ {y}

end if

end if

end for

end if

end for

output: R(P)

Once the set of reflections are determined, the Voronoi

diagram of the P ∪ R(P) is constructed. For each y ∈ P,

we compute the centroid of Voronoi cell V

y

to complete the

first iteration of the meshing routine. Following the idea of

Lloyd’s algorithm, the set of centroids P

c

will replace P in

the next iteration until convergence is achieved. The con-

vergence criterion is based on the magnitude of the gradient

of the energy functional. In particular, the algorithm should

terminate when ∇E ≈ 0. Recalling (13), the norm of the

gradient is given by:

∇E:=

⎛

⎝

y∈P

_

_

∇

y

E

_

_

2

⎞

⎠

1/2

=

⎛

⎝

y∈P

m

2

y

y −y

c

2

⎞

⎠

1/2

(22)

We can see that this quantity is in fact a measure of

the movement of the seeds in two consecutive iterations,

weighted by the “size” of their Voronoi cells through terms

m

y

. To identify the appropriate convergence tolerance,

we note:

m

y

∝

1

n

_

μ(x)dx, y −y

c

2

∝

¸

¸

V

y

¸

¸

∝

||

n

(23)

and so the norm of the gradient scales as:

∇E ∝

_

n

_

1

n

_

μ(x)dx

_

2

||

n

_

1/2

=

||

1/2

n

_

μ(x)dx (24)

We define the following “non-dimensional” error

parameter:

E

r

:=

n ∇E

||

1/2

_

μ(x)dx

(25)

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

Algorithm 3 Main function

input: n, M,

tol

%%number of seeds n, max. number

of iterations M, tolerance

tol

generate P, a random point set of size n

i ←0, E

r

←1, P

c

←P %Initialization of variables

while i ≤ M and E

r

≥

tol

do

P ← P

c

compute reflections R(P)

construct diagram T (P ∪ R(P); R

2

)

calculate P

c

← {y

c

: y ∈ P}

compute E

r

using Equation (27)

i ← i +1

end while

output:

˜

M

(P) :=

_

V

y

∈ T (P ∪ R(P); R

2

) : y ∈ P

_

Thus convergence is established when:

E

r

<

tol

(26)

Here 0 <

tol

1 is the specified convergence tolerance. The

pseudo-code for the main routine is shown in Algorithm 3.

Note that the mesh is still defined by expression (17) with

R

(P) replaced by R(P).

4.3 Remarks on min/max formulas

We conclude this section with a remark regarding min/-

max formulas in (7) and implicitly used in (18) and their

influence on the behavior of the meshing algorithm. As

mentioned before, these expressions may produce incor-

rect distance values in certain regions of the plane. A close

inspection of the algorithm shows that the magnitude of d

**generated by (18) is used only in the evaluation of inter-
**

ference criterion (21). Elsewhere—in generating an initial

point set, checking condition (19), or computing reflection

of a seed—we either use the sign of d

**or the distance val-
**

ues of the constituent domains. The requirement on F and

the structure of min/max formulas implicitly used in F guar-

antee that |d

(y)| =

¸

¸

d

j

(y)

¸

¸

for some index j . Here d

**denotes the distance function generated by F, which may be
**

different from the exact distance functions associated with

in some regions of the plane. In such a case, the violation

of condition (21) implies

¸

¸

d

j

(y)

¸

¸

= |d

(y)| ≤ η

¸

¸

d

i

(y)

¸

¸

<

¸

¸

d

i

(y)

¸

¸

for some j = i and so the reflection y = R

i

(y) is “cor-

rectly” rejected because it is expected to cause interference

with approximation of

j

. In fact, in this algorithm, we do

not need the exact distance function associated with . The

need for d

i

’s is primarily due to the issue of corners and

capturing non-convex features.

5 Matlab implementation

In this section, we explain the details of the Matlab code for

polygonal mesh generator. We begin by describing the struc-

ture of the code, the input and output parameters and the

user-defined Domain function that characterizes the mesh-

ing domain. Next we make some comments on the routines

inside the meshing kernel.

5.1 Structure of the code: meshing kernel and input data

The kernel of the mesh generator is implemented in the

PolyMesher function. The following variables are the

user inputs to this function:

[Node,Element,Supp,Load,P]

= PolyMesher(@Domain,NElem,MaxIter,P)

Domain This is a Matlab function defining the domain.

As shown above, a handle to this function (e.g.,

@MichellDomain) is passed to the kernel, providing

access to information about domain geometry (i.e., the sign

distance function), the bounding box B (see Section 4.2),

and the boundary conditions. The details of this function

are discussed later in this section.

NElem This is an integer that represents the desired num-

ber of elements in the mesh. When an initial point set P is

specified, NElem is replaced by the number of elements

in P.

MaxIter This integer specifies the maximum number of

Lloyd’s iterations. By setting MaxIter to zero and pro-

viding an initial point set, the user can obtain/recover the

Voronoi mesh produced by that point set.

P The user has the option of inputting an initial set of

seeds through the array P, in which the kth row repre-

sents the coordinates of the kth seed. If no such input is

passed to the code, an initial random point set is generated

(see description of the function PolyMshr_RndPtSet

below).

The PolyMesher function computes and returns the

Voronoi discretization along with the final set of seeds

and the boundary conditions arrays (Supp and Load as

described below). The mesh is represented by the com-

monly used data structure in finite element community,

namely a node list and an element connectivity matrix. The

node list, Node, is a two-column array whose i th row repre-

sents the coordinates of the node with index number i . The

connectivity Element is stored inside a Matlab cell of size

NElem. The kth entry of the cell contains the indices of

C. Talischi et al.

Table 1 Various uses and commands for the Domain function

Use Input Output

Bounding box Domain(‘BdBox’) Coordinates of bounding box [xmin,xmax,ymin,ymax]

Distance values Domain(‘Dist’,P) (m +1) ×n matrix of distance values for point set P consisting of n points

Boundary conditions Domain(‘BC’,Node) Cell consisting of Load and Supp arrays

the nodes incident on the kth element in counter-clockwise

order.

3

All the domain-related information is included in

Domain defined outside the kernel. This provides more

flexibility for generating meshes for new domains and elim-

inates the need for the repeated modifications of the kernel.

The domain function is used in the kernel for three distinct

purposes: (1) retrieving the coordinates of the bounding

box for the domain, (2) obtaining the distance of a given

point set to the boundary segments, and (3) determining the

boundary condition arrays for a given node list. In the sam-

ple domain functions, the input string Demand specifies

the type of information requested. Table 1 summarizes the

different input and output choices.

Within the Domain function, the user must define the

distance function of the meshing domain. This function,

called DistFnc in the sample domain functions, accepts

the coordinates of a point set P and return a matrix of

(m +1)×n distance values. The entry located at i th column

and j th row represents the signed distance value d

i

(P

j

),

while the last column is the signed distance for the entire

domain . If d is a matrix of distance values, this last

column can be quickly accessed by command d(:,end).

The user also defines the function that returns the lists of

nodal loads and supports given the node list for the mesh.

The nodal support array Supp has three columns, the first

holds the node number, the second and third columns give

support conditions for that node in the x- and y-direction,

respectively. Value of 0 means that the node is free, and

value of 1 specifies a fixed node. The nodal load vector

Load is structured in a similar way, except for the values in

the second and third columns that represent the magnitude

of the x- and y-components of the force.

5.2 Comments on the functions in the kernel

We now proceed to discuss some of the details of the imple-

mentation of the kernel and comment on its functions. We

remark that in this implementation, it is assumed μ(x) ≡ 1

3

The cell structure allows for storing vectors of different size and is

therefore suitable for connectivity of polygonal elements with different

number of nodes.

so y

c

is the centroid of a polygon, m

y

=

¸

¸

V

y

¸

¸

and the

expression for the error is simplified as:

E

r

=

n

||

3/2

⎛

⎝

y∈P

¸

¸

V

y

¸

¸

2

y −y

c

2

⎞

⎠

1/2

(27)

PolyMesher The main function follows closely the

pseudo-code in Algorithm 3. On line 7, we check to see if an

initial point set is provided by the user. The variable NElem

is updated on line 8 to make sure it is consistent with size of

P. The iteration counter It and error value Err are ini-

tialized such that the while-loop is executed at least once.

Upon the first execution, line 15 recovers the initial points

in variable P. The area of the domain, needed for comput-

ing E

r

and α, is initially set to the area of the bounding box

on line 11. This value is updated when the centroids of the

elements are computed.

4

Since the output of the Matlab voronoin command

on line 17 is the set of vertices and connectivity of the

entire Voronoi diagram (i.e., with all the cells in T (P ∪

R(P); R

2

)) and the discretization is composed only of the

cells in M

**, we need to extract the nodes and connectivity
**

of these cells. This is done in the PolyMshr_ExtrNds

function (line 24). The mesh is updated once more in

PolyMshr_CllpsEdgs to remove small edges that can

appear in a CVT (line 25). Furthermore, since resulting

node numbering and connectivity are random (as a con-

sequence of random placement), the bandwidth of finite

element stiffness matrix may be too large. This issue is

addressed in the PolyMshr_RsqsNds function (line 26).

The main function ends with obtaining the boundary condi-

tion arrays from the domain function (line 27) and plotting

the final mesh (line 28).

PolyMshr_RndPtSet This function generates an ini-

tial random point set of size NElem. A candidate point set

Y of size NElem is generated using the coordinates of the

bounding box and rand function in Matlab (lines 33–34).

Only seeds in Y that lie inside the domain are accepted.

The variable Ctr counts the number of seeds accepted so

far. The while-loop terminates when the desired number of

seeds is reached.

4

This small overhead can be removed after a few iterations once a good

estimate value is obtained.

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

PolyMshr_Rflct The implementation of this func-

tion follows Algorithm 2 in Section 4.2. The gradient of

the distance function is computed by means of numerical

differentiation:

n := ∇d

i

(y)

≈

−1

d

_

d

i

(y +(

d

, 0)) −d

i

(y),

d

i

(y +(0,

d

)) −d

i

(y)

_

(28)

Here

d

is a small positive number, set to 10

−8

by default on

line 43. We compute the normal vector for the entire point

set at once on lines 46 and 47, where n1 and n2 denote

the first and second components of the normal, respectively.

The logical array index I, computed on line 48, is then

used to identify and reflect the seeds only about the nearby

boundary segments, i.e., those within distance of α. In order

to compute the reflections R_P at once, the point set P is

extended, by repeating its columns, to two matrices of the

same size as n1 and n2 on lines 49 and 50. Once the candi-

date set of reflections R_P of the boundary-adjacent seeds

are obtained (lines 51–52), the two conditions for accepting

the reflections are enforced on line 55 by means of another

logical array index J.

PolyMshr_CntrdPly This function returns the areas

and centroids of the first NElem cells in the mesh. Since the

density is assumed to be constant, we can compute the area

and centroid of each cell using the available formulae for

polygons. The signed area for an -sided polygon is given by:

A =

1

2

k=1

_

v

[k]

x

v

[k+1]

y

−v

[k+1]

x

v

[k]

y

_

(29)

where (v

[k]

x

, v

[k]

y

) is the coordinates of the kth vertex of

the polygon, k = 1, . . . , . In the above equation, we

are defining ( +1)th vertex to be the same as the first.

Similarly, The formula for computing the centroid is:

c

x

=

1

6A

k=1

_

v

[k]

x

+v

[k+1]

x

_

×

_

v

[k]

x

v

[k+1]

y

−v

[k+1]

x

v

[k]

y

_

(30)

c

y

=

1

6A

k=1

_

v

[k]

y

+v

[k+1]

y

_

×

_

v

[k]

x

v

[k+1]

y

−v

[k+1]

x

v

[k]

y

_

(31)

PolyMshr_ExtrNds The original discretization is

passed to this function through variables Element0 and

Node0. The connectivity of the Voronoi cells that make up

the mesh are stored in the first n arrays of the cell vari-

able Element0 as a result of passing the seeds P in the

first block of the input to Matlab function voronoin on

line 17. However, the vertices of these cells are not nec-

essarily stored in the first block of rows of Node0. The

extraction of the additional nodes requires modification of

both the node list and the connectivity matrix. The func-

tion PolyMshr_ExtrNds first creates a one-dimensional

array, map, containing the indices of the nodes that must

remain in the mesh (the Matlab function unique is used

to remove the appearance of duplicate nodes). The array

cNode, needed for updating the node list and element con-

nectivity matrix, is constructed on lines 69–70. By setting

the entries of cNode that correspond to the nodes that

must be removed to the maximum value in map (which

is necessarily the index of a node that will remain in the

node list) on line 70, we ensure that they are removed

in PolyMshr_RbldLists function (see below for the

description of this function).

PolyMshr_CllpsEdgs This function addresses the

issue of appearance of small edges in the centroidal Voronoi

Fig. 10 Small edges can form

in elements near a curved

boundary since the generating

seeds are not the same distance

from that boundary. The issue

can be addressed by a

post-processing step of

collapsing these edges onto

single nodes

C. Talischi et al.

Fig. 11 Illustration of small interior edges in a CVT and definition of

angle β in (32)

meshes, which can occur around the boundary of the domain

or in the interior. In former case, such phenomenon is due

to the use of numerical differentiation to compute the gradi-

ent of the distance function and unequal distance of seeds

to curved boundaries, as illustrated in Fig. 10. A small

interior edge can also form when four seeds are almost

co-circular (see Fig. 11). A simple remedy, implemented

in PolyMshr_CllpsEdgs function, is to collapse the

edges that are small compared to the element size into a

single node. This operation does not distort the mesh topol-

ogy (elements remain to be convex polygons) and ensures

a uniform quality of the mesh. An alternative penalization

approach is discussed in (Sieger et al. 2010). In our imple-

mentation, we search all the edges in the mesh by looping

over all the elements (for-loop in lines 76–84). Given an

edge of an element, we compute the angle between the vec-

tors connecting the center (the location with mean value of

the coordinates of the nodes) of the element and the vertices

forming the edge (lines 79–80). The edge will be collapsed

into a single node when

β <

a

_

2π

_

(32)

Here is the number of vertices of the element and

a

is a user-defined tolerance. To update the node list and

element connectivity matrices, the set of edges that needs to

be collapsed is stored in array cEdge (line 86). The input

cNode is defined on line 89 such that the two nodes at

the end of a tagged edge are replaced by a single node in

PolyMshr_RbldLists.

PolyMshr_RsqsNds The Reverse Cuthill–McKee

(RCM) algorithm (Cuthill and McKee 1969) is used to

renumber the nodes once more in order to reduce the band-

width and profile of the stiffness matrix for the mesh. Note

that other resequencing algorithms may be used as well,

e.g. (Paulino et al. 1994a, b). In the present function, the

sparsity pattern of the corresponding stiffness matrix is first

computed (lines 98–104). The assembly of this pseudo-

stiffness matrix K is carried out by the use of Matlab’s

sparse assembly function (on line 105). The Matlab function

symrcm returns the reverse Cuthill-McKee ordering, stored

in variable p, which is then used to compute the cNode

array passed to PolyMshr_RbldLists function. The

reader is referred to the Matlab documentation on func-

tions sparse and symrcm for further information of this

implementation.

PolyMshr_RbldLists This auxiliary function is

used in all three mesh modification functions (PolyMshr_

ExtrNds, PolyMshr_CllpsEdgs, and PolyMshr_

RsqsNds) for updating the node list and element connec-

tivity according to the information contained in the input

array cNode. This is an array of integer with the same

length as the input node list Node0. If the i th entry of

cNode is set to have value k, then after the update, the

i th node, Node0(i), is replaced by the coordinates of

kth node, Node0(k). For example, in order to collapse

nodes i and j, we can set cNode(i)=j (see line 89

in PolyMshr_CllpsEdgs function). Similarly, if we

wish to remove the node with index i from the node list

(which is the case in PolyMshr_ExtrNds function), we

set cNode(i) to be the highest index of the nodes that

will remain in the mesh after the modification. On line

112, we use the unique function in Matlab to identify

the duplicate nodes and the resulting index array ix allows

us to extract the desired nodal coordinates from Node0.

When reducing the node list size we need to make sure

that the last mapped node is the maximum node of the

input map cNode (line 113). The connectivity Element is

updated on line 116 while lines 117–119 guarantee that final

arrangement of nodes in the connectivity cell Element is

ordered counter-clockwise. Note that the voronoin does

not necessarily store the nodes in the connectivity cell in a

counter-clockwise order requiring this correction.

PolyMshr_PlotMsh This function plots the mesh

and boundary conditions. In order to use the Matlab

patch function to plot the entire mesh at once, we

create an element connectivity matrix ElemMat that is

padded with NaNs. This matrix has NElem rows and

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

MaxNVer columns (as computed on line 125, MaxNVer

is the maximum number of vertices of elements in the

mesh). The location of support and loads are also marked

provided that Supp and Load arrays are passed to the

function.

6 Examples

In this section, we will present several examples to illus-

trate the use of the code. In particular, we show how

an appropriate distance function can be constructed using

(a) Domain of the MBB beam

(b) Domain of the Michell cantilever problem

(c) Horn geometry

(d) Wrench geometry

Fig. 12 Distance functions (left) and sample meshes (right) for various domains. a Domain of the MBB beam; b Domain of the Michell cantilever

problem; c Horn geometry; d Wrench geometry

C. Talischi et al.

(a) (b)

Fig. 13 Suspension triangle a geometry and b discretization

the library of distance functions. The Domain functions

for these example geometries and the library of distance

functions are provided as supplementary material. Figures 12

and 13 show the contour plot of the distance function and a

sample mesh for each example. In all the cases, the default

values of c = 1.5,

a

= 0.1 and

tol

= 5 × 10

−3

were

used.

6.1 MBB beam

The domain is a rectangular box with width of 3 and height

of 1, and bottom left corner located at the origin. The

distance function is simply given by:

d = dRectangle(p,0,3,0,1)

and the bounding box is the entire domain, i.e., BdBox =

[0 3 0 1]. The boundary conditions for the MBB prob-

lem are specified by searching the nodes located along the

left edge and bottom corner. The following command was

used to generate the result in Fig. 12a:

[Node,Element,Supp,Load,P]

= PolyMesher(@MbbDomain,200,100);

6.2 Michell cantilever

The second example is the extended domain for the Michell

cantilever beam problem. The support is a circular hole and

the a vertical load is applied at midspan of the free end. The

distance function is constructed as follows:

d1 = dRectangle(p,0,5,-2,2)

d2 = dCircle(p,0,0,1)

d = dDiff(d1,d2)

The mesh shown in Fig. 12b consists of 1000 elements, and

was constructed to be symmetric about horizontal axis

(located at the midspan). The initial point set was restricted

Fig. 14 Uniform discretizations of the MBB beam domain obtained

from appropriate placements of the seeds

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

to the upper half of the domain by modifying line 36 as

follows:

I = find(d(:,end)<0 & Y(:,2)>0);

Also during the iterations that point set was reflected about

the x-axis to obtain the complete set of generating seeds. In

particular, we replaced P = Pc on line 15 by the following

line of code:

P = [Pc(1:NElem/2,:);[Pc(1:NElem/2,1),

-Pc(1:NElem/2,2)]];

6.3 Horn

The third example has the geometry of a horn, which

comes from the difference of two half-circles. The distance

function is computed by:

d1 = dCircle(p,0,0,1)

d2 = dCircle(p,-0.4,0,0.55)

d3 = dLine(p,0,0,1,0)

d = dIntersect(d3,dDiff(d1,d2));

The mesh in Fig. 12c consists of 500 elements.

6.4 Two more examples

The construction of the distance functions for the last two

example involves several geometries and set operations.

The first is an extended domain for the design of a socket

wrench and the other is domain for a suspension triangle

which is presented as an industrial application of topology

optimization in Allaire and Jouve (2005). The constituent

domains of the suspension triangle are shown in Fig. 13a.

The meshes in Figs. 12d and 13b are both made up of 1,000

elements.

6.5 Uniform meshes

The proposed algorithm can also be used to generate certain

uniform meshes (regular tessellations), as shown in Fig. 14

for the MBB domain. The user must specify the set of seed

P and turn off the Lloyd’s iterations by setting MaxIter

to zero. The following set of seeds generates a uniform

rectangular mesh with nelx elements in the x-direction

and nely elements in the y-direction for the MBB beam

problem:

dx = 3/nelx; dy = 1/nely;

[X,Y] = meshgrid(dx/2:dx:3,dy/2:dy:1);

P = [X(:) Y(:)];

7 Conclusions and Extensions

The present meshing paper was motivated by the desire to

present a complete, self-contained, efficient and useful code

in Matlab, including domain description and discretization

algorithms. The code is based on the concept of Voronoi dia-

grams, which offers a simple and effective approach to dis-

cretize two-dimensional geometries with convex polygons.

Fig. 15 In the left figure, the

reflection of point y

1

has

interfered with the

approximation of the horizontal

boundary by seeds z and y

2

. In

the right figure, seeds y

1

, y

2

and

y

3

are fixed in such way that

they all have y as the reflection

C. Talischi et al.

Fig. 16 Sample graded meshes:

the left figures show the initial

distribution of seeds generated

using a mesh size function and

rejection method and the right

figures show the final mesh

after Lloyd’s iterations. a MBB

domain; b Horn domain

(a) MBB domain

(b) Horn domain

Its range of applications is broad, including optimization

(shape, topology, etc), and other applications (Raghavan

et al. 2004).

We conclude this paper by discussing a few extensions

of our meshing algorithm, which were left out of the Matlab

code for the sake of simplicity and clarity. The first is related

to the approximation of certain non-convex corners, which

may not be adequately captured with the reflection criteria

described above. An example of a domain that exhibits such

geometry is the L-shaped domain shown in Fig. 15. Since

the seeds near the non-convex corner are placed indepen-

dently (during the Lloyd’s iterations), their reflections may

interfere with each other. One possible solution is to place

some seeds at an equal distance fromthe corner and fix them

during the Lloyd’s iteration. This process can be made sys-

tematic by choosing, as the fixed seeds, the reflections of

appropriately places seed outside such a corner (e.g. point y

in Fig. 15).

The second extension is regarding the generation of

non-uniform meshes. The Lloyd’s algorithm with constant

density function, μ(x), leads to a uniform distribution of

seeds and subsequently a Voronoi discretization that is uni-

form in size over the entire domain. It is possible to generate

non-uniform meshes with desirable gradation by selecting

an appropriate density function, which biases the placement

of points in certain regions (see the effects on varying den-

sity function in Du et al. (1999)). Note that, to generalize

the code further in this direction, an integration scheme

for convex polygons is needed to compute the centroids.

Alternatively, we can choose an initial distribution of seeds

such that regions that need refinement contain more seeds.

Persson and Strang (2004) and Persson (2006) employed a

rejection method that relies on defining a mesh size func-

tion h(x) over the domain. Figure 16 shows examples of

graded meshes that can be generated by the algorithm pre-

sented in this work in conjunction with the rejection method.

Note that CVT iterations naturally lead to a smooth grada-

tion in the mesh. Although not explored, it is also possible to

combine the two approaches and specify suitable and related

density and mesh size functions.

5

We hope that the engineering community will make use

of the present mesh generator in ways that we cannot antic-

ipate. Because the source code is provided and explained in

detail, the realm of applications of this mesh generator is

boundless.

Acknowledgments The first and second authors acknowledge the

support by the Department of Energy Computational Science Gradu-

ate Fellowship Program of the Office of Science and National Nuclear

Security Administration in the Department of Energy under con-

tract DE-FG02-97ER25308. The third and last authors acknowledge

the financial support by Tecgraf (Group of Technology in Computer

Graphics), PUC-Rio, Rio de Janeiro, Brazil. The authors also acknowl-

edge the insightful comments of the two anonymous reviewers which

contributed to improving the manuscript further.

5

Since the gradation in mesh is often dictated by the geometry of the

domain, it is natural that both μ and h be defined based on the distance

function d

.

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

Appendix A: PolyMesher

1 %------------------------------ PolyMesher -------------------------------%

2 % Ref: C Talischi, GH Paulino, A Pereira, IFM Menezes, "PolyMesher: A %

3 % general-purpose mesh generator for polygonal elements written in %

4 % Matlab," Struct Multidisc Optim, DOI 10.1007/s00158-011-0706-z %

5 %-------------------------------------------------------------------------%

6 function [Node,Element,Supp,Load,P] = PolyMesher(Domain,NElem,MaxIter,P)

7 if ~exist('P','var'), P=PolyMshr_RndPtSet(NElem,Domain); end

8 NElem = size(P,1);

9 Tol=5e-3; It=0; Err=1; c=1.5;

10 BdBox = Domain('BdBox');

11 Area = (BdBox(2)-BdBox(1))

*

(BdBox(4)-BdBox(3));

12 Pc = P; figure;

13 while(It≤MaxIter && Err>Tol)

14 Alpha = c

*

sqrt(Area/NElem);

15 P = Pc; %Lloyd's update

16 R_P = PolyMshr_Rflct(P,NElem,Domain,Alpha); %Generate the reflections

17 [Node,Element] = voronoin([P;R_P]); %Construct Voronoi diagram

18 [Pc,A] = PolyMshr_CntrdPly(Element,Node,NElem);

19 Area = sum(abs(A));

20 Err = sqrt(sum((A.^2).

*

sum((Pc-P).

*

(Pc-P),2)))

*

NElem/Area^1.5;

21 fprintf('It: %3d Error: %1.3e\n',It,Err); It=It+1;

22 if NElem≤2000, PolyMshr_PlotMsh(Node,Element,NElem); end;

23 end

24 [Node,Element] = PolyMshr_ExtrNds(NElem,Node,Element); %Extract node list

25 [Node,Element] = PolyMshr_CllpsEdgs(Node,Element,0.1); %Remove small edges

26 [Node,Element] = PolyMshr_RsqsNds(Node,Element); %Reoder Nodes

27 BC=Domain('BC',Node); Supp=BC{1}; Load=BC{2}; %Recover BC arrays

28 PolyMshr_PlotMsh(Node,Element,NElem,Supp,Load); %Plot mesh and BCs

29 %------------------------------------------------- GENERATE RANDOM POINTSET

30 function P = PolyMshr_RndPtSet(NElem,Domain)

31 P=zeros(NElem,2); BdBox=Domain('BdBox'); Ctr=0;

32 while Ctr<NElem

33 Y(:,1) = (BdBox(2)-BdBox(1))

*

rand(NElem,1)+BdBox(1);

34 Y(:,2) = (BdBox(4)-BdBox(3))

*

rand(NElem,1)+BdBox(3);

35 d = Domain('Dist',Y);

36 I = find(d(:,end)<0); %Index of seeds inside the domain

37 NumAdded = min(NElem-Ctr,length(I)); %Number of seeds that can be added

38 P(Ctr+1:Ctr+NumAdded,:) = Y(I(1:NumAdded),:);

39 Ctr = Ctr+NumAdded;

40 end

41 %--------------------------------------------------------- REFLECT POINTSET

42 function R_P = PolyMshr_Rflct(P,NElem,Domain,Alpha)

43 eps=1e-8; eta=0.9;

44 d = Domain('Dist',P);

45 NBdrySegs = size(d,2)-1; %Number of constituent bdry segments

46 n1 = (Domain('Dist',P+repmat([eps,0],NElem,1))-d)/eps;

47 n2 = (Domain('Dist',P+repmat([0,eps],NElem,1))-d)/eps;

48 I = abs(d(:,1:NBdrySegs))<Alpha; %Logical index of seeds near the bdry

49 P1 = repmat(P(:,1),1,NBdrySegs); %[NElem x NBdrySegs] extension of P(:,1)

50 P2 = repmat(P(:,2),1,NBdrySegs); %[NElem x NBdrySegs] extension of P(:,2)

51 R_P(:,1) = P1(I)-2

*

n1(I).

*

d(I);

52 R_P(:,2) = P2(I)-2

*

n2(I).

*

d(I);

53 d_R_P = Domain('Dist',R_P);

54 J = abs(d_R_P(:,end))≥eta

*

abs(d(I)) & d_R_P(:,end)>0;

55 R_P = R_P(J,:); R_P = unique(R_P,'rows');

56 %---------------------------------------------- COMPUTE CENTROID OF POLYGON

57 function [Pc,A] = PolyMshr_CntrdPly(Element,Node,NElem)

58 Pc=zeros(NElem,2); A=zeros(NElem,1);

59 for el = 1:NElem

60 vx=Node(Element{el},1); vy=Node(Element{el},2); nv=length(Element{el});

61 vxS=vx([2:nv 1]); vyS=vy([2:nv 1]); %Shifted vertices

62 temp = vx.

*

vyS - vy.

*

vxS;

63 A(el) = 0.5

*

sum(temp);

64 Pc(el,:) = 1/(6

*

A(el,1))

*

[sum((vx+vxS).

*

temp),sum((vy+vyS).

*

temp)];

65 end

66 %------------------------------------------------------- EXTRACT MESH NODES

67 function [Node,Element] = PolyMshr_ExtrNds(NElem,Node0,Element0)

68 map = unique([Element0{1:NElem}]);

69 cNode = 1:size(Node0,1);

70 cNode(setdiff(cNode,map)) = max(map);

71 [Node,Element] = PolyMshr_RbldLists(Node0,Element0(1:NElem),cNode);

72 %----------------------------------------------------- COLLAPSE SMALL EDGES

C. Talischi et al.

73 function [Node0,Element0] = PolyMshr_CllpsEdgs(Node0,Element0,Tol)

74 while(true)

75 cEdge = [];

76 for el=1:size(Element0,1)

77 if size(Element0{el},2)<4, continue; end; %Cannot collapse triangles

78 vx=Node0(Element0{el},1); vy=Node0(Element0{el},2); nv=length(vx);

79 beta = atan2(vy-sum(vy)/nv, vx-sum(vx)/nv);

80 beta = mod(beta([2:end 1]) -beta,2

*

pi);

81 betaIdeal = 2

*

pi/size(Element0{el},2);

82 Edge = [Element0{el}',Element0{el}([2:end 1])'];

83 cEdge = [cEdge; Edge(beta<Tol

*

betaIdeal,:)];

84 end

85 if (size(cEdge,1)==0), break; end

86 cEdge = unique(sort(cEdge,2),'rows');

87 cNode = 1:size(Node0,1);

88 for i=1:size(cEdge,1)

89 cNode(cEdge(i,2)) = cNode(cEdge(i,1));

90 end

91 [Node0,Element0] = PolyMshr_RbldLists(Node0,Element0,cNode);

92 end

93 %--------------------------------------------------------- RESEQUENSE NODES

94 function [Node,Element] = PolyMshr_RsqsNds(Node0,Element0)

95 NNode0=size(Node0,1); NElem0=size(Element0,1);

96 ElemLnght=cellfun(@length,Element0); nn=sum(ElemLnght.^2);

97 i=zeros(nn,1); j=zeros(nn,1); s=zeros(nn,1); index=0;

98 for el = 1:NElem0

99 eNode=Element0{el}; ElemSet=index+1:index+ElemLnght(el)^2;

100 i(ElemSet) = kron(eNode,ones(ElemLnght(el),1))';

101 j(ElemSet) = kron(eNode,ones(1,ElemLnght(el)))';

102 s(ElemSet) = 1;

103 index = index+ElemLnght(el)^2;

104 end

105 K = sparse(i,j,s,NNode0, NNode0);

106 p = symrcm(K);

107 cNode(p(1:NNode0))=1:NNode0;

108 [Node,Element] = PolyMshr_RbldLists(Node0,Element0,cNode);

109 %------------------------------------------------------------ REBUILD LISTS

110 function [Node,Element] = PolyMshr_RbldLists(Node0,Element0,cNode)

111 Element = cell(size(Element0,1),1);

112 [foo,ix,jx] = unique(cNode);

113 if size(Node0,1)>length(ix), ix(end)=max(cNode); end;

114 Node = Node0(ix,:);

115 for el=1:size(Element0,1)

116 Element{el} = unique(jx(Element0{el}));

117 vx=Node(Element{el},1); vy=Node(Element{el},2); nv=length(vx);

118 [foo,iix] = sort(atan2(vy-sum(vy)/nv,vx-sum(vx)/nv));

119 Element{el} = Element{el}(iix);

120 end

121 %---------------------------------------------------------------- PLOT MESH

122 function PolyMshr_PlotMsh(Node,Element,NElem,Supp,Load)

123 clf; axis equal; axis off; hold on;

124 Element = Element(1:NElem)'; %Only plot the first block

125 MaxNVer = max(cellfun(@numel,Element)); %Max. num. of vertices in mesh

126 PadWNaN = @(E) [E NaN(1,MaxNVer-numel(E))]; %Pad cells with NaN

127 ElemMat = cellfun(PadWNaN,Element,'UniformOutput',false);

128 ElemMat = vertcat(ElemMat{:}); %Create padded element matrix

129 patch('Faces',ElemMat,'Vertices',Node,'FaceColor','w'); pause(1e-6)

130 if exist('Supp','var')&&~isempty(Supp)&&~isempty(Load)%Plot BC if specified

131 plot(Node(Supp(:,1),1),Node(Supp(:,1),2),'b>','MarkerSize',8);

132 plot(Node(Load(:,1),1),Node(Load(:,1),2),'m^','MarkerSize',8); hold off;

133 end

134 %-------------------------------------------------------------------------%

PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab

Appendix B: Library of distance functions

1 %-------------------------------------------------------------------------%

2 function d = dRectangle(P,x1,x2,y1,y2)

3 d = [x1-P(:,1), P(:,1)-x2, y1-P(:,2), P(:,2)-y2];

4 d = [d,max(d,[],2)];

5 %-------------------------------------------------------------------------%

6 function d = dCircle(P,xc,yc,r)

7 d=sqrt((P(:,1)-xc).^2+(P(:,2)-yc).^2)-r;

8 d=[d,d];

9 %-------------------------------------------------------------------------%

10 function d = dLine(P,x1,y1,x2,y2)

11 % By convention, a point located at the left hand side of the line

12 % is inside the region and it is assigned a negative distance value.

13 a=[x2-x1,y2-y1]; a=a/norm(a);

14 b=[P(:,1)-x1,P(:,2)-y1];

15 d=b(:,1)

*

a(2)-b(:,2)

*

a(1);

16 d=[d,d];

17 %-------------------------------------------------------------------------%

18 function d = dUnion(d1,d2) % min(d1,d2)

19 d=[d1(:,1:(end-1)),d2(:,1:(end-1))];

20 d=[d,min(d1(:,end),d2(:,end))];

21 %-------------------------------------------------------------------------%

22 function d = dIntersect(d1,d2) % max(d1,d2)

23 d=[d1(:,1:(end-1)),d2(:,1:(end-1))];

24 d=[d,max(d1(:,end),d2(:,end))];

25 %-------------------------------------------------------------------------%

26 function d = dDiff(d1,d2) % max(d1,-d2)

27 d=[d1(:,1:(end-1)),d2(:,1:(end-1))];

28 d=[d,max(d1(:,end),-d2(:,end))];

29 %-------------------------------------------------------------------------%

References

Allaire G, Jouve F (2005) Alevel-set method for vibration and multiple

loads structural optimization. Comput Methods Appl Mech Eng

194(30–33):3269–3290. doi:10.1016/j.cma.2004.12.018

Allaire G, Pantz O (2006) Structural optimization with FreeFem++.

Struct Multidisc Optim 32(3):173–181. doi:10.1007/s00158-006-

0017-y

Andreassen E, Clausen A, Schevenels M, Lazarov B, Sigmund O

(2011) Efficient topology optimization in MATLAB using 88

lines of code. Struct Multidisc Optim 43(1):1–16. doi:10.1007/

s00158-010-0594-7

Aurenhammer F (1991) Voronoi diagrams—a survey of a fundamental

geometric data structure. ACM Comput Surv 23(3):345–405

Bolander JE, Saito S (1998) Fracture analyses using spring net-

works with random geometry. Eng Fract Mech 61(5–6):569–591.

doi:10.1016/S0013-7944(98)00069-1

Challis VJ (2010) A discrete level-set topology optimization code

written in matlab. Struct Multidisc Optim 41(3):453–464.

doi:10.1007/s00158-009-0430-0

Cuthill E, McKee J (1969) Reducing the bandwidth of sparse sym-

metric matrices. In: Proceedings of the 24th national confer-

ence. ACM Press, New York, NY, pp 157–172. doi:10.1145/

800195.805928

Du Q, Gunzburger M (2002) Grid generation and optimization based

on centroidal Voronoi tessellations. Appl Math Comput 133(2–

3):591–607. doi:10.1016/S0096-3003(01)00260-0

Du Q, Wang DS (2005) The optimal centroidal Voronoi tessella-

tions and the Gersho’s conjecture in the three-dimensional space.

Comput Math Appl 49(9–10):1355–1373

Du Q, Faber V, Gunzburger M(1999) Centroidal Voronoi tessellations:

applications and algorithms. Siam Rev 41(4):637–676

Du Q, Gunzburger M, Ju L (2003) Constrained centroidal Voronoi

tessellations for surfaces. Siam J Sci Comput 24(5):1488–1506

Du Q, Emelianenko M, Ju LL (2006) Convergence of the Lloyd

algorithm for computing centroidal Voronoi tessellations. Siam

J Numer Anal 44(1):102–119. doi:10.1137/040617364

Huang Y, Qin H, Wang D (2008) Centroidal Voronoi tessellation-

based finite element superconvergence. Int J Numer Methods Eng

76(12):1819–1839. doi:10.1002/nme.2374

Ju L, Gunzburger M, Zhao W (2006) Adaptive finite element meth-

ods for elliptic PDEs based on conforming centroidal Voronoi-

Delaunay triangulations. Siam J Sci Comput 28(6):2023–2053

Langelaar M (2007) The use of convex uniform honeycomb tessella-

tions in structural topology optimization. In: 7th world congress

on structural and multidisciplinary optimization, Seoul, South

Korea, 21–25 May 2007

Liu Y, Wang W, Levy B, Sun F, Yan D, Lu L, Yang C (2009)

On centroidal Voronoi tesselleations–energy smoothness and fast

computation. ACM Trans Graph 28(4):101:1–17

Liu Z, Korvink JG, Huang R (2005) Structure topology optimization:

fully coupled level set method via FEMLAB. Struct Multidisc

Optim 29:407–417

Osher S, Fedkiw R (2003) Level set methods and dynamic implicit sur-

faces. Applied mathematical sciences, vol 153. Springer-Verlag,

New York

Paulino GH, Menezes IFM, Gattass M, Mukherjee S (1994a) Node

and element resequencing using the laplacian of a finite ele-

ment graph: part I—general concepts and algorithm. Int J Numer

Methods Eng 37(9):1511–1530. doi:10.1002/nme.1620370907

Paulino GH, Menezes IFM, Gattass M, Mukherjee S (1994b) Node

and element resequencing using the laplacian of a finite ele-

ment graph: part II—implementation and numerical results.

Int J Numer Methods Eng 37(9):1531–1555. doi:10.1002/nme.

1620370908

Persson P (2006) Mesh size functions for implicit geometries and PDE-

based gradient limiting. Eng Comput 22(2):95–109

Persson P, Strang G (2004) A simple mesh generator in MATLAB.

Siam Rev 46(2):329–345

C. Talischi et al.

Raghavan P, Li S, Ghosh S (2004) Two scale response and dam-

age modeling of composite materials. Finite Elem Anal Des

40(12):1619–1640

Ricci A (1973) A constructive geometry for computer graphics.

Comput J 16(2):157–160

Saxena A (2008) A material-mask overlay strategy for continuum

topology optimization of compliant mechanisms using honey-

comb discretization. J Mech Des 130(8):082304. doi:10.1115/

1.2936891

Sethian JA (1999) Fast marching methods. Siam Rev 41(2):199–

235

Sieger D, Alliez P, Botsch M (2010) Optimizing Voronoi diagrams

for polygonal finite element computations. In: Proceedings of the

19th international meshing roundtable

Sigmund O (2001) A 99 line topology optimization code written in

Matlab. Struct Multidisc Optim 21(2):120–127

Sukumar N, Malsch EA (2006) Recent advances in the construction of

polygonal finite element interpolants. Arch Comput Methods Eng

13(1):129–163

Sukumar N, Tabarraei A(2004) Conforming polygonal finite elements.

Int J Numer Methods Eng 61(12):2045–2066. doi:10.1002/

nme.1141

Suresh K (2010) A 199-line matlab code for Pareto-optimal trac-

ing in topology optimization. Struct Multidisc Optim 42(5):665–

679. doi:10.1007/s00158-010-0534-6

Sussman M, Fatemi E, Smereka P, Osher S (1998) An improved level

set method for incompressible two-phase flows. Comput Fluids

27(5–6):663–680

Talischi C, Paulino GH, Le CH (2009) Honeycomb Wachspress finite

elements for structural topology optimization. Struct Multidisc

Optim 37(6):569–583. doi:10.1007/s00158-008-0261-4

Talischi C, Paulino GH, Pereira A, Menezes IFM (2010) Polygonal fi-

nite elements for topology optimization: a unifying paradigm. Int

J Numer Methods Eng 82(6):671–698. doi:10.1002/nme.2763

Talischi C, Paulino GH, Pereira A, Menezes IFM (2011) PolyTop:

a Matlab implementation of a general topology optimization

framework using unstructured polygonal finite element meshes.

doi:10.1007/s00158-011-0696-x

Yip M, Mohle J, Bolander JE (2005) Automated modeling

of three-dimensional structural components using irregular

lattices. Comput-aided Civil Infrastruct Eng 20(6):393–407.

doi:10.1111/j.1467-8667.2005.00407.x

Zhao H (2004) A fast sweeping method for Eikonal equations. Math

Comput 74(250):603–627

C. Talischi et al.

generation scheme that relies on an implicit description of the domain geometry; (2) Polygonal finite elements outperform linear triangles and quads in topology optimization as they are not susceptible to numerical instabilities such as checkerboard patterns (Langelaar 2007; Saxena 2008; Talischi et al. 2009, 2010); (3) The isoparametric formulation for polygonal finite elements can be viewed as extension of the common linear triangles and bilinear quads to all convex n-gons (Sukumar and Tabarraei 2004; Sukumar and Malsch 2006; Talischi et al. 2010). As a special case, these codes can generate and analyze structured triangular and quadrilateral meshes. The main ingredients of our mesh generator are the implicit representation of the domain and the use of Centroidal Voronoi diagrams for its discretization. The signed distance function contains all the essential information about the meshing domain needed in our mesh algorithm. Inspired by the work of Persson and Strang (2004), we note that this implicit description provides great flexibility to construct a relatively large class of domains with algebraic expressions. A discretization of the domain is constructed from a Centroidal Voronoi Tessellation (CVT) that incorporates an approximation to its boundary. The approximation is obtained by including the set of reflections of the seeds (Bolander and Saito 1998; Yip et al. 2005). The Lloyd’s method is used to establish a uniform (optimal) distribution of seeds and thus a high quality mesh (Talischi et al. 2010). We remark that CVTs have been previously used for generation and analysis of triangular discretizations (see, for example, Du and Gunzburger 2002; Du et al. 2003; Ju et al. 2006) and, in some cases, superconvergence of numerical solutions has been observed (Huang et al. 2008). The remainder of this paper is organized as follows: in the next two sections, we review the main concepts and recall the properties of signed distance functions, Voronoi diagrams and CVTs before discussing the details of the proposed meshing algorithm in Section 4. We explain the Matlab implementation of this algorithm in Section 5 and present numerical examples in Section 6. Potential extensions and generalizations of the code are addressed in Section 7. An added educational aspect of the present work consists of demonstrating how intuitive and geometrical concepts can be expressed in the language of mathematics and ultimately linked with feasible computational algorithms.

where ∂ denotes the boundary of , · is the standard Euclidean norm in R2 (so x − y here is the distance between x and point y on the boundary of the domain), and the sign function is given by: s (x) := −1, x ∈ +1, x ∈ R2 \

(2)

Thus, if x lies inside the domain , d (x) is minus the distance of x to the closest boundary point. The following characterizations are immediate from this definition: = x ∈ R2 : d (x) ≤ 0 , ∂ = x ∈ R2 : d (x) = 0 (3)

In our meshing algorithm, we need to determine if a candidate point (seed) x lies in the interior of domain . With an explicit representation of , based on parametrization of its boundary, this may be difficult as it requires counting the number of times a ray connecting x and some exterior point intersects the boundary (Osher and Fedkiw 2003). Given the signed distance function, we recover this information by evaluating the sign of d (x) (see Fig. 1). Other useful information about the domain geometry is provided by the signed distance function. Its gradient, ∇d , gives the direction to the nearest boundary point. If has smooth boundary and x ∈ ∂ , then ∇d (x) is the unit vector normal to the boundary. In general, for almost every point x ∈ R2 , we have: ∇d (x) = 1 (4)

It is possible that the distance function exhibits kinks even when ∂ is smooth. In particular, if x is equidistant to more than one point of ∂ , then ∇d (x) fails to exist. As illustrated in Fig. 2b, the variation of the distance function changes depending on which boundary point is approached. In such a case, numerical differentiation may result in ∇d (x) = 1. In the proposed algorithm, we use the property of the gradient to find the reflection of x about the closest boundary point. Denoting the reflection by R (x), we have (cf. Fig. 2a): R (x) = x − 2d (x)∇d (x) (5)

2 Distance function and implicit representation Let be a subset of R2 . The signed distance function associated with is the mapping d : R2 → R defined by: d (x) = s (x) min x − y

y∈∂

(1)

Note that this expression is valid for both interior and exterior points, i.e., for any x ∈ R2 . We can see from the discussion so far that when is characterized by its signed distance function, a great deal

is given by ∇d (x). as illustrated in Fig. we note that the “distance” property may not necessarily hold (a) (b) Fig. Here ∇d (x) denotes the one-sided gradient at such a point x . b The distance function exhibit kinks at points that are equidistant to more than one boundary point. 2 a For x ∈ R2 . 3. For many simple geometries. and complementation can be used to piece together and com- capture the “sign” property of the distance function for the combined geometry. which can be used to compute the reflection R (x). indicating x ∈ . intersects ∂ an ˜ / even number of times. An essential task then is to construct d for a given domain that we wish to discretize. set operations such as union. c Surface plot of the signed distance function: note that ∂ is given by the zero level set of d of useful information about can be readily extracted.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab (a) (b) (c) ˜ Fig. the direction to the closest boundary point. For example. if is a circle of radius r centered at point xo . intersection. the signed distance function can be readily identified. Given domains expressions d d 1∪ 2 1∩ 2 1 and 2. xb . known to lie outside the domain. d 2 (x) (7) dR2 \ 1 (x) = −d 1 (x) Moreover. However. b Implicit representation of the domain: the sign of the distance function d (x) determines if x lies inside the domain. the (x) = min d 1 (x). its distance function is given by: d (x) = x − xo − r (6) bine different geometries. 1 a Explicit parametrization of domain boundary: the ray connecting point x to point o. d 2 (x) (x) = max d 1 (x).

∀z ∈ P\ {y} (10) Fig.e. ) is centroidal if for every y ∈ P: y = yc where yc := Vy ∩ Vy ∩ xμ(x)dx μ(x)dx (11) 3 Voronoi diagrams. if Tθ is the matrix for rotation by angle θ about the origin. i. 2 A tessellation or tiling of is a collection of open sets Si such that ∪i S i = and Si ∩ S j = ∅ if i = j. Therefore. 0) formed by the union operation. A Voronoi tessellation T (P. while it is common in the literature to define Vy ∩ to be the Voronoi cell (see Fig. A random or quasi-random set of generators may lead to a discretization not suitable for use in finite element analysis. Hence. Note that the energy depends on points in P not only through the appearance of y in the integral but also the Voronoi cells in domain of the integral. d 2 (x) has incorrect distance “value” in the third quadrant. Persson and Strang 2004) or more generally using marching algorithms (see. Zhao 2004)). Hence. One relevant property in two dimensions is that if a Voronoi cell is bounded. ) = Vy ∩ 1 For and μ(x) is a given density function defined over . The regularity of Voronoi diagrams is determined entirely by the distribution of the generating point set... we require access to the distance functions of the constituent domains. ) = y∈P Vy (P)∩ μ(x) x − y 2 dx (12) :y∈P (9) example. Lloyd’s algorithm The concept of Voronoi diagrams plays a central role in our meshing algorithm. Given a set of n distinct points or seeds P. 2010). 2009): ∇y E = 2m y (y − yc ) where my = μ(x)dx (13) Vy ∩ . For example. Critical points of E (P. 1998. the Voronoi tessellation2 of the domain ⊂ R2 is defined by: T (P. x2 ) ∈ R2 : x1 < 0 and 1 2 : x < 0 . to address this issue. x2 < 0. Transformations such as rotation and translation can also be incorporated to obtain desired geometries. the closest boundary point is the new corner x = (0. 3 Correspondence between set operations and the sign of distance functions everywhere. we are defining the cells over the entire R2 . Sethian 1999. the signed distance function for rotated domain θ is given by: d θ (x) = d (T−1 x) θ (8) Also. it is necessarily a convex polygon since it is formed by finite intersection of half-planes (each of which is a convex set). our meshing algorithm produces discretizations consisting only of convex polygons. for x1 < 0. 1999. The formula d = = (x1 . for example.C. CVTs. measured by the following energy functional: E (P. (Sussman et al. in part. The properties of Voronoi diagrams have been studied extensively and we refer the reader to review paper (Aurenhammer 1991) on the topic. a signed distance function can be obtained from the level sets of a given implicit function by solving a nonlinear system of equations (cf. Liu et al. in a Centroid Voronoi Tessellation (CVT). each generating point y coincides with the centroid yc of the corresponding region (i. Osher and Fedkiw 2003. This is pertinent to the isoparametric formulation for polygonal finite elements which requires convexity of all the elements in the mesh (Sukumar and Tabarraei 2004.1 A reference commonly cited in conjunction with these equations is the work of Ricci (1973) but there the implicit functions do not carry the distance property. In our meshing algorithm.e. as we shall see in the next section. consider = (x1 . x2 ) ∈ R 2 2 1 ∪ 2 (x) min d 1 (x). Talischi et al. where Vy is the Voronoi cell associated with point y: Vy = x ∈ R2 : x − y < x − z . Talischi et al. Therefore Vy consists of points in the plane closer to y than any other point in P. An alternative variational characterization of a CVT is based on the deviation of each Voronoi region from its generating seed. Sukumar and Malsch 2006. we restrict our attention to a special class of Voronoi tessellations that enjoy a higher level of regularity. To simplify the notation for the meshing algorithm. 4). Vy ∩ ). We will revisit the issue of computing distance functions in relation to our meshing algorithm and later through examples. ) are point sets that generate CVTs since the gradient of energy functional with respect to a given y ∈ P is given by (Du et al. In this region.

b Illustrating the difference between Vy . the centroids of the Voronoi cells of P1 . c Distribution of seeds and the diagram after 80 iterations (d) Monotonic convergence of the energy functional and decay in the norm of its gradient (a) (b) (c) (d) . Liu et al.e. as the regions making up the Voronoi tessellation of (cf. b First iteration of Lloyd’s method: the Voronoi diagram generated by P2 = L(P1 ). Moreover. 9) (a) (b) Clearly ∇y E = 0 when relation (11) holds. defined in (10) as the Voronoi cell. and Vy ∩ .. the Delaunay triangulation. 4 a Voronoi diagram and its dual. 5 a Random initial point set P1 and the corresponding Voronoi diagram. CVTs can be further classified based on the minimization of the energy functional. 2009). The CVTs in the latter groups form a more compact tessellation of the domain and due Fig. respectively (Du and Wang 2005. i. The CVTs corresponding to saddle points of E are called unstable while local and global minimizers (for fixed number of seeds) of the energy functional are known as stable and optimal CVTs.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab Fig.

that is. 4. we first reflect each point in P about the closest boundary point of and denote the resulting set of points by R (P): R (P) := {R (y) : y ∈ P} (16) Fig. we illustrate the main ideas based on the concepts developed so far.e. a polygonal discretization can be obtained from the Voronoi diagram of a given set of seeds and their reflections. ) (15) We further note that the convexity of implies that the boundary edges lie on the exterior of the domain and so the discretization M (P) covers . 6). if Vy ∩ V R (y) = ∅.. forms a CVT.. ) ≤ E (Pi .g. 6 Illustration of the meshing approach: the Voronoi edges shared between seeds and their reflection approximate the boundary of the domain. which iteratively replaces the given generating seeds by the centroids of the corresponding Voronoi regions. these edges form an approximation to the domain boundary and a reasonable discretization of is given by the collection of Voronoi cells corresponding to the points in P. (1999) for a survey on the topic. Therefore. From the above relation.2 Algorithm The basic ideas laid out in the previous section can be extended for discretization of more general domains. This gives a systematic and consistent approach for discretizing under the given assumptions. Given an initial point set P1 . Thus. L maps the point set P to the set of centroids of the Voronoi cells in T (P. To construct a polygonal discretization of . i.e. we will incorporate Lloyd’s iterations to obtain a point set P that produces a CVT. i. ). R2 ). Lloyd’s algorithm can be thought of as a fixed point T iteration for the mapping L = Ly y∈P : Rn×2 → Rn×2 where each component function is given by: Ly (P) = Vy (P)∩ Vy (P)∩ reflection. then this edge is tangent to ∂ at the yb (see Fig. Clearly a better approximation is obtained if the points in P are distributed more “evenly” in . Since optimal CVTs consist of Voronoi cells that are congruent to a basic cell (and thus are uniform in size) (Du and Wang 2005).C. Note that the reflections of the interior seeds “far” from the boundary (e. (2006). In other words. (Bolander and Saito 1998. As discussed later. 2005). Lloyd’s algorithm is incorporated in our meshing algorithm to construct more uniform polygonal meshes. Talischi et al. it is expected ∪V ∈M (P) V ≈ especially for a large number of generating points. For a given point set P. we compute T (P ∪ R (P). In our algorithm. A simple but powerful method for computing CVTs is the Lloyd’s algorithm. it is shown that the energy functional decreases in consecutive iterations of Lloyd’s algorithm. we have: M (P) = Vy ∈ T (P ∪ R (P). it is clear that a fixed point of this map. Yip et al. the Lloyd’s method produces point set Pk+1 = L(Pk ) at the kth iteration. one that satisfies P = L(P). 5. If the Voronoi cells of a point y and its reflection have a common edge. in particular those that are non-convex and have piecewise smooth boundaries (e. such a discretization is uniquely defined and is denoted by M (P).1 Explanation of the approach Assume ⊂ R2 is a bounded convex domain with smooth boundary and P is a given set of distinct seeds in . We then construct the Voronoi diagram of the plane by including the original point set as well as its . As shown by Bolander et al. ∂ has corner points where there is a jump which means that the Lloyd’s algorithm can be viewed as a descent method for the energy functional. 4. point z in the figure) do not contribute to the final mesh Convexity of ensures that all of the reflected points lie outside of . E (Pi+1 . to this property find many applications in areas other than mesh generation—see Du et al. 4 Voronoi meshing Before discussing the details of the proposed meshing algorithm. R2 ) : y ∈ P xμ(x)dx μ(x)dx (14) (17) Therefore. This property is illustrated in Fig. In Du et al.g.

For example. we add a condition to reflect only seeds that are in a band near the boundary. Algorithm 1 Initial random seed placement input: B. 8). the reflection R (y) is closer to the boundary of the domain than the seed y itself. Using formulas in (7). The implementation of random seed generation is simplified by specifying a bounding box B = [xmin . as seen in Fig.e. i = 1. i. m. 8 In this non-convex domain. Finally. . . |d (R (y))| < |d (y)|. This significantly reduces the computational cost and improves the robustness of algorithm by alleviating the problem of interference. A random seed y ∈ B is accepted only if it lies inside the domain and this is determined by evaluating the sign of the d (y). . reflecting a point about the nearest boundary point may not be sufficient to capture a nearby corner (see Fig.. 6. xmax ] × ymin . We resolve this issue by reflecting the seeds about both boundary segments incident on the corner. We consider domains that are formed by finite union. ymax that contains . the reflection of most of the seeds in the interior of the domain has no effect on the approximation of the boundary. Not only this reflection does not contribute to the approximation of the boundary. . These features lead to a number of complications that require (minor) modifications of the previous approach.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab Fig. The first step in the algorithm is to generate an initial set of points P. Similarly. Algorithm 1 shows the basic steps for obtaining a random point set of n size. We check the sign and value of the distance function to exclude such a scenario. intersection and/or difference of smooth but perhaps unbounded regions i . which is important in dealing with complex non-convex domains (Fig. d m (x)) (18) It is expected that i ’s and operations represented by F are defined in such a way that distance to the every boundary segment of can be found among the values of d i . . 9). Thus. for non-convex domains. it causes interference with seed z . n %%B ⊃ is the bounding box and n is the desired number of seeds set P = ∅ while |P| < n do generate random point y ∈ B if d (y) < 0 then P ← P ∪ {y} end if end while output: P Fig. the following algorithm is proposed. 7). Based on these considerations. . . . 7 To accurately capture a corner. the distance function associated with can be written as a function of d i : d (x) = F(d 1 (x). nearby seeds need to be reflected about both boundary segments incident on that corner in the normal vector). reflection of a seed far from the boundary may land inside the domain or interfere with the reflection of another seed (Fig.

μ(x)dx μ(x)dx following | | n 1/2 | |1/2 n the (24) “non-dimensional” error We define parameter: Er := n ∇E | |1/2 μ(x)dx (25) . In (17). Hence we exclude this possibility by accepting only the reflections that satisfy the condition in (21). Note that convex corners are captured as nearby seeds are reflected about both boundary segments incident on these corners.e. the set of centroids Pc will replace P in the next iteration until convergence is achieved. Fig. η R(P) = ∅ for each y ∈ P do if |d (y)| < α then for i = 1 to m do %% m is the number of regions if d i (y) < α then let y = R i (y) if d (y) > 0 and |d (y)| > η d i (y) then R(P) ← R(P) ∪ {y} end if end if end for end if end for output: R(P) Once the set of reflections are determined.C. the Voronoi diagram of the P ∪ R(P) is constructed. ) (19) Algorithm 2 Reflection input: P. i. y − yc 2 ∝ Vy ∝ | | n (23) and so the norm of the gradient scales as: ∇E ∝ n = 1 n 2 where 0 < η < 1 is a specified parameter to adjust for numerical errors (round-off and numerical differentiation). |d (y)| = d i (y) so no difficulty will occur. other than the one that generated it (i. A seed y ∈ P is reflected about boundary segment ∂ i provided that: d i (y) < α(n.. R (P) may not be sufficient for producing a good discretization M . d (y) > 0. For each y ∈ P. In the case of a convex domain. In general. In particular. Moreover. The reflection y = R i (y) is accepted if it lies outside the domain. 9 In the algorithm. the algorithm should terminate when ∇ E ≈ 0. we compute the centroid of Voronoi cell Vy to complete the first iteration of the meshing routine. the norm of the gradient is given by: ⎛ ∇ E := ⎝ y∈P where α(n. ) := c | | n 1/2 (20) ⎞ 1/2 ∇y E 2⎠ ⎛ =⎝ y∈P ⎞ 1/2 m 2 y − yc 2⎠ y (22) We choose the constant of proportionality c to be greater than 1 so that α is larger than the average element width. however. weighted by the “size” of their Voronoi cells through terms m y . The procedure for computing the new set of reflections. we note: my ∝ 1 n μ(x)dx.. Figure 8 illustrates the idea behind this criterion. the set of reflections must be chosen carefully in order to deal with possible non-convex and nonsmooth features of . In particular. To identify the appropriate convergence tolerance. The convergence criterion is based on the magnitude of the gradient of the energy functional. the reflection may be closer to a boundary segment of . Recalling (13). only the seeds in band of length α(n. Talischi et al. i ). is outlined in Algorithm 2. the following criterion is added to avoid interference with the reflection of other seeds: |d (y)| > η d i (y) (21) We can see that this quantity is in fact a measure of the movement of the seeds in two consecutive iterations. in which case the reflection will not help with the approximation of the boundary and may possibly interfere with the reflection of another seed.e. ) is a distance value proportional to the width of an element: α(n. ) near the boundary (shaded area in the figure) are reflected As discussed above. Following the idea of Lloyd’s algorithm. we expect an interference when d (y) < −d i (y). denoted by R(P). α.

Here d denotes the distance function generated by F. M. the user can obtain/recover the Voronoi mesh produced by that point set. The need for d i ’s is primarily due to the issue of corners and capturing non-convex features. The requirement on F and the structure of min/max formulas implicitly used in F guarantee that |d (y)| = d j (y) for some index j. we explain the details of the Matlab code for polygonal mesh generator. When an initial point set P is specified. Node.e. 4. Note that the mesh is still defined by expression (17) with R (P) replaced by R(P).. As mentioned before. The mesh is represented by the commonly used data structure in finite element community. In fact. checking condition (19).3 Remarks on min/max formulas We conclude this section with a remark regarding min/max formulas in (7) and implicitly used in (18) and their influence on the behavior of the meshing algorithm. . namely a node list and an element connectivity matrix. Er ← 1. R2 ) : y ∈ P 5 Matlab implementation In this section.Load. By setting MaxIter to zero and providing an initial point set. the input and output parameters and the user-defined Domain function that characterizes the meshing domain. tolerance tol generate P. If no such input is passed to the code. the sign distance function).1 Structure of the code: meshing kernel and input data The kernel of the mesh generator is implemented in the PolyMesher function. The kth entry of the cell contains the indices of (y) = |d (y)| ≤ η d i (y) < d i (y) for some j = i and so the reflection y = R i (y) is “correctly” rejected because it is expected to cause interference with approximation of j . Next we make some comments on the routines inside the meshing kernel. a handle to this function (e. A close inspection of the algorithm shows that the magnitude of d generated by (18) is used only in the evaluation of interference criterion (21). max. NElem This is an integer that represents the desired number of elements in the mesh.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab Algorithm 3 Main function input: n. or computing reflection of a seed—we either use the sign of d or the distance values of the constituent domains. The node list. the bounding box B (see Section 4. The pseudo-code for the main routine is shown in Algorithm 3.MaxIter. We begin by describing the structure of the code. The PolyMesher function computes and returns the Voronoi discretization along with the final set of seeds and the boundary conditions arrays (Supp and Load as described below).2).Supp.g. R2 ) calculate Pc ← {yc : y ∈ P} compute Er using Equation (27) i ←i +1 end while ˜ output: M (P) := Vy ∈ T (P ∪ R(P). As shown above. P The user has the option of inputting an initial set of seeds through the array P. The connectivity Element is stored inside a Matlab cell of size NElem.P) Thus convergence is established when: Er < tol (26) Here 0 < tol 1 is the specified convergence tolerance. we do not need the exact distance function associated with . and the boundary conditions. Pc ← P while i ≤ M and Er ≥ tol do P ← Pc compute reflections R(P) construct diagram T (P ∪ R(P). the violation of condition (21) implies d j Domain This is a Matlab function defining the domain.NElem. is a two-column array whose ith row represents the coordinates of the node with index number i. which may be different from the exact distance functions associated with in some regions of the plane. @MichellDomain) is passed to the kernel. number of iterations M.P] = PolyMesher(@Domain. tol %%number of seeds n. 5. these expressions may produce incorrect distance values in certain regions of the plane. In such a case. MaxIter This integer specifies the maximum number of Lloyd’s iterations. a random point set of size n %Initialization of variables i ← 0. in which the kth row represents the coordinates of the kth seed. The details of this function are discussed later in this section. an initial random point set is generated (see description of the function PolyMshr_RndPtSet below). NElem is replaced by the number of elements in P.Element. The following variables are the user inputs to this function: [Node.. in this algorithm. providing access to information about domain geometry (i. Elsewhere—in generating an initial point set.

accepts the coordinates of a point set P and return a matrix of (m + 1)×n distance values. The iteration counter It and error value Err are initialized such that the while-loop is executed at least once.2 Comments on the functions in the kernel We now proceed to discuss some of the details of the implementation of the kernel and comment on its functions. since resulting node numbering and connectivity are random (as a consequence of random placement).4 Since the output of the Matlab voronoin command on line 17 is the set of vertices and connectivity of the entire Voronoi diagram (i. the input string Demand specifies the type of information requested. The entry located at ith column and jth row represents the signed distance value d i (P j ). Within the Domain function. We remark that in this implementation. 4 This small overhead can be removed after a few iterations once a good 5. except for the values in the second and third columns that represent the magnitude of the x.Node) Output Coordinates of bounding box [xmin. A candidate point set Y of size NElem is generated using the coordinates of the bounding box and rand function in Matlab (lines 33–34). called DistFnc in the sample domain functions.and y-direction. If d is a matrix of distance values. we need to extract the nodes and connectivity of these cells. and value of 1 specifies a fixed node. The area of the domain. The nodal support array Supp has three columns. The mesh is updated once more in PolyMshr_CllpsEdgs to remove small edges that can appear in a CVT (line 25)..3 All the domain-related information is included in Domain defined outside the kernel. the first holds the node number. it is assumed μ(x) ≡ 1 3 The cell structure allows for storing vectors of different size and is therefore suitable for connectivity of polygonal elements with different number of nodes. The user also defines the function that returns the lists of nodal loads and supports given the node list for the mesh. On line 7. This issue is addressed in the PolyMshr_RsqsNds function (line 26). The variable NElem is updated on line 8 to make sure it is consistent with size of P. estimate value is obtained. . In the sample domain functions. Furthermore. PolyMshr_RndPtSet This function generates an initial random point set of size NElem.ymax] (m + 1) × n matrix of distance values for point set P consisting of n points Cell consisting of Load and Supp arrays the nodes incident on the kth element in counter-clockwise order. Value of 0 means that the node is free. Table 1 summarizes the different input and output choices. and (3) determining the boundary condition arrays for a given node list. needed for computing Er and α. The variable Ctr counts the number of seeds accepted so far.C. Talischi et al. This provides more flexibility for generating meshes for new domains and eliminates the need for the repeated modifications of the kernel. the bandwidth of finite element stiffness matrix may be too large.P) Domain(‘BC’. the user must define the distance function of the meshing domain. This function.ymin. we check to see if an initial point set is provided by the user. (2) obtaining the distance of a given point set to the boundary segments. with all the cells in T (P ∪ R(P).e. so yc is the centroid of a polygon. Only seeds in Y that lie inside the domain are accepted. R2 )) and the discretization is composed only of the cells in M . m y = Vy and the expression for the error is simplified as: ⎛ Er = n | |3/2 ⎝ y∈P ⎞1/2 Vy 2 y − yc 2 ⎠ (27) PolyMesher The main function follows closely the pseudo-code in Algorithm 3. while the last column is the signed distance for the entire domain . line 15 recovers the initial points in variable P. This is done in the PolyMshr_ExtrNds function (line 24). The while-loop terminates when the desired number of seeds is reached. The nodal load vector Load is structured in a similar way. This value is updated when the centroids of the elements are computed. The main function ends with obtaining the boundary condition arrays from the domain function (line 27) and plotting the final mesh (line 28). is initially set to the area of the bounding box on line 11. The domain function is used in the kernel for three distinct purposes: (1) retrieving the coordinates of the bounding box for the domain. Table 1 Various uses and commands for the Domain function Use Bounding box Distance values Boundary conditions Input Domain(‘BdBox’) Domain(‘Dist’.xmax. Upon the first execution. this last column can be quickly accessed by command d(:.end). respectively.and y-components of the force. the second and third columns give support conditions for that node in the x.

i. . PolyMshr_CllpsEdgs This function addresses the issue of appearance of small edges in the centroidal Voronoi [k] where (vx . The array cNode. The connectivity of the Voronoi cells that make up the mesh are stored in the first n arrays of the cell variable Element0 as a result of passing the seeds P in the first block of the input to Matlab function voronoin on line 17. v [k] ) is the coordinates of the kth vertex of y the polygon. containing the indices of the nodes that must remain in the mesh (the Matlab function unique is used to remove the appearance of duplicate nodes). the vertices of these cells are not necessarily stored in the first block of rows of Node0. Since the density is assumed to be constant. computed on line 48. 10 Small edges can form in elements near a curved boundary since the generating seeds are not the same distance from that boundary. set to 10−8 by default on line 43. The issue can be addressed by a post-processing step of collapsing these edges onto single nodes . by repeating its columns. where n1 and n2 denote the first and second components of the normal. we can compute the area and centroid of each cell using the available formulae for polygons. d )) − d i [k] [k+1] [k] × vx v [k+1] − vx vy y (30) (y) (28) cy = 1 6A v [k] + v [k+1] y y k=1 Here d is a small positive number. The logical array index I. is then used to identify and reflect the seeds only about the nearby boundary segments. respectively. By setting the entries of cNode that correspond to the nodes that must be removed to the maximum value in map (which is necessarily the index of a node that will remain in the node list) on line 70. We compute the normal vector for the entire point set at once on lines 46 and 47. . those within distance of α. Once the candidate set of reflections R_P of the boundary-adjacent seeds are obtained (lines 51–52). we ensure that they are removed in PolyMshr_RbldLists function (see below for the description of this function).e. is constructed on lines 69–70. [k] [k+1] [k] vy × vx v [k+1] − vx y (31) PolyMshr_CntrdPly This function returns the areas and centroids of the first NElem cells in the mesh. The function PolyMshr_ExtrNds first creates a one-dimensional array. However. Similarly. 0)) − d i (y). In the above equation.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab PolyMshr_Rflct The implementation of this function follows Algorithm 2 in Section 4.. the two conditions for accepting the reflections are enforced on line 55 by means of another logical array index J. . The signed area for an -sided polygon is given by: 1 2 A= [k] [k+1] [k] vx v [k+1] − vx vy y k=1 (29) PolyMshr_ExtrNds The original discretization is passed to this function through variables Element0 and Node0. . In order to compute the reflections R_P at once. map. k = 1. The formula for computing the centroid is: cx = 1 6A [k] [k+1] vx + vx k=1 d i (y + ( d .2. needed for updating the node list and element connectivity matrix. The extraction of the additional nodes requires modification of both the node list and the connectivity matrix. d i (y + (0. we Fig. The gradient of the distance function is computed by means of numerical differentiation: n := ∇d i (y) ≈ −1 d are defining ( + 1)th vertex to be the same as the first. to two matrices of the same size as n1 and n2 on lines 49 and 50. the point set P is extended. .

The input cNode is defined on line 89 such that the two nodes at the end of a tagged edge are replaced by a single node in PolyMshr_RbldLists. The edge will be collapsed into a single node when β< 2π a (32) Here is the number of vertices of the element and a is a user-defined tolerance. Fig. A simple remedy. and PolyMshr_ RsqsNds) for updating the node list and element connectivity according to the information contained in the input array cNode. in order to collapse nodes i and j. PolyMshr_CllpsEdgs. 1994a. stored in variable p. This operation does not distort the mesh topology (elements remain to be convex polygons) and ensures a uniform quality of the mesh. In our implementation. This matrix has NElem rows and . 2010). The reader is referred to the Matlab documentation on functions sparse and symrcm for further information of this implementation. The Matlab function symrcm returns the reverse Cuthill-McKee ordering. Given an edge of an element. e. Talischi et al. is to collapse the edges that are small compared to the element size into a single node. implemented in PolyMshr_CllpsEdgs function. b). then after the update. is replaced by the coordinates of kth node. In the present function. For example. In order to use the Matlab patch function to plot the entire mesh at once. we set cNode(i) to be the highest index of the nodes that will remain in the mesh after the modification. To update the node list and element connectivity matrices. On line 112. 10. Node0(i). In former case. PolyMshr_RbldLists This auxiliary function is used in all three mesh modification functions (PolyMshr_ ExtrNds. The connectivity Element is updated on line 116 while lines 117–119 guarantee that final arrangement of nodes in the connectivity cell Element is ordered counter-clockwise. When reducing the node list size we need to make sure that the last mapped node is the maximum node of the input map cNode (line 113). which is then used to compute the cNode array passed to PolyMshr_RbldLists function. A small interior edge can also form when four seeds are almost co-circular (see Fig. PolyMshr_PlotMsh This function plots the mesh and boundary conditions. if we wish to remove the node with index i from the node list (which is the case in PolyMshr_ExtrNds function). An alternative penalization approach is discussed in (Sieger et al. as illustrated in Fig. If the ith entry of cNode is set to have value k. Note that other resequencing algorithms may be used as well.C. such phenomenon is due to the use of numerical differentiation to compute the gradient of the distance function and unequal distance of seeds to curved boundaries.g. we create an element connectivity matrix ElemMat that is padded with NaNs. PolyMshr_RsqsNds The Reverse Cuthill–McKee (RCM) algorithm (Cuthill and McKee 1969) is used to renumber the nodes once more in order to reduce the bandwidth and profile of the stiffness matrix for the mesh. 11). we compute the angle between the vectors connecting the center (the location with mean value of the coordinates of the nodes) of the element and the vertices forming the edge (lines 79–80). the ith node. the sparsity pattern of the corresponding stiffness matrix is first computed (lines 98–104). The assembly of this pseudostiffness matrix K is carried out by the use of Matlab’s sparse assembly function (on line 105). we can set cNode(i)=j (see line 89 in PolyMshr_CllpsEdgs function). Note that the voronoin does not necessarily store the nodes in the connectivity cell in a counter-clockwise order requiring this correction. (Paulino et al. which can occur around the boundary of the domain or in the interior. we search all the edges in the mesh by looping over all the elements (for-loop in lines 76–84). This is an array of integer with the same length as the input node list Node0. Node0(k). we use the unique function in Matlab to identify the duplicate nodes and the resulting index array ix allows us to extract the desired nodal coordinates from Node0. Similarly. 11 Illustration of small interior edges in a CVT and definition of angle β in (32) meshes. the set of edges that needs to be collapsed is stored in array cEdge (line 86).

d Wrench geometry . we will present several examples to illustrate the use of the code. a Domain of the MBB beam. 6 Examples In this section. 12 Distance functions (left) and sample meshes (right) for various domains. The location of support and loads are also marked provided that Supp and Load arrays are passed to the function. MaxNVer is the maximum number of vertices of elements in the mesh). In particular. c Horn geometry.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab MaxNVer columns (as computed on line 125. we show how an appropriate distance function can be constructed using (a) Domain of the MBB beam (b) Domain of the Michell cantilever problem (c) Horn geometry (d) Wrench geometry Fig. b Domain of the Michell cantilever problem.

5. 12b consists of 1000 elements.0. a = 0. and bottom left corner located at the origin. The distance function is constructed as follows: d1 = dRectangle(p.0.Supp. 14 Uniform discretizations of the MBB beam domain obtained from appropriate placements of the seeds . 6.0. and was constructed to be symmetric about horizontal axis (located at the midspan).P] = PolyMesher(@MbbDomain.5.d2) The mesh shown in Fig. 12a: [Node.2) d2 = dCircle(p.0.100). the default values of c = 1. BdBox = [0 3 0 1]. In all the cases.-2. The distance function is simply given by: d = dRectangle(p.0.Load. 13 Suspension triangle a geometry and b discretization (b) the library of distance functions.1 MBB beam The domain is a rectangular box with width of 3 and height of 1. The support is a circular hole and the a vertical load is applied at midspan of the free end. Figures 12 and 13 show the contour plot of the distance function and a sample mesh for each example.1 and tol = 5 × 10−3 were used..2 Michell cantilever The second example is the extended domain for the Michell cantilever beam problem.200.C.3. The initial point set was restricted Fig.Element. The Domain functions for these example geometries and the library of distance functions are provided as supplementary material. The boundary conditions for the MBB problem are specified by searching the nodes located along the left edge and bottom corner. The following command was used to generate the result in Fig. 6.1) d = dDiff(d1. (a) Fig.e. i.1) and the bounding box is the entire domain. Talischi et al.

dDiff(d1. The following set of seeds generates a uniform rectangular mesh with nelx elements in the x-direction and nely elements in the y-direction for the MBB beam problem: dx = 3/nelx.1) wrench and the other is domain for a suspension triangle which is presented as an industrial application of topology optimization in Allaire and Jouve (2005).0.1. which offers a simple and effective approach to discretize two-dimensional geometries with convex polygons. 13a. [X. dy = 1/nely.d2)).2)]]. The first is an extended domain for the design of a socket The present meshing paper was motivated by the desire to present a complete.[Pc(1:NElem/2.0. the reflection of point y1 has interfered with the approximation of the horizontal boundary by seeds z and y2 .-0. In the right figure. we replaced P = Pc on line 15 by the following line of code: P = [Pc(1:NElem/2. d2 = dCircle(p. 14 for the MBB domain. 12c consists of 500 elements.0. The constituent domains of the suspension triangle are shown in Fig. 7 Conclusions and Extensions The mesh in Fig.Y] = meshgrid(dx/2:dx:3.0. 15 In the left figure.4 Two more examples The construction of the distance functions for the last two example involves several geometries and set operations.000 elements. Fig. as shown in Fig. 12d and 13b are both made up of 1. 6.end)<0 & Y(:. including domain description and discretization algorithms. In particular.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab to the upper half of the domain by modifying line 36 as follows: I = find(d(:.0. efficient and useful code in Matlab.2)>0).3 Horn The third example has the geometry of a horn.dy/2:dy:1). -Pc(1:NElem/2. which comes from the difference of two half-circles.0) d = dIntersect(d3. The user must specify the set of seed P and turn off the Lloyd’s iterations by setting MaxIter to zero. Also during the iterations that point set was reflected about the x-axis to obtain the complete set of generating seeds.0.5 Uniform meshes The proposed algorithm can also be used to generate certain uniform meshes (regular tessellations).1). y2 and y3 are fixed in such way that they all have y as the reflection . 6.:). The distance function is computed by: d1 = dCircle(p. The meshes in Figs. seeds y1 . 6.4. d3 = dLine(p.55) P = [X(:) Y(:)]. The code is based on the concept of Voronoi diagrams. self-contained.

15. 15). Persson and Strang (2004) and Persson (2006) employed a rejection method that relies on defining a mesh size function h(x) over the domain. Brazil. the realm of applications of this mesh generator is boundless. it is natural that both μ and h be defined based on the distance function d . μ(x). Alternatively. it is also possible to combine the two approaches and specify suitable and related density and mesh size functions. which may not be adequately captured with the reflection criteria described above. This process can be made systematic by choosing. etc).5 We hope that the engineering community will make use of the present mesh generator in ways that we cannot anticipate. the gradation in mesh is often dictated by the geometry of the domain. Note that. and other applications (Raghavan et al. Since the seeds near the non-convex corner are placed independently (during the Lloyd’s iterations).C. 5 Since . their reflections may interfere with each other. (1999)). Fig.g. b Horn domain (a) MBB domain (b) Horn domain Its range of applications is broad. leads to a uniform distribution of seeds and subsequently a Voronoi discretization that is uniform in size over the entire domain. including optimization (shape. Acknowledgments The first and second authors acknowledge the support by the Department of Energy Computational Science Graduate Fellowship Program of the Office of Science and National Nuclear Security Administration in the Department of Energy under contract DE-FG02-97ER25308. Figure 16 shows examples of graded meshes that can be generated by the algorithm presented in this work in conjunction with the rejection method. which biases the placement of points in certain regions (see the effects on varying density function in Du et al. 2004). Note that CVT iterations naturally lead to a smooth gradation in the mesh. topology. One possible solution is to place some seeds at an equal distance from the corner and fix them during the Lloyd’s iteration. Rio de Janeiro. We conclude this paper by discussing a few extensions of our meshing algorithm. It is possible to generate non-uniform meshes with desirable gradation by selecting an appropriate density function. as the fixed seeds. The third and last authors acknowledge the financial support by Tecgraf (Group of Technology in Computer Graphics). The authors also acknowledge the insightful comments of the two anonymous reviewers which contributed to improving the manuscript further. 16 Sample graded meshes: the left figures show the initial distribution of seeds generated using a mesh size function and rejection method and the right figures show the final mesh after Lloyd’s iterations. Because the source code is provided and explained in detail. PUC-Rio. a MBB domain. point y in Fig. an integration scheme for convex polygons is needed to compute the centroids. we can choose an initial distribution of seeds such that regions that need refinement contain more seeds. The first is related to the approximation of certain non-convex corners. which were left out of the Matlab code for the sake of simplicity and clarity. The second extension is regarding the generation of non-uniform meshes. Talischi et al. The Lloyd’s algorithm with constant density function. to generalize the code further in this direction. Although not explored. An example of a domain that exhibits such geometry is the L-shaped domain shown in Fig. the reflections of appropriately places seed outside such a corner (e.

Domain) P=zeros(NElem. J = abs(d_R_P(:.:). end %--------------------------------------------------------. while(It≤MaxIter && Err>Tol) Alpha = c*sqrt(Area/NElem).1) = (BdBox(2)-BdBox(1))*rand(NElem.NBdrySegs).map)) = max(map).'rows').P+repmat([eps.1). %Logical index of seeds near the bdry P1 = repmat(P(:. end %------------------------------------------------------.1) = P1(I)-2*n1(I).Element0(1:NElem).:) = Y(I(1:NumAdded). %Recover BC arrays PolyMshr_PlotMsh(Node. PolyMshr_PlotMsh(Node. Err=1.Node). %Generate the reflections [Node. if NElem≤2000.Element. n2 = (Domain('Dist'.PolyMesher -------------------------------% % Ref: C Talischi.2). Ctr = Ctr+NumAdded.1).Element] = PolyMshr_RbldLists(Node0.5. end NElem = size(P.2). A=zeros(NElem.vy. A(el) = 0.It.eps]. cNode(setdiff(cNode.1.1))-d)/eps.Supp. Area = sum(abs(A)).1) P2 = repmat(P(:. end.*(Pc-P).Element] = PolyMshr_ExtrNds(NElem. Tol=5e-3. Err = sqrt(sum((A.5*sum(temp).EXTRACT MESH NODES function [Node. IFM Menezes.Domain.'var').Element] = voronoin([P. Ctr=0.*vxS. d = Domain('Dist'.Node.Node0.Load).0].MaxIter. P = Pc. Area = (BdBox(2)-BdBox(1))*(BdBox(4)-BdBox(3)). vy=Node(Element{el}.1.NElem).Element] = PolyMshr_RsqsNds(Node.5.2) = (BdBox(4)-BdBox(3))*rand(NElem.end)>0.R_P).1007/s00158-011-0706-z % %-------------------------------------------------------------------------% function [Node.Node. %Remove small edges [Node.1)+BdBox(3).NElem) Pc=zeros(NElem.Element0) map = unique([Element0{1:NElem}]). NBdrySegs = size(d.A] = PolyMshr_CntrdPly(Element.Domain).Domain.2)-1. "PolyMesher: A % % general-purpose mesh generator for polygonal elements written in % % Matlab. %Number of seeds that can be added P(Ctr+1:Ctr+NumAdded." Struct Multidisc Optim. vyS=vy([2:nv 1]). %Reoder Nodes BC=Domain('BC'. while Ctr<NElem Y(:.cNode). R_P = unique(R_P.P).Err). Y(:. GH Paulino.2).1))*[sum((vx+vxS). %Plot mesh and BCs %------------------------------------------------.Element. It=It+1.:).Node.NElem. fprintf('It: %3d Error: %1.1:NBdrySegs))<Alpha.1). for el = 1:NElem vx=Node(Element{el}.Element).Load.2) R_P(:. figure. R_P(:.^2).sum((vy+vyS).NElem. I = abs(d(:.Alpha).A] = PolyMshr_CntrdPly(Element.Supp. Pc(el.9.Element).COLLAPSE SMALL EDGES .R_P]). end [Node.NBdrySegs). %[NElem x NBdrySegs] extension of P(:. d = Domain('Dist'. %Number of constituent bdry segments n1 = (Domain('Dist'. [Node.NElem.0. %[NElem x NBdrySegs] extension of P(:. nv=length(Element{el}).NElem. cNode = 1:size(Node0.1).1))-d)/eps.Y). BdBox = Domain('BdBox').NElem. %---------------------------------------------.NElem. %Extract node list [Node.3e\n'.*vyS .1). %Index of seeds inside the domain NumAdded = min(NElem-Ctr. R_P = R_P(J. d_R_P = Domain('Dist'.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab Appendix A: PolyMesher 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 %-----------------------------.1)+BdBox(1). P=PolyMshr_RndPtSet(NElem. c=1.end)<0). %Lloyd's update R_P = PolyMshr_Rflct(P.P+repmat([0.Element] = PolyMshr_ExtrNds(NElem.*temp). Pc = P.COMPUTE CENTROID OF POLYGON function [Pc. eta=0.end))≥eta*abs(d(I)) & d_R_P(:. Supp=BC{1}. DOI 10.length(I)).*sum((Pc-P). Load=BC{2}.1).P] = PolyMesher(Domain. %Shifted vertices temp = vx.*d(I).GENERATE RANDOM POINTSET function P = PolyMshr_RndPtSet(NElem. BdBox=Domain('BdBox'). I = find(d(:. %Construct Voronoi diagram [Pc. vxS=vx([2:nv 1]).:) = 1/(6*A(el. A Pereira.2).P) if ~exist('P'.Alpha) eps=1e-8.2) = P2(I)-2*n2(I).*d(I).NElem).Element.2)))*NElem/Area^1. It=0.REFLECT POINTSET function R_P = PolyMshr_Rflct(P.Element.Element] = PolyMshr_CllpsEdgs(Node. %----------------------------------------------------.*temp)].

2)) = cNode(cEdge(i.8).'rows').1)).NElem.2). Talischi et al.1). hold on. if size(Node0.1). j(ElemSet) = kron(eNode. %Cannot collapse triangles vx=Node0(Element0{el}. for i=1:size(cEdge.REBUILD LISTS function [Node. %Only plot the first block MaxNVer = max(cellfun(@numel.ones(ElemLnght(el). [Node.1).MaxNVer-numel(E))].'FaceColor'. 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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 function [Node0.iix] = sort(atan2(vy-sum(vy)/nv.Load) clf.ElemMat. %-----------------------------------------------------------. for el = 1:NElem0 eNode=Element0{el}. %Create padded element matrix patch('Faces'. for el=1:size(Element0. break. s(ElemSet) = 1. [foo.ElemLnght(el)))'. cEdge = [cEdge.1). Edge(beta<Tol*betaIdeal.Node(Load(:. end %-------------------------------------------------------------------------% . axis equal.1). Element = Element(1:NElem)'.NNode0.1).'w'). end. plot(Node(Load(:.Supp. hold off.Node.Element0{el}([2:end 1])'].C.2).ones(1. end [Node0. continue.ix.'MarkerSize'. ElemLnght=cellfun(@length. index=0. nv=length(vx). Edge = [Element0{el}'.cNode) Element = cell(size(Element0. NNode0).RESEQUENSE NODES function [Node.^2). vy=Node(Element{el}.:). beta = mod(beta([2:end 1]) -beta. end if (size(cEdge.2).Element0.2). nn=sum(ElemLnght. end %--------------------------------------------------------.Element0). of vertices in mesh PadWNaN = @(E) [E NaN(1.1).'UniformOutput'.1))'.'MarkerSize'.1) Element{el} = unique(jx(Element0{el})). for el=1:size(Element0.2*pi).Element0.'m^'. %Pad cells with NaN ElemMat = cellfun(PadWNaN.Element0] = PolyMshr_CllpsEdgs(Node0. Node = Node0(ix.1) cNode(cEdge(i.:)]. j=zeros(nn.Element] = PolyMshr_RbldLists(Node0. ElemSet=index+1:index+ElemLnght(el)^2.'b>'.Element0] = PolyMshr_RbldLists(Node0. betaIdeal = 2*pi/size(Element0{el}.'var')&&~isempty(Supp)&&~isempty(Load)%Plot BC if specified plot(Node(Supp(:.cNode).1).1). s=zeros(nn.Element)).1). Element{el} = Element{el}(iix).1).Element] = PolyMshr_RbldLists(Node0.1).'Vertices'.2).Element0. cNode(p(1:NNode0))=1:NNode0.Element] = PolyMshr_RsqsNds(Node0. i(ElemSet) = kron(eNode.1). %Max.Element.1). vy=Node0(Element0{el}.jx] = unique(cNode).8). vx-sum(vx)/nv).1)==0).s. cNode = 1:size(Node0.2). end %---------------------------------------------------------------. axis off. end. pause(1e-6) if exist('Supp'.2)<4.Element.Element0.1).vx-sum(vx)/nv)). [foo. NElem0=size(Element0.cNode).Element0) NNode0=size(Node0. p = symrcm(K). num.Tol) while(true) cEdge = [].false).1) if size(Element0{el}. end cEdge = unique(sort(cEdge. nv=length(vx).j. ElemMat = vertcat(ElemMat{:}). end K = sparse(i.Node(Supp(:. beta = atan2(vy-sum(vy)/nv. i=zeros(nn. vx=Node(Element{el}.1)>length(ix).1). index = index+ElemLnght(el)^2. ix(end)=max(cNode).PLOT MESH function PolyMshr_PlotMsh(Node.

1137/040617364 Huang Y.1). Yang C (2009) On centroidal Voronoi tesselleations–energy smoothness and fast computation.y2) d = [x1-P(:.x2.-d2) d=[d1(:. Emelianenko M. Springer-Verlag. doi:10. Int J Numer Methods Eng 37(9):1531–1555. Jouve F (2005) A level-set method for vibration and multiple loads structural optimization.d2(:.12. Gunzburger M.end).1:(end-1)). Sun F. doi:10. Menezes IFM.1002/nme. Seoul. Struct Multidisc Optim 29:407–417 Osher S.xc. %-------------------------------------------------------------------------% function d = dDiff(d1. Levy B. Menezes IFM. doi:10. d=[d. d=[d.^2+(P(:. Gunzburger M.1007/s00158-009-0430-0 Cuthill E.2)-y2]. Ju LL (2006) Convergence of the Lloyd algorithm for computing centroidal Voronoi tessellations.d2) % min(d1. Gattass M. Huang R (2005) Structure topology optimization: fully coupled level set method via FEMLAB. ACM Press.1)-x1. Struct Multidisc Optim 32(3):173–181.d2) d=[d1(:.1:(end-1))]. d = [d. New York. Gunzburger M (2002) Grid generation and optimization based on centroidal Voronoi tessellations. Int J Numer Methods Eng 37(9):1511–1530. Korvink JG. 1620370908 Persson P (2006) Mesh size functions for implicit geometries and PDEbased gradient limiting. doi:10.1)-xc).y2) % By convention.1007/s00158-0060017-y Andreassen E. Mukherjee S (1994a) Node and element resequencing using the laplacian of a finite element graph: part I—general concepts and algorithm.d2(:.end).P(:. Gunzburger M (1999) Centroidal Voronoi tessellations: applications and algorithms.1002/nme.y2-y1]. d=[d.end))]. a=a/norm(a). Siam Rev 41(4):637–676 Du Q.2)]. Pantz O (2006) Structural optimization with FreeFem++.d2(:. New York Paulino GH.cma. Lazarov B. %-------------------------------------------------------------------------% function d = dCircle(P.x1. %-------------------------------------------------------------------------% function d = dIntersect(d1. Comput Methods Appl Mech Eng 194(30–33):3269–3290. Wang D (2008) Centroidal Voronoi tessellationbased finite element superconvergence. doi:10. Sigmund O (2011) Efficient topology optimization in MATLAB using 88 lines of code. Gattass M.1007/ s00158-010-0594-7 Aurenhammer F (1991) Voronoi diagrams—a survey of a fundamental geometric data structure. d=b(:. %-------------------------------------------------------------------------% function d = dUnion(d1. Ju L (2003) Constrained centroidal Voronoi tessellations for surfaces. Eng Comput 22(2):95–109 Persson P. Zhao W (2006) Adaptive finite element methods for elliptic PDEs based on conforming centroidal VoronoiDelaunay triangulations.805928 Du Q. %-------------------------------------------------------------------------% function d = dLine(P. Mukherjee S (1994b) Node and element resequencing using the laplacian of a finite element graph: part II—implementation and numerical results. McKee J (1969) Reducing the bandwidth of sparse symmetric matrices. In: 7th world congress on structural and multidisciplinary optimization. Wang DS (2005) The optimal centroidal Voronoi tessellations and the Gersho’s conjecture in the three-dimensional space. pp 157–172.PolyMesher: a general-purpose mesh generator for polygonal elements written in Matlab Appendix B: Library of distance functions 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 %-------------------------------------------------------------------------% function d = dRectangle(P.y1.max(d1(:. Fedkiw R (2003) Level set methods and dynamic implicit surfaces. y1-P(:. South Korea.y1.1002/nme.1:(end-1))].x2. P(:.[].d2) d=[d1(:. ACM Trans Graph 28(4):101:1–17 Liu Z. Comput Math Appl 49(9–10):1355–1373 Du Q. doi:10. Siam J Numer Anal 44(1):102–119.2)*a(1). d=[d. Yan D. Saito S (1998) Fracture analyses using spring networks with random geometry.yc. vol 153.d2(:.1)*a(2)-b(:.d]. d=[d. Clausen A.d2(:. doi:10. ACM Comput Surv 23(3):345–405 Bolander JE. doi:10. doi:10.1620370907 Paulino GH.d2) % max(d1.1)-x2. %-------------------------------------------------------------------------% References Allaire G.end))].max(d1(:. Int J Numer Methods Eng 76(12):1819–1839.end). Struct Multidisc Optim 41(3):453–464. Applied mathematical sciences.max(d.d2) % max(d1. P(:. doi:10. Strang G (2004) A simple mesh generator in MATLAB. NY. Struct Multidisc Optim 43(1):1–16.r) d=sqrt((P(:.min(d1(:.2).2374 Ju L.1016/S0096-3003(01)00260-0 Du Q. Appl Math Comput 133(2– 3):591–607.2)-yc). a point located at the left hand side of the line % is inside the region and it is assigned a negative distance value.-d2(:. Wang W. Siam J Sci Comput 28(6):2023–2053 Langelaar M (2007) The use of convex uniform honeycomb tessellations in structural topology optimization.^2)-r.1:(end-1)).1:(end-1)). Qin H. Eng Fract Mech 61(5–6):569–591.2004.end))].1145/ 800195.1:(end-1))]. Schevenels M. Siam Rev 46(2):329–345 . Faber V. doi:10. b=[P(:.2)-y1].d]. In: Proceedings of the 24th national conference.018 Allaire G. a=[x2-x1.x1.1016/j. Lu L. Siam J Sci Comput 24(5):1488–1506 Du Q. 21–25 May 2007 Liu Y.1016/S0013-7944(98)00069-1 Challis VJ (2010) A discrete level-set topology optimization code written in matlab.

1467-8667. Comput J 16(2):157–160 Saxena A (2008) A material-mask overlay strategy for continuum topology optimization of compliant mechanisms using honeycomb discretization. J Mech Des 130(8):082304.1002/nme. Math Comput 74(250):603–627 .2936891 Sethian JA (1999) Fast marching methods. Menezes IFM (2010) Polygonal finite elements for topology optimization: a unifying paradigm. Comput Fluids 27(5–6):663–680 Talischi C.1007/s00158-011-0696-x Yip M. Paulino GH. Malsch EA (2006) Recent advances in the construction of polygonal finite element interpolants.1141 Suresh K (2010) A 199-line matlab code for Pareto-optimal tracing in topology optimization. Tabarraei A (2004) Conforming polygonal finite elements. Pereira A. Paulino GH. Paulino GH. Alliez P. Pereira A. Siam Rev 41(2):199– 235 Sieger D. Smereka P.2005. Mohle J. doi:10. doi:10.C. Raghavan P.1115/ 1. Int J Numer Methods Eng 82(6):671–698. doi:10. Finite Elem Anal Des 40(12):1619–1640 Ricci A (1973) A constructive geometry for computer graphics. Ghosh S (2004) Two scale response and damage modeling of composite materials. Talischi et al. Li S. In: Proceedings of the 19th international meshing roundtable Sigmund O (2001) A 99 line topology optimization code written in Matlab. Bolander JE (2005) Automated modeling of three-dimensional structural components using irregular lattices. doi:10. doi:10. Menezes IFM (2011) PolyTop: a Matlab implementation of a general topology optimization framework using unstructured polygonal finite element meshes. Struct Multidisc Optim 21(2):120–127 Sukumar N.x Zhao H (2004) A fast sweeping method for Eikonal equations. Fatemi E. doi:10. Int J Numer Methods Eng 61(12):2045–2066. Arch Comput Methods Eng 13(1):129–163 Sukumar N. doi:10.2763 Talischi C. Comput-aided Civil Infrastruct Eng 20(6):393–407.00407.1111/j. Osher S (1998) An improved level set method for incompressible two-phase flows.1007/s00158-010-0534-6 Sussman M. Struct Multidisc Optim 37(6):569–583. Le CH (2009) Honeycomb Wachspress finite elements for structural topology optimization. Botsch M (2010) Optimizing Voronoi diagrams for polygonal finite element computations.1007/s00158-008-0261-4 Talischi C.1002/ nme. Struct Multidisc Optim 42(5):665– 679.

- RIGID BODY DYNAMIC
- SS-304L
- ds-2-mod
- Precarico e Serraggio
- 290390 Manuale Uso
- Shopping Cart - Tube-Town GmbH
- Industria Metalmeccanica
- Calcolo di giunti saldati
- VOITH Vorecon Variable Speed Panetary Gear
- Precarico e serraggio.pdf
- Tension Chart 13934
- [E-book - ITA] - Leggi Di Murphy
- Danny Gatton - Telemaster
- Fac Simile Compilazione Modulo Cambio Residenza-Indirizzo
- Hand in Hand With Blues
- Tabella TUBI.pdf
- HyperMesh 8.0 User's Guide.pdf
- Dumb Le Notes
- 59 Bassman Manual
- 1- Meccanica Della Locomozione
- .__ AMT Electronics - Articles — Why «TUBE-LIKE» Cannot Measure Up To «TUBE INSIDE» __
- MetodoElementiFiniti
- Two Dimensional Analysis of Frame Structures

- Seeger - Low Rank Updates for the Cholesky Decomposition - Cholupdate
- 1687-2770-2013-10
- m Sequence
- The Polynomial Toolbox for MATLAB
- spectral methods
- Digital Control System-1
- Recognizing&RepresentingaGraph TopCoders
- Num Computing Notes Only
- Algorithms Interview Questions
- Hmm
- Vorlesung_3.2_SpatialTransformations.pdf
- Lin Do Tutorial
- Decoding by Linear Programming
- Chapter14_2007
- Fast and Precise Fourier Transforms
- Finding the Complex Roots of Polynomials
- Grid Generation
- A Fast Algorithm for Computing High-Dimensional Risk Parity Portfolios
- DSP--LAB#01
- Optimum design of measurement channels and control policies for linear-quadratic stochastic systems.pdf
- 01708008
- Dat Toro Convo Pt
- Definite Integration in Mathematica
- US Federal Reserve
- c11-5
- Min-Max Transfer Capability - A New Concept.pdf
- Ms 000000000
- Chapter No 03
- JournalVersion_57_-1.pdf
- aaai05-ao

Are you sure?

This action might not be possible to undo. Are you sure you want to continue?

We've moved you to where you read on your other device.

Get the full title to continue

Get the full title to continue listening from where you left off, or restart the preview.

scribd