Skip to content
Open
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/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ SimplexGridFactory = "57bfcd06-606e-45d6-baf4-4ba06da0efd5"
Triangulate = "f7e6ffb2-c36d-4f8f-a77e-16e897189344"

[compat]
Documenter = "1"
Documenter = "1.3"
julia = "1.9"
ExampleJuggler = "2"
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ function mkdocs()
repo = "https://github.com/j-fu/ExtendableGrids.jl",
pages = [
"Home" => "index.md",
"extendablegrid.md",
"adjacency.md",
"vectorofconstants.md",
"typehierarchy.md",
"elementgeometry.md",
"shape_specs.md",
"coordinatesystem.md",
"extendablegrid.md",
"subgrid.md",
"more.md",
"voronoi.md",
Expand Down
19 changes: 11 additions & 8 deletions docs/src/adjacency.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
```@meta
CollapsedDocStrings = true
```
# Adjacency

This handles adjacency matrices between entities of polyhedral complexes, e.g.
Expand All @@ -22,19 +25,19 @@ From these ideas we develop the following interface for an adjacency a.
In order to avoid name confusion, we introduce the following notation which
should be consistent with the use in assembly loops.

source: source of adjacency link
target: target of adjacency link
source: source of adjacency link
target: target of adjacency link

E.g. the cell-node adjacency for FEM assembly links a number of
cells with a collection of nodes. The cells are the sources,
and the targets are the nodes.

getindex(a,i,isource) aka a[i,isource]: return i-th target of source j
num_sources(a): overall number of sources, e.g. number of cells
num_targets(a): overall number of targets
num_targets(a,isource): number of targets for source given by isource
num_links(a): number of links aka nonzero entries of adjacency matrix
show(a): print stuff
getindex(a,i,isource) aka a[i,isource]: return i-th target of source j
num_sources(a): overall number of sources, e.g. number of cells
num_targets(a): overall number of targets
num_targets(a,isource): number of targets for source given by isource
num_links(a): number of links aka nonzero entries of adjacency matrix
show(a): print stuff

Further API ideas:
- Convert between Matrix and Variable target stuff using 0 entries as "padding"
Expand Down
64 changes: 61 additions & 3 deletions docs/src/extendablegrid.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Extendable grid


An ExtendableGrid in form of a dictionary with types as keys and type stable value access.
This means that grid components are accessed as dict entries, e.g. `grid[Coordinates]` .
The rationale of this approach is explained [here](tdict.md).
This means that grid components are accessed as dict entries, e.g. `grid[Coordinates]`.
The rationale behind this decision is described [below](@ref TDict).

```@contents
Pages = ["extendablegrid.md"]
Depth = 2:6
```

## Notations
## Extendable grid notations
A grid is assumed to be a subset of components of a polyhedral complex in d-dimensional space.
We distinguish the following element classes characterized by their dimension:

Expand Down Expand Up @@ -78,3 +84,55 @@ Modules = [ExtendableGrids]
Pages = ["extendablegrid.jl"]
```



## [The TDict interface pattern](@id TDict)

Here we describe the idea behind the data structure used in this package.
TDict means: extendable containers with type stable content access and lazy content creation via the Julia type system.

### Problem to be addressed

In certain contexts it is desirable to use containers with core components
which are user extendable and allow for type stable component acces. Moreover,
some components are necessary on demand only, so they should be created lazily.
Furthermore, there should be a kind of safety protocol which prevents errors
from typos in component names etc.

Julia default data structures do not provide these properties.

#### `struct`
- Julia structs with proper field type annotations guarantee type stability
- Julia structs are not extendable, fields and their types are fixed upon definition
- If we don't fix types of struct fields they become Any and a source
for type instability
- The situation could be fixed if `getfield` could be overloaded but it cant't

#### `Dict`
- Plain Dicts with flexible value types are a source of type instability
- Dicts with strings as keys needs a meta protocol to handle
semantics of keys which at the end probably hinges on string comparison which
will make things slow
- Dicts with symbols as keys still need this meta protocol
- Same for the implementation of a lazy evaluation protocol
- If a dict contains components of different types, component access will not be typestable

### Proposed solution:

Harness the power of the Julia type system:
- Use a struct containing a Dict with DataType as keys. Every key is a type.
- Use type hierarchies to manage different value classes
- Use the type system to dispatch between `getindex`/`setindex!` methods for keys
- Extension requires declaring new types, keys can be only existing types almost removing
typos as sources for errors
- Lazy extension is managed bye an `instantiate` method called by `getindex` if necessary
- Component access is made type stable by type dispatched`getindex` methods
- Component insertion is made safe by having `setindex!` calling a `veryform` method

#### Pros
See above ...

#### Cons
- Implemented using a Dict, so access is inherently slower than access to a component
of a struct. Therefore it is not well suited for inner loops.

5 changes: 4 additions & 1 deletion docs/src/gmsh.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ This functionality is in beta stage.
Breaking changes for this API are considered non-breaking for the package.
Therefore, these functions are not exported yet.


```@contents
Pages = ["gmsh.md"]
Depth = 2:4
```

## API
These methods become available via a package extension which is loaded together with
Expand Down
3 changes: 3 additions & 0 deletions docs/src/gridconstructors.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

```@docs
simplexgrid
XCoordinates
YCoordinates
ZCoordinates
glue
```

Expand Down
13 changes: 6 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
````@eval
using Markdown
Markdown.parse("""
$(read("../../README.md",String))
""")
````

```@docs
ExtendableGrids
```
```@contents
Depth=5
```
50 changes: 0 additions & 50 deletions docs/src/tdict.md

This file was deleted.

5 changes: 5 additions & 0 deletions src/ExtendableGrids.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""
ExtendableGrids

$(read(joinpath(@__DIR__,"..","README.md"),String))
"""
module ExtendableGrids

using DocStringExtensions
Expand Down
15 changes: 15 additions & 0 deletions src/simplexgrid.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,23 @@ end


##########################################################

"""
$(TYPEDEF)
X coordinates of simplex grid derived from tensor product
"""
abstract type XCoordinates <: AbstractGridFloatArray1D end

"""
$(TYPEDEF)
Y coordinates of simplex grid derived from tensor product
"""
abstract type YCoordinates <: AbstractGridFloatArray1D end

"""
$(TYPEDEF)
Z coordinates of simplex grid derived from tensor product
"""
abstract type ZCoordinates <: AbstractGridFloatArray1D end


Expand Down
2 changes: 0 additions & 2 deletions test/gmsh.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using Gmsh: gmsh

# Add this later as an verbosity option
# gmsh.option.setNumber("General.Terminal", 0)
# gmsh.option.setNumber("General.Verbosity", 0)
Expand Down
28 changes: 20 additions & 8 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
using Test, Aqua
using ExampleJuggler
using Gmsh: gmsh

using ExtendableGrids, SHA

using AbstractTrees, StatsBase

if isdefined(Docs,:undocumented_names) # 1.11
@testset "undocumented names" begin
undocnames=Docs.undocumented_names(ExtendableGrids)
@test isempty(undocnames)
end
end


@testset "Aqua" begin
Aqua.test_ambiguities([ExtendableGrids, Base, Core], exclude=[view, ==, StatsBase.TestStat, copyto!])
Aqua.test_unbound_args(ExtendableGrids)
Aqua.test_undefined_exports(ExtendableGrids)
Aqua.test_project_extras(ExtendableGrids)
Aqua.test_stale_deps(ExtendableGrids,ignore=[:Requires,:Bijections])
Aqua.test_deps_compat(ExtendableGrids)
Aqua.test_piracies(ExtendableGrids,treat_as_own=[AbstractTrees.children])
Aqua.test_persistent_tasks(ExtendableGrids)
# not sure why copyto! and StatsBase are popping up here
Aqua.test_ambiguities([ExtendableGrids, Base, Core], exclude=[view, ==, StatsBase.TestStat, copyto!])
Aqua.test_unbound_args(ExtendableGrids)
Aqua.test_undefined_exports(ExtendableGrids)
Aqua.test_project_extras(ExtendableGrids)
Aqua.test_stale_deps(ExtendableGrids,ignore=[:Requires,:Bijections])
Aqua.test_deps_compat(ExtendableGrids)

# Guilty of pirating: AbstracTrees.children(::Type)...
Aqua.test_piracies(ExtendableGrids,treat_as_own=[AbstractTrees.children])
Aqua.test_persistent_tasks(ExtendableGrids)
end


Expand Down