A *deformation* refers to a node that can be added to a plot to deform the visual results according to a chosen vector quantity. In structural mechanics applications, you might want to show the displacement of a part. In acoustics models, which we’ll discuss most extensively here, you can visualize the actual shape of the wave.

Let’s consider the example of a condenser microphone, which can be found under *File > Application Libraries > Acoustics Module > Electroacoustic Transducers > condenser microphone*, or downloaded here. For those of you who do not have the Acoustics Module installed, note that you can still open the tutorial model to investigate the settings and run postprocessing.

The condenser microphone tutorial model studies the deformation of a membrane (a diaphragm) in the microphone that transforms mechanical displacement into an AC signal. An existing plot in the solved tutorial model called *3D Membrane deformation* already shows the deformation of the diaphragm:

The surface node plots the displacement field in the vertical direction at a chosen frequency. The plot below illustrates the maximum frequency in the simulation, with the deformation disabled (to disable a node, right-click and choose *Disable*):

To add a deformation from scratch, right-click the appropriate plot node and choose *Deformation*:

Deformations can be applied to most 2D and 3D plot types — arrow, isosurface, contour, streamline, surface, slice, and volume. In the settings, you can choose the relevant vector quantity (in this case, the displacement field):

With the deformation plot re-enabled, we can see the changes in the shape of the membrane for this frequency:

If you take another quick look at the settings, you’ll notice that there is a very large scale factor:

Deformations are often scaled by a large factor in order to make microscale changes and deflections visible, or to shrink enormous deformations so they don’t obscure important parts of the model. In very small devices such as MEMS hardware or in the case of this microphone, real deformations are not always visible to the naked eye.

*Height expressions* are a special kind of deformation that, rather than being based on a vector quantity, plot a single variable. This type of deformation allows you to transform a 2D plot into a 3D plot. In another acoustics simulation (found under *File > Application Libraries > Acoustics Module > Piezoelectric Devices > piezoacoustic transducer* or downloaded here), one plot uses a height expression to demonstrate the acoustic pressure field generated by a piezoacoustic transducer.

The pressure field is originally plotted on a surface in two dimensions:

A height expression, however, will turn this surface into a 3D plot, showing the height of the peaks and troughs:

This particular height expression pulls settings from the parent node; however, the settings can also be set to use an expression selected by the user. In this tutorial model, the default expression for the height data will base the height of the surface at each point on the magnitude of the acoustic pressure field:

Height expressions also have an offset toggle bar (shown above) that allows you to manually shift the entire deformed structure in the *z*-direction. The plot below indicates the results, with an offset of 1.5.

Finally, we’ll take a look at 2D deformations that are very useful for creating *periodic arrays* — arrangements where an object or pattern is repeated over and over, but usually only a single cell or slice of the device has been modeled.

To demonstrate this, we’ll turn to the plasmonic wire grating tutorial model. The tutorial model can be found under *File > Application Libraries > RF Module > Demo Tutorials > plasmonic wire grating* or downloaded here. This example computes transmission and reflection coefficients for a planar electromagnetic wave incident on a wire grating. Rather than modeling the entire device, a unit cell representing only one bar of the grating is used. However, the tutorial model contains a periodic condition to indicate that, in the real structure, the cell is repeated on either side of itself.

The results for the plasmonic wire grating tutorial model show the electric field norm on the grating for a chosen angle of incidence. Although the solved tutorial model in the Application Libraries contains an array data set, we have generated a new surface plot that demonstrates the creation of an array using deformations:

In some cases, a 2D array data set is faster and easier to use than a deformation; however, individual deformations enable you to control the exact placement of different copies of a solution. Here, we have translated a second surface by *d* nanometers (nm), which is the width of the unit cell, in the positive *x*-direction:

The scaling factor is set to *1* to ensure that the surface moves by the correct distance. Notice that the title is now duplicated as well. The plot title can be disabled in the node for each surface plot in order to avoid repeats. The same can be done for color legends.

We can duplicate this surface and simply change the expression for the *x*-component in each plot, and thus line up several cells next to each other:

The figure below illustrates the results with four translated copies of the surface. The original plot is in the center, with the outline of the data set shown:

While we won’t go into detail here about other cases of using deformations, you might also want to show displacements in many structural mechanics and fluid models. For example, the plot below shows the displacement of a reciprocating engine in motion, with the outlines of the original position:

In this tutorial model of a micromirror, a deformation shows the displacement field (with *u*, *v*, and *w* components) to depict the mirror’s response to different levels of prestress. The outline of the original position (flat) is shown underneath:

Deformations can also be used to creatively illustrate fluid flow so the meaning becomes clearer. In the figure below, a line plot is deformed according to the velocity of air flowing across a heat sink:

That wraps up our blog post on deformations. In the next blog post of our postprocessing series, we will focus on various tips and tricks designed to advance your postprocessing techniques!

]]>

Recall our simple example of 1D heat transfer at steady state with no heat source, where the temperature T is a function of the position x in the domain defined by the interval 1 \le x \le 5. We imposed the Neumann boundary condition such that the outgoing flux should be 2 at the left boundary (x=1) and the Dirichlet boundary condition such that the temperature should be 9 at the right boundary (x=5). After discretizing the weak form equation, we obtained this matrix equation:

\left(

\begin{array}{cccccc}

1 & -1 & 0 & 0 & 0 & 0 \\

-1 & 2 & -1 & 0 & 0 & 0 \\

0 & -1 & 2 & -1 & 0 & 0 \\

0 & 0 & -1 & 2 & -1 & 0 \\

0 & 0 & 0 & -1 & 1 & 1 \\

0 & 0 & 0 & 0 & 1 & 0

\end{array}

\right)

\left(

\begin{array}{c} a_1 \\ a_2 \\ a_3 \\ a_4 \\ a_5 \\ \lambda_2 \end{array}

\right)

= \left(

\begin{array}{c} -2 \\ 0 \\ 0 \\ 0 \\ 0 \\ 9 \end{array}

\right)

\begin{array}{cccccc}

1 & -1 & 0 & 0 & 0 & 0 \\

-1 & 2 & -1 & 0 & 0 & 0 \\

0 & -1 & 2 & -1 & 0 & 0 \\

0 & 0 & -1 & 2 & -1 & 0 \\

0 & 0 & 0 & -1 & 1 & 1 \\

0 & 0 & 0 & 0 & 1 & 0

\end{array}

\right)

\left(

\begin{array}{c} a_1 \\ a_2 \\ a_3 \\ a_4 \\ a_5 \\ \lambda_2 \end{array}

\right)

= \left(

\begin{array}{c} -2 \\ 0 \\ 0 \\ 0 \\ 0 \\ 9 \end{array}

\right)

where a_1, a_2, \cdots , a_5 are unknown temperature values at the nodal points (x=1, 2, \cdots, 5) and \lambda_2 is an unknown heat flux at the right boundary (x=5). The matrix on the left-hand side is customarily called the *stiffness matrix* and the vector on the right is called the *load vector*, due to the application of this technique in structural mechanics.

The steps for implementing the weak form equation in COMSOL Multiphysics have been discussed in this earlier blog entry, thus we will not repeat them here. To view the stiffness matrix and load vector, right-click *Solution 1* in the model tree → *Other* → *Assemble*, as shown in the screenshot below:

Then, in the settings window for the *Assemble 1* node, we can select the matrices of interest by checking the corresponding checkbox for each item. After solving, we can evaluate the matrices by right-clicking *Derived Values* and then selecting *System Matrix*, as illustrated below:

In the corresponding settings window, we can select *Stiffness matrix* from the *Matrix* drop-down menu and evaluate it in a table. As indicated in the screenshot below, we obtain exactly the same 6×6 matrix as the one in Eq. (1).

The load vector on the right-hand side of Eq. (1) can be evaluated and verified by the same procedure.

We mentioned before that it is sometimes desirable not to solve for the Lagrange multiplier \lambda_2 — for example, to save computation resources. To do so, we right-click the *Weak Form PDE* main node → *More* → *Pointwise Constraint*, as depicted below:

Then, in the settings window, we enter 9-T for the *Constraint expression* input field. After solving, we obtain exactly the same solution, but a smaller 5×5 stiffness matrix:

If we look at this matrix closely, we find that it matches the upper left-hand part of the 6×6 matrix that we observed earlier. This should not be too surprising, as we are solving exactly the same problem (represented by Eq. (1)), just in a slightly different way. We will briefly discuss this next.

When we implement the Dirichlet boundary condition using the *Weak Contribution* feature with a Lagrange multiplier \lambda_2 (as shown in this previous blog post), we effectively ask that the entire matrix equation (1) be solved to yield the coefficients a_1, a_2, \cdots , a_5 as well as the multiplier \lambda_2.

On the other hand, when we implement the fixed boundary condition using the *Pointwise Constraint* feature as shown above, we essentially ask that the same matrix equation (1) be solved without explicitly solving for the Lagrange multiplier \lambda_2. The software effectively segregates Eq. (1) to this form (see below)

\left(\begin{array}{cc}

K & N_F \\

N & 0 \end{array}\right)

\left(\begin{array}{c}

U \\

\Lambda \end{array}\right)

=

\left(\begin{array}{c}

L \\

M \end{array}\right)

K & N_F \\

N & 0 \end{array}\right)

\left(\begin{array}{c}

U \\

\Lambda \end{array}\right)

=

\left(\begin{array}{c}

L \\

M \end{array}\right)

where the stiffness matrix K is the 5×5 matrix shown above, the constraint Jacobian matrix N is (0 \, 0 \, 0 \, 0 \, 1), the constraint force Jacobian matrix N_F is (0 \, 0 \, 0 \, 0 \, 1)^T, the solution vector U is formed by the coefficients a_1, a_2, \cdots , a_5, the (one-element) vector \Lambda is formed by the Lagrange multiplier \lambda_2, the load vector L is (-2 \, 0 \, 0\, 0\, 0)^T, and the (one-element) constraint vector M is (9).

This segregation of Eq. (1) is shown graphically below:

Of course, in reality, when the

Pointwise Constraintfeature is specified, the software does not bother to assemble the full 6×6 matrix in Eq. (1). Instead, it assembles K, N, and N_F, which requires less computational resources than assembling the full matrix.

Eq. (2) can be written as a system of two matrix equations:

K \, U+ N_F \, \Lambda = L

