int SerialProgram::ConnectivityMaps(SolverUtils::Mesh::Connectivity nodesToElems){ std::ostringstream Ostr; std::stringstream ss; FunctionEntry("ConnectivityMaps"); std::cout << "In ConnectivityMaps function" << std::endl; //resize nodeToNode map nodeToNode.resize(numNodes); int elem, node; //Generate node to node map //loop over every node for(int i=0; i < numNodes; i++){ std::cout << "node " << i+1 << ":" << std::endl; //loop over every element for that node for(int j=0; j < nodesToElems[i].size(); j++){ std::cout << "element " << nodesToElems[i][j] << ":" << std::endl; elem = nodesToElems[i][j]-1; //loop over every node for that element for(int k=0; k < numNodesPerElem; k++){ node = elems[numNodesPerElem*elem + k]; //don't add the node to its own list if(node == i+1) continue; //loop over all the entries for the nodeToNode map and //see if this node has been added yet bool newValue=true; for(int l=0; l < nodeToNode[i].size(); l++){ if(node == nodeToNode[i][l]){ newValue=false; break; } } //if its a new value add it if(newValue){ nodeToNode[i].push_back(node); } } }//element around node loop }//node lope //print nodeToNode to check if(verblevel > 3){ Ostr << "Node to node map:" << std::endl; for(int i=0; i < nodeToNode.size(); i++){ Ostr << i+1 << ":" << std::endl; for(int j=0; j < nodeToNode[i].size(); j++){ Ostr << nodeToNode[i][j] << " "; } Ostr << std::endl; } } //Generate list of element edges from node to node map //loop over every node numNodesPerElemEdge = 2; numElemEdges = 0; for(int i=0; i < numNodes; i++){ //loop over every node connected to that node for(int j=0; j < nodeToNode[i].size(); j++){ node = nodeToNode[i][j]; //if the node # is greater than the current node then it //hasn't been processed yet so its a new edge if(node > i+1){ elemEdges.push_back(i+1); elemEdges.push_back(node); numElemEdges++; } }//nodes around node loop }//node loop //print nodeToNode to check if(verblevel > 3){ Ostr << "Element edges:" << std::endl; for(int i=0; i < numElemEdges; i++){ Ostr << i+1 << ":" << std::endl; for(int j=0; j < numNodesPerElemEdge; j++){ Ostr << elemEdges[i*numNodesPerElemEdge + j] << " "; } Ostr << std::endl; } } //Genereate a map from elements to element edges numEdgesPerElem = 6; //Everything is pretty much hard coded //for linear tets right now //loop over every element for(int i=0; i < numElems; i++){ //loop over every node for the element for(int j=0; j < numNodesPerElem; j++){ int n1, n2; n1 = elems[i*numNodesPerElem + j]; //loop over every other node for the element for(int k=j+1; k < numNodesPerElem; k++){ n2 = elems[i*numNodesPerElem + k]; //loop over every element edge to find what edge //these two nodes are for(int l=0; l < numElemEdges; l++){ if(n1 == elemEdges[l*numNodesPerElemEdge] && n2 == elemEdges[l*numNodesPerElemEdge + 1]) elemToElemEdges.push_back(l+1); else if(n2 == elemEdges[l*numNodesPerElemEdge] && n1 == elemEdges[l*numNodesPerElemEdge + 1]) elemToElemEdges.push_back(l+1); }//loop over every element edge }//loop over every other node for the element }//loop over every node for the element }//loop over every element //print elemToElemEdges to check if(verblevel > 3){ Ostr << "Element to element edges:" << std::endl; for(int i=0; i < numElems; i++){ Ostr << i+1 << ":" << std::endl; for(int j=0; j < numEdgesPerElem; j++){ Ostr << elemToElemEdges[i*numEdgesPerElem + j] << " "; } Ostr << std::endl; } } StdOut(Ostr.str()); Ostr.str(""); FunctionExit("ConnectivityMaps"); return 0; } //HigherOrderTets function
cTmpReechEpip::cTmpReechEpip ( bool aConsChan, const std::string & aNameOri, Box2dr aBoxImIn, ElDistortion22_Gen * anEpi, Box2dr aBox, double aStep, const std::string & aNameOut, const std::string & aPostMasq, int aNumKer , bool Debug ) : mBoxImIn(aBoxImIn), mEpi (anEpi), mStep (aStep), mP0 (aBox._p0), mSzEpi (aBox.sz()), mSzRed (round_up (aBox.sz() / aStep) + Pt2di(1,1)), mRedIMasq (mSzRed.x,mSzRed.y,0), mRedTMasq (mRedIMasq), mRedImX (mSzRed.x,mSzRed.y), mRedTImX (mRedImX), mRedImY (mSzRed.x,mSzRed.y), mRedTImY (mRedImY) { cInterpolateurIm2D<REAL4> * aPtrSCI = 0; if (aNumKer==0) { aPtrSCI = new cInterpolBilineaire<REAL4>; } else { cKernelInterpol1D * aKer = 0; if (aNumKer==1) aKer = new cCubicInterpKernel(-0.5); else aKer = new cSinCardApodInterpol1D(cSinCardApodInterpol1D::eTukeyApod,aNumKer,aNumKer/2,1e-4,false); aPtrSCI = new cTabIM2D_FromIm2D<REAL4> (aKer,1000,false); // cTabIM2D_FromIm2D<REAL4> aSSCI (&aKer,1000,false); } cInterpolateurIm2D<REAL4> & aSCI = *aPtrSCI; Pt2di aPInd; for (aPInd.x=0 ; aPInd.x<mSzRed.x ; aPInd.x++) { for (aPInd.y=0 ; aPInd.y<mSzRed.y ; aPInd.y++) { bool Ok= false; Pt2dr aPEpi = ToFullEpiCoord(aPInd); Pt2dr aPIm = anEpi->Inverse(aPEpi); if ((aPIm.x>mBoxImIn._p0.x) && (aPIm.y>mBoxImIn._p0.y) && (aPIm.x<mBoxImIn._p1.x) && (aPIm.y<mBoxImIn._p1.y)) { Pt2dr aPEpi2 = anEpi->Direct(aPIm); if (euclid(aPEpi-aPEpi2) < 1e-2) { Ok= true; mRedTMasq.oset(aPInd,Ok); } } mRedTImX.oset(aPInd,aPIm.x); mRedTImY.oset(aPInd,aPIm.y); } } ELISE_COPY(mRedIMasq.all_pts(),dilat_d8(mRedIMasq.in(0),4),mRedIMasq.out()); Tiff_Im aTifOri = Tiff_Im::StdConvGen(aNameOri.c_str(),aConsChan ? -1 :1 ,true); Tiff_Im aTifEpi = Debug ? Tiff_Im(aNameOut.c_str()) : Tiff_Im ( aNameOut.c_str(), mSzEpi, aTifOri.type_el(), Tiff_Im::No_Compr, aTifOri.phot_interp() ) ; Tiff_Im aTifMasq = aTifEpi; bool ExportMasq = (aPostMasq!="NONE"); // std::cout << "POSTMAS " << aPostMasq << "\n"; if (ExportMasq) { std::string aNameMasq = StdPrefix(aNameOut)+ aPostMasq +".tif"; aTifMasq = Debug ? Tiff_Im(aNameMasq.c_str()) : Tiff_Im ( aNameMasq.c_str(), mSzEpi, GenIm::bits1_msbf, Tiff_Im::No_Compr, Tiff_Im::BlackIsZero ) ; } int aNbBloc=2000; int aBrd = aNumKer+10; Pt2di aSzBrd(aBrd,aBrd); int aX00 = 0; int aY00 = 0; for (int aX0=aX00 ; aX0<mSzEpi.x ; aX0+=aNbBloc) { int aX1 = ElMin(aX0+aNbBloc,mSzEpi.x); for (int aY0=aY00 ; aY0<mSzEpi.y ; aY0+=aNbBloc) { // std::cout << "X0Y0 " << aX0 << " " << aY0 << "\n"; int aY1 = ElMin(aY0+aNbBloc,mSzEpi.y); Pt2di aP0Epi(aX0,aY0); Pt2di aSzBloc(aX1-aX0,aY1-aY0); TIm2D<REAL4,REAL8> aTImX(aSzBloc); TIm2D<REAL4,REAL8> aTImY(aSzBloc); TIm2DBits<1> aTImMasq(aSzBloc,0); Pt2dr aInfIm(1e20,1e20); Pt2dr aSupIm(-1e20,-1e20); bool NonVide= false; for (int anX =aX0 ; anX<aX1 ; anX++) { for (int anY =aY0 ; anY<aY1 ; anY++) { Pt2dr aIndEpi (anX/mStep , anY/mStep); Pt2di aPIndLoc (anX-aX0,anY-aY0); if (mRedTMasq.get(round_down(aIndEpi))) { double aXIm = mRedTImX.getr(aIndEpi,-1,true); double aYIm = mRedTImY.getr(aIndEpi,-1,true); if ((aXIm>0) && (aYIm>0)) { // aTImMasq.oset(aPIndLoc,1); aTImX.oset(aPIndLoc,aXIm); aTImY.oset(aPIndLoc,aYIm); aInfIm = Inf(aInfIm,Pt2dr(aXIm,aYIm)); aSupIm = Sup(aSupIm,Pt2dr(aXIm,aYIm)); NonVide= true; } } } } Pt2di aP0BoxIm = Sup(Pt2di(0,0),Pt2di(round_down(aInfIm) - aSzBrd)); Pt2di aP1BoxIm = Inf(aTifOri.sz(),Pt2di(round_down(aSupIm) + aSzBrd)); Pt2di aSzIm = aP1BoxIm - aP0BoxIm; NonVide = NonVide && (aSzIm.x>0) && (aSzIm.y>0); if (NonVide) { // std::vector<Im2D_REAL4> aVIm; std::vector<Im2D_REAL4> aVIm= aTifOri.VecOfImFloat(aSzIm); ELISE_COPY ( rectangle(Pt2di(0,0),aSzIm), trans(aTifOri.in(),aP0BoxIm), StdOut(aVIm) ); std::vector<Im2D_REAL4> aVImEpi = aTifEpi.VecOfImFloat(aSzBloc); ELISE_ASSERT(aVImEpi.size()==aVIm.size(),"Incohe in nb chan, cTmpReechEpip::cTmpReechEpip"); for (int aKIm=0 ; aKIm <int(aVImEpi.size()) ; aKIm++) { TIm2D<REAL4,REAL8> aImEpi(aVImEpi[aKIm]); REAL4 ** aDataOri = aVIm[aKIm].data(); for (int anX =0 ; anX<aSzBloc.x ; anX++) { for (int anY =0 ; anY<aSzBloc.y ; anY++) { Pt2di aIndEpi(anX,anY); aImEpi.oset(aIndEpi,0); Pt2di anIndEpiGlob = aIndEpi + aP0Epi; Pt2dr aIndEpiRed (anIndEpiGlob.x/mStep , anIndEpiGlob.y/mStep); if (mRedTMasq.get(round_down(aIndEpiRed),0)) { double aXIm = mRedTImX.getr(aIndEpiRed,-1,true); double aYIm = mRedTImY.getr(aIndEpiRed,-1,true); Pt2dr aPImLoc = Pt2dr(aXIm,aYIm) - Pt2dr(aP0BoxIm); double aV= 128; if ((aPImLoc.x>aNumKer+2) && (aPImLoc.y>aNumKer+2) && (aPImLoc.x<aSzIm.x-aNumKer-3) && (aPImLoc.y<aSzIm.y-aNumKer-3)) { aTImMasq.oset(aIndEpi,1); aV = aSCI.GetVal(aDataOri,aPImLoc); // aV= 255; } aImEpi.oset(aIndEpi,aV); } } } } ELISE_COPY ( rectangle(aP0Epi,aP0Epi+aSzBloc), Tronque(aTifEpi.type_el(),trans(StdInput(aVImEpi),-aP0Epi)), aTifEpi.out() ); } if (ExportMasq) { ELISE_COPY ( rectangle(aP0Epi,aP0Epi+aSzBloc), trans(aTImMasq._the_im.in(0),-aP0Epi), aTifMasq.out() ); } // std::cout << "ReechDONE " << aX0 << " "<< aY0 << "\n"; } } }
void ProgramVersion::CLIVersion () { StdOut() << Version() << endl; }
int SerialProgram::Run() { // FunctionEntry("NAME"): Updates the user-defined stack and // the program profiles with timing information. The placement // of FunctionEntry and FunctionExit calls is at the developer's // discretion. FunctionEntry("Run"); // ---------- The Program ----------------- // This program just "copies" the input file // to the output file. // // Open the specified input file for reading Inf.open(input_name.c_str()); if(!Inf){ // If the input file failed to open, notify to // the error stream and return non-zero std::ostringstream Ostr; Ostr << "SerialProgram:Run: Error: Could not output input file, " << input_name << "."; ErrOut(Ostr.str()); // don't forget to tell the profiler/stacker the // function is exiting. FunctionExit("Run"); return(1); } // Open the specified output file for writing bool use_outfile = false; if(!output_name.empty()){ use_outfile = true; Ouf.open(output_name.c_str()); if(!Ouf){ // If the output file failed to open, notify // to error stream and return non-zero std::ostringstream Ostr; Ostr << "SerialProgram:Run: Error: Unable to open output file, " << output_name << "."; ErrOut(Ostr.str()); // don't forget to tell the profiler/stacker the // function is exiting. FunctionExit("Run"); return(1); } } // Read lines from the input file and repeat them // to the output file. std::string line; while(std::getline(Inf,line)){ if(use_outfile) Ouf << line << std::endl; else StdOut(line+"\n"); } // Close both files Ouf.close(); Inf.close(); // // ---------- Program End ----------------- // Update the stacker/profiler that we are exiting // this function. FunctionExit("Run"); // return 0 for success return(0); };
int SerialProgram::WriteOutput(){ std::ostringstream Ostr; std::stringstream ss; // Open the specified output file for writing bool use_outfile = false; if(!output_name.empty()){ use_outfile = true; Ouf.open(output_name.c_str()); if(!Ouf){ // If the output file failed to open, notify // to error stream and return non-zero std::ostringstream ErrOstr; ErrOstr << "Error: Unable to open output file, " << output_name << "."; StdOut(Ostr.str()); Ostr.str(""); ErrOut(ErrOstr.str()); ErrOstr.str(""); // don't forget to tell the profiler/stacker the // function is exiting. FunctionExit("Run"); return(1); } } // Write mesh info to output file or screen ss.clear(); ss.str(""); //Write Patran packet 25 Intro (unused) ss << "unused line" << std::endl; ss << "unused line" << std::endl; //Write Patran packet 26 ss << "26 1 1 1 " << numNodes << " " << numElems << " 1 1 1" << std::endl; ss << "unused line" << std::endl; unsigned int ePos, expPos; std::stringstream numSS; std::string output, exponent; //Write Patran packet 1 node coordinates for(int i=0; i < numNodes; i++){ ss << "1 " << i+1 << std::endl; if(fabs(nodes[3*i+0]) > 1.0e-10 || nodes[3*i+0] == 0.0){ numSS << std::setprecision(9) << std::scientific << nodes[3*i + 0]; ePos = numSS.str().find("e"); expPos = numSS.str().find_last_of("0"); //std::cout << "numSS.str() = " << numSS.str() << std::endl; //std::cout << "expPos = " << expPos << std::endl; //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl; if(expPos == numSS.str().size()-1) exponent = "0"; else exponent = numSS.str().substr(expPos+1,numSS.str().size()); output = numSS.str().substr(0,ePos+2) + exponent; } else{//we have to be careful with numbers that have two digit exponents //in scientific notation because Rocfrac expects all numbers to take a //specific number of columns. if(nodes[3*i+0] < 0.0) numSS << std::setprecision(8) << std::scientific << nodes[3*i + 0]; else numSS << std::setprecision(9) << std::scientific << nodes[3*i + 0]; output = numSS.str(); } ss << std::setw(16) << output; numSS.str(""); numSS.clear(); if(fabs(nodes[3*i+1]) > 1.0e-10 || nodes[3*i+1] == 0.0){ numSS << std::setprecision(9) << std::scientific << nodes[3*i + 1]; ePos = numSS.str().find("e"); expPos = numSS.str().find_last_of("0"); //std::cout << "numSS.str() = " << numSS.str() << std::endl; //std::cout << "expPos = " << expPos << std::endl; //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl; if(expPos == numSS.str().size()-1) exponent = "0"; else exponent = numSS.str().substr(expPos+1,numSS.str().size()); output = numSS.str().substr(0,ePos+2) + exponent; } else{//we have to be careful with numbers that have two digit exponents //in scientific notation because Rocfrac expects all numbers to take a //specific number of columns. if(nodes[3*i+1] < 0.0) numSS << std::setprecision(8) << std::scientific << nodes[3*i + 1]; else numSS << std::setprecision(9) << std::scientific << nodes[3*i + 1]; output = numSS.str(); } ss << std::setw(16) << output; numSS.str(""); numSS.clear(); if(fabs(nodes[3*i+2]) > 1.0e-10 || nodes[3*i+2] == 0.0){ numSS << std::setprecision(9) << std::scientific << nodes[3*i + 2]; ePos = numSS.str().find("e"); expPos = numSS.str().find_last_of("0"); //std::cout << "numSS.str() = " << numSS.str() << std::endl; //std::cout << "expPos = " << expPos << std::endl; //std::cout << "numSS.str().size() = " << numSS.str().size() << std::endl; if(expPos == numSS.str().size()-1) exponent = "0"; else exponent = numSS.str().substr(expPos+1,numSS.str().size()); output = numSS.str().substr(0,ePos+2) + exponent; } else{//we have to be careful with numbers that have two digit exponents //in scientific notation because Rocfrac expects all numbers to take a //specific number of columns. if(nodes[3*i+2] < 0.0) numSS << std::setprecision(8) << std::scientific << nodes[3*i + 2]; else numSS << std::setprecision(9) << std::scientific << nodes[3*i + 2]; output = numSS.str(); } ss << std::setw(16) << output << std::endl; numSS.str(""); numSS.clear(); ss << "unused line" << std::endl; } //Write Patran packet 2 element connectivities for(int i=0; i < numElems; i++){ ss << "2 " << i+1 << " " << elemShape << std::endl << " " << numNodesPerElem << " 0" << " 0" << std::endl; for(int j=0; j < numNodesPerElem; j++){ ss << elems[i*numNodesPerElem + j] << " "; } ss << std::endl; } //Write Patran packet 8 (all nodes with this boundary type) for(int i=0; i < numNodes; i++){ for(int k=0; k < nodeBCs[i].size(); k++){ if(nodeBCs[i][k] == 8){ ss << "8 " << i+1 << " 1 2" << std::endl; ss << " 0"; for(int j=0; j < 3; j++) ss << int(nodeBCValues[i][k][j]); ss << "000" << std::endl; for(int j=3; j < 6; j++){ if(nodeBCValues[i][k][j-3] != 0) ss << " " << nodeBCValues[i][k][j]; } ss << std::endl; } } } //Write Patran packet 6 (all elements with this boundary type) //loop over all the elements //std::cout << "bcs of type 6: " << std::endl; for(int i=0; i < numElems; i++){ //std::cout << "elem " << i+1 << ": " << std::endl; //loop over the domains for that element (we only want //to print one domain's bcs for the element at a time for(int doms=0; doms < elemsToDomains[i].size(); doms++){ int domain=elemsToDomains[i][doms]-1; //std::cout << "domain " << domain+1 << std::endl; //loop over the boundary flags for that domain for(int j=0; j < domainBCs[domain].size(); j++){ int bcCount=0; if(domainBCs[domain][j] == 6){ //std::cout << "bc " << j+1 << ": " << std::endl; ss << "6 " << i+1 << " 1 2 0 0 0 0 0" << std::endl; ss << "111100000"; //loop over the nodes for that element for(int k=0; k < numNodesPerElem; k++){ bool onBC=false; int node = elems[i*numNodesPerElem + k]-1; //std::cout << "node " << k+1 << " (" << node+1 << ")" << std::endl; //loop over the bc flags for that node for(int l=0; l < nodeBCs[node].size(); l++){ if(nodeBCs[node][l] == 6){ //check if the bcs have the same values for(int m=0; m < nodeBCValues[node][l].size(); m++){ if(nodeBCValues[node][l][m] != domainBCValues[domain][j][m]) break; else if(m == nodeBCValues[node][l].size()-1){ onBC=true; bcCount++; //std::cout << "has bc" << std::endl; } } } }//loop over node bcs if(onBC){ //now check that the node is on that domain int domCount; for(domCount=0; domCount < nodesToDomains[node].size(); domCount++){ if(nodesToDomains[node][domCount] == domain+1){ //std::cout << "node on domain (writing it)" << std::endl; ss << "1"; break; } } if(domCount == nodesToDomains[node].size()) ss << "0"; } else ss << "0"; }//loop over nodes for the element //Fill in with 0's at the end if we are using tet elements if(numNodesPerElem == 4) ss << "0000"; ss << std::endl; for(int m=0; m < domainBCValues[domain][j].size(); m++) ss << domainBCValues[domain][j][m] << " "; ss << std::endl; }//if it is bc type 6 }//loop over bc flags for domain }//loop over the domains for the element }//loop over all elements ss << "99 0 0 1"; if(use_outfile){ Ouf << ss.str(); } else StdOut(ss.str()); // Close output file Ouf.close(); StdOut(Ostr.str()); Ostr.str(""); return 0; } //ReadOutput function
int ParallelProgram::Run() { // FunctionEntry("NAME"): Updates the user-defined stack and // the program profiles with timing information. The placement // of FunctionEntry and FunctionExit calls is at the developer's // discretion. FunctionEntry("Run"); int myid = _communicator.Rank(); int nproc = _communicator.Size(); bool use_file = !output_name.empty(); // Put out a quick blurb about number of procs just // to give the user confidence we are actually running // in parallel. Note that when using the "StdOut" method // that it automatically does output only on rank 0. If // the developer wants asyncrhonous output, then they // have to revert to using standard streams. std::ostringstream RepStr; if(verblevel > 1) RepStr << "Running on " << nproc << " processors." << std::endl; StdOut(RepStr.str()); _communicator.Barrier(); if(verblevel > 1) StdOut("All procesors ready.\n"); // Open the specified output file for writing on rank 0 if(use_file && !myid){ Ouf.open(output_name.c_str(),std::ios::app); if(!Ouf){ // If the output file failed to open, notify // to error stream and return non-zero std::ostringstream Ostr; Ostr << "Error: Unable to open output file, " << output_name << "."; ErrOut(Ostr.str()); // In parallel, we don't return right away since // this part of the code is only done on proc 0. // Instead, the error value is set in the communicator // which will indicate to all processors that there // has been some error. _communicator.SetExit(1); } } // Check to see if an error condition was set // in the file open block above. If so, then // return with an error code. if(_communicator.Check()){ // don't forget to tell the profiler/stacker the // function is exiting. FunctionExit("Run"); return(1); } // Correct value of PI to several places double PIVAL = 3.141592653589793238462643383; // All processors should already have this as it // came from the command line - but just in case, // we broadcast it here to make sure. FunctionEntry("Broadcast"); _communicator.BroadCast(ndiv,0); FunctionExit("Broadcast"); // This block partitions the // domain [0,1] with ndiv // intervals among nproc processors int nper = ndiv/nproc; int nvol = nper*nproc; int leftover = ndiv - nvol; int myn = nper; if(myid < leftover) myn++; int mystart = 0; for(int i = 0; i < myid;i++){ mystart += nper; if(i < leftover) mystart++; } // If there are less divisions than processors, then // just forget about domain decomposition and do everything // on processor 0. if(nper == 0){ if(myid == 0) myn = ndiv; else myn = 0; } // Use the results from domain decomposition to // set the domain [a,b] for this processor and get the // stepsize. double h = 1.0/(static_cast<double>(ndiv)); double a = h*mystart; double b = a + h*myn; // Integrate f on this processor's subdomain using trapezoid quadrature FunctionEntry("TrapezoidMethod"); double my_tpi = 0.0; if(myn > 0){ // if there are points in this processor's domain try { FunctionEntry("TrapezoidQuadrature"); my_tpi = GridConversion::TrapezoidQuadrature(f,a,b,myn); FunctionExit("TrapezoidQuadrature"); } catch (...){ StdOut("Numerical limits of GridConversion::TrapezoidQuadrature exceeded."); my_tpi = 0.0; } } double tpi = 0.0; // Sum up the contributions from each processor and store the results on // processor 0 in "tpi". FunctionEntry("Reduce"); // time the communication _communicator.Reduce(my_tpi, tpi,IRAD::Comm::DTDOUBLE, IRAD::Comm::SUMOP, 0); FunctionExit("Reduce"); // end of the communication FunctionExit("TrapezoidMethod"); // Integrate f on this processor's subdomain using midpoint quadrature FunctionEntry("MidPointMethod"); double my_mppi = 0.0; if(myn > 0) { // if there are points in this processor's domain try{ FunctionEntry("MidPointQuadrature"); my_mppi = GridConversion::MidPointQuadrature(f,a,b,myn); FunctionExit("MidPointQuadrature"); } catch (...){ StdOut("Numerical limits of GridConversion::MidPointQuadrature exceeded."); my_mppi = 0.0; } } double mppi = 0.0; // Sum up the contributions from each processor and store the results on // processor 0 in "mppi". FunctionEntry("Reduce"); // time the communication _communicator.Reduce(my_mppi, mppi,IRAD::Comm::DTDOUBLE, IRAD::Comm::SUMOP, 0); FunctionExit("Reduce"); // end of the communication FunctionExit("MidPointMethod"); // Report the results to stdout or to file if one was specified. FunctionEntry("IO"); if (!myid) { if(use_file){ Ouf << ndiv << " " << std::setprecision(16) << tpi << " " << std::setprecision(4) << std::fabs(tpi-PIVAL) << " " << std::setprecision(16) << mppi << " " << std::setprecision(4) << std::fabs(mppi-PIVAL) << " " << std::endl; Ouf.close(); } else if(verblevel) { std::ostringstream Ostr; Ostr << "With " << ndiv << " divisions, PI was calculated:" << std::endl << "MidPointQuadrature: " << std::setprecision(16) << mppi << "\t\t" << std::setprecision(4) << std::fabs(mppi - PIVAL) << std::endl << "TrapezoidQuadrature: " << std::setprecision(16) << tpi << "\t\t" << std::setprecision(4) << std::fabs(tpi - PIVAL) << std::endl; StdOut(Ostr.str()); } } FunctionExit("IO"); // // ---------- Program End ---------------- // Update the stacker/profiler that we are exiting // this function. FunctionExit("Run"); // return 0 for success return(0); };