22 #include <gsl/gsl_math.h>
24 #include "pism/earth/matlablike.hh"
25 #include "pism/earth/greens.hh"
26 #include "pism/earth/LingleClarkSerial.hh"
28 #include "pism/util/ConfigInterface.hh"
29 #include "pism/util/error_handling.hh"
30 #include "pism/util/petscwrappers/Vec.hh"
31 #include "pism/util/fftw_utilities.hh"
57 if (include_elastic) {
62 if (config.
get_number(
"bed_deformation.lc.grid_size_factor") < 2) {
64 "bed_deformation.lc.elastic_model"
65 " requires bed_deformation.lc.grid_size_factor > 1");
80 m_D = config.
get_number(
"bed_deformation.lithosphere_flexural_rigidity");
91 PetscErrorCode ierr = 0;
113 FFTW_FORWARD, FFTW_ESTIMATE);
115 FFTW_BACKWARD, FFTW_ESTIMATE);
168 for (
int j = 0; j <= Ny2; ++j) {
170 for (
int i = 0; i <= Nx2; ++i) {
197 for (
int i = Nx2 + 1; i <
m_Nx; ++i) {
198 assert(2 * Nx2 - i >= 0);
199 LRM(i, j) = LRM(2 * Nx2 - i, j);
206 for (
int j = Ny2 + 1; j <
m_Ny; ++j) {
207 for (
int i = 0; i <
m_Nx; ++i) {
208 assert(2 * Ny2 - j >= 0);
209 LRM(i, j) = LRM(i, 2 * Ny2 - j);
226 m_log->message(2,
" computing spherical elastic load response matrix ...");
233 m_log->message(2,
" done\n");
280 for (
int i = 0; i <
m_Nx; i++) {
281 for (
int j = 0; j <
m_Ny; j++) {
284 A = - 2.0 *
m_eta * sqrt(
C),
287 u0_hat(i, j) = (load_hat(i, j) + A * uplift_hat(i, j)) / B;
325 PetscErrorCode ierr = VecSet(
m_Ue, 0.0);
PISM_CHK(ierr,
"VecSet");
341 PetscErrorCode ierr = 0;
399 for (
int i = 0; i <
m_Nx; i++) {
400 for (
int j = 0; j <
m_Ny; j++) {
403 part1 = 2.0 *
m_eta * sqrt(
C),
408 input(i, j) = (load_hat(i, j) + A * u_hat(i, j)) / B;
422 PetscErrorCode ierr = VecSet(
m_Uv, 0.0);
PISM_CHK(ierr,
"VecSet");
460 for (
int i = 0; i <
m_Nx; i++) {
461 for (
int j = 0; j <
m_Ny; j++) {
462 input(i, j) = LRM_hat(i, j) * load_hat(i, j);
492 for (
int i = 0; i <
m_Mx; i++) {
493 for (
int j = 0; j <
m_My; j++) {
494 u(i, j) = u_viscous(i, j) + u_elastic(i, j);
513 PetscErrorCode ierr = 0;
519 double average = 0.0;
520 for (
int i = 0; i < Nx; i++) {
524 for (
int j = 0; j < Ny; j++) {
528 average /= (double) (Nx + Ny);
536 const double L_average = (
m_Lx +
m_Ly) / 2.0;
537 const double R = L_average * (2.0 / 3.0);
540 ierr = VecSum(load_thickness, &H_sum);
PISM_CHK(ierr,
"VecSum");
543 const double H = (H_sum *
m_dx *
m_dy) / (M_PI * R * R);
555 ierr = VecShift(U, shift - average);
PISM_CHK(ierr,
"VecShift");
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
std::shared_ptr< const Logger > ConstPtr
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
void uplift_problem(petsc::Vec &load_thickness, petsc::Vec &bed_uplift, petsc::Vec &output)
void update_displacement(petsc::Vec &V, petsc::Vec &dE, petsc::Vec &dU)
LingleClarkSerial(Logger::ConstPtr log, const Config &config, bool include_elastic, int Mx, int My, double dx, double dy, int Nx, int Ny)
void step(double dt_seconds, petsc::Vec &H)
const petsc::Vec & viscous_displacement() const
void tweak(petsc::Vec &load_thickness, petsc::Vec &U, int Nx, int Ny, double time)
fftw_complex * m_fftw_input
double m_D
lithosphere flexural rigidity
void bootstrap(petsc::Vec &thickness, petsc::Vec &uplift)
void precompute_coefficients()
void compute_elastic_response(petsc::Vec &H, petsc::Vec &dE)
double m_mantle_density
mantle density
std::vector< double > m_cy
void compute_load_response_matrix(fftw_complex *output)
void init(petsc::Vec &viscous_displacement, petsc::Vec &elastic_displacement)
const petsc::Vec & elastic_displacement() const
const petsc::Vec & total_displacement() const
fftw_complex * m_fftw_output
double m_eta
mantle viscosity
double m_standard_gravity
double m_load_density
load density (for computing load from its thickness)
std::vector< double > m_cx
Wrapper around VecGetArray2d and VecRestoreArray2d.
#define PISM_CHK(errcode, name)
#define PISM_ERROR_LOCATION
double dblquad_cubature(integrand f, double ax, double bx, double ay, double by, double reqRelError, void *fdata)
double ge_integrand(unsigned ndim, const double *args, void *data)
The integrand in defining the elastic Green's function from the [Farrell] earth model.
double viscDisc(double t, double H0, double R0, double r, double rho, double rho_ice, double grav, double D, double eta)
Actually compute the response of the viscous half-space model in LingleClark, to a disc load.
void clear_fftw_array(fftw_complex *input, int Nx, int Ny)
Fill input with zeros.
void copy_fftw_array(fftw_complex *source, fftw_complex *destination, int Nx, int Ny)
Copy source to destination.
void get_real_part(fftw_complex *input, double normalization, int Mx, int My, int Nx, int Ny, int i0, int j0, petsc::Vec &output)
Get the real part of input and put it in output.
void set_real_part(petsc::Vec &input, double normalization, int Mx, int My, int Nx, int Ny, int i0, int j0, fftw_complex *output)
std::vector< double > fftfreq(int M, double normalization)
Parameters used to access elastic Green's function from the [Farrell] earth model.