N \, U = M

where the first one (3) contains the part of the discretized weak form equation with heat flux boundary conditions and the second one (4) contains the constraint imposed by the Dirichlet boundary condition.

The equation system can be solved in two steps. In the first step, the constraint equation (4) is solved for the degree(s) of freedom involved with the Dirichlet boundary condition. In the second step, the solution from the first step is substituted into Eq. (3) to solve for the remaining degrees of freedom.

The resulting solution vector U is then given as the linear combination of the solutions from the two steps:

(5)

U=U_d+Null \, U_n

The first term U_d is the solution vector of the constraint equation (4) solved in the first step. The second term is obtained from the second step in the form of the product of a matrix Null and a solution vector U_n. The columns of the matrix Null are formed by the basis vectors spanning the null space of the constraint Jacobian matrix N. So, we have

N \, Null \equiv 0

The solution vector U_n is the solution to the *eliminated* matrix equation

K_c \, U_n = L_c

where the *eliminated stiffness matrix* K_c and the *eliminated load vector* L_c are given by

\begin{align}

K_c& = Nullf^T \, K \, Null \\

L_c& = Nullf^T \, (L-K \, U_d)

\end{align}

K_c& = Nullf^T \, K \, Null \\

L_c& = Nullf^T \, (L-K \, U_d)

\end{align}

and the columns of the matrix Nullf are formed by the basis vectors spanning the null space of the transpose of the constraint force Jacobian matrix N_F. So, we have

Nullf^T \, N_F \equiv 0

The term *eliminated* indicates that the degree(s) of freedom involved in the Dirichlet boundary condition have been removed from the matrix equation (6). In our example, the size of the eliminated stiffness matrix K_c is 4×4.

Notice that the solution procedure described above does not involve the Lagrange multiplier vector \Lambda. Indeed, the value of the Lagrange multiplier \lambda_2 is left unsolved by this procedure. The advantage of this method is that the required computational resources are reduced. For our simple example, the size of the matrix is reduced from 6×6 to 4×4 (plus an even smaller one for the constraint equation).

COMSOL Multiphysics allows us to evaluate and view any of the matrices and vectors mentioned above. All we have to do is to follow the same procedure outlined in the previous section on viewing the stiffness matrix and load vector. However, we quickly find out that we will spend a lot of time clicking on each System Matrix node in the Model Builder and then clicking on the “Evaluate” button in the settings window. Also, we can only see one matrix or vector at a time, making it tedious to examine all the matrices and vectors.

This represents one of the many situations in which a COMSOL application can help enhance modeling experience and productivity (learn about application webinars below). The core package of COMSOL Multiphysics can be used to build a COMSOL app based on any COMSOL model by wrapping a user interface (UI) around it. The UI is completely customizable and can be easily configured to suit individual modeling needs.

For an introduction to COMSOL applications, see the following webinars: Intro to COMSOL Multiphysics® 5.0 and the Application Builder (with a focus on the second half) and How to Build and Run Simulation Apps with COMSOL Server™.

The following screenshots show just one of the essentially infinite number of ways that a UI can be arranged to serve as a convenient tool for investigating the matrices and vectors. The app is set up to switch among several different kinds of boundary conditions via checkboxes. All matrices and vectors are evaluated and displayed by a single click of the “Compute” button. Here is a screenshot of the case in which the full 6×6 matrix is used to solve:

We see that N, N_F, and M are empty and K_c remains the full size of 6×6. In contrast, here is the screenshot for the second case where the eliminated 4×4 matrix is used to solve:

Using our simple heat transfer example, we have explored the two different ways to solve the matrix equation obtained from discretizing the weak form equation. We found that it can be much simpler to evaluate and inspect the various matrices and vectors involved in the solution process by setting up a COMSOL application. In the next blog posts, we will continue to use COMSOL apps to help us investigate more complex examples.

As a general-purpose development environment for multiphysics simulation, the COMSOL Desktop® environment must be structured with a limited arrangement of UI elements. The COMSOL app frees us from such limitations, providing the power for building specialized UI for unique requirements. Additionally, the built-in coding functionality allows much more versatile computations, and COMSOL Server™ license enables the deployment of apps for worldwide access by coworkers as well as clients.

We hope that you will use these powerful features in COMSOL Multiphysics to boost your own work efficiency!

]]>

When light is incident upon a semi-transparent material, some of the energy will be absorbed by the material itself. If we can assume that the light is single wavelength, collimated (such as from a laser), and experiences very minimal refraction, reflection, or scattering within the material itself, then it is appropriate to model the light intensity via the *Beer-Lambert law*. This law can be written in differential form for the light intensity I as:

\frac{\partial I }{\partial z} = \alpha(T) I

where *z* is the coordinate along the beam direction and \alpha(T) is the temperature-dependent absorption coefficient of the material. Because this temperature can vary in space and time, we must also solve the governing partial differential equation for temperature distribution within the material:

\rho C_p \frac{\partial T }{\partial t}-\nabla \cdot (k \nabla T)= Q = \alpha(T) I

where the heat source term, Q, equals the absorbed light. These two equations present a bidirectionally coupled multiphysics problem that is well suited for modeling within the core architecture of COMSOL Multiphysics. Let’s find out how…

We will consider the problem shown above, which depicts a solid cylinder of material (20 mm in diameter and 25 mm in length) with a laser incident on the top. To reduce the model size, we will exploit symmetry and consider only one quarter of the entire cylinder. We will also partition the domain up into two volumes. These volumes will represent the same material, but we will only solve the Beer-Lambert law on the inside domain — the only region that the beam is heating up.

To implement the Beer-Lambert law, we will begin by adding the *General Form PDE* interface with the *Dependent Variables* and *Units* settings, as shown in the figure below.

*Settings for the implementing the Beer-Lambert law. Note the Units settings.*

Next, the equation itself is implemented via the *General Form PDE* interface, as illustrated in the following screenshot. Aside from the source term, f, all terms within the equation are set to zero; thus, the equation being solved is f=0. The source term is set to **Iz-(50[1/m]*(1+(T-300[K])/40[K]))*I**, where the partial derivative of light intensity with respect to the *z*-direction is **Iz**, and the absorption coefficient is **(50[1/m]*(1+(T-300[K])/40[K]))**, which introduces a temperature dependency for illustrative purposes. This one line implements the Beer-Lambert law for a material with a temperature-dependent absorption coefficient, assuming that we will also solve for the temperature field, **T**, in our model.

*Implementation of the Beer-Lambert law with the* General Form PDE *interface.*

Since this equation is linear and stationary, the *Initial Values* do not affect the solution for the intensity variable. The *Zero Flux* boundary condition is appropriate on most faces, with the exception of the illuminated face. We will assume that the incident laser light intensity follows a Gaussian distribution with respect to distance from the origin. At the origin, and immediately above the material, the incident intensity is 3 W/mm^{2}. Some of the laser light will be reflected at the dielectric interface, so the intensity of light at the surface of the material is reduced to 0.95 of the incident intensity. This condition is implemented with a *Dirichlet Boundary Condition*. At the face opposite to the incident face, the Zero Flux boundary condition simply means that any light reaching that boundary will leave the domain.

*The Dirichlet Boundary Condition sets the incident light intensity within the material.*

With these settings described above, the problem of temperature-dependent light absorption governed by the Beer-Lambert law has been implemented. It is, of course, also necessary to solve for the temperature variation in the material over time. We will consider an arbitrary material with a thermal conductivity of 2 W/m/K, a density of 2000 kg/m^{3}, and a specific heat of 1000 J/kg/K that is initially at 300 K with a volumetric heat source.

The heat source itself is simply the absorption coefficient times the intensity, or equivalently, the derivative of the intensity with respect to the propagation direction, which can be entered as shown below.

*The heat source term is the absorbed light.*

Most other boundaries can be left at the default *Thermal Insulation*, which will also be appropriate for implementing the symmetry of the temperature field. However, at the illuminated boundary, the temperature will rise significantly and radiative heat loss can occur. This can be modeled with the *Diffuse Surface* boundary condition, which takes the ambient temperature of the surroundings and the surface emissivity as inputs.

*Thermal radiation from the top face to the surroundings is modeled with the Diffuse Surface boundary condition.*

It is worth noting that using the Diffuse Surface boundary condition implies that the object radiates as a gray body. However, the gray body assumption would imply that this material is opaque. So how can we reconcile this with the fact that we are using the Beer-Lambert law, which is appropriate for semi-transparent materials?

We can resolve this apparent discrepancy by noting that the material absorptivity is highly wavelength-dependent. At the wavelength of incident laser light that we are considering in this example, the penetration depth is large. However, when the part heats up, it will re-radiate primarily in the long-infrared regime. At long-infrared wavelengths, we can assume that the penetration depth is very small, and thus the assumption that the material bulk is opaque for emitted radiation is valid.

It is possible to solve this model either for the steady-state solution or for the transient response. The figure below shows the temperature and light intensity in the material over time, as well as the finite element mesh that is used. Although it is not necessary to use a swept mesh in the absorption direction, applying this feature provides a smooth solution for the light intensity with relatively fewer elements than a tetrahedral mesh. The plot of light intensity and temperature with respect to depth at the centerline illustrates the effect of the varying absorption coefficient due to the rise in temperature.

*Plot of the mesh (on the far left) and the light intensity and temperature at different times.*

*Light intensity and temperature as a function of depth along the centerline over time.*

Here, we have highlighted how the *General Form PDE* interface, available in the core COMSOL Multiphysics package, can be used for implementing the Beer-Lambert law to model the heating of a semi-transparent medium. This approach is appropriate if the incident light is collimated and at a wavelength where the material is semi-transparent.

Although this approach has been presented in the context of laser heating, the incident light needs only to be collimated for this approach to be valid. The light does not need to be coherent nor single wavelength. A wide spectrum source can be broken down into a sum of several wavelength bands over which the material absorption coefficient is roughly constant, with each solved using a separate *General Form PDE* interface.

In the approach presented here, the material itself is assumed to be completely opaque to ambient thermal radiation. It is, however, possible to model thermal re-radiation within the material using the *Radiation in Participating Media* physics interface available within the Heat Transfer Module.

The Beer-Lambert law does assume that the incident laser light is perfectly collimated and propagates in a single direction. If you are instead modeling a focused laser beam with gradual variations in the intensity along the optical path then the *Beam Envelopes* interface in the Wave Optics Module is more appropriate.

