On Wed, Sep 8, 2010 at 2:28 AM, Dave Makhija <span dir="ltr"><<a href="mailto:makhijad@colorado.edu">makhijad@colorado.edu</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I used to have a decent setup that worked as follows:<br>
<br>
1. Build node->element table (For a given node, which elements contain<br>
this node. You may already have this) OR build a node connectivity<br>
table (For a given node, which nodes are connected).<br>
2. Build element->node table (For a given element, which nodes are<br>
contained in this element. You probably already have this)<br>
4. Loop over nodes and get the global DOFs contained in that node. For<br>
those DOF id rows, add the number of nodal DOFs for each unique node<br>
connected to the current node using the node->element and<br>
element->node table OR the node connectivity table.<br>
5. Loop over elements and add the number of elemental DOFs to each<br>
nodal DOF global id row contained in this element using element->node<br>
table. Also add the number of elemental DOF's and the sum of the nodal<br>
DOF's to the elemental global DOF id rows.<br>
6. Add contributions of multi-point constraints, i.e. Lagrange multiplier DOF's.<br>
<br>
Note that in parallel you may have to scatter values to global DOF ids<br>
owned by off-processors to get an accurate Onz. This setup as a whole<br>
can be pretty fast but can scale poorly if you don't have a good way<br>
of developing the node-element table or node connectivity since it<br>
requires some loops within loops.<br>
<br>
Another way is to use the PETSc preallocation macros such as<br>
MatPreallocateSet. You can essentially do a "dry run" of a Jacobian<br>
Matrix assembly into the preallocation macros. They can be tricky to<br>
use, so if you have problems you can simply look at the PETSc<br>
documentation for those macros and hand code them yourself. This<br>
strategy will overestimate the memory, but a matrix inversion will<br>
dwarf how much this will waste. I vaguely remember a PETSc archive<br>
asking how to free the unneeded memory if this is absolutely<br>
necessary, but I don't think anything really worked without a full<br>
matrix copy. If someone by chance knows how the Trilinos<br>
"OptimizeStorage" routine works for Epetra matricies they could<br>
potentially shed some light on how to do this - if it is even<br>
possible.</blockquote><div><br></div><div>If you can assemble the Jacobian, you can count the nonzeros. The only</div><div>subtlety here is nonzeros coming from other processes. However, for finite</div><div>elements with a normal cell division or finite differences with a normal</div>
<div>vertex division, you need only count the nonzeros for rows you own since</div><div>the partitions overlap on the boundary. Distinguishing the diagonal from</div><div>off-diagonal block is easy since you know the rows you own. The whole</div>
<div>process takes a vanishing small time compared to assembly since you are</div><div>not constructing the values.</div><div><br></div><div> Matt</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
Dave Makhija<br>
</font><div><div></div><div class="h5"><br>
<br>
<br>
On Tue, Sep 7, 2010 at 2:24 PM, stali <<a href="mailto:stali@purdue.edu">stali@purdue.edu</a>> wrote:<br>
> Petsc-users<br>
><br>
> How can I efficiently calculate the _exact_ number of non-zeros that would<br>
> be in the global sparse (stiffness) matrix given an unstructured mesh?<br>
><br>
> Thanks<br>
><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br>
-- Norbert Wiener<br>