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;
}
Ejemplo n.º 2
0
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();

}
Ejemplo n.º 3
0
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) {

	// Initialize Tempest
	TempestInitialize(&argc, &argv);

try {
	// Model height cap
	double dZtop;

	// Grid rotation angle
	double dAlpha;

	// Include tracer field
	bool fTracersOn;

	// Rayleigh layer
	bool fRayleighFriction;

	// Deep atmosphere flag
	bool fDeepAtmosphere;

	// Perturbation type
	std::string strPerturbationType;

	// Parse the command line
	BeginTempestCommandLine("BaroclinicWaveUMJS");
		SetDefaultResolution(20);
		SetDefaultLevels(10);
		SetDefaultOutputDeltaT("200s");
		SetDefaultDeltaT("200s");
		SetDefaultEndTime("200s");
		SetDefaultHorizontalOrder(4);
		SetDefaultVerticalOrder(1);

		CommandLineDouble(dZtop, "ztop", 10000.0);
		CommandLineDouble(dAlpha, "alpha", 0.0);
		CommandLineBool(fDeepAtmosphere, "deep_atmosphere");
		CommandLineBool(fRayleighFriction, "rayleigh");
		CommandLineStringD(strPerturbationType, "pert",
			"None", "(None | Exp | Sfn)");

		ParseCommandLine(argc, argv);
	EndTempestCommandLine(argv)

	// Setup the Model
	AnnounceBanner("MODEL SETUP");

	Model model(EquationSet::PrimitiveNonhydrostaticEquations);

	TempestSetupCubedSphereModel(model);

	// Set the test case for the model
	AnnounceStartBlock("Initializing test case");

	BaroclinicWaveUMJSTest::PerturbationType ePerturbationType;
	STLStringHelper::ToLower(strPerturbationType);
	if (strPerturbationType == "none") {
		ePerturbationType = BaroclinicWaveUMJSTest::PerturbationType_None;
	} else if (strPerturbationType == "exp") {
		ePerturbationType = BaroclinicWaveUMJSTest::PerturbationType_Exp;
	} else if (strPerturbationType == "sfn") {
		ePerturbationType = BaroclinicWaveUMJSTest::PerturbationType_StreamFn;
	} else {
		_EXCEPTIONT("Invalid perturbation type:"
			" Expected \"None\", \"Exp\" or \"SFn\"");
	}

	model.SetTestCase(
		new BaroclinicWaveUMJSTest(
			dAlpha,
			fDeepAtmosphere,
			dZtop,
			ePerturbationType,
			fRayleighFriction));

	AnnounceEndBlock("Done");

	// Begin execution
	AnnounceBanner("SIMULATION");
	model.Go();

	// Compute error norms
	AnnounceBanner("RESULTS");
	model.ComputeErrorNorms();
	AnnounceBanner();

} catch(Exception & e) {
	std::cout << e.ToString() << std::endl;
}

	// Deinitialize
	TempestDeinitialize();
}
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) {

	// Initialize Tempest
	TempestInitialize(&argc, &argv);

try {
	// Nondimensional vertical width parameter
	double dbC;
	
	// Uniform zonal velocity
	double dU0;

	// Magnitude of the zonal wind perturbation
	double dUp;

	// Lapse rate
	double ddTdz;

	// Reference absolute temperature
	double dT0;

	// Width parameter for the perturbation
	double dLpC;

	// Center position of the perturbation
	double dXC;

	// Center position of the perturbation
	double dYC;

	// No Rayleigh friction
	bool fNoRayleighFriction;

	// Parse the command line
	BeginTempestCommandLine("Baroclinic3DCartesianTest");
		SetDefaultResolutionX(288);
		SetDefaultResolutionY(48);
		SetDefaultLevels(32);
		SetDefaultOutputDeltaT("3h");
		SetDefaultDeltaT("300s");
		SetDefaultEndTime("12d");
		SetDefaultHorizontalOrder(4);
		SetDefaultVerticalOrder(1);

		CommandLineDouble(dbC, "b", 2.0);
		CommandLineDouble(dU0, "u0", 35.0);
		CommandLineDouble(dUp, "up", 1.0);
		CommandLineDouble(ddTdz, "gamma", 0.005);
		CommandLineDouble(dT0, "T0", 288.0);
		CommandLineDouble(dLpC, "Lp", 600000.0);
		CommandLineDouble(dXC, "Xc", 2000000.0);
		CommandLineDouble(dYC, "Yc", 2500000.0);
		CommandLineBool(fNoRayleighFriction, "norayleigh");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	// Create a new instance of the test
	Baroclinic3DCartesianTest * test =
		new Baroclinic3DCartesianTest(dbC,
		        dU0,
        		dUp,
	        	ddTdz,
        		dT0,
	        	dLpC,
	        	dXC,
	        	dYC,
	        	fNoRayleighFriction);

	// Setup the Model
	AnnounceBanner("MODEL SETUP");

	Model model(EquationSet::PrimitiveNonhydrostaticEquations);
	
	// Setup the cartesian model with dimensions and reference latitude
	TempestSetupCartesianModel(model, test->m_dGDim, test->m_dRefLat, 
                                   test->m_iLatBC);

	// Set the reference length to reduce diffusion relative to global scale
	const double XL = std::abs(test->m_dGDim[1] - test->m_dGDim[0]);
	const double oneDegScale = 110000.0;
	if (XL < oneDegScale) {
		model.GetGrid()->SetReferenceLength(XL);
	}
	else {
		model.GetGrid()->SetReferenceLength(oneDegScale);
	}

	// Set the test case for the model
	AnnounceStartBlock("Initializing test case");
	model.SetTestCase(test);
	AnnounceEndBlock("Done");

	// Begin execution
	AnnounceBanner("SIMULATION");
	model.Go();

	// Compute error norms
	AnnounceBanner("RESULTS");
	model.ComputeErrorNorms();
	AnnounceBanner();

} catch(Exception & e) {
	std::cout << e.ToString() << std::endl;
        std::cout << "Try/catch block in the main program!" << std::endl;
}

	// Deinitialize Tempest
	TempestDeinitialize();
}
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();
}
Ejemplo n.º 8
0
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);
}
}
Ejemplo n.º 9
0
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) {

	// Initialize Tempest
	TempestInitialize(&argc, &argv);

try {
	// Uniform +X flow field.
	double dU0;

	// Reference temperature
	double dT0;

	// Parameter reference height for temperature disturbance
	double dhC;

	// Parameter reference length a for temperature disturbance
	double daC;

	// Parameter reference length for mountain profile
	double dxC;

	// Parameter Archimede's Constant (essentially Pi but to some digits)
	double dpiC;

	// No Rayleigh friction
	bool fNoRayleighFriction;


	// Parse the command line
	BeginTempestCommandLine("HydrostaticMountainCartesianTest");
		SetDefaultResolutionX(40);
		SetDefaultResolutionY(1);
		SetDefaultLevels(48);
		SetDefaultOutputDeltaT("1800s");
		SetDefaultDeltaT("1s");
		SetDefaultEndTime("36000s");
		SetDefaultHorizontalOrder(4);
		SetDefaultVerticalOrder(4);

		CommandLineDouble(dU0, "u0", 20.0);
		CommandLineDouble(dT0, "T0", 250.0);
		CommandLineDouble(dhC, "hC", 1.0);
		CommandLineDouble(daC, "aC", 10000.0);
		CommandLineDouble(dxC, "xC", 1.2E+5);
		CommandLineDouble(dpiC, "piC", 3.14159265);
		CommandLineBool(fNoRayleighFriction, "norayleigh");

		ParseCommandLine(argc, argv);
	EndCommandLine(argv)

	// Create a new instance of the test
	HydrostaticMountainCartesianTest * test =
		new HydrostaticMountainCartesianTest(
			dT0,
			dU0,
			dhC,
			dxC,
			daC, 
			dpiC,
			fNoRayleighFriction);

	// Setup the Model
	AnnounceBanner("MODEL SETUP");

	Model model(EquationSet::PrimitiveNonhydrostaticEquations);

	// Setup the cartesian model with dimensions and reference latitude
	TempestSetupCartesianModel(model, test->m_dGDim, 0.0, 
                                   test->m_iLatBC);

	// Set the reference length to reduce diffusion relative to global scale
	const double XL = std::abs(test->m_dGDim[1] - test->m_dGDim[0]);
	const double oneDegScale = 110000.0;
	if (XL < oneDegScale) {
		model.GetGrid()->SetReferenceLength(XL);
	}
	else {
		model.GetGrid()->SetReferenceLength(oneDegScale);
	}

	// Set the test case for the model
	AnnounceStartBlock("Initializing test case");
	model.SetTestCase(test);
	AnnounceEndBlock("Done");

	// Begin execution
	AnnounceBanner("SIMULATION");
	model.Go();

	// Compute error norms
	AnnounceBanner("RESULTS");
	model.ComputeErrorNorms();
	AnnounceBanner();

} catch(Exception & e) {
	std::cout << e.ToString() << std::endl;
}

	// Deinitialize Tempest
	TempestDeinitialize();
}
Ejemplo n.º 11
0
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) {

	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) {

	// Initialize MPI
	TempestInitialize(&argc, &argv);

try {
	// Model height cap.
	double dZtop;

	// Model scaling parameter
	double dEarthScaling;

	// Rotation rate of the Earth with X = 1.
	double dOmega;

	// Reference temperature.
	double dT0;

	// Temperature lapse rate.
	double dGamma;

	// Longitude of Schar-type mountain centerpoint.
	double dLonM;

	// Latitude of Schar-type mountain centerpoint.
	double dLatM;

	// Maximum Schar-type mountain height.
	double dH0;

	// Schar-type mountain radius (radians).
	double dRM;

	// Schar-type mountain oscillation half-width (radians).
	double dZetaM;

	// Parse the command line
	BeginTempestCommandLine("StationaryMountainFlowTest");
		SetDefaultResolution(30);
		SetDefaultLevels(30);
		SetDefaultOutputDeltaT("1d");
		SetDefaultDeltaT("300s");
		SetDefaultEndTime("6d");
		SetDefaultHorizontalOrder(4);
		SetDefaultVerticalOrder(1);

		CommandLineDouble(dZtop, "ztop", 30000.0);
		CommandLineDouble(dEarthScaling, "X", 1.0);
		CommandLineDouble(dOmega, "omega", 0.0);
		CommandLineDouble(dT0, "T0", 300.0);
		CommandLineDouble(dGamma, "Gamma", 0.0065);
		CommandLineDouble(dLonM, "lonm", 270.0);
		CommandLineDouble(dLatM, "latm", 0.0);
		CommandLineDouble(dH0, "h0", 2000.0);
		CommandLineDouble(dRM, "rm", 135.0);
		CommandLineDouble(dZetaM, "zetam", 11.25);

		ParseCommandLine(argc, argv);
	EndTempestCommandLine(argv)

	// Setup the Model
	AnnounceBanner("MODEL SETUP");

	Model model(EquationSet::PrimitiveNonhydrostaticEquations);

	TempestSetupCubedSphereModel(model);

	// Set the test case for the model
	AnnounceStartBlock("Initializing test case");

	model.SetTestCase(
		new StationaryMountainFlowTest(
			dZtop,
			dEarthScaling,
			dOmega,
			dT0,
			dGamma,
			dLonM,
			dLatM,
			dH0,
			dRM,
			dZetaM));

	AnnounceEndBlock("Done");

	// Set the reference length
	model.GetGrid()->SetReferenceLength(0.5 * M_PI / 30.0 * dEarthScaling);

	// Begin execution
	AnnounceBanner("SIMULATION");
	model.Go();

	// Compute error norms
	AnnounceBanner("RESULTS");
	model.ComputeErrorNorms();
	AnnounceBanner();

} catch(Exception & e) {
	std::cout << e.ToString() << std::endl;
}

	// Deinitialize Tempest
	TempestDeinitialize();
}
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) {

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) {

	// Initialize Tempest
	TempestInitialize(&argc, &argv);
	

try {
	// Model cap.
	double dZtop;

	// Earth radius scaling parameter.
	double dEarthScaling;

	// Deactivate physics
	bool fNoPhysics;

	// Bryan Boundary Layer
	bool fBryanPBL;

	// Reed-Jablonowksi precipitation
	bool fReedJablonowskiPrecip;

	// Parse the command line
	BeginTempestCommandLine("TropicalCycloneTest");
		SetDefaultResolution(20);
		SetDefaultLevels(30);
		SetDefaultOutputDeltaT("1h");
		SetDefaultDeltaT("200s");
		SetDefaultEndTime("10d");
		SetDefaultHorizontalOrder(4);
		SetDefaultVerticalOrder(1);

		CommandLineDouble(dZtop, "ztop", 30000.0);
		CommandLineDouble(dEarthScaling, "X", 1.0);
		CommandLineBool(fNoPhysics, "nophys");
		CommandLineBool(fBryanPBL, "bryanpbl");
		CommandLineBool(fReedJablonowskiPrecip, "rjprecip");

		ParseCommandLine(argc, argv);
	EndTempestCommandLine(argv)

	// Setup the Model
	AnnounceBanner("MODEL SETUP");

	EquationSet eqn(EquationSet::PrimitiveNonhydrostaticEquations);
 
	eqn.InsertTracer("RhoQv", "RhoQv");
	eqn.InsertTracer("RhoQc", "RhoQc");
	eqn.InsertTracer("RhoQr", "RhoQr");

	UserDataMeta metaUserData;

	metaUserData.InsertDataItem2D("PRECT");

	Model model(eqn, metaUserData);

	TempestSetupCubedSphereModel(model);

	// Set the test case for the model
	AnnounceStartBlock("Initializing test case");
	model.SetTestCase(
			new TropicalCycloneTest(
			dZtop,
			dEarthScaling));
	AnnounceEndBlock("Done");

	// Add DCMIP physics
	if (!fNoPhysics) {
		model.AttachWorkflowProcess(
			new DCMIPPhysics(
				model,
				model.GetDeltaT(),
				2,
				(fBryanPBL)?(1):(0),
				(fReedJablonowskiPrecip)?(1):(0)));
	}

	// Begin execution
	AnnounceBanner("SIMULATION");
	model.Go();

	// Compute error norms
	AnnounceBanner("RESULTS");
	model.ComputeErrorNorms();
	AnnounceBanner();

} catch(Exception & e) {
	std::cout << e.ToString() << std::endl;
}

	// Deinitialize Tempest
	TempestDeinitialize();
}
Ejemplo n.º 17
0
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){
  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;
  }
}
Ejemplo n.º 19
0
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());
}
}