NeoPZ
tpzellipse3d.cpp
Go to the documentation of this file.
1 
6 #include "tpzellipse3d.h"
7 
8 #include "TPZGeoLinear.h"
9 #include "pzshapelinear.h"
10 
11 #include "pzfmatrix.h"
12 #include "pzvec.h"
13 #include "pzgmesh.h"
14 #include "pzgeoel.h"
15 #include "pznoderep.h"
16 #include "pzgnode.h"
17 #include "pzreal.h"
18 
19 #include "pzgeoelrefless.h.h"
20 #include "tpzgeoelrefpattern.h.h"
21 #include "pznoderep.h.h"
22 
23 using namespace std;
24 using namespace pzgeom;
25 using namespace pztopology;
26 using namespace pzshape;
27 
29 const double tolerance = 1.E-9;
30 
31 void TPZEllipse3D::SetAxes(TPZVec<REAL> Origin, TPZVec<REAL> SemiAxeX, TPZVec<REAL> SemiAxeY, TPZGeoMesh &gmesh)
32 {
33 #ifdef PZDEBUG
34  if(SemiAxeX.size() != 3 || SemiAxeY.size() != 3 || Origin.size() != 3)
35  {
36  cout << "\nThe two semi-axes and origin of TPZEllipse3D must be in 3D!!!\n";
37  DebugStop();
38  }
39 
40  double dotXY = (SemiAxeX[0]*SemiAxeY[0] + SemiAxeX[1]*SemiAxeY[1] + SemiAxeX[2]*SemiAxeY[2]);
41  if(fabs(dotXY) > tolerance)
42  {
43  cout << "\nThe two semi-axes of TPZEllipse3D must be orthogonal!!!\n";
44  DebugStop();
45  }
46 
47  double dotXX = sqrt(SemiAxeX[0]*SemiAxeX[0] + SemiAxeX[1]*SemiAxeX[1] + SemiAxeX[2]*SemiAxeX[2]);
48  double dotYY = sqrt(SemiAxeY[0]*SemiAxeY[0] + SemiAxeY[1]*SemiAxeY[1] + SemiAxeY[2]*SemiAxeY[2]);
49  if(dotXX < tolerance || dotYY < tolerance || fabs(dotXY) > tolerance)
50  {
51  cout << "Null semi-axe(s) on TPZEllipse3D!!! or semi-axes not orthogonal\n";
52  DebugStop();
53  }
54 #endif
55 
56  fOrigin = Origin;
57  fsAxeX = sqrt(SemiAxeX[0]*SemiAxeX[0] + SemiAxeX[1]*SemiAxeX[1] + SemiAxeX[2]*SemiAxeX[2]);
58  fsAxeY = sqrt(SemiAxeY[0]*SemiAxeY[0] + SemiAxeY[1]*SemiAxeY[1] + SemiAxeY[2]*SemiAxeY[2]);
59  fAxes.Redim(3, 3);
60  for(int i = 0; i < 3; i++)
61  {
62  fAxes(0,i) = SemiAxeX[i]/fsAxeX;
63  fAxes(1,i) = SemiAxeY[i]/fsAxeY;
64  }
65  fAxes(2,0) = fAxes(0,1)*fAxes(1,2)-fAxes(0,2)*fAxes(1,1);
66  fAxes(2,1) = -fAxes(0,0)*fAxes(1,2)+fAxes(0,2)*fAxes(1,0);
67  fAxes(2,2) = fAxes(0,0)*fAxes(1,1)-fAxes(0,1)*fAxes(1,0);
68 
69 #ifdef PZDEBUG
70  TPZFNMatrix<9,REAL> ident(3,3);
71  fAxes.MultAdd(fAxes, fAxes, ident,1.,0.,1);
72  for (int i=0; i<3; i++) {
73  ident(i,i) -= 1.;
74  }
75  REAL norm = Norm(ident);
76  if (norm > 1.e-6) {
77  fAxes.Print("Axes = ",std::cout,EMathematicaInput);
78  DebugStop();
79  }
80 #endif
81  TPZManVector<REAL,3> xini(3),xfinal(3);
82  gmesh.NodeVec()[fNodeIndexes[0]].GetCoordinates(xini);
83  gmesh.NodeVec()[fNodeIndexes[1]].GetCoordinates(xfinal);
84  fAngleIni = ComputeAngle(xini);
85  fAngleFinal = ComputeAngle(xfinal);
86  if (fAngleFinal < fAngleIni) {
87  fAngleFinal += 2.*M_PI;
88  }
89 
90 }
91 
93 double TPZEllipse3D::ComputeAngle(TPZVec<REAL> &co) const
94 {
95  TPZFNMatrix<3,REAL> comat(3,1), localco(3,1);
96  for(int i=0; i<3; i++) comat(i,0) = co[i]-fOrigin[i];
97  fAxes.Multiply(comat, localco);
98 #ifdef PZDEBUG
99  {
100  if(fabs(localco[2]) > 1.e-6) DebugStop();
101  }
102 #endif
103  localco(0,0) /= fsAxeX;
104  localco(1,0) /= fsAxeY;
105 #ifdef PZDEBUG
106  {
107  double r = localco(0,0)*localco(0,0)+localco(1,0)*localco(1,0);
108  if (fabs(r-1.) > 1.e-6) {
109  DebugStop();
110  }
111  }
112 #endif
113  double angle = atan2(localco(1,0),localco(0,0));
114  return angle;
115 }
116 
117 template<class T>
118 void TPZEllipse3D::X(TPZFMatrix<REAL> &nodeCoord,TPZVec<T> &qsi,TPZVec<T> &x) const
119 {
120 #ifdef PZDEBUG
121  {
122  REAL angle = fAngleIni;
123  TPZFNMatrix<3,REAL> xcoloc(3,1,0.),xcoglob(3,1,0.);
124  xcoloc(0,0) = fsAxeX*cos(angle);
125  xcoloc(1,0) = fsAxeY*sin(angle);
126  int transp = 1;
127  fAxes.MultAdd(xcoloc, xcoloc, xcoglob,1.,0.,transp);
128  for (int i=0; i<3; i++) {
129  x[i] = fOrigin[i]+xcoglob(i,0)-nodeCoord(i,0);
130  }
131  T norm = 0.;
132  for (int i=0; i<3; i++) {
133  norm += x[i]*x[i];
134  }
135  norm = sqrt(norm);
136  if (norm > 1.e-6) {
137  DebugStop();
138  }
139  }
140  {
141  REAL angle = fAngleFinal;
142  TPZFNMatrix<3,REAL> xcoloc(3,1,0.),xcoglob(3,1,0.);
143  xcoloc(0,0) = fsAxeX*cos(angle);
144  xcoloc(1,0) = fsAxeY*sin(angle);
145  int transp = 1;
146  fAxes.MultAdd(xcoloc, xcoloc, xcoglob,1.,0.,transp);
147  for (int i=0; i<3; i++) {
148  x[i] = fOrigin[i]+xcoglob(i,0)-nodeCoord(i,1);
149  }
150  T norm = 0.;
151  for (int i=0; i<3; i++) {
152  norm += x[i]*x[i];
153  }
154  norm = sqrt(norm);
155  if (norm > 1.e-6) {
156  DebugStop();
157  }
158  }
159 #endif
160  REAL delangle = fAngleFinal - fAngleIni;
161  T angle = fAngleIni + (qsi[0]+1.)/2.*delangle;
162  TPZFNMatrix<3,T> xcoloc(3,1,0.),xcoglob(3,1,0.);
163  xcoloc(0,0) = fsAxeX*cos(angle);
164  xcoloc(1,0) = fsAxeY*sin(angle);
165  int transp = 1;
166  T one(1.), zero(0.);
167  TPZFMatrix<T> axloc(3,3);
168  for (int i=0; i<3; i++) {
169  for (int j=0; j<3; j++) {
170  axloc(i,j) = fAxes.GetVal(i,j);
171  }
172  }
173  axloc.MultAdd(xcoloc, xcoloc, xcoglob,one,zero,transp);
174  for (int i=0; i<3; i++) {
175  x[i] = fOrigin[i]+xcoglob(i,0);
176  }
177 }
178 
179 template<class T>
180 void TPZEllipse3D::GradX(TPZFMatrix<REAL> &cornerco, TPZVec<T> &par, TPZFMatrix<T> &gradx) const
181 {
182  REAL delangle = fAngleFinal - fAngleIni;
183  T dangledqsi = 1./2.*delangle;
184  T angle = fAngleIni + (par[0]+1.)/2.*delangle;
185  TPZFNMatrix<3,T> dxcoloc(3,1,0.),dxcoglob(3,1,0.);
186  dxcoloc(0,0) = -fsAxeX*sin(angle);
187  dxcoloc(1,0) = fsAxeY*cos(angle);
188  int transp = 1;
189  TPZFMatrix<T> axloc(3,3);
190  for (int i=0; i<3; i++) {
191  for (int j=0; j<3; j++) {
192  axloc(i,j) = fAxes.GetVal(i,j);
193  }
194  }
195  axloc.MultAdd(dxcoloc, dxcoloc, dxcoglob,1.,0.,transp);
196  for (int i=0; i<3; i++) {
197  gradx(i,0) = dangledqsi*dxcoglob(i,0);
198  }
199 
200 }
201 
202 
203 
204 void TPZEllipse3D::GetNodesCoords(TPZGeoMesh &mesh, TPZFMatrix<REAL> &nodes)
205 {
206  for(int i = 0; i < NNodes; i++)
207  {
208  const int64_t nodeindex = this->fNodeIndexes[i];
209  TPZGeoNode * np = &(mesh.NodeVec()[nodeindex]);
210  for(int j = 0; j < 3; j++)
211  {
212  nodes(j,i) = np->Coord(j);
213  }
214  }
215 }//void
216 
217 void TPZEllipse3D::SetNodesCoords(TPZGeoMesh &mesh, TPZFMatrix<REAL> &nodes)
218 {
219  for(int i = 0; i < NNodes; i++)
220  {
221  const int64_t nodeindex = this->fNodeIndexes[i];
222  TPZGeoNode * np = &(mesh.NodeVec()[nodeindex]);
223  for(int j = 0; j < 3; j++)
224  {
225  np->SetCoord(j,nodes(j,i));
226  }
227  }
228  TPZManVector<REAL,3> origin(fOrigin), Ax0(3), Ax1(3);
229  for(int i=0; i<3; i++)
230  {
231  Ax0[i] = fAxes(0,i)*fsAxeX;
232  Ax1[i] = fAxes(1,i)*fsAxeY;
233  }
234  SetAxes(origin, Ax0, Ax1, mesh);
235 }//void
236 
237 #include <math.h>
238 void TPZEllipse3D::AdjustNodesCoordinates(TPZGeoMesh &mesh)
239 {
240  TPZFNMatrix<6,REAL> nodes(3,2);
241 #ifdef PZDEBUG
242  {
243  REAL angle = fAngleIni;
244  TPZFNMatrix<3,REAL> xcoloc(3,1,0.),xcoglob(3,1,0.);
245  xcoloc(0,0) = fsAxeX*cos(angle);
246  xcoloc(1,0) = fsAxeY*sin(angle);
247  int transp = 1;
248  fAxes.MultAdd(xcoloc, xcoloc, xcoglob,1.,0.,transp);
249  for (int i=0; i<3; i++) {
250  nodes(i,0) = fOrigin[i]+xcoglob(i,0);
251  }
252  }
253  {
254  REAL angle = fAngleFinal;
255  TPZFNMatrix<3,REAL> xcoloc(3,1,0.),xcoglob(3,1,0.);
256  xcoloc(0,0) = fsAxeX*cos(angle);
257  xcoloc(1,0) = fsAxeY*sin(angle);
258  int transp = 1;
259  fAxes.MultAdd(xcoloc, xcoloc, xcoglob,1.,0.,transp);
260  for (int i=0; i<3; i++) {
261  nodes(i,1) = fOrigin[i]+xcoglob(i,0);
262  }
263  }
264 #endif
265  SetNodesCoords(mesh, nodes);
266 }//void
267 
268 // TPZGeoEl *TPZEllipse3D::CreateBCGeoEl(TPZGeoEl *orig, int side,int bc)
269 // {
270 // if(side==2)
271 // {
272 // TPZManVector<int64_t> nodes(3);
273 // nodes[0] = orig->SideNodeIndex(side,0); nodes[1] = orig->SideNodeIndex(side,1); nodes[2] = orig->SideNodeIndex(side,2);
274 // int64_t index;
275 // TPZGeoEl *gel = gel->Clone(*gel->Mesh());
276 // TPZGeoElSide(gel,0).SetConnectivity(TPZGeoElSide(orig,TPZShapeLinear::ContainedSideLocId(side,0)));
277 // TPZGeoElSide(gel,1).SetConnectivity(TPZGeoElSide(orig,TPZShapeLinear::ContainedSideLocId(side,1)));
278 // TPZGeoElSide(gel,2).SetConnectivity(TPZGeoElSide(orig,side));
279 // return gel;
280 // }
281 
282 // else if(side==0 || side==1)
283 // {
284 // TPZManVector<int64_t> nodeindexes(1);
285 // nodeindexes[0] = orig->SideNodeIndex(side,0);
286 // int64_t index;
287 // TPZGeoEl *gel = orig->Mesh()->CreateGeoElement(EPoint,nodeindexes,bc,index);
288 // TPZGeoElSide(gel,0).SetConnectivity(TPZGeoElSide(orig,side));
289 // return gel;
290 // }
291 
292 // else PZError << "\nTPZGeoLinear::CreateBCGeoEl. Side = " << side << endl;
293 // return 0;
294 // }
295 
296 
297 #include "tpzgeoelmapped.h"
298 #include "tpzgeomid.h"
299 
301 // TPZGeoEl *TPZEllipse3D::CreateGeoElement(TPZGeoMesh &mesh, MElementType type,
302 // TPZVec<int64_t>& nodeindexes,
303 // int matid,
304 // int64_t& index)
305 // {
306 // return CreateGeoElementMapped(mesh,type,nodeindexes,matid,index);
307 // }
308 
309 void TPZEllipse3D::ParametricDomainNodeCoord(int64_t node, TPZVec<REAL> &nodeCoord)
310 {
311  if(node > this->NNodes)
312  {
313  DebugStop();
314  }
315  nodeCoord.Resize(Dimension, 0.);
316  switch (node) {
317  case (0):
318  {
319  nodeCoord[0] = -1.;
320  break;
321  }
322  case (1):
323  {
324  nodeCoord[0] = 1.;
325  break;
326  }
327  default:
328  {
329  DebugStop();
330  break;
331  }
332  }
333 }
334 
335 int TPZEllipse3D::ClassId() const{
336  return Hash("TPZEllipse3D") ^ TPZNodeRep<2,pztopology::TPZLine>::ClassId() << 1;
337 }
338 
339 void TPZEllipse3D::InsertExampleElement(TPZGeoMesh &gmesh, int matid, TPZVec<REAL> &lowercorner, TPZVec<REAL> &size)
340 {
341  TPZFNMatrix<9,REAL> vander(3,3),rotation(3,3,0.), jac(3,3);
342  // create a vandermonde matrix
343  for (int i=0; i<3; i++) {
344  for (int j=0; j<3; j++) {
345  vander(i,j) = pow(i+1.,j);
346  }
347  }
348  vander.GramSchmidt(rotation, jac);
349 // rotation.Print("rot = ",std::cout, EMathematicaInput);
350  REAL ax1 = 3., ax2 = 1.;
351  REAL angle1 = M_PI/5.5;
352  REAL angle2 = M_PI*0.96;
353  TPZFNMatrix<6,REAL> xloc(3,2,0.);
354  xloc(0,0) = ax1*cos(angle1);
355  xloc(1,0) = ax2*sin(angle1);
356  xloc(0,1) = ax1*cos(angle2);
357  xloc(1,1) = ax2*sin(angle2);
358  TPZManVector<REAL,3> orig(3);
359  for (int i=0; i<3; i++) {
360  orig[i] = lowercorner[i]+3.;
361  size[i] = 6;
362  }
363  TPZFNMatrix<6,REAL> xfinal(3,2);
364  rotation.Multiply(xloc, xfinal);
365  TPZManVector<REAL,3> axis1(3),axis2(3);
366  for (int i=0; i<3; i++) {
367  axis1[i] = rotation(i,0)*ax1;
368  axis2[i] = rotation(i,1)*ax2;
369  for (int j=0; j<2; j++) {
370  xfinal(i,j) += orig[i];
371  }
372  }
373  TPZManVector<int64_t,2> index(2);
374  TPZManVector<REAL,3> xco(3);
375  index[0] = gmesh.NodeVec().AllocateNewElement();
376  for(int i=0; i<3; i++) xco[i] = xfinal(i,0);
377  gmesh.NodeVec()[index[0]].Initialize(xco, gmesh);
378  index[1] = gmesh.NodeVec().AllocateNewElement();
379  for(int i=0; i<3; i++) xco[i] = xfinal(i,1);
380  gmesh.NodeVec()[index[1]].Initialize(xco, gmesh);
381 
383  gel->Geom().SetAxes(orig, axis1, axis2, gmesh);
384 }
385 
386 
388 template class TPZGeoElRefLess<TPZEllipse3D>;
389 /*@orlandini : I REALLY dont know why is this here, so I have commented the following lines.
390 If it breaks something, I am sorry.*/
391 //template class pzgeom::TPZNodeRep<2,TPZEllipse3D>;
static REAL cornerco[8][3]
TPZFlopCounter atan2(const TPZFlopCounter &val1, const TPZFlopCounter &val2)
Returns the arc tangent in radians and increments the counter of the Arc Tangent. ATAN2 returns the ...
Definition: pzreal.h:544
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
int AllocateNewElement()
Makes more room for new elements.
Definition: pzadmchunk.h:184
void SetCoord(const TPZVec< REAL > &x)
Sets all coordinates into the current node. It gets the dim values from x.
Definition: pzgnode.cpp:60
const double tolerance
Tolerance value (Is zero)
Contains declaration of TPZGeoNode class which defines a geometrical node.
REAL Coord(int i) const
Returns i-th coordinate of the current node.
Definition: pzgnode.h:99
Templated vector implementation.
groups all classes dedicated to the computation of shape functions
Definition: pzshapeextend.h:16
void SetAxes(TPZVec< REAL > Origin, TPZVec< REAL > SemiAxeX, TPZVec< REAL > SemiAxeY, TPZGeoMesh &gmesh)
Origin defines the translation of ellipse while semi-axes defines the rotation of ellipse...
Implements the mapping between the master element and deformed element. Geometry. ...
Contains TPZShapeLinear class which implements the shape functions of a linear one-dimensional elemen...
Contains declaration of TPZGeoElMapped class which implements a geometric element using its ancestral...
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Definition: pzvec.h:373
sin
Definition: fadfunc.h:63
Contains declaration of TPZMesh class which defines a geometrical mesh and contains a corresponding l...
Groups all classes defining the structure of the master element.
Definition: PrismExtend.cpp:15
Implements a generic geometric element which is refined according to a generic refinement pattern...
Definition: pzgmesh.h:35
TVar Norm(const TPZFMatrix< TVar > &A)
Returns the norm of the matrix A.
Contains TPZMatrixclass which implements full matrix (using column major representation).
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
TPZAdmChunkVector< TPZGeoNode > & NodeVec()
Definition: pzgmesh.h:140
Contains the TPZNodeRep class which implements ... Clase intermediaria que guarda.
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
Definition: tfadfunc.h:120
REAL co[8][3]
Coordinates of the eight nodes.
Implements ... Geometry Topology.
Definition: pznoderep.h:40
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
static REAL angle
Angle in radians to test.
Definition: pzsubcmesh.cpp:53
TPZFlopCounter pow(const TPZFlopCounter &orig, const TPZFlopCounter &xp)
Returns the power and increments the counter of the power.
Definition: pzreal.h:487
Implements a geometric node in the pz environment. Geometry.
Definition: pzgnode.h:31
This class implements a geometric mesh for the pz environment. Geometry.
Definition: pzgmesh.h:48
Contains the implementation of the TPZNodeRep methods.
virtual void MultAdd(const TPZFMatrix< TVar > &x, const TPZFMatrix< TVar > &y, TPZFMatrix< TVar > &z, const TVar alpha=1., const TVar beta=0., const int opt=0) const override
It computes z = beta * y + alpha * opt(this)*x but z and x can not overlap in memory.
Definition: pzfmatrix.cpp:757
Contains the declaration of TPZFlopCounter class and TPZCounter struct.
Contains the implementation of the TPZGeoElRefPattern methods.
Groups all classes which model the geometry.
Definition: pzgeopoint.cpp:18
TPZFlopCounter cos(const TPZFlopCounter &orig)
Returns the cosine in radians and increments the counter of the Cosine.
Definition: pzreal.h:514
const TVar & GetVal(const int64_t row, const int64_t col) const override
Get values without bounds checking This method is faster than "Get" if DEBUG is defined.
Definition: pzfmatrix.h:566
Contains the TPZEllipse3D class which defines a linear geometric element which maps a line segment to...
Implements an interface to register a class id and a restore function. Persistence.
Definition: TPZSavable.h:150