foeppl_von_karman_volume_constraint_element.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for FoepplvonKarman elements
31 #ifndef OOMPH_FVK_VOLUME_CONSTRAINT_ELEMENT_HEADER
32 #define OOMPH_FVK_VOLUME_CONSTRAINT_ELEMENT_HEADER
33 
34 #ifdef HAVE_CONFIG_H
35  #include <oomph-lib-config.h>
36 #endif
37 
38 #include "../generic/elements.h"
39 #include "../meshes/triangle_mesh.h"
41 
42 #include <fstream>
43 
44 namespace oomph
45 {
46 
47 
48 //=============================================================
49 /// A class which allows the user to specify a prescribed
50 /// volume (as opposed to a prescribed pressure) for in the region
51 /// bounded by the membrane.
52 /// Effectively adds an equation to the system for pressure.
53 /// There would usually only be a single instance of this
54 /// element in a problem.
55 //=============================================================
56  template <class ELEMENT, template<class> class MESH>
58  public virtual GeneralisedElement
59  {
60  public:
61 
62  /// \short Constructor. Takes pointer to mesh of Foeppl von Karman
63  /// elements and a vector of unsigneds which identifies the
64  /// regions within it that contribute to the controlled volume
65  /// defined as int w dA (i.e. the "volume under the membrane").
66  /// The optional final argument specifies the initial value
67  /// for the pressure that is "traded" in exchange for the
68  /// volume constraint.
70  MESH<ELEMENT> *bounding_mesh_pt,
71  const Vector<unsigned>& contributing_region,
72  const double& pressure = 0.0) :
73  Bounding_mesh_pt(bounding_mesh_pt),
74  Contributing_region(contributing_region),
76  {
77  // Create instance of pressure that is traded for volume constraint
80 
81  // Add the data object as internal data for this element
83  }
84 
85  // Destructor (empty)
87  {}
88 
89  /// Broken copy constructor
92  {
93  BrokenCopy::broken_copy("FoepplvonKarmanVolumeConstraintElement");
94  }
95 
96  /// Broken assignment operator
98  {
99  BrokenCopy::broken_assign("FoepplvonKarmanVolumeConstraintElement");
100  }
101 
102  /// \short Returns the volume "under the elements" in the constrained
103  /// regions
105  {
106  double bounded_volume = 0.0;
107 
108  // Loop over the bounded regions
109  unsigned n_contributing_regions = Contributing_region.size();
110  for(unsigned r = 0; r < n_contributing_regions; r++)
111  {
112  // Loop over the elements in the bounded regions
113  unsigned n_inner_el =
114  Bounding_mesh_pt->nregion_element(Contributing_region[r]);
115  for(unsigned e = 0; e < n_inner_el; e++)
116  {
117  // Add the contribution
118  ELEMENT *el_pt = dynamic_cast<ELEMENT*>
119  (Bounding_mesh_pt->region_element_pt(Contributing_region[r],e));
120  bounded_volume += el_pt->get_bounded_volume();
121  }
122  }
123  return bounded_volume;
124  }
125 
126  /// Assign the equation number for the new equation
128  {
130  }
131 
132  /// \short Fill in residual: Difference between actual and
133  /// prescribed bounded volume.
135  {
136  if(Volume_control_local_eqn >= 0)
137  {
138  residuals[Volume_control_local_eqn] +=
139  - (*Prescribed_volume_pt);
140  }
141  }
142 
143 
144  /// Fill in contribution to elemental residual and Jacobian
146  DenseMatrix<double> &jacobian)
147  {
148  if(Volume_control_local_eqn >= 0)
149  {
150  // Only add contribution to residual; Jacobian (derivs w.r.t. to
151  // this element's external data is handled by FvK elements)
152  residuals[Volume_control_local_eqn] -= (*Prescribed_volume_pt);
153 
154 
155  /* // We are in charge... */
156  /* else */
157  /* { */
158  /* // NOTE: This is very slow but keep code alive -- can be */
159  /* // recycled if/when we ever make the Jacobians in the */
160  /* // Foeppl von Karman elements analytical. */
161  /* double t_start=TimingHelpers::timer(); */
162 
163  /* // Setup lookup scheme between local and global data */
164  /* std::map<unsigned,unsigned> local_external_eqn; */
165  /* unsigned next=nexternal_data(); */
166  /* for (unsigned j=0;j<next;j++) */
167  /* { */
168  /* Data* data_pt=external_data_pt(j); */
169  /* unsigned nval=data_pt->nvalue(); */
170  /* for (unsigned k=0;k<nval;k++) */
171  /* { */
172  /* int local_eqn=external_local_eqn(j,k); */
173  /* if (local_eqn>=0) */
174  /* { */
175  /* int global_eqn=data_pt->eqn_number(k); */
176  /* local_external_eqn[global_eqn]=local_eqn; */
177  /* } */
178  /* } */
179  /* } */
180 
181 
182  /* double t_end=TimingHelpers::timer(); */
183  /* oomph_info << "Time for local_external_eqn setup: " */
184  /* << t_end-t_start << std::endl; */
185  /* t_start=TimingHelpers::timer(); */
186 
187 
188  /* // Add initial contribution */
189  /* residuals[Volume_control_local_eqn] -= (*Prescribed_volume_pt); */
190 
191  /* // Initialise total bounded volume */
192  /* double bounded_volume = 0.0; */
193 
194  /* // Loop over the bounded regions */
195  /* unsigned n_contributing_regions = Contributing_region.size(); */
196  /* for(unsigned r = 0; r < n_contributing_regions; r++) */
197  /* { */
198  /* // Loop over the elements in the bounded regions */
199  /* unsigned n_inner_el = */
200  /* Bounding_mesh_pt->nregion_element(Contributing_region[r]); */
201  /* for(unsigned e = 0; e < n_inner_el; e++) */
202  /* { */
203  /* // Get element */
204  /* ELEMENT *el_pt = dynamic_cast<ELEMENT*> */
205  /* (Bounding_mesh_pt->region_element_pt(Contributing_region[r],e)); */
206 
207  /* // Get element's contribution to bounded volume and */
208  /* // derivative w.r.t. its unknowns */
209  /* double el_bounded_volume=0.0; */
210 
211  /* std::map<unsigned,double> d_bounded_volume_d_unknown; */
212  /* el_pt->fill_in_d_bounded_volume_d_unknown(el_bounded_volume, */
213  /* d_bounded_volume_d_unknown); */
214 
215  /* // Add contribution to bounded volume */
216  /* bounded_volume += el_bounded_volume; */
217 
218 
219  /* // Add contribution to Jacobian */
220  /* for (std::map<unsigned,double>::iterator it= */
221  /* d_bounded_volume_d_unknown.begin();it!= */
222  /* d_bounded_volume_d_unknown.end();it++) */
223  /* { */
224  /* unsigned global_eqn=(*it).first; */
225  /* unsigned local_eqn=local_external_eqn[global_eqn]; */
226  /* jacobian(Volume_control_local_eqn,local_eqn)+=(*it).second; */
227  /* } */
228  /* } */
229  /* } */
230  /* // Add contribution to residuals */
231  /* residuals[Volume_control_local_eqn]+=bounded_volume; */
232 
233 
234 
235  /* t_end=TimingHelpers::timer(); */
236  /* oomph_info << "Time for second part (actual work) of fill...jacobian: " */
237  /* << t_end-t_start << std::endl; */
238 
239  /* } */
240 
241 
242  }
243  }
244 
245  /// Set pointer to target volume
246  void set_prescribed_volume(double* volume_pt)
247  {
248  Prescribed_volume_pt = volume_pt;
249  }
250 
251  /// \short Access to Data object whose single value contains the pressure
252  /// that has been "traded" for the volume constraint.
254  {
256  }
257 
258  protected:
259 
260  /// \short Data object whose single value contains the pressure
261  /// that has been "traded" for the volume constraint.
263 
264  /// \short Unsigned indicating which internal Data object
265  /// stores the pressure
267 
268  /// Local equation number of volume constraint
270 
271  /// \short Pointer to mesh of Foeppl von Karman elements that bound
272  /// the prescribed volume; NULL if the FvK elements that contribute
273  /// to the bounding volume are in charge of adding their own
274  /// contribution to the volume constraint equation (and the
275  /// associated Jacobian)
276  MESH<ELEMENT>* Bounding_mesh_pt;
277 
278  /// \short Region IDs in the bounding mesh that contribute to the
279  /// prescribed/controlled volume
281 
282  /// Pointer to target volume
284 
285  };
286 
287 }
288 
289 #endif
A Generalised Element class.
Definition: elements.h:76
int internal_local_eqn(const unsigned &i, const unsigned &j) const
Return the local equation number corresponding to the j-th value stored at the i-th internal data...
Definition: elements.h:268
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
unsigned Pressure_data_index
Unsigned indicating which internal Data object stores the pressure.
void set_prescribed_volume(double *volume_pt)
Set pointer to target volume.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in residual: Difference between actual and prescribed bounded volume.
FoepplvonKarmanVolumeConstraintElement(MESH< ELEMENT > *bounding_mesh_pt, const Vector< unsigned > &contributing_region, const double &pressure=0.0)
Constructor. Takes pointer to mesh of Foeppl von Karman elements and a vector of unsigneds which iden...
e
Definition: cfortran.h:575
void operator=(const FoepplvonKarmanVolumeConstraintElement &)
Broken assignment operator.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to elemental residual and Jacobian.
Vector< unsigned > Contributing_region
Region IDs in the bounding mesh that contribute to the prescribed/controlled volume.
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
Definition: nodes.h:267
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:89
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
double get_bounded_volume()
Returns the volume "under the elements" in the constrained regions.
void assign_additional_local_eqn_numbers()
Assign the equation number for the new equation.
MESH< ELEMENT > * Bounding_mesh_pt
Pointer to mesh of Foeppl von Karman elements that bound the prescribed volume; NULL if the FvK eleme...
FoepplvonKarmanVolumeConstraintElement(const FoepplvonKarmanVolumeConstraintElement &)
Broken copy constructor.
Data * Volume_control_pressure_pt
Data object whose single value contains the pressure that has been "traded" for the volume constraint...
unsigned add_internal_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) internal data object to the element and return the index required to obtain it ...
Definition: elements.cc:66
Data * pressure_data_pt() const
Access to Data object whose single value contains the pressure that has been "traded" for the volume ...
int Volume_control_local_eqn
Local equation number of volume constraint.