GRINS-0.7.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-2016 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  _pin_location(1) = input("Physics/"+physics_name+"/pin_location", 0.0, 1 );
60 
61  if( pin_loc_dim == 3 )
62  _pin_location(2) = input("Physics/"+physics_name+"/pin_location", 0.0, 2 );
63 
64  return;
65  }
66 
68  {
69  return;
70  }
71 
72  void PressurePinning::check_pin_location( const libMesh::MeshBase& mesh )
73  {
74  // We need to reset to invalid_id since this may not be the first time called
75  _pinned_elem_id = libMesh::DofObject::invalid_id;
76 
77  libMesh::MeshBase::const_element_iterator el = mesh.active_local_elements_begin();
78  const libMesh::MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();
79 
80  for ( ; el != end_el; ++el)
81  {
82  const libMesh::Elem* elem = *el;
83 
84  if( elem->contains_point(_pin_location) )
85  {
86  _pinned_elem_id = elem->id();
87  break;
88  }
89  }
90 
91  // If we found the point on one of the processors, then we need
92  // to tell all the others. invalid_id is exceedingly large,
93  // so if we found an element, that id should be the smallest
94  mesh.comm().min( _pinned_elem_id );
95 
96  if( _pinned_elem_id == libMesh::DofObject::invalid_id )
97  {
98  libMesh::err << "ERROR: Could not locate point " << _pin_location
99  << " in mesh!" << std::endl;
100  libmesh_error();
101  }
102  }
103 
104  void PressurePinning::pin_value( libMesh::DiffContext &context,
105  const bool request_jacobian,
106  const VariableIndex var,
107  const double penalty )
108  {
109  // Make sure we've called check_pin_location() and that pin location
110  // is in the mesh somewhere
111  libmesh_assert_not_equal_to( _pinned_elem_id, libMesh::DofObject::invalid_id );
112 
114  AssemblyContext &c = libMesh::libmesh_cast_ref<AssemblyContext&>(context);
115 
116  if( c.get_elem().id() == _pinned_elem_id )
117  {
118  // This is redundant for vast majority of cases, but we trying to
119  // be prepared for cases involving, e.g. mesh motion that we're not
120  // currently handling.
121  if( !c.get_elem().contains_point(_pin_location) )
122  {
123  libmesh_error_msg("ERROR: _pin_location not in the current element!");
124  }
125 
126  libMesh::DenseSubVector<libMesh::Number> &F_var = c.get_elem_residual(var); // residual
127  libMesh::DenseSubMatrix<libMesh::Number> &K_var = c.get_elem_jacobian(var, var); // jacobian
128 
129  // The number of local degrees of freedom in p variable.
130  const unsigned int n_var_dofs = c.get_dof_indices(var).size();
131 
132  libMesh::Number var_value = c.point_value(var, _pin_location);
133 
134  libMesh::FEType fe_type = c.get_element_fe(var)->get_fe_type();
135 
136  libMesh::Point point_loc_in_masterelem =
137  libMesh::FEInterface::inverse_map(c.get_dim(), fe_type, &c.get_elem(), _pin_location);
138 
139  std::vector<libMesh::Real> phi(n_var_dofs);
140 
141  for (unsigned int i=0; i != n_var_dofs; i++)
142  phi[i] = libMesh::FEInterface::shape( c.get_dim(), fe_type, &c.get_elem(), i,
143  point_loc_in_masterelem );
144 
145  for (unsigned int i=0; i != n_var_dofs; i++)
146  {
147  F_var(i) += penalty*(var_value - _pin_value)*phi[i];
148 
150  if (request_jacobian && c.get_elem_solution_derivative())
151  {
152  libmesh_assert (c.get_elem_solution_derivative() == 1.0);
153 
154  for (unsigned int j=0; j != n_var_dofs; j++)
155  K_var(i,j) += penalty*phi[i]*phi[j];
156 
157  } // End if request_jacobian
158  } // End i loop
159  } // End if pin_location
160 
161  return;
162  }
163 
164 } // 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 Thu Jun 2 2016 21:52:27 for GRINS-0.7.0 by  doxygen 1.8.10