Coder Social home page Coder Social logo

ferrite-fem / ferrite.jl Goto Github PK

View Code? Open in Web Editor NEW
337.0 337.0 86.0 109.13 MB

Finite element toolbox for Julia

Home Page: https://ferrite-fem.github.io

License: Other

Julia 99.91% Makefile 0.09%
finite-elements hacktoberfest julia julialang partial-differential-equations

ferrite.jl's People

Contributors

3rb16 avatar abdalazezahmed avatar abdelrahman912 avatar argeht avatar bhaveshshrimali avatar blaszm avatar dependabot[bot] avatar drollin avatar edljk avatar femtocleaner[bot] avatar fredrikekre avatar gagankaushikmanyam avatar goggle avatar haampie avatar janm12 avatar jimbrouzoulis avatar jw3126 avatar kimauth avatar knutam avatar koehlerson avatar kristofferc avatar lijas avatar louisponet avatar michaelhatherly avatar mohamed82008 avatar pitmonticone avatar ranocha avatar suurj avatar termi-official avatar vinhtu95 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ferrite.jl's Issues

Naming of functions

Some of the function names feels a bit awkward. I suggest that we change some of them so that they are easier to "say".

function_scalar_value -> scalar_function_value # "value of a scalar function" rather than "value of a function scalar"
function_vector_value -> vector_function_value
function_scalar_gradient -> scalar_function_gradient
...

Assemble matrix when functions have explicit x-dependence

What is the best approach to assemble the matrix that arises from the following weak form on [-1,1]:

\int 2x v_x u - (1-x^2) v_x u_x dx

v is the trial function and u is the test function. Subscripts are derivatives wrt x
I can set up the v_x u term and the v_x u_x term by using shape_value and shape_gradient, but need some guidance for how to include the 2x and 1-x^2 terms.

My assembler function so far:

function doassemble{dim}(cellvalues::CellScalarValues{dim}, K::SparseMatrixCSC, dh::DofHandler)
    # Trying the set up matrix for the linear form
    # \int u \mathcal L v\,dx
    # = \int 2x(b-a)∂v(x)*u(x) - b(1-x^2)∂v(x)∂u(x) dx

    assembler = start_assemble(K)

    n_basefuncs = getnbasefunctions(cellvalues)
    global_dofs = zeros(Int, ndofs_per_cell(dh))
    Ke = zeros(n_basefuncs, n_basefuncs) # Local FEM matrix

    @inbounds for (cellcount, cell) in enumerate(CellIterator(dh))
        fill!(Ke, 0)

        reinit!(cellvalues, cell)

        for q_point in 1:getnquadpoints(cellvalues)
            dΩ = getdetJdV(cellvalues, q_point)
            for i in 1:n_basefuncs
                vi = shape_value(cellvalues, q_point, i)
                dvi = shape_gradient(cellvalues, q_point, i)[1]
                for j in 1:n_basefuncs
                    vj = shape_value(cellvalues, q_point, j)
                    dvj = shape_gradient(cellvalues, q_point, j)[1]                   
                    Ke[i,j] += (dvi * vj) *# Missing 2x(b-a)
                    Ke[i,j] -= (dvi * dvj) *# Missing b(1-x^2)
                end
            end
        end

        celldofs!(global_dofs, cell)
        assemble!(assembler, global_dofs, Ke)
    end
end

Dev docs

Explain how the elements functions are being generated.

Compilation time of generating a quadrature rule is very long

Probably due to @nloops and friends? Mostly on v0.6, but pretty slow on v0.5 aswell:

v0.5:

julia> using JuAFEM

julia> @time qr = QuadratureRule{2, RefCube}(:legendre, 2);
  3.661755 seconds (5.95 M allocations: 239.781 MB, 2.25% gc time)

v0.6:

julia> using JuAFEM

julia> @time qr = QuadratureRule{2, RefCube}(:legendre, 2);
 10.056088 seconds (11.82 M allocations: 544.792 MiB, 1.60% gc time)

missing create_face_quad_rule

julia> ip = Lagrange{2,RefTetrahedron,1}()
JuAFEM.Lagrange{2,JuAFEM.RefTetrahedron,1}()

julia> qr = QuadratureRule{2, RefTetrahedron}(4)
JuAFEM.QuadratureRule{2,JuAFEM.RefTetrahedron,Float64}([0.111691, 0.111691, 0.111691, 0.0549759, 0.0549759, 0.0549759], Tensors.Tensor{1,2,Float64,2}[[0.445948, 0.445948], [0.445948, 0.108103], [0.108103, 0.445948], [0.0915762, 0.0915762], [0.0915762, 0.816848], [0.816848, 0.0915762]])

