1
// Copyright (C) 2011 Marie E. Rognes
2
// Licensed under the GNU LGPL Version 3.0 or any later version
4
// First added: 2011-01-04
5
// Last changed: 2011-02-21
7
#include <dolfin/fem/UFC.h>
8
#include <dolfin/mesh/Cell.h>
9
#include <dolfin/mesh/Facet.h>
10
#include "LocalAssembler.h"
12
using namespace dolfin;
14
//------------------------------------------------------------------------------
15
void LocalAssembler::assemble(arma::mat& A,
18
const MeshFunction<uint>* cell_domains,
19
const MeshFunction<uint>* exterior_facet_domains,
20
const MeshFunction<uint>* interior_facet_domains)
25
// Assemble contributions from cell integral
26
assemble_cell(A, ufc, cell, cell_domains);
28
// Assemble contributions from facet integrals
29
for (FacetIterator facet(cell); !facet.end(); ++facet)
31
if (facet->num_entities(cell.dim()) == 2)
32
assemble_interior_facet(A, ufc, cell, *facet,
33
facet.pos(), interior_facet_domains);
35
assemble_exterior_facet(A, ufc, cell, *facet,
36
facet.pos(), exterior_facet_domains);
39
//------------------------------------------------------------------------------
40
void LocalAssembler::assemble_cell(arma::mat& A,
43
const MeshFunction<uint>* domains)
45
// Skip if there are no cell integrals
46
if (ufc.form.num_cell_domains() == 0)
49
// Extract default cell integral
50
ufc::cell_integral* integral = ufc.cell_integrals[0].get();
52
// Get integral for sub domain (if any)
53
if (domains && domains->size() > 0)
55
const uint domain = (*domains)[cell];
56
if (domain < ufc.form.num_cell_domains())
57
integral = ufc.cell_integrals[domain].get();
62
// Skip integral if zero
66
// Update to current cell
69
// Tabulate cell tensor
70
integral->tabulate_tensor(ufc.A.get(), ufc.w, ufc.cell);
72
// Stuff a_ufc.A into A
73
const uint M = A.n_rows;
74
const uint N = A.n_cols;
75
for (uint i=0; i < M; i++)
76
for (uint j=0; j < N; j++)
77
A(i, j) += ufc.A[N*i + j];
80
//------------------------------------------------------------------------------
81
void LocalAssembler::assemble_exterior_facet(arma::mat& A,
85
const uint local_facet,
86
const MeshFunction<uint>* domains)
88
// Skip if there are no exterior facet integrals
89
if (ufc.form.num_exterior_facet_domains() == 0)
92
// Extract default exterior facet integral
93
ufc::exterior_facet_integral* integral = ufc.exterior_facet_integrals[0].get();
95
// Get integral for sub domain (if any)
96
if (domains && domains->size() > 0)
98
const uint domain = (*domains)[facet];
99
if (domain < ufc.form.num_exterior_facet_domains())
100
integral = ufc.exterior_facet_integrals[domain].get();
105
// Skip integral if zero
109
// Update to current cell
110
ufc.update(cell, local_facet);
112
// Tabulate exterior facet tensor
113
integral->tabulate_tensor(ufc.A.get(), ufc.w, ufc.cell, local_facet);
115
// Stuff a_ufc.A into A
116
const uint M = A.n_rows;
117
const uint N = A.n_cols;
118
for (uint i=0; i < M; i++)
120
for (uint j=0; j < N; j++)
121
A(i, j) += ufc.A[N*i + j];
124
//------------------------------------------------------------------------------
125
void LocalAssembler::assemble_interior_facet(arma::mat& A,
129
const uint local_facet,
130
const MeshFunction<uint>* domains)
132
// Skip if there are no interior facet integrals
133
if (ufc.form.num_interior_facet_domains() == 0)
136
// Extract default interior facet integral
137
ufc::interior_facet_integral* integral = ufc.interior_facet_integrals[0].get();
139
// Get integral for sub domain (if any)
140
if (domains && domains->size() > 0)
142
const uint domain = (*domains)[facet];
143
if (domain < ufc.form.num_interior_facet_domains())
144
integral = ufc.interior_facet_integrals[domain].get();
149
// Skip integral if zero
153
// Update to current pair of cells and facets
154
ufc.update(cell, local_facet, cell, local_facet);
156
// Tabulate interior facet tensor on macro element
157
integral->tabulate_tensor(ufc.macro_A.get(), ufc.macro_w,
158
ufc.cell0, ufc.cell1,
159
local_facet, local_facet);
161
// Stuff upper left quadrant (corresponding to this cell) into A
162
const uint M = A.n_rows;
163
const uint N = A.n_cols;
164
for (uint i=0; i < M; i++)
165
for (uint j=0; j < N; j++)
166
A(i, j) += ufc.macro_A[2*N*i + j]; // FIXME: row/col swap for vectors!
168
//------------------------------------------------------------------------------