Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc : how to build custom operator #57

Merged
merged 9 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ makedocs(;
"api/dof/dof.md",
"api/output/vtk.md",
],
"How to..." => "howto/howto.md",
"How to... (FAQ)" => "howto/howto.md",
],
)

Expand Down
6 changes: 6 additions & 0 deletions docs/src/assets/sketch/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.aux
*.fls
*.log
*.synctex.gz
*.fdb_latexmk
*.pdf
Binary file added docs/src/assets/sketch/sketch-mapping.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions docs/src/assets/sketch/sketch-mapping.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
\documentclass[tikz,convert={density=600,size=1080x800,outext=.png}]{standalone} % we can also output .svg
\usetikzlibrary{backgrounds}
\usetikzlibrary{arrows.meta}
\usepackage{amsmath}
\newcommand{\bo}[1]{\boldsymbol{#1}}
\tikzset{background fill/.style={background rectangle/.style={fill=#1},show background rectangle}}

\begin{document}
\begin{tikzpicture}[background fill=white]
% Background rectangle
% \fill[color=red] (-1,-1) rectangle (10,3);

% Globals
\pgfmathsetmacro{\refXMin}{0}
\pgfmathsetmacro{\refXMax}{2}

% Ref quad
\coordinate (REF_SW) at (\refXMin, \refXMin);
\coordinate (REF_NE) at (\refXMax, \refXMax);
\draw[color=black] (REF_SW) rectangle (REF_NE);

\pgfmathsetmacro{\x}{\refXMin};
\pgfmathsetmacro{\y}{0};
\coordinate (A) at (\x,\y);
\node[font=\tiny] at (A) {$\times$};
\node[below, font=\tiny] at (A) {$(-1,-1)$};

\pgfmathsetmacro{\x}{\refXMax};
\pgfmathsetmacro{\y}{0};
\coordinate (B) at (\x,\y);
\node[font=\tiny] at (B) {$\times$};
\node[below, font=\tiny] at (B) {$(1,-1)$};

\pgfmathsetmacro{\x}{\refXMax};
\pgfmathsetmacro{\y}{\refXMax};
\coordinate (C) at (\x,\y);
\node[font=\tiny] at (C) {$\times$};
\node[above, font=\tiny] at (C) {$(1,1)$};

\pgfmathsetmacro{\x}{\refXMin};
\pgfmathsetmacro{\y}{\refXMax};
\coordinate (D) at (\x,\y);
\node[font=\tiny] at (D) {$\times$};
\node[above, font=\tiny] at (D) {$(-1,1)$};

\pgfmathsetmacro{\x}{\refXMin - 0.7}
\pgfmathsetmacro{\y}{\refXMin - 0.6}
\draw[-{Latex[length=1mm, width=1mm]}] (\x,\y) -- ++(0.4, 0) node[below] {\tiny $\xi$};
\draw[-{Latex[length=1mm, width=1mm]}] (\x,\y) -- ++(0, 0.4) node[left] {\tiny $\eta$};


% Map line
\pgfmathsetmacro{\arrowWidth}{4}
\pgfmathsetmacro{\arrowMarginX}{0.5}
\pgfmathsetmacro{\x}{\refXMax+\arrowMarginX}
\pgfmathsetmacro{\y}{(\refXMax-\refXMin)/2}
\coordinate (LINE_W) at (\x, \y);
\pgfmathsetmacro{\x}{\x+\arrowWidth}
\coordinate (LINE_E) at (\x, \y);
\draw[->] (LINE_W) to[bend left = 10] node[midway, above]{
$\bo{x} = F(\bo{\xi}) = \sum_{i=1}^N \hat{\lambda}_i(\bo{\xi})\bo{M}_i$
} (LINE_E);

% Physical quad
\pgfmathsetmacro{\x}{\refXMax + 2*\arrowMarginX + \arrowWidth};
\pgfmathsetmacro{\y}{0};
\coordinate (A) at (\x,\y);
\node[font=\tiny] at (A) {+};
\node[below, font=\tiny] at (A) {$M_1$};

\pgfmathsetmacro{\x}{\x + 2};
\pgfmathsetmacro{\y}{\y + 1};
\coordinate (B) at (\x,\y);
\node[font=\tiny] at (B) {+};
\node[right, font=\tiny] at (B) {$M_2$};

\pgfmathsetmacro{\x}{\x + 0.3};
\pgfmathsetmacro{\y}{\y + 1.5};
\coordinate (C) at (\x,\y);
\node[font=\tiny] at (C) {+};
\node[right, font=\tiny] at (C) {$M_3$};

\pgfmathsetmacro{\x}{\x - 1.5};
\pgfmathsetmacro{\y}{\y - 0.6};
\coordinate (D) at (\x,\y);
\node[font=\tiny] at (D) {+};
\node[left, font=\tiny] at (D) {$M_4$};

\pgfmathsetmacro{\x}{\x + 0.5};
\pgfmathsetmacro{\y}{\y - 0.5};
\coordinate (E) at (\x,\y);
\node[font=\tiny] at (E) {+};
\node[below, font=\tiny] at (E) {$M_9$};

\draw[font=\tiny] (A) to[bend right = 15] node[midway] {+} node[midway,below] {$M_{5}$} (B) to[bend left = 15] node[midway] {+} node[midway,right] {$M_{6}$} (C) to[bend right = 20] node[midway] {+} node[midway,above] {$M_{7}$} (D) to[bend left=15] node[midway] {+} node[midway,left] {$M_{8}$} cycle;

\pgfmathsetmacro{\x}{\refXMax + 2*\arrowMarginX + \arrowWidth + 2}
\pgfmathsetmacro{\y}{0 - 0.6}
\draw[-{Latex[length=1mm, width=1mm]}] (\x,\y) -- ++(0.4, 0) node[below] {\tiny $x$};
\draw[-{Latex[length=1mm, width=1mm]}] (\x,\y) -- ++(0, 0.4) node[left] {\tiny $y$};

\end{tikzpicture}
\end{document}
39 changes: 35 additions & 4 deletions docs/src/howto/howto.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,48 @@
# How to
# How to... (FAQ)

To be completed to answer common user questions.
## Build your own `LazyOperator`
Imagine that you want some kind of function (~operator) that has a different behavior depending on the cell (or face) it is applied to. The `PhysicalFunction` won't do the job since it is assumed that the provided function applies the same way in all the different cells. What you want is a `LazyOperator`. Here is how to build a custom one.

For the example, let's say that you want an operator whose action is to multiply `x`, the evaluated point, by the index of the cell surrounding `x`. Start importing some Bcube material and by declaring a type corresponding to this operator:
```julia
using Bcube
import Bcube: CellInfo, CellPoint, get_coord
struct DummyOperator <: Bcube.AbstractLazy end
```

Then, specify what happens when `Bcube` asks for the restriction of your operator in a given cell. This is done before applying it to any point. In most case, you don't want to do anything special, so just return the operator itself:
```julia
Bcube.materialize(op::DummyOperator, ::CellInfo) = op
```

Now, specify what to return when `Bcube` wants to apply this operator on a given point in a cell. As said earlier, we want it the return the point, multiplied by the cell index (but it could be anything you want):
```julia
function Bcube.materialize(
::DummyOperator,
cPoint::CellPoint,
)
x = get_coord(cPoint)
cInfo = Bcube.get_cellinfo(cPoint)
index = Bcube.cellindex(cInfo)
return x * index
end
```

That's it! To see your operator in action, take a look at the related [section](@ref Evaluate-a-LazyOperator-on-a-specific-point).

In this short example, note that we restricted ourselves to `CellPoint` : the `DummyOperator` won't be applicable to a face. To do so, you have to specialize the materialization on a `Side` of a `FaceInfo` and on a `Side` of a `FacePoint`. Checkout the source code for `TangentialProjector` to see this in action. Besides, the `CellPoint` is parametrized by a `DomainStyle`, allowing to specify different behavior depending on if your operator is applied to a point in the `ReferenceDomain` or in the `PhysicalDomain`.

## Evaluate a `LazyOperator` on a specific point
Suppose that you have built a mesh and defined a `LazyOperator` on this mesh and you want, for debug purpose, evaluate this operator on a point of your choice. First, let's define our example operator:
```julia
using Bcube
mesh = circle_mesh(10)
op = Bcube.TangentialOperator()
op = Bcube.TangentialProjector()
```
Then, let's define the point where we want to evaluate this operator. For this, we need to create a so-called `CellPoint`. It's structure is quite basic : it needs the coordinates, the mesh cell owning these coordinates, and if the coordinates are given in the `ReferenceDomain` or in the `PhysicalDomain`. Here, we will select the first cell of the mesh, and choose the coordinates `[0.5]` (recall that we are in 1D, hence this vector of one component):
```julia
cInfo = Bcube.CellInfo(mesh, 1)
cPoint = Bcube.CellPoint(SA[0.5], cInfo, Bcube.ReferenceDomain())
cPoint = Bcube.CellPoint([0.5], cInfo, Bcube.ReferenceDomain())
```
Now, they are always two steps to evaluate a `LazyOperator`. First we need to materialize it on a cell (or a face) and then to evaluate it on a cell-point (or face-point). The materialization on a cell does not necessarily triggers something, it depends on the operator. For instance, an analytic function will not have a specific behaviour depending on the cell; however a shape function will.
```julia
Expand Down
2 changes: 2 additions & 0 deletions docs/src/manual/geometry.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ F(\xi) = \sum_{i=1}^n \hat{\lambda}_i(\xi)M_i
```

where $(\lambda)_i$ are the Lagrange polynomials whose order matches the element order.

![sketch](../assets/sketch/sketch-mapping.png)
4 changes: 2 additions & 2 deletions docs/src/manual/integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ To compute an integral on a geometrical element, for instance a curved element,

where we recall that $$F$$ is the reference to physical mapping and $$J$$ is the determinant of the jacobian matrix of this mapping. Depending on the shape and element order, this determinant is either hard-coded or computed with `ForwardDiff`.

Now, to compute the right side, i.e the integral on the reference shape, quadrature rules are applied:
Now, to compute the right side, i.e the integral on the reference shape, quadrature rules are applied to $\hat{g} = g \circ F$:

```math
\int_{\hat{\Omega}} g(\hat{x}) \mathrm{\,d} \hat{\Omega} = \sum_{i =1}^{N_q} \omega_i g(\hat{x}_i)
\int_{\hat{\Omega}} \hat{g}(\hat{x}) \mathrm{\,d} \hat{\Omega} = \sum_{i =1}^{N_q} \omega_i \hat{g}(\hat{x}_i)
```

A specific procedure is applied to compute integrals on a face of a cell (i.e a surfacic integral on a face of a volumic element).
2 changes: 1 addition & 1 deletion src/mesh/entity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ struct isVolumic <: TopologyStyle end
"""
topology_style(::AbstractEntityType{topoDim}, ::Node{spaceDim, T}) where {topoDim, spaceDim, T}
topology_style(::AbstractEntityType{topoDim}, ::AbstractArray{Node{spaceDim, T}, N}) where {spaceDim, T, N, topoDim}
)


Indicate the `TopologyStyle` of an entity of topology `topoDim` living in space of dimension `spaceDim`.
"""
Expand Down
Loading