## RE: [Libmesh-users] how to change node position

 RE: [Libmesh-users] how to change node position From: KIRK, BENJAMIN (JSC-EG) (NASA) - 2005-07-28 14:25:48 ```Please! -Ben -----Original Message----- From: Martin L=FCthi [mailto:luthi@...]=20 Sent: Wednesday, July 27, 2005 7:10 PM To: KIRK, BENJAMIN (JSC-EG) (NASA) Cc: 'Roy Stogner'; Michael Povolotskyi; = libmesh-users@... Subject: RE: [Libmesh-users] how to change node position Michael Some time ago I commited a patch to mesh::smooth, that apparently never = got applied. With this you should be able to move *all* nodes with the = method Ben mentioned: KIRK, BENJAMIN (JSC-EG) (NASA) writes: > Functionally, to move a node you simply assign a new Point value to = it: >=20 > mesh.node(n) =3D Point(x_new, y_new, z_new); >=20 > for example. A number of functions in src/mesh/mesh_modification.C = alter > the mesh in such a fashion. After that you make a call to mesh.smooth. What it does is: o relaxes all nodes (you could comment out that step if you don't want this. I used it for an advected mesh, and it helped improve the quality. =20 o looks for higher order nodes (the ones on the element sides) and places them on the edge of the element. This works in 2D, but I'm not sure anymore about 3D. Besides the fact = that the algorithm works for higher order elements it also is much more = efficient than the LaplaceSmoother in the library, since there is no need to = build an expensive data structure of the graph. Hopefully this code still works! Best, Martin BEN: should I prepare another patch? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D from = mesh_modification.C = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D void MeshTools::Modification::smooth (MeshBase& mesh, const unsigned int n_iterations, const Real power) { /* * find the boundary nodes */ std::vector on_boundary; MeshTools::find_boundary_nodes(mesh, on_boundary); for (unsigned int iter=3D0; iter new_positions; std::vector weight; new_positions.resize(mesh.n_nodes()); weight.resize(mesh.n_nodes()); /* * Loop over the elements to calculate new node positions */ MeshBase::element_iterator el =3D mesh.level_elements_begin(refinement_level); const MeshBase::element_iterator end =3D mesh.level_elements_end(refinement_level);=20 =09 for (; el !=3D end; ++el) { /* * Constant handle for the element */ const Elem* elem =3D *el; =20 /* * We relax all nodes on level 0 first=20 * If the element is refined (level > 0), we interpolate = the * parents nodes with help of the embedding matrix */ if (refinement_level =3D=3D 0) { for (unsigned int s=3D0; sn_neighbors(); s++) { /* * Only operate on sides which are on the * boundary or for which the current element's * id is greater than its neighbor's. * Sides get only built once. */ if ((elem->neighbor(s) !=3D NULL) && (elem->id() > elem->neighbor(s)->id()) )=20 { AutoPtr side(elem->build_side(s)); Node* node0 =3D side->get_node(0); Node* node1 =3D side->get_node(1); Real node_weight =3D 1.; // calculate the weight of the nodes if (power > 0) { Point diff =3D (*node0)-(*node1); node_weight =3D pow( diff.size(), power = ); } const unsigned int id0 =3D node0->id(), id1 = =3D node1->id(); new_positions[id0].add_scaled( *node1, = node_weight ); new_positions[id1].add_scaled( *node0, = node_weight ); weight[id0] +=3D node_weight; weight[id1] +=3D node_weight; } } // element neighbor loop }=20 else // refinement_level > 0 { /* * Find the positions of the hanging nodes of refined elements. * We do this by calculating their position based on = the parent * (one level less refined) element, and the = embedding matrix */ const Elem* parent =3D elem->parent(); /* * find out which child I am */ for (unsigned int c=3D0; c < parent->n_children(); = c++) { if (parent->child(c) =3D=3D elem) { /* *loop over the childs (that is, the current elements) nodes */ for (unsigned int nc=3D0; nc < = elem->n_nodes(); nc++) { /* * the new position of the node */ Point point; for (unsigned int n=3D0; = nn_nodes(); n++) { /* * The value from the embedding = matrix */ const float em_val =3D parent->embedding_matrix(c,nc,n); =20 if (em_val !=3D 0.) point.add_scaled (parent->point(n), em_val); } const unsigned int id =3D elem->get_node(nc)->id(); new_positions[id] =3D point; weight[id] =3D 1.; } =20 } // if parent->child =3D=3D elem } // for parent->n_children } // if element refinement_level /* * Now handle the additional second_order nodes by = calculating * their position based on the vertex postitions */ std::vector adjacent_vertices_ids; const unsigned int son_begin =3D elem->n_vertices(); const unsigned int son_end =3D elem->n_nodes(); for (unsigned int n=3Dson_begin; nn_second_order_adjacent_vertices(n); Point point;=20 for (unsigned int v=3D0; vpoint( elem->second_order_adjacent_vertex(n,v) )); const unsigned int id =3D elem->get_node(n)->id(); new_positions[id] =3D point; weight[id] =3D 1.*n_adjacent_vertices; } } // element loop /* * finally reposition the nodes */ for (unsigned int nid=3D0; nid 0.) mesh.node(nid) =3D new_positions[nid]/weight[nid]; =20 } // refinement_level loop } // end iteration } ```

 RE: [Libmesh-users] how to change node position From: KIRK, BENJAMIN (JSC-EG) (NASA) - 2005-07-27 20:43:57 ```Roy's comments are right on target. Functionally, to move a node you simply assign a new Point value to it: mesh.node(n) = Point(x_new, y_new, z_new); for example. A number of functions in src/mesh/mesh_modification.C alter the mesh in such a fashion. -Ben -----Original Message----- From: libmesh-users-admin@... [mailto:libmesh-users-admin@...] On Behalf Of Roy Stogner Sent: Wednesday, July 27, 2005 1:02 PM To: Michael Povolotskyi Cc: libmesh-users@... Subject: Re: [Libmesh-users] how to change node position On Wed, 27 Jul 2005, Michael Povolotskyi wrote: > Dear Libmesh developers, > I have a question. > > After solving a PDE with libmesh, I'd like to change positions of some > nodes. Is it possible to change slightly positions of grid nodes "by > hand", keeping the connectivity? If the grid has not been adaptively refined, then as long as you don't give any elements singular Jacobians you ought to be able to move any nodes whereever you want. If the grid has been adaptively refined, there are currently some pretty severe geometric constraints: hanging node constraint calculations assume that child faces map back to the "reference child" of their parent's faces, and element coarsening projections assume that entire child elements map back to the reference child. Really the only safe way to move nodes on adaptive meshes AFAIK is to move only the nodes of the coarsest elements independently, then walk down the tree of child elements and move their nodes to the correct intermediate positions. --- Roy Stogner ------------------------------------------------------- SF.Net email is sponsored by: Discover Easy Linux Migration Strategies from IBM. Find simple to follow Roadmaps, straightforward articles, informative Webcasts and more! Get everything you need to get up to speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click _______________________________________________ Libmesh-users mailing list Libmesh-users@... https://lists.sourceforge.net/lists/listinfo/libmesh-users ```
 RE: [Libmesh-users] how to change node position From: KIRK, BENJAMIN (JSC-EG) (NASA) - 2005-07-28 14:25:48 ```Please! -Ben -----Original Message----- From: Martin L=FCthi [mailto:luthi@...]=20 Sent: Wednesday, July 27, 2005 7:10 PM To: KIRK, BENJAMIN (JSC-EG) (NASA) Cc: 'Roy Stogner'; Michael Povolotskyi; = libmesh-users@... Subject: RE: [Libmesh-users] how to change node position Michael Some time ago I commited a patch to mesh::smooth, that apparently never = got applied. With this you should be able to move *all* nodes with the = method Ben mentioned: KIRK, BENJAMIN (JSC-EG) (NASA) writes: > Functionally, to move a node you simply assign a new Point value to = it: >=20 > mesh.node(n) =3D Point(x_new, y_new, z_new); >=20 > for example. A number of functions in src/mesh/mesh_modification.C = alter > the mesh in such a fashion. After that you make a call to mesh.smooth. What it does is: o relaxes all nodes (you could comment out that step if you don't want this. I used it for an advected mesh, and it helped improve the quality. =20 o looks for higher order nodes (the ones on the element sides) and places them on the edge of the element. This works in 2D, but I'm not sure anymore about 3D. Besides the fact = that the algorithm works for higher order elements it also is much more = efficient than the LaplaceSmoother in the library, since there is no need to = build an expensive data structure of the graph. Hopefully this code still works! Best, Martin BEN: should I prepare another patch? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D from = mesh_modification.C = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D void MeshTools::Modification::smooth (MeshBase& mesh, const unsigned int n_iterations, const Real power) { /* * find the boundary nodes */ std::vector on_boundary; MeshTools::find_boundary_nodes(mesh, on_boundary); for (unsigned int iter=3D0; iter new_positions; std::vector weight; new_positions.resize(mesh.n_nodes()); weight.resize(mesh.n_nodes()); /* * Loop over the elements to calculate new node positions */ MeshBase::element_iterator el =3D mesh.level_elements_begin(refinement_level); const MeshBase::element_iterator end =3D mesh.level_elements_end(refinement_level);=20 =09 for (; el !=3D end; ++el) { /* * Constant handle for the element */ const Elem* elem =3D *el; =20 /* * We relax all nodes on level 0 first=20 * If the element is refined (level > 0), we interpolate = the * parents nodes with help of the embedding matrix */ if (refinement_level =3D=3D 0) { for (unsigned int s=3D0; sn_neighbors(); s++) { /* * Only operate on sides which are on the * boundary or for which the current element's * id is greater than its neighbor's. * Sides get only built once. */ if ((elem->neighbor(s) !=3D NULL) && (elem->id() > elem->neighbor(s)->id()) )=20 { AutoPtr side(elem->build_side(s)); Node* node0 =3D side->get_node(0); Node* node1 =3D side->get_node(1); Real node_weight =3D 1.; // calculate the weight of the nodes if (power > 0) { Point diff =3D (*node0)-(*node1); node_weight =3D pow( diff.size(), power = ); } const unsigned int id0 =3D node0->id(), id1 = =3D node1->id(); new_positions[id0].add_scaled( *node1, = node_weight ); new_positions[id1].add_scaled( *node0, = node_weight ); weight[id0] +=3D node_weight; weight[id1] +=3D node_weight; } } // element neighbor loop }=20 else // refinement_level > 0 { /* * Find the positions of the hanging nodes of refined elements. * We do this by calculating their position based on = the parent * (one level less refined) element, and the = embedding matrix */ const Elem* parent =3D elem->parent(); /* * find out which child I am */ for (unsigned int c=3D0; c < parent->n_children(); = c++) { if (parent->child(c) =3D=3D elem) { /* *loop over the childs (that is, the current elements) nodes */ for (unsigned int nc=3D0; nc < = elem->n_nodes(); nc++) { /* * the new position of the node */ Point point; for (unsigned int n=3D0; = nn_nodes(); n++) { /* * The value from the embedding = matrix */ const float em_val =3D parent->embedding_matrix(c,nc,n); =20 if (em_val !=3D 0.) point.add_scaled (parent->point(n), em_val); } const unsigned int id =3D elem->get_node(nc)->id(); new_positions[id] =3D point; weight[id] =3D 1.; } =20 } // if parent->child =3D=3D elem } // for parent->n_children } // if element refinement_level /* * Now handle the additional second_order nodes by = calculating * their position based on the vertex postitions */ std::vector adjacent_vertices_ids; const unsigned int son_begin =3D elem->n_vertices(); const unsigned int son_end =3D elem->n_nodes(); for (unsigned int n=3Dson_begin; nn_second_order_adjacent_vertices(n); Point point;=20 for (unsigned int v=3D0; vpoint( elem->second_order_adjacent_vertex(n,v) )); const unsigned int id =3D elem->get_node(n)->id(); new_positions[id] =3D point; weight[id] =3D 1.*n_adjacent_vertices; } } // element loop /* * finally reposition the nodes */ for (unsigned int nid=3D0; nid 0.) mesh.node(nid) =3D new_positions[nid]/weight[nid]; =20 } // refinement_level loop } // end iteration } ```
 RE: [Libmesh-users] how to change node position From: Martin - 2005-07-28 00:10:31 ```Michael Some time ago I commited a patch to mesh::smooth, that apparently never got applied. With this you should be able to move *all* nodes with the method Ben mentioned: KIRK, BENJAMIN (JSC-EG) (NASA) writes: > Functionally, to move a node you simply assign a new Point value to it: > > mesh.node(n) = Point(x_new, y_new, z_new); > > for example. A number of functions in src/mesh/mesh_modification.C alter > the mesh in such a fashion. After that you make a call to mesh.smooth. What it does is: o relaxes all nodes (you could comment out that step if you don't want this. I used it for an advected mesh, and it helped improve the quality. o looks for higher order nodes (the ones on the element sides) and places them on the edge of the element. This works in 2D, but I'm not sure anymore about 3D. Besides the fact that the algorithm works for higher order elements it also is much more efficient than the LaplaceSmoother in the library, since there is no need to build an expensive data structure of the graph. Hopefully this code still works! Best, Martin BEN: should I prepare another patch? ===================== from mesh_modification.C ====================== void MeshTools::Modification::smooth (MeshBase& mesh, const unsigned int n_iterations, const Real power) { /* * find the boundary nodes */ std::vector on_boundary; MeshTools::find_boundary_nodes(mesh, on_boundary); for (unsigned int iter=0; iter new_positions; std::vector weight; new_positions.resize(mesh.n_nodes()); weight.resize(mesh.n_nodes()); /* * Loop over the elements to calculate new node positions */ MeshBase::element_iterator el = mesh.level_elements_begin(refinement_level); const MeshBase::element_iterator end = mesh.level_elements_end(refinement_level); for (; el != end; ++el) { /* * Constant handle for the element */ const Elem* elem = *el; /* * We relax all nodes on level 0 first * If the element is refined (level > 0), we interpolate the * parents nodes with help of the embedding matrix */ if (refinement_level == 0) { for (unsigned int s=0; sn_neighbors(); s++) { /* * Only operate on sides which are on the * boundary or for which the current element's * id is greater than its neighbor's. * Sides get only built once. */ if ((elem->neighbor(s) != NULL) && (elem->id() > elem->neighbor(s)->id()) ) { AutoPtr side(elem->build_side(s)); Node* node0 = side->get_node(0); Node* node1 = side->get_node(1); Real node_weight = 1.; // calculate the weight of the nodes if (power > 0) { Point diff = (*node0)-(*node1); node_weight = pow( diff.size(), power ); } const unsigned int id0 = node0->id(), id1 = node1->id(); new_positions[id0].add_scaled( *node1, node_weight ); new_positions[id1].add_scaled( *node0, node_weight ); weight[id0] += node_weight; weight[id1] += node_weight; } } // element neighbor loop } else // refinement_level > 0 { /* * Find the positions of the hanging nodes of refined elements. * We do this by calculating their position based on the parent * (one level less refined) element, and the embedding matrix */ const Elem* parent = elem->parent(); /* * find out which child I am */ for (unsigned int c=0; c < parent->n_children(); c++) { if (parent->child(c) == elem) { /* *loop over the childs (that is, the current elements) nodes */ for (unsigned int nc=0; nc < elem->n_nodes(); nc++) { /* * the new position of the node */ Point point; for (unsigned int n=0; nn_nodes(); n++) { /* * The value from the embedding matrix */ const float em_val = parent->embedding_matrix(c,nc,n); if (em_val != 0.) point.add_scaled (parent->point(n), em_val); } const unsigned int id = elem->get_node(nc)->id(); new_positions[id] = point; weight[id] = 1.; } } // if parent->child == elem } // for parent->n_children } // if element refinement_level /* * Now handle the additional second_order nodes by calculating * their position based on the vertex postitions */ std::vector adjacent_vertices_ids; const unsigned int son_begin = elem->n_vertices(); const unsigned int son_end = elem->n_nodes(); for (unsigned int n=son_begin; nn_second_order_adjacent_vertices(n); Point point; for (unsigned int v=0; vpoint( elem->second_order_adjacent_vertex(n,v) )); const unsigned int id = elem->get_node(n)->id(); new_positions[id] = point; weight[id] = 1.*n_adjacent_vertices; } } // element loop /* * finally reposition the nodes */ for (unsigned int nid=0; nid 0.) mesh.node(nid) = new_positions[nid]/weight[nid]; } // refinement_level loop } // end iteration } ```