Ok.  I've been somewhat following this... and here's my input.

I like option #1.  I truly believe that this is an edge case... if you are 
doing this much advanced stuff then you can worry about clearing your 
preconditioner first.  I don't like the idea that ANY user providing a custom 
preconditioner (which currently isn't a huge deal to do) has to deal with stuff 
so that solving on subsets of the domain in this way works.

But... that really is just my opinion... and certainly might not be popular.  I 
really do appreciate the work that Tim is putting into this and it is a nice 
capability... so don't get me wrong.  I just don't think that enabling a very 
advanced capability like this shouldn't cause simpler capability (like plugging 
in a fairly benign Preconditioner object) to do more work.

This is somewhat similar to the Ghosted vector stuff I was talking about a 
couple of weeks ago.  What did I finally decide?  The impact on the framework 
was too great for just my one (highly specialized) use case... so for now I've 
just handled everything myself until I come up with something clean that 
doesn't impact anyone else (which we are actively working on... but it's not 
ready for primetime yet).

Oh - one more thing.  Moving the burden "to remember" something from a person 
doing something (ie solving on a subset) to another person doing something 
unrelated (ie preconditioning) is a bad idea.  This is in reference to 
possibility #7.  If someone needs to remember to do something... it should be 
the person enabling the more advanced capability.

Ok - as long as I'm sounding negative... I should throw out another option to 
try to be helpful.  How about:

Possibility #8:

Build multiple Preconditioner objects.... one for each subset you want to solve 
on... and associate them that way.  So then we you are solving on one subset it 
uses it's preconditioner... and when you are solving on another it uses _it's_ 
preconditioner.  This would also make it easier to specify _different_ 
preconditioners based on subset... something you might want to do if you are 
solving something like fluid flow in one region and just heat conduction in 
another (for instance).

Other than these objections... if you make changes to the Preconditioner 
object... just let me know so I can modify our preconditioners.

Derek

The reason is that 
On Sep 21, 2010, at 9:51 AM, Roy Stogner wrote:

> 
> Cc:ing this to Derek to make sure he doesn't miss this one; I think
> he's done the most libMesh work with custom preconditioners most
> recently and he might have thoughts or see concerns we're missing.
> 
> My own thoughts:
> 
> On Tue, 21 Sep 2010, Tim Kroeger wrote:
> 
>> One problem just popped up with the subset stuff: PetscLinearSolver keeps 
>> the _pc object constant across solves (... perhaps that was the reason for 
>> using SAME_NONZERO_PATTERN?) unless PetscLinearSolver::clear() is called in 
>> between.  When the subset on which to solve is changed, however, this causes 
>> a PetscError.  Of course, I can let PetscLinearSolver::restrict_solve_to() 
>> call PetscLinearSolver::clear(), but this does not always suffice.  That is, 
>> a given SystemSubset object might change the list of dofs from time to time. 
>> That is, if the subset is selected via the subdomain id and the application 
>> changes some cell's subdomain id (which is done in my application), the 
>> subset changes without a call to PetscLinearSolver::restrict_solve_to().  
>> The question is now: Whose responsibility is it to call 
>> LinearSolver::clear() in this situation?
> 
> That's an interesting case.
> 
>> Possibility #1: The user.  Works of course, but the user is likely to 
>> forget, and this causes a difficult-to-find error.
>> 
>> Possibility #2: The PetscLinearSolver class.  But this class doesn't 
>> directly get to know.  It would have to make a backup of the dof list of the 
>> previous solve and compare it.  That does not seem to be performant.
> 
> Definitely don't like these options.
> 
>> Possibility #3: The SystemSubset class.  This seems natural since this class 
>> has to re-determine the list anyway (which, in the current implementation, 
>> is done in a method that has to be called by the user).  However, the 
>> SystemSubset class has no access to the solver. It has access to the System 
>> object (needs that because of the DofMap), but in general can't assume that 
>> the System is a LinearImplicitSystem.
> 
> Hmm... The SystemSubset is indeed what's responsible for determining
> whether the dof list has changed, so it should be responsible for
> communicating that somehow.
> 
> Call this Possibility #7:
> 
> int SystemSubset::set_revision gets incremented every time the dof
> list changes.  LinearImplicitSystem::last_set_revision stores the
> set_revision that was used to create the current preconditioner.
> Before solving, we check to see whether the set_revisions no longer
> match; if they don't then we clear the preconditioner.
> 
> If the user is creating custom preconditioners, then he has to
> remember to tell SystemSubset to redetermine the dof list manually and
> then create a preconditioner accordingly, but if his code doesn't do
> so then at least he's just stuck with a default preconditioner, not a
> broken one.
> 
>> Possibility #4: The SystemSubset class calls System::restrict_solve_to(this) 
>> in the described situation, and LinearImplicitSystem::restrict_solve_to() 
>> calls LinearSolver::clear(). The latter has to be done anyway, of course. 
>> The problem with this is that it cannot be assumed that the System is 
>> actually currently restricted to the given SystemSubset.  That is, the user 
>> could create several SystemSubset objects for the same System and activate 
>> them one after each other, to solve the same system of different subsets.
> 
> But unless the System is using the current SystemSubset, that
> SystemSubset never gets called upon to create a new dof list, right?
> 
>> Possibility #5: As #4, but SystemSubset will check first whether System is 
>> currently restricted to *this.
> 
> Even if I'm right about this being unnecessary, it would be a very
> good idea at least as an assertion.
> 
>> Possibility #6: Similarly as #5, but to make it less confusing, the API of 
>> System gets an additional method called 
>> System::update_subset(SystemSubset&), the task of which is to recognize that 
>> the given subset has changed.  That is, 
>> LinearImplicitSystem::update_subset(my_subset) will call 
>> LinearSolver::init() if the System is currently restricted to my_subset, 
>> otherwise do nothing.
> 
> I think it's a matter of opinion whether this is less or more
> confusing than #5. ---
> Roy


------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Libmesh-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-users

Reply via email to