In future blog posts, we will introduce these as well as alternate approaches for modeling laser-material interactions. Stay tuned!

]]>

Consider a drum head constructed by stretching a membrane over a stiff frame that encloses a flat 2D domain. The vibration of the membrane is described by the wave equation (Helmholtz equation) with the Dirichlet boundary condition at the periphery of the domain where the membrane is constrained by the stiff frame. In this case, there is a set of discrete solutions to the wave equation, called *normal modes* or *eigenmodes*, each of which vibrates at a characteristic frequency, called *eigenfrequencies*.

The lowest eigenfrequency defines the fundamental tone, which for instance could be concert pitch A (440 Hz). The set of higher eigenfrequencies, or *overtones* in musical terms, gives rise to the tone color or timbre of the vibrating membrane. Kac’s lecture drew our attention to the eigenfrequencies: Is it possible to construct two drum heads with different shapes that share a set of eigenfrequencies? The idea was that if the two drums have an identical set of eigenfrequencies (being *isospectral*), then they would have the same timbre and sound the same to the ear, even though their shapes are different.

Kac commented on the asymptotic behavior of the eigenfrequencies in the limit of very high frequencies and made connections to various branches of physics and mathematics to provide a ground for intuitive understanding. The uniqueness question (in 2D flat space) remained unsolved until over two decades later when Gordon, Webb, and Wolpert finally constructed two polygons with an identical set of eigenvalues (see “One cannot hear the shape of a drum” and “Isospectral plane domains and surfaces via Riemannian orbifolds“).

The eigenvalues of the two polygons can be computed numerically, which is shown in this Isospectral Drums model in our Model Gallery.

The image below shows the first three normal modes of the two polygons that share the same set of eigenfrequencies:

In Gordon and Webb’s easy-to-read introductory article on this subject (“You can’t hear the shape of a drum”, *American Scientist*, vol. 84 (1996), pp. 46–55), they commented that such isospectral drums with different shapes are expected to be the exception, not the rule. In other words, they expected that, in general, one *can* hear the shape of a drum, unless the shape of the drum is specially constructed to be isospectral with another shape, like the two polygons depicted above.

In the following discussion, we will take a closer look at such special shapes by considering various physical mechanisms involved in the sound production and detection. We will find that when we include relevant physical effects, we actually *can* tell two drums apart by the sound, even if they are specially constructed to share the same set of eigenfrequencies.

The first effect we will examine is the excitation of the vibrational modes in the membrane. Since the timbre is determined by the set of relative amplitudes of the normal modes, it is not enough to just have an identical set of eigenfrequencies for the two drums to sound the same. They also need to have the same relative amplitude for each eigenmode, which may not be trivial to achieve.

Let’s take, for example, the same two polygonal drums from above and hit them with a drum stick at a few arbitrary places, one at a time, as such:

Each location of striking is somewhere in the middle of the drum, where a child may instinctively choose to hit if given such a drum and a drum stick. We use COMSOL Multiphysics simulation software to calculate the frequency response of each of the locations and plot the results in the graphs below.

We first focus on just one drum, say, the one on the left. Here is a plot showing the left drum’s frequency response:

As we hinted at earlier, the drum sounds differently depending on the location where it is struck by the drum stick. We see different energy distribution among the first three eigenmodes, which will result in different timbre. This is, of course, a well-known fact to percussionists and is the result of the same principle that enables a single bell to ring in two distinct tones, as demonstrated by this ancient set of bells from over two thousand years ago.

Now we know we can’t even make one drum sound the same unless we have a perfect aim of the drum stick. Is there any hope that we can make the two different drums sound the same?

In the graph below, we’ve added the frequency response of the second drum (the dashed curves). As we examine the graph, it becomes evident that none of the dashed curves match the solid curves in all three of the eigenmodes. In other words, the two drums do sound differently, even though they are isospectral, sharing the same set of eigenfrequencies.

Of course, we haven’t done an exhaustive search of all the possible combinations of striking locations. However, this simple example illustrates that it is not an easy job to make the drums sound the same, due to the different coupling strengths of energy from the drum stick to the various vibrational modes of the membrane.

The magic of mathematics never ceases to amaze us. Not long after the two isospectral polygons were published, Buser, Conway, Doyle, and Semmler constructed a pair of domains that are not only isospectral (sharing the same set of eigenfrequencies), but also *homophonic*: having a special point in the domain such that “corresponding normalized Dirichlet eigenfunctions take equal values at the distinguished points” (“Some planar isospectral domains“). In other words, if the special point of each drum is hit by a drum stick, then each corresponding pair of eigenmodes of the two drums will be excited with the same amplitude and the two drums will sound the same.

Shown below are the first few normal mode shapes computed numerically:

The special point of each domain is marked with a blue square in the schematic below:

In the following graph, we plot the computed frequency response of the two drums to a narrow Gaussian area load centered on each of the special points:

Isn’t it amazing how well the two frequency response curves (solid blue curve and green circles) lie on top of each other? With such a perfectly matched vibrational energy spectrum, wouldn’t the two drums sound exactly the same? Let’s continue our journey to explore more physical effects and find out.

Our ears do not sense the vibration of the membrane directly. Rather, the sensing is mediated by the acoustic wave in the air. Let’s set up the two homophonic drums outdoors, where the sound is allowed to propagate away from the drums without significant reflection. In this case, we can easily compute the frequency spectrum of the sound wave using COMSOL Multiphysics to find out what we really hear with our ears.

Let’s take a look at the three vibrational modes with the highest energies at about 111, 146, and 184 Hz as shown in the spectral graph above. For convenience, we will call them the first, second, and third mode, with the understanding that there are other modes in between being neglected since they are much less energetic.

The polar graph below compares the computed sound pressure level (in dB) in the plane of each of the two drums, a few meters away from each drum.

We see that the sound pressure field produced by the first mode is more or less independent of direction (solid and dashed blue curves). This is not surprising, since the mode shape of each drum looks pretty much like a monopole source:

On the other hand, the directionality of the sound field from the second or the third mode of each of the drums is quite pronounced and also quite different between the two drums. For example, for the second mode, the sound field from Drum 1 looks like a dipole field (solid red curve), while the one from Drum 2 is more complex (dashed red curve). This observation again matches what we see in the mode shapes of the two drums:

What really determines the perceived timbre is the ratio of the amplitudes of the higher modes (the overtones) to the lowest mode (the fundamental tone). So, in the next graph, we plot the amplitude ratios of the second and the third modes to the first mode, at a sampling of directions:

The blue square points are from Drum 1 and the red round points from Drum 2. The graph can be viewed as a map of timbre — if two points on the graph are near each other, then they sound similar; on the other hand, if two points on the graph are far away from each other, then they have very distinct timbre. As qualitatively illustrated by the green dashed boundaries, each drum can produce a range of timbre that the other cannot, in some range of directions.

As long as a listener is allowed to move around each drum, perhaps blindfolded, he or she will hear distinct ranges of timbre that tell the two drums apart. Therefore, even though the two “homophonic” drums share the same energy spectrum in their vibration modes, due to the difference in the mode shape and to the difference in energy transfer to the sound field in the air, the acoustic energy spectrum in some range of directions can be quite different. This is what would cause the two drums to sound differently to our ears.

In the previous analysis, we ignored the reaction force acted on the membrane by the air, the so-called *air loading effect*. It turns out that this effect is very significant for a real drum, since, after all, the entire area of the membrane participates in the pushing and pulling of the air around it.

We can simulate this effect using the *Acoustic-Structure Boundary* Multiphysics coupling feature of COMSOL Multiphysics. We find, for example, that the eigenfrequency of the second mode that we were discussing shifts from 146 Hz down to about 86 Hz. In addition, the magnitudes of shift of the two drums are different. The eigenfrequency of one drum was shifted down to 85.6 Hz, while the one of the other drum shifted to 86.8 Hz. This difference causes a pitch difference of about 23 cents, which is very audible in a side-by-side comparison.

Therefore, not only do the two drums differ in timbre (in some range of directions), they also differ in absolute pitch when we take the air loading effect into account.

The graph below shows the frequency response of the two drums around this mode. The difference in the resonant frequency is clearly seen, as well as the difference in the width of the resonance. There should be no doubt in our mind that with such different frequency responses, the two drums will produce easily distinguishable sounds.

It is a great achievement in mathematics to invent the isospectral drums that share the same set of eigenfrequencies and the homophonic drums that share the same power spectrum of the vibrational modes when excited at a special point. However, these phenomena only happen in vacuum, where there is no sound. Once we put the drums to test in air, they start to sound differently due to the air loading effect and the directionality of the energy transfer from the membrane to the sound wave.

In his lecture, Kac told the early 20^{th}-century story of Lorentz calling for mathematicians’ attention to the eigenvalue problem involved in the theory of black body radiation and Weyl answering the call with the proof of the theorem of the asymptotic behavior of eigenvalues at very high frequencies.

Here, we could use the help of our mathematician friends again, even though the subject matter may not be as grand as black body radiation and quantum mechanics. Is it possible to construct homophonic drums with different shapes that sound the same when including directionality and air loading effects? It may be possible to pose this as an optimization problem to solve numerically for a solution with a finite set of audible frequencies.

However, the computation cost will be high and the result will be approximate. An elegant analytical solution similar to those shown in the papers mentioned above would be much nicer. I hope this will arouse the interest of mathematicians who are reading.

]]>

Let’s start by giving a very conceptual introduction to how a 3D CAD geometry is meshed when you use the default mesh settings in COMSOL Multiphysics. The default mesh settings will always use a Free Tetrahedral mesh to discretize an arbitrary volume into smaller elements. Tetrahedral elements (tets) are the default element type because any geometry, no matter how topologically complex, can be subdivided and approximated as tets. Within this article, we will only discuss free tetrahedral meshing, although there are situations when other types of meshes can be more appropriate, as discussed here.

*A cylinder (left) is meshed with triangular elements (grey) on the surface and the tetrahedral meshing algorithm subdivides the volume with tets (cyan). The ends are omitted for clarity.*