julia> cv = FaceScalarValues(qr, ip)
ERROR: MethodError: no method matching create_face_quad_rule(::JuAFEM.QuadratureRule{2,JuAFEM.RefTetrahedron,Float64}, ::JuAFEM.Lagrange{2,JuAFEM.RefTetrahedron,1})
Closest candidates are:
  create_face_quad_rule(::JuAFEM.QuadratureRule{1,shape<:JuAFEM.RefTetrahedron,T}, ::JuAFEM.Interpolation{2,shape<:JuAFEM.RefTetrahedron,order} where order) where {T, shape<:JuAFEM.RefTetrahedron} at /home/fredrik/Dropbox/Programming/stable/JuAFEM.jl/src/FEValues/face_integrals.jl:63
  create_face_quad_rule(::JuAFEM.QuadratureRule{2,shape<:JuAFEM.RefTetrahedron,T}, ::JuAFEM.Interpolation{3,shape<:JuAFEM.RefTetrahedron,order} where order) where {T, shape<:JuAFEM.RefTetrahedron} at /home/fredrik/Dropbox/Programming/stable/JuAFEM.jl/src/FEValues/face_integrals.jl:137
Stacktrace:
 [1] JuAFEM.FaceScalarValues(::Type{Float64}, ::JuAFEM.QuadratureRule{2,JuAFEM.RefTetrahedron,Float64}, ::JuAFEM.Lagrange{2,JuAFEM.RefTetrahedron,1}, ::JuAFEM.Lagrange{2,JuAFEM.RefTetrahedron,1}) at /home/fredrik/Dropbox/Programming/stable/JuAFEM.jl/src/FEValues/face_values.jl:72
 [2] JuAFEM.FaceScalarValues(::JuAFEM.QuadratureRule{2,JuAFEM.RefTetrahedron,Float64}, ::JuAFEM.Lagrange{2,JuAFEM.RefTetrahedron,1}) at /home/fredrik/Dropbox/Programming/stable/JuAFEM.jl/src/FEValues/face_values.jl:61

DofHandler does't account for higher order basis functions

In the following setting

dim = 2
grid = generate_grid(Quadrilateral, (1, 1))
ip = Lagrange{dim, RefCube, 1}()
qr = QuadratureRule{dim, RefCube}(2)
cellvalues = CellScalarValues(qr, ip)

results in

JuAFEM.CellScalarValues{2,Float64,JuAFEM.RefCube} with 9 shape functions and 4 quadrature points

so i would expect the DofHandler to produce a 9x9 sparsity pattern, but it doesn't have the information for recognizing that.

Have a version comatible with Julia 0.6?

Somehow, the Julia 0.6 package manager doesn't seem to get that the latest master is made for Julia 0.7/1.0 only. Is it possible to have a tagged version that works with Julia 0.6? The complaint is that Julia doesn't know the library LinearAlgebra.

Include JuAFEM in a package via REQUIRE

Once the JuAFEM upgrade to Julia 0.7 is through, how would one include it in a non-registered package that uses REQUIRE? Just mentioning JuAFEM there seems to give an error.

A preliminary question about calling functions of JuAFEM

Hi everyone,

I am a new learner of Julia and JuAFEM. I want to ask a preliminary question about calling the JuAFEM functions: In the Julia-REPL, I run some functions like that

julia> using JuAFEM, SparseArrays

julia> grid = generate_grid(Quadrilateral, (20, 20));

julia> dim = 2;

julia> ip = Lagrange{dim, RefCube, 1}();

I want to check the functions in interpolations.jl, first I run the getnbasefunctions() function successfully

julia> getnbasefunctions(ip)
4

but the getdim() function failed

julia> getdim(ip)
ERROR: UndefVarError: getdim not defined
Stacktrace:
 [1] top-level scope at none:0

the calling of value() function is also failed.

Actually, getnbasefunctions(), getdim(), value() are in the same file interpolations.jl, and getnbasefunctions() is exported by the exports.jl.

But in the cell_values.jl I find that

@assert getdim(func_interpol) == getdim(geom_interpol)
...
ξ -> value(geom_interpol, basefunc, ξ)

I'm wondering to know that why the functions in cell_values.jl can call the functions in interpolations.jl which are not exported by the exports.jl?

