2
2
// Licensed under the GNU LGPL Version 2.1.
4
4
// Modified by Kristian Oelgaard, 2007
5
// Modified by Johan Hake, 2009
6
7
// First added: 2007-04-10
7
// Last changed: 2008-12-12
8
// Last changed: 2009-10-04
9
10
// FIXME: This class needs some cleanup, in particular collecting
10
11
// FIXME: all data from different representations into a common
27
class GenericFunction;
26
28
class FunctionSpace;
28
30
class GenericMatrix;
29
31
class GenericVector;
31
template<class T> class MeshFunction;
33
template<class T> class MeshFunction;
33
/// The BCMethod variable may be used to specify the type of method
34
/// used to identify degrees of freedom on the boundary. Available
35
/// methods are: topological approach (default), geometric approach,
36
/// and pointwise approach. The topological approach is faster,
37
/// but will only identify degrees of freedom that are located on a
38
/// facet that is entirely on the boundary. In particular, the
39
/// topological approach will not identify degrees of freedom
40
/// for discontinuous elements (which are all internal to the cell).
41
/// A remedy for this is to use the geometric approach. To apply
42
/// pointwise boundary conditions e.g. pointloads, one will have to
43
/// use the pointwise approach which in turn is the slowest of the
44
/// three possible methods.
45
enum BCMethod {topological, geometric, pointwise};
47
35
/// This class specifies the interface for setting (strong)
48
36
/// Dirichlet boundary conditions for partial differential
53
41
/// where u is the solution to be computed, g is a function
54
42
/// and G is a sub domain of the mesh.
56
/// A DirichletBC is specified by the Function g, the FunctionSpace
44
/// A DirichletBC is specified by the function g, the function space
57
45
/// (trial space) and boundary indicators on (a subset of) the mesh
71
59
/// The third option is to attach the boundary information to the
72
60
/// mesh. This is handled automatically when exporting a mesh from
73
61
/// for example VMTK.
63
/// The BCMethod variable may be used to specify the type of method
64
/// used to identify degrees of freedom on the boundary. Available
65
/// methods are: topological approach (default), geometric approach,
66
/// and pointwise approach. The topological approach is faster, but
67
/// will only identify degrees of freedom that are located on a
68
/// facet that is entirely on the boundary. In particular, the
69
/// topological approach will not identify degrees of freedom for
70
/// discontinuous elements (which are all internal to the cell). A
71
/// remedy for this is to use the geometric approach. To apply
72
/// pointwise boundary conditions e.g. pointloads, one will have to
73
/// use the pointwise approach which in turn is the slowest of the
74
/// three possible methods. The three possibilties are
75
/// "topological", "geometric" and "pointwise".
77
/// This class specifies the interface for setting (strong)
75
79
class DirichletBC : public BoundaryCondition
79
83
/// Create boundary condition for subdomain
80
84
DirichletBC(const FunctionSpace& V,
85
const GenericFunction& g,
82
86
const SubDomain& sub_domain,
83
BCMethod method=topological);
85
/// Create boundary condition for subdomain specified by index
86
DirichletBC(const FunctionSpace& V,
88
const MeshFunction<uint>& sub_domains, uint sub_domain,
89
BCMethod method=topological);
91
/// Create boundary condition for boundary data included in the mesh
92
DirichletBC(const FunctionSpace& V,
95
BCMethod method=topological);
87
std::string method="topological");
89
/// Create boundary condition for subdomain
90
DirichletBC(boost::shared_ptr<const FunctionSpace> V,
91
boost::shared_ptr<const GenericFunction> g,
92
boost::shared_ptr<const SubDomain> sub_domain,
93
std::string method="topological");
95
/// Create boundary condition for subdomain specified by index
96
DirichletBC(const FunctionSpace& V,
97
const GenericFunction& g,
98
const MeshFunction<uint>& sub_domains, uint sub_domain,
99
std::string method="topological");
101
/// Create boundary condition for subdomain specified by index
102
DirichletBC(boost::shared_ptr<const FunctionSpace> V,
103
boost::shared_ptr<const GenericFunction> g,
104
const MeshFunction<uint>& sub_domains, uint sub_domain,
105
std::string method="topological");
107
/// Create boundary condition for boundary data included in the mesh
108
DirichletBC(const FunctionSpace& V,
109
const GenericFunction& g,
111
std::string method="topological");
113
/// Create boundary condition for boundary data included in the mesh
114
DirichletBC(boost::shared_ptr<const FunctionSpace> V,
115
boost::shared_ptr<const GenericFunction> g,
117
std::string method="topological");
112
134
/// Apply boundary condition to a linear system for a nonlinear problem
113
135
void apply(GenericMatrix& A, GenericVector& b, const GenericVector& x) const;
115
/// Make row associated with boundary conditions zero, useful for non-diagonal matrices in a block matrix.
137
/// Make row associated with boundary conditions zero, useful for non-diagonal matrices in a block matrix.
116
138
void zero(GenericMatrix& A) const;
118
/// Get Dirichlet values and indicators
140
/// Get Dirichlet values and indicators
119
141
void get_bc(uint* indicators, double* values) const;
121
143
/// Check if given function is compatible with boundary condition (checking only vertex values)
122
bool is_compatible(Function& v) const;
144
bool is_compatible(GenericFunction& v) const;
126
148
// Apply boundary conditions
127
149
void apply(GenericMatrix* A, GenericVector* b, const GenericVector* x) const;
129
151
// Check input data to constructor
130
152
void check() const;
133
155
void check(GenericMatrix* A, GenericVector* b, const GenericVector* x) const;
135
157
// Initialize sub domain markers from sub domain
136
void init_from_sub_domain(const SubDomain& sub_domain);
158
void init_from_sub_domain(boost::shared_ptr<const SubDomain> sub_domain);
138
160
// Initialize sub domain markers from MeshFunction
139
161
void init_from_mesh_function(const MeshFunction<uint>& sub_domains, uint sub_domain);
141
163
// Initialize sub domain markers from mesh
142
164
void init_from_mesh(uint sub_domain);
144
166
// Compute dofs and values for application of boundary conditions
145
167
void compute_bc(std::map<uint, double>& boundary_values,
146
168
BoundaryCondition::LocalData& data) const;
148
170
// Compute boundary values for facet (topological approach)
149
171
void compute_bc_topological(std::map<uint, double>& boundary_values,
150
172
BoundaryCondition::LocalData& data) const;
152
174
// Compute boundary values for facet (geometrical approach)
153
175
void compute_bc_geometric(std::map<uint, double>& boundary_values,
154
176
BoundaryCondition::LocalData& data) const;
156
178
// Compute boundary values for facet (pointwise approach)
157
179
void compute_bc_pointwise(std::map<uint, double>& boundary_values,
158
180
BoundaryCondition::LocalData& data) const;
160
182
// Check if the point is in the same plane as the given facet
161
183
bool on_facet(double* coordinates, Facet& facet) const;
186
boost::shared_ptr<const GenericFunction> g;
191
// Possible search methods
192
static const std::set<std::string> methods;
169
194
// User defined sub domain
170
const SubDomain* user_sub_domain;
195
boost::shared_ptr<const SubDomain> user_sub_domain;
172
197
// Boundary facets, stored as pairs (cell, local facet number)
173
198
std::vector< std::pair<uint, uint> > facets;