At a conceptual level, the tetrahedral meshing algorithm begins by applying a triangular mesh to all of the faces of the volume that you want to mesh. The volume is then subdivided into tetrahedra, such that each triangle on the boundary is respected and the size and shape of the tetrahedra inside the volume meets the specified size and growth criteria. If you get the error message “Failed to respect boundary element edge on geometry face” or similar, it is because the shape of the tetrahedra became too distorted during this process.

Of course, the true algorithm can only be stated mathematically, not in words. There are, however, cases that can cause this algorithm some difficulties, and these cases can be understood without resorting to any equations. The free tetrahedral meshing algorithm can have difficulties if:

- The part is extremely complex with very detailed regions mixed with coarse mesh.
- The aspect ratios of the edges and boundaries defining the domain are very large.

Let’s take a look at some examples of each case and how partitioning can help us.

To get us started, let us consider a modestly complex geometry: the *Helix* geometry primitive. You can certainly think of more complex geometries than this, but we can illustrate many concepts starting with this case.

Go ahead and open a new COMSOL Model file and create a helix with ten turns, and then mesh it with the default settings, as shown below.

*A ten-turn helix primitive with the corresponding default tetrahedral mesh.*

When you were meshing this relatively simple part, you may have noticed that the meshing step took a relatively long time. So let’s look at how partitioning can simplify this geometry. Add a *Work plane* to your geometry sequence that bisects the length of the helix and then add a *Partition* feature, using the Work plane as the partitioning object.

*A Work plane is used to partition the helix.*

As you can see from the image above, the resultant ten-turn helix object is now composed of twenty different domains, each representing a half-turn of the helix. When you re-mesh this model, you will find that the meshing time is reduced, which is good. Each domain represents a much easier meshing problem than the original problem, and, furthermore, the domains can be meshed in parallel on a multi-core computer.

However, you’re probably also thinking to yourself that we now have twenty different domains, and that we’ve subdivided the six surfaces of this helix into one hundred two surfaces, including the internal boundaries, which are dividing up the domain. Although this geometry now meshes a lot faster, we have added many more domains and boundaries that can be a distraction as we apply material properties and boundary conditions. What we actually want is to use the partitioned geometry for the mesh, but ignore the partitioning during the set-up of the physics.

What you’ll want to do next is to add a *Virtual Operation, the Mesh Control Domains* operation. This feature will take, as input, all twenty domains defining the helix. The output will appear to be our original helix, and when we apply material properties and physics settings, there will be only one domain and six boundaries.

*The Mesh Control Domains will specify that these are different domains only for the purposes of meshing.*

When you now mesh this geometry, you’ll observe that you have the best of both. The meshing takes relatively little time, and the physics settings will be easy to apply. If you haven’t already, try this out on your own!

We have only looked at one example geometry here, but there are many other cases where you’ll want to use this type of partitioning. Domains that look like combs or serpentines or objects that have many holes, cutouts, or domains embedded within them all present situations in which you should consider partitioning. Also, keep in mind that you don’t need to partition with planes; you can create and use other objects for partitioning. We’ll take a look at such an example next.

The CAD geometries you are working with can often contain some edges or surfaces that have vastly different sizes relative to the other edges and surfaces defining a domain. We often want to avoid such situations, since small features on a large domain may not be that important for our analysis objectives.

We’ve already looked at how we can ignore these small features using Virtual Operations to Simplify the Geometry, but what if these small features are important? Let’s examine how partitioning can help us in terms of the example geometry shown below.

*A flow domain to be meshed. Three small inlets, with even smaller fillets, protrude from the main pipe.*

The geometry that you see above has a large pipe with three smaller pipes protruding from it. The small fillets that round the transition between the two have dimensions that are over one hundred times smaller than the pipe volume. If we mesh this domain with the default mesh settings, the same settings will be used throughout. However, we will almost certainly want to have smaller mesh sizes around the inlets.

The default mesh will use one setting for all elements within the model. That will not be very useful here. We could just add additional *Size* features to the mesh, and apply these features to all of the faces around the small pipes to adjust the element sizes at these boundaries, but this is not quite optimal. It’s a lot of work and might not give us exactly what we want.

We can also use partitioning to define a small volume within which we will want to have different mesh settings. In the figure below, additional cylinders have been included that surround each of the smaller pipes and extend some distance into the pipe.

*Additional domains (wireframe) which will be used for partitioning of the blue domain.*

*Results of the partitioning operation.*

These additional cylinder objects can be used to partition the original modeling domain, as shown above. Using the Mesh Control Domains, it will again be possible to simplify this geometry down to a single domain for the purposes of physics and materials settings. Once you get to the meshing step, however, it is possible to add a Size feature to the Mesh sequence that will set the element size settings of these newly partitioned domains. This gives us control over the element sizes in these domains and makes things a little bit easier for the mesher.

*Different size features can be applied to each partitioned geometry.*

The geometries that we have looked at here can be meshed with minimal effort or modification to the default meshing settings, but this is not always the case. It is relatively easy to come up with a geometry that no meshing algorithm will ever be able to mesh in a reasonable amount of time. What can we do in that situation?

The answer (as I’m sure you’ve already guessed) is partitioning along with one other concept: divide and conquer. When confronted with a domain that does not mesh, use partitioning to divide it into two domains. Try to individually mesh each one. If one of the domains does not mesh, keep partitioning each half. Using this approach, you’ll very quickly zoom in on the problematic region of the original domain. You can then decide if you want to simplify the problematic parts of the geometry via the usage of Virtual Operations, or you can use the techniques we’ve outlined here and mesh sub-domain by sub-domain, or you can even use some combination of the two.

Another technique that you can use is to apply a Free Triangular mesh on all of the boundaries of the imported geometry. Surface meshing is much faster than volume meshing and will almost always succeed. Visually inspect the resultant surface mesh. It will then often be immediately apparent where in the model the small features and problematic areas are. Once you know where the issues are, delete the Free Triangular mesh, since the free tetrahedral meshing algorithm will typically want to adjust the mesh on the boundaries, but will not do so if there is already a surface mesh defined.

Along with the Virtual Operations which we have already mentioned for simplifying the geometry for meshing, you can also use the Repair and Defeaturing functionality to clean up CAD data originating from another source. The Virtual Operations will simply create an abstraction of the CAD geometry which can only be used inside of the COMSOL software, as compared to the Repair and Defeaturing operations which will modify the CAD directly, and will create a modified CAD representation that can be written out from COMSOL Multiphysics to other software packages.

We have now looked at two different representative cases where the default mesh settings are not optimal — a domain that is very complex as well as a domain with extreme aspect ratios. In both cases, we can use partitioning along with the Mesh Control Domains Virtual Operations feature to simplify the meshing operations.

We have also presented some strategies for handling cases in which your geometry will not mesh with the default settings. It is also worth saying that such situations arise most often when working with imported CAD geometry that was meant for manufacturing, rather than analysis purposes. If you are given a CAD file with many features that are cosmetic rather than functional or that you are reasonably certain will not affect the physics of the problem, consider removing these features in the originating CAD package, before they even get to COMSOL Multiphysics.

In future blog posts, we will also look at combining partitioning with swept meshing, which is another powerful technique in your toolkit as you use COMSOL Multiphysics. Stay tuned!

]]>

Let’s take a look at some sample experimental data in the plot below. Observe that the data is noisy and that the sampling is nonuniform in the *x*-axis. This experimental data may represent a material property. If the material property is dependent upon the solution variable (such as a temperature-dependent thermal conductivity), then we would usually not want to use this data directly in our analyses. Such noisy input data can often cause solver convergence difficulties, for the reasons discussed here. If we instead approximate the data with a smooth curve, then model convergence can often be improved and we will also have a simple function to represent the material property.

*Experimental data that we would like to approximate with a simpler function.*

What we would like to do is find a function, F(x), that fits the experimental data, D(x), as closely as possible. We will define the “best-fit” function as the function that minimizes the square of the difference between the experimental data and our fitting function, integrated over the entire data range. That is, our objective is to minimize:

\int_a^b (D(x)- F(x))^2 dx

So the first thing that we need to do is to make some decisions about what type of function we would like to fit. We have a great deal of flexibility about what *type* of functions to use, but we should choose a fitting function that results in a problem which will be numerically well-conditioned. Although we will not go into the details about why, for maximum robustness we will choose to fit this function:

F(x) = c_0\left(\frac{b-x}{b-a}\right)^3 + c_1 \left(\frac{x-a}{b-a}\right)\left(\frac{b-x}{b-a}\right)^2 + c_2 \left(\frac{x-a}{b-a}\right)^2\left(\frac{b-x}{b-a}\right) + c_3 \left(\frac{x-a}{b-a}\right)^3

which in this case, for a=0, b=1, simplifies to:

F(x) = c_0(1-x)^3 + c_1 x(1-x)^2 + c_2 x^2(1-x) + c_3 x^3

Now we need to find the four coefficients that will minimize:

R(c_0,c_1,c_2,c_3,x)= \int_a^b (D(x)- F(c_0,c_1,c_2,c_3,x))^2 dx

Although this may sound like an optimization problem, we do not have any constraints on our coefficients and we will assume that the above function has a single minimum. This minimum will correspond to the point where the derivatives, with respect to the coefficients, are zero. That is, to find the best fit function, we must find the values of the coefficients at which:

\frac{\partial R} {\partial c_0} = \frac{\partial R} {\partial c_1} = \frac{\partial R} {\partial c_2} =\frac{\partial R} {\partial c_3} = 0

It turns out that we can solve this problem with the core capabilities of COMSOL Multiphysics. Let’s find out how…

We start by creating a new file containing a 1D component. We will use the *Global ODEs and DAEs* physics interface to solve for our coefficients and we will use the Stationary Solver. For simplicity, we will use a dimensionless length unit, as shown in the screenshot below.

*Start out with a 1D component and set Unit system to None.*

Next, create the geometry. Our geometry should contain our interval (in this case, the range of our sample points is from 0 to 1) as well as a set of points along the *x*-direction for every sample point. You can simply copy and paste this range of points from a spreadsheet into the *Point* feature, as shown.

*Add points over the interval at every data sample point.*

Read in the experimental data using the *Interpolation* function. Give your data a reasonable name (we simply use *D* in the screenshot below), check on the “Use spatial coordinates as arguments”, and make sure to use the default *Linear* interpolation between data points.

*The settings for importing the experimental data.*

Define an Integration Operator over all domains. You can use the default name: *intop1*. This feature will be used to take the integral described above.

