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