Skip to content
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
3 changes: 1 addition & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Exodus = "f57ae99e-f805-4780-bdca-96e224be1e5a"
FiniteElementContainers = "d08262e4-672f-4e7f-a976-f2cea5767631"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
7 changes: 7 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ makedocs(;
),
pages=[
"Home" => "index.md",
"Tutorial" => [
"1 Poisson Equation" => "tutorials/1_poisson_equation.md",
"2 Advection-Diffusion Equation" => "tutorials/2_advection_diffusion_equation.md",
"3 Coupled Problem" => "tutorials/3_coupled_problem.md",
"4 Transient Problem" => "tutorials/4_transient_problem.md",
"5 Solid Mechanics" => "tutorials/5_solid_mechanics.md"
],
"Assemblers" => "assemblers.md",
"Boundary Conditions" => "boundary_conditions.md",
"DofManager" => "dof_manager.md",
Expand Down
7 changes: 7 additions & 0 deletions docs/src/assemblers.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ This section describes the assemblers that are currently available and their abs

All assemblers must possess at minimum a ```DofManager```.

The assemblers possess all the baggage to use the internal method ```sparse!``` in ```SparseArrays.jl```. This method allows for a zero allocation instantiation of a ```SparseMatrixCSC``` type on the CPU. There are also methods available to ease in the conversion of CSC types and other sparse types such as CSR.

On the GPU, however, this type is first converted to an appropriate COO matrix type on the desired backend. There is unfortunately not a unified sparse matrix API in ```julia``` for GPUs, so we implement this functionality in package extensions. On CUDA, for example, the operational sequence to get a ```CuSparseMatrixCSC``` is to first
sort the COO ```(row, col, val)``` triplets so they are ordered by row and then column. Then a ```CuSparseMatrixCOO``` type is created and converted to a ```CuSparseMatrixCSC``` type via ```CUDA.jl``` methods. An identical approach is taken for RocM types.

NOTE: This is one of the most actively developed areas of the package. Please use caution with any method beginning with a "_" as these are internal methods that will change without notice.

## Matrices
```@autodocs
Modules = [FiniteElementContainers]
Expand Down
36 changes: 34 additions & 2 deletions docs/src/boundary_conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,55 @@ and sideset ```sset_1``` with a zero function as follows.
```@repl
using FiniteElementContainers
bc_func(x, t) = 0.
bc = DirichletBC(:u, :sset_1, bc_func)
bc = DirichletBC(:u, bc_func; sideset_name = :sset_1)
```
Internally this is eventually converted in a ```DirichletBCContainer```

### API
Dirichlet bcs can be setup on element blocks, nodesets, or sidesets. The appropriate keyword argument needs to be supplied with the ```DirichletBC``` constructor.

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["DirichletBCs.jl"]
Order = [:type, :function]
```

# NeumannBC
We can setup Neumann bcs on a variable ```u``` and sideset ```sset_1``` with a
simple constant function as follows
```@repl
using FiniteElementContainers
using StaticArrays
bc_func(x, t) = SVector{1, Float64}(1.)
bc = NeumannBC(:u, :sset_1, bc_func)
```
Note that in comparison to the dirichlet bc example above, the function in this case returns a ```SVector``` of size 1. This will hold for any variable ```u``` that has a single dof. For vector variables, e.g. a traction vector in continuum mechanics, would need something like
```@repl
using FiniteElementContainers
using StaticArrays
ND = 2
bc_func(x, t) = SVector{ND, Float64}(1.)
bc = NeumannBC(:u, :sset_1, bc_func)
```
where ```ND``` is the number of dimensions.

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["NeumannBCs.jl"]
Order = [:type, :function]
```

# PeriodicBC
Periodic boundary conditions are very much a work in progress. There is currently
some machinary to implement a Lagrange multiplier approach.

Stay tuned.

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["PeriodicBCs.jl"]
Order = [:type, :function]
```

## Boundary Condition Implementation Details
```@autodocs
Modules = [FiniteElementContainers]
Expand Down
9 changes: 5 additions & 4 deletions docs/src/dof_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ mesh = UnstructuredMesh("../../test/poisson/poisson.g")
V = FunctionSpace(mesh, H1Field, Lagrange)
u = VectorFunction(V, :u)
t = ScalarFunction(V, :t)
f = FiniteElementContainers.GeneralFunction(u, t)
```
Now we can supply these variables to the ```DofManager``` which takes varargs as inputs
```@repl dof
dof = DofManager(u, t)
dof = DofManager(f)
```
The print methods for this struct show simple metadata about the current dofs for each possible function space.

Expand All @@ -33,10 +34,10 @@ field = create_unknowns(dof)
We can create fields of the right size from the ```DofManager``` with the following methods

```@repl dof
field = create_field(dof, H1Field)
field = create_field(dof)
```

These methods take the backed of ```dof``` into account to ensure that the fields or unknowns produced are on the same device, e.g. CPU/GPU if ```dof``` is on the CPU/GPU.
These methods take the backend of ```dof``` into account to ensure that the fields or unknowns produced are on the same device, e.g. CPU/GPU if ```dof``` is on the CPU/GPU.

This struct is created with all dofs initially set as unknown. To modify the unknowns we can do the following

Expand All @@ -45,4 +46,4 @@ This struct is created with all dofs initially set as unknown. To modify the unk
Modules = [FiniteElementContainers]
Pages = ["DofManagers.jl"]
Order = [:type, :function]
```
```
11 changes: 3 additions & 8 deletions docs/src/fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ Fields serve as loose wrappers around ```AbstractArray``` subtypes such that the
All fields are subtypes of the abstract type ```AbstractField```
```@repl
using FiniteElementContainers
AbstractField
FiniteElementContainers.AbstractField
```

## Example - H1Field a.k.a. NodalField
We can set up a ```H1Field``` in one of two ways. The simplest constructor form can be used as follows
```@repl h1field
using FiniteElementContainers
field = H1Field(rand(2, 10), (:field_1, :field_2))
field = H1Field(rand(2, 10))
```
This is stored in a vectorized way as can be seen above
```@repl h1field
field.vals
field.data
```
Fields can be indexed like regular arrays, e.g.
```@repl h1field
Expand All @@ -30,11 +30,6 @@ field[1, :]
```
etc.

But they can also be indexed by the symbols provided during construction
```@repl h1field
field[:field_1]
```

## Abstract type
The base type for fields is the ```AbstractField``` abstract type.
```@autodocs
Expand Down
9 changes: 4 additions & 5 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@ of computational solid mechanics in mind where meshes deform,
there's path dependence, there's contact between bodies, there are potentially heterogeneous material properties, and other challenges.

If you're primarily interested in writing FEM applications for e.g.
the Poisson equation or heat equation, there's likely more efficient packages (e.g. ```Gridap``` or ```Ferrite```) out there for this purpose in terms of memory and computational efficiency.
the Poisson equation or heat equation, there's likely other FEM packages with less mental overhead out there for this purpose.

However, if you need to solve problems with multiple material models, meshes where
there are mixed elements types, etc. this is likely the only julia package
at the time of writing this that supports such capabilities.
there are mixed elements types, etc. this is the package for you.

Inspiration for the software design primarily comes from ```fenics``` and ```MOOSE```.
We've specifically designed the interface to get around all the shortcomings of ```fenics```
(e.g. boundary conditions are a pain, mixed element types a plain, different blocks are pain
(e.g. boundary conditions are a pain, mixed element types are pain, different blocks are pain
etc.)

Our goal is also to ensure all of our methods are next generation hardware capable. This
means not only supporting things on CPUs but also GPUs (and that doesn't just mean NVIDIA).
means not only supporting things on CPUs but also GPUs (and that doesn't just mean NVIDIA). The package is regularly tested against CUDA and RocM aware hardware to ensure all the types, methods, etc. work on CPUs and GPUs. Additionally, we test against Linux, MacOS, and Windows so in theory this should run on any personal computer out of the box. High performance computers are another story.
30 changes: 26 additions & 4 deletions docs/src/meshes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,35 @@ CurrentModule = FiniteElementContainers
```

# Meshes
Meshes in ```FiniteElementContainers``` leverage a very abstract interface. No
single mesh format is directly supported in the main src code but rather different
mesh types are relegated to package extensions. Currently, only an ```Exodus``` package
extension is supported but others could be readily supported.
Meshes in ```FiniteElementContainers``` leverage a very abstract interface. Currently, only an ```Exodus``` interface is directly supported within the main package but others could be readily supported through package extensions which we are planning on.

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["Meshes.jl"]
Order = [:type, :function]
```

# Structured Meshes
Simple structured meshes on rectangles or parallepipeds can be create through ```StructuredMesh``` mesh type.

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["StructuredMesh.jl"]
Order = [:type, :function]
```

# Unstructured Meshes
Unstructured meshes (e.g. those read from a file created by a mesher) can be created with the following mesh type

```@autodocs
Modules = [FiniteElementContainers]
Pages = ["UnstructuredMesh.jl"]
Order = [:type, :function]
```

# Exodus interface API
```@autodocs
Modules = [FiniteElementContainers]
Pages = ["Exodus.jl"]
Order = [:type, :function]
```
Loading
Loading