GRINS-0.8.0
pressure_pinning.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2017 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 
26 // This class
27 #include "grins/pressure_pinning.h"
28 
29 // GRINS
30 #include "grins/assembly_context.h"
31 
32 // libMesh
33 #include "libmesh/getpot.h"
34 #include "libmesh/elem.h"
35 #include "libmesh/fe_interface.h"
36 #include "libmesh/mesh_base.h"
37 #include "libmesh/parallel.h"
38 
39 namespace GRINS
40 {
41 
42  PressurePinning::PressurePinning( const GetPot& input,
43  const std::string& physics_name )
44  : _pinned_elem_id(libMesh::DofObject::invalid_id)
45  {
46  _pin_value = input("Physics/"+physics_name+"/pin_value", 0.0 );
47 
48  unsigned int pin_loc_dim = input.vector_variable_size("Physics/"+physics_name+"/pin_location");
49 
50  // If the user is specifying a pin_location, it had better be at least 2-dimensional
51  if( pin_loc_dim > 0 && pin_loc_dim < 2 )
52  {
53  std::cerr << "Error: pressure pin location must be at least 2 dimensional"
54  << std::endl;
55  libmesh_error();
56  }
57 
58  _pin_location(0) = input("Physics/"+physics_name+"/pin_location", 0.0, 0 );
59 
60  if( pin_loc_dim > 1 )
61  _pin_location(1) = input("Physics/"+physics_name+"/pin_location", 0.0, 1 );
62 
63  if( pin_loc_dim == 3 )
64  _pin_location(2) = input("Physics/"+physics_name+"/pin_location", 0.0, 2 );
65 
66  return;
67  }
68 
70  {
71  return;
72  }
73 
74  void PressurePinning::check_pin_location( const libMesh::MeshBase& mesh )
75  {
76  // We need to reset to invalid_id since this may not be the first time called
77  _pinned_elem_id = libMesh::DofObject::invalid_id;
78 
79  libMesh::MeshBase::const_element_iterator el = mesh.active_local_elements_begin();
80  const libMesh::MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();
81 
82  for ( ; el != end_el; ++el)
83  {
84  const libMesh::Elem* elem = *el;
85 
86  if( elem->contains_point(_pin_location) )
87  {
88  _pinned_elem_id = elem->id();
89  break;
90  }
91  }
92 
93  // If we found the point on one of the processors, then we need
94  // to tell all the others. invalid_id is exceedingly large,
95  // so if we found an element, that id should be the smallest
96  mesh.comm().min( _pinned_elem_id );
97 
98  if( _pinned_elem_id == libMesh::DofObject::invalid_id )
99  {
100  libMesh::err << "ERROR: Could not locate point " << _pin_location
101  << " in mesh!" << std::endl;
102  libmesh_error();
103  }
104  }
105 
106  void PressurePinning::pin_value( libMesh::DiffContext &context,
107  const bool request_jacobian,
108  const VariableIndex var,
109  const double penalty )
110  {
111  // Make sure we've called check_pin_location() and that pin location
112  // is in the mesh somewhere
113  libmesh_assert_not_equal_to( _pinned_elem_id, libMesh::DofObject::invalid_id );
114 
116  AssemblyContext &c = libMesh::cast_ref<AssemblyContext&>(context);
117 
118  if( c.get_elem().id() == _pinned_elem_id )
119  {
120  // This is redundant for vast majority of cases, but we trying to
121  // be prepared for cases involving, e.g. mesh motion that we're not
122  // currently handling.
123  if( !c.get_elem().contains_point(_pin_location) )
124  {
125  libmesh_error_msg("ERROR: _pin_location not in the current element!");
126  }
127 
128  libMesh::DenseSubVector<libMesh::Number> &F_var = c.get_elem_residual(var); // residual
129  libMesh::DenseSubMatrix<libMesh::Number> &K_var = c.get_elem_jacobian(var, var); // jacobian
130 
131  // The number of local degrees of freedom in p variable.
132  const unsigned int n_var_dofs = c.get_dof_indices(var).size();
133 
134  libMesh::Number var_value = c.point_value(var, _pin_location);
135 
136  libMesh::FEType fe_type = c.get_element_fe(var)->get_fe_type();
137 
138  libMesh::Point point_loc_in_masterelem =
139  libMesh::FEInterface::inverse_map(c.get_dim(), fe_type, &c.get_elem(), _pin_location);
140 
141  std::vector<libMesh::Real> phi(n_var_dofs);
142 
143  for (unsigned int i=0; i != n_var_dofs; i++)
144  phi[i] = libMesh::FEInterface::shape( c.get_dim(), fe_type, &c.get_elem(), i,
145  point_loc_in_masterelem );
146 
147  for (unsigned int i=0; i != n_var_dofs; i++)
148  {
149  F_var(i) += penalty*(var_value - _pin_value)*phi[i];
150 
152  if (request_jacobian && c.get_elem_solution_derivative())
153  {
154  libmesh_assert (c.get_elem_solution_derivative() == 1.0);
155 
156  for (unsigned int j=0; j != n_var_dofs; j++)
157  K_var(i,j) += penalty*phi[i]*phi[j];
158 
159  } // End if request_jacobian
160  } // End i loop
161  } // End if pin_location
162 
163  return;
164  }
165 
166 } // namespace GRINS
unsigned int VariableIndex
More descriptive name of the type used for variable indices.
Definition: var_typedefs.h:42
libMesh::Point _pin_location
Location we want to pin the pressure.
GRINS namespace.
void check_pin_location(const libMesh::MeshBase &mesh)
Check the mesh to ensure pin location is found.
libMesh::dof_id_type _pinned_elem_id
Cache element id for element that contains _pin_location.
void pin_value(libMesh::DiffContext &context, const bool request_jacobian, const GRINS::VariableIndex var, const double penalty=1.0)
The idea here is to pin a variable to a particular value if there is a null space - e...
libMesh::Number _pin_value
Value of pressure we wish to pin.
PressurePinning(const GetPot &input, const std::string &physics_name)

Generated on Tue Dec 19 2017 12:47:27 for GRINS-0.8.0 by  doxygen 1.8.9.1