GithubHelp home page GithubHelp logo

upa's People

Contributors

albertguti avatar danigallart avatar jordimanyer avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

upa's Issues

Find element from coordinates

Given a set of coordinates (x,y,z), we would like to obtain the index of the element where this point belongs.

How to do it:

As a first approach, my idea would be the following: We could add to the mesh an element-element connectivity map (which has not been implemented yet but is quite standard to have). Once this is done, a Dijkstra algorithm could be used to navigate between elements until finding the one containing the target coordinates. As a distance function, one could use the distance between the target coordinates and the baricenter of the elements (since all elements are convex, this would be an OK measure).

To do:

  • Implement the element-element connectivity matrix into the mesh class.
  • Implement a function returning the baricenter of an element.
  • Implement a function checking if a point is inside an element. Since all elements are convex, one can probably use the following algorithm: https://demonstrations.wolfram.com/AnEfficientTestForAPointToBeInAConvexPolygon/
  • Implement the Dijkstra-like algorithm: Starting from a reduced number of elements (as spread as possible), add their neighbors to a list. The list is then ordered by distance and the first element is considered as new candidate. Repeat until found, checking if the point is in the element at each step.

Possible other options:

  • Have an array with all baricenters, and look for the minimum distance using one of the optimized c++ sorting libraries. There exists a possibility that the selected element is not the solution (the baricenter distance could fail) but one of the neighboring elements will be.

Enhancement: Check GMRES error at each substep

A feature can be added to GMRES to check the error of the approximation at each substep and stop the algorithm when needed to. This feature could also allow to run GMRES without restart.

This is not urgent, but could be a good (and easy) enhancement to the algorithm.

First solver

Decide on which kind of solver to use (Direct, iterative) for a first approach.
The solver will be sequential and a first approach.

1D Laplace FEM not working for some problem sizes

In the implementation of 1D Laplace, in file src/Tests/v0_Laplace1D, there is an allocation error in the mesh when the number of elements per side in an even number.

Lines 18 to 21 of the file are as follows:

    int dim = 1;
    ElemType type = ElemType::Line;

    auto* mesh = new StructuredMesh();
    mesh->produceCartesian(dim,11,type);

