xc
PlaneElement.h
1 // -*-c++-*-
2 //----------------------------------------------------------------------------
3 // XC program; finite element analysis code
4 // for structural analysis and design.
5 //
6 // Copyright (C) Luis C. Pérez Tato
7 //
8 // This program derives from OpenSees <http://opensees.berkeley.edu>
9 // developed by the «Pacific earthquake engineering research center».
10 //
11 // Except for the restrictions that may arise from the copyright
12 // of the original program (see copyright_opensees.txt)
13 // XC is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // This software is distributed in the hope that it will be useful, but
19 // WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program.
26 // If not, see <http://www.gnu.org/licenses/>.
27 //----------------------------------------------------------------------------
28 //PlaneElement.h
29 
30 #ifndef PlaneElement_h
31 #define PlaneElement_h
32 
33 #include <domain/mesh/element/ElemWithMaterial.h>
34 #include "utility/geom/d2/Polygon3d.h"
35 #include "utility/geom/d1/Segment3d.h"
36 #include "utility/geom/pos_vec/Pos3d.h"
37 #include "utility/geom/lists/utils_list_pos3d.h"
38 #include "preprocessor/Preprocessor.h"
39 
40 #include "domain/mesh/node/Node.h"
41 
42 namespace XC {
43 
44 const double elem_warning_area= 1e-6; // If area smaller than this trig a warning.
48 //
54 template <int NNODES,class PhysProp>
55 class PlaneElement: public ElemWithMaterial<NNODES, PhysProp>
56  {
57  protected:
58  mutable std::vector<double> tributaryAreas;
59  public:
60  PlaneElement(int tag, int classTag,const PhysProp &);
61  virtual void checkElem(void);
62  void setDomain(Domain *theDomain);
63 
64  std::deque<Pos3d> getNodePositions(bool initialGeometry= true) const;
65  Plane getPlane(bool initialGeometry= true) const;
66  virtual Polygon3d getPolygon(bool initialGeometry= true) const;
67  bool clockwise(const Pos3d &, bool initialGeometry= true) const;
68  bool counterclockwise(const Pos3d &, bool initialGeometry= true) const;
69  std::string orientation(const Pos3d &, bool initialGeometry= true) const;
70  virtual Segment3d getSide(const size_t &i,bool initialGeometry= true) const;
71  double getMaximumCornerAngle(bool initialGeometry= true) const;
72  Pos3d getCenterOfMassPosition(bool initialGeometry= true) const;
73  virtual double getPerimeter(bool initialGeometry= true) const;
74  virtual double getArea(bool initialGeometry= true) const;
75  virtual void computeTributaryAreas(bool initialGeometry= true) const;
76  const std::vector<double> &getTributaryAreas(void) const;
77  double getTributaryArea(const int &) const;
78  double getTributaryArea(const Node *) const;
79 
80  double getDist2(const Pos2d &p,bool initialGeometry= true) const;
81  double getDist(const Pos2d &p,bool initialGeometry= true) const;
82  double getDist2(const Pos3d &p,bool initialGeometry= true) const;
83  double getDist(const Pos3d &p,bool initialGeometry= true) const;
84  Pos2d getProjection(const Pos2d &p,bool initialGeometry= true) const;
85  Pos3d getProjection(const Pos3d &p,bool initialGeometry= true) const;
86 
87  size_t getDimension(void) const;
88  };
89 
93 template <int NNODES,class PhysProp>
94 XC::PlaneElement<NNODES, PhysProp>::PlaneElement(int tag,int classTag,const PhysProp &physProp)
95  :ElemWithMaterial<NNODES, PhysProp>(tag,classTag,physProp), tributaryAreas(NNODES,0.0)
96  {}
97 
101 template <int NNODES,class PhysProp>
103  {
104  if(this->getNodePtrs().hasNull())
105  std::cerr << this->getClassName() << "::" << __FUNCTION__
106  << "; the element: " << this->getTag()
107  << " pointers to nodes not set." << std::endl;
108  else
109  {
110  const double area= this->getArea();
111  if(area<elem_warning_area)
112  {
113  std::clog << this->getClassName() << "::" << __FUNCTION__
114  << "; element: " << this->getTag() << " with nodes: [";
115  const std::vector<int> inodes= this->getNodePtrs().getTags();
116  std::vector<int>::const_iterator i= inodes.begin();
117  std::clog << *i;
118  i++;
119  for(;i!=inodes.end();i++)
120  std::clog << "," << *i;
121  std::clog << "] has a very little area (" << area << ").\n";
122  }
123  }
124  }
125 
129 template <int NNODES,class PhysProp>
131  {
133  if(theDomain)
134  checkElem();
135  else
136  std::cerr << this->getClassName() << "::" << __FUNCTION__
137  << "; Domain is null\n";
138  }
139 
143 template <int NNODES,class PhysProp>
145  { return getPolygon(initialGeometry).getCenterOfMass(); }
146 
150 template <int NNODES,class PhysProp>
152  { return 2; }
153 
157 template <int NNODES,class PhysProp>
158 double XC::PlaneElement<NNODES, PhysProp>::getPerimeter(bool initialGeometry) const
159  { return getPolygon(initialGeometry).getPerimeter(); }
160 
166 template <int NNODES,class PhysProp>
167 double XC::PlaneElement<NNODES, PhysProp>::getArea(bool initialGeometry) const
168  { return getPolygon(initialGeometry).getArea(); }
169 
173 template <int NNODES,class PhysProp>
175  {
176  tributaryAreas= getPolygon(initialGeometry).getTributaryAreas();
177  this->dumpTributaries(tributaryAreas);
178  }
179 
181 template <int NNODES,class PhysProp>
182 const std::vector<double> &XC::PlaneElement<NNODES, PhysProp>::getTributaryAreas(void) const
183  { return this->tributaryAreas; }
184 
185 
189 template <int NNODES,class PhysProp>
191  {
192  double retval= 0;
193  if((i>0) && (i<NNODES))
194  retval= tributaryAreas[i];
195  return retval;
196  }
197 
201 template <int NNODES,class PhysProp>
203  {
204  const int i= this->theNodes.find(nod);
205  return getTributaryArea(i);
206  }
207 
211 template <int NNODES,class PhysProp>
213  {
214  const std::deque<Pos3d> positions= getNodePositions(initialGeometry);
215  return getMaxCornerAngle(positions.begin(),positions.end());
216  }
217 
222 template <int NNODES,class PhysProp>
223 std::deque<Pos3d> XC::PlaneElement<NNODES, PhysProp>::getNodePositions(bool initialGeometry) const
224  {
225  const std::deque<Pos3d> tmp= this->getPosNodes(initialGeometry);
226  // Filter collapsed sides.
227  std::deque<Pos3d> retval;
228  std::deque<Pos3d>::const_iterator i= tmp.begin();
229  Pos3d p0= *i;
230  i++;
231  retval.push_back(p0);
232  for(;i!= tmp.end();i++)
233  {
234  Pos3d p1= *i;
235  if(dist2(p0,p1)>1e-12)
236  retval.push_back(p1);
237  p0= p1;
238  }
239  // Repeated nodes removed (if any).
240  return retval;
241  }
242 
246 template <int NNODES,class PhysProp>
248  {
249  const std::deque<Pos3d> positions= getNodePositions(initialGeometry);
250  return Plane(positions.begin(),positions.end());
251  }
252 
257 template <int NNODES,class PhysProp>
259  {
260  const std::deque<Pos3d> positions= getNodePositions(initialGeometry);
261  Polygon3d retval(positions.begin(),positions.end());
262  const double maxAngle= getMaximumCornerAngle();
263  if((PlaneElement<NNODES, PhysProp>::verbosity>1) && (abs(maxAngle-M_PI)<1e-3))
264  {
265  std::cerr << this->getClassName() << "::" << __FUNCTION__
266  << " element with tag: " << this->getTag()
267  << " has maximum corner angle of "
268  << RadToDeg(maxAngle)
269  << " degrees (too distorted)."
270  << " Returning empty polygon."
271  << std::endl;
272  }
273  return retval;
274  }
275 
279 template <int NNODES,class PhysProp>
281  {
282  const Pos3d tmp(getProjection(Pos3d(p.x(),p.y(),0.0)));
283  return tmp.XY2DProjection();
284  }
285 
289 template <int NNODES,class PhysProp>
291  {
292  const Plane plane= getPlane(initialGeometry);
293  return plane.Projection(p);
294  }
295 
300 template <int NNODES,class PhysProp>
301 bool XC::PlaneElement<NNODES, PhysProp>::clockwise(const Pos3d &vPoint, bool initialGeometry) const
302  {
303  const Polygon3d plg= this->getPolygon(initialGeometry);
304  return plg.clockwise(vPoint);
305  }
306 
311 template <int NNODES,class PhysProp>
312 bool XC::PlaneElement<NNODES, PhysProp>::counterclockwise(const Pos3d &vPoint, bool initialGeometry) const
313 { return !this->clockwise(vPoint, initialGeometry); }
314 
319 template <int NNODES,class PhysProp>
320 std::string XC::PlaneElement<NNODES, PhysProp>::orientation(const Pos3d &vPoint, bool initialGeometry) const
321  {
322  std::string retval= "counterclockwise";
323  if(this->clockwise(vPoint, initialGeometry))
324  { retval= "clockwise"; }
325  return retval;
326  }
327 
328 
330 template <int NNODES,class PhysProp>
331 Segment3d XC::PlaneElement<NNODES, PhysProp>::getSide(const size_t &i,bool initialGeometry) const
332  {
333  Segment3d retval;
334  const NodePtrsWithIDs &nodes= this->getNodePtrs();
335  const size_t sz= nodes.size();
336  if(i<sz)
337  {
338  const Pos3d p1= nodes.getPosNode(i,initialGeometry);
339  if(i<(sz-1))
340  retval= Segment3d(p1,nodes.getPosNode(i+1,initialGeometry));
341  else
342  retval= Segment3d(p1,nodes.getPosNode(0,initialGeometry));
343  }
344  return retval;
345  }
346 
351 template <int NNODES,class PhysProp>
352 double XC::PlaneElement<NNODES, PhysProp>::getDist2(const Pos2d &p,bool initialGeometry) const
353  { return getDist2(To3dXY2d(p),initialGeometry); }
354 
359 template <int NNODES,class PhysProp>
360 double XC::PlaneElement<NNODES, PhysProp>::getDist(const Pos2d &p,bool initialGeometry) const
361  { return getDist(To3dXY2d(p),initialGeometry); }
362 
367 template <int NNODES,class PhysProp>
368 double XC::PlaneElement<NNODES, PhysProp>::getDist2(const Pos3d &p,bool initialGeometry) const
369  { return getPolygon(initialGeometry).dist2(p); }
370 
375 template <int NNODES,class PhysProp>
376 double XC::PlaneElement<NNODES, PhysProp>::getDist(const Pos3d &p,bool initialGeometry) const
377  { return getPolygon(initialGeometry).dist(p); }
378 
379 } // end of XC namespace
380 #endif
bool counterclockwise(const Pos3d &, bool initialGeometry=true) const
Return true if the nodes are counterclockwise ordered with respect to the element.
Definition: PlaneElement.h:312
double getDist2(const Pos2d &p, bool initialGeometry=true) const
Returns the squared distance from the element to the point being passed as parameter.
Definition: PlaneElement.h:352
Pos3d getPosNode(const size_t &i, bool initialGeometry=true) const
Return the position of the i-th node.
Definition: NodePtrs.cc:352
Plane polygon in a 3D space.
Definition: Polygon3d.h:35
virtual double getArea(bool initialGeometry=true) const
Returns element area.
Definition: PlaneElement.h:167
Segment en tres dimensiones.
Definition: Segment3d.h:41
virtual void checkElem(void)
Sets nodes and checks the element.
Definition: PlaneElement.h:102
PlaneElement(int tag, int classTag, const PhysProp &)
Constructor.
Definition: PlaneElement.h:94
virtual void computeTributaryAreas(bool initialGeometry=true) const
Computes tributary areas that correspond to each node.
Definition: PlaneElement.h:174
double getTributaryArea(const int &) const
Returns tributary area for the i-th node.
Definition: PlaneElement.h:190
virtual Segment3d getSide(const size_t &i, bool initialGeometry=true) const
Returns a side of the element.
Definition: PlaneElement.h:331
Posición en dos dimensiones.
Definition: Pos2d.h:41
Plane getPlane(bool initialGeometry=true) const
Returns the plane that contains the element.
Definition: PlaneElement.h:247
Pos2d XY2DProjection(void) const
Return the projection onto XY plane.
Definition: Pos3d.cc:169
void setDomain(Domain *theDomain)
Sets the element domain.
Definition: PlaneElement.h:130
Plane in a three-dimensional space.
Definition: Plane.h:49
double getDist(const Pos2d &p, bool initialGeometry=true) const
Return the distance from the element to the point being passed as parameter.
Definition: PlaneElement.h:360
std::string orientation(const Pos3d &, bool initialGeometry=true) const
Return the orientation of the element (clockwise or counterclockwise).
Definition: PlaneElement.h:320
const std::vector< double > & getTributaryAreas(void) const
Return tributary areas that correspond to each node.
Definition: PlaneElement.h:182
double getMaximumCornerAngle(bool initialGeometry=true) const
Returns the maximum corner angle quality parameter.
Definition: PlaneElement.h:212
Pos3d getCenterOfMassPosition(bool initialGeometry=true) const
Return the position of the element centroid.
Definition: PlaneElement.h:144
Pos2d getProjection(const Pos2d &p, bool initialGeometry=true) const
Return the projection of the argument on the element.
Definition: PlaneElement.h:280
bool clockwise(const Pos3d &) const
Return true if the point list is oriented clockwise.
Definition: Polygon3d.cc:468
Pos3d Projection(const Pos3d &) const
Return the projection of the point onto this plane.
Definition: Plane.cc:176
Node pointer container for elements.
Definition: NodePtrsWithIDs.h:46
Posición en tres dimensiones.
Definition: Pos3d.h:44
Open source finite element program for structural analysis.
Definition: ContinuaReprComponent.h:35
virtual double getPerimeter(bool initialGeometry=true) const
Returns the perimeter of the element.
Definition: PlaneElement.h:158
Element with material.
Definition: ElemWithMaterial.h:45
size_t getDimension(void) const
Return the element dimension (0, 1, 2 o3 3).
Definition: PlaneElement.h:151
virtual Polygon3d getPolygon(bool initialGeometry=true) const
Returns the element contour as a polygon.
Definition: PlaneElement.h:258
Domain (mesh and boundary conditions) of the finite element model.
Definition: Domain.h:117
Mesh node.
Definition: Node.h:111
Base class for plane elements.
Definition: PlaneElement.h:55
std::deque< Pos3d > getNodePositions(bool initialGeometry=true) const
Returns the positions of the element nodes (without duplicates corresponding to degenerated elements)...
Definition: PlaneElement.h:223
bool clockwise(const Pos3d &, bool initialGeometry=true) const
Return true if the nodes are clockwise ordered with respect to the element.
Definition: PlaneElement.h:301