示例#1
0
/**
 * @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();
}
示例#2
0
/**
 * @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();
}
示例#3
0
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;
}
示例#4
0
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;
	}
}
示例#5
0
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;
		}
	}
}
示例#6
0
//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;
}