In the last line, if 11 is the number of elements per side the created cartesian mesh will have (the mesh is the line [0,1], divided into as many elements as the number states.
If 11 is changed to any other odd number (13, 19, 21, ....) the code will run as intended. However, if the number of elements is changed to an even number (10, 12, 8, ...) the code will give a malloc error when allocating the arrays in the mesh.

For 12, the output is as follows

Selected rows: 
0 1 1 1 1 1 1 1 1 1 1 1 0 
Complete matrix: 
    24    -12    0    0    0    0    0    0    0    0    0
    -12    24    -12    0    0    0    0    0    0    0    0
    0    -12    24    -12    0    0    0    0    0    0    0
    0    0    -12    24    -12    0    0    0    0    0    0
    0    0    0    -12    24    -12    0    0    0    0    0
    0    0    0    0    -12    24    -12    0    0    0    0
    0    0    0    0    0    -12    24    -12    0    0    0
    0    0    0    0    0    0    -12    24    -12    0    0
    0    0    0    0    0    0    0    -12    24    -12    0
    0    0    0    0    0    0    0    0    -12    24    -12
    0    0    0    0    0    0    0    0    0    -12    24

Complete Vector: 
    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333    0.0833333
malloc(): corrupted top size

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

I do not know why this happens. Why is it doing this?

Distributed mesh

We need to add a distributed mesh structure.

  • new Graph class for adjacency lists.
  • Distributed mesh class
    • Basic structure and variables
    • Connect to structuredMesh class. METIS to partition.
    • Communication routines.

Read and write data format

Interaction with Pre & Post processing

  • Input data from Gmesh
  • Output data for Visit / Paraview, preferably with VTK format.

Preconditioned CG solver

For hard systems, preconditioning is needed. As a start, we should implement a preconditioned version of CG, which works for symmetric positive-definite matrices.

To do:

  • Implement preconditioner class
  • Implement diagonal preconditioner (simplest)
  • Implement PCG

Dirichlet Boundary Conditions

There are two main types of boundary conditions: Dirichlet and Newmann.

Newmann Boundary Conditions (NBCs) impose values on the normal derivatives of the solution (the fluxes) at the boundary. For instance, Newmann boundary conditions equal to zero on a boundary impose that there is no flux of solution through that boundary. NBCs are easy to impose since they are part of the Weak Form and therefore are taken care of while integrating the system.

On the other hand, Dirichlet BCs (DBCs) impose values directly on the DOFs themselves. For instance, DBCs equal to zero on the boundary impose that the solution is zero on that boundary.

Theoretically, DBCs are very easy to impose. On practice, some implementation issues arise.
There are different ways of imposing DBCs on a FEM system, each one woith its own drawbacks:

  • DBCs can be imposed using elimination of the DOFs. This is the most straighforward way, but it requires changing the matrix size and relabeling the nodes (then inverting all of this once the system has been solved).
  • One can use Lagrange multiplier methods, but this breaks the positiveness of the system matrix (I think) and therefore CG cannot be used. If we use this, we should implement a more general solver such as GMRES. However the this also woudl affect solving time, so it is probably not a good way of doing it.
  • A Nitsche method could be designed, which keeps the positiveness of the system (allowing to use CG). This directly modifies the weak form, and therefore we would impose DBCs weakly (the values at the boundary would not be exactly the ones we want, some small numerical error would arise).

All in all, I think the first method is the one to go (it is the one used in the 1D Laplace example) but for 2D , 3D meshes it is not as trivial. As advertised, a re-labeling and resizing of the matrix is needed (which is easier said than done using our own matrix classes). The implementation should be thought through to make it as optimal as possible.

Algebra libraries?

For now, c++ solvers have been implemented using arrays as matrices.
However, we will be using a lot of matrices in the future. Is it worth to implement some sort of matrix class? Or to use a 3rd party albegra library? I really have no idea on the advantages/disadvantages of these options, but we should probably consider it before having too much code.

Basis Function library

We need to implement a basis function library, similar on how the Reference element class is implemented.

Why do we need this?

Basis functions for different types of elements are needed for two things: First, you need to evaluate them at the gauss points when integrating the weak form (system matrix assembly). Second, you might need them after solving the system, to do postprocessing stuff.
This second usage is increased if we want to have Nedelec Edge Elements (as Dani suggests). The reason is that Lagrangian basis functions (the standard ones) are interpolative at the nodes, so the solution of the problem can already be used without postprocessing. However Nedelec DOFs are non-interpolative and therefore the solution needs to be interpolated at the nodes as a post-process. This requires evaluating the basis functions.

So this is a feature we MUST have if we ever want to use Nedelec elements. It is also a more elegant way of doing things and a nice quality-of-life feauture even for Lagrangian elements.

How to do it

We can do one of the two things:

  1. Implement it as a different class, similar to the reference element class.
  2. Extend the reference element class with new templeted functions for basis function evaluation.

I lean towards the second option. We could also use this opportunity to revise how the reference elemnt class is implemented and enhance it we feel it is necessary.

To do:

  • Revise the Reference Element class implementation. Decide if we want to change something (how to call the functions, how the templetates shoudl be used, etc...). Modify the code accordingly until the 1D and 2D laplace work again.
  • Once the style has been set, extend the Reference element class to include basis function evaluation. The new functions should allow us to easily obtain: A) The basis functions at any point of the reference element. B) As many derivatives as the think necessary (normally 1st and second derivatives are enough, but will depend on the equations we want to implement. It can be extended later).

Once this has been done, we will be able to start implementing Nedelec elements.

Iterative solvers for non-symmetric matrices

We will eventually run into non-symmetric matrices. It would be good to have a solver for this cases.

The most common are GMRES (Krylov method similar to CG but for non-symmetric problems) and AMG.
Both can be complicated to implement in an efficient way:

For GMRES, the main problem is the least squares problem that needs to be solved at each loop iteration. For this reason, most people build and dynamically update a QR factorization when finding the orthogonal basis for the Krylov space. This can be done efficiently using Householder transformations.

For AMG, the problem is how to create an efficient sparse interpolator (i.e the transformation between the different fine and coarse levels). Rugge-Steuben is the all-purpose standard interpolator, but it can be tricky to implement in a sparse way. For simple geometries, and taking advantage of the mesh structure, simpler interpolatros can be obtained. After this, the actual solver is very easy to implement and test.

All in all, here are my initial thoughts:

  • If we decide on a specific mesh, AMG can be made quite efficient by building a mesh-specific interpolator. For general meshes, I would probably prefer GMRES.
  • When parallelizing the code, GMRES will suffer minimal changes whereas AMG will require a lot of work (specifically on the interpolator).
  • AMG can be later used as a preconditioner (one of the best) for GMRES and CG if we ever need to.

So in conclusion I would start working towards GMRES as a priority and then try to go towards. Both could be nice to have, but neither are a real priority, since I doubt we find non-symmetric matrices in quite a while.

GMRES Solver

  • Basic structure (re-use from CG)
  • Implement Householder transformations
  • Implement QR solver
  • Implement GMRES loop (with restart)

AMG Solver

  • Basic structure
  • Implement general iterator class. Implement Jacobi and test separately.
  • Implement interpolator for FEM.
  • Implement AMG Level class.
  • Put everything together and test.

Implement Laplacian FEM

Develop first version of 1D Finite Element Method libraries to implement the Laplace equation.

Documentation - Numerical tools

Before any physics can be implemented, we need some Documentation on how the numerical tools work. This will allow for other people to be able to cooperate with ease.

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.