25 static LoggerPtr logger(Logger::getLogger(
"pz.topology.pzquadrilateral"));
35 int TPZQuadrilateral::SideNodes[4][2] = { {0,1},{1,2},{2,3},{3,0} };
36 int TPZQuadrilateral::FaceNodes[1][4] = { {0,1,2,3} };
38 int TPZQuadrilateral::NSideNodes(
int side)
40 return nsidenodes[side];
50 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,-99,-99}},
51 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,-99,-99}},
52 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,-1,-99}}
55 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,-99,-99}},
56 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,-99,-99}},
57 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,-1,-99}}
60 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,-99,-99}},
61 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,-99,-99}},
62 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,1,-99}}
65 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{1,-99,-99}},
66 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,-99,-99}},
67 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-1,1,-99}}
70 {{1,0,-99},{-99,-99,-99},{-99,-99,-99},{0,-1,-99}}
73 {{0,1,-99},{-99,-99,-99},{-99,-99,-99},{1,0,-99}}
76 {{-1,0,-99},{-99,-99,-99},{-99,-99,-99},{0,1,-99}}
79 {{0,-1,-99},{-99,-99,-99},{-99,-99,-99},{-1,0,-99}}
82 {{-99,-99,-99},{-99,-99,-99},{-99,-99,-99},{-99,-99,-99}}
100 {-1.,-1.},{ 1.,-1.},{1.,1.},
101 {-1., 1.},{ 0.,-1.},{1.,0.},
102 { 0., 1.},{-1., 0.},{0.,0.} };
149 static int vectorsideorder [18] = {0,1,4,1,2,5,2,3,6,3,0,7,4,5,6,7,8,8};
151 static int bilinearounao [18] = {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1};
156 for(
int i=12; i< 18; i++) bilinearounao[i] = 0;
159 for(
int i=12; i< 18; i++) bilinearounao[i] = 1;
167 static int direcaoksioueta [18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
169 int TPZQuadrilateral::fPermutations [8][9] =
181 REAL TPZQuadrilateral::fTangentVectors [16][2] =
203 T qsi = loc[0], eta = loc[1];
205 phi(0,0) = 0.25*(1.-qsi)*(1.-eta);
206 phi(1,0) = 0.25*(1.+qsi)*(1.-eta);
207 phi(2,0) = 0.25*(1.+qsi)*(1.+eta);
208 phi(3,0) = 0.25*(1.-qsi)*(1.+eta);
210 dphi(0,0) = 0.25*(eta-1.);
211 dphi(1,0) = 0.25*(qsi-1.);
213 dphi(0,1) = 0.25*(1.-eta);
214 dphi(1,1) =-0.25*(1.+qsi);
216 dphi(0,2) = 0.25*(1.+eta);
217 dphi(1,2) = 0.25*(1.+qsi);
219 dphi(0,3) =-0.25*(1.+eta);
220 dphi(1,3) = 0.25*(1.-qsi);
226 void TPZQuadrilateral::BlendFactorForSide(
const int &side,
const TPZVec<T> &xi, T &blendFactor,
230 std::ostringstream sout;
231 if(side < NCornerNodes || side >= NSides){
232 sout<<
"The side\t"<<side<<
"is invalid. Aborting..."<<std::endl;
234 PZError<<std::endl<<sout.str()<<std::endl;
238 if(!IsInParametricDomain(xi,tol)){
239 sout<<
"The method BlendFactorForSide expects the point xi to correspond to coordinates of a point";
240 sout<<
" inside the parametric domain. Aborting...";
241 PZError<<std::endl<<sout.str()<<std::endl;
250 TPZQuadrilateral::TShape(xi,phi,dphi);
251 corrFactorDxi.
Resize(TPZQuadrilateral::Dimension, (T) 0);
276 blendFactor = phi(i,0) + phi((i+1)%NCornerNodes,0);
277 corrFactorDxi[0] = dphi(0,i) + dphi(0,(i+1)%NCornerNodes);
278 corrFactorDxi[1] = dphi(1,i) + dphi(1,(i+1)%NCornerNodes);
281 int TPZQuadrilateral::NBilinearSides()
286 int TPZQuadrilateral::SideNodeLocId(
int side,
int node)
288 if(side<4 && node==0)
return side;
289 if(side>=4 && side<8 && node <2)
return (side+node)%4;
290 if(side==8 && node <4)
return node;
291 PZError <<
"TPZQuadrilateral::SideNodeLocId inconsistent side or node " << side
292 <<
' ' << node << endl;
296 void TPZQuadrilateral::LowerDimensionSides(
int side,
TPZStack<int> &smallsides)
299 int nsidecon = NContainedSides(side);
301 for(is=0; is<nsidecon-1; is++)
302 smallsides.
Push(ContainedSideLocId(side,is));
305 void TPZQuadrilateral::LowerDimensionSides(
int side,
TPZStack<int> &smallsides,
int DimTarget)
308 int nsidecon = NContainedSides(side);
309 for(
int is = 0; is < nsidecon - 1; is++) {
310 if (SideDimension(ContainedSideLocId(side,is)) == DimTarget) smallsides.
Push(ContainedSideLocId(side,is));
316 if(side <0 || side >= NSides) {
317 PZError <<
"TPZQuadrilateral::HigherDimensionSides side "<< side << endl;
320 for(is=0; is<nhighdimsides[side]; is++) high.
Push(highsides[side][is]);
325 if (center.
size()!=Dimension) {
329 for(i=0; i<Dimension; i++) {
330 center[i] = MidSideNode[side][i];
334 TPZIntPoints * TPZQuadrilateral::CreateSideIntegrationRule(
int side,
int order){
335 if(side<0 || side>8) {
336 PZError <<
"TPZQuadrilateral::CreateSideIntegrationRule wrong side " << side << endl;
340 if(side<8)
return new TPZInt1d(order);
348 if(side<0 || side>8){
349 PZError <<
"TPZShapeQuad::TransformElementToSide called with side error\n";
370 t.
Mult()(0,0) = -1.0;
373 t.
Mult()(0,1) = -1.0;
385 const REAL qsi = pt[0];
386 const REAL eta = pt[1];
387 if( (
fabs(qsi) <= 1. + tol ) && (
fabs(eta) <= 1. + tol ) ){
398 for(
int i=0; i<2; i++)
400 REAL
val = -1. + 2.*(REAL) rand() / (RAND_MAX);
406 bool TPZQuadrilateral::CheckProjectionForSingularity(
const int &side,
const TPZVec<T> &xiInterior) {
414 SidePar.
Resize(SideDimension(side));
415 Transf.
Apply(InternalPar,SidePar);
421 for(
int i = 0; i < R; i++)
423 for(
int j = 0; j < C; j++) JacToSide(i,j) = Transf.
Mult()(i,j);
427 void TPZQuadrilateral::ParametricDomainNodeCoord(
int node,
TPZVec<REAL> &nodeCoord)
429 if(node > NCornerNodes)
433 nodeCoord.
Resize(Dimension, 0.);
494 if(sidefrom <0 || sidefrom >= NSides || sideto <0 || sideto >= NSides) {
495 PZError <<
"TPZShapeQuad::SideToSideTransform sidefrom "<< sidefrom <<
496 ' ' << sideto << endl;
499 if(sidefrom == sideto) {
502 if(sidefrom == NSides-1) {
503 return TransformElementToSide(sideto);
506 if (sideto == NSides -1) {
507 TransformSideToElement(sidefrom);
510 int nhigh = nhighdimsides[sidefrom];
512 for(is=0; is<nhigh; is++) {
513 if(highsides[sidefrom][is] == sideto) {
514 int dfr = sidedimension[sidefrom];
515 int dto = sidedimension[sideto];
518 for(i=0; i<dto; i++) {
519 for(j=0; j<dfr; j++) {
520 trans.
Mult()(i,j) = sidetosidetransforms[sidefrom][is][j][i];
522 trans.
Sum()(i,0) = sidetosidetransforms[sidefrom][is][3][i];
527 PZError <<
"TPZShapeQuad::SideToSideTransform highside not found sidefrom " 528 << sidefrom <<
' ' << sideto <<
".\n";
533 int TPZQuadrilateral::SideDimension(
int side) {
534 if(side<0 || side >= NSides) {
535 PZError <<
"TPZShapeQuad::SideDimension. Out of scope side " << side <<
".\n";
538 return sidedimension[side];
541 int TPZQuadrilateral::NContainedSides(
int side) {
542 if(side<0 || side>8) {
543 PZError <<
"TPZShapeQuad::NContainedSides. Bad parameter side = " << side <<
".\n";
552 if(dimension<0 || dimension> 2) {
553 PZError <<
"TPZShapeQuad::NumSides. Bad parameter dimension = " << dimension <<
".\n";
556 if(dimension==0)
return 4;
557 if(dimension==1)
return 4;
558 if(dimension==2)
return 1;
565 int TPZQuadrilateral::ContainedSideLocId(
int side,
int c) {
576 if(!c)
return side-4;
577 if(c==1)
return (side-3)%4;
578 if(c==2)
return side;
582 PZError <<
"TPZShapeQuad::ContainedSideLocId, connect = " << c << endl;
590 if(side<0 || side>8){
591 PZError <<
"TPZShapeQuad::TransformSideToElement side out range\n";
617 t.
Sum() (1,0) = -1.0;
624 t.
Mult()(0,0) = -1.0;
628 t.
Mult()(1,0) = -1.0;
629 t.
Sum() (0,0) = -1.0;
649 id0 = (
id[0] <
id[1]) ? 0 : 1;
650 id1 = (
id[2] <
id[3]) ? 2 : 3;
651 minid = (
id[id0] <
id[id1]) ? id0 : id1;
652 id0 = (minid + 1) % 4;
653 id1 = (minid + 3) % 4;
656 if (
id[id0] <
id[id1]) {
658 if (minid ==
id[0])
return 0;
659 if (minid ==
id[1])
return 2;
660 if (minid ==
id[2])
return 4;
661 if (minid ==
id[3])
return 6;
666 if (minid ==
id[0])
return 1;
667 if (minid ==
id[1])
return 3;
668 if (minid ==
id[2])
return 5;
669 if (minid ==
id[3])
return 7;
678 void TPZQuadrilateral::GetGatherPermute(
int transformid,
TPZVec<int> &permute)
681 if (permute.
size() != 9) {
686 if (transformid%2 ==1) dir = -1;
687 int runsmall = transformid/4;
688 int runlarge = runsmall+4;
690 for (
int is=0; is<4; is++) {
691 permute[is] = runsmall;
692 permute[is+4] = runlarge;
695 if (dir == 1 && runsmall > 3) {
699 else if(dir == -1 && runsmall < 0)
728 int in1 = ContainedSideLocId(side,0);
729 int in2 = ContainedSideLocId(side,1);
730 return id[in1]<
id[in2] ? 0 : 1;
735 return GetTransformId(
id);
752 void TPZQuadrilateral::GetSideHDivPermutation(
int transformationid,
TPZVec<int> &permgather)
756 if (transformationid < 0 || transformationid > 8 || permgather.
size() != 9) {
761 for (
int i=0; i<9; i++)
763 permgather[i] = fPermutations[transformationid][i];
768 if(transformationid%2 == 0)
770 switch (transformationid)
773 for(i=0; i<9; i++) permgather[i] = i;
776 for(i=0; i<4; i++) permgather[i] = (i+1)%4;
777 for(i=4; i<8; i++) permgather[i] = 4+(i+1)%4;
781 for(i=0; i<4; i++) permgather[i] = (i+2)%4;
782 for(i=4; i<8; i++) permgather[i] = 4+(i+2)%4;
786 for(i=0; i<4; i++) permgather[i] = (i+3)%4;
787 for(i=4; i<8; i++) permgather[i] = 4+(i+3)%4;
799 switch (transformationid) {
801 for(i=0; i<4; i++) permgather[i] = invid[i];
802 for(i=4; i<8; i++) permgather[i] = 4+invid[(i+1)%4];
806 for(i=0; i<4; i++) permgather[i] = invid[(i+1)%4];
807 for(i=4; i<8; i++) permgather[i] = 4+invid[(i+2)%4];
811 for(i=0; i<4; i++) permgather[i] = invid[(i+2)%4];
812 for(i=4; i<8; i++) permgather[i] = 4+invid[(i+3)%4];
816 for(i=0; i<4; i++) permgather[i] = invid[(i+3)%4];
817 for(i=4; i<8; i++) permgather[i] = 4+invid[(i+0)%4];
1008 for (
int ilin=0; ilin<3; ilin++)
1010 u[ilin] = gradx(ilin, 0);
1011 v[ilin] = gradx(ilin, 1);
1015 uxv[0] = u[1]*v[2]-u[2]*v[1];
1016 uxv[1] = -(u[0]*v[2]-v[0]*u[2]);
1017 uxv[2] = u[0]*v[1]-v[0]*u[1];
1019 for (
int pos=0; pos<3; pos++)
1021 detgrad += uxv[pos]*uxv[pos];
1027 for (
int ivet=inicio; ivet<=fim; ivet++)
1035 for (
int il=0; il<3; il++)
1037 for (
int i = 0 ; i<2; i++)
1039 gvec[il] += gradx(il,i) * t1vec(i,ivet);
1040 Vvec[il] += gradx(il,i) * bvec(i,ivet);
1043 acumng += gvec[il]*gvec[il];
1045 gvecnorm =
sqrt(acumng);
1047 for (
int il=0; il<3; il++)
1049 Wvec(il,0) = Vvec[il]*gvecnorm/detgrad;
1050 directions(il,cont) = Wvec(il,0);
1069 directions.
Redim(3, 18);
1070 for (
int lin = 0; lin<18; lin++)
1072 for(
int col = 0;col<2;col++)
1074 bvec.
PutVal(col, lin, bQuad[lin][col]);
1075 t1vec.
PutVal(col, lin, tQuad[lin][col]);
1099 directions.
Redim(3, 3);
1101 int inumvec = 0, fnumvec = 2;
1103 for (
int ip = 0; ip < 3; ip++) {
1104 sidevectors[ip] = vectorsideorder[ip];
1111 directions.
Redim(3, 3);
1113 int inumvec = 3, fnumvec = 5;
1115 for (
int ip = 0; ip < 3; ip++) {
1116 sidevectors[ip] = vectorsideorder[ip+inumvec];
1122 directions.
Redim(3, 3);
1124 int inumvec = 6, fnumvec = 8;
1126 for (
int ip = 0; ip < 3; ip++) {
1127 sidevectors[ip] = vectorsideorder[ip+inumvec];
1133 directions.
Redim(3, 3);
1135 int inumvec = 9, fnumvec = 11;
1137 for (
int ip = 0; ip < 3; ip++) {
1138 sidevectors[ip] = vectorsideorder[ip+inumvec];
1144 directions.
Redim(3, 6);
1146 int inumvec = 12, fnumvec = 17;
1148 for (
int ip = 0; ip < 6; ip++) {
1149 sidevectors[ip] = vectorsideorder[ip+inumvec];
1162 template <
class TVar>
1168 for (
int i=0; i<3; i++) {
1169 v1[i] = gradx(i,0)/detjac;
1170 v2[i] = gradx(i,1)/detjac;
1179 for (
int i=0; i<3; i++)
1181 for (
int v=0; v<3; v++)
1183 directions(i,v) = -v2[i];
1184 directions(i,v+3) = v1[i];
1185 directions(i,v+6) = v2[i];
1186 directions(i,v+9) = -v1[i];
1189 directions(i,12) = v1[i];
1190 directions(i,13) = v2[i];
1191 directions(i,14) = -v1[i];
1192 directions(i,15) = -v2[i];
1194 directions(i,16) = v1[i];
1195 directions(i,17) = v2[i];
1199 template <
class TVar>
1202 const auto dim = gradx.
Rows();
1204 for (
int i=0; i<dim; i++) {
1208 constexpr
auto nEdges{4};
1209 constexpr REAL faceArea{TPZQuadrilateral::RefElVolume()};
1210 const int facePermute = transformationIds[nEdges];
1213 for(
auto iEdge = 0; iEdge < nEdges; iEdge++){
1214 edgeSign[iEdge] = transformationIds[iEdge] == 0 ? 1 : -1;
1217 for (
int i=0; i<dim; i++)
1219 for(
int iSide = 0; iSide < 4; iSide ++){
1220 int sign = iSide /2 ? -1 : 1;
1221 sign *= edgeSign[iSide];
1225 directions(i,iSide * 2) =
1226 directions(i,iSide * 2 + 1) =
1228 directions(i,8 + iSide) =
1229 iSide % 2 ? sign * 0.5 * v2[i] : sign * 0.5 * v1[i];
1231 sign = ((iSide + 1) / 2) %2 ? -1 : 1;
1232 sign *= edgeSign[iSide];
1236 directions(i,12 + iSide) = iSide % 2 ? sign * v1[i] : sign * v2[i];
1237 directions(i,12 + iSide) /= faceArea;
1240 directions(i,16) = fTangentVectors[2*facePermute][i];
1241 directions(i,17) = fTangentVectors[2*facePermute + 1][i];
1245 template <
class TVar>
1248 for (
auto i=0; i< Dimension; i++){
1250 v1[i] = fTangentVectors[2*transformationId][i];
1251 v2[i] = fTangentVectors[2*transformationId + 1][i];
1256 int nsides = NumSides()*2;
1262 for (
int is = 0; is<nsides; is++)
1264 sides[is] = vectorsideorder[is];
1265 dir[is] = direcaoksioueta[is];
1266 bilounao[is] = bilinearounao[is];
1271 int nsides = NumSides()*2;
1277 for (
int is = 0; is<nsides; is++)
1279 sides[is] = vectorsideorder[is];
1280 dir[is] = direcaoksioueta[is];
1281 bilounao[is] = bilinearounao[is];
1283 for (
int i=0; i<Dimension*NumSides(); i++) {
1284 sidevectors[i] = vectorsideorder[i];
1288 int TPZQuadrilateral::ClassId()
const{
1289 return Hash(
"TPZQuadrilateral");
1292 void TPZQuadrilateral::Read(
TPZStream& buf,
void* context) {
1296 void TPZQuadrilateral::Write(
TPZStream& buf,
int withclassid)
const {
1308 template bool pztopology::TPZQuadrilateral::CheckProjectionForSingularity<REAL>(
const int &side,
const TPZVec<REAL> &xiInterior);
1312 template void pztopology::TPZQuadrilateral::BlendFactorForSide<REAL>(
const int &,
const TPZVec<REAL> &, REAL &, TPZVec<REAL> &);
1320 template void pztopology::TPZQuadrilateral::ComputeHCurlFaceDirections<REAL>(TPZVec<REAL> &v1, TPZVec<REAL> &v2,
int transformationId);
1322 template bool pztopology::TPZQuadrilateral::CheckProjectionForSingularity<Fad<REAL>>(
const int &side,
const TPZVec<Fad<REAL>> &xiInterior);
1326 template void pztopology::TPZQuadrilateral::BlendFactorForSide<Fad<REAL>>(
const int &,
const TPZVec<Fad<REAL>> &,
Fad<REAL> &,
1327 TPZVec<Fad<REAL>> &);
1334 template void pztopology::TPZQuadrilateral::ComputeHCurlFaceDirections<Fad<REAL>>(TPZVec<Fad<REAL>> &v1, TPZVec<Fad<REAL>> &v2,
int transformationId);
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
Contains the TPZInt1d, TPZIntTriang, TPZIntQuad, TPZIntCube3D, TPZIntTetra3D, TPZIntPyram3D and TPZIn...
static int vectorsideorder[18]
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
void computedirectionsq(int inicio, int fim, TPZFMatrix< REAL > &bvec, TPZFMatrix< REAL > &t1vec, TPZFMatrix< REAL > &gradx, TPZFMatrix< REAL > &directions)
clarg::argInt dimension("-d", "Matrices dimension M x M", 1000)
static REAL sidetosidetransforms[9][3][4][3]
Defines enum MElementType and contains the implementation of MElementType_NNodes(...) functions.
This class implements a simple vector storage scheme for a templated class T. Utility.
REAL val(STATE &number)
Returns value of the variable.
static TPZTransform SideToSideTransform(int sidefrom, int sideto)
returns the transformation which takes a point from the side sidefrom to the side sideto ...
static int direcaoksioueta[18]
static int highsides[9][3]
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
Handles the numerical integration for one-dimensional problems. Numerical Integration.
static int bilinearounao[18]
#define LOGPZ_FATAL(A, B)
Define log for fatal errors (cout)
Abstract class defining integration rules. Numerical Integration.
int Zero() override
Makes Zero all the elements.
int64_t size() const
Returns the number of elements of the vector.
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...
Handles the numerical integration for two-dimensional problems using quadrilateral elements...
Groups all classes defining the structure of the master element.
void Push(const T object)
Pushes a copy of the object on the stack.
#define DebugStop()
Returns a message to user put a breakpoint in.
Free store vector implementation.
Contains the TPZQuadrilateral class which defines the topology of a quadrilateral element...
int64_t Rows() const
Returns number of rows.
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ sqrt
static int sidedimension[9]
#define LOGPZ_ERROR(A, B)
Define log for errors (cout)
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
int32_t Hash(std::string str)
static int nhighdimsides[9]
Integration rule for one point. Numerical Integration.
MElementType
Define the element types.
int64_t Cols() const
Returns number of cols.
static REAL MidSideNode[9][3]
int Resize(const int64_t newRows, const int64_t wCols) override
Redimension a matrix, but maintain your elements.
Defines the interface for saving and reading data. Persistency.
Contains the declaration of TPZFlopCounter class and TPZCounter struct.
Contains declaration of the TPZNumeric class which implements several methods to calculation.
int PutVal(const int64_t row, const int64_t col, const TVar &value) override
Put values without bounds checking This method is faster than "Put" if DEBUG is defined.
Non abstract class which implements full matrices with preallocated storage with (N+1) entries...
#define PZError
Defines the output device to error messages and the DebugStop() function.