MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
dirichlet_boundary_condition.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 // MAST includes
23 
24 
25 // libMesh includes
26 #include "libmesh/zero_function.h"
27 
28 void
30 init(const libMesh::boundary_id_type bid,
31  const std::vector<unsigned int>& constrained_vars,
33  libMesh::VariableIndexing index,
34  unsigned int n_sys_vars) {
35 
36  // should not have been initialized if this is called
37  libmesh_assert(_dirichlet_boundary.get() == nullptr);
38 
39  std::set<libMesh::boundary_id_type> bid_set;
40  bid_set.insert(bid);
41 
42  if (!f_val) {
43 
44  // if the function was not give, then assume it to be zero function
45  std::unique_ptr<libMesh::FunctionBase<Real> >
46  function(new libMesh::ZeroFunction<Real>);
47 
48  _dirichlet_boundary.reset(new libMesh::DirichletBoundary(bid_set,
49  constrained_vars,
50  function.get()));
51  }
52  else {
53 
54  // make sure that the number of variables is specified if indexing
55  // is set to system_variable_order.
56  if (index == libMesh::SYSTEM_VARIABLE_ORDER)
57  libmesh_assert_greater(n_sys_vars, 0);
58 
59  // create a wrapper to the provided field function and pass it to the
60  // DirichletBoundary object
61  class FunctionWrapper: public libMesh::FunctionBase<Real> {
62  public:
63  FunctionWrapper(MAST::FieldFunction<RealVectorX>& f,
64  libMesh::VariableIndexing index,
65  unsigned int n_constrained_vars,
66  unsigned int n_sys_vars):
67  libMesh::FunctionBase<Real>(),
68  _f(f),
69  _index(index),
70  _n_constrained_vars(n_constrained_vars),
71  _n_sys_vars(n_sys_vars) {
72 
73  if (_index == libMesh::SYSTEM_VARIABLE_ORDER)
74  libmesh_assert_greater(n_sys_vars, 0);
75  }
76 
77  // copy constructor
78  FunctionWrapper(const FunctionWrapper& f):
79  libMesh::FunctionBase<Real>(),
80  _f(f._f),
81  _index(f._index),
82  _n_constrained_vars(f._n_constrained_vars),
83  _n_sys_vars(f._n_sys_vars) { }
84 
85  virtual ~FunctionWrapper() {}
86 
87  virtual std::unique_ptr<libMesh::FunctionBase<Real>> clone () const {
88 
89  std::unique_ptr<libMesh::FunctionBase<Real>> f;
90  f.reset(new FunctionWrapper(*this));
91  return f;
92  }
93 
100  virtual Real operator() (const libMesh::Point & p,
101  const Real time = 0.) {
102  // should not get called
103  libmesh_error();
104  }
105 
106  virtual void operator() (const libMesh::Point & p,
107  const Real time,
108  libMesh::DenseVector<Real>& output) {
109 
110  RealVectorX v;
111  _f(p, time, v);
112 
113  if (_index == libMesh::SYSTEM_VARIABLE_ORDER) {
114  libmesh_assert_equal_to(v.size(), _n_sys_vars);
115  output.resize(_n_sys_vars);
116  for (unsigned int i=0; i<_n_sys_vars; i++) output(i) = v(i);
117  }
118  else if (_index == libMesh::LOCAL_VARIABLE_ORDER) {
119 
120  libmesh_assert_equal_to(v.size(), _n_constrained_vars);
121  output.resize(_n_constrained_vars);
122  for (unsigned int i=0; i<_n_constrained_vars; i++) output(i) = v(i);
123  }
124  }
125 
126 
127  protected:
129  libMesh::VariableIndexing _index;
130  unsigned int _n_constrained_vars;
131  unsigned int _n_sys_vars;
132  };
133 
134  std::unique_ptr<libMesh::FunctionBase<Real>>
135  function(new FunctionWrapper(*f_val,
136  index,
137  constrained_vars.size(),
138  n_sys_vars));
139 
140  _dirichlet_boundary.reset(new libMesh::DirichletBoundary(bid_set,
141  constrained_vars,
142  *function,
143  index));
144  }
145 }
146 
147 
std::unique_ptr< libMesh::DirichletBoundary > _dirichlet_boundary
Dirichlet boundary function for this boundary.
libMesh::Real Real
Matrix< Real, Dynamic, 1 > RealVectorX
void init(const libMesh::boundary_id_type bid, const std::vector< unsigned int > &constrained_vars, MAST::FieldFunction< RealVectorX > *f_val=nullptr, libMesh::VariableIndexing index=libMesh::SYSTEM_VARIABLE_ORDER, unsigned int n_sys_vars=0)
initializes the object for the specified domain id (either boundary, or subdomain), for the displacement components initialized using a bitwise operator.