-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP -- generate valid value masks from surface pressure #625
Open
burlen
wants to merge
1
commit into
develop
Choose a base branch
from
pressure_mask
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
#include "teca_surface_pressure_estimate.h" | ||
|
||
#include "teca_mesh.h" | ||
#include "teca_array_collection.h" | ||
#include "teca_variant_array.h" | ||
#include "teca_metadata.h" | ||
#include "teca_array_attributes.h" | ||
|
||
#include <algorithm> | ||
#include <iostream> | ||
#include <string> | ||
#include <set> | ||
#include <cmath> | ||
|
||
#if defined(TECA_HAS_BOOST) | ||
#include <boost/program_options.hpp> | ||
#endif | ||
|
||
//#define TECA_DEBUG | ||
|
||
namespace internal | ||
{ | ||
template <typename num_t, typename coord_t> | ||
void compute_surface_pressure(size_t n_elem, const num_t *tas, | ||
const num_t *psl, coord_t *z, num_t *ps) | ||
{ | ||
num_t cp = 1.0; // kJ/kg.K | ||
num_t cv = 0.718; // kJ/kg.K | ||
num_t g = 9.81; | ||
num_t GAM = -g / cp; | ||
num_t gam = cp / cv; | ||
num_t gam_o_gam_m_1 = gam / (gam - num_t(1)); | ||
|
||
for (size_t i = 0; i < n_elem; ++i) | ||
{ | ||
num_t zi = z[i]; | ||
ps[i] = psl[i] * pow( num_t(1) + | ||
GAM * zi / ( tas[i] - GAM *zi ), gam_o_gam_m_1 ); | ||
} | ||
} | ||
} | ||
|
||
|
||
// -------------------------------------------------------------------------- | ||
teca_surface_pressure_estimate::teca_surface_pressure_estimate() : | ||
surface_temperature_variable("tas"), sea_level_pressure_variable("psl"), | ||
surface_elevation_variable("z"), surface_pressure_variable("ps") | ||
{ | ||
this->set_number_of_input_connections(1); | ||
this->set_number_of_output_ports(1); | ||
} | ||
|
||
// -------------------------------------------------------------------------- | ||
teca_surface_pressure_estimate::~teca_surface_pressure_estimate() | ||
{} | ||
|
||
#if defined(TECA_HAS_BOOST) | ||
// -------------------------------------------------------------------------- | ||
void teca_surface_pressure_estimate::get_properties_description( | ||
const std::string &prefix, options_description &global_opts) | ||
{ | ||
options_description opts("Options for " | ||
+ (prefix.empty()?"teca_surface_pressure_estimate":prefix)); | ||
|
||
opts.add_options() | ||
TECA_POPTS_GET(std::string, prefix, surface_temperature_variable, | ||
"array containg the surface temperature field") | ||
TECA_POPTS_GET(std::string, prefix, sea_level_pressure_variable, | ||
"array containg the mean sea level pressure field") | ||
TECA_POPTS_GET(std::string, prefix, surface_elevation_variable, | ||
"array containg the surface elevation field") | ||
TECA_POPTS_GET(std::string, prefix, surface_pressure_variable, | ||
"array to store the computed surface pressure in") | ||
; | ||
|
||
this->teca_algorithm::get_properties_description(prefix, opts); | ||
|
||
global_opts.add(opts); | ||
} | ||
|
||
// -------------------------------------------------------------------------- | ||
void teca_surface_pressure_estimate::set_properties( | ||
const std::string &prefix, variables_map &opts) | ||
{ | ||
this->teca_algorithm::set_properties(prefix, opts); | ||
|
||
TECA_POPTS_SET(opts, std::string, prefix, surface_temperature_variable) | ||
TECA_POPTS_SET(opts, std::string, prefix, sea_level_pressure_variable) | ||
TECA_POPTS_SET(opts, std::string, prefix, surface_elevation_variable) | ||
TECA_POPTS_SET(opts, std::string, prefix, surface_pressure_variable) | ||
} | ||
#endif | ||
|
||
// -------------------------------------------------------------------------- | ||
teca_metadata teca_surface_pressure_estimate::get_output_metadata( | ||
unsigned int port, | ||
const std::vector<teca_metadata> &input_md) | ||
{ | ||
#ifdef TECA_DEBUG | ||
std::cerr << teca_parallel_id() | ||
<< "teca_surface_pressure_estimate::get_output_metadata" << std::endl; | ||
#endif | ||
(void)port; | ||
|
||
// pass existing metadata | ||
teca_metadata out_md(input_md[0]); | ||
|
||
// add in the array we will generate | ||
out_md.append("variables", this->surface_pressure_variable); | ||
|
||
// insert attributes to enable this to be written by the CF writer | ||
teca_metadata attributes; | ||
out_md.get("attributes", attributes); | ||
|
||
teca_metadata psl_atts; | ||
if (attributes.get(this->sea_level_pressure_variable, psl_atts)) | ||
{ | ||
TECA_WARNING("Failed to get seal level pressure \"" | ||
<< this->sea_level_pressure_variable | ||
<< "\" attrbibutes. Writing the result will not be possible") | ||
} | ||
else | ||
{ | ||
// copy the attributes from the input. this will capture the | ||
// data type, size, units, etc. | ||
teca_array_attributes ps_atts(psl_atts); | ||
|
||
// update name, long_name, and description. | ||
ps_atts.long_name = this->surface_pressure_variable; | ||
|
||
ps_atts.description = std::string("Surface pressure estimated from " + | ||
this->sea_level_pressure_variable + ", " + this->surface_temperature_variable + | ||
", and " + this->surface_elevation_variable); | ||
|
||
attributes.set(this->surface_pressure_variable, (teca_metadata)ps_atts); | ||
out_md.set("attributes", attributes); | ||
} | ||
|
||
return out_md; | ||
} | ||
|
||
// -------------------------------------------------------------------------- | ||
std::vector<teca_metadata> teca_surface_pressure_estimate::get_upstream_request( | ||
unsigned int port, | ||
const std::vector<teca_metadata> &input_md, | ||
const teca_metadata &request) | ||
{ | ||
(void)port; | ||
(void)input_md; | ||
|
||
std::vector<teca_metadata> up_reqs; | ||
|
||
// copy the incoming request to preserve the downstream | ||
// requirements and add the arrays we need | ||
teca_metadata req(request); | ||
|
||
std::set<std::string> arrays; | ||
if (req.has("arrays")) | ||
req.get("arrays", arrays); | ||
|
||
arrays.insert(this->surface_temperature_variable); | ||
arrays.insert(this->sea_level_pressure_variable); | ||
arrays.insert(this->surface_elevation_variable); | ||
|
||
// intercept request for our output | ||
arrays.erase(this->surface_pressure_variable); | ||
|
||
req.set("arrays", arrays); | ||
up_reqs.push_back(req); | ||
|
||
return up_reqs; | ||
} | ||
|
||
// -------------------------------------------------------------------------- | ||
const_p_teca_dataset teca_surface_pressure_estimate::execute( | ||
unsigned int port, | ||
const std::vector<const_p_teca_dataset> &input_data, | ||
const teca_metadata &request) | ||
{ | ||
#ifdef TECA_DEBUG | ||
std::cerr << teca_parallel_id() << "teca_surface_pressure_estimate::execute" << std::endl; | ||
#endif | ||
(void)port; | ||
(void)request; | ||
|
||
// get the input mesh | ||
const_p_teca_mesh in_mesh | ||
= std::dynamic_pointer_cast<const teca_mesh>(input_data[0]); | ||
|
||
if (!in_mesh) | ||
{ | ||
TECA_ERROR("Failed to compute surface pressure. The dataset is" | ||
" not a teca_mesh") | ||
return nullptr; | ||
} | ||
|
||
// get the surface temperature | ||
const_p_teca_variant_array tas | ||
= in_mesh->get_point_arrays()->get(this->surface_temperature_variable); | ||
if (!tas) | ||
{ | ||
TECA_ERROR("surface temperature array \"" | ||
<< this->surface_temperature_variable << "\" was not found.") | ||
return nullptr; | ||
} | ||
|
||
// get the sea level pressure | ||
const_p_teca_variant_array psl = nullptr; | ||
if (!this->sea_level_pressure_variable.empty() && | ||
!(psl = in_mesh->get_point_arrays()->get(this->sea_level_pressure_variable))) | ||
{ | ||
TECA_ERROR("sea level pressure array \"" | ||
<< this->sea_level_pressure_variable << "\" was not found.") | ||
return nullptr; | ||
} | ||
|
||
// get the surface elevation | ||
const_p_teca_variant_array z = nullptr; | ||
if (!this->surface_elevation_variable.empty() && | ||
!(z = in_mesh->get_point_arrays()->get(this->surface_elevation_variable))) | ||
{ | ||
TECA_ERROR("surface elevation array \"" | ||
<< this->surface_elevation_variable << "\" was not found.") | ||
return nullptr; | ||
} | ||
|
||
// allocate the output array | ||
unsigned long n = psl->size(); | ||
p_teca_variant_array ps = psl->new_instance(); | ||
ps->resize(n); | ||
|
||
// compute the surface pressure | ||
NESTED_TEMPLATE_DISPATCH_FP( | ||
teca_variant_array_impl, | ||
ps.get(), | ||
_DATA, | ||
|
||
const NT_DATA *p_tas = static_cast<const TT_DATA*>(tas.get())->get(); | ||
const NT_DATA *p_psl = static_cast<const TT_DATA*>(psl.get())->get(); | ||
NT_DATA *p_ps = static_cast<TT_DATA*>(ps.get())->get(); | ||
|
||
NESTED_TEMPLATE_DISPATCH_FP( | ||
const teca_variant_array_impl, | ||
z.get(), | ||
_COORD, | ||
|
||
const NT_COORD *p_z = static_cast<const TT_COORD*>(z.get())->get(); | ||
|
||
internal::compute_surface_pressure(n, p_tas, p_psl, p_z, p_ps); | ||
) | ||
) | ||
|
||
// create the output mesh, pass everything through, and | ||
// add the l2 norm array | ||
p_teca_mesh out_mesh = std::static_pointer_cast<teca_mesh> | ||
(std::const_pointer_cast<teca_mesh>(in_mesh)->new_shallow_copy()); | ||
|
||
out_mesh->get_point_arrays()->set( | ||
this->surface_pressure_variable, ps); | ||
|
||
return out_mesh; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#ifndef teca_surface_pressure_estimate_h | ||
#define teca_surface_pressure_estimate_h | ||
|
||
#include "teca_shared_object.h" | ||
#include "teca_algorithm.h" | ||
#include "teca_metadata.h" | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
TECA_SHARED_OBJECT_FORWARD_DECL(teca_surface_pressure_estimate) | ||
|
||
/** @breif | ||
* An algorithm that computes an estimate surface pressure from mean sea level | ||
* pressure, surface temperature, and surface elevation and the dry adiabatic | ||
* lapse rate. | ||
*/ | ||
class teca_surface_pressure_estimate : public teca_algorithm | ||
{ | ||
public: | ||
TECA_ALGORITHM_STATIC_NEW(teca_surface_pressure_estimate) | ||
TECA_ALGORITHM_DELETE_COPY_ASSIGN(teca_surface_pressure_estimate) | ||
TECA_ALGORITHM_CLASS_NAME(teca_surface_pressure_estimate) | ||
~teca_surface_pressure_estimate(); | ||
|
||
// report/initialize to/from Boost program options | ||
// objects. | ||
TECA_GET_ALGORITHM_PROPERTIES_DESCRIPTION() | ||
TECA_SET_ALGORITHM_PROPERTIES() | ||
|
||
/** @name surface_temperature_variable | ||
* The name of the array that contains the surface temperature field. | ||
* The default is "tas" | ||
*/ | ||
///@{ | ||
TECA_ALGORITHM_PROPERTY(std::string, surface_temperature_variable) | ||
///@} | ||
|
||
/** @name sea_level_pressure_variable | ||
* The name of the array that contains the mean sea level pressure field. | ||
* The default is "psl" | ||
*/ | ||
///@{ | ||
TECA_ALGORITHM_PROPERTY(std::string, sea_level_pressure_variable) | ||
///@} | ||
|
||
/** @name surface_elevation_variable | ||
* The name of the array that contains the surface elevation field. | ||
* The default is "z" | ||
*/ | ||
///@{ | ||
TECA_ALGORITHM_PROPERTY(std::string, surface_elevation_variable) | ||
///@} | ||
|
||
|
||
/** @name surface_pressure_variable | ||
* set the name of the array to store the computed surface pressure in. | ||
* the default is "ps" | ||
*/ | ||
///@{ | ||
TECA_ALGORITHM_PROPERTY(std::string, surface_pressure_variable) | ||
///@} | ||
|
||
protected: | ||
teca_surface_pressure_estimate(); | ||
|
||
private: | ||
teca_metadata get_output_metadata( | ||
unsigned int port, | ||
const std::vector<teca_metadata> &input_md) override; | ||
|
||
std::vector<teca_metadata> get_upstream_request( | ||
unsigned int port, | ||
const std::vector<teca_metadata> &input_md, | ||
const teca_metadata &request) override; | ||
|
||
const_p_teca_dataset execute( | ||
unsigned int port, | ||
const std::vector<const_p_teca_dataset> &input_data, | ||
const teca_metadata &request) override; | ||
|
||
private: | ||
std::string surface_temperature_variable; | ||
std::string sea_level_pressure_variable; | ||
std::string surface_elevation_variable; | ||
std::string surface_pressure_variable; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cp and cv should be in units of J/Kg/K. This would matter for
gam
since the units cancel, but it does matter for theGAM * zi
parts.I suggest
cp=1004.
andcv = 718.
as the values used