*The Integration Operator is defined over all domains.*

Now define two variables. One will be your function, F, and the other will be the function that we want to minimize, R. Since the *Geometric Entity Level* is set to *Entire Model*, F will be defined everywhere and spatially varying as a function of x. On the other hand, R is scalar valued everywhere and also available throughout the entire model. As shown in the screenshot below, we can enter F as a function of c_0,c_1,c_2,c_3 and will define these coefficients later.

*The definition of our fitting function and the quantity we wish to minimize.*

Next, we can use the *Global Equations* interface to define the four equations that we want to satisfy for our four coefficients. Recall that we want the derivative of R with respect to each coefficient to be zero. Using the differentiation operator, **d(f(x),x)**, we can enter this as shown below:

*The Global Equations that are used to solve for the coefficients of our fitting function.*

Finally, we need to have an appropriate mesh on our 1D domain. Recall that earlier we placed a geometric point at each data sampling point. Using the *Distribution* subfeature on the *Edge Mesh* feature, we can ensure that there is one element between each data point. We do not need any *more* elements than this, since we are assuming linear interpolation between data points, but we do not want *less* than this, because then we will miss some of the experimental data points.

*There should be one element over each data interval.*

We can now solve this stationary problem for the numerical values of our coefficients and plot the results. From the plot below, we can see the data points with the linear interpolation between them, as well as the computed fitting function. We have minimized the square of the difference between these two curves, integrated over the interval, and now have a smooth and simple function that approximates our data quite well.

*The experimental data (black, with linear interpolation) and the fitted function (red).*

Now, what we’ve done so far is actually fairly straightforward and you could compute similar types of curve fits in a spreadsheet program or any number of other software tools. But there is much more that we can do with this approach. We are not limited to using this fitting function. You are free to choose any function you want, but it is best to use a function that is a sum of set of orthogonal functions. Try out, for example:

F(x) = c_0 + c_1sin ( \pi x /4 ) + c_2cos ( \pi x /4 ) + c_3sin ( \pi x /2 ) + c_4cos ( \pi x /2 )

Be aware, however, that you will only want to solve for the linear coefficients on the various terms within the fitting function. You would not want to use nonlinear fitting coefficients such as F(x) = c_0 + c_1sin ( \pi x /c_3 ) + c_2cos ( \pi x /c_4 ) since such a problem might be too highly nonlinear to converge.

And what if you have a 2D or 3D data set? You can actually apply the exact same approach as we’ve outlined here. The only difference is that you will need to set up a 2D or a 3D domain. The domains need not be Cartesian and you can even switch to a different coordinate system.

Let’s take a quick look at some sample data points measured over the region shown below:

*Sampled data in a 2D region. We want a best fit surface to the heights of these points.*

Since the data is sampled over this annular region and seems to have variations with respect to the radial and circumferential directions (r,\theta), rather than the Cartesian directions, we can try to fit the function:

F(x) = c_0 + c_1r cos ( \theta ) +c_2 r sin ( \theta )+ c_3(2r^2-1) + c_4 r^2 cos ( 2\theta ) +c_5 r^2 sin ( 2\theta )

We can follow the exact same procedure as before. The only difference being that we need to integrate over a 2D domain rather than a line and write our expression using a cylindrical coordinate system.

*The computed best-fit surface to the data shown above.*

You can see that the core COMSOL Multiphysics package has very flexible capabilities for finding a best-fit curve to data in 1D, 2D, or 3D using the methods shown here.

There can be cases where you might want to go beyond a simple curve-fit and want to consider some additional constraints. In that case, you would want to use the capabilities of the Optimization Module, which can also perform these types of curve fits and much, much more. For an introduction to the Optimization Module for curve fitting and the related topic of parameter estimation, please also see these models:

]]>

Imagine that you are modeling an electronic device and are interested in its temperature distribution during operation. After testing a few set-ups, you discover that the heat flux boundary condition you applied is not a well-suited approximation for your model. You realize that a fluid flow simulation is required in order to achieve more accurate results. The only problem is that you have used almost all of your laptop’s 4 GB of RAM to model the heat transfer simulation, based on the heat flux approximation. You require two-way coupling, and including the simulation of fluid flow will only add even more degrees of freedom to your computation — and require even more RAM.

What now? You need more computer power.

Now imagine, instead, that you are analyzing the mechanics of a structural component with a lot of small details for your customer. In order to optimize the design, you are required to run the analysis for a large number of different design dimensions. As you have only the one processor, locally, and each run will take quite a bit of time, you realize that you will not reach your customer’s deadline.

The solution? You would need to run these simulations in parallel on multiple processors.

Finally, let’s look at an application independent of the physics involved, but still reliant on the analysis performed. You have set up your model using the physics interface of your choice, but it’s the end of the day and you just want to get the computed solution to your model as quickly and easily as possible, overnight. Utilizing a direct solver does not require a lot of work with manipulating solver settings and the like, but the required RAM of a direct solver increases greatly with the number of degrees of freedom in your model.

What’s the fix this time? You need a bigger computer.

What if there was another solution to all three cases…

This is where cloud computing comes into the picture. Compute clouds are services that make computing power available to those who need it, when they need it.

The service has several advantages, especially if you don’t have the time, money, and experience to invest in a traditional cluster or server rack. You might also not need a cluster available 24/7, but only need that extra compute power during certain periods of time. For instance, for that one-off analysis or that task that needs to be performed quicker.

*An organization can access COMSOL Multiphysics® and the hardware resources of cloud computing to run many different analyses at the time they require, utilizing the resources they require.*

Utilizing cloud computing will have a positive impact on your workflow. The ability to add more compute power directly when you need it will enable you to be more agile in your day-to-day COMSOL Multiphysics® simulation work. You won’t have to worry about the lack of adequate hardware on-site and you can go about your daily business with the certainty that you can expand into the cloud whenever the situation calls for it.

Traditionally, when using cloud computing services, you needed expertise in the network and hardware technology being used, as well as the operating system and software implemented by the cloud service to support running your application. An example workflow would have had you register to the cloud service, research what specifications their machines require, rent the machine, and then connect it to your network to allow access to your license server. Then came the easy part: Install COMSOL Multiphysics and run your model.

However, since HPC is becoming more and more important in the CAE community, we at COMSOL have made it as simple as possible for you to take the step into the cloud. To achieve this, we now provide a simpler way to launch remote COMSOL® software installations for use with the Amazon Elastic Compute Cloud™, or Amazon EC2™ for short.

Note: COMSOL Multiphysics has been able to utilize remote computing resources for a long time, either through batch jobs started from the user interface or the command line, or on-the-fly through client-server technology. For this, you only need a Floating Network License (FNL) for COMSOL Multiphysics®.

To simplify launching your virtual computers onto Amazon EC2™, Amazon provides a tool called AWS CloudFormation™. This reads from a template file containing information about the structure of the cloud resources that you are about to launch. COMSOL supplies you with such a template, thus reducing the number of steps that you need to go through to launch and send your computations to the cloud.

After a few initial steps, such as registering to Amazon Web Services™, all you need to do is run the AWS CloudFormation™ tool with our templates to launch a license server on Amazon EC2™ (or forward your local license server) and then run COMSOL Multiphysics®. You can choose to either run COMSOL® software on a single cloud-based machine or on a cloud-based cluster. To connect to the cloud, you just use the COMSOL Multiphysics® client-server functionality and then work as if on your own local computer, but using the Amazon EC2™ cloud-based compute power.

To help you with these steps, we have released a new User’s Guide on how to run COMSOL Multiphysics® with Amazon Elastic Compute Cloud™. The guide will take you through every step necessary to get started with COMSOL Multiphysics and cloud computing. And if you are having difficulty, please do not hesitate to contact our technical support team.

*Amazon Web Services, the “Powered by Amazon Web Services” logo, Amazon Elastic Compute Cloud, Amazon EC2, and AWS CloudFormation are trademarks of Amazon.com, Inc. or its affiliates in the United States and/or other countries.*

Let’s consider a thermostat similar to the one that you have in your home. Although there are many different types of thermostats, most of them use the same control scheme: A sensor that monitors temperature is placed somewhere within the system, usually some distance away from the heater. When the sensed temperature falls below a desired lower setpoint, the thermostat switches the heater on. As the temperature rises above a desired upper setpoint, the thermostat switches the heater off. This is known as a *bang-bang controller*. In practice, you typically only have a single setpoint, and there is an offset, or lag, which is used to define the upper and lower setpoints.

The objective of having different upper and lower setpoints is to minimize the switching of the heater state. If the upper and lower setpoints are the same, the thermostat would constantly be cycling the heater, which can lead to premature component failure. If you do want to implement such a control, you only need to know the current temperature of the sensor. This can be modeled in COMSOL Multiphysics quite easily, as we have highlighted in this previous blog post.

On the other hand, the bang-bang controller is a bit more complex since it does need to know something about the history of the system; the heater changes its state as the temperature rises above or below the setpoints. In other words, the controller provides *hysteresis*. In COMSOL Multiphysics, this can be implemented using the *Events* interface.

When using COMSOL Multiphysics to solve time-dependent models, the *Events* interface is used to stop the time-stepping algorithms at a particular point and offer the possibility of changing the values of variables. The times at which these events occur can be specified either explicitly or implicitly. An *explicit event* should be used when we know the point in time when something about the system changes. We’ve previously written about this topic on the blog in the context of modeling a periodic heat load. An *implicit event*, on the other hand, occurs at an unknown point in time and thus requires a bit more set-up. Let’s take a look at how this is done within the context of the thermal model shown below.

*Sketch of the thermal system under consideration.*

Consider a simple thermal model of a lab-on-a-chip device modeled in a 2D plane. A one millimeter thick glass slide has a heater on one side and a temperature sensor on the other. We will treat the heater as a 1W heat load distributed across part of the bottom surface, and we will assume that there is a very small, thermally insignificant temperature sensor on the top surface. There is also free convective cooling from the top of the slide to the surroundings, which is modeled with a heat flux boundary condition. The system is initially at 20°C, and we want to keep the sensor between 45°C and 55°C.

*A Component Coupling is used to define the Variable, T_s, the sensor temperature.*

The first thing we need to do — before using the *Events* interface — is define the temperature at the sensor point via an Integration Component Coupling and a Variable, as shown above. The reason why this is done is to make the temperature at this point, T_s, available within the *Events* interface.

