[Trilinos-Users] FECrs Vector/Matrix
David Neckels
dneckels at ucar.edu
Thu Nov 29 09:51:35 MST 2007
Hi Alan,
Okay. Using your previous explanation as a guide, I reworked things and
figured out what I was doing wrong.
After creating the matrix and vectors with the unique map, and calling
InsertValues, I was calling a version of
SumIntoGlobalValues
that exists only in the base class, Epetra_CrsMatrix:
int SumIntoGlobalValues(int GlobalRow, int NumEntries, double* Values,
int* Indices);
Obviously, since the function is in the base class it didn't know about
the extra (shared rows), and so it would return an error.
I now call:
int SumIntoGlobalValues(int numRows, const int* rows,
int numCols, const int* cols,
const double* values,
int format=Epetra_FECrsMatrix::COLUMN_MAJOR);
from Epetra_FECrsMatrix, which works correctly.
Also, after assembly I apply dirichlet boundary conditions by replacing
the row for a dirichlet dof. I call
int ret = matrix->ExtractGlobalRowView(row_id, nentries, old_row,
old_indices);
followed by
matrix->ReplaceGlobalValues(1, &row_id, nentries, old_indices, &new_row[0]);
At first this wasn't working correctly for shared dofs, since the
ExtractView didn't know about the shared dofs on non-owning side (it is
a function in the base class CrsMatrix).
What seems to work is to call:
matrix->GlobalAssemble(false /* don't fillcomplete */ );
and then extract the row and replace, on the owning processor.....
I don't know how I was getting away with my previous unique/shared map
approach. It was giving the right answer, but I notice that my matrices
are much better conditioned now.... A fluke, I guess.
Thanks a lot for the help.
-David N.
Williams, Alan B wrote:
> If you can give me some example code that reproduces the -1
> return-errors you're seeing, I'll figure out what's going on.
>
> Perhaps there is a bug in FECrsMatrix.
>
> Alan
>
>
>
>> -----Original Message-----
>> From: David Neckels [mailto:dneckels at ucar.edu]
>> Sent: Wednesday, November 28, 2007 6:07 PM
>> To: Williams, Alan B
>> Cc: trilinos-users at software.sandia.gov
>> Subject: Re: [Trilinos-Users] FECrs Vector/Matrix
>>
>> Hi Alan,
>>
>> Thanks for responding, good to hear from you, hope all is well!
>>
>> I appreciate the basic explanation, I think it helps
>> understand the theory on using the classes better.
>> However, I still don't seem to have luck with things. I have
>> now tried:
>>
>> matrix = new Epetra_FECrsMatrix(Copy, *unique_map, max_df);
>>
>> x = new Epetra_FEVector(*unique_map); //( solving Ax=b) b =
>> new Epetra_FEVector(*unique_map);
>>
>> Call InsertGlobalValues for the shared set of dofs to build
>> the matrix stencil.
>>
>> Then,
>> during assembly call SumIntoGlobalValues for the same set of
>> dofs (the shared and unique dofs).
>> However, for shared dofs this function now returns -1 !!
>>
>> I then close the assembly:
>> matrix->GlobalAssembly();
>> b->GlobalAssembly()
>>
>> This gives the wrong result...
>> I notice that calling the InsertGlobalValues alone does
>> appear to correctly sum the entries, but it doesn't seem to
>> play well with SumIntoGlobalValues for some reason.
>>
>> For this example I am not using ReplaceGlobalValues; I have
>> no constraints...
>>
>> If you like I can try to boil this down to a simple example....??
>>
>> Thanks,
>> David N.
>>
>>
>> // insert rows with all (shared) dofs
>> // sum into global with all (shared) dofs --here is I used
>> unique_map to create the matrix, above, I would get bad
>> return values??
>> // Call ExtractGlobalView and replace constrained rows of the
>> matrix for shared dofs (unique_map in the matrix create
>> caused this to fail) // Also sum into shared dofs of b
>>
>> // After assembly:
>> matrix->GlobalAssemble(*umap, *umap);
>> b->GlobalAssemble();
>>
>>
>>
>>
>> Williams, Alan B wrote:
>>
>>> Hi David,
>>>
>>> The "FE" epetra objects are intended to handle the situation you
>>> describe, where shared nodes exist on multiple processors,
>>>
>> so you're
>>
>>> on the right track.
>>>
>>> As you know, the non-FE epetra objects tend to be used for the
>>> uniquely-owned case, where the Epetra_Map attribute has
>>> non-overlapping entries.
>>>
>>> The general idea is that the FE objects allow a
>>>
>> finite-element caller
>>
>>> to assemble data on the local processor (i.e. overlapping data for
>>> shared nodes), which may end up on another processor in the
>>> non-overlapping distribution.
>>>
>>> The FE objects inherit their non-FE counterparts
>>>
>> (FECrsMatrix inherits
>>
>>> CrsMatrix, etc), and the Epetra_Map objects that are passed as
>>> constructor arguments should describe the uniquely-owned,
>>> non-overlapping distribution (which is what you want the underlying
>>> CrsMatrix to end up with).
>>>
>>> When you assemble data into an FE object, it checks whether
>>>
>> the data
>>
>>> is local according to the Epetra_Map object it was
>>>
>> constructed with.
>>
>>> If so, that data is passed straight through to the non-FE
>>>
>> base-class
>>
>>> object. If the data belongs on another processor, then it is held
>>> locally in "temporary" data structures until the
>>>
>> GlobalAssemble method is called.
>>
>>> GlobalAssemble uses Import/Export operations to send that
>>>
>> data to the
>>
>>> appropriate owning processors, where it is placed into the non-FE
>>> base-class object.
>>>
>>> So you should create your FECrsMatrix with the
>>>
>> non-overlapping row-map.
>>
>>> FECrsMatrix shouldn't need your shared-map at all. Note
>>>
>> that the map
>>
>>> arguments which are passed to the GlobalAssemble method are the
>>> domain-map and range-map for the underlying CrsMatrix, which is the
>>> target of the global assembly. In general, a CrsMatrix has 4 maps:
>>> row-map, column-map, domain-map and range-map. In some cases the
>>> domain-map is different than the column-map, and the range-map is
>>> different than the row-map. See the doxygen documentation for
>>> Epetra_CrsGraph for a description of these 4 map attributes. (At
>>> trilinos.sandia.gov, go to packages => epetra => documentation.)
>>>
>>> The GlobalAssemble method should work without any map arguments in
>>> most cases. (It internally obtains the domain-map and
>>>
>> range-map from
>>
>>> the underlying CrsMatrix.)
>>>
>>> Let me know if this doesn't clear things up for you, or if you are
>>> still seeing errors.
>>>
>>> Note that non-zero return-values for SumIntoGlobalValues don't
>>> necessarily indicate an error. If the return-value is a positive
>>> number, it simply means that the matrix did an internal
>>>
>> allocation in
>>
>>> the process of storing the input values, because it wasn't
>>>
>> constructed
>>
>>> with enough information to pre-allocate all needed nonzero
>>>
>> positions.
>>
>>> If you see a negative return-value, then that's an error.
>>>
>>> Alan
>>>
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: trilinos-users-bounces at software.sandia.gov
>>>> [mailto:trilinos-users-bounces at software.sandia.gov] On Behalf Of
>>>> David Neckels
>>>> Sent: Wednesday, November 28, 2007 3:12 PM
>>>> To: trilinos-users at software.sandia.gov
>>>> Subject: [Trilinos-Users] FECrs Vector/Matrix
>>>>
>>>> Hi,
>>>>
>>>> I installed the Epetra_FECrsMatrix and Epetra_FEVector
>>>>
>> classes in a
>>
>>>> parallel finite element code, but had some trouble figured
>>>>
>> out how to
>>
>>>> use the classes and their Epetra_Map's. I settled on
>>>>
>> something that
>>
>>>> seems to work, but wasn't sure if it was correct?
>>>>
>>>> My code partitions on element boundary's, so faces, edges,
>>>>
>> and nodes
>>
>>>> on a shared element side exist on more than one processor.
>>>> Hence although each degree of freedom is owned by only one
>>>>
>> processor,
>>
>>>> it may reside on multiple processors.
>>>>
>>>> I have two corresponding Epetra_Map's:
>>>> unique_map: contains only the owned dofs on a processor
>>>>
>> (partitions
>>
>>>> the problem by processors).
>>>> shared_map: has overlap, i.e. a dof will appear on each processor
>>>> where the dof resides.
>>>>
>>>> This was the sequence that seemed to work:
>>>>
>>>> matrix = new Epetra_FECrsMatrix(Copy, *shared_map,
>>>>
>> max_df); x = new
>>
>>>> Epetra_FEVector(*shared_map); //( solving Ax=b) b = new
>>>> Epetra_FEVector(*unique_map);
>>>>
>>>> // insert rows with all (shared) dofs // sum into global with all
>>>> (shared) dofs --here is I used unique_map to create the matrix,
>>>> above, I would get bad return values??
>>>> // Call ExtractGlobalView and replace constrained rows of
>>>>
>> the matrix
>>
>>>> for shared dofs (unique_map in the matrix create caused
>>>>
>> this to fail)
>>
>>>> // Also sum into shared dofs of b
>>>>
>>>> // After assembly:
>>>> matrix->GlobalAssemble(*umap, *umap);
>>>> b->GlobalAssemble();
>>>>
>>>> // Call Aztec solver....
>>>>
>>>> This dance between the unique and shared maps seemed strange.
>>>> I just wondered if a more thorough example for using the
>>>>
>> FE classes
>>
>>>> existed, or if someone knew what the correct approach was?
>>>>
>> For now
>>
>>>> things seem to work....
>>>>
>>>> I have attached the routine where I set these maps up.
>>>>
>>>> Thanks for any help.
>>>>
>>>> -David N.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>
More information about the Trilinos-Users
mailing list