Code duplications

The code for reinit! for FEBoundaryValues is very similar to the one for FECellValues. Just need to set the active boundary and then the rest is the same so should be able to pull it out to a common function.

Try becoming API compatible with the common stuff in CALFEM

Done:

Elements

Springs
  • spring1e
  • spring1s
Bars
  • bar2e
  • bar2s
  • bar2g
Solids (TODO: plane stress)
  • plante
  • plants
  • plantf

  • plani4e
  • plani4s
  • plani4f

  • plani8e
  • plani8s
  • plani8f

  • soli8e
  • soli8s
  • soli8f
Heat flow
  • flw2te
  • flw2ts

  • flw2i8e
  • flw2i8s

  • flw2i4e
  • flw2i4s

  • flw2i8e
  • flw2i8s

Materials

  • hooke

Utilities

  • assem
  • solveq
  • extract
  • statcon
  • coordxtr

Graphics

  • eldraw2
  • eldisp2

To do:

Elements

Bars
  • bar3e
  • bar3s
Beams
  • beam2e
  • beam2s

  • beam2t
  • beam2ts

  • beam2w
  • beam2ws

  • beam2g
  • beam2gs

  • beam2d
  • beam2ds

  • beam3e
  • beam3s

Materials

  • mises
  • dmises

Utilities

  • eigen
  • insert

Grahpics

  • fill
  • eldia2
  • elflux2
  • elprinc2
  • scalfact2
  • pltscalb2

generate_grid(Tetrahedron) results in bad grid

As far as I can tell the current generate_grid() for Tetrahedral elements in 3D results in discontinuous "hat" functions.

To see this, notice that for every hexahedron the line (1,0,0) to (1,1,1) passes through a face and separates two elements. But for the adjacent hexahedron, this line is within an element. See also http://www.baumanneduard.ch/Splitting%20a%20cube%20in%20tetrahedras2.htm (which is cited in generate_grid which does a rotated version of #13): if you look at the image of #13, you'll see that the lines on adjacent cubes don't fit together.

Change FEBoundaryValues

For a 3D case, the FEBoundaryValues should be a 2D space, embedded in a 3D space. Like dealii has a dim and a spacedim.

My wishlist

After learning how to use/using JuAFEM for about 2 weeks, I must say that it is a great tool, very understandable and hackable design, and it seems general enough to be expanded upon greatly!

I've used JuAFEM basically as a discretization tool for calculating a continuum model's total energy and gradients/hessians, as discussed on juafem-forwarddiff-nlsolve-finite-elements-for-nonlinear-problems It performs very well, vastly outperforming other implementations that colleagues of mine have done in c++ or Mathematica (duh).

I'll now give my wishlist for features as requested in the thread:

  • Easier ways to access the fields inside a DofHandler, and create starting conditions e.g.:
function startingconditions!(dofvec, dh)
    mid = div(ndofs_per_cell(dh), 2)
    for cell in CellIterator(dh)
        globaldofs = celldofs(cell)
        for i=1:3:mid
            it = div(i, 3) + 1
            dofvec[globaldofs[mid+i]] = -0.53
            dofvec[globaldofs[mid+i+1]] = 0.53tanh(cell.coords[it][1]/5)
            dofvec[globaldofs[mid+i+2]] = 0.53
        end
    end
end

In light of the other design, something like fielddofs(:Field, cell) similar to celldofs(cell), seems a good way. Also fielddofs(:Field, dh::DofHandler) would be very nice to calculate certain things from the finalized result.
Edit: see #187 for implementation

  • A way to add fancier constraints, such as bounds on fields etc

  • More options to generate grids/read them from formats, although I think this is already somewhat possible with various other packages. What would be cool is if it was possible to generate non uniform grids, defining some kind of rule for element size/mesh density, depending on the coordinates.

  • Higher flexibility on combining field dimensions with geometry dimensions, e.g. 3D field on a 2D geometry.

  • A way to thread over the CellIterator loop.
    This seems a bit tricky since assembling residus or stiffness tensors is not trivial multithreaded. It really depends on the grid what needs to be done. The way I do it now, which is very much not scalable is pretty brutal (I have two fields, :u, :P, and thus a dofvector uP):

mutable struct ModelCaches{T, CV, CI, CF}
    ∇fs::Vector{Vector{T}}
    cvus::Vector{CV}
    cvPs::Vector{CV}
    cellits::CI
    configs::CF
end

function ModelCaches(∇f::Vector{T}, cvu, cvP, dh) where T
    cellits = [CellIterator(dh) for t=1:nth]
    ellen   = length(celldofs(cellits[1]))
    ∇fs     = [zeros(∇f) for t=1:nth]
    cvus    = [copy(cvu) for t=1:nth]
    cvPs    = [copy(cvP) for t=1:nth]
    configs = [GradientConfig(nothing, zeros(T, ellen), Chunk(ellen)) for t=1:nth]
    return ModelCaches(∇fs, cvus, cvPs, cellits, configs)
end

function ∇F!(∇f::Vector{T} , uP::Vector{T}, caches, params) where T
    @threads for i=1:length(caches.∇fs)
        fill!(caches.∇fs[i], zero(T))
    end
    results = [zeros(T, length(celldofs(caches.cellits[1]))) for t=1:nth]
    @threads for i=1:length(caches.cellits[1])
        tid = threadid()
        reinit!(caches.cellits[tid], i)
        reinit!(caches.cvus[tid], caches.cellits[tid])
        reinit!(caches.cvPs[tid], caches.cellits[tid])
        ForwardDiff.gradient!(results[tid],
            uel -> element_potential(uel, caches.cvus[tid], caches.cvPs[tid], params),
            uP[celldofs(caches.cellits[tid])],
            caches.configs[tid])
        assemble!(caches.∇fs[tid], celldofs(caches.cellits[tid]), results[tid])
    end
    ∇f .= caches.∇fs[1]
    for fs in caches.∇fs[2:end]
        ∇f .+= fs
    end
end

This works, but is very much not scalable, and quite a lot of redundant things happen.

For now this is what I ran into the most. If I have more I'll update this issue. I could also maybe try to implement a couple of these things myself, no promises on that :p.
Anyway keep up the good work, and again thanks for helping me in the discourse thread!

Separate CALFEM stuff into its own repo

It's annoying to have all the CALFEM stuff in the same repo as the other new stuff. I suggest moving all the CALFEM stuff to its own repo, CALFEM.jl perhaps, and just let that one use JuAFEM like it does now. This would make it easier to keep the examples using the new JuAFEM stuff and the CALFEM stuff separate.

colon error in steprange

Not sure if this is a bug in julia or a syntax error in the package. Anyway the following code confuses julia steprange and colon from ternary operator.

Code to reproduce the error:

using JuAFEM
grid = generate_grid(Tetrahedron, (20, 20, 20))
dh = DofHandler(grid)
ip = Lagrange{3, RefTetrahedron, 2}()

push!(dh, :u, 1, ip)
close!(dh)

line of the error:

https://github.com/KristofferC/JuAFEM.jl/blob/a007e3d0a650954472fe059150088abc69d567c6/src/Dofs/DofHandler.jl#L162

Code to fix error:
for edgedof in (dir == olddir ? (1:interpolation_info.nedgedofs) : (interpolation_info.nedgedofs:-1:1))

Cheers!

Is this an ok place to ask questions? Not sure if there is a gitter channel

Hi Kristoffer,

I'm working on 'translating' a FEM toolkit (http://ptfem.github.io/PtFEM.jl/latest/INTRO.html) that I have been using in Fortran & R for quite some years (these days mainly for directional drilling applications for geothermal holes and occasionally buckling). The book contains 7 chapters demonstrating a variety of applications of the PtFEM toolkit.

I've converted about 2 1/3 chapters out of the 7 to Julia and started (in parallel) to explore the possibility of making JuaFEM the core layer, i.e. underneath what the book describes as the program layer (p41.jl, p52.jl, etc) and complete that item maybe earlier then I had anticipated in my TODO list.

Not sure if the exploration shows it is possible and if so if going that route is a better approach, but looking at JuAFEM evaluating this option is certainly worth a 1 or 2 week effort from my side.

Apologies for the long intro. Finally, my questions:

  1. Exploring JuAFEM's grid.jl, a fairly simple first question: Is in JuAFEM a Cell always synonymous with a finite element? In the latest docs under "Implementation in JuAFEM" it does state "elements or cells". PtFEM distinguishes structural elements like in your examples the cantilever beam.

  2. Looking at interpolations.jl, the shape functions look similar (they are numbered differently). Is the intention that a package like PtFEM.jl add interpolations like the 20-node hexahedron or would you prefer PRs?

Still early on, but I sure like what I'm seeing in JuAFEM.jl!

Regards,
Rob