The *Events* interface itself is added like any other physics interface within COMSOL Multiphysics. It is available within the *Mathematics > ODE and DAE interfaces* branch.

*The *Discrete States* interface is used to define the state of the heater. Initially, the heater is on.*

First, we use the *Events* interface to define a set of *discrete variables*, variables which are discontinuous in time. These are appropriate for modeling on/off conditions, as we have here. The *Discrete States* interface shown above defines a variable, *HeaterState*, which is multiplied by the applied heat load in the *Heat Transfer in Solids* problem. The variable can be either one or zero, depending upon the system’s temperature history. The initial condition is one, meaning we are starting our simulation with the heater on. It is important that we set the appropriate initial condition here. It is this *HeaterState* variable that will be changed depending upon the sensor temperature during the simulation.

*Two *Indicator States* in the *Events* interface depend upon the sensor temperature.*

To trigger a change in the *HeaterState* variable, we need to first introduce two *Indicator States*. The objective of the *Indicator States* is to define variables that will indicate when an event will occur. There are two indicator variables defined. The *Up* indicator variable is defined as:

`T_s - 55[degC]`

which goes smoothly from negative to positive as the sensor temperature rises above 55°C. Similarly, the *Down* indicator variable will go smoothly from negative to positive at 45°C. We will want to trigger a change in the *HeaterState* variable as these indicator variables change sign.

*The* HeaterState* variable is reinitialized within the *Events* interface.*

We use the *Implicit Events* interface, since we do not know ahead of time when these events will occur, but we do know under what conditions we want to change the state of the heater. As shown above, two *Implicit Event* features are used to reinitialize the state of the heater to either zero or one, depending upon when the *Up* and *Down* indicator variables become greater than or less than zero, respectively. The event is triggered when the logical condition becomes true. Once this happens, the transient solver will stop and restart with the newly initialized *HeaterState* variable, which is used to control the applied heat, as illustrated below.

*The *HeaterState *variable controls the applied heat.*

When solving this model, we can make some changes to the solver settings to ensure that we have good accuracy and keep only the most important results. We will want to solve this model for a total time of 30 minutes, and we will store the results only at the time steps that the solver takes. These settings are depicted below.

*The study settings for the Time-Dependent Solver set the total solution time from 0-30 minutes, with a relative tolerance of 0.001.*

We will need to make some changes within the settings for the Time-Dependent Solver. These changes can be made prior to the solution by first right-clicking on the *Study* branch, choosing “Show Default Solver”, and then making the two changes shown below.

*Modifications to the default solver settings. The event tolerance is changed to 0.001 and the output times to store are set to the steps taken by the solver.*

Of course, as with any finite element simulation, we will want to study the convergence of the solution as the mesh is refined and the solver tolerances are made tighter. Representative simulation results are highlighted below and demonstrate how the sensor temperature is kept between the upper and lower setpoints. Also, observe that the solver takes smaller time steps immediately after each event, but larger time steps when the solution varies gradually.

*The heater switches on and off to keep the sensor temperature between the setpoints.*

We have demonstrated here how implicit events can be used to stop and restart the solver as well as change variables that control the model. This enables us to model systems with hysteresis, such as thermostats, and perform simulations with minimal computational cost.

]]>

First, let’s take a (very) brief conceptual look at the implicit time-stepping algorithms used when you are solving a time-dependent problem in COMSOL Multiphysics. These algorithms choose a time step based upon a user-specified tolerance. While this allows the software to take very large time steps when there are gradual variations in the solution, the drawback is that using too loose of a tolerance can skip over certain transient events.

To understand this, consider the ordinary differential equation:

\frac{\partial u}{\partial t} = -u + f(t)

where the forcing function f(t) is a square unit pulse starting at t_s and ending at t_e. Given an initial condition, u_0, we can solve this problem for any length of time, either analytically or numerically. Here is the analytic solution for u_0=1:

In the above plot, we can observe the exponential decay and rise as the forcing function is zero or one. Let’s now look at the numerical solution to this problem for two different user-specified tolerances:

*The numeric solution (red dots) is shown for a relative tolerance of 0.2 and 0.01 and is compared to the analytical result (grey line).*

We can see from the plot above that a very loose relative tolerance of 0.2 does not accurately capture the switching of the load. At a tighter relative tolerance of 0.01 (the solver default), the solution is reasonably well resolved. We can also observe that the spacing of the points shows the varying time steps used by the solver. It is apparent that the solver takes larger time steps where the solution changes slowly and finer time steps when the heat load switches on and off.

However, if the tolerance is set too loosely, the solver may skip over the heat load change entirely when the width of the heat load gets very small. That is, if t_s and t_e move very close to each other, the magnitude of the total heat load is too small for the specified tolerance. We can of course mitigate this by using tighter tolerances, but a better option exists.

We can avoid having to tighten the tolerances by using *Explicit Events*, which are a way of letting the solver know that it should evaluate the solution at a specified point in time. From that point in time forward, the solver will continue as before until the next event is reached. Let’s look at the numeric solution to the above problem, with *Explicit Events* at t_s and t_e and solved with a relative tolerance of 0.2 (a very loose tolerance):

*When using* Explicit Events*, the numerical solution — even with a very loose relative tolerance of 0.2 — compares quite well with the analytical result. Away from the events, large time steps are taken.*

The above plot illustrates that the *Explicit Events* force a solution evaluation when the load switches on or off. The loose relative tolerance allows the solver to take large time steps when the solution varies gradually. Small time steps are taken immediately after the events to give good resolution of the variation in the solution. Thus, we have both good resolution of the heat load switching on or off and we take large time steps to minimize the overall computational cost.

Now that we’ve introduced the concepts, we will take a look at implementing these *Explicit Events*.

We will begin with an existing example from the COMSOL Multiphysics Model Library and modify it slightly to include a periodic heat load and the *Events* interface. We will look at an example of the Laser Heating of a Silicon Wafer, where a laser is modeled as a distributed heat source moving back and forth across the surface of a spinning silicon wafer.

The laser heat source itself traverses back and forth over the wafer with a period of 10 seconds along the centerline. To minimize the temperature variation over the wafer during the heating process, we want to turn the laser off periodically, while the heat source is in the center of the wafer. To model this, we will introduce an *Analytic* function, pulse (x), that uses the Boolean expression:

`(x<2)||(x>3)`

to evaluate pulse (t) to zero between t=2-3 seconds, and one otherwise. The *Periodic Extension* option is used to repeat this pattern every five seconds, as shown in the screenshot below.

*The settings used to define a periodic function, as plotted.*

We can use this function to modify the applied heat flux representing the laser heat source, as illustrated below:

*The settings for the applied heat flux boundary condition.*

The last thing that we need to do is to add the *Events* interface. This physics interface is found within *Mathematics > ODE and DAE interfaces* when using the *Add Physics* browser. Within the *Events* interface, add two *Explicit Events* with the settings shown below to define a periodic event starting at two and three seconds and repeating every five seconds.

*The* Explicit Events* settings. The second of these events starts at 3 s.*

No other changes are needed, but we can take a quick look at the solver settings:

*The settings for the time-dependent solver.*

Note that the entries in the *Times* field are the output times. These settings do not directly control the actual time steps taken by the solver. The *Relative Tolerance* field (default value of 0.01) along with the *Events* — if they are in the model — control these time steps.

*A comparison of unpulsed (left) and pulsed (right) heat loads.*

You can compare the results of this simulation to the original model to see the differences in temperature across the wafer. With a periodic heat load, the temperature rise is more gradual and the temperature variations at any point in time are smaller.

We have looked at using the *Events* interface for modeling a periodic heat load over time and introduced why it provides a good combination of accuracy and low computational requirements. There is a great deal more that you can do with the *Events* interface — if you would like to learn more, we encourage you to consult the documentation. An extended demonstration of the usage of the *Events* interface is featured in the Capacity Fade of a Li-ion Battery example from the Model Library.

On the other hand, when dealing with problems that are either convection dominated or wave-type problems (e.g., fluid flow models or transient structural response, respectively), then we would not want to introduce instantaneous changes in the loads. The reasons behind that — and alternative modeling techniques for such situations — will be the topic of an upcoming blog. Stay tuned!

]]>

Recall our simple example of 1D heat transfer at steady state with no heat source, where the temperature T is a function of the position x in the domain defined by the interval 1\le x\le 5. With the boundary conditions that the outgoing flux should be 2 at the left boundary (x=1) and the temperature should be 9 at the right boundary (x=5), the weak form equation reads:

(1)

\int_1^5 \partial_x T(x) \partial_x \tilde{T}(x) \,dx = -2 \tilde{T}_1 -\lambda_2 \tilde{T}_2 -\tilde{\lambda}_2 (T_2-9)

We now attempt to find a way to solve this equation numerically.

To solve Eq. (1) numerically, we first divide the domain 1\le x\le 5 into four evenly spaced sub-intervals, or *mesh elements*, bound by five *nodal points* x = 1, 2, \cdots, 5. Then, we can define a set of basis functions, or *shape functions*, \psi_{1L}(x), \psi_{1R}(x), \psi_{2L}(x), \psi_{2R}(x), \cdots, \psi_{4R}(x), as shown in the graph below, where there are two shape functions in each mesh element, represented by a solid line and a dashed line.

For example, in the first element (1 \le x \le 2), we have

(2)

\begin{equation*}

