PISM, A Parallel Ice Sheet Model  stable v0.5
src/base/rheology/flowlaws.hh
Go to the documentation of this file.
00001 // Copyright (C) 2004-2012 Jed Brown, Ed Bueler, and Constantine Khroulev
00002 //
00003 // This file is part of PISM.
00004 //
00005 // PISM is free software; you can redistribute it and/or modify it under the
00006 // terms of the GNU General Public License as published by the Free Software
00007 // Foundation; either version 2 of the License, or (at your option) any later
00008 // version.
00009 //
00010 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
00011 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012 // FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013 // details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with PISM; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 #ifndef __flowlaws_hh
00020 #define __flowlaws_hh
00021 
00022 #include <petscsys.h>
00023 
00024 class EnthalpyConverter;
00025 class NCConfigVariable;
00026 
00027 // This uses the definition of second invariant from Hutter and several others, namely
00028 // \f$ \frac 1 2 D_{ij} D_{ij} \f$ where incompressibility is used to compute \f$ D_{zz} \f$
00029 static inline PetscReal secondInvariant(PetscReal u_x, PetscReal u_y,
00030                                         PetscReal v_x, PetscReal v_y)
00031 { return 0.5 * (PetscSqr(u_x) + PetscSqr(v_y) + PetscSqr(u_x + v_y) + 0.5*PetscSqr(u_y + v_x)); }
00032 
00033 // The second invariant of a symmetric strain rate tensor in compressed form [u_x, v_y, 0.5(u_y+v_x)]
00034 static inline PetscReal secondInvariantDu(const PetscReal Du[])
00035 { return 0.5 * (PetscSqr(Du[0]) + PetscSqr(Du[1]) + PetscSqr(Du[0]+Du[1]) + 2*PetscSqr(Du[2])); }
00036 
00037 
00040 
00057 class IceFlowLaw {
00058 public:
00059   IceFlowLaw(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00060              EnthalpyConverter *EC);
00061  virtual ~IceFlowLaw() {}
00062   virtual PetscErrorCode setFromOptions();
00063 
00064   virtual PetscReal effective_viscosity(PetscReal hardness,
00065                                         PetscReal u_x, PetscReal u_y,
00066                                         PetscReal v_x, PetscReal v_y) const;
00067 
00068   virtual void effective_viscosity_with_derivative(PetscReal hardness, const PetscReal Du[],
00069                                                    PetscReal *nu, PetscReal *dnu) const;
00070 
00071   virtual PetscReal averaged_hardness(PetscReal thickness,
00072                                       PetscInt kbelowH,
00073                                       const PetscReal *zlevels,
00074                                       const PetscReal *enthalpy) const;
00075   virtual PetscReal exponent() const { return n; }
00076   virtual PetscReal enhancement_factor() const { return e; }
00077 
00078   virtual PetscReal hardness_parameter(PetscReal E, PetscReal p) const;
00079   virtual PetscReal softness_parameter(PetscReal E, PetscReal p) const = 0;
00080   virtual PetscReal flow(PetscReal stress, PetscReal E,
00081                          PetscReal pressure, PetscReal grainsize) const;
00082 
00083 protected:
00084   PetscReal rho,          
00085     beta_CC_grad, 
00086     melting_point_temp;  
00087   EnthalpyConverter *EC;
00088 
00089   PetscReal softness_parameter_paterson_budd(PetscReal T_pa) const;
00090 
00091   PetscReal schoofLen,schoofVel,schoofReg,
00092     A_cold, A_warm, Q_cold, Q_warm,  // see Paterson & Budd (1982)
00093     crit_temp;
00094 
00095   PetscReal standard_gravity,
00096     ideal_gas_constant,
00097     e,                          // flow enhancement factor
00098     n;                          // power law exponent
00099 
00100   MPI_Comm com;
00101   char prefix[256];
00102 };
00103 
00104 // Helper functions:
00105 PetscBool IceFlowLawIsPatersonBuddCold(IceFlowLaw *, const NCConfigVariable &, EnthalpyConverter*);
00106 PetscBool IceFlowLawUsesGrainSize(IceFlowLaw *);
00107 
00109 
00113 class GPBLDIce : public IceFlowLaw {
00114 public:
00115   GPBLDIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00116            EnthalpyConverter *EC);
00117   virtual ~GPBLDIce() {}
00118 
00119   virtual PetscErrorCode setFromOptions();
00120   virtual PetscReal softness_parameter(PetscReal enthalpy,
00121                                        PetscReal pressure) const;
00122 protected:
00123   PetscReal T_0, water_frac_coeff, water_frac_observed_limit;
00124 };
00125 
00127 class ThermoGlenIce : public IceFlowLaw {
00128 public:
00129   ThermoGlenIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00130                 EnthalpyConverter *my_EC)
00131     : IceFlowLaw(c, pre, config, my_EC) {
00132     n = 3;    // Paterson-Budd has the fixed Glen exponent, so it's hard-wired.
00133   }
00134   virtual ~ThermoGlenIce() {}
00135 
00136   // This also takes care of hardness_parameter
00137   virtual PetscReal softness_parameter(PetscReal enthalpy, PetscReal pressure) const;
00138 
00139   virtual PetscReal flow(PetscReal stress, PetscReal E,
00140                          PetscReal pressure, PetscReal gs) const;
00141 
00142 protected:
00143   virtual PetscReal softness_parameter_from_temp(PetscReal T_pa) const
00144   { return softness_parameter_paterson_budd(T_pa); }
00145 
00146   virtual PetscReal hardness_parameter_from_temp(PetscReal T_pa) const
00147   { return pow(softness_parameter_from_temp(T_pa), -1.0/n); }
00148 
00149   // special temperature-dependent method
00150   virtual PetscReal flow_from_temp(PetscReal stress, PetscReal temp,
00151                                    PetscReal pressure, PetscReal gs) const;
00152 };
00153 
00155 class IsothermalGlenIce : public ThermoGlenIce {
00156 public:
00157   IsothermalGlenIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00158                     EnthalpyConverter *my_EC);
00159   virtual ~IsothermalGlenIce() {}
00160 
00161   virtual PetscReal averaged_hardness(PetscReal, PetscInt,
00162                                       const PetscReal*, const PetscReal*) const
00163   { return hardness_B; }
00164 
00165   virtual PetscReal flow(PetscReal stress, PetscReal,
00166                          PetscReal, PetscReal ) const
00167   { return softness_A * pow(stress, n-1); }
00168 
00169   virtual PetscReal softness_parameter(PetscReal, PetscReal) const
00170   { return softness_A; }
00171 
00172   virtual PetscReal hardness_parameter(PetscReal, PetscReal) const
00173   { return hardness_B; }
00174 
00175 protected:
00176   virtual PetscReal flow_from_temp(PetscReal stress, PetscReal,
00177                                    PetscReal, PetscReal ) const
00178   { return softness_A * pow(stress,n-1); }
00179 
00180 protected:
00181   PetscReal softness_A, hardness_B;
00182 };
00183 
00185 class HookeIce : public ThermoGlenIce {
00186 public:
00187   HookeIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00188            EnthalpyConverter *EC);
00189   virtual ~HookeIce() {}
00190 protected:
00191   virtual PetscReal softness_parameter_from_temp(PetscReal T_pa) const;
00192 
00193   PetscReal A_Hooke, Q_Hooke, C_Hooke, K_Hooke, Tr_Hooke; // constants from Hooke (1981)
00194   // R_Hooke is the ideal_gas_constant.
00195 };
00196 
00198 class ThermoGlenArrIce : public ThermoGlenIce {
00199 public:
00200   ThermoGlenArrIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00201                    EnthalpyConverter *my_EC)
00202     : ThermoGlenIce(c, pre, config, my_EC) {}
00203   virtual ~ThermoGlenArrIce() {}
00204 
00206   PetscReal tempFromSoftness(PetscReal myA) const
00207   { return - Q() / (ideal_gas_constant * (log(myA) - log(A()))); }
00208 
00209 protected:
00210   virtual PetscReal A() const { return A_cold; }
00211   virtual PetscReal Q() const { return Q_cold; }
00212 
00213   // takes care of hardness_parameter...
00214   virtual PetscReal softness_parameter_from_temp(PetscReal T_pa) const
00215   { return A() * exp(-Q()/(ideal_gas_constant * T_pa)); }
00216 
00217 
00218   // ignores pressure and uses non-pressure-adjusted temperature
00219   virtual PetscReal flow_from_temp(PetscReal stress, PetscReal temp,
00220                                    PetscReal , PetscReal ) const
00221   { return softness_parameter_from_temp(temp) * pow(stress,n-1); }
00222 };
00223 
00225 class ThermoGlenArrIceWarm : public ThermoGlenArrIce {
00226 public:
00227   ThermoGlenArrIceWarm(MPI_Comm c, const char pre[],
00228                        const NCConfigVariable &config, EnthalpyConverter *my_EC)
00229     : ThermoGlenArrIce(c, pre, config, my_EC) {}
00230   virtual ~ThermoGlenArrIceWarm() {}
00231 
00232 protected:
00233   virtual PetscReal A() const { return A_warm; }
00234   virtual PetscReal Q() const { return Q_warm; }
00235 };
00236 
00237 // Hybrid (Goldsby-Kohlstedt/Glen) ice flow law
00238 
00239 struct GKparts {
00240   PetscReal eps_total, eps_diff, eps_disl, eps_basal, eps_gbs;
00241 };
00242 
00243 
00245 
00252 class GoldsbyKohlstedtIce : public IceFlowLaw {
00253 public:
00254   GoldsbyKohlstedtIce(MPI_Comm c, const char pre[], const NCConfigVariable &config,
00255                       EnthalpyConverter *my_EC);
00256 
00257   virtual PetscReal flow(PetscReal stress, PetscReal E,
00258                          PetscReal pressure, PetscReal grainsize) const;
00259 
00260   virtual PetscReal effective_viscosity(PetscReal hardness,
00261                                         PetscReal u_x, PetscReal u_y,
00262                                         PetscReal v_x, PetscReal v_y) const;
00263 
00264   virtual void effective_viscosity_with_derivative(PetscReal hardness, const PetscReal Du[],
00265                                                    PetscReal *nu, PetscReal *dnu) const;
00266 
00267   virtual PetscReal averaged_hardness(PetscReal thickness,
00268                                       PetscInt kbelowH,
00269                                       const PetscReal *zlevels,
00270                                       const PetscReal *enthalpy) const;
00271 
00272   virtual PetscReal hardness_parameter(PetscReal E, PetscReal p) const;
00273 
00274   virtual PetscReal softness_parameter(PetscReal E, PetscReal p) const;
00275 
00276 protected:
00277   virtual PetscReal flow_from_temp(PetscReal stress, PetscReal temp,
00278                                    PetscReal pressure, PetscReal gs) const;
00279   GKparts flowParts(PetscReal stress, PetscReal temp, PetscReal pressure) const;
00280 
00281   PetscReal  V_act_vol,  d_grain_size,
00282              //--- diffusional flow ---
00283              diff_crit_temp, diff_V_m, diff_D_0v, diff_Q_v, diff_D_0b, diff_Q_b, diff_delta,
00284              //--- dislocation creep ---
00285              disl_crit_temp, disl_A_cold, disl_A_warm, disl_n, disl_Q_cold, disl_Q_warm,
00286              //--- easy slip (basal) ---
00287              basal_A, basal_n, basal_Q,
00288              //--- grain boundary sliding ---
00289              gbs_crit_temp, gbs_A_cold, gbs_A_warm, gbs_n, gbs_Q_cold,
00290              p_grain_sz_exp, gbs_Q_warm;
00291 };
00292 
00294 
00298 class GoldsbyKohlstedtIceStripped : public GoldsbyKohlstedtIce {
00299 public:
00300   GoldsbyKohlstedtIceStripped(MPI_Comm c, const char pre[],
00301                               const NCConfigVariable &config, EnthalpyConverter *my_EC);
00302 protected:
00303   virtual PetscReal flow_from_temp(PetscReal stress, PetscReal temp,
00304                                    PetscReal pressure, PetscReal gs) const;
00305 
00306   PetscReal d_grain_size_stripped;
00307 };
00308 
00309 #endif // __flowlaws_hh
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines