Exemplo n.º 1
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;
		}
	}
}
Exemplo n.º 2
0
void TPZAnalysisError::MathematicaPlot() {
	
	TPZGeoMesh *gmesh = fCompMesh->Reference();
	TPZAdmChunkVector<TPZGeoNode> &listnodes = gmesh->NodeVec();
	int64_t nnodes = gmesh->NNodes();
	TPZAdmChunkVector<TPZGeoNode> nodes(listnodes);
	TPZVec<int64_t> nodeindex(0);
	int64_t keepindex;
	int64_t in;
    TPZGeoNode *nodei = 0;   /// jorge 2017 - I think it's unnecessary, because if node is created its exists always
	for(in=0;in<nnodes;in++) {
		nodei = &nodes[in];
		REAL xi;
		if(nodei) xi = nodei->Coord(0);
		else continue;
		keepindex = in;
		for(int64_t jn=in;jn<nnodes;jn++) {
			TPZGeoNode *nodej = &nodes[jn];
			REAL xj;
			if(nodej) xj = nodej->Coord(0); else continue;
			if(xj < xi) {
				keepindex = jn;
				xi = xj;
			}
		}
		if(keepindex!=in) {
			TPZGeoNode commut = nodes[in];
			nodes[in] = nodes[keepindex];
			nodes[keepindex] = commut;
		}
	}
	ofstream mesh("Malha.dat");
	ofstream graph("Graphic.nb");
	mesh << "\nDistribuicao de nos\n\n";
	int64_t i;
	for(i=0;i<nnodes;i++) {
        nodei = &nodes[i];
		if(nodei) mesh << nodei->Coord(0) << endl;
	}
	//2a parte
	TPZVec<int64_t> locnodid(nnodes,0);
	TPZVec<TPZGeoEl *> gelptr(nnodes);
	int64_t nel = gmesh->NElements();
	int64_t count = 0;
	for(in=0;in<nnodes;in++) {
		nodei = &nodes[in];
		if(!nodei) continue;
		for(int64_t iel=0;iel<nel;iel++) {
			TPZGeoEl *gel = gmesh->ElementVec()[iel];
			if(!gel || !gel->Reference() || gel->MaterialId() < 0) continue;
			//int numnodes = gel->NNodes();
			int ic=0;//for(int ic=0;ic<numnodes;ic++)
			if(in==nnodes-1) ic = 1;
			if(nodei->Id() == gel->NodePtr(ic)->Id()) {
				gelptr[count] = gel;
				locnodid[count++] = ic;
				break;
            }
		}
	}
	TPZVec<int64_t> connects(nnodes);
	int64_t iel;
	for(iel=0;iel<nnodes;iel++) {
		//if(!gelptr[iel] || !(gelptr[iel]->Reference())) continue;
		connects[iel] = gelptr[iel]->Reference()->ConnectIndex(locnodid[iel]);
	}
	TPZVec<STATE> sol(nnodes);
	for(i=0; i<nnodes; i++) {
        TPZConnect *df = &fCompMesh->ConnectVec()[connects[i]];
        if(!df) {
         	cout << "\nError in structure of dates\n";
            mesh << "\nError in structure of dates\n";
            return;//exit(-1);
        }
        int64_t seqnum = df->SequenceNumber();
        int64_t pos = fCompMesh->Block().Position(seqnum);
        sol[i] = fCompMesh->Solution()(pos,0);
	}
	mesh << "\nSolucao nodal\n\n";
	for(i=0;i<nnodes;i++) {
		mesh << sol[i] << endl;
	}
	// expanding solution
	int64_t numsols = 5*(nnodes-1)+1;   // 5 values by element: 3 interpolated (interior) + 2 over corners
	TPZVec<STATE> expand_sol(numsols);
	TPZVec<REAL> expand_nodes(numsols);
 	TPZVec<REAL> qsi(1);
	int64_t exp_iel = -1;
	for(iel=0;iel<nnodes-1;iel++) {
		TPZManVector<STATE> locsol(1);
		exp_iel++;
		expand_sol[exp_iel] = sol[iel];
		qsi[0] = -1.;
		expand_nodes[exp_iel] = nodes[iel].Coord(0);
		REAL h = h_Parameter(gelptr[iel]->Reference());
		for(int i=1;i<5;i++) {
			exp_iel++;
			expand_nodes[exp_iel] = i*h/5. + nodes[iel].Coord(0);
			qsi[0] += .4;
			gelptr[iel]->Reference()->Solution(qsi,0,locsol);
			expand_sol[exp_iel] = locsol[0];
		}
	}
	expand_nodes[numsols-1] = nodes[nnodes-1].Coord(0);
	expand_sol[numsols-1] = sol[nnodes-1];
	// Mathematica output format
	graph << "list = {" << endl;
	for(int64_t isol=0;isol<numsols;isol++) {
		if(isol > 0) graph << ",";
		STATE expandsol = expand_sol[isol];
		if(fabs(expandsol) < 1.e-10) expandsol = 0.;
		graph << "{" << expand_nodes[isol] << "," << expandsol << "}";
		if( !((isol+1)%5) ) graph << endl;
	}
	graph << "\n};\n";
	graph << "ListPlot[list, PlotJoined->True, PlotRange->All];" << endl;
}
Exemplo n.º 3
0
REAL TPZMGAnalysis::ElementError(TPZInterpolatedElement *fine, TPZInterpolatedElement *coarse, TPZTransform &tr,
								 void (*f)(TPZVec<REAL> &loc, TPZVec<REAL> &val, TPZFMatrix<REAL> &deriv),REAL &truerror){
	// accumulates the transfer coefficients between the current element and the
	// coarse element into the transfer matrix, using the transformation t
	int locnod = fine->NConnects();
	int cornod = coarse->NConnects();
	int locmatsize = fine->NShapeF();
	int cormatsize = coarse->NShapeF();
	REAL error = 0.;
	truerror = 0.;
	
	REAL loclocmatstore[500] = {0.},loccormatstore[500] = {0.};
	TPZFMatrix<REAL> loclocmat(locmatsize,locmatsize,loclocmatstore,500);
	TPZFMatrix<REAL> loccormat(locmatsize,cormatsize,loccormatstore,500);
	
	TPZAutoPointer<TPZIntPoints> intrule = fine->GetIntegrationRule().Clone();
	int dimension = fine->Dimension();
	int numdof = fine->Material()->NStateVariables();
	TPZBlock<REAL> &locblock = fine->Mesh()->Block();
	TPZFMatrix<REAL> &locsolmesh = fine->Mesh()->Solution();
	
	TPZBlock<REAL> &corblock = coarse->Mesh()->Block();
	TPZFMatrix<REAL> &corsolmesh = coarse->Mesh()->Solution();
	
	TPZVec<REAL> locsol(numdof);
	TPZFMatrix<REAL> locdsol(dimension,numdof);
	
	TPZVec<REAL> corsol(numdof);
	TPZFMatrix<REAL> cordsol(dimension,numdof);
	
	TPZManVector<int> prevorder(dimension),
    order(dimension);
	intrule->GetOrder(prevorder);
	
	TPZManVector<int> interpolation(dimension);
	fine->GetInterpolationOrder(interpolation);
	
	// compute the interpolation order of the shapefunctions squared
	int dim;
	int maxorder = interpolation[0];
	for(dim=0; dim<interpolation.NElements(); dim++) {
		maxorder = interpolation[dim] < maxorder ? maxorder : interpolation[dim];
	}
	for(dim=0; dim<dimension; dim++) {
		order[dim] = 20;
	}
	intrule->SetOrder(order);
	
	
	REAL locphistore[50]={0.},locdphistore[150]={0.};
	TPZFMatrix<REAL> locphi(locmatsize,1,locphistore,50);
	TPZFMatrix<REAL> locdphi(dimension,locmatsize,locdphistore,150),locdphix(dimension,locmatsize);
	// derivative of the shape function
	// in the master domain
	
	REAL corphistore[50]={0.},cordphistore[150]={0.};
	TPZFMatrix<REAL> corphi(cormatsize,1,corphistore,50);
	TPZFMatrix<REAL> cordphi(dimension,cormatsize,cordphistore,150), cordphix(dimension,cormatsize);
	// derivative of the shape function
	// in the master domain
	
	REAL jacobianstore[9],
    axesstore[9];
	TPZManVector<REAL> int_point(dimension),
    coarse_int_point(dimension);
	TPZFMatrix<REAL> jacfine(dimension,dimension,jacobianstore,9),jacinvfine(dimension,dimension);
	TPZFMatrix<REAL> axesfine(3,3,axesstore,9);
	TPZManVector<REAL> xfine(3);
	TPZFMatrix<REAL> jaccoarse(dimension,dimension),jacinvcoarse(dimension,dimension);
	TPZFMatrix<REAL> axescoarse(3,3), axesinner(dimension,dimension);
	TPZManVector<REAL> xcoarse(3);
	
	REAL jacdetcoarse;
	int numintpoints = intrule->NPoints();
	REAL weight;
	int i,j,k;
	
	TPZVec<REAL> truesol(numdof);
	TPZFMatrix<REAL> truedsol(dimension,numdof);
	for(int int_ind = 0; int_ind < numintpoints; ++int_ind) {
		
		intrule->Point(int_ind,int_point,weight);
		REAL jacdetfine;
		fine->Reference()->Jacobian( int_point, jacfine , axesfine, jacdetfine, jacinvfine);
		fine->Reference()->X(int_point, xfine);
		if(f) f(xfine,truesol,truedsol);
		fine->Shape(int_point,locphi,locdphi);
		tr.Apply(int_point,coarse_int_point);
		coarse->Shape(coarse_int_point,corphi,cordphi);
		coarse->Reference()->Jacobian( coarse_int_point,jaccoarse,axescoarse, jacdetcoarse, jacinvcoarse);
		coarse->Reference()->X(coarse_int_point,xcoarse);
		REAL dist = (xfine[0]-xcoarse[0])*(xfine[0]-xcoarse[0])+(xfine[1]-xcoarse[1])*(xfine[1]-xcoarse[1])+(xfine[2]-xcoarse[2])*(xfine[2]-xcoarse[2]);
		if(dist > 1.e-6) cout << "TPZMGAnalysis::ElementError transformation between fine and coarse is wrong\n";
		for(i=0; i<dimension; i++) {
			for(j=0; j<dimension; j++) {
				axesinner(i,j) = 0.;
				for(k=0; k<3; k++) axesinner(i,j) += axesfine(i,k)*axescoarse(j,k);
			}
		}
		if(fabs(axesinner(0,0)-1.) > 1.e-6 || fabs(axesinner(1,1)-1.) > 1.e-6 || fabs(axesinner(0,1)) > 1.e-6 || fabs(axesinner(1,0)) > 1.e-6) {
			cout << "TPZMGAnalysis axesinner is not identify?\n";
		}
		weight *= fabs(jacdetfine);
		
		locdphix.Zero();
		
		int ieq,d;
		switch(dim) {
			case 0:
				//dphix.Redim(1,1);
				//dphix(0,0) = dphi(0,0);
				break;
			case 1:
				for(d=0; d<dimension; d++) {
					for(ieq=0; ieq<locmatsize; ieq++) locdphix(d,ieq) = locdphi(d,ieq)*(1./jacdetfine);
					for(ieq=0; ieq<cormatsize; ieq++) cordphix(d,ieq) = cordphi(d,ieq)*(axesinner(0,0)/jacdetcoarse);
				}
				break;
			case 2:
				for(ieq = 0; ieq < locmatsize; ieq++) {
					locdphix(0,ieq) = jacinvfine(0,0)*locdphi(0,ieq) + jacinvfine(1,0)*locdphi(1,ieq);
					locdphix(1,ieq) = jacinvfine(0,1)*locdphi(0,ieq) + jacinvfine(1,1)*locdphi(1,ieq);
					REAL tmp[2];
					tmp[0] = locdphix(0,ieq)*axesfine(0,0)+locdphix(1,ieq)*axesfine(1,0);
					tmp[1] = locdphix(0,ieq)*axesfine(0,1)+locdphix(1,ieq)*axesfine(1,1);
					locdphix(0,ieq) = tmp[0];
					locdphix(1,ieq) = tmp[1];
				}
				for(ieq = 0; ieq < cormatsize; ieq++) {
					cordphix(0,ieq) = jacinvcoarse(0,0)*cordphi(0,ieq) + jacinvcoarse(1,0)*cordphi(1,ieq);
					cordphix(1,ieq) = jacinvcoarse(0,1)*cordphi(0,ieq) + jacinvcoarse(1,1)*cordphi(1,ieq);
					REAL tmp[2];
					tmp[0] = cordphix(0,ieq)*axescoarse(0,0)+cordphix(1,ieq)*axescoarse(1,0);
					tmp[1] = cordphix(0,ieq)*axescoarse(0,1)+cordphix(1,ieq)*axescoarse(1,1);
					cordphix(0,ieq) = tmp[0];
					cordphix(1,ieq) = tmp[1];
				}
				break;
			case 3:
				for(ieq = 0; ieq < locmatsize; ieq++) {
					locdphix(0,ieq) = jacinvfine(0,0)*locdphi(0,ieq) + jacinvfine(0,1)*locdphi(1,ieq) + jacinvfine(0,2)*locdphi(2,ieq);
					locdphix(1,ieq) = jacinvfine(1,0)*locdphi(0,ieq) + jacinvfine(1,1)*locdphi(1,ieq) + jacinvfine(1,2)*locdphi(2,ieq);
					locdphix(2,ieq) = jacinvfine(2,0)*locdphi(0,ieq) + jacinvfine(2,1)*locdphi(1,ieq) + jacinvfine(2,2)*locdphi(2,ieq);
				}
				for(ieq = 0; ieq < cormatsize; ieq++) {
					cordphix(0,ieq) = jacinvcoarse(0,0)*cordphi(0,ieq) + jacinvcoarse(0,1)*cordphi(1,ieq) + jacinvcoarse(0,2)*cordphi(2,ieq);
					cordphix(1,ieq) = jacinvcoarse(1,0)*cordphi(0,ieq) + jacinvcoarse(1,1)*cordphi(1,ieq) + jacinvcoarse(1,2)*cordphi(2,ieq);
					cordphix(2,ieq) = jacinvcoarse(2,0)*cordphi(0,ieq) + jacinvcoarse(2,1)*cordphi(1,ieq) + jacinvcoarse(2,2)*cordphi(2,ieq);
					REAL tmp[3];
					tmp[0] = cordphix(0,ieq)*axesinner(0,0)+cordphix(1,ieq)*axesinner(0,1)+cordphix(2,ieq)*axesinner(0,2);
					tmp[1] = cordphix(0,ieq)*axesinner(1,0)+cordphix(1,ieq)*axesinner(1,1)+cordphix(2,ieq)*axesinner(1,2);
					tmp[2] = cordphix(0,ieq)*axesinner(2,0)+cordphix(1,ieq)*axesinner(2,1)+cordphix(2,ieq)*axesinner(2,2);
					cordphix(0,ieq) = tmp[0];
					cordphix(1,ieq) = tmp[1];
					cordphix(2,ieq) = tmp[2];
				}
				break;
			default:
				PZError << "pzintel.c please implement the " << dim << "d Jacobian and inverse\n";
				PZError.flush();
		}
		int iv=0;
		locsol.Fill(0.);
		locdsol.Zero();
		iv=0;
		int in;
		for(in=0; in<locnod; in++) {
			TPZConnect *df = &fine->Connect(in);
			int dfseq = df->SequenceNumber();
			int dfvar = locblock.Size(dfseq);
			int pos = locblock.Position(dfseq);
			
			for(int jn=0; jn<dfvar; jn++) {
				locsol[iv%numdof] += locphi(iv/numdof,0)*locsolmesh(pos+jn,0);
				for(d=0; d<dim; d++)
					locdsol(d,iv%numdof) += locdphix(d,iv/numdof)*locsolmesh(pos+jn,0);
				iv++;
			}
		}
		corsol.Fill(0.);
		cordsol.Zero();
		iv=0;
		for(in=0; in<cornod; in++) {
			TPZConnect *df = &coarse->Connect(in);
			int dfseq = df->SequenceNumber();
			int dfvar = corblock.Size(dfseq);
			int pos = corblock.Position(dfseq);
			for(int jn=0; jn<dfvar; jn++) {
				corsol[iv%numdof] += corphi(iv/numdof,0)*corsolmesh(pos+jn,0);
				for(d=0; d<dim; d++)
					cordsol(d,iv%numdof) += cordphix(d,iv/numdof)*corsolmesh(pos+jn,0);
				iv++;
			}
		}
		int jn;
		for(jn=0; jn<numdof; jn++) {
			//       error += (locsol[jn]-corsol[jn])*(locsol[jn]-corsol[jn])*weight;
			//       if(f) truerror += (corsol[jn]-truesol[jn])*(corsol[jn]-truesol[jn])*weight;
			for(d=0; d<dim; d++) {
				error += (locdsol(d,jn)-cordsol(d,jn))*(locdsol(d,jn)-cordsol(d,jn))*weight;
				if(f) truerror += (cordsol(d,jn)-truedsol(d,jn))*(cordsol(d,jn)-truedsol(d,jn))*weight;
			}
		}
	}
	intrule->SetOrder(prevorder);
	return error;
}