FEATool MultiphysicsFEATool Multiphysics - an Easy to Use Octave and Matlab Finite Element Simulation Toolbox
https://www.featool.com
Python FEM and Multiphysics Simulations with FEniCS and FEATool<p><a href="https://fenicsproject.org/">FEniCS</a> is a flexible and comprehensive
finite element FEM and partial differential equation PDE modeling and
simulation toolkit with <a href="https://www.python.org/">Python</a> and C++
interfaces along with many integrated solvers. As both FEATool and
FEniCS discretize equations employing a weak finite element
formulation it is quite straightforward to translate FEATool syntax
and convert it to FEniCS python scripts. Similar to what has been done
with the
<a href="https://www.featool.com/tutorial/2016/11/14/Easy-Matlab-CFD-FeatFlow-external-CFD-solver-with-FEATool-integration.html">FeatFlow CFD solver</a>,
this post introduces an update patch for FEATool v1.6 allowing for
easy conversion, exporting, solving, and importing FEATool
Multiphysics models to FEniCS directly from the GUI, as well as the
Matlab and Octave command line interfaces.</p>
<p>In contrast to FeatFlow which is highly specialized to solve
incompressible fluid flow problems efficiently, FEniCS is aimed at
supporting and solving general systems of PDEs, such as found in
engineering and coupled multiphysics problems. As both FEATool and
FEniCS discretize the equations in the same way the solutions they
produce should be virtually identical. One of the many advantages of
using FEniCS then, in addition to now supporting the Python scripting
language as well as Matlab and Octave, is that FEniCS solvers have
support for both distributed (MPI) and shared memory (OpenMP) parallel
execution allowing for larger models to be solved faster (FEniCS has
been tested on problem sizes up to 10<sup>8</sup> degrees of freedom
run on 512 CPUs in parallel, where Matlab and Octave in contrast is
limited to the serial sparse linear solvers, the Umfpack direct solver
and selection of iterative ones.</p>
<h2 id="gui-usage">GUI Usage</h2>
<p><img src="https://www.featool.com/images/featool-fenics-python-fem-simulation-matlab-gui.jpg" alt="FEATool-FEniCS Python Finite Element FEM Simulation and Matlab GUI" class="full" /></p>
<p>After installing the patch a new button labeled <strong>FEniCS</strong> will be
present in the <em>Solve Mode</em> toolbar of the FEATool GUI. Pressing this
button will open a dialog box where the current model equations and
parameters has been translated to a FEniCS python script. The script
can there be inspected and edited, as well as changing the output file
name and system shell command to run it (which is <em>bash</em> by default).</p>
<p>The FEniCS solver dialog box also features <strong>Export</strong>, <strong>Solve</strong>, and
<strong>Import</strong> buttons. The <strong>Export</strong> option saves the current grid in
Dolfin XML format and exports the FEniCS simulation script. <strong>Solve</strong>
attempts to run and execute the FEniCS python script in a bash shell
if present, and <strong>Import</strong> will import an existing solution if it
matches with the FEATool problem definition.</p>
<h2 id="command-line-usage">Command Line Usage</h2>
<p>The installed <strong>fenics</strong> Matlab function can also be used on the
command line (CLI) to manually perform the export, solve, and import
actions. In the following is an example to set up a simple heat
transfer model on a unit circle with a unit heat source term, and
<em>T=0</em> fixed temperature on all the boundaries. In the FEATool Matlab
m-script language the model will look like the following</p>
<div class="highlighter-rouge"><pre class="highlight"><code>fea.sdim = {'x' 'y'};
fea.grid = quad2tri(circgrid());
fea = addphys(fea, @heattransfer);
fea.phys.ht.eqn.coef{6,end} = {1}; % Heat source term.
fea.phys.ht.bdr.sel(:) = 1; % Zero temperature boundary conditions.
fea = parsephys(fea); % Parse physics mode and fea problem struct.
fea = parseprob(fea);
fea.sol.u = solvestat(fea);
postplot(fea, 'surfexpr', 'T')
</code></pre>
</div>
<p>By running the command <code>fenics(fea, 'mode', 'export')</code> a
grid file <em>featool_fenics_mesh.xml</em> and FEniCS simulation script file
<em>featool_fenics.py</em> will automatically be generated in the current
directory</p>
<div class="highlighter-rouge"><pre class="highlight"><code>from fenics import *
# Mesh and subdomains.
mesh = Mesh("featool_fenics_mesh.xml")
# Finite element and function spaces.
E0 = FiniteElement("P", mesh.ufl_cell(), 1)
V = FunctionSpace(mesh, E0)
T = Function(V)
T_t = TestFunction(V)
# Model constants and expressions.
rho = Constant(1)
cp = Constant(1)
k = Constant(1)
u = Constant(0)
v = Constant(0)
q = Constant(1)
# Bilinear forms.
a = ( (rho*cp*u)*T*T_t.dx(0) + (k)*T.dx(0)*T_t.dx(0) + \
(rho*cp*v)*T*T_t.dx(1) + (k)*T.dx(1)*T_t.dx(1) )*dx
# Linear forms.
f = q*T_t*dx
# Boundary conditions.
dbc0 = DirichletBC(V, Constant(0), 0)
dbc1 = DirichletBC(V, Constant(0), 1)
dbc2 = DirichletBC(V, Constant(0), 2)
dbc3 = DirichletBC(V, Constant(0), 3)
dbc = [dbc0, dbc1, dbc2, dbc3]
# Initial conditions.
assign(T, interpolate( Constant(0), V))
# Solve.
solve( a - f == 0, T, dbc )
# Output.
import numpy as np
T_h = T.compute_vertex_values(mesh)
np.savetxt("featool_fenics_sol.txt", np.column_stack((T_h)))
# Postprocessing.
plot(T, title = "T")
interactive()
</code></pre>
</div>
<p>The generated FEniCS python FEM script is longer and somewhat more
verbose since all the FEATool physics mode defaults must be explicitly
expressed.</p>
<p>Calling <code>fenics(fea, 'mode', 'solve')</code> will attempt to
solve the problem if python and FEniCS is installed and set up
correctly. Alternatively, the script can be run by itself by a valid
FEniCS installation.</p>
<p>The solution process will generate the file <em>featool_fenics_sol.txt</em>
containing the nodal solution(s) which can be imported back into
FEATool with <code>fea = fenics(fea, 'mode', 'import')</code> after
which it can be postprocessed and visualized with the usual FEATool
and Matlab functions.</p>
<h2 id="notes">Notes</h2>
<p>The FEniCS-FEATool integration and problem file export should work for
general multiphysics problems using both the GUI and command
line. However, a subset of FEATool functionality is currently not
supported (the known ones are listed here)</p>
<ul>
<li>
<p>Non-linear Dirichlet fixed value boundary conditions are not
supported. The exported FEniCS C++ boundary condition expressions do
not currently allow for dependent variables / solution unknowns.</p>
</li>
<li>
<p>As FEniCS does not feature a built-in time dependent solver. Solvers
for instationary problems must currently be implemented manually.</p>
</li>
<li>
<p>Switch and logical expressions (for example <em>x>1 & y<=0</em>) must be
manually rewritten to conform with the C++ expression syntax.</p>
</li>
<li>
<p>The ordering of expressions and constants is arbitrary in FEATool
while in FEniCS constants and expressions must be defined
sequentially in the order they are used, and may therefore need to
be rearranged in the auto generated FEniCS problem file.</p>
</li>
<li>
<p>Point source terms are not supported by the FEniCS non-linear
solution form (which is used by default since it also handles linear
problems).</p>
</li>
<li>
<p>Although FEATool and FEniCS uses the same finite element FEM basis
functions the internal ordering is different, thus the FEniCS
solution will be exported in the grid points (<em>P1</em> space). Thus even
if higher-order FEM spaces are used solution accuracy will be lost
during FEATool import. This issue might not be that important for
visualization but when calculating quantities, boundary and
subdomain integrals, and expression evaluations it would currently
be more accurate to perform that in FEniCS and python.</p>
</li>
<li>
<p>FEniCS does not currently support quadrilateral or hexahedral grid
cells and must be converted to triangles and tetrahedra,
respectively. Grid conversion of these types of grids can be
performed directly in the GUI or with the
<a href="https://www.featool.com/doc/quad2tri_8m.html"><code>quad2tri</code></a> and
<a href="https://www.featool.com/doc/hex2tet_8m.html"><code>hex2tet</code></a>
commands. Typically this will not be an issue since FEATool and the
automatic mesh generator
<a href="https://www.featool.com/doc/gridgen_8m.html"><code>gridgen</code></a> by default
creates simplex grids (line segments, triangles, and tetrahedra).</p>
</li>
<li>
<p>In addition to supporting FEniCS, the exported python simulation
scripts should also be compatible with the
<a href="http://www.firedrakeproject.org/index.html">Firedrake</a> project
solver which also uses the FEniCS Unified Form Language (UFL) for
problem definitions.</p>
</li>
</ul>
<h2 id="installation">Installation</h2>
<p>The FEniCS-FEATool update patch can be downloaded from the link below</p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/assets/featool-fenics-patch.zip" target="_blank" class="btn btn--inverse">
<strong>FEATool-FEniCS Integration Update Patch</strong></a></div>
<p><br /></p>
<p>The included patch files need to be extracted into the current
<em>featool</em> source directory.</p>
<p>Note that the patch and update does not include a Python interpreter
or FEniCS itself which must be installed separately. The FEniCS
homepage provides instructions
<a href="https://fenicsproject.org/download/">how to install FEniCS on *nix systems</a>
and pre-configured Docker Linux images.</p>
<p>For systems running <em>Windows 10</em> FEniCS can be installed with the
<a href="https://msdn.microsoft.com/en-us/commandline/wsl/about">Ubuntu Bash Windows Subsystem for Linux</a>
by simply opening a Windows Bash shell and running the FEniCS on
Ubuntu commands (which automatically also installs Python if required)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>sudo add-apt-repository ppa:fenics-packages/fenics
sudo apt-get update
sudo apt-get install --no-install-recommends fenics
sudo apt-get dist-upgrade
</code></pre>
</div>
<p>To allow FEniCS and python plotting and visualization on Windows one
must also install an X window server such as
<a href="https://sourceforge.net/projects/xming/">Xming</a> (note that plotting
of the solution variables is commented and disabled in the
FEATool-FEniCS scripts by default).</p>
<p>Please do <a href="mailto://info@featool.com">report</a> any errors or anomalies
encountered due to either FEATool or the new FEATool-FEniCS export
functionality.</p>
Fri, 16 Jun 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/06/16/Python-FEM-and-Multiphysics-Simulations-with-Fenics-and-FEATool.html
https://www.featool.com/tutorial/2017/06/16/Python-FEM-and-Multiphysics-Simulations-with-Fenics-and-FEATool.htmlRunning Matlab FEM and Multiphysics Simulations in Parallel<p>When tasked with performing many finite element simulations, for example in optimization studies or performing parametric studies over several variables as described in <a href="https://www.featool.com/tutorial/2015/09/09/Parametric-Studies-with-FEATool-M-Script-Model-Files.html">this post</a>, one can speed up the overall process significantly by performing the simulations in parallel. This post describes an automated way to do this using the Unix <em>xargs</em> tool with a <em>bash</em> command script.</p>
<p>It is of course easy to simply run simulations in sequence with <em>for</em>
loops, but as modern machines often have two or more CPU cores one can
significantly reduce the total simulation time running the jobs in
parallel. The script described in the following will run on any Linux
or Unix machine with <em>bash</em> and
<a href="https://stackoverflow.com/questions/28357997/running-programs-in-parallel-using-xargs"><em>xargs</em></a>
installed including Windows systems with the <em>Ubuntu on Windows</em> shell
(available with the latest update). Matlab or Octave is also a
requirement of course.</p>
<p>In the setup and configuration of the script the total number of
parallel runs and the number of simultaneous number of parallel
processes is defined (the latter typically taken as the number or CPU
cores available).</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nv">n_parruns</span><span class="o">=</span>16 <span class="c"># Total number of jobs/runs.</span>
<span class="nv">n_parproc</span><span class="o">=</span>3 <span class="c"># Number of simultaneous parallel processes.</span>
</code></pre>
</div>
<p>Also the path to the Octave or Matlab binary executable file has to be
specified, as well as a Matlab m-script file to run, in this case
simply called <em>mscript.m</em>.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>export runcmd='/mnt/c/Octave/Octave-4.2.1/bin/octave-cli.exe'
export mscript=mscript.m
</code></pre>
</div>
<p>Next a global function is defined which will be called for each
parallel run and start its own Matlab/Octave instance to run a
simulation in.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>function parfun
{
echo parproc$1-$$: start # Terminal output.
# Write parproc file to temporary (current) directory.
tempdir=$(pwd)
echo > "$tempdir/parproc$1-$$"
# Octave/Matlab command string.
cmdstr="i_parrun = $1;
$(sed -n '/exit/!p;//q' $mscript)
delete([pwd,filesep,'parproc$1-$$']);"
echo "$cmdstr" > mscript_$1.m
eval $runcmd" mscript_$1.m"
# Sleep while parproc file exists.
while [ -f "$tempdir/parproc$1-$$" ]
do
sleep 1
done
# Cleanup.
rm -f mscript_$1.m
rm -f parproc$1-$$
echo parproc$1-$$: end # Terminal output.
}
export -f parfun
</code></pre>
</div>
<p>Lastly, <em>xargs</em> is called which automatically handles the batch
processing, that is to run <em>n_parproc</em> m-scripts in parallel starting
new jobs as running ones have finished.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>eval "printf \"%i\n\" {1..$n_parruns}" | xargs -n 1 -P $n_parproc -I {} bash -c 'parfun "$@"' _ {}
</code></pre>
</div>
<p>The whole script supporting both Matlab and Octave calls can be
downloaded from this link</p>
<div align="center" style="font-size:1.4em"><a href="https://github.com/precisesimulation/multiphysics/blob/master/parrun.sh" target="_blank" class="btn btn--inverse">
<strong>Matlab and Octave Parallel Job Script</strong></a></div>
<p><br /></p>
<p>As for the m-script file, it can contain any valid Matlab code
including FEATool functions (just make use Matlab/Octave can find
FEATool in the paths). The important thing to note is that each
instance has access to a variable <strong>i_parrun</strong> containing the parallel
job number (1-<em>n_parruns</em>). This variable can in turn be used to
select and set simulation and processing parameters.</p>
<p>For example, the following m-script can be used to run a parametric
study of the
<a href="https://www.featool.com/doc/quickstart.html#ex_ps1">hole in plate plane-stress model</a>,
varying both the hole diameter and plate thickness</p>
<div class="highlighter-rouge"><pre class="highlight"><code>disp(['parallel simulation run ',num2str(i_parrun)])
i_cnt = 0;
for diam = [0.01 0.02 0.03 0.05]
for thick = [0.001 0.0015 0.002 0.004]
i_cnt = i_cnt + 1;
if( i_parrun==i_cnt ) % Only run the simulation for i_parrun
[fea,out] = ex_planestress1( 'diam', diam, 'thick', thick, 'iplot', 0 );
eval( ['fea',num2str(i_parrun),' = fea;'] )
save( ['fea',num2str(i_parrun)], ['fea',num2str(i_parrun)] )
end
end
end
</code></pre>
</div>
<p>Once all the simulation runs have finished one can collect,
postprocess and visualize the results, for example</p>
<div class="highlighter-rouge"><pre class="highlight"><code>diam = [0.01 0.02 0.03 0.05];
thick = [0.001 0.0015 0.002 0.004];
s_sx = '200e9/(1-0.3^2)*ux + 0.3*200e9*vy';
for i=1:length(diam)
for j=1:length(thick)
i_cnt = 4*(i-1) + j;
load( ['fea',num2str(i_cnt)] )
eval( ['fea = fea',num2str(i_cnt),';'] )
[~,sx_max(i,j)] = minmaxsubd( s_sx, fea );
end
end
bar3(sx_max*1e-6)
xlabel( 'Thickness [mm]' )
set( gca, 'xticklabel', regexp(num2str(thick*1e3),'\s+','split') )
ylabel( 'Diameter [mm]' )
set( gca, 'yticklabel', regexp(num2str(diam*1e3),'\s+','split') )
zlabel( 'Maximum stress [GPa]' )
</code></pre>
</div>
<p><img src="https://www.featool.com/images/featool-multiphysics-parametric-maximum-stress-study.jpg" alt="FEATool Multiphysics - Parallel Parametric Stress Strain Analysis" class="full" /></p>
<p>In this particular case we can see that the maximum stress is found
with the largest diameter hole and thinnest plate as expected due to
the least amount of material left.</p>
Wed, 07 Jun 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/06/07/Running-Parallel-Matlab-FEM-and-Multiphysics-Simulations.html
https://www.featool.com/tutorial/2017/06/07/Running-Parallel-Matlab-FEM-and-Multiphysics-Simulations.htmlEuler-Bernoulli Beam Modeling and Simulation with FEATool<p>This post will discuss how to implement and model elastic deformations of simple beams with FEATool Multiphysics. Although not available as a pre-defined physics mode and GUI option yet, beams and truss structures can be implemented and accurately simulated with slight extension of the available FEM Matlab functions and subroutines. The following modeling example will be limited to small deformations according to <a href="https://en.wikipedia.org/wiki/Euler%E2%80%93Bernoulli_beam_theory">Euler-Bernoulli beam theory</a>.</p>
<h2 id="static-deformation">Static deformation</h2>
<p>For modeling the static vertical deflections, <em>v(x)</em> of a
horizontal beam the following fourth order equation applies</p>
<center>$$-\frac{\partial^2 }{\partial x^2}(EI(x)\frac{\partial^2 v}{\partial x^2}) = q(x)$$</center>
<p><br /></p>
<p>where <em>E</em> is the modulus of elasticity, <em>I(x)</em> cross-section moment of
inertia, and <em>q(x)</em> any applied volume load or force.</p>
<p>Due to the partial integration in the finite element weak formulation
it is sufficient with basis functions with non-vanishing 2nd
derivatives. Traditionally FEM beam simulations employ the 3rd order
<a href="https://www.featool.com/doc/sf__line___h3_8m.html">Hermite finite element</a>. Although
FEATool currently does not include support for evaluating 2nd order
derivatives, the open design of the source code makes this easy to
support simply by including the following <em>i_eval</em> case in the
<strong>sf_line_H3</strong> m-file definition (for more regarding implementing
custom finite element shape functions in Matlab script code see
<a href="https://www.featool.com/tutorial/2016/09/09/User-Defined-Finite-Element-FEM-Shape-Functions-with-FEATool.html">this previous post</a></p>
<div class="highlighter-rouge"><pre class="highlight"><code>function [ vBase, nLDof, xLDof, sfun ] = ...
sf_line_H3( i_eval, n_sdim, n_vert, i_dof, xi, aInvJac, vBase )
...
case 22 % Evaluation of second derivatives.
switch i_dof % Basis function derivative to evaluate.
case 1
dNdxi1 = 6*(2*xi(1)-1) ./ aInvJac(:,3);
dNdxi2 = 0;
case 2
dNdxi1 = 0;
dNdxi2 = -6*(2*xi(2)-1) ./ aInvJac(:,3);
case 3
dNdxi1 = 6*xi(1) - 2;
dNdxi2 = 0;
case 4
dNdxi1 = 0;
dNdxi2 = 6*xi(2) - 2;
end
vBase = aInvJac(:,1) .* dNdxi1 + aInvJac(:,2) .* dNdxi2;
....
</code></pre>
</div>
<p>In addition to the standard <em>i_eval</em> = 1 function value, and 2/3/4
x/y/z-derivative evaluations, we have created the new case <em>22</em> for
the <em>x</em><sup>2</sup>-derivative.</p>
<p>To define the simulation model we first create a finite element
analysis <em>fea</em> struct with a line grid spanning from <em>0</em> to <em>L</em> with
<em>nx</em> cells</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Grid generation.
fea.sdim = {'x'}; % Space dimension coordinate name.
fea.grid = linegrid( nx, 0, L );
</code></pre>
</div>
<p>We define the PDE equation for the y-displacement <em>v</em></p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Problem and equation definitions.
fea.dvar{1} = 'v'; % Dependent variable name.
fea.sfun{1} = 'sf_line_H3'; % FEM shape function for v.
eqn_v = '-E*I*vx_x = q';
</code></pre>
</div>
<p>Note here that this equation specifies <em>vx_x</em> for the bilinear form,
not <em>vxx_xx</em> which one would like. This is due to the fact that the
FEATool equation parser not yet supports 2nd order derivatives, thus
<em>vx_x</em> is used as a temporary placeholder. Furthermore, we also add a
help equation for the rotation <script type="math/tex">\theta</script></p>
<div class="highlighter-rouge"><pre class="highlight"><code>fea.dvar{1} = 'th'; % Help variable name.
fea.sfun{1} = 'sflag2';
eqn_th = 'th_t - vx_t = 0';
</code></pre>
</div>
<p>This help equation is not essential and does not influence the
solution since it simply is an algebraic expression for <script type="math/tex">\theta =
\frac{\partial v}{\partial x}</script>. We will however use the <em>th</em> variable
in postprocessing, or more accurately <em>thx</em> = <script type="math/tex">\frac{\partial
\theta}{\partial x}</script>, which is equivalent to the 2nd derivative of
<em>v</em> used in calculating the bending moment.</p>
<p>Having specified the equations we can call the FEATool equation parser
which processes the string equations into the weak finite element
definitions into the <em>fea.eqn</em> fields</p>
<div class="highlighter-rouge"><pre class="highlight"><code>fea.eqn = parseeqn( { eqn_v, eqn_th }, fea.dvar, fea.sdim );
fea.eqn.a.form{1} = [22;22];
</code></pre>
</div>
<p>Note here that we manually substitute the first weak <em>a</em> bilinear form
component from <code>[2;2]</code> (due to <em>vx_x</em>) to
<code>[22;22]</code> which will correspond to the sought term
<em>vxx_xx</em>. What this simply means in practical terms is that in the
FEM system matrix assembly step an <em>i_eval</em> flag of <em>22</em> will be
passed to the FEM trial and test shape function routine instead of the
usual <em>2</em>.</p>
<p>Boundary conditions also need to be prescribed, in this case the
assumption is the the left end at <em>x=0</em> is completely fixed while the
right end is free. This means homogeneous Dirichlet conditions at
point 1 and Neumann at point 2, for both the displacement and
rotational degrees of freedom. For the help equation do-nothing
Neumann BCs are appropriate.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Dirichlet boundary conditions.
bdr_d_v = { 0 [] ;
0 [] };
bdr_d_th = { [] [] };
fea.bdr.d = { bdr_d_v, bdr_d_th };
% Neumann boundary conditions.
bdr_n_v = { [] 0 ;
[] 0 };
bdr_n_th = { 0 0 };
fea.bdr.n = { bdr_n_v, bdr_n_th };
</code></pre>
</div>
<p>Before we solve the problem we define some model constants and
expressions. In FEATool these can conveniently be used both in
equation and boundary definitions, as well as postprocessing, and can
be either scalar or general string expressions of both Matlab built-in
and user defined functions (as long as the functions are found on the
Matlab path or current directory).</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Coefficients and equation/postprocessing expressions.
fea.expr = { 'L', L ;
'E', E ;
'I', I ;
'q', q ;
'M', 'E*I*thx' };
</code></pre>
</div>
<p>After everything is defined one can call the final parser to check
everything, and call the solver. In this case due to the higher order
Hermite FEM basis function we also need to use a corresponding higher
order numerical integration or quadrature rule.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Parse and solve problem.
fea = parseprob( fea );
fea.sol.u = solvestat( fea, 'icub', 4 );
</code></pre>
</div>
<p>When the problem has been solved we can plot the results and in this
case compare with the analytical reference solution (note that for the
definition of the moment <em>M</em> we use the derivative of the help
variable <em>thx</em> as defined in the <em>fea.expr</em> field)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>postplot( fea, 'surfexpr', 'E*I*v/(q*L^4)', 'linewidth', 2 ), hold on
postplot( fea, 'surfexpr', 'x^2*(6*L^2-4*L*x+x^2)/24/L^4', 'color', 'r', 'linestyle', ':' )
title( 'E*I*v(x)/(q*L^4)' )
postplot( fea, 'surfexpr', 'E*I*th/(q*L^3)', 'linewidth', 2 ), hold on
postplot( fea, 'surfexpr', 'x*(3*L^2-3*L*x+x^2)/6/L^3', 'color', 'r', 'linestyle', ':' )
title( 'E*I*theta(x)/(q*L^3)' )
postplot( fea, 'surfexpr', 'M/(q*L^2)', 'linewidth', 2 ), hold on
postplot( fea, 'surfexpr', '1/2*(L-x)^2/L^2', 'color', 'r', 'linestyle', ':' )
title( 'M(x)/(q*L^2)' )
</code></pre>
</div>
<p>Note that due to Octave bugs the postprocessing commands above crash
and segfault on the tested systems, an alternative is to use the
Plotly html web visualization introduced with <a href="https://www.featool.com/tutorial/2017/05/22/Full-Plotly-Integration-with-FEATool-Multiphysics.html">this update patch</a></p>
<div class="highlighter-rouge"><pre class="highlight"><code>p1 = postplot( fea, 'surfexpr', 'E*I*v/(q*L^4)', 'linewidth', 2, 'renderer', 'plotly' )
p2 = postplot( fea, 'surfexpr', 'x^2*(6*L^2-4*L*x+x^2)/24/L^4', 'color', 'r', 'linestyle', ':', 'renderer', 'plotly' )
p1.data = [ p1.data p2.data ];
plotly_html_file = plotlyoffline( p1 )
</code></pre>
</div>
<p>Although very hard to discern from the resulting image, the exact and
computed solutions agree and perfectly overlap as would be expected
here.</p>
<p><img src="https://www.featool.com/images/featool-multiphysics-matlab-beam-fem-simulation-displacement.jpg" alt="FEATool Multiphysics Matlab FEM Euler Beam Displacement" class="full" /></p>
<h2 id="vibration-analysis">Vibration analysis</h2>
<p>To perform an vibrational analysis to calculate eigenmodes and
eigenfrequencies we use manual assembly to build the input required
for the Matlab <em>eigs</em> function (calling arpack). Here we want to get
the mass and stiffness matrices due to</p>
<center>$$\rho A(x)\frac{\partial^2 v}{\partial t^2} - \frac{\partial^2 }{\partial x^2}(EI(x)\frac{\partial^2 v}{\partial x^2}) = 0$$</center>
<p><br /></p>
<p>where <script type="math/tex">\rho</script> is the material density, and <em>A</em> the cross-sectional
area. For the problem setup we proceed as above omitting the help
equation for <em>th</em>. To directly compute the matrices we use the
<a href="https://www.featool.com/doc/assembleprob_8m.html">assembleprob</a> function with
flags <em>f_m</em>, <em>f_a</em>, and <em>f_sparse</em> to compute and return the sparse
mass and stiffness matrices</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Parse and assemble matrices.
fea = parseprob( fea );
[M,A] = assembleprob( fea, 'f_m', 1, 'f_a', 1, 'f_sparse', 1, 'icub', 4 );
</code></pre>
</div>
<p>As for boundary conditions we must here eliminate rows corresponding
to the homogeneous Dirichlet ones as</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Eliminate Dirichlet boundary conditions from matrices.
ix_b = ones(size(M,1),1);
[tmp,ix_b] = bdrsetd( [], ix_b, fea );
ix_rem = find(ix_b==0);
M(:,ix_rem) = [];
M(ix_rem,:) = [];
A(:,ix_rem) = [];
A(ix_rem,:) = [];
</code></pre>
</div>
<p>The problem can now be solved for the desired number of
eigenfrequencies by calling the built-in eigs function</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Solve for eigenvalues and eigenvectors.
n_eigs = 6;
[V,D] = eigs( A, M, n_eigs, 0 );
efq = sqrt(diag(D))/(2*pi);
</code></pre>
</div>
<p>We can also plot and visualize the four first vibration modes as
follows</p>
<div class="highlighter-rouge"><pre class="highlight"><code>figure, hold on, grid on
cols = {'b' 'r' 'y' 'g' 'c' 'm'};
x = fea.grid.p;
ind_dof_v = find(ix_b(1:length(x)));
for i=1:4
y = zeros(size(x));
y(ind_dof_v) = V(1:length(ind_dof_v),n_eigs-i+1);
plot( x, y, 'color', cols{mod(i-1,6)+1}, 'linewidth', 2 )
end
legend( {'Mode 1' 'Mode 2' 'Mode 3' 'Mode 4'} )
title( 'Vibration modes' )
xlabel( 'x' )
ylabel( 'Displacement' ) <br>
</code></pre>
</div>
<p><img src="https://www.featool.com/images/featool-multiphysics-matlab-beam-fem-simulation-vibration-modes.jpg" alt="FEATool Multiphysics Matlab FEM Euler Beam Vibration Modes" class="full" /></p>
<p>The FEATool Multiphysics model m-script files for these two beam
simulation examples can be downloaded from the links below</p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/assets/ex_euler_beam1.m" target="_blank" class="btn btn--inverse">
<strong>FEATool Multiphysics Euler Static Beam Analysis </strong></a></div>
<p><br /></p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/assets/ex_euler_beam2.m" target="_blank" class="btn btn--inverse">
<strong>FEATool Multiphysics Euler Beam Vibration Analysis</strong></a></div>
Tue, 30 May 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/05/30/Euler-Bernoulli-Beam-Matlab-Simulation-in-FEATool-Multiphysics.html
https://www.featool.com/tutorial/2017/05/30/Euler-Bernoulli-Beam-Matlab-Simulation-in-FEATool-Multiphysics.htmlFull Plotly Integration with FEATool Multiphysics<p>The <a href="http://plot.ly/">Plotly</a> javascript visualization library has previously featured <a href="https://www.featool.com/tutorial/2016/08/17/Plotly-Integration-and-Plot-Export-With-FEATool.html">partial integration with FEATool Multiphysics</a> through its online web based service. As the core <a href="https://github.com/plotly/plotly.js/">Plotly javascript library</a> has been open sourced and made available to external projects, as well as now supporting full 3D plots with the <em>mesh3d</em> type, Plotly has now been fully integrated with FEATool supporting all finite element FEM postprocessing options such as surface, contour, and arrow plots in 1D, 2D, and 3D. This means that one can now use Plotly directly for visualization instead of the default Matlab or Octave plots.</p>
<p>From the FEATool GUI Plotly plots can now be created directly by
simply pressing the button labeled <strong>Plotly</strong>, either in the
postprocessing toolbar or in the postprocessing settings dialog
box. This will create the selected plotly visualization data and save
it to a corresponding <em>html</em> file which will be opened in your default
web browser. The plot and data can then be examined with the plotly
interface, exported as image files, and also uploaded to the plotly
cloud for sharing with colleagues and coworkers, see for example the
<a href="https://plot.ly/~featool/">FEATool Multiphysics Plotly</a> web
archive. Besides creating nice looking plots, direct web interface to
examining the data, and online sharing, other advantages of using
Plotly compared to Matlab or Octave is that the performance can be
better, especially for 3D plots.</p>
<p><img src="https://www.featool.com/images/featool-multiphysics-matlab-full-plotly-integration.jpg" alt="FEATool Multiphysics - Plotly integration with Matlab and Octave" class="full" /></p>
<p>Matlab and Octave CLI command line usage is just as easy as
before. The <a href="https://www.featool.com/doc/postplot_8m.html">postplot</a> commands have been updated to include a
<em>renderer</em> flag with a <em>plotly</em> option, to use plotly simply add this
flag to a corresponding postplot command</p>
<div class="highlighter-rouge"><pre class="highlight"><code>postplot( fea, ..., 'renderer', 'plotly' )
</code></pre>
</div>
<p>where <em>…</em> are your usual postprocessing property value pairs such as
<em>surfexpr</em>, <em>isoexpr</em>, and <em>arrowexpr</em> etc. The plotly postprocessing
data struct can also optionally be obtained as</p>
<div class="highlighter-rouge"><pre class="highlight"><code>plotly_data = postplot( fea, ..., 'renderer', 'plotly' );
</code></pre>
</div>
<p>and corresponding web <em>html</em> file generation can manually be called with</p>
<div class="highlighter-rouge"><pre class="highlight"><code>html_file = plotlyoffline( plotly_data );
</code></pre>
</div>
<p>For example, the image above can be created with the following
Matlab/Octave commands</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Set up model, solve, and export finite element FEA/FEM data.
fea = ex_linearelasticity4( 'ilev', 1 );
% Optionally deform grid according to displacement.
dscale = 5e3;
dp = zeros(size(fea.grid.p));
for i=1:3
dp(i,:) = dscale * evalexpr( fea.dvar{i}, fea.grid.p, fea );
end
fea.grid.p = fea.grid.p + dp;
% Postprocessing call with plotly switch.
postplot( fea, 'surfexpr', 'sqrt(u^2+v^2+w^2)', ...
'title', 'Total displacement', ...
'renderer', 'plotly' )
</code></pre>
</div>
<p>The full plotly integration update patch can be downloaded from the link below</p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/assets/featool-plotly-patch.zip" target="_blank" class="btn btn--inverse">
<strong>FEATool Multiphysics Full Plotly Integration Patch</strong></a></div>
<p><br /></p>
<p>To install it, extract the contents and overwrite the corresponding
files in your existing <em>featool</em> directory, and restart Matlab/Octave
and FEATool.</p>
<p>Please feel free to try the FEATool Plotly visualization and share
your models and plots.</p>
Mon, 22 May 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/05/22/Full-Plotly-Integration-with-FEATool-Multiphysics.html
https://www.featool.com/tutorial/2017/05/22/Full-Plotly-Integration-with-FEATool-Multiphysics.htmlMultiphysics Modeling of Resistive Heating in a Tungsten Filament<p>The following tutorial discusses multiphysics modeling of resistive Joule heating simulated with the FEATool Multiphysics Octave and Matlab FEM toolbox. In the model the resulting current from an applied electric potential will heat a thin spiral shaped Tungsten wire, such as can be found in incandescent light bulbs. After the start up phase the filament reaches an equilibrium temperature where the internal heat generation is balanced by radiative heat loss through the boundaries. Although the model could quite easily be implemented in the FEATool GUI, since it features a one way multiphysics coupling it will be shown how the dependent variables and equations can be decoupled and implemented as a Matlab m-script file to save computational time.<br /></p>
<p><img src="https://www.featool.com/images/featool-multiphysics-matlab-electrical-resistivity-fem-simulation.jpg" alt="FEATool Multiphysics - Resistive Heating FEM Matlab Simulation Geometry and Grid" class="full" /></p>
<h2 id="model-parameters-and-constants">Model parameters and constants</h2>
<p>The first modeling step is to define constants for the equation
coefficients and boundary conditions. It is assumed the material of
the filament is Tungsten and is held at <em>20</em> ℃ at its connecting
points in the socket, and is also subject to radiative heat loss with
an ambient temperature of <em>80</em> ℃. An electric potential of <em>0.2
V</em> is applied across the wire resulting in temperature rise due to the
source term <em>Q</em>. Here, we label this term with the coefficient string
<em>qfunction</em> which FEATool will attempt to parse as a general string
expression. (Valid equation, boundary, and postprocessing string
expressions may consist of combinations of numerical values, dependent
variables and derivatives, here <em>V</em> and <em>Vx</em> etc., space coordinates
<em>x</em>, <em>y</em>, and <em>z</em>, built-in constants and functions such as <em>pi</em> and
<em>sin</em>, and custom functions). Here we will use the fact that as a last
resort FEATool will try to parse and evaluate <em>qfunction</em> as a custom
user-defined Matlab m-function the construction of which will be
discussed later.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>V0 = 0.2; % Potential difference [V].
sigma = 1/52.8e-9; % Electrical conductivity [1/Ohm/m].
rho = 19.25e3; % Density [kg/m3].
cp = 133.9776; % Specific heat capacity [J/kg/K].
k = 173; % Thermal conductivity [W/m/K].
Q = 'qfunction'; % Resistive heating source term function.
C = 5.670367e-8; % Stefan-Bolzmann radiation constant.
T0 = 20 + 273.15; % Initial temperature [K].
Tamb = 80 + 273.15; % Mean ambient temperature [K].
</code></pre>
</div>
<h2 id="grid-generation">Grid generation</h2>
<p>Since the geometry in this case is quite simple we can omit it and
directly proceed to manually create the grid through using the grid
primitive functions (<em>fea.geom</em> fields are only used by the
unstructured grid generation function <em>gridgen</em>). The computational
grid is thus here created by taking a circle
(<a href="https://www.featool.com/doc/circgrid_8m.html">circgrid</a>),
extruding, and revolving it to create the filament spiral
(<a href="https://www.featool.com/doc/gridrevolve_8m.html">gridrevolve</a>).</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Geometry dimensions in [m].
r_wire = 0.0005; % Wire radius.
l_spiral = 0.005; % Length of spiral.
r_spiral = 0.004; % Outer radius of spiral.
fea.sdim = { 'x' 'y' 'z' };
fea.grid = gridrotate( gridrevolve( ...
circgrid( 2, 3, r_wire ), ...
80, l_spiral, 3, r_spiral ), ...
-pi/2, 2 );
</code></pre>
</div>
<p>The resulting grid and boundaries can be visualized with the
<code>plotgrid(fea)</code> and <code>plotbdr(fea)</code> commands,
respectively.</p>
<h2 id="electrostatics">Electrostatics</h2>
<p>The model is quasi-static in the sense that the electric potential
solution is static while the overall heat transfer process is examined
as a function of time. Although we could solve this as a
monolithically coupled problem (solving for <em>T</em> and <em>V</em> simultaneously
together), the electric potential problem is assumed to be independent
of the temperature (the electrical conductivity <script type="math/tex">\sigma</script> is
constant) and can thus be solved separately as a steady state problem
by itself, that is</p>
<center>$$\nabla\cdot(\sigma\nabla V) = 0 $$</center>
<p><br /></p>
<p>with insulation boundary conditions, <script type="math/tex">\mathbf{n}\cdot(\sigma\nabla
V)=0</script>, everywhere except for the two ends where the potential
difference <em>V0</em> is applied. In the Matlab m-script of language
used by FEATool this looks like the following</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Set up and solve electrostatics problem.
feaV = addphys( fea, @conductivemediadc );
feaV.phys.dc.eqn.coef{2,end} = {sigma}; % Electrical conductivity.
feaV.phys.dc.bdr.sel([1 98]) = 1;
feaV.phys.dc.bdr.coef{1,end}{1} = V0; % Potential difference.
feaV = parsephys( feaV );
feaV = parseprob( feaV );
feaV.sol.u = solvestat( feaV );
</code></pre>
</div>
<p>Note that here an alternative help variable for the FEM struct
belonging to the electric potential has been used, <code>feaV</code>.</p>
<h2 id="heat-transfer">Heat transfer</h2>
<p>The heat transfer problem for the temperature field is governed by the heat equation PDE</p>
<center>$$\rho c_p\frac{\partial T}{\partial t} - \nabla\cdot (k\nabla T) = Q $$</center>
<p><br /></p>
<p>where here the electric potential is also the source of heat
generation with the term <script type="math/tex">Q = \sigma|\nabla V|^2</script>. Thus this
equation features a non-linear one-way multiphysics coupling, <em>V</em>
coupled to the temperature <em>T</em>. As for interaction with the
surroundings the temperature is fixed at <em>T = T0</em> at both ends while
radiation flux boundary conditions <script type="math/tex">\mathbf{n}\cdot(k\nabla
T)=C(T_{amb}^4-T^4)</script> are applied everywhere else. The following code
sets up this heat transfer problem</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Set up heat transfer problem.
fea = addphys( fea, @heattransfer );
fea.phys.ht.eqn.coef{1,end} = {rho}; % Density.
fea.phys.ht.eqn.coef{2,end} = {cp}; % Heat capacity.
fea.phys.ht.eqn.coef{3,end} = {k}; % Thermal conductivity.
% Use generalized heat flux boundary condition (4) for all boundaries
% except at the ends where the temperature T0 is prescribed(1).
fea.phys.ht.bdr.sel([2:97]) = deal(4);
[fea.phys.ht.bdr.coef{4,end}{2:97}] = deal({0 0 0 C Tamb});
fea.phys.ht.bdr.sel([1 98]) = deal(1);
fea.phys.ht.bdr.coef{1,end}{ 1} = T0;
fea.phys.ht.bdr.coef{1,end}{98} = T0;
% Specify heat source term - qfunction.
fea.phys.ht.eqn.coef{7,end} = {'qfunction'};
% Add sigma and electric potential solution used by qfunction.
fea.expr = { 's_sigma' '' '' sigma ;
'u_V' '' '' feaV.so.u };
</code></pre>
</div>
<h2 id="custom-external-source-term-function">Custom external source term function</h2>
<p>We cannot solve the temperature problem yet since we have not defined
the heat source term <code>qfunction</code>. We do this in a separate
Matlab m-file with the same name as the equation coefficient itself,
that is <em>qfunction.m</em>. Although the following code for <em>qfunction</em>
might look intimidating, all it does is to essentially take the
solution for <em>V</em> stored in <em>fea.expr</em> and computes the heat source
term as <strong>sigma*(Vx^2+Vy^2+Vz^2)</strong>. Although we could easily solve the
fully monolithically coupled problem with the FEATool GUI, we would
then have to solve a much larger coupled system in each time
step. This decoupled approach we save both time and memory at the cost
of having to use a custom function.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>function [ Q ] = qfunction()
% Build up a source term expression from the precomputed solution
% vector stored in prob.expr{ u_V }. Expected to be called from evalexpr0.
% Workaround to get input variable string names from evalexpr0.
persistent inputname0
if( isempty(inputname0) )
ds = dbstack;
fid = fopen( which(ds(2).file), 'r' );
sline = fgetl( fid );
sline = sline( find( sline== '(', 1 )+1:find( sline== ')', 1 )-1 );
inputname0 = regexp( sline(~isspace(sline)), ',', 'split' );
fclose( fid );
end
% Extract variable from the calling function, evalexpr0.
xi = evalin( 'caller', inputname0{2} );
ind_s = evalin( 'caller', inputname0{3} );
ind_c = evalin( 'caller', inputname0{4} );
prob = evalin( 'caller', inputname0{6} );
aJac = evalin( 'caller', inputname0{7} );
n_sdim = size( prob.grid.p, 1 );
n_vert = size( prob.grid.c, 1 );
i_dvar = 1; % Assume same dep. var. fem basis function for u_V as for i_dvar=1.
[~,~,~,sfun] = evalsfun( prob.sfun{i_dvar}, 0, n_sdim, n_vert ); % Get shape function root string.
if( isempty(aJac) ) % Calculate Jacobian if required.
store_aJTmp = strcmpi(sfun(end-1:end),'H3') && ( (n_sdim==2 && n_vert==4) || (n_sdim==3 && n_vert==8) );
[~,aJac] = tfjac( 1, prob.grid.p, prob.grid.c(:,ind_c), [], xi, aJac, store_aJTmp );
end
u_V = prob.expr{ find(strcmp(prob.expr,'u_V')), end }; % V solution vector.
% Evaluate derivatives of V (1=function value, 2=x-derivative, 3=y-derivative, 4=z-derivative).
Vx = evaldvar( sfun, 2, n_sdim, n_vert, xi, aJac, prob.eqn.dofm{i_dvar}(:,ind_c), u_V );
Vy = evaldvar( sfun, 3, n_sdim, n_vert, xi, aJac, prob.eqn.dofm{i_dvar}(:,ind_c), u_V );
Vz = evaldvar( sfun, 4, n_sdim, n_vert, xi, aJac, prob.eqn.dofm{i_dvar}(:,ind_c), u_V );
% Value or expression for sigma.
s_sigma = prob.expr{ find(strcmp(prob.expr,'s_sigma')), end };
% Calculate final expression and return values.
Q = evalexpr0( s_sigma, xi, ind_s, ind_c, [], prob, aJac ).*( Vx.^2 + Vy.^2 + Vz.^2 );
</code></pre>
</div>
<h2 id="solution-and-postprocessing">Solution and postprocessing</h2>
<p><img src="https://www.featool.com/images/featool-multiphysics-matlab-resistive-heating-fem-simulation.jpg" alt="FEATool Multiphysics - Resistive Heating FEM Matlab Simulation Solution" class="full" /></p>
<p>Finally we can solve the time-dependent heat transfer problem and plot
the solutions keeping in mind that the electric potential is stored in
the <code>feaV</code> FEM struct and temperature separately in
<code>fea</code>.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>fea = parsephys( fea );
fea = parseprob( fea );
fea.sol.u = solvetime( fea, 'init', {T0}, 'tstep', 1, 'tmax', 20 );
figure
subplot(1,2,1)
postplot( feaV, 'surfexpr', 'V' )
subplot(1,2,2)
postplot( fea, 'surfexpr', 'T' )
</code></pre>
</div>
<p>After the solver has finished we can see that the maximum reached
temperature is about <em>700 K</em>. The temporal evolution of the
temperature field can also be seen in the video linked
below. Technically, we could continue our study by also examining the
heat induced stresses and strains, coupling the temperature to the
linear elasticity physics mode. However since for this particular
application the failure point is likely to be due to temperature,
which is far lower than the melting temperature of Tungsten, it is
safe to assume that we do not need to examine the stresses.<br /><br /></p>
<iframe width="420" height="315" src="https://www.youtube.com/embed/jwbzkN1YyZs" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>
<p><br /></p>
<p>The described resistive heating Matlab model m-file is available for download from the link below.</p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/assets/featool_multiphysics_resistive_heating1.m" target="_blank" class="btn btn--inverse">
<strong>FEATool Multiphysics Resistive Heating Model Example</strong></a></div>
Mon, 15 May 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/05/15/Multiphysics-Modeling-of-Resistive-Heating-in-a-Tungsten-Filament.html
https://www.featool.com/tutorial/2017/05/15/Multiphysics-Modeling-of-Resistive-Heating-in-a-Tungsten-Filament.htmlAdvanced Matlab Command Line Postprocessing and Visualization<p>The following post will break down and explain the steps used to create the images and video for the <a href="https://www.featool.com/tutorial/2017/04/14/Multiphysics-Modeling-of-Heat-Induced-Stress-in-a-Brake-Disk.html">axisymmetric stress-strain brake disk analysis</a> model. By using the Octave or Matlab command line and exported finite element <em>fea</em> data we can create custom postprocessing and visualizations that is not possible in the FEATool GUI.</p>
<iframe width="420" height="315" src="https://www.youtube.com/embed/0v7Uy-zIU3M" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>
<p><br /></p>
<p>The first step is to run the FEATool model script file to generate and
return the finite element struct <em>fea</em> and solution stored in
<em>fea.sol.u</em> (in this case the automatic pre-defined plots can be
turned off, <em>iplot=0</em>, since we will do postprocessing manually)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>fea = axi_stress_strain_heat_brake_disk( 'iplot', 0 );
</code></pre>
</div>
<p>Next we prescribe the model constants and parameters used in the
postprocessing</p>
<div class="highlighter-rouge"><pre class="highlight"><code>deltad = 5.5e-3; % Disk thickness.
rd = 66e-3; % Disk inner radius.
rp = 75.5e-3; % Pad inner radius.
Rd = 113.5e-3; % Disk outer radius.
</code></pre>
</div>
<p>To continue, the solution vector for all time steps is saved in a
temporary variable <em>u</em> (the solution at each time step corresponds to
a column in <em>u</em>). The parameters <em>cmax</em> and <em>cmin</em> are also calculated
which later are used to fix the colormap range (otherwise we would not
be able to see much difference between hot and cold maxima)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>u = fea.sol.u;
cmax = max(u(:)) - 273.15;
cmin = 0;
</code></pre>
</div>
<p>Next, coordinates to plot and visualize the countours and
boundaries of the brake disk are created (here the assumption is that
the disk is centered at the origin with the radial coordinate spanning
the x-z plane)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>% Points around the circumference.
npth = 72;
th = linspace( 0, 2*pi, npth );
% Inner coordinates.
x = rd*cos(th);
z = rd*sin(th);
% Outer coordinates.
xx = Rd*cos(th);
zz = Rd*sin(th);
y = deltad*ones(size(x));
</code></pre>
</div>
<p>We also use the
<a href="https://www.featool.com/doc/ringgrid_8m.html">ringgrid</a> function
to generate coordinates around the disk in the grid struct <em>g</em> and
evaluation points in <em>rz</em>. These will be used to interpolate the
temperature field from axisymmetric coordinates to three dimensions
(the ringgrid can be visualized by itself with using the <em>plotgrid(g)</em>
command)</p>
<div class="highlighter-rouge"><pre class="highlight"><code>npr = 25;
g = ringgrid( npr-1, npth-1, rd, Rd );
r = sqrt( g.p(1,:).^2 + g.p(2,:).^2 );
rz = [rd+sqrt(eps) rd+(Rd-rd)/2 Rd-sqrt(eps);deltad/2*[1 1 1]];
</code></pre>
</div>
<p>Now we can begin by creating a figure to plot in, an empty array for
the stresses at the three points (inner radius, outer radius, and the
mid point), and starting the postprocessing loop</p>
<div class="highlighter-rouge"><pre class="highlight"><code>figure
st = zeros(3,1);
for i=1:size(u,2)
</code></pre>
</div>
<p>We use <em>subplot</em> to hold two horizontal images. First is the 3D
temperature field, starting with drawing the black outline of the
brake disk</p>
<div class="highlighter-rouge"><pre class="highlight"><code> subplot(1,2,1)
hold on
plot3(x, y, z,'k-')
plot3(x, -y, z,'k-')
plot3(xx, y,zz,'k-')
plot3(xx,-y,zz,'k-')
</code></pre>
</div>
<p>The <em>i</em>:th solution is selected as the only solution in <em>fea.sol.u</em>
(since <em>evalexpr</em> per default uses the solution at the last time
step), after which the temperature is evaluated along the radius at
the disk center line coordinate (z=0).</p>
<div class="highlighter-rouge"><pre class="highlight"><code> fea.sol.u = u(:,i);
T = evalexpr( 'T-273.15', [r;zeros(size(r))], fea );
</code></pre>
</div>
<p>We use the fact that the solution is axisymmetric to extrapolate this
data all along the brake disk using the annular grid struct <em>g</em>
created earlier. The Matlab <em>patch</em> command is used to plot the <em>x-z</em>
temperature field</p>
<div class="highlighter-rouge"><pre class="highlight"><code> h = patch( 'faces', g.c', ...
'vertices', [g.p(1,:)' zeros(size(g.p,2),1) g.p(2,:)'], ...
'facevertexcdata', T, ...
'facecolor', 'interp', ...
'linestyle', 'none' );
</code></pre>
</div>
<p>Furthermore, we also plot the temperature for the original patch in
the positive and mirrored (negative) z-directions</p>
<div class="highlighter-rouge"><pre class="highlight"><code> postplot( fea, 'surfexpr', 'T-273.15', 'colorbar', 'off' )
fea.grid.p(2,:) = -fea.grid.p(2,:);
postplot( fea, 'surfexpr', 'T-273.15', 'colorbar', 'off' )
fea.grid.p(2,:) = -fea.grid.p(2,:);
</code></pre>
</div>
<p>Lastly, we set a title, fix the color map range, and choose a suitable
viewing angle</p>
<div class="highlighter-rouge"><pre class="highlight"><code> title( 'Temperature' )
caxis( [cmin cmax] )
view(3)
axis off
axis tight
</code></pre>
</div>
<p>For the second subplot we want to follow the von Mieses stress as a
function of time for the three points in <em>rz</em>. Just as for the
temperature, the stress can be evaluated with the
<a href="https://www.featool.com/doc/evalexpr_8m.html">evalexpr</a> command
where the stress expression <em>svm</em> has been defined earlier in the
model <em>fea.const</em> field</p>
<div class="highlighter-rouge"><pre class="highlight"><code> subplot(1,2,2)
hold on
grid on
if( i>1 ) % Skip first zero solution
st = [st evalexpr( '(svm)*1e-6', rz, fea )];
</code></pre>
</div>
<p>The stress is plotted as a function of time, with additional text
and legends added for identification</p>
<div class="highlighter-rouge"><pre class="highlight"><code> plot( tlist(1:i), st(1,:) )
plot( tlist(1:i), st(2,:) )
plot( tlist(1:i), st(3,:) )
text( tlist(i), st(1,end), 'r = rd' )
text( tlist(i), st(2,end), 'r = (rd+Rd)/2' )
text( tlist(i), st(3,end), 'r = Rd' )
axis( [0 tmax 0 max(st(:))] )
end
xlabel( 'Time [s]' )
ylabel( 'von Mieses stress [MPa]' )
</code></pre>
</div>
<p>Finally, we force drawing with the <em>drawnow</em> command, optionally write
out and save a <em>jpeg</em> image file, and close the loop</p>
<div class="highlighter-rouge"><pre class="highlight"><code> drawnow
print( '-r200', '-djpeg', sprintf('img%03i.jpg',i) )
end
</code></pre>
</div>
<p>After processing has finished the images can easily be converted to a
video with a suitable tool, such as for example
<a href="https://ffmpeg.org/">ffmpeg</a></p>
<div class="highlighter-rouge"><pre class="highlight"><code>ffmpeg -i img%03d.jpg -c:v libx264 -vf "fps=25,format=yuv420p,crop=1600:1198:0:0" out.mp4
</code></pre>
</div>
<p>From the video we can see that the temperature is the highest on the
outer two-thirds of the disk consistent with where the break pad is
acting. In contrast the maximum stress is achieved at the inner radius
<em>r=rd</em> around <em>t=3</em>, and is significantly higher than at the two
points measured further out on the disk.</p>
Mon, 08 May 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/05/08/Advanced-Matlab-Command-Line-Postprocessing-and-Visualization.html
https://www.featool.com/tutorial/2017/05/08/Advanced-Matlab-Command-Line-Postprocessing-and-Visualization.htmlMultiphysics Modeling of Heat Induced Stress in a Brake Disk<p>This post shows how to couple a heat transfer model with linear elasticity. The custom PDE equation model examines how temperature rise in break disk under breaking results in stresses and strains. Using the assumption that all variations in the rotational direction can be neglected we can use an axisymmetric formulation saving computational time compared to full 3D.</p>
Fri, 14 Apr 2017 00:00:00 +0900
https://www.featool.com/tutorial/2017/04/14/Multiphysics-Modeling-of-Heat-Induced-Stress-in-a-Brake-Disk.html
https://www.featool.com/tutorial/2017/04/14/Multiphysics-Modeling-of-Heat-Induced-Stress-in-a-Brake-Disk.htmlFeatFlow vs. FEATool Umfpack Matlab CFD Solver Benchmark<p>To evaluate the efficiency of the <a href="https://www.featool.com/tutorial/2016/11/14/Easy-Matlab-CFD-FeatFlow-external-CFD-solver-with-FEATool-integration.html">FeatFlow CFD solver</a> one can use the now classic DFG flow over a cylinder CFD benchmark [<a href="#1">1</a>][<a href="#2">2</a>] for which very accurate reference solutions for drag, lift, and pressure difference have been established [<a href="#3">3</a>][<a href="#4">4</a>]. The model problem is set up and solved with identical grids and finite element FEM spaces for both the built-in FEATool solver and the dedicated FeatFlow CFD solver. FEATool uses the built-in Matlab and Octave direct solver which currently defaults to <a href="http://faculty.cse.tamu.edu/davis/suitesparse.html">Umfpack</a>, while FeatFlow uses a very efficient geometric multigrid approach.</p>
Fri, 31 Mar 2017 00:00:00 +0900
https://www.featool.com/fem/2017/03/31/FeatFlow-Matlab-CFD-Solver-Benchmark.html
https://www.featool.com/fem/2017/03/31/FeatFlow-Matlab-CFD-Solver-Benchmark.htmlFEATool 1.6 - Easy and Efficient CFD Simulations in Matlab<h2 id="featool-multiphysics-version-16-now-available">FEATool Multiphysics version 1.6 now available</h2>
<p>FEATool is designed to be a very easy to use, flexible, and customizable PDE and FEM Continuum Mechanics and Multiphysics Simulation Toolbox for Matlab and Octave. This release brings the following major features and improvements
<br />
<br /></p>
<div class="fw">
<div class="fi--left">
<div class="archive__item">
<div class="archive__item-teaser">
<img src="https://www.featool.com/images/featool-multiphysics-with-featflow-matlab-cfd-toolbox.jpg" alt="FEATool v1.6 with FeatFlow - Easy and Efficient CFD Simulations in Matlab" />
</div>
<div class="archive__item-body">
<div class="archive__item-excerpt">
<ul>
<li><strong><a href="https://www.featool.com/tutorial/2016/11/14/Easy-Matlab-CFD-FeatFlow-external-CFD-solver-with-FEATool-integration.html">FeatFlow CFD Solver - CFD in Matlab</a></strong><br /><br />The dedicated <a href="http://www.featflow.de/">FeatFlow CFD solver</a> is now integrated with FEATool. For the first time, this allows high performance CFD simulations from an easy to use and convenient GUI directly in Matlab.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<p>The open source FeatFlow CFD solver has been thoroughly tested,
validated, and used in computational fluid dynamics benchmarks and in
a wide variety of industrial fluid flow simulations such as heat
exchangers, two-phase flows, screw and fixed industrial mixers, and
more. Employing a novel and unique FEM multigrid solver approach
FeatFlow has consistently shown to be both faster and more accurate
compared to both modern academic and commercial CFD codes [<a href="#1">1</a>],
[<a href="#2">2</a>]. With the new FEATool integration the high performance
FeatFlow CFD solver now can be used by everyone.</p>
<div class="fw"></div>
<div class="fw">
<div class="fi--right">
<div class="archive__item">
<div class="archive__item-teaser">
<img src="https://www.featool.com/images/featool-multiphysics-matlab-quadrilateral-grid-generation-collage-2.jpg" alt="FEATool v1.6 - Automatic Quadrilateral Grid Generation" />
</div>
<div class="archive__item-body">
<div class="archive__item-excerpt">
<ul>
<li><strong><a href="https://www.featool.com/tutorial/2016/08/10/Automatic-Quadrilateral-Grid-Generation.html">Automatic Quadrilateral Grid Generation</a></strong><br /><br />FEATool now also includes an experimental automatic quadrilateral grid generation function suitable for generating structured grids as required by FeatFlow.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<p>In addition grid smoothing and refinement functionality has been
expanded and improved, as well as allowing conversion between simplex
(triangle and tetrahedral) and structured (quadrilateral and
hexahedral) grid cells.</p>
<div class="fw"></div>
<div class="fw">
<div class="fi--left">
<div class="archive__item">
<div class="archive__item-teaser">
<img src="https://www.featool.com/images/featool-multiphysics-high-order-fem-shape-functions.jpg" alt="FEATool v1.6 - High Order FEM Shape Functions " />
</div>
<div class="archive__item-body">
<div class="archive__item-excerpt">
<ul>
<li><strong><a href="https://www.featool.com/tutorial/2016/09/09/User-Defined-Finite-Element-FEM-Shape-Functions-with-FEATool.html">High Order FEM Shape Functions</a></strong><br /><br />The FEATool Finite Element FEM basis function library has been expanded for increased accuracy to include conforming Lagrange functions up to fifth order (P1-P5/Q1-Q5), and also C1 Hermite functions in 1D and 2D.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<ul>
<li>
<p><strong>General improvements</strong><br /></p>
<ul>
<li>
<p>New examples including three axisymmetric stress-strain models, two
non-linear PDE models, and one new 2D Laplace equation test model</p>
</li>
<li>
<p>GUI fixes for Octave 4.2.x, bug fixes and stability improvements</p>
</li>
</ul>
</li>
</ul>
<p><br /></p>
<div align="center" style="font-size:1.4em"><a href="https://www.featool.com/get-featool/" class="btn btn--inverse">
<strong>Try FEATool Multiphysics</strong></a></div>
<p><br /></p>
<h2 id="references">References</h2>
<p><a name="1">[1]</a> S. Turek,
<a href="http://link.springer.com/book/10.1007%2F978-3-642-58393-3">Efficient Solvers for Incompressible Flow Problems: An Algorithmic and Computational Approach</a>,
Series: Lecture Notes in Computational Science and Engineering ,
Volume 6, Springer-Verlag, 1999.</p>
<p><a name="2">[2]</a> E. Bayraktar, O. Mierka, S. Turek,
<a href="http://www.mathematik.tu-dortmund.de/lsiii/cms/papers/BayraktarMierkaTurek2011.pdf">Benchmark Computations of 3D Laminar Flow Around a Cylinder with CFX, OpenFOAM and FeatFlow</a>,
International Journal of Computational Science and Engineering, 7, 3,
253-266, 2012.</p>
Fri, 17 Mar 2017 00:00:00 +0900
https://www.featool.com/news/2017/03/17/FEATool-v1p6-for-Easy-CFD-Simulations-in-Matlab.html
https://www.featool.com/news/2017/03/17/FEATool-v1p6-for-Easy-CFD-Simulations-in-Matlab.htmlFEATool Multiphysics VirtualBox VM Available<p>FEATool Multiphysics is now available as a VirtualBox Virtual Machine (VM) disk image to quickly get up and running and for easy installation on systems that do not natively support or has Octave or Matlab installed. The image can for instance be used on macOS systems for which the Octave GUI is unavailable. To use the image, first download and install <a href="https://www.virtualbox.org">VirtualBox</a>, set up a Linux (Ubuntu) VM system with for example 1 GB of RAM memory, lastly download and use the VDI image file from the link below. Starting the VM should quickly load Ubuntu 16.04 Linux with the low resource IceWM window manager. To launch Octave and start the FEATool GUI simply double click on the <em>FEATool Multiphysics</em> icon. Users who want to customize the image should note that the used username and password both are <em>featool</em>.</p>
<div align="center" style="font-size:1.4em"><a href="https://drive.google.com/open?id=0B-0RxBwwgDMBZnhROFFHdnpUekU" target="_blank" class="btn btn--inverse">
<strong>FEATool Multiphysics VirtualBox Linux VM Image</strong></a></div>
<p><br /></p>
Wed, 30 Nov 2016 00:00:00 +0900
https://www.featool.com/news/2016/11/30/FEATool-Multiphysics-Linux-VirtualBox-VM.html
https://www.featool.com/news/2016/11/30/FEATool-Multiphysics-Linux-VirtualBox-VM.html