int main(int argc, char ** argv) { // Initialize MPI MPI_Init(&argc, &argv); try { // Input filename std::string strInputFile; // Output filename std::string strOutputFile; // List of variables to extract std::string strVariables; // Extract geopotential height bool fGeopotentialHeight; // Pressure levels to extract std::string strPressureLevels; // Height levels to extract std::string strHeightLevels; // Extract variables at the surface bool fExtractSurface; // Extract total energy bool fExtractTotalEnergy; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); CommandLineString(strVariables, "var", ""); CommandLineBool(fGeopotentialHeight, "output_z"); CommandLineBool(fExtractTotalEnergy, "output_energy"); CommandLineString(strPressureLevels, "p", ""); CommandLineString(strHeightLevels, "z", ""); CommandLineBool(fExtractSurface, "surf"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); AnnounceEndBlock("Done"); } catch(Exception & e) { Announce(e.ToString().c_str()); } // Finalize MPI MPI_Finalize(); }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Resolution int nResolution; // Dual mesh bool fDual; // Output filename std::string strOutputFile; // Parse the command line BeginCommandLine() CommandLineInt(nResolution, "res", 10); CommandLineBool(fDual, "dual"); CommandLineString(strOutputFile, "file", "outICOMesh.g"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Generate Mesh AnnounceBanner(); AnnounceStartBlock("Generating Mesh"); Mesh mesh; GenerateIcosahedralQuadGrid(nResolution, mesh.nodes, mesh.faces); AnnounceEndBlock("Done"); // Generate the dual grid if (fDual) { Dual(mesh); } // Output the mesh AnnounceStartBlock("Writing Mesh to file"); Announce("Mesh size: Nodes [%i] Elements [%i]", mesh.nodes.size(), mesh.faces.size()); mesh.Write(strOutputFile); AnnounceEndBlock("Done"); } catch(Exception & e) { std::cout << e.ToString() << std::endl; } }
int main(int argc, char** argv) { // Input mesh std::string strMesh; // Polynomial order int nP; // Use of bubble to adjust areas bool fBubble; // Output metadata file std::string strOutput; // Parse the command line BeginCommandLine() CommandLineString(strMesh, "mesh", ""); CommandLineInt(nP, "np", 4); CommandLineString(strOutput, "out", "gllmeta.nc"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Calculate metadata DataArray3D<int> dataGLLnodes; DataArray3D<double> dataGLLJacobian; Mesh mesh; int err = GenerateGLLMetaData( strMesh, mesh, nP, fBubble, strOutput, dataGLLnodes, dataGLLJacobian); if (err) exit(err); // Done AnnounceBanner(); return 0; }
int main(int argc, char ** argv){ NcError error(NcError::verbose_nonfatal); try{ std::string inFile; std::string outFile; std::string varName; std::string inList; // bool calcStdDev; BeginCommandLine() CommandLineString(inFile, "in", ""); CommandLineString(inList, "inlist",""); CommandLineString(varName, "var", ""); CommandLineString(outFile, "out", ""); // CommandLineBool(calcStdDev, "std"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); if ((inFile != "") && (inList != "")){ _EXCEPTIONT("Can only open one file (--in) or list (--inlist)."); } //file list vector std::vector<std::string> vecFiles; if (inFile != ""){ vecFiles.push_back(inFile); } if (inList != ""){ GetInputFileList(inList,vecFiles); } //open up first file NcFile readin(vecFiles[0].c_str()); if (!readin.is_valid()){ _EXCEPTION1("Unable to open file %s for reading",\ vecFiles[0].c_str()); } int tLen,latLen,lonLen; NcDim * time = readin.get_dim("time"); tLen = time->size(); NcVar * timeVar = readin.get_var("time"); NcDim * lat = readin.get_dim("lat"); latLen = lat->size(); NcVar * latVar = readin.get_var("lat"); NcDim * lon = readin.get_dim("lon"); lonLen = lon->size(); NcVar * lonVar = readin.get_var("lon"); //read input variable NcVar * inVar = readin.get_var(varName.c_str()); //Create output matrix DataMatrix<double> outMat(latLen,lonLen); densCalc(inVar,outMat); //Option for calculating the yearly standard deviation /* if (calcStdDev){ for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ storeMat[0][a][b] = outMat[a][b]; } } } */ //If multiple files, add these values to the output if (vecFiles.size()>1){ DataMatrix<double> addMat(latLen,lonLen); std::cout<<"There are "<<vecFiles.size()<<" files."<<std::endl; for (int v=1; v<vecFiles.size(); v++){ NcFile addread(vecFiles[v].c_str()); NcVar * inVar = addread.get_var(varName.c_str()); densCalc(inVar,addMat); for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ outMat[a][b]+=addMat[a][b]; } } /* if (calcStdDev){ for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ storeMat[v][a][b] = addMat[a][b]; } } }*/ addread.close(); } //Divide output by number of files double div = 1./((double) vecFiles.size()); for (int a=0; a<latLen; a++){ for (int b=0; b<lonLen; b++){ outMat[a][b]*=div; } } } NcFile readout(outFile.c_str(),NcFile::Replace, NULL,0,NcFile::Offset64Bits); NcDim * outLat = readout.add_dim("lat", latLen); NcDim * outLon = readout.add_dim("lon", lonLen); NcVar * outLatVar = readout.add_var("lat",ncDouble,outLat); NcVar * outLonVar = readout.add_var("lon",ncDouble,outLon); std::cout<<"Copying dimension attributes."<<std::endl; copy_dim_var(latVar,outLatVar); copy_dim_var(lonVar,outLonVar); std::cout<<"Creating density variable."<<std::endl; NcVar * densVar = readout.add_var("dens",ncDouble,outLat,outLon); densVar->set_cur(0,0); densVar->put((&outMat[0][0]),latLen,lonLen); /* if (calcStdDev){ NcVar * stdDevVar = readout.add_var("stddev", ncDouble,outLat,outLon); DataMatrix<double> stdDevMat(latLen,lonLen); yearlyStdDev(storeMat,vecFiles.size(),latLen,lonLen,stdDevMat); stdDevVar->set_cur(0,0); stdDevVar->put(&(stdDevMat[0][0]),latLen,lonLen); std::cout<<" created sd variable"<<std::endl; } */ readout.close(); readin.close(); } catch (Exception &e){ std::cout<<e.ToString()<<std::endl; } }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output mesh filename std::string strOutputMesh; // Output connectivity filename std::string strOutputConnectivity; // Number of elements in mesh int nP; // Use uniformly spaced sub-volumes bool fUniformSpacing = false; // Do not merge faces bool fNoMergeFaces = false; // Nodes appear at GLL nodes bool fCGLL = true; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputMesh, "out", ""); CommandLineString(strOutputConnectivity, "out_connect", ""); CommandLineInt(nP, "np", 2); CommandLineBool(fUniformSpacing, "uniform"); //CommandLineBool(fNoMergeFaces, "no-merge-face"); //CommandLineBool(fCGLL, "cgll"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check file names if (strInputFile == "") { _EXCEPTIONT("No input file specified"); } if (nP < 2) { _EXCEPTIONT("--np must be >= 2"); } if ((fNoMergeFaces) && (strOutputConnectivity != "")) { _EXCEPTIONT("--out_connect and --no-merge-face not implemented"); } // Load input mesh std::cout << std::endl; std::cout << "..Loading input mesh" << std::endl; Mesh meshIn(strInputFile); meshIn.RemoveZeroEdges(); // Number of elements int nElements = meshIn.faces.size(); // Gauss-Lobatto quadrature nodes and weights std::cout << "..Computing sub-volume boundaries" << std::endl; DataArray1D<double> dG(nP); DataArray1D<double> dW(nP); // Uniformly spaced nodes if (fUniformSpacing) { for (int i = 0; i < nP; i++) { dG[i] = (2.0 * static_cast<double>(i) + 1.0) / (2.0 * nP); dW[i] = 1.0 / nP; } dG[0] = 0.0; dG[1] = 1.0; // Get Gauss-Lobatto Weights } else { GaussLobattoQuadrature::GetPoints(nP, 0.0, 1.0, dG, dW); } // Accumulated weight vector DataArray1D<double> dAccumW(nP+1); dAccumW[0] = 0.0; for (int i = 1; i < nP+1; i++) { dAccumW[i] = dAccumW[i-1] + dW[i-1]; } if (fabs(dAccumW[dAccumW.GetRows()-1] - 1.0) > 1.0e-14) { _EXCEPTIONT("Logic error in accumulated weight"); } // Data structures used for generating connectivity DataArray3D<int> dataGLLnodes(nP, nP, nElements); std::vector<Node> vecNodes; std::map<Node, int> mapFaces; // Data structure for // Data structure used for avoiding coincident nodes on the fly std::map<Node, int> mapNewNodes; // Generate new mesh std::cout << "..Generating sub-volumes" << std::endl; Mesh meshOut; for (size_t f = 0; f < nElements; f++) { const Face & face = meshIn.faces[f]; if (face.edges.size() != 4) { _EXCEPTIONT("Input mesh must only contain quadrilaterals"); } const Node & node0 = meshIn.nodes[face[0]]; const Node & node1 = meshIn.nodes[face[1]]; const Node & node2 = meshIn.nodes[face[2]]; const Node & node3 = meshIn.nodes[face[3]]; for (int q = 0; q < nP; q++) { for (int p = 0; p < nP; p++) { bool fNewFace = true; // Build unique node array if CGLL if (fCGLL) { // Get local nodal location Node nodeGLL; Node dDx1G; Node dDx2G; ApplyLocalMap( face, meshIn.nodes, dG[p], dG[q], nodeGLL, dDx1G, dDx2G); // Determine if this is a unique Node std::map<Node, int>::const_iterator iter = mapFaces.find(nodeGLL); if (iter == mapFaces.end()) { // Insert new unique node into map int ixNode = static_cast<int>(mapFaces.size()); mapFaces.insert(std::pair<Node, int>(nodeGLL, ixNode)); dataGLLnodes[q][p][f] = ixNode + 1; vecNodes.push_back(nodeGLL); } else { dataGLLnodes[q][p][f] = iter->second + 1; fNewFace = false; } // Non-unique node array if DGLL } else { dataGLLnodes[q][p][f] = nP * nP * f + q * nP + p; } // Get volumetric region Face faceNew(4); for (int i = 0; i < 4; i++) { int px = p+((i+1)/2)%2; // p,p+1,p+1,p int qx = q+(i/2); // q,q,q+1,q+1 Node nodeOut = InterpolateQuadrilateralNode( node0, node1, node2, node3, dAccumW[px], dAccumW[qx]); std::map<Node, int>::const_iterator iterNode = mapNewNodes.find(nodeOut); if (iterNode == mapNewNodes.end()) { mapNewNodes.insert( std::pair<Node, int>(nodeOut, meshOut.nodes.size())); faceNew.SetNode(i, meshOut.nodes.size()); meshOut.nodes.push_back(nodeOut); } else { faceNew.SetNode(i, iterNode->second); } } // Insert new Face or merge with existing Face meshOut.faces.push_back(faceNew); /* if ((fNoMergeFaces) || (fNewFace)) { } else { std::cout << dataGLLnodes[q][p][f]-1 << " " << mapFaces.size()-1 << std::endl; meshOut.faces[dataGLLnodes[q][p][f]-1].Merge(faceNew); } */ } } } meshOut.RemoveCoincidentNodes(); // Build connectivity and write to file if (strOutputConnectivity != "") { std::cout << "..Constructing connectivity file" << std::endl; std::vector< std::set<int> > vecConnectivity; vecConnectivity.resize(mapFaces.size()); for (size_t f = 0; f < nElements; f++) { for (int q = 0; q < nP; q++) { for (int p = 0; p < nP; p++) { std::set<int> & setLocalConnectivity = vecConnectivity[dataGLLnodes[q][p][f]-1]; // Connect in all directions if (p != 0) { setLocalConnectivity.insert( dataGLLnodes[q][p-1][f]); } if (p != (nP-1)) { setLocalConnectivity.insert( dataGLLnodes[q][p+1][f]); } if (q != 0) { setLocalConnectivity.insert( dataGLLnodes[q-1][p][f]); } if (q != (nP-1)) { setLocalConnectivity.insert( dataGLLnodes[q+1][p][f]); } } } } // Open output file FILE * fp = fopen(strOutputConnectivity.c_str(), "w"); fprintf(fp, "%lu\n", vecConnectivity.size()); for (size_t f = 0; f < vecConnectivity.size(); f++) { const Node & node = vecNodes[f]; double dLon = atan2(node.y, node.x); double dLat = asin(node.z); if (dLon < 0.0) { dLon += 2.0 * M_PI; } fprintf(fp, "%1.14f,", dLon / M_PI * 180.0); fprintf(fp, "%1.14f,", dLat / M_PI * 180.0); fprintf(fp, "%lu", vecConnectivity[f].size()); std::set<int>::const_iterator iter = vecConnectivity[f].begin(); for (; iter != vecConnectivity[f].end(); iter++) { fprintf(fp, ",%i", *iter); } if (f != vecConnectivity.size()-1) { fprintf(fp,"\n"); } } fclose(fp); } // Remove coincident nodes //std::cout << "..Removing coincident nodes" << std::endl; //meshOut.RemoveCoincidentNodes(); // Write the mesh if (strOutputMesh != "") { std::cout << "..Writing mesh" << std::endl; meshOut.Write(strOutputMesh); } // Announce std::cout << "..Mesh generator exited successfully" << std::endl; std::cout << "========================================================="; std::cout << std::endl; return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int main(int argc, char ** argv) { MPI_Init(&argc, &argv); try { // Number of latitudes int nLat; // Number of longitudes int nLon; // Zonal wavenumber int nK; // Meridional power int nLpow; // Output file std::string strOutputFile; // Parse the command line BeginCommandLine() CommandLineInt(nLat, "lat", 40); CommandLineInt(nLon, "lon", 80); CommandLineString(strOutputFile, "out", "topo.nc"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Generate longitude and latitude arrays AnnounceBanner(); AnnounceStartBlock("Generating longitude and latitude arrays"); DataVector<double> dLon; dLon.Initialize(nLon); Parameters param; param.GenerateLatituteArray(nLat); std::vector<double> & dLat = param.vecNode; double dDeltaLon = 2.0 * M_PI / static_cast<double>(nLon); for (int i = 0; i < nLon; i++) { dLon[i] = (static_cast<double>(i) + 0.5) * dDeltaLon; } AnnounceEndBlock("Done"); // Open NetCDF output file AnnounceStartBlock("Writing to file"); NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); // Output coordinates NcDim * dimLat = ncdf_out.add_dim("lat", nLat); NcDim * dimLon = ncdf_out.add_dim("lon", nLon); NcVar * varLat = ncdf_out.add_var("lat", ncDouble, dimLat); varLat->set_cur((long)0); varLat->put(&(param.vecNode[0]), nLat); NcVar * varLon = ncdf_out.add_var("lon", ncDouble, dimLon); varLon->set_cur((long)0); varLon->put(&(dLon[0]), nLon); // Generate topography DataMatrix<double> dTopo; dTopo.Initialize(nLat, nLon); double dK = static_cast<double>(nK); double dLpow = static_cast<double>(nLpow); double dA = 6.37122e6; double dX = 500.0; double dLatM = 0.0; double dLonM = M_PI / 4.0; double dD = 5000.0; double dH0 = 1.0; double dXiM = 4000.0; for (int j = 0; j < nLat; j++) { for (int i = 0; i < nLon; i++) { // Great circle distance double dR = dA / dX * acos(sin(dLatM) * sin(dLat[j]) + cos(dLatM) * cos(dLat[j]) * cos(dLon[i] - dLonM)); double dCosXi = 1.0; //cos(M_PI * dR / dXiM); dTopo[j][i] = dH0 * exp(- dR * dR / (dD * dD)) * dCosXi * dCosXi; } } // Write topography NcVar * varZs = ncdf_out.add_var("Zs", ncDouble, dimLat, dimLon); varZs->set_cur(0, 0); varZs->put(&(dTopo[0][0]), nLat, nLon); AnnounceEndBlock("Done"); Announce("Completed successfully!"); AnnounceBanner(); } catch(Exception & e) { Announce(e.ToString().c_str()); } MPI_Finalize(); }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input data file std::string strInputData; // Input map file std::string strInputMap; // List of variables std::string strVariables; // Input data file (second instance) std::string strInputData2; // Input map file (second instance) std::string strInputMap2; // List of variables (second instance) std::string strVariables2; // Output data file std::string strOutputData; // Name of the ncol variable std::string strNColName; // Output as double bool fOutputDouble; // List of variables to preserve std::string strPreserveVariables; // Preserve all non-remapped variables bool fPreserveAll; // Fill value override double dFillValueOverride; // Parse the command line BeginCommandLine() CommandLineString(strInputData, "in_data", ""); CommandLineString(strInputMap, "map", ""); CommandLineString(strVariables, "var", ""); CommandLineString(strInputData2, "in_data2", ""); CommandLineString(strInputMap2, "map2", ""); CommandLineString(strVariables2, "var2", ""); CommandLineString(strOutputData, "out_data", ""); CommandLineString(strNColName, "ncol_name", "ncol"); CommandLineBool(fOutputDouble, "out_double"); CommandLineString(strPreserveVariables, "preserve", ""); CommandLineBool(fPreserveAll, "preserveall"); CommandLineDouble(dFillValueOverride, "fillvalue", 0.0); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check parameters if (strInputMap == "") { _EXCEPTIONT("No map specified"); } if (strInputData == "") { _EXCEPTIONT("No input data specified"); } if (strOutputData == "") { _EXCEPTIONT("No output data specified"); } // Parse variable list std::vector< std::string > vecVariableStrings; ParseVariableList(strVariables, vecVariableStrings); // Parse preserve variable list std::vector< std::string > vecPreserveVariableStrings; ParseVariableList(strPreserveVariables, vecPreserveVariableStrings); if (fPreserveAll && (vecPreserveVariableStrings.size() != 0)) { _EXCEPTIONT("--preserveall and --preserve cannot both be specified"); } // Second input data file std::vector< std::string > vecVariableStrings2; if (strInputData2 != "") { ParseVariableList(strVariables2, vecVariableStrings2); if (vecVariableStrings2.size() == 0) { _EXCEPTIONT("No variables specified for --in_data2"); } if (strInputMap2 == "") { _EXCEPTIONT("No map specified for --in_data2"); } } if ((strInputMap2 != "") && (strInputData2 == "")) { _EXCEPTIONT("No input data specified for --map2"); } // Apply OfflineMap to data if (strInputMap2 == "") { AnnounceStartBlock("Applying offline map to data"); } else { AnnounceStartBlock("Applying first offline map to data"); } // OfflineMap OfflineMap mapRemap; mapRemap.Read(strInputMap); mapRemap.SetFillValueOverride(static_cast<float>(dFillValueOverride)); mapRemap.Apply( strInputData, strOutputData, vecVariableStrings, strNColName, fOutputDouble, false); AnnounceEndBlock(NULL); if (strInputMap2 != "") { AnnounceStartBlock("Applying second offline map to data"); // OfflineMap OfflineMap mapRemap2; mapRemap2.Read(strInputMap2); // Verify consistency of maps SparseMatrix<double> & smatRemap = mapRemap .GetSparseMatrix(); SparseMatrix<double> & smatRemap2 = mapRemap2.GetSparseMatrix(); if ((smatRemap.GetRows() != smatRemap2.GetRows()) || (smatRemap.GetColumns() != smatRemap2.GetColumns()) ) { _EXCEPTIONT("Mismatch in dimensions of input maps " "--map and --map2"); } mapRemap2.Apply( strInputData2, strOutputData, vecVariableStrings2, strNColName, false, true); AnnounceEndBlock(NULL); } // Copy variables from input file to output file if (fPreserveAll) { AnnounceStartBlock("Preserving variables"); mapRemap.PreserveAllVariables(strInputData, strOutputData); AnnounceEndBlock(NULL); } else if (vecPreserveVariableStrings.size() != 0) { AnnounceStartBlock("Preserving variables"); mapRemap.PreserveVariables( strInputData, strOutputData, vecPreserveVariableStrings); AnnounceEndBlock(NULL); } AnnounceBanner(); return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int main(int argc, char ** argv) { MPI_Init(&argc, &argv); NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output filename std::string strOutputFile; // Separate topography file std::string strTopographyFile; // List of variables to extract std::string strVariables; // Extract geopotential height bool fGeopotentialHeight; // Pressure levels to extract std::string strPressureLevels; // Height levels to extract std::string strHeightLevels; // Extract variables at the surface bool fExtractSurface; // Extract total energy bool fExtractTotalEnergy; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); CommandLineString(strVariables, "var", ""); CommandLineBool(fGeopotentialHeight, "output_z"); CommandLineBool(fExtractTotalEnergy, "output_energy"); CommandLineString(strPressureLevels, "p", ""); CommandLineString(strHeightLevels, "z", ""); CommandLineBool(fExtractSurface, "surf"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check command line arguments if (strInputFile == "") { _EXCEPTIONT("No input file specified"); } if (strOutputFile == "") { _EXCEPTIONT("No output file specified"); } if (strVariables == "") { _EXCEPTIONT("No variables specified"); } // Parse variable string std::vector< std::string > vecVariableStrings; ParseVariableList(strVariables, vecVariableStrings); // Check variables if (vecVariableStrings.size() == 0) { _EXCEPTIONT("No variables specified"); } // Parse pressure level string std::vector<double> vecPressureLevels; ParseLevelArray(strPressureLevels, vecPressureLevels); int nPressureLevels = (int)(vecPressureLevels.size()); for (int k = 0; k < nPressureLevels; k++) { if (vecPressureLevels[k] <= 0.0) { _EXCEPTIONT("Non-positive pressure values not allowed"); } } // Parse height level string std::vector<double> vecHeightLevels; ParseLevelArray(strHeightLevels, vecHeightLevels); int nHeightLevels = (int)(vecHeightLevels.size()); // Check pressure levels if ((nPressureLevels == 0) && (nHeightLevels == 0) && (!fExtractSurface) ) { _EXCEPTIONT("No pressure / height levels to process"); } // Open input file AnnounceStartBlock("Loading input file"); NcFile ncdf_in(strInputFile.c_str(), NcFile::ReadOnly); if (!ncdf_in.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for reading", strInputFile.c_str()); } // Load time array Announce("Time"); NcVar * varTime = ncdf_in.get_var("time"); if (varTime == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"time\"", strInputFile.c_str()); } int nTime = varTime->get_dim(0)->size(); DataArray1D<double> dTime(nTime); varTime->set_cur((long)0); varTime->get(&(dTime[0]), nTime); // Load latitude array Announce("Latitude"); NcVar * varLat = ncdf_in.get_var("lat"); if (varLat == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lat\"", strInputFile.c_str()); } int nLat = varLat->get_dim(0)->size(); DataArray1D<double> dLat(nLat); varLat->set_cur((long)0); varLat->get(&(dLat[0]), nLat); // Load longitude array Announce("Longitude"); NcVar * varLon = ncdf_in.get_var("lon"); if (varLon == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lon\"", strInputFile.c_str()); } int nLon = varLon->get_dim(0)->size(); DataArray1D<double> dLon(nLon); varLon->set_cur((long)0); varLon->get(&(dLon[0]), nLon); // Load level array Announce("Level"); NcVar * varLev = ncdf_in.get_var("lev"); if (varLev == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"lev\"", strInputFile.c_str()); } int nLev = varLev->get_dim(0)->size(); DataArray1D<double> dLev(nLev); varLev->set_cur((long)0); varLev->get(&(dLev[0]), nLev); // Load level interface array Announce("Interface"); NcVar * varILev = ncdf_in.get_var("ilev"); int nILev = 0; DataArray1D<double> dILev; if (varILev == NULL) { Announce("Warning: Variable \"ilev\" not found"); } else { nILev = varILev->get_dim(0)->size(); if (nILev != nLev + 1) { _EXCEPTIONT("Variable \"ilev\" must have size lev+1"); } dILev.Allocate(nILev); varILev->set_cur((long)0); varILev->get(&(dILev[0]), nILev); } // Load topography Announce("Topography"); NcVar * varZs = ncdf_in.get_var("Zs"); if (varZs == NULL) { _EXCEPTION1("File \"%s\" does not contain variable \"Zs\"", strInputFile.c_str()); } DataArray2D<double> dZs(nLat, nLon); varZs->set_cur((long)0, (long)0); varZs->get(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Open output file AnnounceStartBlock("Constructing output file"); NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); if (!ncdf_out.is_valid()) { _EXCEPTION1("Unable to open file \"%s\" for writing", strOutputFile.c_str()); } CopyNcFileAttributes(&ncdf_in, &ncdf_out); // Output time array Announce("Time"); NcDim * dimOutTime = ncdf_out.add_dim("time"); NcVar * varOutTime = ncdf_out.add_var("time", ncDouble, dimOutTime); varOutTime->set_cur((long)0); varOutTime->put(&(dTime[0]), nTime); CopyNcVarAttributes(varTime, varOutTime); // Output pressure array NcDim * dimOutP = NULL; NcVar * varOutP = NULL; if (nPressureLevels > 0) { Announce("Pressure"); dimOutP = ncdf_out.add_dim("p", nPressureLevels); varOutP = ncdf_out.add_var("p", ncDouble, dimOutP); varOutP->set_cur((long)0); varOutP->put(&(vecPressureLevels[0]), nPressureLevels); } // Output height array NcDim * dimOutZ = NULL; NcVar * varOutZ = NULL; if (nHeightLevels > 0) { Announce("Height"); dimOutZ = ncdf_out.add_dim("z", nHeightLevels); varOutZ = ncdf_out.add_var("z", ncDouble, dimOutZ); varOutZ->set_cur((long)0); varOutZ->put(&(vecHeightLevels[0]), nHeightLevels); } // Output latitude and longitude array Announce("Latitude"); NcDim * dimOutLat = ncdf_out.add_dim("lat", nLat); NcVar * varOutLat = ncdf_out.add_var("lat", ncDouble, dimOutLat); varOutLat->set_cur((long)0); varOutLat->put(&(dLat[0]), nLat); CopyNcVarAttributes(varLat, varOutLat); Announce("Longitude"); NcDim * dimOutLon = ncdf_out.add_dim("lon", nLon); NcVar * varOutLon = ncdf_out.add_var("lon", ncDouble, dimOutLon); varOutLon->set_cur((long)0); varOutLon->put(&(dLon[0]), nLon); CopyNcVarAttributes(varLon, varOutLon); // Output topography Announce("Topography"); NcVar * varOutZs = ncdf_out.add_var( "Zs", ncDouble, dimOutLat, dimOutLon); varOutZs->set_cur((long)0, (long)0); varOutZs->put(&(dZs[0][0]), nLat, nLon); AnnounceEndBlock("Done"); // Done AnnounceEndBlock("Done"); // Load all variables Announce("Loading variables"); std::vector<NcVar *> vecNcVar; for (int v = 0; v < vecVariableStrings.size(); v++) { vecNcVar.push_back(ncdf_in.get_var(vecVariableStrings[v].c_str())); if (vecNcVar[v] == NULL) { _EXCEPTION1("Unable to load variable \"%s\" from file", vecVariableStrings[v].c_str()); } } // Physical constants Announce("Initializing thermodynamic variables"); NcAtt * attEarthRadius = ncdf_in.get_att("earth_radius"); double dEarthRadius = attEarthRadius->as_double(0); NcAtt * attRd = ncdf_in.get_att("Rd"); double dRd = attRd->as_double(0); NcAtt * attCp = ncdf_in.get_att("Cp"); double dCp = attCp->as_double(0); double dGamma = dCp / (dCp - dRd); NcAtt * attP0 = ncdf_in.get_att("P0"); double dP0 = attP0->as_double(0); double dPressureScaling = dP0 * std::pow(dRd / dP0, dGamma); NcAtt * attZtop = ncdf_in.get_att("Ztop"); double dZtop = attZtop->as_double(0); // Input data DataArray3D<double> dataIn(nLev, nLat, nLon); DataArray3D<double> dataInt(nILev, nLat, nLon); // Output data DataArray2D<double> dataOut(nLat, nLon); // Pressure in column DataArray1D<double> dataColumnP(nLev); // Height in column DataArray1D<double> dataColumnZ(nLev); DataArray1D<double> dataColumnIZ(nILev); // Column weights DataArray1D<double> dW(nLev); DataArray1D<double> dIW(nILev); // Loop through all times, pressure levels and variables AnnounceStartBlock("Interpolating"); // Add energy variable NcVar * varEnergy; if (fExtractTotalEnergy) { varEnergy = ncdf_out.add_var("TE", ncDouble, dimOutTime); } // Create output pressure variables std::vector<NcVar *> vecOutNcVarP; if (nPressureLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { vecOutNcVarP.push_back( ncdf_out.add_var( vecVariableStrings[v].c_str(), ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarP[v]); } } // Create output height variables std::vector<NcVar *> vecOutNcVarZ; if (nHeightLevels > 0) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; if (nPressureLevels > 0) { strVarName += "z"; } vecOutNcVarZ.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutZ, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarZ[v]); } } // Create output surface variable std::vector<NcVar *> vecOutNcVarS; if (fExtractSurface) { for (int v = 0; v < vecVariableStrings.size(); v++) { std::string strVarName = vecVariableStrings[v]; strVarName += "S"; vecOutNcVarS.push_back( ncdf_out.add_var( strVarName.c_str(), ncDouble, dimOutTime, dimOutLat, dimOutLon)); // Copy attributes CopyNcVarAttributes(vecNcVar[v], vecOutNcVarS[v]); } } // Loop over all times for (int t = 0; t < nTime; t++) { char szAnnounce[256]; sprintf(szAnnounce, "Time %i", t); AnnounceStartBlock(szAnnounce); // Rho DataArray3D<double> dataRho(nLev, nLat, nLon); NcVar * varRho = ncdf_in.get_var("Rho"); if (varRho == NULL) { _EXCEPTIONT("Unable to load variable \"Rho\" from file"); } varRho->set_cur(t, 0, 0, 0); varRho->get(&(dataRho[0][0][0]), 1, nLev, nLat, nLon); // Pressure DataArray3D<double> dataP(nLev, nLat, nLon); if (nPressureLevels != 0) { NcVar * varP = ncdf_in.get_var("P"); if (varP == NULL) { _EXCEPTIONT("Unable to load variable \"P\" from file"); } varP->set_cur(t, 0, 0, 0); varP->get(&(dataP[0][0][0]), 1, nLev, nLat, nLon); } /* // Populate pressure array if (nPressureLevels > 0) { // Calculate pointwise pressure for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataP[k][i][j] = dPressureScaling * exp(log(dataRho[k][i][j] * dataP[k][i][j]) * dGamma); } } } } */ // Height everywhere DataArray3D<double> dataZ(nLev, nLat, nLon); DataArray3D<double> dataIZ; if (nILev != 0) { dataIZ.Allocate(nILev, nLat, nLon); } // Populate height array if ((nHeightLevels > 0) || (fGeopotentialHeight)) { for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataZ[k][i][j] = dZs[i][j] + dLev[k] * (dZtop - dZs[i][j]); } } } for (int k = 0; k < nILev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataIZ[k][i][j] = dZs[i][j] + dILev[k] * (dZtop - dZs[i][j]); } } } } // Loop through all pressure levels and variables for (int v = 0; v < vecNcVar.size(); v++) { bool fOnInterfaces = false; // Load in the data array vecNcVar[v]->set_cur(t, 0, 0, 0); if (vecNcVar[v]->get_dim(1)->size() == nLev) { vecNcVar[v]->get(&(dataIn[0][0][0]), 1, nLev, nLat, nLon); Announce("%s (n)", vecVariableStrings[v].c_str()); } else if (vecNcVar[v]->get_dim(1)->size() == nILev) { vecNcVar[v]->get(&(dataInt[0][0][0]), 1, nILev, nLat, nLon); fOnInterfaces = true; Announce("%s (i)", vecVariableStrings[v].c_str()); } else { _EXCEPTION1("Variable \"%s\" has invalid level dimension", vecVariableStrings[v].c_str()); } // At the physical surface if (fExtractSurface) { if (fOnInterfaces) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { dataOut[i][j] = dataInt[0][i][j]; } } } else { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } } // Write variable vecOutNcVarS[v]->set_cur(t, 0, 0); vecOutNcVarS[v]->put(&(dataOut[0][0]), 1, nLat, nLon); } // Loop through all pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Store column pressure for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } // Find weights int kBegin = 0; int kEnd = 0; // On a pressure surface InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } } } // Write variable vecOutNcVarP[v]->set_cur(t, p, 0, 0); vecOutNcVarP[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Loop through all height levels for (int z = 0; z < nHeightLevels; z++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Find weights int kBegin = 0; int kEnd = 0; // Interpolate from levels to z surfaces if (!fOnInterfaces) { for (int k = 0; k < nLev; k++) { dataColumnZ[k] = dataZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnZ, kBegin, kEnd, dW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataIn[k][i][j]; } // Interpolate from interfaces to z surfaces } else { for (int k = 0; k < nILev; k++) { dataColumnIZ[k] = dataIZ[k][i][j]; } InterpolationWeightsLinear( vecHeightLevels[z], dataColumnIZ, kBegin, kEnd, dIW); dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dIW[k] * dataInt[k][i][j]; } } } } // Write variable vecOutNcVarZ[v]->set_cur(t, z, 0, 0); vecOutNcVarZ[v]->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } } // Output geopotential height if (fGeopotentialHeight) { Announce("Geopotential height"); // Output variables NcVar * varOutZ; NcVar * varOutZs; if (nPressureLevels > 0) { varOutZ = ncdf_out.add_var( "PHIZ", ncDouble, dimOutTime, dimOutP, dimOutLat, dimOutLon); } if (fExtractSurface) { varOutZs = ncdf_out.add_var( "PHIZS", ncDouble, dimOutTime, dimOutLat, dimOutLon); } // Interpolate onto pressure levels for (int p = 0; p < nPressureLevels; p++) { // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { int kBegin = 0; int kEnd = 0; for (int k = 0; k < nLev; k++) { dataColumnP[k] = dataP[k][i][j]; } InterpolationWeightsLinear( vecPressureLevels[p], dataColumnP, kBegin, kEnd, dW); // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZ->set_cur(t, p, 0, 0); varOutZ->put(&(dataOut[0][0]), 1, 1, nLat, nLon); } // Interpolate onto the physical surface if (fExtractSurface) { int kBegin = 0; int kEnd = 3; PolynomialInterp::LagrangianPolynomialCoeffs( 3, dLev, dW, 0.0); // Loop thorugh all latlon indices for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { // Interpolate in the vertical dataOut[i][j] = 0.0; for (int k = kBegin; k < kEnd; k++) { dataOut[i][j] += dW[k] * dataZ[k][i][j]; } } } // Write variable varOutZs->set_cur(t, 0, 0); varOutZs->put(&(dataOut[0][0]), 1, nLat, nLon); } } // Extract total energy if (fExtractTotalEnergy) { Announce("Total Energy"); // Zonal velocity DataArray3D<double> dataU(nLev, nLat, nLon); NcVar * varU = ncdf_in.get_var("U"); varU->set_cur(t, 0, 0, 0); varU->get(&(dataU[0][0][0]), 1, nLev, nLat, nLon); // Meridional velocity DataArray3D<double> dataV(nLev, nLat, nLon); NcVar * varV = ncdf_in.get_var("V"); varV->set_cur(t, 0, 0, 0); varV->get(&(dataV[0][0][0]), 1, nLev, nLat, nLon); // Vertical velocity DataArray3D<double> dataW(nLev, nLat, nLon); NcVar * varW = ncdf_in.get_var("W"); varW->set_cur(t, 0, 0, 0); varW->get(&(dataW[0][0][0]), 1, nLev, nLat, nLon); // Calculate total energy double dTotalEnergy = 0.0; double dElementRefArea = dEarthRadius * dEarthRadius * M_PI / static_cast<double>(nLat) * 2.0 * M_PI / static_cast<double>(nLon); for (int k = 0; k < nLev; k++) { for (int i = 0; i < nLat; i++) { for (int j = 0; j < nLon; j++) { double dKineticEnergy = 0.5 * dataRho[k][i][j] * ( dataU[k][i][j] * dataU[k][i][j] + dataV[k][i][j] * dataV[k][i][j] + dataW[k][i][j] * dataW[k][i][j]); double dInternalEnergy = dataP[k][i][j] / (dGamma - 1.0); dTotalEnergy += (dKineticEnergy + dInternalEnergy) * std::cos(M_PI * dLat[i] / 180.0) * dElementRefArea * (dZtop - dZs[i][j]) / static_cast<double>(nLev); } } } // Put total energy into file varEnergy->set_cur(t); varEnergy->put(&dTotalEnergy, 1); } AnnounceEndBlock("Done"); } AnnounceEndBlock("Done"); } catch(Exception & e) { Announce(e.ToString().c_str()); } // Finalize MPI MPI_Finalize(); }
int main(int argc, char ** argv) { try { // Parameters Parameters param; // Output filename std::string strOutputFile; // Horizontal minimum wave number int nKmin; // Horizontal maximum wave number int nKmax; // Parse the command line BeginCommandLine() CommandLineInt(param.nPhiElements, "n", 40); CommandLineInt(nKmin, "kmin", 1); CommandLineInt(nKmax, "kmax", 20); CommandLineDouble(param.dXscale, "X", 1.0); CommandLineDouble(param.dT0, "T0", 300.0); CommandLineDouble(param.dU0, "U0", 20.0); CommandLineDouble(param.dG, "G", 9.80616); CommandLineDouble(param.dOmega, "omega", 7.29212e-5); CommandLineDouble(param.dGamma, "gamma", 1.4); CommandLineString(strOutputFile, "out", "wave.nc"); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Generate latitude values param.GenerateLatituteArray(param.nPhiElements); // Open NetCDF file NcFile ncdf_out(strOutputFile.c_str(), NcFile::Replace); NcDim *dimK = ncdf_out.add_dim("k", nKmax - nKmin + 1); NcDim *dimLat = ncdf_out.add_dim("lat", param.nPhiElements); NcDim *dimEig = ncdf_out.add_dim("eig", param.nPhiElements); // Write parameters and latitudes to file param.WriteToNcFile(ncdf_out, dimLat, dimLatS); // Wave numbers NcVar *varK = ncdf_out.add_var("k", ncInt, dimK); DataVector<int> vecK; vecK.Initialize(nKmax - nKmin + 1); for (int nK = nKmin; nK <= nKmax; nK++) { vecK[nK - nKmin] = nK; } varK->set_cur((long)0); varK->put(vecK, nKmax - nKmin + 1); // Eigenvalues NcVar *varMR = ncdf_out.add_var("mR", ncDouble, dimK, dimEig); NcVar *varMI = ncdf_out.add_var("mI", ncDouble, dimK, dimEig); NcVar *varUR = ncdf_out.add_var("uR", ncDouble, dimK, dimEig, dimLat); NcVar *varUI = ncdf_out.add_var("uI", ncDouble, dimK, dimEig, dimLat); NcVar *varVR = ncdf_out.add_var("vR", ncDouble, dimK, dimEig, dimLatS); NcVar *varVI = ncdf_out.add_var("vI", ncDouble, dimK, dimEig, dimLatS); NcVar *varPR = ncdf_out.add_var("pR", ncDouble, dimK, dimEig, dimLat); NcVar *varPI = ncdf_out.add_var("pI", ncDouble, dimK, dimEig, dimLat); NcVar *varWR = ncdf_out.add_var("wR", ncDouble, dimK, dimEig, dimLat); NcVar *varWI = ncdf_out.add_var("wI", ncDouble, dimK, dimEig, dimLat); NcVar *varRhoR = ncdf_out.add_var("rhoR", ncDouble, dimK, dimEig, dimLat); NcVar *varRhoI = ncdf_out.add_var("rhoI", ncDouble, dimK, dimEig, dimLat); // Allocate temporary arrays DataVector<double> dUR; dUR.Initialize(param.nPhiElements); DataVector<double> dUI; dUI.Initialize(param.nPhiElements); DataVector<double> dVR; dVR.Initialize(param.nPhiElements-1); DataVector<double> dVI; dVI.Initialize(param.nPhiElements-1); DataVector<double> dPR; dPR.Initialize(param.nPhiElements); DataVector<double> dPI; dPI.Initialize(param.nPhiElements); DataVector<double> dWR; dWR.Initialize(param.nPhiElements); DataVector<double> dWI; dWI.Initialize(param.nPhiElements); DataVector<double> dRhoR; dRhoR.Initialize(param.nPhiElements); DataVector<double> dRhoI; dRhoI.Initialize(param.nPhiElements); // Loop over all horizontal wave numbers for (int nK = nKmin; nK <= nKmax; nK++) { // Build matrices char szMessage[100]; sprintf(szMessage, "Building evolution matrices (k = %i)", nK); AnnounceStartBlock(szMessage); DataMatrix<double> matM; DataMatrix<double> matB; GenerateEvolutionMatrix(nK, param, matM, matB); AnnounceEndBlock("Done"); // Solve the matrices AnnounceStartBlock("Solving evolution matrices"); DataVector<double> vecAlphaR; DataVector<double> vecAlphaI; DataVector<double> vecBeta; DataMatrix<double> matVR; vecAlphaR.Initialize(matM.GetRows()); vecAlphaI.Initialize(matM.GetRows()); vecBeta .Initialize(matM.GetRows()); matVR .Initialize(matM.GetRows(), matM.GetColumns()); SolveEvolutionMatrix( matM, matB, vecAlphaR, vecAlphaI, vecBeta, matVR); // Sort eigenvalues std::multimap<double, int> mapSortedRows; for (int i = 0; i < vecBeta.GetRows(); i++) { if (vecBeta[i] != 0.0) { double dLambdaR = vecAlphaR[i] / vecBeta[i]; double dLambdaI = vecAlphaI[i] / vecBeta[i]; double dMR = dLambdaI; double dMI = - dLambdaR - 1.0; double dEvalMagnitude = fabs(dMR); //printf("\n%1.5e %1.5e ", dMR, dMI); // Purely imaginary eigenvalue if (dMR == 0.0) { // Wave must decay with height if (dMI < 0.0) { continue; } // Complex-conjugate pair of eigenvalues } else { // Phase propagation must be downward, and energy // propagation upwards if (dMR < 0.0) { continue; } } //printf("(OK)"); mapSortedRows.insert( std::pair<double, int>(dEvalMagnitude, i)); // Only store one entry for complex-conjugate pairs if (vecAlphaI[i] != 0.0) { i++; } } } Announce("%i eigenmodes found to satisfy entropy condition", mapSortedRows.size()); /* if (mapSortedRows.size() != param.nPhiElements) { _EXCEPTIONT("Mismatch between eigenmode count and latitude count"); } */ AnnounceEndBlock("Done"); // Write the matrices to a file AnnounceStartBlock("Writing results"); int iKix = nK - nKmin; int iWave = 0; std::map<double, int>::const_iterator it; for (it = mapSortedRows.begin(); it != mapSortedRows.end(); it++) { int i = it->second; double dLambdaR = vecAlphaR[i] / vecBeta[i]; double dLambdaI = vecAlphaI[i] / vecBeta[i]; double dMR = dLambdaI; double dMI = - dLambdaR - 1.0; // Dump eigenvalue to NetCDF file varMR->set_cur(iKix, iWave); varMR->put(&dMR, 1, 1); varMI->set_cur(iKix, iWave); varMI->put(&dMI, 1, 1); // Store real part of eigenfunction for (int j = 0; j < param.nPhiElements; j++) { dUR [j] = matVR[i][4*j ]; dPR [j] = matVR[i][4*j+1]; dWR [j] = matVR[i][4*j+2]; dRhoR[j] = matVR[i][4*j+3]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVR[j] = matVR[i][4 * param.nPhiElements + j]; } // Complex eigenvalue / eigenfunction pair if (dLambdaI != 0.0) { // Eigenvalue Lambda is complex conjugate dMR = -dMR; // Dump eigenvalue to NetCDF file varMR->set_cur(iKix, iWave+1); varMR->put(&dMR, 1, 1); varMI->set_cur(iKix, iWave+1); varMI->put(&dMI, 1, 1); // Store imaginary component of vector for (int j = 0; j < param.nPhiElements; j++) { dUI [j] = matVR[i+1][4*j ]; dPI [j] = matVR[i+1][4*j+1]; dWI [j] = matVR[i+1][4*j+2]; dRhoI[j] = matVR[i+1][4*j+3]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVI[j] = matVR[i+1][4 * param.nPhiElements + j]; } // Real eigenvalue / eigenvector pair } else { dUI.Zero(); dPI.Zero(); dWI.Zero(); dRhoI.Zero(); dVI.Zero(); } // Dump the first eigenfunction to the file varUR->set_cur(iKix, iWave, 0); varUR->put(dUR, 1, 1, param.nPhiElements); varVR->set_cur(iKix, iWave, 0); varVR->put(dVR, 1, 1, param.nPhiElements-1); varPR->set_cur(iKix, iWave, 0); varPR->put(dPR, 1, 1, param.nPhiElements); varWR->set_cur(iKix, iWave, 0); varWR->put(dWR, 1, 1, param.nPhiElements); varRhoR->set_cur(iKix, iWave, 0); varRhoR->put(dRhoR, 1, 1, param.nPhiElements); varUI->set_cur(iKix, iWave, 0); varUI->put(dUI, 1, 1, param.nPhiElements); varVI->set_cur(iKix, iWave, 0); varVI->put(dVI, 1, 1, param.nPhiElements-1); varPI->set_cur(iKix, iWave, 0); varPI->put(dPI, 1, 1, param.nPhiElements); varWI->set_cur(iKix, iWave, 0); varWI->put(dWI, 1, 1, param.nPhiElements); varRhoI->set_cur(iKix, iWave, 0); varRhoI->put(dRhoI, 1, 1, param.nPhiElements); // Complex eigenvalue / eigenvector pair if (dLambdaI != 0.0) { for (int j = 0; j < param.nPhiElements; j++) { dUI [j] = - dUI [j]; dPI [j] = - dPI [j]; dWI [j] = - dWI [j]; dRhoI[j] = - dRhoI[j]; } for (int j = 0; j < param.nPhiElements-1; j++) { dVI[j] = - dVI[j]; } varUR->set_cur(iKix, iWave+1, 0); varUR->put(dUR, 1, 1, param.nPhiElements); varVR->set_cur(iKix, iWave+1, 0); varVR->put(dVR, 1, 1, param.nPhiElements-1); varPR->set_cur(iKix, iWave+1, 0); varPR->put(dPR, 1, 1, param.nPhiElements); varWR->set_cur(iKix, iWave+1, 0); varWR->put(dWR, 1, 1, param.nPhiElements); varRhoR->set_cur(iKix, iWave+1, 0); varRhoR->put(dRhoR, 1, 1, param.nPhiElements); varUI->set_cur(iKix, iWave+1, 0); varUI->put(dUI, 1, 1, param.nPhiElements); varVI->set_cur(iKix, iWave+1, 0); varVI->put(dVI, 1, 1, param.nPhiElements-1); varPI->set_cur(iKix, iWave+1, 0); varPI->put(dPI, 1, 1, param.nPhiElements); varWI->set_cur(iKix, iWave+1, 0); varWI->put(dWI, 1, 1, param.nPhiElements); varRhoI->set_cur(iKix, iWave+1, 0); varRhoI->put(dRhoI, 1, 1, param.nPhiElements); } // Increment wave index iWave++; if (dLambdaI != 0.0) { iWave++; } } AnnounceEndBlock("Done"); AnnounceBanner(); } } catch(Exception & e) { Announce(e.ToString().c_str()); } }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output mesh filename std::string strOutputFile; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); ParseCommandLine(argc, argv); EndCommandLine(argv) // Check file names if (strInputFile == "") { std::cout << "ERROR: No input file specified" << std::endl; return (-1); } if (strOutputFile == "") { std::cout << "ERROR: No output file specified" << std::endl; return (-1); } AnnounceBanner(); // Load shapefile AnnounceStartBlock("Loading shapefile"); std::ifstream shpfile( strInputFile.c_str(), std::ios::in | std::ios::binary); SHPHeader shphead; shpfile.read((char*)(&shphead), sizeof(SHPHeader)); if (O32_HOST_ORDER == O32_LITTLE_ENDIAN) { shphead.iFileCode = SwapEndianInt32(shphead.iFileCode); shphead.iFileLength = SwapEndianInt32(shphead.iFileLength); } else if (O32_HOST_ORDER == O32_BIG_ENDIAN) { shphead.iVersion = SwapEndianInt32(shphead.iVersion); shphead.iShapeType = SwapEndianInt32(shphead.iShapeType); } else { _EXCEPTIONT("Invalid system Endian"); } if (shphead.iFileCode != SHPFileCodeRef) { _EXCEPTIONT("Input file does not appear to be a ESRI Shapefile: " "File code mismatch"); } if (shphead.iVersion != SHPVersionRef) { _EXCEPTIONT("Input file error: Version mismatch"); } if (shphead.iShapeType != SHPPolygonType) { _EXCEPTIONT("Input file error: Polygon type expected"); } SHPBounds shpbounds; shpfile.read((char*)(&shpbounds), sizeof(SHPBounds)); if (O32_HOST_ORDER == O32_BIG_ENDIAN) { shpbounds.dXmin = SwapEndianDouble(shpbounds.dXmin); shpbounds.dYmin = SwapEndianDouble(shpbounds.dYmin); shpbounds.dXmax = SwapEndianDouble(shpbounds.dXmax); shpbounds.dYmax = SwapEndianDouble(shpbounds.dXmax); shpbounds.dZmin = SwapEndianDouble(shpbounds.dZmin); shpbounds.dZmax = SwapEndianDouble(shpbounds.dZmax); shpbounds.dMmin = SwapEndianDouble(shpbounds.dMmin); shpbounds.dMmax = SwapEndianDouble(shpbounds.dMmax); } // Current position (in 16-bit words) int32_t iCurrentPosition = 50; int32_t iPolygonIx = 1; // Exodus mesh Mesh mesh; // Load records while (iCurrentPosition < shphead.iFileLength) { // Read the record header SHPRecordHeader shprechead; shpfile.read((char*)(&shprechead), sizeof(SHPRecordHeader)); if (shpfile.eof()) { break; } if (O32_HOST_ORDER == O32_LITTLE_ENDIAN) { shprechead.iNumber = SwapEndianInt32(shprechead.iNumber); shprechead.nLength = SwapEndianInt32(shprechead.nLength); } char szBuffer[128]; sprintf(szBuffer, "Polygon %i", shprechead.iNumber); iPolygonIx++; AnnounceStartBlock(szBuffer); iCurrentPosition += shprechead.nLength; // Read the shape type int32_t iShapeType; shpfile.read((char*)(&iShapeType), sizeof(int32_t)); if (shpfile.eof()) { break; } if (O32_HOST_ORDER == O32_BIG_ENDIAN) { iShapeType = SwapEndianInt32(iShapeType); } if (iShapeType != SHPPolygonType) { _EXCEPTIONT("Input file error: Record Polygon type expected"); } // Read the polygon header SHPPolygonHeader shppolyhead; shpfile.read((char*)(&shppolyhead), sizeof(SHPPolygonHeader)); if (shpfile.eof()) { break; } if (O32_HOST_ORDER == O32_BIG_ENDIAN) { shppolyhead.dXmin = SwapEndianDouble(shppolyhead.dXmin); shppolyhead.dYmin = SwapEndianDouble(shppolyhead.dYmin); shppolyhead.dXmax = SwapEndianDouble(shppolyhead.dXmax); shppolyhead.dYmax = SwapEndianDouble(shppolyhead.dYmax); shppolyhead.nNumParts = SwapEndianInt32(shppolyhead.nNumParts); shppolyhead.nNumPoints = SwapEndianInt32(shppolyhead.nNumPoints); } // Sanity check if (shppolyhead.nNumParts > 0x1000000) { _EXCEPTION1("Polygon NumParts exceeds sanity bound (%i)", shppolyhead.nNumParts); } if (shppolyhead.nNumPoints > 0x1000000) { _EXCEPTION1("Polygon NumPoints exceeds sanity bound (%i)", shppolyhead.nNumPoints); } Announce("containing %i part(s) with %i points", shppolyhead.nNumParts, shppolyhead.nNumPoints); Announce("Xmin: %3.5f", shppolyhead.dXmin); Announce("Ymin: %3.5f", shppolyhead.dYmin); Announce("Xmax: %3.5f", shppolyhead.dXmax); Announce("Ymax: %3.5f", shppolyhead.dYmax); if (shppolyhead.nNumParts != 1) { _EXCEPTIONT("Only polygons with 1 part currently supported" " in Exodus format"); } DataVector<int32_t> iParts(shppolyhead.nNumParts); shpfile.read((char*)&(iParts[0]), shppolyhead.nNumParts * sizeof(int32_t)); if (shpfile.eof()) { break; } DataVector<double> dPoints(shppolyhead.nNumPoints * 2); shpfile.read((char*)&(dPoints[0]), shppolyhead.nNumPoints * 2 * sizeof(double)); if (shpfile.eof()) { break; } if (O32_HOST_ORDER == O32_BIG_ENDIAN) { for (int i = 0; i < shppolyhead.nNumParts; i++) { iParts[i] = SwapEndianInt32(iParts[i]); } for (int i = 0; i < shppolyhead.nNumPoints * 2; i++) { dPoints[i] = SwapEndianDouble(dPoints[i]); } } // Convert to Exodus mesh int nFaces = mesh.faces.size(); int nNodes = mesh.nodes.size(); mesh.faces.resize(nFaces+1); mesh.nodes.resize(nNodes + shppolyhead.nNumPoints); mesh.faces[nFaces] = Face(shppolyhead.nNumPoints); for (int i = 0; i < shppolyhead.nNumPoints; i++) { double dLonRad = dPoints[2*i] / 180.0 * M_PI; double dLatRad = dPoints[2*i+1] / 180.0 * M_PI; mesh.nodes[nNodes+i].x = cos(dLatRad) * cos(dLonRad); mesh.nodes[nNodes+i].y = cos(dLatRad) * sin(dLonRad); mesh.nodes[nNodes+i].z = sin(dLatRad); mesh.faces[nFaces].SetNode(i, nNodes + i); } AnnounceEndBlock("Done"); } AnnounceEndBlock("Done"); // Write to file AnnounceStartBlock("Write Exodus mesh"); mesh.Write(strOutputFile); AnnounceEndBlock("Done"); // Announce AnnounceBanner(); return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int main(int argc, char** argv) { // UTM zone int nZone; // Number of columns in mesh int nCols; // Number of rows in mesh int nRows; // XLL Corner of the mesh double dXLLCorner; // YLL Corner of the mesh double dYLLCorner; // Cell size (in meters) double dCellSize; // Output filename std::string strOutputFile; // Verbose output bool fVerbose; // Parse the command line BeginCommandLine() CommandLineInt(nZone, "zone", 0); CommandLineInt(nCols, "cols", 128); CommandLineInt(nRows, "rows", 64); CommandLineDouble(dXLLCorner, "xllcorner", 0.0); CommandLineDouble(dYLLCorner, "yllcorner", 0.0); CommandLineDouble(dCellSize, "cellsize", 1000.0); CommandLineString(strOutputFile, "file", "outUTMMesh.g"); CommandLineBool(fVerbose, "verbose"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Verify input arguments if (nCols <= 0) { _EXCEPTIONT("--cols must be positive"); } if (nRows <= 0) { _EXCEPTIONT("--rows must be positive"); } if (dCellSize <= 0.0) { _EXCEPTIONT("--cellsize must be positive"); } std::cout << "========================================================="; std::cout << std::endl; // Call the actual mesh generator Mesh mesh; int err = GenerateUTMMesh(mesh, nZone, nCols, nRows, dXLLCorner, dYLLCorner, dCellSize, strOutputFile, fVerbose); if (err) exit(err); return 0; }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input filename std::string strInputFile; // Output mesh filename std::string strOutputFile; // Polynomial degree per element int nP = 2; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strOutputFile, "out", ""); //CommandLineInt(nP, "np", 2); //CommandLineBool(fCGLL, "cgll"); ParseCommandLine(argc, argv); EndCommandLine(argv) // Check file names if (strInputFile == "") { std::cout << "ERROR: No input file specified" << std::endl; return (-1); } if (strOutputFile == "") { std::cout << "ERROR: No output file specified" << std::endl; return (-1); } if (nP < 1) { std::cout << "ERROR: --np must be >= 2" << std::endl; return (-1); } AnnounceBanner(); // Load input mesh AnnounceStartBlock("Loading input mesh"); Mesh meshIn(strInputFile); meshIn.RemoveZeroEdges(); AnnounceEndBlock("Done"); // Construct edge map AnnounceStartBlock("Constructing edge map"); meshIn.ConstructEdgeMap(); AnnounceEndBlock("Done"); // Build connectivity vector using edge map AnnounceStartBlock("Constructing connectivity"); std::vector< std::set<int> > vecConnectivity; int err = GenerateConnectivityData(meshIn, vecConnectivity); if (err) return err; AnnounceEndBlock("Done"); // Open output file AnnounceStartBlock("Writing connectivity file"); NcFile ncmesh(strInputFile.c_str(), NcFile::ReadOnly); NcVar * varLat = ncmesh.get_var("grid_center_lat"); NcVar * varLon = ncmesh.get_var("grid_center_lon"); // Check if center latitudes and longitudes are already available DataArray1D<double> dAllLats; DataArray1D<double> dAllLons; bool fConvertLatToDegrees = true; bool fConvertLonToDegrees = true; if ((varLat == NULL) || (varLon == NULL)) { Announce("grid_center_lat not found, recalculating face centers"); } else { Announce("grid_center_lat found in file, loading values"); if (varLat->get_dim(0)->size() != vecConnectivity.size()) { _EXCEPTIONT("grid_center_lat dimension mismatch"); } if (varLon->get_dim(0)->size() != vecConnectivity.size()) { _EXCEPTIONT("grid_center_lon dimension mismatch"); } dAllLats.Allocate(vecConnectivity.size()); varLat->set_cur((long)0); varLat->get(dAllLats, vecConnectivity.size()); NcAtt * attLatUnits = varLat->get_att("units"); std::string strLatUnits = attLatUnits->as_string(0); if (strLatUnits == "degrees") { fConvertLatToDegrees = false; } dAllLons.Allocate(vecConnectivity.size()); varLon->set_cur((long)0); varLon->get(dAllLons, vecConnectivity.size()); NcAtt * attLonUnits = varLon->get_att("units"); std::string strLonUnits = attLonUnits->as_string(0); if (strLonUnits == "degrees") { fConvertLonToDegrees = false; } } // Write connectiivty file FILE * fp = fopen(strOutputFile.c_str(), "w"); fprintf(fp, "%lu\n", vecConnectivity.size()); for (size_t f = 0; f < vecConnectivity.size(); f++) { double dLon; double dLat; if ((varLat == NULL) || (varLon == NULL)) { Node nodeCentroid; for (int i = 0; i < meshIn.faces[f].edges.size(); i++) { nodeCentroid.x += meshIn.nodes[meshIn.faces[f][i]].x; nodeCentroid.y += meshIn.nodes[meshIn.faces[f][i]].y; nodeCentroid.z += meshIn.nodes[meshIn.faces[f][i]].z; } double dMagnitude = nodeCentroid.Magnitude(); nodeCentroid.x /= dMagnitude; nodeCentroid.y /= dMagnitude; nodeCentroid.z /= dMagnitude; dLon = atan2(nodeCentroid.y, nodeCentroid.x); dLat = asin(nodeCentroid.z); if (dLon < 0.0) { dLon += 2.0 * M_PI; } } else { dLon = dAllLons[f]; dLat = dAllLats[f]; } if (fConvertLonToDegrees) { dLon *= 180.0 / M_PI; } if (fConvertLatToDegrees) { dLat *= 180.0 / M_PI; } fprintf(fp, "%1.14f,", dLon); fprintf(fp, "%1.14f,", dLat); fprintf(fp, "%lu", vecConnectivity[f].size()); std::set<int>::const_iterator iter = vecConnectivity[f].begin(); for (; iter != vecConnectivity[f].end(); iter++) { fprintf(fp, ",%i", *iter); } if (f != vecConnectivity.size()-1) { fprintf(fp,"\n"); } } fclose(fp); AnnounceEndBlock("Done"); // Announce AnnounceBanner(); return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int main(int argc, char** argv) { NcError error(NcError::verbose_nonfatal); try { // Input file std::string strInputFile; // Input file list std::string strInputFileList; // Input file format std::string strInputFormat; // NetCDF file containing latitude and longitude arrays std::string strLatLonFile; // Output file (NetCDF) std::string strOutputFile; // Output variable name std::string strOutputVariable; // Column in which the longitude index appears int iLonIxCol; // Column in which the latitude index appears int iLatIxCol; // Begin latitude double dLatBegin; // End latitude double dLatEnd; // Begin longitude double dLonBegin; // End longitude double dLonEnd; // Number of latitudes in output int nLat; // Number of longitudes in output int nLon; // Parse the command line BeginCommandLine() CommandLineString(strInputFile, "in", ""); CommandLineString(strInputFileList, "inlist", ""); CommandLineStringD(strInputFormat, "in_format", "std", "(std|visit)"); CommandLineString(strOutputFile, "out", ""); CommandLineString(strOutputVariable, "outvar", "density"); CommandLineInt(iLonIxCol, "iloncol", 8); CommandLineInt(iLatIxCol, "ilatcol", 9); CommandLineDouble(dLatBegin, "lat_begin", -90.0); CommandLineDouble(dLatEnd, "lat_end", 90.0); CommandLineDouble(dLonBegin, "lon_begin", 0.0); CommandLineDouble(dLonEnd, "lon_end", 360.0); CommandLineInt(nLat, "nlat", 180); CommandLineInt(nLon, "nlon", 360); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check input if ((strInputFile == "") && (strInputFileList == "")) { _EXCEPTIONT("No input file (--in) or (--inlist) specified"); } if ((strInputFile != "") && (strInputFileList != "")) { _EXCEPTIONT("Only one input file (--in) or (--inlist) allowed"); } if (strInputFormat != "std") { _EXCEPTIONT("UNIMPLEMENTED: Only \"--in_format std\" supported"); } // Check output if (strOutputFile == "") { _EXCEPTIONT("No output file (--out) specified"); } // Check output variable if (strOutputVariable == "") { _EXCEPTIONT("No output variable name (--outvar) specified"); } // Number of latitudes and longitudes if (nLat == 0) { _EXCEPTIONT("UNIMPLEMENTED: --nlat must be specified currently"); } if (nLon == 0) { _EXCEPTIONT("UNIMPLEMENTED: --nlon must be specified currently"); } // Input file list std::vector<std::string> vecInputFiles; if (strInputFile != "") { vecInputFiles.push_back(strInputFile); } if (strInputFileList != "") { GetInputFileList(strInputFileList, vecInputFiles); } int nFiles = vecInputFiles.size(); // Density DataMatrix<int> nCounts; nCounts.Initialize(nLat, nLon); // Loop through all files in list AnnounceStartBlock("Processing files"); std::string strBuffer; strBuffer.reserve(1024); for (int f = 0; f < nFiles; f++) { Announce("File \"%s\"", vecInputFiles[f].c_str()); FILE * fp = fopen(vecInputFiles[f].c_str(), "r"); if (fp == NULL) { _EXCEPTION1("Unable to open input file \"%s\"", vecInputFiles[f].c_str()); } for (;;) { // Read in the next line fgets(&(strBuffer[0]), 1024, fp); int nLength = strlen(&(strBuffer[0])); // Check for end of file if (feof(fp)) { break; } // Check for comment line if (strBuffer[0] == '#') { continue; } // Check for new storm if (strncmp(&(strBuffer[0]), "start", 5) == 0) { continue; } // Parse line double dLon; double dLat; int iCol = 0; int iLast = 0; bool fWhitespace = true; for (int i = 0; i <= nLength; i++) { if ((strBuffer[i] == ' ') || (strBuffer[i] == ',') || (strBuffer[i] == '\t') || (strBuffer[i] == '\0') ) { if (!fWhitespace) { if (iCol == iLonIxCol) { strBuffer[i] = '\0'; dLon = atof(&(strBuffer[iLast])); } if (iCol == iLatIxCol) { strBuffer[i] = '\0'; dLat = atof(&(strBuffer[iLast])); } } fWhitespace = true; } else { if (fWhitespace) { iLast = i; iCol++; } fWhitespace = false; } } // Latitude and longitude index int iLon = static_cast<int>(static_cast<double>(nLon) * (dLon - dLonBegin) / (dLonEnd - dLonBegin)); int iLat = static_cast<int>(static_cast<double>(nLat) * (dLat - dLatBegin) / (dLatEnd - dLatBegin)); if (iLon == (-1)) { iLon = 0; } if (iLon == nLon) { iLon = nLon - 1; } if (iLat == (-1)) { iLat = 0; } if (iLat == nLat) { iLat = nLat - 1; } if ((iLat < 0) || (iLat >= nLat)) { _EXCEPTION1("Latitude index (%i) out of range", iLat); } if ((iLon < 0) || (iLon >= nLon)) { _EXCEPTION1("Longitude index (%i) out of range", iLon); } nCounts[iLat][iLon]++; } fclose(fp); } AnnounceEndBlock("Done"); // Output results AnnounceStartBlock("Output results"); // Load the netcdf output file NcFile ncOutput(strOutputFile.c_str(), NcFile::Replace); if (!ncOutput.is_valid()) { _EXCEPTION1("Unable to open output file \"%s\"", strOutputFile.c_str()); } // Create output NcDim * dimLat = ncOutput.add_dim("lat", nLat); NcDim * dimLon = ncOutput.add_dim("lon", nLon); NcVar * varLat = ncOutput.add_var("lat", ncDouble, dimLat); NcVar * varLon = ncOutput.add_var("lon", ncDouble, dimLon); varLat->add_att("units", "degrees_north"); varLon->add_att("units", "degrees_east"); DataVector<double> dLat(nLat); DataVector<double> dLon(nLon); for (int j = 0; j < nLat; j++) { dLat[j] = dLatBegin + (dLatEnd - dLatBegin) * (static_cast<double>(j) + 0.5) / static_cast<double>(nLat); } for (int i = 0; i < nLon; i++) { dLon[i] = dLonBegin + (dLonEnd - dLonBegin) * (static_cast<double>(i) + 0.5) / static_cast<double>(nLon); } varLat->put(&(dLat[0]), nLat); varLon->put(&(dLon[0]), nLon); // Output counts NcVar * varCount = ncOutput.add_var( strOutputVariable.c_str(), ncInt, dimLat, dimLon); varCount->put(&(nCounts[0][0]), nLat, nLon); ncOutput.close(); AnnounceEndBlock("Done"); AnnounceBanner(); } catch(Exception & e) { Announce(e.ToString().c_str()); } }
int main(int argc, char** argv) { NcError error(NcError::silent_nonfatal); try { // Input / Output types enum DiscretizationType { DiscretizationType_FV, DiscretizationType_CGLL, DiscretizationType_DGLL }; // Input mesh file std::string strInputMesh; // Overlap mesh file std::string strOverlapMesh; // Input metadata file std::string strInputMeta; // Output metadata file std::string strOutputMeta; // Input data type std::string strInputType; // Output data type std::string strOutputType; // Order of polynomial in each element int nPin; // Order of polynomial in each output element int nPout; // Use bubble on interior of spectral element nodes bool fBubble; // Enforce monotonicity bool fMonotoneType1; // Enforce monotonicity bool fMonotoneType2; // Enforce monotonicity bool fMonotoneType3; // Volumetric remapping bool fVolumetric; // No conservation bool fNoConservation; // Turn off checking for conservation / consistency bool fNoCheck; // Output mesh file std::string strOutputMesh; // Variable list std::string strVariables; // Output map file std::string strOutputMap; // Input data file std::string strInputData; // Output data file std::string strOutputData; // Name of the ncol variable std::string strNColName; // Output as double bool fOutputDouble; // List of variables to preserve std::string strPreserveVariables; // Preserve all non-remapped variables bool fPreserveAll; // Fill value override double dFillValueOverride; // Parse the command line BeginCommandLine() //CommandLineStringD(strMethod, "method", "", "[se]"); CommandLineString(strInputMesh, "in_mesh", ""); CommandLineString(strOutputMesh, "out_mesh", ""); CommandLineString(strOverlapMesh, "ov_mesh", ""); CommandLineString(strInputMeta, "in_meta", ""); CommandLineString(strOutputMeta, "out_meta", ""); CommandLineStringD(strInputType, "in_type", "fv", "[fv|cgll|dgll]"); CommandLineStringD(strOutputType, "out_type", "fv", "[fv|cgll|dgll]"); CommandLineInt(nPin, "in_np", 4); CommandLineInt(nPout, "out_np", 4); CommandLineBool(fBubble, "bubble"); CommandLineBool(fMonotoneType1, "mono"); CommandLineBool(fMonotoneType2, "mono2"); CommandLineBool(fMonotoneType3, "mono3"); CommandLineBool(fVolumetric, "volumetric"); CommandLineBool(fNoConservation, "noconserve"); CommandLineBool(fNoCheck, "nocheck"); CommandLineString(strVariables, "var", ""); CommandLineString(strOutputMap, "out_map", ""); CommandLineString(strInputData, "in_data", ""); CommandLineString(strOutputData, "out_data", ""); CommandLineString(strNColName, "ncol_name", "ncol"); CommandLineBool(fOutputDouble, "out_double"); CommandLineString(strPreserveVariables, "preserve", ""); CommandLineBool(fPreserveAll, "preserveall"); CommandLineDouble(dFillValueOverride, "fillvalue", 0.0); ParseCommandLine(argc, argv); EndCommandLine(argv) AnnounceBanner(); // Check command line parameters (mesh arguments) if (strInputMesh == "") { _EXCEPTIONT("No input mesh (--in_mesh) specified"); } if (strOutputMesh == "") { _EXCEPTIONT("No output mesh (--out_mesh) specified"); } // Overlap mesh if (strOverlapMesh == "") { _EXCEPTIONT("No overlap mesh specified"); } // Check command line parameters (data arguments) if ((strInputData != "") && (strOutputData == "")) { _EXCEPTIONT("--in_data specified without --out_data"); } if ((strInputData == "") && (strOutputData != "")) { _EXCEPTIONT("--out_data specified without --in_data"); } // Check metadata parameters if ((strInputMeta != "") && (strInputType == "fv")) { _EXCEPTIONT("--in_meta cannot be used with --in_type fv"); } if ((strOutputMeta != "") && (strOutputType == "fv")) { _EXCEPTIONT("--out_meta cannot be used with --out_type fv"); } // Check command line parameters (data type arguments) STLStringHelper::ToLower(strInputType); STLStringHelper::ToLower(strOutputType); DiscretizationType eInputType; DiscretizationType eOutputType; if (strInputType == "fv") { eInputType = DiscretizationType_FV; } else if (strInputType == "cgll") { eInputType = DiscretizationType_CGLL; } else if (strInputType == "dgll") { eInputType = DiscretizationType_DGLL; } else { _EXCEPTION1("Invalid \"in_type\" value (%s), expected [fv|cgll|dgll]", strInputType.c_str()); } if (strOutputType == "fv") { eOutputType = DiscretizationType_FV; } else if (strOutputType == "cgll") { eOutputType = DiscretizationType_CGLL; } else if (strOutputType == "dgll") { eOutputType = DiscretizationType_DGLL; } else { _EXCEPTION1("Invalid \"out_type\" value (%s), expected [fv|cgll|dgll]", strOutputType.c_str()); } // Monotonicity flags int nMonotoneType = 0; if (fMonotoneType1) { nMonotoneType = 1; } if (fMonotoneType2) { if (nMonotoneType != 0) { _EXCEPTIONT("Only one of --mono, --mono2 and --mono3 may be set"); } nMonotoneType = 2; } if (fMonotoneType3) { if (nMonotoneType != 0) { _EXCEPTIONT("Only one of --mono, --mono2 and --mono3 may be set"); } nMonotoneType = 3; } /* // Volumetric if (fVolumetric && (nMonotoneType != 0)) { _EXCEPTIONT("--volumetric cannot be used in conjunction with --mono#"); } */ // Create Offline Map OfflineMap mapRemap; // Initialize dimension information from file AnnounceStartBlock("Initializing dimensions of map"); Announce("Input mesh"); mapRemap.InitializeSourceDimensionsFromFile(strInputMesh); Announce("Output mesh"); mapRemap.InitializeTargetDimensionsFromFile(strOutputMesh); AnnounceEndBlock(NULL); // Parse variable list std::vector< std::string > vecVariableStrings; ParseVariableList(strVariables, vecVariableStrings); // Parse preserve variable list std::vector< std::string > vecPreserveVariableStrings; ParseVariableList(strPreserveVariables, vecPreserveVariableStrings); if (fPreserveAll && (vecPreserveVariableStrings.size() != 0)) { _EXCEPTIONT("--preserveall and --preserve cannot both be specified"); } // Load input mesh AnnounceStartBlock("Loading input mesh"); Mesh meshInput(strInputMesh); meshInput.RemoveZeroEdges(); AnnounceEndBlock(NULL); // Calculate Face areas AnnounceStartBlock("Calculating input mesh Face areas"); double dTotalAreaInput = meshInput.CalculateFaceAreas(); Announce("Input Mesh Geometric Area: %1.15e", dTotalAreaInput); AnnounceEndBlock(NULL); // Input mesh areas if (eInputType == DiscretizationType_FV) { mapRemap.SetSourceAreas(meshInput.vecFaceArea); } // Load output mesh AnnounceStartBlock("Loading output mesh"); Mesh meshOutput(strOutputMesh); meshOutput.RemoveZeroEdges(); AnnounceEndBlock(NULL); // Calculate Face areas AnnounceStartBlock("Calculating output mesh Face areas"); Real dTotalAreaOutput = meshOutput.CalculateFaceAreas(); Announce("Output Mesh Geometric Area: %1.15e", dTotalAreaOutput); AnnounceEndBlock(NULL); // Output mesh areas if (eOutputType == DiscretizationType_FV) { mapRemap.SetTargetAreas(meshOutput.vecFaceArea); } // Load overlap mesh AnnounceStartBlock("Loading overlap mesh"); Mesh meshOverlap(strOverlapMesh); meshOverlap.RemoveZeroEdges(); // Verify that overlap mesh is in the correct order int ixSourceFaceMax = (-1); int ixTargetFaceMax = (-1); if (meshOverlap.vecSourceFaceIx.size() != meshOverlap.vecTargetFaceIx.size() ) { _EXCEPTIONT("Invalid overlap mesh:\n" " Possible mesh file corruption?"); } for (int i = 0; i < meshOverlap.vecSourceFaceIx.size(); i++) { if (meshOverlap.vecSourceFaceIx[i] + 1 > ixSourceFaceMax) { ixSourceFaceMax = meshOverlap.vecSourceFaceIx[i] + 1; } if (meshOverlap.vecTargetFaceIx[i] + 1 > ixTargetFaceMax) { ixTargetFaceMax = meshOverlap.vecTargetFaceIx[i] + 1; } } // Check for forward correspondence in overlap mesh if (ixSourceFaceMax == meshInput.faces.size() //&& //(ixTargetFaceMax == meshOutput.faces.size()) ) { Announce("Overlap mesh forward correspondence found"); // Check for reverse correspondence in overlap mesh } else if ( ixSourceFaceMax == meshOutput.faces.size() //&& //(ixTargetFaceMax == meshInput.faces.size()) ) { Announce("Overlap mesh reverse correspondence found (reversing)"); // Reorder overlap mesh meshOverlap.ExchangeFirstAndSecondMesh(); // No correspondence found } else { _EXCEPTION2("Invalid overlap mesh:\n" " No correspondence found with input and output meshes (%i,%i)", ixSourceFaceMax, ixTargetFaceMax); } AnnounceEndBlock(NULL); // Calculate Face areas AnnounceStartBlock("Calculating overlap mesh Face areas"); Real dTotalAreaOverlap = meshOverlap.CalculateFaceAreas(); Announce("Overlap Mesh Area: %1.15e", dTotalAreaOverlap); AnnounceEndBlock(NULL); // Partial cover if (fabs(dTotalAreaOverlap - dTotalAreaInput) > 1.0e-10) { if (!fNoCheck) { Announce("WARNING: Significant mismatch between overlap mesh area " "and input mesh area.\n Automatically enabling --nocheck"); fNoCheck = true; } } /* // Recalculate input mesh area from overlap mesh if (fabs(dTotalAreaOverlap - dTotalAreaInput) > 1.0e-10) { AnnounceStartBlock("Overlap mesh only covers a sub-area of the sphere"); Announce("Recalculating source mesh areas"); dTotalAreaInput = meshInput.CalculateFaceAreasFromOverlap(meshOverlap); Announce("New Input Mesh Geometric Area: %1.15e", dTotalAreaInput); AnnounceEndBlock(NULL); } */ // Finite volume input / Finite volume output if ((eInputType == DiscretizationType_FV) && (eOutputType == DiscretizationType_FV) ) { // Generate reverse node array and edge map meshInput.ConstructReverseNodeArray(); meshInput.ConstructEdgeMap(); // Initialize coordinates for map mapRemap.InitializeSourceCoordinatesFromMeshFV(meshInput); mapRemap.InitializeTargetCoordinatesFromMeshFV(meshOutput); // Construct OfflineMap AnnounceStartBlock("Calculating offline map"); LinearRemapFVtoFV( meshInput, meshOutput, meshOverlap, nPin, mapRemap); // Finite volume input / Finite element output } else if (eInputType == DiscretizationType_FV) { DataMatrix3D<int> dataGLLNodes; DataMatrix3D<double> dataGLLJacobian; if (strOutputMeta != "") { AnnounceStartBlock("Loading meta data file"); LoadMetaDataFile(strOutputMeta, dataGLLNodes, dataGLLJacobian); AnnounceEndBlock(NULL); } else { AnnounceStartBlock("Generating output mesh meta data"); double dNumericalArea = GenerateMetaData( meshOutput, nPout, fBubble, dataGLLNodes, dataGLLJacobian); Announce("Output Mesh Numerical Area: %1.15e", dNumericalArea); AnnounceEndBlock(NULL); } // Initialize coordinates for map mapRemap.InitializeSourceCoordinatesFromMeshFV(meshInput); mapRemap.InitializeTargetCoordinatesFromMeshFE( meshOutput, nPout, dataGLLNodes); // Generate the continuous Jacobian bool fContinuous = (eOutputType == DiscretizationType_CGLL); if (eOutputType == DiscretizationType_CGLL) { GenerateUniqueJacobian( dataGLLNodes, dataGLLJacobian, mapRemap.GetTargetAreas()); } else { GenerateDiscontinuousJacobian( dataGLLJacobian, mapRemap.GetTargetAreas()); } // Generate reverse node array and edge map meshInput.ConstructReverseNodeArray(); meshInput.ConstructEdgeMap(); // Generate remap weights AnnounceStartBlock("Calculating offline map"); if (fVolumetric) { LinearRemapFVtoGLL_Volumetric( meshInput, meshOutput, meshOverlap, dataGLLNodes, dataGLLJacobian, mapRemap.GetTargetAreas(), nPin, mapRemap, nMonotoneType, fContinuous, fNoConservation); } else { LinearRemapFVtoGLL( meshInput, meshOutput, meshOverlap, dataGLLNodes, dataGLLJacobian, mapRemap.GetTargetAreas(), nPin, mapRemap, nMonotoneType, fContinuous, fNoConservation); } // Finite element input / Finite volume output } else if ( (eInputType != DiscretizationType_FV) && (eOutputType == DiscretizationType_FV) ) { DataMatrix3D<int> dataGLLNodes; DataMatrix3D<double> dataGLLJacobian; if (strInputMeta != "") { AnnounceStartBlock("Loading meta data file"); LoadMetaDataFile(strInputMeta, dataGLLNodes, dataGLLJacobian); AnnounceEndBlock(NULL); } else { AnnounceStartBlock("Generating input mesh meta data"); double dNumericalArea = GenerateMetaData( meshInput, nPin, fBubble, dataGLLNodes, dataGLLJacobian); Announce("Input Mesh Numerical Area: %1.15e", dNumericalArea); AnnounceEndBlock(NULL); if (fabs(dNumericalArea - dTotalAreaInput) > 1.0e-12) { Announce("WARNING: Significant mismatch between input mesh " "numerical area and geometric area"); } } if (dataGLLNodes.GetSubColumns() != meshInput.faces.size()) { _EXCEPTIONT("Number of element does not match between metadata and " "input mesh"); } // Initialize coordinates for map mapRemap.InitializeSourceCoordinatesFromMeshFE( meshInput, nPin, dataGLLNodes); mapRemap.InitializeTargetCoordinatesFromMeshFV(meshOutput); // Generate the continuous Jacobian for input mesh bool fContinuousIn = (eInputType == DiscretizationType_CGLL); if (eInputType == DiscretizationType_CGLL) { GenerateUniqueJacobian( dataGLLNodes, dataGLLJacobian, mapRemap.GetSourceAreas()); } else { GenerateDiscontinuousJacobian( dataGLLJacobian, mapRemap.GetSourceAreas()); } // Generate offline map AnnounceStartBlock("Calculating offline map"); if (fVolumetric) { _EXCEPTIONT("Unimplemented: Volumetric currently unavailable for" "GLL input mesh"); } LinearRemapSE4( meshInput, meshOutput, meshOverlap, dataGLLNodes, dataGLLJacobian, nMonotoneType, fContinuousIn, fNoConservation, mapRemap ); // Finite element input / Finite element output } else if ( (eInputType != DiscretizationType_FV) && (eOutputType != DiscretizationType_FV) ) { DataMatrix3D<int> dataGLLNodesIn; DataMatrix3D<double> dataGLLJacobianIn; DataMatrix3D<int> dataGLLNodesOut; DataMatrix3D<double> dataGLLJacobianOut; // Input metadata if (strInputMeta != "") { AnnounceStartBlock("Loading input meta data file"); LoadMetaDataFile( strInputMeta, dataGLLNodesIn, dataGLLJacobianIn); AnnounceEndBlock(NULL); } else { AnnounceStartBlock("Generating input mesh meta data"); double dNumericalAreaIn = GenerateMetaData( meshInput, nPin, fBubble, dataGLLNodesIn, dataGLLJacobianIn); Announce("Input Mesh Numerical Area: %1.15e", dNumericalAreaIn); AnnounceEndBlock(NULL); if (fabs(dNumericalAreaIn - dTotalAreaInput) > 1.0e-12) { Announce("WARNING: Significant mismatch between input mesh " "numerical area and geometric area"); } } // Output metadata if (strOutputMeta != "") { AnnounceStartBlock("Loading output meta data file"); LoadMetaDataFile( strOutputMeta, dataGLLNodesOut, dataGLLJacobianOut); AnnounceEndBlock(NULL); } else { AnnounceStartBlock("Generating output mesh meta data"); double dNumericalAreaOut = GenerateMetaData( meshOutput, nPout, fBubble, dataGLLNodesOut, dataGLLJacobianOut); Announce("Output Mesh Numerical Area: %1.15e", dNumericalAreaOut); AnnounceEndBlock(NULL); if (fabs(dNumericalAreaOut - dTotalAreaOutput) > 1.0e-12) { Announce("WARNING: Significant mismatch between output mesh " "numerical area and geometric area"); } } // Initialize coordinates for map mapRemap.InitializeSourceCoordinatesFromMeshFE( meshInput, nPin, dataGLLNodesIn); mapRemap.InitializeTargetCoordinatesFromMeshFE( meshOutput, nPout, dataGLLNodesOut); // Generate the continuous Jacobian for input mesh bool fContinuousIn = (eInputType == DiscretizationType_CGLL); if (eInputType == DiscretizationType_CGLL) { GenerateUniqueJacobian( dataGLLNodesIn, dataGLLJacobianIn, mapRemap.GetSourceAreas()); } else { GenerateDiscontinuousJacobian( dataGLLJacobianIn, mapRemap.GetSourceAreas()); } // Generate the continuous Jacobian for output mesh bool fContinuousOut = (eOutputType == DiscretizationType_CGLL); if (eOutputType == DiscretizationType_CGLL) { GenerateUniqueJacobian( dataGLLNodesOut, dataGLLJacobianOut, mapRemap.GetTargetAreas()); } else { GenerateDiscontinuousJacobian( dataGLLJacobianOut, mapRemap.GetTargetAreas()); } // Generate offline map AnnounceStartBlock("Calculating offline map"); LinearRemapGLLtoGLL2( meshInput, meshOutput, meshOverlap, dataGLLNodesIn, dataGLLJacobianIn, dataGLLNodesOut, dataGLLJacobianOut, mapRemap.GetTargetAreas(), nPin, nPout, nMonotoneType, fContinuousIn, fContinuousOut, fNoConservation, mapRemap ); } else { _EXCEPTIONT("Not implemented"); } //#pragma warning "NOTE: VERIFICATION DISABLED" // Verify consistency, conservation and monotonicity if (!fNoCheck) { AnnounceStartBlock("Verifying map"); mapRemap.IsConsistent(1.0e-8); mapRemap.IsConservative(1.0e-8); if (nMonotoneType != 0) { mapRemap.IsMonotone(1.0e-12); } AnnounceEndBlock(NULL); } AnnounceEndBlock(NULL); // Initialize element dimensions from input/output Mesh AnnounceStartBlock("Writing output"); // Output the Offline Map if (strOutputMap != "") { AnnounceStartBlock("Writing offline map"); mapRemap.Write(strOutputMap); AnnounceEndBlock(NULL); } // Apply Offline Map to data if (strInputData != "") { AnnounceStartBlock("Applying offline map to data"); mapRemap.SetFillValueOverride(static_cast<float>(dFillValueOverride)); mapRemap.Apply( strInputData, strOutputData, vecVariableStrings, strNColName, fOutputDouble, false); AnnounceEndBlock(NULL); } AnnounceEndBlock(NULL); // Copy variables from input file to output file if ((strInputData != "") && (strOutputData != "")) { if (fPreserveAll) { AnnounceStartBlock("Preserving variables"); mapRemap.PreserveAllVariables(strInputData, strOutputData); AnnounceEndBlock(NULL); } else if (vecPreserveVariableStrings.size() != 0) { AnnounceStartBlock("Preserving variables"); mapRemap.PreserveVariables( strInputData, strOutputData, vecPreserveVariableStrings); AnnounceEndBlock(NULL); } } AnnounceBanner(); return (0); } catch(Exception & e) { Announce(e.ToString().c_str()); return (-1); } catch(...) { return (-2); } }
int main(int argc, char** argv) { try { // Input mesh file std::string strInputMesh; // Output node file std::string strOutputNodes; // Output face file std::string strOutputFaces; // Parse the command line BeginCommandLine() CommandLineString(strInputMesh, "in", ""); CommandLineString(strOutputNodes, "out_nodes", "nodes.dat"); CommandLineString(strOutputFaces, "out_faces", "faces.dat"); ParseCommandLine(argc, argv); EndCommandLine(argv) if (strInputMesh == "") { return (-1); } AnnounceBanner(); // Load input mesh AnnounceStartBlock("Loading input mesh"); Mesh meshInput(strInputMesh); AnnounceEndBlock(NULL); // Output nodes AnnounceStartBlock("Writing nodes"); FILE * fpNodes = fopen(strOutputNodes.c_str(), "w"); for (int i = 0; i < meshInput.nodes.size(); i++) { fprintf(fpNodes, "%1.10e %1.10e %1.10e\n", static_cast<double>(meshInput.nodes[i].x), static_cast<double>(meshInput.nodes[i].y), static_cast<double>(meshInput.nodes[i].z)); } fclose(fpNodes); AnnounceEndBlock("Done!"); // Output faces AnnounceStartBlock("Writing faces"); FILE * fpFaces = fopen(strOutputFaces.c_str(), "w"); for (int i = 0; i < meshInput.faces.size(); i++) { for (int j = 0; j < meshInput.faces[i].edges.size(); j++) { fprintf(fpFaces, "%i", meshInput.faces[i][j] + 1); if (j != meshInput.faces[i].edges.size()-1) { fprintf(fpFaces, " "); } } fprintf(fpFaces, "\n"); } fclose(fpFaces); AnnounceEndBlock("Done!"); AnnounceBanner(); } catch(Exception & e) { Announce(e.ToString().c_str()); } }