<jupyter_start><jupyter_text>*This notebook requires fenicstools to generate the DOFs plots*<jupyter_code>import dolfin as df
import numpy as np
import finmag<jupyter_output>[2015-04-15 15:28:49] INFO: Finmag logging output will be appended to file: '/home/david/.finmag/global.log'
[2015-04-15 15:28:49] DEBUG: Building modules in 'native'...
[2015-04-15 15:28:50] DEBUG: FinMag          5797:b416a2672cfee657ac9e9aaf8d69f7daeb55227d
[2015-04-15 15:28:50] DEBUG: Dolfin          1.5.0                Matplotlib      lazily loaded       
[2015-04-15 15:28:50] DEBUG: Numpy           1.9.2                Scipy           0.13.3              
[2015-04-15 15:28:50] DEBUG: IPython         3.1.0                Python          2.7.6               
[2015-04-15 15:28:50] DEBUG: Paraview        4.0.1-1ubuntu1       Sundials        2.5.0               
[2015-04-15 15:28:50] DEBUG: Boost-Python    <unknown>            Linux           Ubuntu 14.04.2 LTS  
[2015-04-15 15:28:50] DEBUG: Registering debug signal handler. Press Ctrl-Z any time to stop execution and jump into the debugger.<jupyter_text>Generate a 2D sqaure mesh:<jupyter_code>mesh = df.RectangleMesh(-4, -4, 4, 4, 4, 4)
df.plot(mesh, interactive=True)<jupyter_output><empty_output><jupyter_text>Mesh coordinates:<jupyter_code>mesh.coordinates()
S1 = df.FunctionSpace(mesh, 'CG', 1)
S3 = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3)
v_fun = df.Function(S3)<jupyter_output><empty_output><jupyter_text>Simulation with PBCs:<jupyter_code>Ms = 1e5
sim = finmag.Simulation(mesh, Ms, unit_length=1e-9, pbc='2d')<jupyter_output>[2015-04-15 15:29:04] INFO: Finmag logging output will be written to file: '/home/david/tmp/PBC_load_test/unnamed.log' (any old content will be overwritten).
[2015-04-15 15:29:04] DEBUG: Creating DataWriter for file 'unnamed.ndt'
[2015-04-15 15:29:04] INFO: Creating Sim object 'unnamed' (rank=0/1).
[2015-04-15 15:29:04] INFO: <Mesh of topological dimension 2 (triangles) with 25 vertices and 32 cells, ordered>
[2015-04-15 15:29:04] DEBUG: Setting 2d periodic boundary conditions (in the xy-plane).
[2015-04-15 15:29:04] DEBUG: Creating LLG object.<jupyter_text>The values in the boundaries are (0, 0, -1) while the rest of the mesh vertexes will have associated a value of (0, 0, 1)<jupyter_code>def m_init(pos):
    x, y = pos[0], pos[1]
    if x > 3 or x < -3:
        return (0, 0, -1)
    elif y > 3 or y < -3:
        return (0, 0, -1)
    else:
        return (0, 0, 1)
    
