On Thu, Nov 8, 2012 at 12:34 PM, Mikael Mortensen
<[email protected]> wrote:
> Hi,
>
> The migration of the periodic boundary conditions to the dofmap is now more 
> or less completed. This is a rather large changeset so it would be nice if 
> someone could have a look. Anyone who wants to test it can find it at 
> lp:~mikael-mortensen/dolfin/periodic_to_dofmap.
>

Great. I'll take a look.

Garth

> Best regards
>
> Mikael
>
>
> Den Nov 4, 2012 kl. 6:18 PM skrev Garth N. Wells:
>
>> On Sat, Nov 3, 2012 at 8:28 PM, Mikael Mortensen
>> <[email protected]> wrote:
>>> Hi,
>>>
>>> This week I have been working on migrating the periodic boundary conditions 
>>> to the dofmap. I have made it to the point where I now have working code, 
>>> at least for CG elements, for single and multiple periodic directions, 
>>> regular and mixed functionspaces, 2D/3D and in parallel. Symmetric problems 
>>> remain symmetric also for periodic domains. It is actually not all that 
>>> difficult, but of coarse there are many ways this could be done. My 
>>> suggested approach is implemented in the branch 
>>> lp:~mikael-mortensen/dolfin/periodic_to_dofmap. The code is still a bit 
>>> messy and in need of refinement and optimization. However, it works, which 
>>> makes it a good starting point:-)
>>>
>>
>> Great.
>>
>>> The implemented approach is basically done in 2 steps as follows:
>>>
>>> Step 1) Create a facet-to-facet map linking a facet on one periodic 
>>> boundary to a facet on the other. Store also the processors the facets live 
>>> on.
>>>
>>> The way it's currently implemented is as follows: take a periodic SubDomain 
>>> (just like before with a map) and add this to the mesh:
>>>
>>> periodicX = PeriodicSubDomainX()
>>> periodicY = PeriodicSubDomainY()
>>> mesh.add_periodic_direction(periodicX)
>>> mesh.add_periodic_direction(periodicY)
>>>
>>> or
>>>
>>> mf = FacetFunction(mesh)
>>> mf.set_all(0)
>>> periodicX.mark(mf, 1)
>>> periodicY.mark(mf, 2)
>>> mesh.add_periodic_direction(mf, 1, 2)
>>>
>>> or something like that. Only the first is currently implemented.
>>>
>>> Adding the periodic SubDomain directly to the mesh I think has some 
>>> advantages:
>>>
>>> i) The facet-to-facet map will be common for all FunctionSpaces/dofmaps and 
>>> can be computed just once.
>>>
>>> ii) I think it should be possible(?) do some work on mesh connectivity such 
>>> that the mesh truly bites its tail. A facet on a periodic boundary would 
>>> then have two adjacent cells, just like any other internal facet. The 
>>> periodic boundary would as such no longer be part of the exterior domain. I 
>>> may be wrong, but I think this would be important for DG methods. I have 
>>> not done anything in detail here yet though.
>>>
>>> After adding the periodicity to the mesh, the user does not have to do 
>>> anything more about the periodic boundary conditions . Everything will be 
>>> handled automatically by modifying the dofmaps.
>>>
>>> Step 2) Elimination of slaves from the dofmap._dofmap.
>>>
>>> When a FunctionSpace now creates a dofmap on a periodic mesh everything run 
>>> as normal at first. However, at the end of DofmapBuilder::build I run 
>>> through the facet-to-facet map and efficiently creates a dof pair map of 
>>> masters and slaves. This map is subsequently used to exchange all slaves in 
>>> dofmap._dofmap with masters (and to update off_process_owners).
>>>
>>> The major downside at this point is that we are left with a bunch of slave 
>>> dofs that will never enter computations. To make it work at this point you 
>>> have to ident all slave-rows from an assembled coefficient matrix (I have 
>>> at the moment a call to ident_zeros in case of a periodic mesh placed at 
>>> the end of Assembler::assemble). Nothing has do be done with assembled 
>>> vectors or scalars. After assembly all the slave rows are empty because the 
>>> slaves do not appear in the dofmap._dofmap. After identing and solving all 
>>> slaves are zero, but this does not seem to affect anything like plotting. 
>>> The only problem I have encountered is when using a function like normalize 
>>> that performs work on the entire vector. For that purpose I have created a 
>>> method "update_slaves", that copies the value of masters to slaves. This 
>>> method must be called before the regular normalize.
>>>
>>> I'm currently trying to figure out how (if possible) to get rid of these 
>>> slave dofs entirely. I would very much appreciate if someone had any 
>>> thoughts on this? I probably have to subclass DofMap since then at least 
>>> the global_dimension will be different from the ufc_dofmap.
>>>
>>
>> I would eliminate the dofs in the DofMap. We can make the
>> global_dimension member data rather than going through the ufc dofmap
>> as it does at present. That way the global_dimension can be set by the
>> DofMap class.
>>
>> Garth
>>
>>> I've added a new demo in my branch under demo/undocumented/periodic/python 
>>> that uses this new approach if somebody cares to try it out.
>>>
>>> Best regards
>>>
>>> Mikael
>>>
>>>
>>> _______________________________________________
>>> Mailing list: https://launchpad.net/~dolfin
>>> Post to     : [email protected]
>>> Unsubscribe : https://launchpad.net/~dolfin
>>> More help   : https://help.launchpad.net/ListHelp
>

_______________________________________________
Mailing list: https://launchpad.net/~dolfin
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~dolfin
More help   : https://help.launchpad.net/ListHelp

Reply via email to