21 #include "pism/stressbalance/sia/BedSmoother.hh"
22 #include "pism/util/Context.hh"
23 #include "pism/util/Grid.hh"
24 #include "pism/util/Logger.hh"
25 #include "pism/util/array/CellType.hh"
26 #include "pism/util/error_handling.hh"
27 #include "pism/util/petscwrappers/Vec.hh"
28 #include "pism/util/pism_utilities.hh"
29 #include "pism/util/VariableMetadata.hh"
32 namespace stressbalance {
36 m_config(
g->ctx()->config()),
37 m_topgsmooth(m_grid,
"topgsmooth"),
38 m_maxtl(m_grid,
"maxtl"),
39 m_C2(m_grid,
"C2bedsmooth"),
40 m_C3(m_grid,
"C3bedsmooth"),
41 m_C4(m_grid,
"C3bedsmooth")
50 .
long_name(
"smoothed bed elevation, in bed roughness parameterization")
53 .
long_name(
"maximum elevation in local topography patch, in bed roughness parameterization")
56 .
long_name(
"polynomial coeff of H^-2, in bed roughness parameterization")
59 .
long_name(
"polynomial coeff of H^-3, in bed roughness parameterization")
62 .
long_name(
"polynomial coeff of H^-4, in bed roughness parameterization")
79 "* Initializing bed smoother object with %.3f km half-width ...\n",
131 unsigned int Nx,
unsigned int Ny) {
135 "domain of smoothing exceeds Grid domain");
159 if (
m_grid->rank() == 0) {
160 const int Mx = (int)
m_grid->Mx();
161 const int My = (int)
m_grid->My();
167 for (
int j=0; j < My; j++) {
168 for (
int i=0; i < Mx; i++) {
172 for (
int r = -
m_Nx; r <=
m_Nx; r++) {
173 for (
int s = -
m_Ny; s <=
m_Ny; s++) {
174 if ((i+r >= 0) and (i+r < Mx) and (j+s >= 0) and (j+s < My)) {
194 const unsigned int Mx =
m_grid->Mx(), My =
m_grid->My();
198 if (
m_grid->rank() == 0) {
207 for (
int j=0; j < (int)My; j++) {
208 for (
int i=0; i < (int)Mx; i++) {
219 for (
int r = -
m_Nx; r <=
m_Nx; r++) {
220 for (
int s = -
m_Ny; s <=
m_Ny; s++) {
221 if ((i+r >= 0) && (i+r < (
int)Mx) && (j+s >= 0) && (j+s < (
int)My)) {
223 const double tl =
b0(i+r, j+s) - topgs;
224 maxtltemp =
std::max(maxtltemp, tl);
226 const double tl2 = tl * tl;
234 mt(i, j) = maxtltemp;
238 c3(i, j) = sum3 /
count;
239 c4(i, j) = sum4 /
count;
247 s2 =
k * (2 *
n + 2) / (2 *
n),
248 s3 = s2 * (3 *
n + 2) / (3 *
n),
249 s4 = s3 * (4 *
n + 2) / (4 *
n);
252 ierr = VecScale(*
m_C2p0,s2);
255 ierr = VecScale(*
m_C3p0,s3);
258 ierr = VecScale(*
m_C4p0,s4);
298 for (
auto p =
m_grid->points(GHOSTS); p; p.next()) {
299 const int i = p.i(), j = p.j();
301 if (thk(i, j) < 0.0) {
303 "at location (i, j) = (%d, %d) ... ending", i, j);
306 if (thk(i, j) == 0.0) {
308 }
else if (
m_maxtl(i, j) >= thk(i, j)) {
309 result(i, j) = thk(i, j);
318 result(i, j) = thk(i, j);
368 theta_min =
m_config->get_number(
"stress_balance.sia.bed_smoother.theta_min"),
373 for (
auto p =
m_grid->points(GHOSTS); p; p.next()) {
374 const int i = p.i(), j = p.j();
380 const double Hinv = 1.0 /
std::max(H, 1.0);
381 double omega = 1.0 + Hinv*Hinv * (
m_C2(i, j) + Hinv * (
m_C3(i, j) + Hinv*
m_C4(i, j)));
384 "omega is negative for i=%d, j=%d\n"
385 "in BedSmoother.theta()", i, j);
397 result(i, j) =
clip(result(i, j), theta_min, theta_max);
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
void failed()
Indicates a failure of a parallel section.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
void get_from_proc0(petsc::Vec &onp0)
Gets a local Array2 from processor 0.
void set(double c)
Result: v[j] <- c for all j.
std::shared_ptr< petsc::Vec > allocate_proc0_copy() const
void put_on_proc0(petsc::Vec &onp0) const
Puts a local array::Scalar on processor 0.
unsigned int stencil_width() const
Get the stencil width of the current Array. Returns 0 if ghosts are not available.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
bool grounded(int i, int j) const
Wrapper around VecGetArray2d and VecRestoreArray2d.
std::shared_ptr< petsc::Vec > m_C3p0
BedSmoother(std::shared_ptr< const Grid > g)
void smoothed_thk(const array::Scalar &usurf, const array::Scalar &thk, const array::CellType2 &mask, array::Scalar &thksmooth) const
Computes a smoothed thickness map.
std::shared_ptr< petsc::Vec > m_topgp0
original bed elevation on processor 0
array::Scalar2 m_topgsmooth
smoothed bed elevation; set by calling preprocess_bed()
std::shared_ptr< petsc::Vec > m_maxtlp0
maximum elevation at (i,j) of local topography (nearby patch)
void smooth_the_bed_on_proc0()
Computes the smoothed bed by a simple average over a rectangle of grid points.
const array::Scalar & smoothed_bed() const
void theta(const array::Scalar &usurf, array::Scalar &result) const
void compute_coefficients_on_proc0()
const Config::ConstPtr m_config
std::shared_ptr< petsc::Vec > m_topgsmoothp0
smoothed bed elevation on processor 0
std::shared_ptr< petsc::Vec > m_C4p0
std::shared_ptr< const Grid > m_grid
void preprocess_bed(const array::Scalar &topg)
std::shared_ptr< petsc::Vec > m_C2p0
#define PISM_CHK(errcode, name)
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double sum(const array::Scalar &input)
Sums up all the values in an array::Scalar object. Ignores ghosts.
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.