/** * @brief transform in low order Raviar Tomas */ void TPZCreateApproximationSpace::UndoMakeRaviartTomas(TPZCompMesh &cmesh) { int numcell = cmesh.NElements(); int el; for (el = 0; el<numcell ; el++) { TPZCompEl *cel = cmesh.ElementVec()[el]; TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(cel); if (!intel) { continue; } TPZGeoEl *gel = intel->Reference(); int geldim = gel->Dimension(); int is; int nsides = gel->NSides(); for (is=0; is<nsides; is++) { if (gel->SideDimension(is) != geldim-1) { continue; } int nsconnects = intel->NSideConnects(is); // only interested in HDiv elements if (nsconnects != 1) { continue; } // int cindex = intel->SideConnectIndex(0, is); TPZConnect &c = intel->Connect(intel->SideConnectLocId(0,is)); if (c.HasDependency()) { c.RemoveDepend(); } } } cmesh.ExpandSolution(); cmesh.CleanUpUnconnectedNodes(); }
/** * @brief transform in low order Raviar Tomas */ void TPZCreateApproximationSpace::MakeRaviartTomas(TPZCompMesh &cmesh) { int numcell = cmesh.NElements(); int el; for (el = 0; el<numcell ; el++) { TPZCompEl *cel = cmesh.ElementVec()[el]; TPZInterpolationSpace *intel = dynamic_cast<TPZInterpolationSpace *>(cel); if (!intel) { continue; } intel->SetPreferredOrder(1); } cmesh.ExpandSolution(); for (el = 0; el<numcell ; el++) { TPZCompEl *cel = cmesh.ElementVec()[el]; TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(cel); if (!intel) { continue; } TPZGeoEl *gel = intel->Reference(); int geldim = gel->Dimension(); int is; int nsides = gel->NSides(); for (is=0; is<nsides; is++) { if (gel->SideDimension(is) != geldim-1) { continue; } int nsconnects = intel->NSideConnects(is); // only interested in HDiv elements if (nsconnects != 1) { continue; } int cindex = intel->SideConnectIndex(0, is); TPZConnect &c = intel->Connect(intel->SideConnectLocId(0,is)); if (c.HasDependency()) { continue; } int nshape = 1; int nstate = 1; int order = 0; int cindex2 = cmesh.AllocateNewConnect(nshape, nstate, order); // TPZConnect &c2 = cmesh.ConnectVec()[cindex]; TPZFNMatrix<2> depmat(2,1,1.); c.AddDependency(cindex, cindex2, depmat, 0, 0, 2, 1); } } cmesh.ExpandSolution(); }
TPZCompMesh *TPZMGAnalysis::UniformlyRefineMesh(TPZCompMesh *mesh, bool withP) { TPZGeoMesh *gmesh = mesh->Reference(); if(!gmesh) { cout << "TPZMGAnalysis::UniformlyRefineMesh encountered no geometric mesh\n"; return 0; } gmesh->ResetReference(); TPZCompMesh *cmesh = new TPZCompMesh(gmesh); mesh->CopyMaterials(*cmesh); TPZAdmChunkVector<TPZCompEl *> &elementvec = mesh->ElementVec(); int el,nelem = elementvec.NElements(); for(el=0; el<nelem; el++) { TPZCompEl *cel = elementvec[el]; if(!cel) continue; TPZInterpolatedElement *cint = dynamic_cast<TPZInterpolatedElement *> (cel); if(!cint) { cout << "TPZMGAnalysis::UniformlyRefineMesh encountered a non interpolated element\n"; continue; } int ncon = cint->NConnects(); int porder = cint->PreferredSideOrder(ncon-1); TPZGeoEl *gel = cint->Reference(); if(!gel) { cout << "TPZMGAnalysis::UniformlyRefineMesh encountered an element without geometric reference\n"; continue; } TPZVec<TPZGeoEl *> sub; gel->Divide(sub); int nsub = sub.NElements(); int isub; int celindex; for(isub=0; isub<nsub; isub++) { TPZInterpolatedElement *csint; csint = (TPZInterpolatedElement *) cmesh->CreateCompEl(sub[isub],celindex); if(withP) csint->PRefine(porder+1); else csint->PRefine(porder); } } return cmesh; }
void TPZMGAnalysis::MeshError(TPZCompMesh *fine, TPZCompMesh *coarse, TPZVec<REAL> &ervec, void (*f)(TPZVec<REAL> &loc, TPZVec<REAL> &val, TPZFMatrix<REAL> &deriv),TPZVec<REAL> &truervec){ coarse->Reference()->ResetReference(); coarse->LoadReferences(); int dim = fine->MaterialVec().begin()->second->Dimension(); ervec.Resize(coarse->NElements()); if(f) { truervec.Resize(coarse->NElements()); truervec.Fill(0.,0); } ervec.Fill(0.,0); TPZCompEl *cel; TPZAdmChunkVector<TPZCompEl *> &elementvec = fine->ElementVec(); int numel = elementvec.NElements(); int el; for(el=0; el<numel; el++) { cel = elementvec[el]; if (!cel) continue; TPZInterpolatedElement *cint = dynamic_cast<TPZInterpolatedElement *> (cel); if(!cint) continue; int ncon = cint->NConnects(); TPZGeoElSide gelside(cint->Reference(),ncon-1); if(gelside.Dimension() != dim) continue; TPZGeoElSide gellarge(gelside); while(!gellarge.Reference().Exists() && gellarge.Father2().Exists()) gellarge = gellarge.Father2(); if(!gellarge.Reference().Exists()) { cout << "TPZMGAnalsysis::BuildTransferMatrix element " << el << " found no corresponding element\n"; continue; } TPZCompElSide cellargeside = gellarge.Reference(); TPZCompEl *cellarge = cellargeside.Element(); TPZInterpolatedElement *cintlarge = (TPZInterpolatedElement *) cellarge; TPZTransform transform(gelside.Dimension(),gellarge.Dimension()); gelside.SideTransform3(gellarge,transform); int index = cellarge->Index(); REAL truerror = 0.; ervec[index] += ElementError(cint,cintlarge,transform,f,truerror); if(f) truervec[index] += truerror; } }
void TPZNonDarcyAnalysis::InitializeFirstSolution(TPZFMatrix<STATE> &Pressure, REAL &pini) { Pressure.Redim(fSolution.Rows(),fSolution.Cols()); TPZBlock<STATE> &block = this->Mesh()->Block(); int nel = this->Mesh()->NElements(); for (int iel = 0 ; iel < nel ; iel++){ TPZCompEl *cel = this->Mesh()->ElementVec()[iel]; if (!cel) continue; TPZInterpolatedElement *intel = dynamic_cast <TPZInterpolatedElement *> (cel); if (!intel) DebugStop(); if (intel->Reference()->Dimension() != 2) continue; //soh elem 2d. int ncc = intel->NCornerConnects(); //if (ncc != 4) DebugStop(); // I expect only quad element, althought it would work for triang for (int icc = 0 ; icc < ncc ; icc++){ TPZConnect *con = &intel->Connect(icc); int conseq = con->SequenceNumber(); int pos = block.Position(conseq); Pressure(pos,0) = pini; } } }
//void DivideRecursive(TPZCompEl *locel,int index,TPZVec<int> indexsubs,int hn); void TPZAnalysisError::HPAdapt(REAL CurrentEtaAdmissible, std::ostream &out) { arq << "CurrentEtaAdmissible " << CurrentEtaAdmissible << endl; TPZAdmChunkVector<TPZCompEl *>&listel = Mesh()->ElementVec(); bool store_error = false; EvaluateError(CurrentEtaAdmissible,store_error, out); TPZVec<TPZCompElSide> SingLocal(fSingular); fSingular.Resize(0); int64_t nel = fElIndexes.NElements(); for(int64_t ielloc=0;ielloc<nel;ielloc++) { int64_t iel = fElIndexes[ielloc]; // if the element has already been treated (e.g. singularity) skip the process if(iel == -1) continue; TPZInterpolatedElement *elem = (TPZInterpolatedElement *) listel[iel]; if(!elem || elem->Material()->Id() < 0) { PZError << "TPZAnalysisError::HPAdapt boundary element with error?\n"; PZError.flush(); continue; } REAL csi = fElErrors[ielloc] / fAdmissibleError; // Verificar se o element atual e um elemento singular int64_t ising, nsing = SingLocal.NElements(); for(ising=0; ising<nsing; ising++) { if(elem == SingLocal[ising].Element()) { ZoomInSingularity(csi,SingLocal[ising]); break; } } // Go to the end of the loop if the element was handled by the singularity if(ising < nsing) continue; //calculo da ordem pn do elemento atual int nsides = elem->Reference()->NSides(); REAL pFo = double(elem->EffectiveSideOrder(nsides-1));//quadrilatero // Newton's Method -> compute pNew REAL pFn = pFo, res = 10.0, phi, del, dph, tol = 0.001; int64_t MaxIter = 100; int64_t iter=0; while (iter < MaxIter && res > tol) { phi = pFo+log(csi)-pFo*log(pFn/pFo); dph = pFn/(pFo+pFn); del = dph*(phi-pFn); if (del+pFn <= 0.0) // caiu fora do intervalo! del = 0.5 - pFn; res = fabs(del); pFn = del+pFn; iter++; } // end of Newton's Method if (iter == MaxIter) PZError << "\n - Newton's Method Failed at Element = " << elem->Reference()->Id() << endl; if(pFn < 1.) pFn = 1.; REAL factor = pow(csi,-1.0/pFn)*(pow(pFn/pFo,pFo/pFn)); if(factor <= 0.75) factor = 0.5; // refine h else factor = 1.0; // don't refine h // Newton's Method -> compute once again pNew pFn = pFo; iter = 0; res = 10.0; while (iter < MaxIter && res > tol) { phi = -pFn*log(factor)-log(csi)+pFo*log(pFn/pFo); dph = pFn/(pFo-pFn*log(factor)); del = -dph*phi; if (del+pFn <= 0.0) // caiu fora do intervalo! del = 0.5 - pFn; res = fabs(del); pFn = del+pFn; iter++; } // end of Newton's Method if (iter == MaxIter) PZError << "\n - Newton's Method Failed at Element = " << elem->Reference()->Id() << endl; if(pFn < 1.) pFn = 1.; int pNew = 0;//(int) floor(pFn + 0.5); // get the integer while(REAL(pNew) < (pFn+0.5)) pNew++; TPZVec<REAL> x(3),cs(2,0.); elem->Reference()->X(cs,x); elem->PRefine(pNew); TPZCompEl *locel = elem; //Divide elements if(factor == 0.5 ) { TPZVec<int64_t> indexsubs; int64_t index = locel->Index(); elem->Divide(index,indexsubs,1); } } }
TPZFlowCompMesh * RSNACompMesh(TPZFlowCompMesh *cmesh, REAL CFL, REAL delta, int degree, int nSubdiv, TPZArtDiffType DiffType, TPZTimeDiscr Diff_TD, TPZTimeDiscr ConvVol_TD, TPZTimeDiscr ConvFace_TD) { TPZCompEl::SetgOrder(degree); REAL gamma = 1.4; // Configuring the PZ to generate discontinuous elements // TPZGeoElement<TPZShapeQuad,TPZGeoQuad,TPZRefQuad> // ::SetCreateFunction(TPZCompElDisc::CreateDisc); // // TPZGeoElement<TPZShapeLinear,TPZGeoLinear,TPZRefLinear> // ::SetCreateFunction(TPZCompElDisc::CreateDisc); int dim = 2; // int interfdim = dim -1; // TPZCompElDisc::gInterfaceDimension = interfdim; // Retrieving the point coordinates and element references TPZVec< TPZVec< REAL > > nodes; TPZVec< TPZVec< int64_t > > elms; TPZVec< TPZGeoEl *> gElem; RSNAMeshPoints(nodes, elms); // Creating the geometric mesh TPZGeoMesh * gmesh = CreateRSNAGeoMesh(cmesh->Reference(), nodes, elms, EQuadrilateral, 1, gElem, nSubdiv); //TPZFlowCompMesh * cmesh = new TPZFlowCompMesh(gmesh); cmesh->SetDimModel(2); // Creating the materials TPZEulerConsLaw * matp = new TPZEulerConsLaw(1/*nummat*/, 0/*timeStep*/, gamma /*gamma*/, 2 /* dim*/, DiffType); // Setting initial solution matp->SetForcingFunction(NULL); // Setting the time discretization method matp->SetTimeDiscr(Diff_TD, ConvVol_TD, ConvFace_TD); //mat->SetDelta(0.1); // Not necessary, since the artDiff // object computes the delta when it equals null. matp->SetCFL(CFL); /* REAL us = sqrt(2.6 * 2.6 + .51 * .51); REAL press = 1.52819; REAL cspeed = sqrt(1.4*press/1.7); REAL lambdaMax = us + cspeed; */ // cout << .22/(2/**lambdaMax*/); matp->SetDelta(delta); TPZMaterial * mat(matp); cmesh -> InsertMaterialObject(mat); // Boundary conditions TPZMaterial *bc; TPZFMatrix<STATE> val1(4,4), val2(4,1); REAL ro = 1.7, u = 2.61934, v = -0.50632, p = 1.52819, vel2 = u*u + v*v; // copiado do Cedric //CC ARESTA INFERIOR : PAREDE val1.Zero(); val2.Zero(); TPZGeoElBC((TPZGeoEl *)gElem[0],4,-1); TPZGeoElBC((TPZGeoEl *)gElem[1],4,-1); bc = mat->CreateBC(mat,-1,5,val1,val2); cmesh->InsertMaterialObject(bc); //CC ARESTA DIREITA : OUTFLOW val1.Zero(); val2.Zero(); TPZGeoElBC((TPZGeoEl *)gElem[1],5,-2); bc = mat->CreateBC(mat,-2,4,val1,val2); cmesh->InsertMaterialObject(bc); //CC ARESTA SUPERIOR : DIRICHLET val1.Zero(); val2.Zero(); val2(0,0) = ro; val2(1,0) = ro * u; val2(2,0) = ro * v; val2(3,0) = p/(gamma-1.0) + 0.5 * ro * vel2; TPZGeoElBC((TPZGeoEl *)gElem[0],6,-3); TPZGeoElBC((TPZGeoEl *)gElem[1],6,-3); bc = mat->CreateBC(mat,-3,3,val1,val2); cmesh->InsertMaterialObject(bc); //CC ARESTA ESQUERDA : INFLOW val1.Zero(); val2.Zero(); ro = 1.0; u = 2.9; v = 0.0; p = 0.714286; val2(0,0) = ro; val2(1,0) = ro * u; val2(2,0) = ro * v; vel2 = u*u+v*v; val2(3,0) = p/(gamma-1.0) + 0.5 * ro * vel2; TPZGeoElBC((TPZGeoEl *)gElem[0],7,-4); bc = mat->CreateBC(mat,-4,3,val1,val2); cmesh->InsertMaterialObject(bc); cmesh->AutoBuild(); cmesh->AdjustBoundaryElements(); // printing meshes ofstream geoOut("geomesh.out"); gmesh->Print(geoOut); geoOut.close(); ofstream compOut("compmesh.out"); cmesh->Print(compOut); compOut.close(); // generating initial guess for the mesh solution TPZFMatrix<STATE> Solution = cmesh->Solution(); int nVars = Solution.Rows(); for(int k = 0; k < nVars; k++)Solution(k)=.1; int nel = cmesh->NElements(); int iel; for(iel=0; iel<nel; iel++) { TPZCompEl *cel = cmesh->ElementVec()[iel]; TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(cel); TPZCompElDisc *disc = dynamic_cast<TPZCompElDisc *>(cel); if(intel) { int nnodes = intel->Reference()->NNodes(); int in; for(in = 0; in<nnodes; in++) { int blnum = intel->SideConnect(0,in).SequenceNumber(); int blockOffset = cmesh->Block().Position(blnum); REAL ro = 1.7, u = 2.9, v = 0, p = 2.714286, vel2 = u*u + v*v; Solution(blockOffset ,0) = ro; Solution(blockOffset+1,0) = ro * u; Solution(blockOffset+2,0) = ro * v; Solution(blockOffset+3,0) = p/(gamma-1.0) + 0.5 * ro * vel2; } } else if(disc) { int conind = disc->ConnectIndex(); // skip boundary elements if(conind < 0) continue; int blnum = cmesh->ConnectVec()[conind].SequenceNumber(); int blpos = cmesh->Block().Position(blnum); int blsize = cmesh->Block().Size(blnum); int blockOffset = blpos+blsize-(dim+2); REAL ro = 1.7, u = 2.9, v = 0, p = 2.714286, vel2 = u*u + v*v; Solution(blockOffset ,0) = ro; Solution(blockOffset+1,0) = ro * u; Solution(blockOffset+2,0) = ro * v; Solution(blockOffset+3,0) = p/(gamma-1.0) + 0.5 * ro * vel2; } } /* int j, NSolutionBlocks; //TPZBlock * pBlock = cmesh->Block(); NSolutionBlocks = cmesh->Block().NBlocks(); int nShape = Solution.Rows() / NSolutionBlocks / (dim + 2); int lastShapeFun = (nShape - 1)*(dim+2); for(j = 0; j < NSolutionBlocks; j++) { int blockOffset = cmesh->Block().Position(j) + lastShapeFun; REAL ro = 1.7, u = 2.9, v = 0, p = 2.714286, vel2 = u*u + v*v; Solution(blockOffset ,0) = ro; Solution(blockOffset+1,0) = ro * u; Solution(blockOffset+2,0) = ro * v; Solution(blockOffset+3,0) = p/(gamma-1.0) + 0.5 * ro * vel2; }*/ cmesh->LoadSolution(Solution); return cmesh; }