Comment 15 for bug 1083720

Revision history for this message
Johan Hake (johan-hake) wrote : Re: [Bug 1083720] Re: replace() fails if the new function spaces have a different mesh

On 11/28/2012 08:58 PM, Joachim Haga wrote:
>>> Will the circular references "functionspace <->
>>> testfunction" be a problem for garbage collection?
>>
>> Yes.
>
> I am not familiar with the particulars here, but the circular
> references are only a problem if the objects have custom deleters
> (__del__ methods). Swig likes to generate (empty) __del__ methods, but
> they can be disabled by the should-have-been-default flag
> --noproxydel.

Ok, nice to know. Also see:

http://stackoverflow.com/questions/2428301/should-i-worry-about-circular-references-in-python

for some nice references.

It also seems like none of the classes implements __del__ so in theory
we should be fine. The thread above do mention possible slowness in
performance in these type of garbage collections, but I guess that would
be for larger chain of circular references?

You could also use weak refs I guess, or just implement the test/trial
count discussed later in the thread.

Johan

> -j.
>
> On 28 November 2012 20:03, Johan Hake <email address hidden> wrote:
>> On 11/28/2012 07:15 PM, Martin Sandve Alnæs wrote:
>>> I fixed this permanently by constructing both test and trial function
>>> simultaneously on demand using Argument(V) and storing them to
>>> V._argument_functions. Will the circular references "functionspace <->
>>> testfunction" be a problem for garbage collection?
>>
>> Yes.
>>
>> I wonder how this can be implemented without some error prone
>> heuristics. A robust, but quite intrusive way, would be to always
>> instantiate a TestFunction together with a TrialFunction whenever one
>> need the latter.
>>
>> Or one could introduce a trial and test space specific counter.
>> Something like:
>>
>> class Argument(.):
>> _test_and_trial_counters = [dict(test=False, trial=False)]
>> ...
>>
>> class TestFunction(.):
>> def __init__(.):
>> .
>> counters = Argument._test_and_trial_counters
>> if counters[-1]["test"]:
>> counters.append(dict(test=False, trial=False))
>> counters[-1]["test"] = True
>> Argument(self, ., count=len(counters)*2)
>>
>> class TrialFunction(.):
>> def __init__(.):
>> .
>> counters = Argument._test_and_trial_counters
>> if counters[-1]["trial"]:
>> counters.append(dict(test=False, trial=False))
>> counters[-1]["trial"] = True
>> Argument(self, ., count=len(counters)*2-1)
>>
>> Johan
>>
>> --
>> You received this bug notification because you are a member of DOLFIN
>> Team, which is subscribed to DOLFIN.
>> https://bugs.launchpad.net/bugs/1083720
>>
>> Title:
>> replace() fails if the new function spaces have a different mesh
>>
>> Status in DOLFIN:
>> Fix Committed
>>
>> Bug description:
>> I submit this bug report following Marie's suggestions on the related
>> DOLFIN question
>> (https://answers.launchpad.net/dolfin/+question/215120)
>>
>> DOLFIN crashes in the solve() routine after using replace() to replace
>> the function spaces of a form.
>>
>> While the solve succeeds if replaced function spaces have:
>> - a different polynomial degree or
>> - a different polynomial degree and a different mesh,
>> it does not work if the new function spaces is based on a new mesh only.
>>
>> This is the error message I get:
>> *** -------------------------------------------------------------------------
>> *** Error: Unable to define linear variational problem a(u, v) = L(v) for all v.
>> *** Reason: Expecting the solution variable u to be a member of the trial space.
>> *** Where: This error was encountered inside LinearVariationalProblem.cpp.
>> *** ------------------------------------------------------------------------
>>
>> The attached file demonstrates the problem.
>>
>> To manage notifications about this bug go to:
>> https://bugs.launchpad.net/dolfin/+bug/1083720/+subscriptions
>