Stuff to fix

Umbrella issue to track things to tweak:

  • some way for a node to know it is on the boundary. Useful for something like this: addnodeset!(grid, "all nodes on boundary", onboundary)
    Edit: We can do this with dispatch on onboundary
  • currently push! is used to add fields to a dofhandler, while for grid we have addnodeset/addcellset. Should we have addfield!() to be more consistent? (and for BC we simply have add!)
  • ~ export some more stuff: free_dofs, dirichlet_dofs ? ~
  • ~ reduce(K::Matrix, dbc) that reduces the matrix ~

Better way to add a facesets

Now that we will apply boundary conditions to facesets (#159) we need a addfaceset!(::Grid, ::String, ::Function) method similar to addnodeset! and addcellset!.

Distinction between geometric interpolation space and function interpolation space

Since #71 this is not so clear IMO. Call the geometric interpolation functions for shape functions (since they are connected to the shape, e.g. geometry) and the function interpolation functions for base functions (they are the base for the FE-approximation)

This would probably mean that some current functions have to be renamed, e.g.

shape_value -> base_value
shape_gradient -> base_gradient
...

Caching the set of faces that each boundary node is part of

I am trying to write a model extractor using FreeCAD into JuAFEM and I ran into a problem. Some of the boundary conditions are defined over faces and the way faces are handled in JuAFEM is different from the way they are handled in FreeCAD. In FreeCAD, a face is just an element with a bunch of nodes, while in JuAFEM, a face is a local property of the cell with a local index in each cell. This means that a mechanism to match boundary faces is needed to read the boundary conditions data into JuAFEM from other files like .inp using FreeCAD.

Initially in https://github.com/KristofferC/JuAFEM.jl/pull/194, I had thought that for Dirichlet boundary conditions, it is possible to assign the BC on the nodes of the faces instead. But this is not correct since the field interpolation can have more support points than face nodes. So the only correct way to do this is to actually match the faces. Even more is the case for Neumann boundary conditions, where a traction force is applied on a face, and cannot be easily distributed among the nodes. Also ideally, the translation done back and forth should not result in any loss of information. So I have been thinking of the best way to make it easier to match faces in JuAFEM with faces in FreeCAD and I thought of the following.

If we cache the set of face ids that a boundary node is part of, in the form of (cell_id, local_face_id), then it is possible using the nodes' ids of the face on which the BC is applied on, to find the intersection of the sets and identify the matching face in JuAFEM. Caching a vector of boundary node ids, and another vector of sets in the grid struct is an idea, probably not the most cache efficient way though.

Please let me know what you think.

Function spaces and quadrature rules are created differently.

For example:

function_space = Lagrange{2, RefTetrahedron, 1}()
quad_rule = GaussQuadrature(Dim{2}, RefTetrahedron(), 1)

Better would probably be

function_space = Lagrange(Dim{2}, RefTetrahedron(), 1)

so they look the same.

Edit: It doesn't work because then we need like Order{1}...

Petition to remove the first row in EDOF

This is a petition to remove the unnecessary first row of the edof matrix. It is never used and makes life harder than it needs to be.

Advantages:

  • Everywhere the edof matrix is used, the first row is removed
  • Simplifies coding since, you can write edof(:,i) instead of edof(2:end,i)
  • The code looks nicer, i.e edof(:,i) looks much better than edof(2:end,i)

Disadvantages:

  • None (except some rewriting of code

Please vote here!

Nature is pleased with simplicity. And nature is no dummy
― Isaac New

QuadratureRule creation

I propose we change the QuadratureRule constructor to use dim and refshape as parameters.

Now:

julia> QuadratureRule(Dim{2}, RefCube(), 2)
JuAFEM.QuadratureRule{2,Float64}([1.0,1.0,1.0,1.0],ContMechTensors.Tensor{1,2,Float64,2}[[-0.57735,-0.57735],[0.57735,-0.57735],[-0.57735,0.57735],[0.57735,0.57735]])

Desired:

julia> QuadratureRule{2, RefCube}(2)
JuAFEM.QuadratureRule{2,Float64}([1.0,1.0,1.0,1.0],ContMechTensors.Tensor{1,2,Float64,2}[[-0.57735,-0.57735],[0.57735,-0.57735],[-0.57735,0.57735],[0.57735,0.57735]])

will have conflicts with the changes in #73 I think so maybe change after that is merged. Or I might include it in that PR, if it helps with the coding of FEFaceValues :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.