Open drwells opened 1 year ago
@boyceg and I are going to use this issue to develop a roadmap for this project. If we want to integrate this with IBAMR then the best path forward is to use the same mechanisms we use for fdl::IFEDMethod
to associate FE information (DoFHandlers, vectors, etc) with SAMRAI patches. All that association code is already written and reduces this project's scope considerably: once you have an fdl::PatchMap
then you can use plain serial data structures. This makes development and testing pretty easy.
Like IFEDMethod
(which has an additional layer for
NodalInteraction
/ElementalInteraction
), we should write these classes with
three distinct layers:
IBStrategy
which is solely responsible for book-keeping and hooking into the rest of IBAMR.Importantly (for the purposes of testing and clean code) a layer will only call
the layers under it: i.e., layer 3 will never call layer 1 (nor should it know
anything about fdl::IIMethod
). This architecture is summarized in fiddle's readme.
Most of the book-keeping work is already done by fiddle: see https://github.com/drwells/fiddle/blob/master/include/fiddle/interaction/ifed_method_base.h. That class can set things up and determine which elements intersect which patches.
We should do this last since it will be relatively easy to bolt the pieces together.
One such data structure is PatchIntersectionMap
, which builds on PatchMap
to
store all the intersections between the FE mesh and a given Patch
. The
iterators are also responsible doing the easy to get wrong index calculations
with SideIndex
.
We might need more but fundamentally we need something to let us easily loop over intersections so that we can implement lots of IIM algorithms.
next steps
PatchIntersectionMap
. To start, we should add a constructor similar to NodalPatchMap
s. It might be easier to set this up with some auxiliary functions first before we write the class constructor.We should implement basic intersection algorithms. For starters we should write code which intersects a ray with a triangle or line.
In principle, we might want to cover stencils which intersect cells an arbitrary number of times, but for now lets just stick with single intersections.
There's a couple of different ways to implement this:
rtree
and then intersect each stencil with the rtree
:
that would quickly tell us which elements it might intersectstd::optional<double>
(i.e., return nothing if no
intersection exists and otherwise the intersection's convex combination
coefficient)I think some combination of 1 and 2 is the right way forward:
If we use std::optional
(available as std_cxx17::optional
in deal.II) then that function can find either (like Haskell's Maybe: I don't know the jargon for this in C++ yet) Nothing
or Just c
in which c
is the convex combination coefficient.
These should be similar to the functions in interaction/interaction_utilities.h
.
There are a couple of different ways to do this: e.g., Phong shading. The best
way to implement all of these in a general way is with a finite element field.
For example, with a tet mesh we can do FESystem<2, 3>(FE_SimplexDGP<2, 3>(0), 3)
to implement standard normal vectors (3
values per element, cell-centered)
or FESystem<2, 3>(FE_SimplexDGP<2, 3>(p), 3)
to do various generalizations of
Phong shading (with p = 1
being the standard linear interpolation). Possible
function signature:
template <int dim, int spacedim = dim>
LinearAlgebra::distributed::Vector<double>
compute_phong_normal_field(const DoFHandler<dim, spacedim> &dof_handler,
const Mapping<dim, spacedim> &mapping);
Like everything else in fiddle we should write these functions first, debug them, and then hook them into a bigger solver.
The major advantage to using FE fields for normal vectors is that we can utilize the preexisting data transfer mechanisms in fiddle to get data to the IB data partitioning easily as computing Phong normal vectors requires additional ghost data only present in the normal FEM data partitioning.
next steps
FEValues
. Since we might want to use multiple representations of the normal vectors we should start by expressing the default piecewise-constant normal vectors as an FESystem<dim, spacedim>(FE_DGQ<dim, spacedim>(0), spacedim)
or FESystem<dim, spacedim>(FE_SimplexDGP<dim, spacedim>(0), spacedim)
FE field.From a conversation with Qi last week: we need a way, when doing velocity interpolation on the interface, to distinguish between grid points outside or inside the interface. Our conversation convinced me that the only reasonable way to do this is with a level set method in which we tag cells outside the interface with 1
and those inside with -1
. In particular, we'll need to tag side-centered data and cell-centered data independently.
Hello David,
I pretty much finished testing intersection code. Here are the two functions that I want to add to fiddle: bool intersect_line_with_edge(std::vector<std::pair<double, Point<1>> >& t_vals, const DoFHandler<1, 2>::active_cell_iterator elem, const dealii::MappingQ<1, 2> &mapping, dealii::Point<2> r, dealii::Tensor<1,2> q, const double tol = 0.0); bool intersect_line_with_face(std::vector<std::pair<double, Point<2>> >& t_vals, const typename DoFHandler<2, 3>::active_cell_iterator elem, const dealii::MappingQ<2, 3> &mapping, dealii::Point<3> r, dealii::Tensor<1,3> q, const double tol=0); Where would you prefer me to add these two functions to? grid_utilities.cc? In the two functions, I do loop over interface elements.
Thanks. How about we put these in interaction/interaction_utilities.h
and open a pull request?
Hello David, I opened a pull request yesterday, although I don't think it's ready to be merged. I believe that there are likely still modifications needed for it to be completely ready for force spreading. But please feel free to share your comments, thoughts, or any preferences you would prefer me to modify?
Lets move that discussion over there - this issue is just the roadmap.
@ryanleaf1000 Looking at the roadmap, one next step is figuring out how to handle normal vectors. Another is populating PatchIntersectionMap
. I'll add some notes on what we can do next for either one up above. Which one would you like to try?
Either one could work. I am not sure I fully understand exactly what I need to do to populating PatchIntersectionMap. Which one you think we should work on first? Regarding handle normal vectors, I have some thought and some most recent findings to share with you. 1) we are still not sure if Phong's shading would solve the existing leaking problem. Maybe we should wait till Michael's tests with IBAMR and then decide? 2) Recently I tried nodal split the forces for jump conditions. So far everything seems working fine at least for the existing examples in IBAMR. Do you think it's necessary for us to have a global representation of the normal? instead we could have a global representation of the force and split it into jump condition only on intersection points and interpoation points on the interface for now? Or potentially using level set for calculating normal? What do you think? 3) I heard Amin is working on near touching problem and I also have some interpolation algorithm for two interfaces within one stencil. I know it's too early for this. I brought up this because maybe we could design some potential extendable feature for storing intersection points from two interfaces? For sure this feature would be useful for double corrected interpolation scheme in future if we decide to do near touching problems which is one of advantage of IIM.
I am not sure I fully understand exactly what I need to do to populating PatchIntersectionMap. Which one you think we should work on first?
One place to start with PatchIntersectionMap
would be to sketch out the algorithms we need. We should probably use an rtree
to look up elements which may intersect a given stencil. We can draft this on paper.
The normal vectors are probably an easier place to start. We just need a representation of normal vectors given some FE space; we can start by asserting that we have multicomponent piecewise constants.
we are still not sure if Phong's shading would solve the existing leaking problem. Maybe we should wait till Michael's tests with IBAMR and then decide?
Do you think it's necessary for us to have a global representation of the normal?
I think we should represent the normal vectors as an FE field. That we we can do whatever we want with it later on.
instead we could have a global representation of the force and split it into jump condition only on intersection points and interpoation points on the interface for now? Or potentially using level set for calculating normal? What do you think?
Doing that still requires having normal vectors available on each cell, so we need a way to compute those.
I heard Amin is working on near touching problem and I also have some interpolation algorithm for two interfaces within one stencil. I know it's too early for this. I brought up this because maybe we could design some potential extendable feature for storing intersection points from two interfaces?
Doing this in parallel is going to be quite tricky so lets hold off on it for now and stick with single intersections.
From a discussion today. This is not something I have time to complete myself but I still want to write down some notes.
The fundamental geometric problem we need to solve is ray intersection: we need to find 1) the points where a finite difference stencil intersects the mesh and 2) the corresponding unique element. If we get those then we can start building IIM algorithms.
There's a lot of interesting things to investigate:
@ryanleaf1000 A good place to start would be to look at how to intersect rays and elements in serial: i.e., given a
fdl::PatchMap
, compute a new structure describing where the intersections are with SAMRAI indices, deal.II elements, points on the structure, and points in the reference configuration. We should get this working before doing any physics. This is similar to https://github.com/drwells/fiddle/blob/057b76976b93b3f5c140a1a63b905576de41d26f/source/interaction/interaction_utilities.cc#L202-L269