sim.set_m(m_init)<jupyter_output><empty_output><jupyter_text>Now we will try to visualize the DOFs ordering and the mesh numbering:<jupyter_code>%matplotlib qt4
import fenicstools<jupyter_output><empty_output><jupyter_text>We can plot the DOFs (degrees of freedom) of the 3 components of the vector field (in the plot windows, press `D` to get the DOFs and `V` to get the vertex numbering). The values are the array indexes of the vector field, which goes into the mesh in the right order, following the **vertex to dof** mapping (see below):<jupyter_code>dmp = fenicstools.DofMapPlotter(sim.S3)
dmp.plot([0, 1, 2])
dmp.show()<jupyter_output>[1;37;34mFigure 1 : Plotting dofmaps [0, 1, 2][0m<jupyter_text>Some values are repeated since they are the PBCs The mesh indexes:  The dolfin vector function (reduced):<jupyter_code>sim.m_field.f.vector().array()<jupyter_output><empty_output><jupyter_text>The Vertex to DOF map give us the mapping for going from the dofin function towards the mesh ordering, which is a **full length** vector (the system including boundaries). It automatically copies the repeated values at the boundaries with PBC:<jupyter_code>v2d = df.vertex_to_dof_map(sim.S3)
v2d<jupyter_output><empty_output><jupyter_text>This gives us the dolfin function values in the same order than the mesh, in the *xyz* order$$ [\underbrace{x_0, y_0, z_0}_\text{node 0}, \underbrace{x_1, y_1, z_1}_\text{node 1}, \underbrace{x_2, y_2, z_2}_\text{node 2}, \ldots  ] $$when calling a dolfin function with the mapping argument. The mapped function in array form looks like:<jupyter_code>vfunction_to_mesh = sim.m_field.f.vector().array()[v2d]
vfunction_to_mesh<jupyter_output><empty_output><jupyter_text>Since we know it is in the *xyz* order with respect to the mesh coordinates, we can print them according to their mesh node association:<jupyter_code>for i in xrange(len(v2d) / 3):
    print sim.mesh.coordinates()[i], ' --> ',  vfunction_to_mesh.reshape(-1, 3)[i]<jupyter_output>[-4. -4.]  -->  [ 0.  0. -1.]
[-2. -4.]  -->  [ 0.  0. -1.]
[ 0. -4.]  -->  [ 0.  0. -1.]
[ 2. -4.]  -->  [ 0.  0. -1.]
[ 4. -4.]  -->  [ 0.  0. -1.]
[-4. -2.]  -->  [ 0.  0. -1.]
[-2. -2.]  -->  [ 0.  0.  1.]
[ 0. -2.]  -->  [ 0.  0.  1.]
[ 2. -2.]  -->  [ 0.  0.  1.]
[ 4. -2.]  -->  [ 0.  0. -1.]
[-4.  0.]  -->  [ 0.  0. -1.]
[-2.  0.]  -->  [ 0.  0.  1.]
[ 0.  0.]  -->  [ 0.  0.  1.]
[ 2.  0.]  -->  [ 0.  0.  1.]
[ 4.  0.]  -->  [ 0.  0. -1.]
[-4.  2.]  -->  [ 0.  0. -1.]
[-2.  2.]  -->  [ 0.  0.  1.]
[ 0.  2.]  -->  [ 0.  0.  1.]
[ 2.  2.]  -->  [ 0.  0.  1.]
[ 4.  2.]  -->  [ 0.  0. -1.]
[-4.  4.]  -->  [ 0.  0. -1.]
[-2.  4.]  -->  [ 0.  0. -1.]
[ 0.  4.]  -->  [ 0.  0. -1.]
[ 2.  4.]  -->  [ 0.  0. -1.]
[ 4.  4.]  -->  [ 0.  0. -1.]<jupyter_text>The DOF to vertex map, which is reduced, is:<jupyter_code>d2v = df.dof_to_vertex_map(sim.S3)
d2v<jupyter_output><empty_output><jupyter_text>This is the opposite mapping, for going from the ordered mesh towards the *original function* (which has a reduced number of elements, since it does not consider the repeated boundaries)<jupyter_code>vfunction_mesh_to_original = vfunction_to_mesh[d2v]
vfunction_mesh_to_original<jupyter_output><empty_output><jupyter_text>To compare this array, the original function was:<jupyter_code>sim.m_field.f.vector().array()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1554520358868185, 'fraction_numerical': 0.0821256038647343, 'mean_word_length': 3.073787772312017, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '39654', 'license': 'BSL-1.0', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2263, 'n_words': 646, 'path': 'dev/sandbox/basics-dolfin/dofs/understanding_indexes_dofs_with_PBCs.ipynb', 'repo_name': 'davidcortesortuno/finmag', 'size': '5796'}