\psi_{1L}(x) %26=%26 \left\{ \begin{array}{ll}

2-x \mbox{ for } 1 \le x \le 2,\\

0 \mbox{ elsewhere}

\end{array} \right \mbox{ (solid red line)}

\end{equation}

\psi_{1L}(x) %26=%26 \left\{ \begin{array}{ll}

2-x \mbox{ for } 1 \le x \le 2,\\

0 \mbox{ elsewhere}

\end{array} \right \mbox{ (solid red line)}

\end{equation}

\begin{equation*}

\psi_{1R}(x) %26=%26 \left\{ \begin{array}{ll}

x-1 \mbox{ for } 1 \le x \le 2, \\

0 \mbox{ elsewhere}

\end{array} \right \mbox{ (dashed red line)}

\end{equation}

\psi_{1R}(x) %26=%26 \left\{ \begin{array}{ll}

x-1 \mbox{ for } 1 \le x \le 2, \\

0 \mbox{ elsewhere}

\end{array} \right \mbox{ (dashed red line)}

\end{equation}

We observe that each shape function is a simple linear function ranging from 0 to 1 within a mesh element, and vanishes outside of that mesh element.

Note: Of course, COMSOL Multiphysics allows shape functions formed with higher-order polynomials, not just linear functions. The choice of linear shape functions here is for visual clarity.

With this set of shape functions, we can approximate any arbitrary function defined in the domain 1\le x\le 5 by a simple linear combination of them:

(3)

u(x) \approx a_{1L} \psi_{1L}(x) + a_{1R} \psi_{1R}(x) + a_{2L} \psi_{2L}(x) + a_{2R} \psi_{2R}(x) + \cdots

where a_{1L}, a_{1R}, a_{2L}, a_{2R}, \cdots are some constant coefficients, one for each shape function. In the graph below, the arbitrary function u(x) is represented by the black curve. The cyan curve represents the approximation by the superposition of the shape functions (3). Each term on the right-hand side of Eq. (3) is plotted using the same color and line style as the graph above.

We see that in general the approximation (represented by the cyan curve) can be discontinuous across the boundary between adjacent mesh elements. In practice, many physical systems, including our simple example of heat conduction, are expected to have continuous solutions. For this reason, the default shape functions for most physics interfaces are *Lagrange elements*, in which the shape function coefficients are constrained so that the solution is continuous across boundaries between adjacent elements. In this case, the approximation is simplified, as shown in the figure below,

where the cyan curve has been made continuous by setting the coefficients on each side of a mesh boundary to be equal: a_{1R} = a_{2L}, a_{2R} = a_{3L}, a_{3R} = a_{4L}. We also renamed the coefficients for brevity:

\begin{equation*}

\begin{align}

a_1 %26\equiv a_{1L}\\

a_2 %26\equiv a_{1R} = a_{2L}\\

a_3 %26\equiv a_{2R} = a_{3L}\\

a_4 %26\equiv a_{3R} = a_{4L}\\

a_5 %26\equiv a_{4R}

\end{align}

\end{equation*}

\begin{align}

a_1 %26\equiv a_{1L}\\

a_2 %26\equiv a_{1R} = a_{2L}\\

a_3 %26\equiv a_{2R} = a_{3L}\\

a_4 %26\equiv a_{3R} = a_{4L}\\

a_5 %26\equiv a_{4R}

\end{align}

\end{equation*}

We see that the continuity condition requires pairs of shape functions to share the same coefficient in making the approximation (3), which can now in turn be simplified by combining those pairs of shape functions into a new set of basis functions *ϕ1(x),ϕ2(x),⋯,ϕ5(x)*, with each function localized around a nodal point:

(4)

\begin{equation*}

\begin{align}

\phi_1(x) \equiv \psi_{1L}(x) %26= \left\{ \begin{array}{ll}

2-x \mbox{ for } 1 \le x \le 2,\\

0 \mbox{ elsewhere}

\end{array} \right

\\

\phi_2(x) \equiv \psi_{1R}(x) + \psi_{2L}(x) %26= \left\{ \begin{array}{lll}

x-1 \mbox{ for } 1 \le x \le 2, \\

3-x \mbox{ for } 2 < x \le 3, \\

0 \mbox{ elsewhere}

\end{array} \right

\\

\phi_3(x) \equiv \psi_{2R}(x) + \psi_{3L}(x) %26= \left\{ \begin{array}{lll}

x-2 \mbox{ for } 2 \le x \le 3, \\

4-x \mbox{ for } 3 < x \le 4, \\

0 \mbox{ elsewhere}

\end{array} \right

\\

\\ &\centerdot&

\\ &\centerdot&

\\ &\centerdot&

\end{align}

\end{equation*}

\begin{align}

\phi_1(x) \equiv \psi_{1L}(x) %26= \left\{ \begin{array}{ll}

2-x \mbox{ for } 1 \le x \le 2,\\

0 \mbox{ elsewhere}

\end{array} \right

\\

\phi_2(x) \equiv \psi_{1R}(x) + \psi_{2L}(x) %26= \left\{ \begin{array}{lll}

x-1 \mbox{ for } 1 \le x \le 2, \\

3-x \mbox{ for } 2 < x \le 3, \\

0 \mbox{ elsewhere}

\end{array} \right

\\

\phi_3(x) \equiv \psi_{2R}(x) + \psi_{3L}(x) %26= \left\{ \begin{array}{lll}

x-2 \mbox{ for } 2 \le x \le 3, \\

4-x \mbox{ for } 3 < x \le 4, \\

0 \mbox{ elsewhere}

\end{array} \right

\\

\\ &\centerdot&

\\ &\centerdot&

\\ &\centerdot&

\end{align}

\end{equation*}

As shown in the graph below, each new basis function is essentially a triangular-shaped, piecewise-linear function centered around a nodal point. Its value varies between 1 and 0 within the mesh element(s) adjacent to the nodal point, and vanishes everywhere else.

As discussed above, by choosing this new set of basis functions, we constrain the solution to be continuous across the boundary between adjacent mesh elements. Most physical systems satisfy this continuity constraint, including our simple heat transfer example here.

Now, with this new set of basis functions, the approximation (3) is simplified to

(5)

u(x) \approx a_1 \phi_1(x) + a_2 \phi_2(x) + \cdots + a_5 \phi_5(x)

In the graph below, the arbitrary function u(x) is represented by the black curve. The cyan curve represents the approximation by the superposition of the new basis functions. Each term on the right-hand side of Eq. (5) is plotted using the same color scheme as the graph above.

As an aside, if the black curve represents the exact solution to some real modeling problem, then we see that the approximation is not very good, due to the coarseness of the mesh. Also, in general, the nodal point values a_1, a_2, \cdots are not required to lie on the exact solution, unless one is constrained to a known solution value (shown in a_5 as an example in the figure above). The discrepancy between the black and the cyan curves we see here represents the discretization error of the solution. In 2D and 3D models, there will also be a discretization error of the geometry. In my colleague Walter Frei’s blog post on meshing considerations, both types of errors are discussed in some detail. Due to these potential errors, a mesh refinement study is necessary to ensure the accuracy of modeling results.

We note that the approximation given by Eq. (5) (the cyan curve) is piecewise-linear. Thus, it’s impossible to evaluate its second derivatives numerically. As we have mentioned before, the weak formulation provides numerical benefits by reducing the order of differentiation in the equation system. In this case, only the first derivative is needed and it can be readily evaluated numerically. In a future blog entry, we will discuss an example of discontinuity in the material property that also benefits from the reduced order of differentiation.

With the new set of basis functions defined above, we proceed to discretize the weak form equation (1) in two steps. First, the temperature function, T(x), can be approximated by the set of basis functions in the same way as in Eq. (5):

(6)

T(x) = a_1 \phi_1(x) + a_2 \phi_2(x) + \cdots + a_5 \phi_5(x)

where a_1, a_2, \cdots , a_5 are unknown coefficients to be determined.

Substituting the expression for T(x) (6) into the weak form equation (1), we obtain

(7)

\begin{array}{ll}

a_1 \int_1^5 \partial_x \phi_1(x) \partial_x \tilde{T}(x) \,dx + a_2 \int_1^5 \partial_x \phi_2(x) \partial_x \tilde{T}(x) \,dx + \cdots + a_5 \int_1^5 \partial_x \phi_5(x) \partial_x \tilde{T}(x) \,dx

\\

= -2 \tilde{T}_1 -\lambda_2 \tilde{T}_2 -\tilde{\lambda}_2 (a_5 -9)

\end{array}

a_1 \int_1^5 \partial_x \phi_1(x) \partial_x \tilde{T}(x) \,dx + a_2 \int_1^5 \partial_x \phi_2(x) \partial_x \tilde{T}(x) \,dx + \cdots + a_5 \int_1^5 \partial_x \phi_5(x) \partial_x \tilde{T}(x) \,dx

\\

= -2 \tilde{T}_1 -\lambda_2 \tilde{T}_2 -\tilde{\lambda}_2 (a_5 -9)

\end{array}

where the temperature at the right boundary x=5, T_2, has been evaluated using the expression (6) and the fact that the basis functions are localized, leading to only one term, a_5 \phi_5(x=5) = a_5, contributing to T(x=5).

We see that there are six unknowns in the discretized version of the weak form equation (7): The five coefficients a_1, a_2, \cdots , a_5 and the one flux \lambda_2 at the right boundary. It is customary to call the unknowns *degrees of freedom*. For example, here we say the (discretized) problem has “six degrees of freedom”.

To solve for the six unknowns, we need six equations. This leads to the second step of discretization. Recall from our first blog post that the role of the test functions is to sample the equation locally to clamp down the solution everywhere within the domain. Now we already have a set of localized functions, our basis functions \phi_1, \cdots, \phi_5, so we can just substitute them into the test function \tilde{T} in Eq. (7) to obtain the six equations we need.

Here is a table showing the six substitutions that will generate the six equations for us:

\tilde{T}(x) | \tilde{\lambda}_2 |
---|---|

\phi_1(x) | 0 |

\phi_2(x) | 0 |

\phi_3(x) | 0 |

\phi_4(x) | 0 |

\phi_5(x) | 0 |

0 | 1 |

Since each of the basis functions is localized, each substitution yields an equation with a small number of terms. For example, the first substitution gives

\begin{array}{ll}

a_1 \int_1^5 \partial_x \phi_1(x) \partial_x \phi_1(x) \,dx + a_2 \int_1^5 \partial_x \phi_2(x) \partial_x \phi_1(x) \,dx + \cdots + a_5 \int_1^5 \partial_x \phi_5(x) \partial_x \phi_1(x) \,dx

\\

= -2 \phi_1(x=1) -\lambda_2 \phi_1(x=5) -0 (a_5 -9)

\end{array}

a_1 \int_1^5 \partial_x \phi_1(x) \partial_x \phi_1(x) \,dx + a_2 \int_1^5 \partial_x \phi_2(x) \partial_x \phi_1(x) \,dx + \cdots + a_5 \int_1^5 \partial_x \phi_5(x) \partial_x \phi_1(x) \,dx

\\

= -2 \phi_1(x=1) -\lambda_2 \phi_1(x=5) -0 (a_5 -9)

\end{array}

We note that \phi_1 has non-trivial overlap only with itself and \phi_2. Therefore, only the first two terms on the left-hand side are non-zero. Also, \phi_1 is localized near the left boundary (x=1), so only the first term on the right-hand side remains. The equation now becomes

(8)

a_1 -a_2 = -2

where we have evaluated the definite integrals on the left-hand side:

\begin{equation*}

\begin{align}

\int_1^5 \partial_x \phi_1(x) \partial_x \phi_1(x) \,dx %26= 1\\

\int_1^5 \partial_x \phi_2(x) \partial_x \phi_1(x) \,dx %26= -1\\

\end{align}

\end{equation*}

\begin{align}

\int_1^5 \partial_x \phi_1(x) \partial_x \phi_1(x) \,dx %26= 1\\

\int_1^5 \partial_x \phi_2(x) \partial_x \phi_1(x) \,dx %26= -1\\

\end{align}

\end{equation*}

and used the definition of \phi_1 on the right-hand side: \phi_1(x=1) = 1.

Similarly, the remaining five substitutions listed in the table above yield these equations:

(9)

\begin{equation*}

\begin{align}

-a_1 + 2 a_2 -a_3 %26= 0\\

-a_2 + 2 a_3 -a_4 %26= 0\\

-a_3 + 2 a_4 -a_5 %26= 0\\

-a_4 + a_5 %26= -\lambda_2\\

0 %26= -(a_5 -9)\\

\end{align}

\end{equation*}

\begin{align}

-a_1 + 2 a_2 -a_3 %26= 0\\

-a_2 + 2 a_3 -a_4 %26= 0\\

-a_3 + 2 a_4 -a_5 %26= 0\\

-a_4 + a_5 %26= -\lambda_2\\

0 %26= -(a_5 -9)\\

\end{align}

\end{equation*}

We now have six equations for our six unknowns and it is straightforward to verify that the solution matches what we have obtained using COMSOL Multiphysics software in the previous post. For example, the last equation immediately gives us a_5 = 9, and using the expression (6) for the temperature, we obtain its value at the right boundary:

\begin{equation*}

\begin{align}

T(x=5) %26= a_1 \phi_1(x=5) + a_2 \phi_2(x=5) + \cdots + a_5 \phi_5(x=5)\\

%26= a_1 \cdot 0 + a_2 \cdot 0 + \cdots + a_5 \cdot 1\\

%26= 9\\

\begin{align}

\end{equation*}

\begin{align}

T(x=5) %26= a_1 \phi_1(x=5) + a_2 \phi_2(x=5) + \cdots + a_5 \phi_5(x=5)\\

%26= a_1 \cdot 0 + a_2 \cdot 0 + \cdots + a_5 \cdot 1\\

%26= 9\\

\begin{align}

\end{equation*}

This agrees with the fixed boundary condition that the temperature should be 9 at the right boundary. It is also easy to see that it is the term associated with the test function \tilde{\lambda}_2 that gives rise to the equation (0 = a_5 -9), as we would expect.

It is convenient to write the discretized system of equations (in our simple example, there are six equations given in (8) and (9)) in terms of matrices and vectors:

(10)

\left(

\begin{array}{cccccc}

1 & -1 & 0 & 0 & 0 & 0 \\

-1 & 2 & -1 & 0 & 0 & 0 \\

0 & -1 & 2 & -1 & 0 & 0 \\

0 & 0 & -1 & 2 & -1 & 0 \\

0 & 0 & 0 & -1 & 1 & 1 \\

0 & 0 & 0 & 0 & 1 & 0

\end{array}

\right)

\left(

\begin{array}{c} a_1 \\ a_2 \\ a_3 \\ a_4 \\ a_5 \\ \lambda_2 \end{array}

\right)

= \left(

\begin{array}{c} -2 \\ 0 \\ 0 \\ 0 \\ 0 \\ 9 \end{array}

\right)

\begin{array}{cccccc}

1 & -1 & 0 & 0 & 0 & 0 \\

-1 & 2 & -1 & 0 & 0 & 0 \\

0 & -1 & 2 & -1 & 0 & 0 \\

0 & 0 & -1 & 2 & -1 & 0 \\

0 & 0 & 0 & -1 & 1 & 1 \\

0 & 0 & 0 & 0 & 1 & 0

\end{array}

\right)

\left(

\begin{array}{c} a_1 \\ a_2 \\ a_3 \\ a_4 \\ a_5 \\ \lambda_2 \end{array}

\right)

= \left(

\begin{array}{c} -2 \\ 0 \\ 0 \\ 0 \\ 0 \\ 9 \end{array}

\right)

The matrix on the left-hand side is customarily called the *stiffness matrix* and the vector on the right is called the *load vector*, due to the application of this technique in structural mechanics.

We notice two interesting facts about this matrix equation. First, there are a lot of zeros in the matrix (a so-called *sparse* matrix). In a practical model where there are many more mesh elements than our four elements here, we can envision that most of the elements in the matrix will be zero. This is a direct benefit of choosing localized shape functions, and it lends itself to very efficient numerical methods to solve the equation system.

Second, the Lagrange multiplier \lambda_2 appears only in one equation (the last column of the matrix has only one non-zero element). The remaining five equations involve only the five unknown coefficients a_1, a_2, \cdots , a_5. Therefore, we can choose to solve for a_1, a_2, \cdots , a_5 using the five equations, without ever needing to solve for \lambda_2. As we briefly mentioned in the previous entry, in general, it is possible to choose not to solve for the Lagrange multiplier(s) in order to gain computation speed.

Today, we reviewed the basic procedure for discretizing the weak form equation using our simple example. We took advantage of a set of localized shape functions in two steps:

- Using them as a basis to approximate the real solution
- Substituting them one by one into the weak form equation to obtain the discretized system of equations

The resulting matrix equation is sparse, which can be solved efficiently using a computer.

In the previous blog post, when we implemented the weak form equation using COMSOL Multiphysics, the discretization was done under the hood without needing the user’s help. Next, we will show you how to inspect the stiffness matrix and load vector, as well as how to choose to solve for — or not to solve for — the Lagrange multiplier by using the *Weak Form PDE* interface in the software.

*Polar plots* are exactly what you remember from math class. They use polar coordinates *r* and $\theta$ to describe a pattern, usually an acoustic or electromagnetic field. These plots are very useful for getting a localized or top-down view of the radiation pattern of your device. For instance, to ensure that a loudspeaker’s design is optimized for the most even sound distribution, you would examine a polar plot to see how the sound waves propagate from the speaker and what the range is.

To demonstrate this, I’ll show a polar plot from a conical antenna model. (If you have the RF Module installed, you can find this simulation under *File > Model Libraries > RF Module > Antennas*.) This model analyzes the impedance and radiation patterns of a conical antenna. The geometry of the antenna is shown below:

This antenna directs an electromagnetic wave propagating in a coaxial cable. Propagation occurs in the *z*-direction, and the model results show the radiation pattern close to the antenna for different frequencies. Below is a polar plot describing the near-field pattern changing with the elevation angle, $\theta$:

In contrast to the plots just shown, a *far-field plot* describes a wave pattern (electromagnetic or acoustic) at distances far from the source. For instance, the far-field pattern of the conical antenna looks like this:

Comparing this to the near-field plot shown earlier, we can see how the radiation pattern changes with large jumps in distance from the antenna.

Far-field plots, however, are often shown in three dimensions, so these are not limited to the polar plot type. Variables are plotted for a chosen number of angles on a circle (in two dimensions) or a sphere (in three dimensions), where you can specify the angle interval as well as the origin and radius of the circle or sphere. This plots the radiation pattern by deforming the circle or sphere in the radial direction for each evaluation point specified. This means that the distance from the center becomes equal to the value of the expression on the evaluation point. (One advantage to this plot type is that the circle or sphere used for defining the plot directions is not part of the model geometry, so the number of plotting directions is unrelated to the solution domain.)

A 3D plot of the far field for the conical antenna is highlighted below. You’ll notice that this gives a very indicative view of the wave pattern, providing a sort of “big-picture” feel in contrast to the localized data in the polar plots.

Lastly, there are a couple of plot types that are unique to particle tracing applications. These are the *particle tracing plots*, *Poincaré maps*, and *phase portraits* in COMSOL Multiphysics. To illustrate each of these plot types, I’ll use a model of a laminar mixer. If you have the Particle Tracing Module installed, this model can be found under *File > Model Libraries > Particle Tracing > Fluid Flow*.

The simulation analyzes fluid being pumped through a pipe with stationary blades. This type of mixing is suited for laminar flow because it generates only small pressure losses. The model evaluates the mixing performance by tracking the trajectories of particles suspended in the mixer.

The particle tracing plot type shows the actual trajectories of a specified number of particles or a specified density and diameter. In this case, a species is dissolved in room temperature water. In the results shown below, a line tracks each particle five seconds after being released into the mixer. The color expression is based on the shear rate (1/s) of the flow.

Another 3D plot group included in this model is a Poincaré map, or a first recurrence map. These are 2D plots that are created from a cut plane defined on the particle data set. This is used for visualizing the position of particles in a section transversal to their trajectories. The Poincaré map represents the particle trajectories in a space dimension that is one dimension lower than the original particle space. The plot shows a dot on the cut plane everywhere that a particle has crossed the plane (including multiple locations for the same particle if it crosses the plane multiple times). In the plot below, the dot color indicates the velocity of the particle when it crosses the plane, five seconds after release.

One nice trick to showing Poincaré maps is to include several of them in a 3D plot group. For instance, the results plot below depicts maps at different locations along the mixer, with the outlines of the blades underneath. In this case, the color of the dots indicates the level of *dissolution* (how well-mixed the species is in the water):

The very last plot type we’ll discuss here is a phase portrait. Like a Poincaré map, phase portraits show the locations of particles on a 2D plot. However, they are not necessarily on a plane with an orientation that is transversal to the direction of particle travel. Phase portraits are typically used to plot particle position and velocity together, where the position is taken as the distance from the origin. Below is a phase portrait depicting particle positions at t=5 seconds:

That’s all for the application-specific plot types. Hopefully you’ve enjoyed this introduction to some unique ways to show results and gather data in RF, acoustic, and particle tracing simulations. Stay tuned for our next blog post on creating deformations in your results plots!