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 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; }
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; }