From: Andrea H. <and...@gm...> - 2009-03-16 18:50:20
|
Hello- I am just wondering if there is a simple way to check if a node is on the boundary. The only way I have found I think will work is to first check (elem->neighbor(side) == NULL) and then check elem.is_node_on_side(i,side). Did I miss another way? Thanks! Andrea |
From: Roy S. <roy...@ic...> - 2009-03-16 18:58:16
|
On Mon, 16 Mar 2009, Andrea Hawkins wrote: > I am just wondering if there is a simple way to check if a node is on the > boundary. Only if you've assigned a boundary id to that part of the boundary; then you can just call BoundaryInfo::boundary_id(node) and check to see if it's not invalid_id. > The only way I have found I think will work is to first check > (elem->neighbor(side) == NULL) and then check > elem.is_node_on_side(i,side). You'll get false negatives that way. Picture an L-shaped domain gridded with squares. At that interior corner, there's an element which has one node but zero sides on the boundary. Of course, sometimes we're happy with false negatives. If you're looping over all elements, then your technique will catch every boundary node eventually, it just won't catch them from each element they're in. If you're setting non-penalty Dirichlet conditions, for example, that's good enough. --- Roy |
From: Derek G. <fri...@gm...> - 2009-03-16 19:09:13
|
On Mar 16, 2009, at 12:58 PM, Roy Stogner wrote: > Of course, sometimes we're happy with false negatives. If you're > looping over all elements, then your technique will catch every > boundary node eventually, it just won't catch them from each element > they're in. If you're setting non-penalty Dirichlet conditions, for > example, that's good enough. That depends on how you're setting that condition. If you're hardcore going in and modifying the global matrix then you're correct. If you're modifying the element matrix _before_ adding it into the global matrix (as is often done with penalty formulations.... ie Example 3) then that won't work (because you never modify the element matrix for that element that has a node but no side on the boundary). Just thought I would point that out for anyone out there using the SLT (Standard Libmesh Template... ie modifying an example) and wanting to set non-penalty conditions.... Derek |
From: Andrea H. <and...@gm...> - 2009-03-16 19:11:32
|
> > That depends on how you're setting that condition. If you're hardcore > going in and modifying the global matrix then you're correct. If you're > modifying the element matrix _before_ adding it into the global matrix (as > is often done with penalty formulations.... ie Example 3) then that won't > work (because you never modify the element matrix for that element that has > a node but no side on the boundary). > > Just thought I would point that out for anyone out there using the SLT > (Standard Libmesh Template... ie modifying an example) and wanting to set > non-penalty conditions.... That's me! =) Thanks! I will look into setting the boundary id. Andrea |
From: Andrea H. <and...@gm...> - 2009-03-16 20:14:40
|
In my code, I'm currently just generating my mesh using MeshTools::Generation::build_square (mesh, x_elem, y_elem, min, max, min, max, QUAD9); In this routine, I see it setting boundary ids for the sides, but I don't see anywhere it sets them (or would set them) for the nodes. Where would be the appropriate place to set this? I'm just wanting the entire boundary to be Dirichlet. Andrea On Mon, Mar 16, 2009 at 2:11 PM, Andrea Hawkins <and...@gm...>wrote: > That depends on how you're setting that condition. If you're hardcore >> going in and modifying the global matrix then you're correct. If you're >> modifying the element matrix _before_ adding it into the global matrix (as >> is often done with penalty formulations.... ie Example 3) then that won't >> work (because you never modify the element matrix for that element that has >> a node but no side on the boundary). >> >> Just thought I would point that out for anyone out there using the SLT >> (Standard Libmesh Template... ie modifying an example) and wanting to set >> non-penalty conditions.... > > > > That's me! =) > > Thanks! I will look into setting the boundary id. > Andrea > > > > > > |
From: Roy S. <roy...@ic...> - 2009-03-16 20:42:37
|
On Mon, 16 Mar 2009, Andrea Hawkins wrote: > In my code, I'm currently just generating my mesh using > > MeshTools::Generation::build_square (mesh, x_elem, y_elem, min, max, min, max, QUAD9); > > In this routine, I see it setting boundary ids for the sides, but I don't see anywhere it sets them (or would set them) > for the nodes. Where would be the appropriate place to set this? I'm just wanting the entire boundary to be Dirichlet. I seem to recall that, when adding a boundary id for a side, the nodes for that side are given the same id, possibly overwriting any existing id of their own. Searching through the library, I can find absolutely no hint that any such behavior exists. I'd say that it might be a useful idea to at least add a method like "BoundaryInfo::sync_sides_to_nodes()" to loop over all elements and set node ids after the fact, but at the moment I'm more concerned about how I hallucinated a memory of code that never existed... --- Roy |
From: John P. <jwp...@gm...> - 2009-03-16 20:52:48
|
On Mon, Mar 16, 2009 at 3:42 PM, Roy Stogner <roy...@ic...> wrote: > > > On Mon, 16 Mar 2009, Andrea Hawkins wrote: > >> In my code, I'm currently just generating my mesh using >> >> MeshTools::Generation::build_square (mesh, x_elem, y_elem, min, max, min, >> max, QUAD9); >> >> In this routine, I see it setting boundary ids for the sides, but I don't >> see anywhere it sets them (or would set them) >> for the nodes. Where would be the appropriate place to set this? I'm just >> wanting the entire boundary to be Dirichlet. > > I seem to recall that, when adding a boundary id for a side, the nodes > for that side are given the same id, possibly overwriting any existing > id of their own. > > Searching through the library, I can find absolutely no hint that any > such behavior exists. Agree, looks like we have definitely been lazy about adding nodes to the boundary during build_cube. I think probably the min of all possible boundary IDs of sides which contain the node might be a logical choice. That shouldn't be too hard to add to build_cube, not that I'm volunteering of course :-) > I'd say that it might be a useful idea to at > least add a method like "BoundaryInfo::sync_sides_to_nodes()" Agree again, because I'm not sure the boundary info will be correctly updated when MeshTools::renumber_nodes_and_elements() is called... > at the > moment I'm more concerned about how I hallucinated a memory of code > that never existed... Maybe you are thinking about the way that child elements' boundary IDs are automatically gotten from their parents' boundary IDs w/o having to add them to the BoundaryInfo object? -- John |
From: Derek G. <fri...@gm...> - 2009-03-16 21:01:52
|
On Mar 16, 2009, at 2:42 PM, Roy Stogner wrote: > Searching through the library, I can find absolutely no hint that any > such behavior exists. I'd say that it might be a useful idea to at > least add a method like "BoundaryInfo::sync_sides_to_nodes()" to > loop over all elements and set node ids after the fact, but at the > moment I'm more concerned about how I hallucinated a memory of code > that never existed... I like the idea of BoundaryInfo::sync_sides_to_nodes().... it's much better than freaking Nodesets (nodes with boundary ids). What do you do when you refine the mesh? What do you do where two boundaries meet? Sidesets are much more well defined in both of these instances. For instance... consider the following side with nodes 1,2,3: 1-----2-----3 Let's say nodes 2 and 3 both have the same boundary ID. Now refine the mesh... 1-----2--4--3 Should node 4 get the same boundary id as 2 and 3? Lots of people would say yes.... but what if nodes 2 and 3 were really some sort of point source.... now you've just added another point source to your simulation.... My point is that boundary ids should be intrinsically tied to sides. In Sierra they have nodesets and it causes TONS of freaking pain. BTW: Andrea.... if you use Cubit you can just assign sidesets when you build the mesh... which will get written to the Exodus file.... and libMesh honors those sidesets by setting boundary-ids when the mesh is read. Just FYI... I don' t know if you have access to Cubit or not. Sorry to go off on a tangent. My point is that sync_sides_to_nodes() is a good idea.... and should be implemented by Roy immediately ;-) Derek |
From: Andrea H. <and...@gm...> - 2009-03-16 21:08:06
|
BTW: Andrea.... if you use Cubit you can just assign sidesets when you build > the mesh... which will get written to the Exodus file.... and libMesh honors > those sidesets by setting boundary-ids when the mesh is read. Just FYI... I > don' t know if you have access to Cubit or not. > I do have access to Cubit. So, I guess I'll just work with that until further notice. Thanks guys! Andrea |
From: Derek G. <fri...@gm...> - 2009-03-16 21:10:34
|
Just to be clear... Cubit won't actually help with your node boundary number problem. I just wanted to point out that it's easy to set boundary ids on sides using Cubit. Exodus and Cubit do have Nodeset capability. But I have specifically not added that to the Exodus reader in libMesh because of the problems I mentioned before. That said.... it wouldn't be hard to do... Derek On Mar 16, 2009, at 3:07 PM, Andrea Hawkins wrote: > > > BTW: Andrea.... if you use Cubit you can just assign sidesets when > you build the mesh... which will get written to the Exodus file.... > and libMesh honors those sidesets by setting boundary-ids when the > mesh is read. Just FYI... I don' t know if you have access to Cubit > or not. > > I do have access to Cubit. So, I guess I'll just work with that > until further notice. > > Thanks guys! > Andrea > > > |
From: Derek G. <fri...@gm...> - 2009-05-13 17:16:46
|
Update on this: I just committed nodeset capability for the Exodus reader / writer. You can now define nodesets in Cubit and they will be properly read into libMesh and written out when you write an Exodus file out using libMesh. HUGE DISCLAIMER: I really suggest that you DON'T use this capability for defining boundary conditions! If you do so... and use adaptivity... you are likely to get the WRONG answer! If you are trying to do non-penalty Dirichlet BCs... define Sidesets and use build_node_list_from_side_list() instead! So why implement reading a writing of nodesets? Well... they can still be useful... for instance picking one node to "pin" in a pure Neumann problem... or doing "point sources".... etc. Let me know if anyone spots any problems. Derek On Mon, Mar 16, 2009 at 3:08 PM, Derek Gaston <fri...@gm...> wrote: > Just to be clear... Cubit won't actually help with your node boundary > number problem. I just wanted to point out that it's easy to set boundary > ids on sides using Cubit. > > Exodus and Cubit do have Nodeset capability. But I have specifically not > added that to the Exodus reader in libMesh because of the problems I > mentioned before. That said.... it wouldn't be hard to do... > > Derek > > > On Mar 16, 2009, at 3:07 PM, Andrea Hawkins wrote: > > >> >> BTW: Andrea.... if you use Cubit you can just assign sidesets when you >> build the mesh... which will get written to the Exodus file.... and libMesh >> honors those sidesets by setting boundary-ids when the mesh is read. Just >> FYI... I don' t know if you have access to Cubit or not. >> >> I do have access to Cubit. So, I guess I'll just work with that until >> further notice. >> >> Thanks guys! >> Andrea >> >> >> >> > |
From: Roy S. <roy...@ic...> - 2009-03-16 21:17:00
|
On Mon, 16 Mar 2009, Derek Gaston wrote: > I like the idea of BoundaryInfo::sync_sides_to_nodes().... it's much better > than freaking Nodesets (nodes with boundary ids). What do you do when you > refine the mesh? What do you do where two boundaries meet? Sidesets are > much more well defined in both of these instances. Good point - like I said, even my imaginative fake memory couldn't come up with a completely sensible behavior for the node in between two boundaries, except for "give it both ids". IIRC multi-ids are a feature Ben wants, but as of now that has very little support in the code. > 1-----2--4--3 > > Should node 4 get the same boundary id as 2 and 3? Lots of people would say > yes.... but what if nodes 2 and 3 were really some sort of point source.... > now you've just added another point source to your simulation.... Interesting. If you think of a nodal boundary id as denoting a single point on the boundary, then point 4 should get the same id as side 2-3, which may have nothing to do with the ids of point 2 or point 3. On the other hand, to do that properly, you'd also want boundary ids on edges (which we could implement, but which we don't have at all right now). And in either case we'd want to stop calling them "boundary ids" if we wanted to (ab)use them for point sources; outside the structural mechanics world, point sources aren't necessarily on boundary points. > My point is that boundary ids should be intrinsically tied to sides. This seems to contradict your next point: > My point is that sync_sides_to_nodes() is a good idea.... Or are you just saying that official libMesh policy should be "We'll handle AMR on boundary sides for you, you're completely on your own with boundary nodes, but here's a utility to make a common usage a little easier"? > and should be implemented by Roy immediately ;-) Yeah, right. Tell you what - I'll write sync_sides_to_nodes(), you debug Tim's test case. Sound fair? --- Roy |
From: Derek G. <fri...@gm...> - 2009-03-16 21:38:40
|
On Mar 16, 2009, at 3:16 PM, Roy Stogner wrote: >> My point is that boundary ids should be intrinsically tied to sides. > > This seems to contradict your next point: > >> My point is that sync_sides_to_nodes() is a good idea.... > > Or are you just saying that official libMesh policy should be "We'll > handle AMR on boundary sides for you, you're completely on your own > with boundary nodes, but here's a utility to make a common usage a > little easier"? Yes. That. Sidesets always propagate properly under AMR... so that should be the only thing libMesh does automatically (as it does now). If you want to use boundary ids on nodes we'll provide a function call to sync boundary ids on sides to nodes in a predetermined way. Doing this automatically is asking for trouble.... >> and should be implemented by Roy immediately ;-) > > Yeah, right. > > Tell you what - I'll write sync_sides_to_nodes(), you debug Tim's test > case. Sound fair? LOL Personally I would actually use this capability (It's on my Todo list).... so if someone hasn't done it by the time I'm finished with my current task (which is a big task so it might be at least 3 or 4 days) I'll implement it myself. Derek |
From: Derek G. <fri...@gm...> - 2009-03-23 21:49:53
|
Ok... a first cut at this capability has been committed. If you call mesh.boundary_info->build_node_list_from_side_list() it will fill the BoundaryInfo object with nodes associated with the boundary id's of their sides. A couple of things: 1. Currently this wipes out all other nodes that (might) have been manually added to the boundary info object. 2. You can pass a vector to build_node_list_from_side_list containing the order you want the boundary ids to be applied. For instance, if you have boundary ids of: 1, 7, 12, 14 and you pass them into bnlfsl() like so: [12, 7, 14, 1] Then 12 will get applied first, then 7 then 14, then 1. This means that if 1 and 7 share a node... 1 will "win". If you _don't_ specify an order... the ordering is not guaranteed but will be consistent. What I mean is... one boundary id will consistently win over another one... you just have no guarantee's about which is which (does that make sense?). In general it seems to follow some natural ordering... Now... how do you actually make use of this thing? First call bnlfsl() (probably after you've read the mesh)... then call build_node_list() to get back a list of all of the nodes and their associated boundary_ids... now you're free to do what you want. Be aware that any time the mesh changes you will need to call bnlfsl() again... let me know of any problems... Derek On Mon, Mar 16, 2009 at 3:36 PM, Derek Gaston <fri...@gm...> wrote: > > On Mar 16, 2009, at 3:16 PM, Roy Stogner wrote: > > My point is that boundary ids should be intrinsically tied to sides. >>> >> >> This seems to contradict your next point: >> >> My point is that sync_sides_to_nodes() is a good idea.... >>> >> >> Or are you just saying that official libMesh policy should be "We'll >> handle AMR on boundary sides for you, you're completely on your own >> with boundary nodes, but here's a utility to make a common usage a >> little easier"? >> > > Yes. That. Sidesets always propagate properly under AMR... so that should > be the only thing libMesh does automatically (as it does now). If you want > to use boundary ids on nodes we'll provide a function call to sync boundary > ids on sides to nodes in a predetermined way. Doing this automatically is > asking for trouble.... > > and should be implemented by Roy immediately ;-) >>> >> >> Yeah, right. >> >> Tell you what - I'll write sync_sides_to_nodes(), you debug Tim's test >> case. Sound fair? >> > > LOL > > Personally I would actually use this capability (It's on my Todo list).... > so if someone hasn't done it by the time I'm finished with my current task > (which is a big task so it might be at least 3 or 4 days) I'll implement it > myself. > > Derek > |
From: Roy S. <roy...@ic...> - 2009-03-23 22:24:37
|
On Mon, 23 Mar 2009, Derek Gaston wrote: > Ok... a first cut at this capability has been committed. Nice job! > If you call mesh.boundary_info->build_node_list_from_side_list() it > will fill the BoundaryInfo object with nodes associated with the > boundary id's of their sides. A couple of things: > > 1. Currently this wipes out all other nodes that (might) have been manually > added to the boundary info object. Hmm... is this necessary? Aside from making this feature harder to use, it makes your point 2 interface more critical. If instead the interface nodes are allowed to already have ids (whether one of the ids they share with an adjoining side, or a unique "this identifies this corner" id) then there's no need to worry about which side id they get a copy of. Of course, lots of people will be loading in files with side ids but no node ids, for which "pick an ordering and autogenerate" is always going to be the way to go. > If you _don't_ specify an order... the ordering is not guaranteed but will > be consistent. What I mean is... one boundary id will consistently win over > another one... you just have no guarantee's about which is which (does that > make sense?). In general it seems to follow some natural ordering... Didn't you just end up with short::operator< as the natural ordering? I think the std::set, Sorted Associative Container specs are supposed to guarantee that. If you want to make doubly sure, you could do a std::sort on apply_order after building it. Thanks! --- Roy |
From: Derek G. <fri...@gm...> - 2009-03-23 22:34:17
|
On Mar 23, 2009, at 4:24 PM, Roy Stogner wrote: > Hmm... is this necessary? Aside from making this feature harder to > use, it makes your point 2 interface more critical. If instead the > interface nodes are allowed to already have ids (whether one of the > ids they share with an adjoining side, or a unique "this identifies > this corner" id) then there's no need to worry about which side id > they get a copy of. I suppose there really isn't a need to clear the map. In successive calls those entries will just get overridden (actually they might or might not because of the ordering logic... but whatever) and not clearing it would preserve any manual entries that don't coincide with a side boundary. I'll go ahead and remove the clear(). >> If you _don't_ specify an order... the ordering is not guaranteed >> but will >> be consistent. What I mean is... one boundary id will consistently >> win over >> another one... you just have no guarantee's about which is which >> (does that >> make sense?). In general it seems to follow some natural ordering... > > Didn't you just end up with short::operator< as the natural ordering? > I think the std::set, Sorted Associative Container specs are supposed > to guarantee that. If you want to make doubly sure, you could do a > std::sort on apply_order after building it. Good point... as you say it's guaranteed since it's a std::set. I'll update the comment to reflect this. Derek |