<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>multiPhysicsFoam – Symmetry</title><link>https://multiphysicsfoam.com/tags/symmetry/</link><description>Recent content in Symmetry on multiPhysicsFoam</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://multiphysicsfoam.com/tags/symmetry/index.xml" rel="self" type="application/rss+xml"/><item><title>Docs: solidSymmetry</title><link>https://multiphysicsfoam.com/docs/user-guide/boundary-conditions/uncoupled-boundary-conditions/solidsymmetry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://multiphysicsfoam.com/docs/user-guide/boundary-conditions/uncoupled-boundary-conditions/solidsymmetry/</guid><description>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>&lt;code>solidSymmetry&lt;/code> is a symmetry-plane condition ported from the foam-extend
solid-mechanics toolbox (Cardiff, Tuković), where it is also known as
&lt;code>symmetryDisplacement&lt;/code>. It exists for two field types, both registered under
the same type name:&lt;/p>
&lt;ul>
&lt;li>&lt;code>solidSymmetryFvPatchVectorField&lt;/code>, intended for the total displacement &lt;code>D&lt;/code>
of a solid region (&lt;code>solidStVK&lt;/code>). It mirrors the near-wall displacement across
the plane, so the normal displacement on the patch is zero and the
tangential displacement is free. An optional second-order correction is
available.&lt;/li>
&lt;li>&lt;code>solidSymmetryFvPatchScalarField&lt;/code>, the scalar counterpart. It sets the patch
value to the corrected near-wall value (zero normal gradient).&lt;/li>
&lt;/ul>
&lt;p>Both classes derive from the stock &lt;code>symmetry&lt;/code> constraint
(&lt;code>symmetryFvPatchField&lt;/code>). They only replace &lt;code>snGrad()&lt;/code> and &lt;code>evaluate()&lt;/code>, so the
patch must be of mesh type &lt;code>symmetry&lt;/code>. The class keeps the matrix
coefficients (implicit part) of the stock condition.&lt;/p>
&lt;h2 id="mathematical-formulation">Mathematical Formulation&lt;/h2>
&lt;p>Let $\mathbf{n}$ be the patch unit normal, $\boldsymbol{\Delta}$ the patch delta
vector (face centre minus cell centre), $\delta = 1/\texttt{deltaCoeffs}$ the
cell-to-face distance, and $\mathbf{R} = \mathbf{I} - 2\,\mathbf{n}\mathbf{n}$
the reflection tensor. The non-orthogonal correction vector and the corrected
near-wall value are&lt;/p>
$$
\mathbf{k} = (\mathbf{I} - \mathbf{n}\mathbf{n}) \cdot \boldsymbol{\Delta},
\qquad
\mathbf{D}_P^{*} = \mathbf{D}_P + \mathbf{k} \cdot (\nabla \mathbf{D})_P
$$
&lt;h3 id="vector-field-first-order-default">Vector field, first order (default)&lt;/h3>
$$
\mathbf{D}_b = \tfrac{1}{2}\left(\mathbf{D}_P^{*} + \mathbf{R}\,\mathbf{D}_P^{*}\right)
= (\mathbf{I} - \mathbf{n}\mathbf{n})\,\mathbf{D}_P^{*},
\qquad
\left.\frac{\partial \mathbf{D}}{\partial n}\right|_b
= \frac{\mathbf{R}\,\mathbf{D}_P^{*} - \mathbf{D}_P^{*}}{2\,\delta}
= -\frac{(\mathbf{n}\cdot\mathbf{D}_P^{*})\,\mathbf{n}}{\delta}
$$
&lt;h3 id="vector-field-second-order-secondorder-yes">Vector field, second order (&lt;code>secondOrder yes&lt;/code>)&lt;/h3>
$$
\mathbf{D}_b = (\mathbf{I} - \mathbf{n}\mathbf{n}) \cdot
\left( \mathbf{D}_P^{*} + \tfrac{\delta}{2}\, \mathbf{n}\cdot(\nabla\mathbf{D})_P \right)
$$
$$
\left.\frac{\partial \mathbf{D}}{\partial n}\right|_b
= -\frac{2\,(\mathbf{n}\cdot\mathbf{D}_P^{*})\,\mathbf{n}}{\delta} - \mathbf{n}\left(\mathbf{n} \cdot \left[\mathbf{n}\cdot(\nabla\mathbf{D})_P\right]\right)
$$
&lt;p>The tangential part of the value is extrapolated over half a cell with the
mean of the zero face gradient and the cell gradient. The normal part of the
gradient is the one-sided second-order estimate
$2(\mathbf{D}_b - \mathbf{D}_P)\cdot\mathbf{n}/\delta - (\partial_n D_n)_P$.&lt;/p>
&lt;h3 id="scalar-field">Scalar field&lt;/h3>
&lt;p>A scalar is invariant under reflection, so $\mathbf{R}\,T = T$ and the
formulas above reduce to&lt;/p>
$$
T_b = T_P + \mathbf{k}\cdot(\nabla T)_P,
\qquad
\left.\frac{\partial T}{\partial n}\right|_b = 0
$$
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Symbol&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Unit&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>$\mathbf{D}$, $T$&lt;/td>
&lt;td>Patch field (vector / scalar)&lt;/td>
&lt;td>field unit&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$\mathbf{n}$&lt;/td>
&lt;td>Patch unit normal (&lt;code>patch().nf()&lt;/code>)&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$\boldsymbol{\Delta}$&lt;/td>
&lt;td>Patch delta vector (&lt;code>patch().delta()&lt;/code>)&lt;/td>
&lt;td>m&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$\delta$&lt;/td>
&lt;td>$1/$&lt;code>patch().deltaCoeffs()&lt;/code>&lt;/td>
&lt;td>m&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$\mathbf{k}$&lt;/td>
&lt;td>Non-orthogonal correction vector&lt;/td>
&lt;td>m&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$(\nabla\mathbf{D})_P$&lt;/td>
&lt;td>Cell-centre gradient from the registered field &lt;code>gradD&lt;/code>&lt;/td>
&lt;td>field unit/m&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>$(\nabla T)_P$&lt;/td>
&lt;td>Cell-centre gradient from the registered field &lt;code>grad(&amp;lt;field&amp;gt;)&lt;/code>&lt;/td>
&lt;td>field unit/m&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>Note on OpenFOAM.com.&lt;/strong> In OpenFOAM.com (v2512 and v2606),
&lt;code>fvPatch::delta()&lt;/code> returns the patch-normal delta
$\mathbf{n}(\mathbf{n}\cdot(\mathbf{C}_f-\mathbf{C}_P))$ for all non-coupled
patches. Then $\mathbf{k} \equiv \mathbf{0}$, $\mathbf{D}_P^{*} = \mathbf{D}_P$,
and the non-orthogonal correction does nothing. It was written for
foam-extend, where &lt;code>delta()&lt;/code> is the full $\mathbf{C}_f - \mathbf{C}_P$. With
the default first-order setting, the vector condition therefore gives exactly
the values and normal gradient of the stock &lt;code>symmetry&lt;/code> condition. The scalar
condition is equivalent to stock &lt;code>symmetry&lt;/code> / &lt;code>zeroGradient&lt;/code> for scalars.&lt;/p>
&lt;h2 id="implementation">Implementation&lt;/h2>
&lt;p>&lt;strong>Construction.&lt;/strong> The dictionary constructor calls the stock &lt;code>symmetry&lt;/code>
constructor. That constructor ignores &lt;code>value&lt;/code> and evaluates the field once
with the stock symmetry formula. The constructor then checks that the patch
is exactly a &lt;code>symmetryFvPatch&lt;/code> (&lt;code>isType&lt;/code>). Any other patch type, including
&lt;code>symmetryPlane&lt;/code>, stops the run with a &lt;code>FatalIOError&lt;/code>. The vector version
reads the optional &lt;code>secondOrder&lt;/code> switch and prints it. Both versions print
&amp;ldquo;Symmetry boundary condition with non-orthogonal correction&amp;rdquo;.&lt;/p>
&lt;p>&lt;strong>&lt;code>evaluate()&lt;/code>&lt;/strong> (called from &lt;code>correctBoundaryConditions()&lt;/code>):&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Calls &lt;code>updateCoeffs()&lt;/code> if needed. This is the base no-op.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Looks up the cell gradient on the patch.&lt;/p>
&lt;ul>
&lt;li>Vector: the &lt;code>volTensorField&lt;/code> named &lt;strong>&lt;code>gradD&lt;/code>&lt;/strong>, whatever the name of the
field the BC is attached to.&lt;/li>
&lt;li>Scalar: the &lt;code>volVectorField&lt;/code> named &lt;strong>&lt;code>grad(&amp;lt;fieldName&amp;gt;)&lt;/code>&lt;/strong>, e.g.
&lt;code>grad(T)&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>The lookup is mandatory. If the field is not registered on the mesh, the
run stops with a fatal error.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Builds $\mathbf{D}_P^{*}$ and assigns the patch value with the formula
above.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Vector only: calls the base &lt;code>evaluate()&lt;/code>, which resets the &lt;code>updated&lt;/code> flag.
The scalar version does not call it.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>&lt;code>snGrad()&lt;/code>&lt;/strong> returns the normal gradient above. It is used wherever the
patch gradient is requested explicitly. The matrix coefficients are inherited
from the stock &lt;code>transform&lt;/code>/&lt;code>basicSymmetry&lt;/code> implementation: for vectors the
implicit diagonal is $|n_i|$ per component. Because
&lt;code>gradientBoundaryCoeffs()&lt;/code> is &lt;code>snGrad() - gradientInternalCoeffs()·D_P&lt;/code>, the
overridden &lt;code>snGrad()&lt;/code> (including the second-order term) enters
&lt;code>fvm::laplacian&lt;/code> as an explicit source. For scalars, the inherited
coefficients are those of a zero-gradient condition.&lt;/p>
&lt;p>&lt;strong>In &lt;code>solidStVK&lt;/code>.&lt;/strong> The momentum equation uses
&lt;code>fvm::laplacian(impKf, D, &amp;quot;laplacian(DD,D)&amp;quot;)&lt;/code>, which picks up the coefficients
above. &lt;code>gradD = fvc::grad(D)&lt;/code> is recomputed in &lt;code>postSolve()&lt;/code> from the patch
values set in &lt;code>evaluate()&lt;/code>. &lt;code>solidStVK&lt;/code> registers &lt;code>gradD&lt;/code>, so the vector BC
works on its &lt;code>D&lt;/code> field. It also works on any other vector field of that
region, but it always uses &lt;code>gradD&lt;/code>.&lt;/p>
&lt;h2 id="dictionary-entries">Dictionary Entries&lt;/h2>
&lt;p>Vector version:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Keyword&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Required&lt;/th>
&lt;th>Default&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>type&lt;/code>&lt;/td>
&lt;td>&lt;code>solidSymmetry&lt;/code>&lt;/td>
&lt;td>yes&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>secondOrder&lt;/code>&lt;/td>
&lt;td>Second-order correction of value and normal gradient (&lt;code>Switch&lt;/code>)&lt;/td>
&lt;td>no&lt;/td>
&lt;td>&lt;code>false&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>patchType&lt;/code>&lt;/td>
&lt;td>Generic &lt;code>fvPatchField&lt;/code> keyword, read by the stock base class&lt;/td>
&lt;td>no&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>value&lt;/code>&lt;/td>
&lt;td>Not read. The initial value comes from the stock symmetry evaluation. Written on output.&lt;/td>
&lt;td>no&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Scalar version:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Keyword&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Required&lt;/th>
&lt;th>Default&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>type&lt;/code>&lt;/td>
&lt;td>&lt;code>solidSymmetry&lt;/code>&lt;/td>
&lt;td>yes&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>patchType&lt;/code>&lt;/td>
&lt;td>Generic &lt;code>fvPatchField&lt;/code> keyword&lt;/td>
&lt;td>no&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>value&lt;/code>&lt;/td>
&lt;td>Not read (see above). Written on output.&lt;/td>
&lt;td>no&lt;/td>
&lt;td>–&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The scalar version does not read &lt;code>secondOrder&lt;/code>.&lt;/p>
&lt;p>Required registered fields:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Field&lt;/th>
&lt;th>Type&lt;/th>
&lt;th>Needed by&lt;/th>
&lt;th>Provided by&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>gradD&lt;/code>&lt;/td>
&lt;td>&lt;code>volTensorField&lt;/code>&lt;/td>
&lt;td>vector version&lt;/td>
&lt;td>&lt;code>solidStVK&lt;/code>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>grad(&amp;lt;fieldName&amp;gt;)&lt;/code>&lt;/td>
&lt;td>&lt;code>volVectorField&lt;/code>&lt;/td>
&lt;td>scalar version&lt;/td>
&lt;td>no shipped region type&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="usage">Usage&lt;/h2>
&lt;p>The mesh patch must be of type &lt;code>symmetry&lt;/code> (e.g. &lt;code>symmetry symmetry (...)&lt;/code> in
&lt;code>blockMeshDict&lt;/code>). From
&lt;code>tutorials/fluidStructureInteraction/beamInCrossFlow/0/solid/orig/partitioned/D&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">symmetry
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> type solidSymmetry;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> patchType symmetry;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> value uniform (0 0 0);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With the second-order correction:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">symmetry
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> type solidSymmetry;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> secondOrder yes;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> value uniform (0 0 0);
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For other fields of the solid region on the same patch, the tutorials use the
stock condition (e.g. &lt;code>T&lt;/code> in &lt;code>heatedBeamInCrossFlow&lt;/code>: &lt;code>type symmetry;&lt;/code>).&lt;/p>
&lt;h2 id="known-limitations">Known Limitations&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Non-orthogonal correction has no effect in OpenFOAM.com.&lt;/strong> The patch delta
is patch-normal, so $\mathbf{k} = \mathbf{0}$ (see the note above). With
&lt;code>secondOrder no&lt;/code>, the vector BC is numerically identical to stock &lt;code>symmetry&lt;/code>.
It still needs &lt;code>gradD&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Hard-coded gradient name (vector).&lt;/strong> The vector version always reads
&lt;code>gradD&lt;/code>. It is only usable in a region that registers a &lt;code>volTensorField&lt;/code>
named &lt;code>gradD&lt;/code>, i.e. &lt;code>solidStVK&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Scalar version needs &lt;code>grad(&amp;lt;field&amp;gt;)&lt;/code>.&lt;/strong> No compiled region type registers
a &lt;code>volVectorField&lt;/code> with that name. Unless something else in the case
provides it, the scalar BC fails on its first evaluation. Because it is
equivalent to the stock condition in OpenFOAM.com, use &lt;code>symmetry&lt;/code> for
scalar fields instead.&lt;/li>
&lt;li>&lt;strong>Patch type &lt;code>symmetry&lt;/code> only.&lt;/strong> &lt;code>symmetryPlane&lt;/code> and other patch types are
rejected.&lt;/li>
&lt;li>&lt;strong>&lt;code>value&lt;/code> is ignored on read.&lt;/strong> The initial patch value is always the stock
symmetry evaluation of the internal field.&lt;/li>
&lt;/ul>
&lt;h2 id="tutorials">Tutorials&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Tutorial&lt;/th>
&lt;th>Description&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;code>tutorials/fluidStructureInteraction/beamInCrossFlow&lt;/code>&lt;/td>
&lt;td>&lt;code>D&lt;/code> of the &lt;code>solidStVK&lt;/code> solid on the &lt;code>symmetry&lt;/code> patch (first order).&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;code>tutorials/fluidStructureInteraction/heatedBeamInCrossFlow&lt;/code>&lt;/td>
&lt;td>Same &lt;code>D&lt;/code> setup in a thermo-FSI case. &lt;code>T&lt;/code> on the same patch uses stock &lt;code>symmetry&lt;/code>.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>No tutorial uses the scalar version or &lt;code>secondOrder yes&lt;/code>.&lt;/p>
&lt;h2 id="references">References&lt;/h2>
&lt;ul>
&lt;li>Cardiff, P., Karač, A., De Jaeger, P., Jasak, H., Nagy, J., Ivanković, A., Tuković, Ž., &lt;em>An open-source finite volume toolbox for solid mechanics and fluid-solid interaction simulations&lt;/em>, arXiv:1808.10736, 2018.&lt;/li>
&lt;li>Alkfri, A., Habes, C., Marschall, H., &lt;em>multiRegionFoam: A Unified Multiphysics Framework for Multi-Region Coupled Continuum-Physical Problems&lt;/em>, Engineering with Computers, 2023.
DOI: &lt;a href="https://doi.org/10.1007/s00366-024-01974-4">10.1007/s00366-024-01974-4&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>