## [Libmesh-users] Looping over Processor's Nodes

 [Libmesh-users] Looping over Processor's Nodes From: John Peterson - 2006-11-02 04:42:41 ```Oh by the way, do you need to compute the reaction values based on the solution at the _nodes_ or at the Gaussian quadrature points? -J Travis Austin writes: > > Hi, > > I'm with a group at the University of Auckland hoping to convince everyone to have libmesh be the basis > for our new software. Currently we are focusing on reaction-diffusion problems so I have built a simple > reaction-diffusion code using libmesh that can run on multiple processors. However I think it could be > more efficient when solving the reaction part. We are currently using linear finite elements so DOFs > are only located at vertices of rectangles and hexs. > > I've got code (seen below) to solve the reaction part at every DOF. It uses the standard method of > looping over elements. The call to cubic.react solves the reaction problem, and in general, can be > expensive so I only want to do it once. > > Currently this approach has me solving reaction (by building up the src vector) multiple times since one > DOF shares many elements. I'd like to only loop over nodes but it appears to be that mesh.nodes_begin() > and mesh.nodes_end() provides a start and end for ALL of the nodes, not the local nodes. > > Does anyone have a solution for looping over all nodes on your local processor without using the following > element-based loop? (I accept that I will solve this reaction problem twice at nodes sitting between processor > boundaries.) > > Travis Austin > > MeshBase::const_element_iterator elem_it = mesh.active_local_elements_begin(); > const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end(); > > for ( ; elem_it != elem_end; ++elem_it) > { > > const Elem* elem = *elem_it; > > dof_map.dof_indices (elem, dof_indices); > > assert (dof_indices.size() <= elem->n_nodes()); > > for (unsigned int i=0; i if ((dof_indices[i] >= src.first_local_index()) && > (dof_indices[i] < src.last_local_index())) > { > // Get local node point > const Point& ep = elem->point (i); > // Get current stimulus for point > const Real stim = Is1(dof_indices[i],ep,time); > // Set stimulus to be used in solving reaction problem > src.set(dof_indices[i],(cubic.react(soln(dof_indices[i]),dt,stim)/Cm)); > } > > } ```

 [Libmesh-users] Looping over Processor's Nodes From: Travis Austin - 2006-11-02 03:17:38 ```=0AHi,=0A=0AI'm with a group at the University of Auckland hoping to convin= ce everyone to have libmesh be the basis =0Afor our new software. Currentl= y we are focusing on reaction-diffusion problems so I have built a simple = =0Areaction-diffusion code using libmesh that can run on multiple processor= s. However I think it could be =0Amore efficient when solving the reaction= part. We are currently using linear finite elements so DOFs =0Aare only l= ocated at vertices of rectangles and hexs.=0A=0AI've got code (seen below) = to solve the reaction part at every DOF. It uses the standard method of=0A= looping over elements. The call to cubic.react solves the reaction problem= , and in general, can be =0Aexpensive so I only want to do it once.=0A=0ACu= rrently this approach has me solving reaction (by building up the src vecto= r) multiple times since one=0ADOF shares many elements. I'd like to only l= oop over nodes but it appears to be that mesh.nodes_begin() =0Aand mesh.nod= es_end() provides a start and end for ALL of the nodes, not the local nodes= . =0A=0ADoes anyone have a solution for looping over all nodes on your loc= al processor without using the following =0Aelement-based loop? (I accept = that I will solve this reaction problem twice at nodes sitting between proc= essor =0Aboundaries.)=0A=0ATravis Austin=0A=0A MeshBase::const_element_iter= ator elem_it =3D mesh.active_local_elements_begin();=0A const MeshBa= se::const_element_iterator elem_end =3D mesh.active_local_elements_end(); = =0A =0A for ( ; elem_it !=3D elem_end; ++elem_it)=0A {=0A=0A co= nst Elem* elem =3D *elem_it;=0A =0A dof_map.dof_indices (elem= , dof_indices);=0A=0A assert (dof_indices.size() <=3D elem->n_nodes= ());=0A=0A for (unsigned int i=3D0; i=3D src.first_local_index()) &&=0A (dof_i= ndices[i] < src.last_local_index()))=0A {=0A // Get local= node point=0A const Point& ep =3D elem->point (i);=0A /= / Get current stimulus for point=0A const Real stim =3D Is1(dof_in= dices[i],ep,time);=0A // Set stimulus to be used in solving reacti= on problem=0A src.set(dof_indices[i],(cubic.react(soln(dof_indices= [i]),dt,stim)/Cm));=0A } =0A =0A }=0A=0A=0A=0A=0A=0A=0A=0A ```
 Re: [Libmesh-users] Looping over Processor's Nodes From: Roy Stogner - 2006-11-02 03:40:42 ```On Wed, 1 Nov 2006, Travis Austin wrote: > I've got code (seen below) to solve the reaction part at every DOF. > It uses the standard method of looping over elements. The call to > cubic.react solves the reaction problem, and in general, can be > expensive so I only want to do it once. > > Currently this approach has me solving reaction (by building up the > src vector) multiple times since one DOF shares many elements. I'd > like to only loop over nodes but it appears to be that > mesh.nodes_begin() and mesh.nodes_end() provides a start and end for > ALL of the nodes, not the local nodes. > > Does anyone have a solution for looping over all nodes on your local > processor without using the following element-based loop? (I accept > that I will solve this reaction problem twice at nodes sitting > between processor boundaries.) Two simple possiblities: Loop over active local elements and over nodes in each element as below, but before doing so create a record like std::vector node_visited(mesh.n_nodes(), false); test to make sure the appropriate flag is false before calling react(), and set the flag flag to true afterward. Loop from nodes_begin() to nodes_end(), but test to make sure each dof index is local before calling react(). I think in the long term the right solution is to create local node iterators (another subclass of variant_filter_iterator?), but that's probably more trouble than you want to go through. --- Roy ```
 Re: [Libmesh-users] Looping over Processor's Nodes From: John Peterson - 2006-11-02 04:37:40 ```Roy Stogner writes: > On Wed, 1 Nov 2006, Travis Austin wrote: > I think in the long term the right solution is to create local node > iterators (another subclass of variant_filter_iterator?), but that's > probably more trouble than you want to go through. Since it is a DofObject, you can ask a Node its processor_id() and (though I am not exactly sure what will be returned since nodes are shared between subdomains) I think it will be the minimum ID of all the elements which share the node. If this is the case, creating the local_nodes_begin() and local_nodes_end() iteration interface is indeed possible. This would not be any more efficient than what Roy suggested, it might make writing the loops slightly easier though. -John ```
 [Libmesh-users] Looping over Processor's Nodes From: John Peterson - 2006-11-02 04:42:41 ```Oh by the way, do you need to compute the reaction values based on the solution at the _nodes_ or at the Gaussian quadrature points? -J Travis Austin writes: > > Hi, > > I'm with a group at the University of Auckland hoping to convince everyone to have libmesh be the basis > for our new software. Currently we are focusing on reaction-diffusion problems so I have built a simple > reaction-diffusion code using libmesh that can run on multiple processors. However I think it could be > more efficient when solving the reaction part. We are currently using linear finite elements so DOFs > are only located at vertices of rectangles and hexs. > > I've got code (seen below) to solve the reaction part at every DOF. It uses the standard method of > looping over elements. The call to cubic.react solves the reaction problem, and in general, can be > expensive so I only want to do it once. > > Currently this approach has me solving reaction (by building up the src vector) multiple times since one > DOF shares many elements. I'd like to only loop over nodes but it appears to be that mesh.nodes_begin() > and mesh.nodes_end() provides a start and end for ALL of the nodes, not the local nodes. > > Does anyone have a solution for looping over all nodes on your local processor without using the following > element-based loop? (I accept that I will solve this reaction problem twice at nodes sitting between processor > boundaries.) > > Travis Austin > > MeshBase::const_element_iterator elem_it = mesh.active_local_elements_begin(); > const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end(); > > for ( ; elem_it != elem_end; ++elem_it) > { > > const Elem* elem = *elem_it; > > dof_map.dof_indices (elem, dof_indices); > > assert (dof_indices.size() <= elem->n_nodes()); > > for (unsigned int i=0; i if ((dof_indices[i] >= src.first_local_index()) && > (dof_indices[i] < src.last_local_index())) > { > // Get local node point > const Point& ep = elem->point (i); > // Get current stimulus for point > const Real stim = Is1(dof_indices[i],ep,time); > // Set stimulus to be used in solving reaction problem > src.set(dof_indices[i],(cubic.react(soln(dof_indices[i]),dt,stim)/Cm)); > } > > } ```