示例#1
0
int TPZTransform::Compare(TPZTransform &t,REAL tol){
	
	if(fCol != t.fCol || fRow != t.fRow)
		return 1;
	int i,j;
	for(i=0;i<fRow;i++){
		if(fabs(fSum(i,0) - t.fSum(i,0)) > tol) return 1;
		for(j=0;j<fCol;j++){
			if(fabs(fMult(i,j) - t.fMult(i,j)) > tol) return 1;
		}
	}
	return 0;
}
示例#2
0
int TPZCheckGeom::CheckSideTransform(TPZGeoEl *gel, int sidefrom, int sideto){
	
	int check = 0;
	int nsides = gel->NSides();
	TPZIntPoints *integ = gel->CreateSideIntegrationRule(sidefrom,2);
	TPZTransform trans = gel->SideToSideTransform(sidefrom,sideto);
	TPZTransform trans1 = gel->SideToSideTransform(sidefrom,nsides-1);
	TPZTransform trans2 = gel->SideToSideTransform(sideto,nsides-1);
	int sidefromdim = gel->SideDimension(sidefrom);
	int sidetodim = gel->SideDimension(sideto);
	int geldim = gel->Dimension();
	TPZVec<REAL> intpoint(sidefromdim);
	TPZVec<REAL> sidetopoint(sidetodim);
	TPZVec<REAL> elpoint1(geldim),elpoint2(geldim);
	TPZVec<REAL> x1(3),x2(3);
	int nintpoints = integ->NPoints();
	int ip;
	REAL w;
	for(ip=0; ip<nintpoints; ip++) {
		integ->Point(ip,intpoint,w);
		trans.Apply(intpoint,sidetopoint);
		trans1.Apply(intpoint,elpoint1);
		trans2.Apply(sidetopoint,elpoint2);
		gel->X(elpoint1,x1);
		gel->X(elpoint2,x2);
		REAL dif = 0;
		int nx = x1.NElements();
		int ix;
		for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]);
		if(dif > 1.e-6) {
			PZError << "TPZCheckGeom::CheckSideTransform sidefrom = "<< sidefrom
			<< " sideto = " << sideto << " dif = " << dif << endl;
			gel->Print();
			check = 1;
		}
	}
	delete integ;
	return check;
}
示例#3
0
int CompareShapeFunctions(TPZCompElSide celsideA, TPZCompElSide celsideB)
{
    TPZGeoElSide gelsideA = celsideA.Reference();
    TPZGeoElSide gelsideB = celsideB.Reference();
    int sideA = gelsideA.Side();
    int sideB = gelsideB.Side();
    TPZCompEl *celA = celsideA.Element();
    TPZCompEl *celB = celsideB.Element();    TPZMultiphysicsElement *MFcelA = dynamic_cast<TPZMultiphysicsElement *>(celA);
    TPZMultiphysicsElement *MFcelB = dynamic_cast<TPZMultiphysicsElement *>(celB);
    TPZInterpolatedElement *interA = dynamic_cast<TPZInterpolatedElement *>(MFcelA->Element(0));
    TPZInterpolatedElement *interB = dynamic_cast<TPZInterpolatedElement *>(MFcelB->Element(0));
    
    TPZMaterialData dataA;
    TPZMaterialData dataB;
    interA->InitMaterialData(dataA);
    interB->InitMaterialData(dataB);
    TPZTransform<> tr = gelsideA.NeighbourSideTransform(gelsideB);
    TPZGeoEl *gelA = gelsideA.Element();
    TPZTransform<> trA = gelA->SideToSideTransform(gelsideA.Side(), gelA->NSides()-1);
    TPZGeoEl *gelB = gelsideB.Element();
    TPZTransform<> trB = gelB->SideToSideTransform(gelsideB.Side(), gelB->NSides()-1);
    
    int dimensionA = gelA->Dimension();
    int dimensionB = gelB->Dimension();
    
    int nSideshapeA = interA->NSideShapeF(sideA);
    int nSideshapeB = interB->NSideShapeF(sideB);
    int is;
    int firstShapeA = 0;
    int firstShapeB = 0;
    for (is=0; is<sideA; is++) {
        firstShapeA += interA->NSideShapeF(is);
    }
    for (is=0; is<sideB; is++) {
        firstShapeB += interB->NSideShapeF(is);
    }
    
    TPZIntPoints *intrule = gelA->CreateSideIntegrationRule(gelsideA.Side(), 4);
    int nwrong = 0;
    int npoints = intrule->NPoints();
    int ip;
    for (ip=0; ip<npoints; ip++) {
        TPZManVector<REAL,3> pointA(gelsideA.Dimension()),pointB(gelsideB.Dimension()), pointElA(gelA->Dimension()),pointElB(gelB->Dimension());
        REAL weight;
        intrule->Point(ip, pointA, weight);
        int sidedim = gelsideA.Dimension();
        TPZFNMatrix<9> jacobian(sidedim,sidedim),jacinv(sidedim,sidedim),axes(sidedim,3);
        REAL detjac;
        gelsideA.Jacobian(pointA, jacobian, jacinv, detjac, jacinv);
        TPZManVector<REAL,3> normal(3,0.), xA(3),xB(3);
        normal[0] = axes(0,1);
        normal[1] = -axes(0,0);
        tr.Apply(pointA, pointB);
        trA.Apply(pointA, pointElA);
        trB.Apply(pointB, pointElB);
        gelsideA.Element()->X(pointElA, xA);
        gelsideB.Element()->X(pointElB, xB);
        for (int i=0; i<3; i++) {
            if(fabs(xA[i]- xB[i])> 1.e-6) DebugStop();
        }
        int nshapeA = 0, nshapeB = 0;
        interA->ComputeRequiredData(dataA, pointElA);
        interB->ComputeRequiredData(dataB, pointElB);
        nshapeA = dataA.phi.Rows();
        nshapeB = dataB.phi.Rows();
        if(nSideshapeA != nSideshapeB) DebugStop();
        
        TPZManVector<REAL> shapesA(nSideshapeA), shapesB(nSideshapeB);
        int nwrongkeep(nwrong);
        int i,j;
        for(i=firstShapeA,j=firstShapeB; i<firstShapeA+nSideshapeA; i++,j++)
        {
            int Ashapeind = i;
            int Bshapeind = j;
            int Avecind = -1;
            int Bvecind = -1;
            // if A or B are boundary elements, their shapefunctions come in the right order
            if (dimensionA != sidedim) {
                Ashapeind = dataA.fVecShapeIndex[i].second;
                Avecind = dataA.fVecShapeIndex[i].first;
            }
            if (dimensionB != sidedim) {
                Bshapeind = dataB.fVecShapeIndex[j].second;
                Bvecind = dataB.fVecShapeIndex[j].first;
            }
            if (dimensionA != sidedim && dimensionB != sidedim) {
                // vefify that the normal component of the normal vector corresponds
                Avecind = dataA.fVecShapeIndex[i].first;
                Bvecind = dataB.fVecShapeIndex[j].first;
                REAL vecnormalA = dataA.fNormalVec(0,Avecind)*normal[0]+dataA.fNormalVec(1,Avecind)*normal[1];
                REAL vecnormalB = dataB.fNormalVec(0,Bvecind)*normal[0]+dataB.fNormalVec(1,Bvecind)*normal[1];
                if(fabs(vecnormalA-vecnormalB) > 1.e-6)
                {
                    nwrong++;
                    LOGPZ_ERROR(logger, "normal vectors aren't equal")
                }
                
            }
            shapesA[i-firstShapeA] = dataA.phi(Ashapeind,0);
            shapesB[j-firstShapeB] = dataB.phi(Bshapeind,0);
            REAL valA = dataA.phi(Ashapeind,0);
            REAL valB = dataB.phi(Bshapeind,0);
            REAL diff = valA-valB;
            REAL decision = fabs(diff)-1.e-6;
            if(decision > 0.)
            {
                nwrong ++;
                std::cout << "valA = " << valA << " valB = " << valB << " Avecind " << Avecind << " Bvecind " << Bvecind <<
                " Ashapeind " << Ashapeind << " Bshapeind " << Bshapeind <<
                " sideA " << sideA << " sideB " << sideB << std::endl;
                LOGPZ_ERROR(logger, "shape function values are different")
            }
示例#4
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;
}
示例#5
0
int TPZCheckGeom::CheckSubFatherTransform(TPZGeoEl *subel, int sidesub) {
	int check = 0;
	TPZGeoElSide father = subel->Father2(sidesub);
	if(!father.Exists()) return check;
	TPZIntPoints *integ = subel->CreateSideIntegrationRule(sidesub,2);
	int subsidedim = subel->SideDimension(sidesub);
	int subdim = subel->Dimension();
	TPZTransform trans(subsidedim);
	trans = subel->BuildTransform2(sidesub,father.Element(),trans);
	int fathsidedim = father.Dimension();
	int fathdim = father.Element()->Dimension();
	int nsubsides = subel->NSides();
	int nfathsides = father.Element()->NSides();
	TPZTransform trans1 = subel->SideToSideTransform(sidesub,nsubsides-1);
	TPZTransform trans2 = father.Element()->SideToSideTransform(father.Side(),nfathsides-1);
	TPZVec<REAL> intpoint(subsidedim);
	TPZVec<REAL> sidetopoint(fathsidedim);
	TPZVec<REAL> elpoint1(subdim),elpoint2(fathdim);
	TPZVec<REAL> x1(3),x2(3);
	int nintpoints = integ->NPoints();
	int ip;
	REAL w;
	for(ip=0; ip<nintpoints; ip++) {
		integ->Point(ip,intpoint,w);
		trans.Apply(intpoint,sidetopoint);
		trans1.Apply(intpoint,elpoint1);
		trans2.Apply(sidetopoint,elpoint2);
		subel->X(elpoint1,x1);
		father.Element()->X(elpoint2,x2);
		int otherfatherside = father.Element()->WhichSide(elpoint2);
		if(otherfatherside != father.Side()) {
			int son = subel->WhichSubel();
			PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
			<< " fathside = " << father.Side() << " otherfatherside = " << otherfatherside << endl;
			check=1;
		}
		REAL dif = 0;
		int nx = x1.NElements();
		int ix;
		for(ix=0; ix<nx; ix++) dif += (x1[ix]-x2[ix])*(x1[ix]-x2[ix]);
		if(dif > 1.e-6) {
			int son = subel->WhichSubel();
			PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
			<< " fathside = " << father.Side() << " dif = " << dif << endl;
			//			subel->Print();
			check = 1;
			TPZTransform t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub);
			t.PrintInputForm(cout);
			cout << endl;
			trans.PrintInputForm(cout);
			cout << endl;
			check = 1;
		}
		
	}
	if(check == 0) {
		TPZTransform t = subel->ComputeParamTrans(father.Element(),father.Side(),sidesub);
		check = t.Compare(trans);
		if(check == 1){
			int son = subel->WhichSubel();
			PZError << "TPZCheckGeom::CheckSubFatherTransform son " << son << " sidesub = "<< sidesub
			<< " fathside = " << father.Side()  << endl;
			t.PrintInputForm(cout);
			cout << endl;
			trans.PrintInputForm(cout);
			cout << endl;
		}
		// compare t with trans
	}
	
	delete integ;
	return check;
	
}