I'm playing with dealii (8.3.0) and trying to solve a 2-D, plane strain elasticity problem for a simple cantilever beam (say 5x1). Although I acknowledge that dealii is made for more sophisticated problems than a "stupid" beam, I think that the use (and documentation) of such simple problems might increase dealii's broader appeal (for example to dumb engineers like myself).
Although I follow step-8 and get expected results for distributed forces (i.e. right hand sides that are continuous functions), I'm having a little difficulty finding a clean way to represent nodal forces (i.e. point forces). My RightHandSide function looks like:
void RightHandSide<dim>::vector_value(const Point<dim>& p,
Vector<double>& values) const
{
Assert(values.size()==dim,ExcDimensionMismatch(values.size(),dim));
Assert(dim ==2,ExcNotImplemented());
//apply a force at the top end of the beam
if(p(1)==1 && p(0)==5)
{
values(0)=0;
values(1)=-1000;
}
else
{
values(0)=0;
values(1)=0;
}
}
When iterating through each cell using Gaussian quadrature to assemble the stiffness matrix and right hand side (following step-8), any point force (say, one applied directly at a node for simplicity) isn't "seen" by the quadrature points, so the right hand side ends up being zero. Fine. So I've got to update the nodal forces some other way...
Let's say I've got a list of vertices (say from triangulation.get_vertices()) and I can return the associated force at each node via RightHandSide.vector_value(). My problem is figuring out how to associate the vertex/point information (and the forces associated with that vertex) with the appropriate global degree of freedom such that I can get an updated right hand side.
I've (partially) tried a couple of things:
1. Using DoFTools::map_support_points_to_dofs in some way, but, as discussed in a previous google group post, this function should probably be deprecated (or updated to return a multimap) and thus is currently not a good candidate for choosing the nodal forces.
2. Iterating through active cells, adding each cell's vertex information (Point<dim>) and global dof information to a unordered_map of type <Point<dim>,std::vector<types::global_dof_index>>. Then, at the end of assemble_system(), I write the value of RightHandSide at each point in the unordered_map to the location specified by the point's global dofs in the system_rhs vector. This is kind of a dumb method (and it requires me to implement a hash function and point comparison function to make the unordered_map work) but it seems to function...
3. Using VectorTools::create_point_source_vector (instead of my RightHandSide function) but I get an error that the function is only implemented in 1-D.
4. Using VectorTools::create_right_hand_side with a custom quadrature rule and mapping (i.e. quadrature points are actually just the vertices, with weights equal to one for each points - and the mapping returns just the function values). Note that I haven't implemented this option because it just seems too crazy to do such a simple thing...
My question is: is there a more elegant way to represent point forces than what I've described in Option 2?
DealII is pretty great, by the way.
P.S. I attach my current source code, although I acknowledge that I haven't yet updated the cell_matrix to reflect the plane strain stiffness matrix (right now it's the perfect 2-D solid, as Wolfgang noted in a previous tutorial). Thanks in advance.