On Sun, Jan 19, 2014 at 04:41:03PM +0000, Garth N. Wells wrote: > We have a long-standing design flaw with GenericTensor::init (and > GenericVector::resize) that has raised its head with the fix to > https://bitbucket.org/fenics-project/dolfin/issue/132. The flaw is that we > allow init() to be called more than once. GenericFoo objects store a > reference to the underlying backend implementation, e.g. a PETSc Mat. Other > objects, e.g. a PETSc KSP, will often store a reference to the matrix or > vector object too. However, if init() is called a second time, the reference > to the underlying object is released and a new object is created. This leads > to a mis-match between objects. In the case of the fix to the SNES interface > bug (Issue 132), the SNES object has a reference to the operator A and the > preconditioner matrix P. In most case, these are the same. However, because > init() is called by default in the assembler, the two SNES matrix pointers no > longer point to the same object. The result is that the solver fails. To use > the fixed SNES interface, a user must now tell the assembler to not reset the > Jacobian. > > Allowing GenericFoo::init() to be called more than once also misleads the > user and does not help the user write good code. Since init() destroys the > underlying object and creates a new one, we should just have the user create > a new object if this is required (which is very rare). This way it’s clear > what’s happening. GenericFoo::init was conceived to do nothing if resizing > was not required, but it is not reasonably possible to perform the necessary > checks as the size, parallel layout and sparsity pattern all need to be > checked. The first is easy to check efficiently, the latter two are not. > Hence, the assemblers call init() by default in DOLFIN. > > I propose that we permit a matrix/vector to be sized/initialised only once. > This is: > > - consistent with the backends (PETSc and Epetra); > - does not obscure what happens behind-the-scene; > - avoids errors and inefficiencies when other objects hold references to > the underlying data; and > - will help users write faster code (considerably faster in many cases) by > re-using matrix data structures rather than frequent behind-the-scenes > destruction and rebuilding. > > If init() is called twice, we can throw an error. During a transition, this > can be a warning. The assemblers will not need the ‘reset_tensor’ option > because the assembler will only initialise an empty matrix. > > Garth
This sounds good. The GenericFoo interface was designed 7 years ago when all we needed to check was the global size. -- Anders _______________________________________________ fenics mailing list [email protected] http://fenicsproject.org/mailman/listinfo/fenics
