BISICLES AMR ice sheet model  0.9
PythonInterface.H
Go to the documentation of this file.
1 
2 #ifdef CH_LANG_CC
3 /*
4  * _______ __
5  * / ___/ / ___ __ _ / / ___
6  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
7  * \___/_//_/\___/_/_/_/_.__/\___/
8  * Please refer to Copyright.txt, in Chombo's root directory.
9  */
10 #endif
11 #ifdef HAVE_PYTHON
12 #ifndef _PYTHONINTERFACE_H_
13 #define _PYTHONINTERFACE_H_
14 
15 #include "Python.h"
16 #include "AmrIceBase.H"
17 #include "IceThicknessIBC.H"
18 #include "IceInternalEnergyIBC.H"
19 #include "SurfaceFlux.H"
20 #include "BasalFriction.H"
21 #include "MuCoefficient.H"
22 #include "IceVelocitySolver.H"
23 #include "VelocityBC.H"
24 #include <map>
25 #include "NamespaceHeader.H"
26 //
27 // PythonInterface.H
28 // ============
29 // BISICLES embedded Python interface. Includes
30 //
31 // PythonInterface, a namespace for common parts of the interface
32 //
33 // PythonInterface::PythonIBC, a PhysIBC-derived class which allows the bedrock and topography to be set by
34 // a user-defined python function f(x,y) . Reflection boundary conditions are imposed on
35 // each edge.
36 //
37 // PythonInterface::PythonInternalEnergyIBC, much as PythonIBC, but provides initial / boundary conditions for the internalEnergy
38 // field
39 //
40 // PythonInterface::PythonSurfaceFlux , a SurfaceFlux derived class which allows a thickness source to be set
41 // by a python function f(x,y,thickness,topography)
42 //
43 //
44 // PythonInterface::PythonVelocitySolver , an IceVelocitySolver that allows the velocity to be set by
45 // a python function f(x,y,thickness,topography)
46 
47 namespace PythonInterface
48 {
49  void InitializePythonModule(PyObject **a_pModule,
50  const std::string& a_pyModuleName);
51 
52  void InitializePythonFunction(PyObject **a_pFunc,
53  PyObject *a_pModule,
54  const std::string& a_pyFuncName );
55 
56 
60  void FillKwargs(std::map<std::string,Real>& a_kwarg,
61  const AmrIceBase& a_amrIce, int a_level,
62  const DataIterator& a_dit, const IntVect& a_iv);
63  //Evalue python function with positional and (optional) keyword args
64  void PythonEval(PyObject* a_pyFunc, Vector<Real>& a_value, Vector<Real>& a_arg, std::map<std::string, Real>* a_kwarg = NULL);
65 
67 
70  class PythonIBC : public IceThicknessIBC
71  {
72  PyObject* m_pModule;
73  PyObject* m_pFuncThck;
74  PyObject* m_pFuncTopg;
75  PyObject* m_pFuncRhs;
76  PyObject* m_pFuncFaceVel;
77 
78  enum BCType {IceDivide, NoSlip, Natural, MaxBCType};
79 
80  RefCountedPtr<CompGridVTOBC> BCFactory(BCType a_type,
81  int a_dir,
82  Side::LoHiSide a_side)
83  {
84  if (a_type == IceDivide)
85  {
86  return RefCountedPtr<CompGridVTOBC>(new IceDivideCompGridVTOBC(a_dir, a_side));
87  }
88  else if (a_type == NoSlip)
89  {
90  return RefCountedPtr<CompGridVTOBC>(new NoSlipCompGridVTOBC(a_dir, a_side));
91  }
92  else if (a_type == Natural)
93  {
94  return RefCountedPtr<CompGridVTOBC>(new NaturalCompGridVTOBC(a_dir, a_side));
95  }
96  CH_assert(a_type < MaxBCType && a_type > 0);
97  return RefCountedPtr<CompGridVTOBC>(new IceDivideCompGridVTOBC(a_dir, a_side));
98  }
99 
100  public:
101 
102  PythonIBC(const std::string& a_pyModuleName ,
103  const std::string& a_pyFuncThckName,
104  const std::string& a_pyFuncTopgName,
105  const std::string& a_pyFuncRhsName,
106  const std::string& a_pyFuncFaceVelName);
107 
108  PythonIBC();
109 
110  virtual ~PythonIBC();
111 
113 
117  virtual void define(const ProblemDomain& a_domain,
118  const Real& a_dx);
119 
121 
127 
128 
130 
132  virtual void initialize(LevelData<FArrayBox>& a_U);
133 
134  bool regridIceGeometry(LevelSigmaCS& a_coords,
135  const RealVect& a_dx,
136  const RealVect& a_domainSize,
137  const Real& a_time,
138  const LevelSigmaCS* a_crseCoords,
139  const int a_refRatio);
140 
142 
144  virtual void initializeIceGeometry(LevelSigmaCS& a_coords,
145  const RealVect& a_dx,
146  const RealVect& a_domainSize,
147  const Real& a_time,
148  const LevelSigmaCS* a_crseCoords,
149  const int a_refRatio);
150 
152 
154  virtual void modifyVelocityRHS(LevelData<FArrayBox>& a_rhs,
155  LevelSigmaCS& a_coords,
156  const ProblemDomain& a_domain,
157  Real a_time, Real a_dt);
159 
161  virtual void modifyFaceVelocity(LevelData<FluxBox>& a_faceVel,
162  const LevelSigmaCS& a_coords,
163  const ProblemDomain& a_domain) const ;
164 
166 
168  virtual void primBC(FArrayBox& a_WGdnv,
169  const FArrayBox& a_Wextrap,
170  const FArrayBox& a_W,
171  const int& a_dir,
172  const Side::LoHiSide& a_side,
173  const Real& a_time);
174 
176 
181  virtual
182  void setBdrySlopes(FArrayBox& a_dW,
183  const FArrayBox& a_W,
184  const int& a_dir,
185  const Real& a_time);
186 
188 
190  virtual
191  void artViscBC(FArrayBox& a_F,
192  const FArrayBox& a_U,
193  const FArrayBox& a_divVel,
194  const int& a_dir,
195  const Real& a_time);
196 
198 
200  virtual RefCountedPtr<CompGridVTOBC> velocitySolveBC();
201 
202 
203 
204 
206  virtual void setSurfaceHeightBCs(LevelData<FArrayBox>& a_zSurface,
207  LevelSigmaCS& a_coords,
208  const ProblemDomain& a_domain,
209  const RealVect& a_dx,
210  Real a_time, Real a_dt);
212  virtual void setGeometryBCs(LevelSigmaCS& a_coords,
213  const ProblemDomain& a_domain,
214  const RealVect& a_dx,
215  Real a_time, Real a_dt);
216 
217  virtual void setIceFractionBCs(LevelData<FArrayBox>& a_fraction,
218  const ProblemDomain& a_domain,
219  const RealVect& a_dx,
220  Real a_time, Real a_dt);
221 
222 
223  private:
224 
225  RealVect m_dx;
226  RefCountedPtr<CompGridVTOBC> m_velBC;
227  bool m_isBCsetUp;
228  bool m_verbose;
229  void setupBCs();
230 
231  private:
232  // Disallowed for all the usual reasons
233  void operator=(const PythonIBC& a_input)
234  {
235  MayDay::Error("invalid operator");
236  }
237 
238  // Disallowed for all the usual reasons
239  PythonIBC(const PythonIBC& a_input)
240  {
241  MayDay::Error("invalid operator");
242  }
243 
244  PythonIBC(PyObject* a_pModule, PyObject* a_pFuncThck,
245  PyObject* a_pFuncTopg, PyObject* a_pFuncRhs,
246  PyObject* a_pFuncFaceVel)
247  {
248  m_isBCsetUp = false;
249  m_pModule = a_pModule;
250  m_pFuncThck = a_pFuncThck;
251  m_pFuncTopg = a_pFuncTopg;
252  m_pFuncRhs = a_pFuncRhs;
253  m_pFuncFaceVel = a_pFuncFaceVel;
254  Py_XINCREF(m_pModule);
255  Py_XINCREF(m_pFuncThck);
256  Py_XINCREF(m_pFuncTopg);
257  if (m_pFuncRhs != NULL)
258  {
259  Py_XINCREF(m_pFuncRhs);
260  }
261  if (m_pFuncFaceVel != NULL)
262  {
263  Py_XINCREF(m_pFuncFaceVel);
264  }
265  }
266 
267  };
269 
293  {
294  PyObject* m_pModule;
295  PyObject* m_pFunc;
296  std::map<std::string,Real> m_kwarg;
297 
298  public:
300 
305  PythonSurfaceFlux(const std::string& a_pyModule,
306  const std::string& a_pyFunc,
307  std::map<std::string,Real>& a_kwarg);
308 
309  virtual ~PythonSurfaceFlux();
310 
311  virtual SurfaceFlux* new_surfaceFlux();
312 
313  virtual void surfaceThicknessFlux(LevelData<FArrayBox>& a_flux,
314  const AmrIceBase& a_amrIce,
315  int a_level, Real a_dt);
316 
317 
318  private:
319  // Disallowed for all the usual reasons
320  void operator=(const PythonSurfaceFlux& a_input)
321  {
322  MayDay::Error("invalid operator");
323  }
324 
325  // Disallowed for all the usual reasons
326  PythonSurfaceFlux(const PythonSurfaceFlux& a_input)
327  {
328  MayDay::Error("invalid operator");
329  }
330 
332  {
333  MayDay::Error("invalid operator");
334  }
335 
336  PythonSurfaceFlux(PyObject* a_pModule, PyObject* a_pFunc, std::map<std::string,Real>& a_kwarg)
337  {
338  m_pModule = a_pModule;
339  m_pFunc = a_pFunc;
340  Py_XINCREF(m_pModule);
341  Py_XINCREF(m_pFunc);
342  m_kwarg = a_kwarg;
343  }
344 
345 
346  };
348 
352  {
353  public:
354  virtual ~PythonIceTemperatureIBC();
355  PythonIceTemperatureIBC(const std::string& a_pyModuleName,
356  const std::string& a_pyFuncName) ;
357 
358  virtual PythonIceTemperatureIBC* new_internalEnergyIBC();
359 
361  virtual void basalHeatFlux(LevelData<FArrayBox>& a_flux,
362  const AmrIceBase& a_amrIce,
363  int a_level, Real a_dt);
364 
365 #if BISICLES_Z == BISICLES_LAYERED
366  virtual void initializeIceInternalEnergy(LevelData<FArrayBox>& a_E,
367  LevelData<FArrayBox>& a_tillWaterDepth,
368  LevelData<FArrayBox>& a_surfaceE,
369  LevelData<FArrayBox>& a_basalE,
370  const AmrIceBase& a_amrIce,
371  int a_level, Real a_dt);
372 
373  virtual void setIceInternalEnergyBC(LevelData<FArrayBox>& a_E,
374  LevelData<FArrayBox>& a_tillWaterDepth,
375  LevelData<FArrayBox>& a_surfaceE,
376  LevelData<FArrayBox>& a_basalE,
377  const LevelSigmaCS& a_coordSys);
378 
379 #elif BISICLES_Z == BISICLES_FULLZ
380 #error BISICLES_FULLZ not implemented
381 #endif
382 
383 private:
384  PyObject* m_pModule;
385  PyObject* m_pFunc;
387 
388  PythonIceTemperatureIBC(PyObject* a_pModule, PyObject* a_pFunc)
389  {
390  m_pModule = a_pModule;
391  m_pFunc = a_pFunc;
392  Py_XINCREF(m_pModule);
393  Py_XINCREF(m_pFunc);
394  }
395 
396  };
397 
399 
417  {
418 
419  PyObject* m_pModule;
420  PyObject* m_pFunc;
421 
422  public:
423 
425 
429  PythonBasalFriction(const std::string& a_pyModule,
430  const std::string& a_pyFunc);
431 
432  virtual ~PythonBasalFriction();
433 
434  virtual BasalFriction* new_basalFriction() const;
435 
436  virtual void setBasalFriction(LevelData<FArrayBox>& a_C,
437  LevelSigmaCS& a_coordSys,
438  Real a_time,
439  Real a_dt);
440  private:
441  void operator=(const PythonBasalFriction& a_input)
442  {
443  MayDay::Error("invalid operator");
444  }
445 
447  {
448  MayDay::Error("invalid operator");
449  }
450 
452  {
453 
454  }
455 
457 
461  PythonBasalFriction(PyObject* a_pModule, PyObject* a_pFunc)
462  {
463  m_pModule = a_pModule;
464  m_pFunc = a_pFunc;
465  Py_XINCREF(m_pModule);
466  Py_XINCREF(m_pFunc);
467  }
468 
469  };
470 
471 
473  {
474 
475  PyObject* m_pModule;
476  PyObject* m_pFunc;
477 
478  public:
479  PythonMuCoefficient(const std::string& a_pyModule,
480  const std::string& a_pyFunc);
481 
482  virtual ~PythonMuCoefficient();
483 
484  virtual MuCoefficient* new_muCoefficient() const;
485 
486  virtual void setMuCoefficient(LevelData<FArrayBox>& a_C,
487  LevelSigmaCS& a_coordSys,
488  Real a_time,
489  Real a_dt);
490  private:
491  void operator=(const PythonMuCoefficient& a_input)
492  {
493  MayDay::Error("invalid operator");
494  }
495 
497  {
498  MayDay::Error("invalid operator");
499  }
500 
502  {
503 
504  }
505 
506 
507  PythonMuCoefficient(PyObject* a_pModule, PyObject* a_pFunc)
508  {
509  m_pModule = a_pModule;
510  m_pFunc = a_pFunc;
511  Py_XINCREF(m_pModule);
512  Py_XINCREF(m_pFunc);
513  }
514 
515  };
516 
518  {
519  PyObject* m_pModule;
520  PyObject* m_pFunc;
521 
522  public:
523  virtual ~PythonVelocitySolver();
524 
525  virtual void define(const ProblemDomain& a_coarseDomain,
526  ConstitutiveRelation* a_constRel,
527  BasalFrictionRelation* a_basalFrictionRel,
528  const Vector<DisjointBoxLayout>& a_vectGrids,
529  const Vector<int>& a_vectRefRatio,
530  const RealVect& a_dxCrse,
531  IceThicknessIBC* a_bc,
532  int a_numLevels);
533 
534  //full solve
535  virtual int solve(Vector<LevelData<FArrayBox>* >& a_horizontalVel,
536  Vector<LevelData<FArrayBox>* >& a_calvedIce,
537  Vector<LevelData<FArrayBox>* >& a_addedIce,
538  Vector<LevelData<FArrayBox>* >& a_removedIce,
539  Real& a_initialResidualNorm, Real& a_finalResidualNorm,
540  const Real a_convergenceMetric,
541  const Vector<LevelData<FArrayBox>* >& a_rhs,
542  const Vector<LevelData<FArrayBox>* >& a_beta,
543  const Vector<LevelData<FArrayBox>* >& a_beta0,
544  const Vector<LevelData<FArrayBox>* >& a_A,
545  const Vector<LevelData<FArrayBox>* >& a_muCoef,
546  Vector<RefCountedPtr<LevelSigmaCS > >& a_coordSys,
547  Real a_time,
548  int a_lbase, int a_maxLevel);
549 
550 
551  PythonVelocitySolver(PyObject* a_pModule, PyObject* a_pFunc)
552  {
553  m_pModule = a_pModule;
554  m_pFunc = a_pFunc;
555  Py_XINCREF(m_pModule);
556  Py_XINCREF(m_pFunc);
557  }
559  {
560  }
561  private:
562 
563  void operator=(const PythonVelocitySolver& a_input)
564  {
565  MayDay::Error("invalid operator");
566  }
567 
569  {
570  MayDay::Error("invalid operator");
571  }
572  };
573 
574 }
575 
576 #include "NamespaceFooter.H"
577 #endif
578 #endif
PythonIBC()
Definition: PythonInterface.cpp:213
Apply natural conditions along one boundary.
Definition: VelocityBC.H:141
BasalFriction that calls a python function to compute .
Definition: PythonInterface.H:416
Definition: MuCoefficient.H:25
Apply ice divide conditions along one boundary.
Definition: VelocityBC.H:83
Abstract class to manage the nonlinear solve for the ice-sheet momentum.
Definition: IceVelocitySolver.H:32
Abstract class around the englacial constitutive relations for ice.
Definition: ConstitutiveRelation.H:34
virtual RefCountedPtr< CompGridVTOBC > velocitySolveBC()
return boundary condition for Ice velocity solve
Definition: PythonInterface.cpp:310
PythonVelocitySolver(PyObject *a_pModule, PyObject *a_pFunc)
Definition: PythonInterface.H:551
virtual void modifyFaceVelocity(LevelData< FluxBox > &a_faceVel, const LevelSigmaCS &a_coords, const ProblemDomain &a_domain) const
if appropriate, modify face velocities in a problem-dependent way.
Definition: PythonInterface.cpp:530
virtual void setGeometryBCs(LevelSigmaCS &a_coords, const ProblemDomain &a_domain, const RealVect &a_dx, Real a_time, Real a_dt)
set non-periodic geometry (thickness, topography) ghost cells
Definition: PythonInterface.cpp:427
virtual void artViscBC(FArrayBox &a_F, const FArrayBox &a_U, const FArrayBox &a_divVel, const int &a_dir, const Real &a_time)
Adjust boundary fluxes to account for artificial viscosity.
Definition: PythonInterface.cpp:297
Apply no-slip conditions along one boundary.
Definition: VelocityBC.H:27
Physical/domain initial and boundary conditions for ice-sheet problems.
Definition: IceThicknessIBC.H:84
PythonVelocitySolver()
Definition: PythonInterface.H:558
virtual void modifyVelocityRHS(LevelData< FArrayBox > &a_rhs, LevelSigmaCS &a_coords, const ProblemDomain &a_domain, Real a_time, Real a_dt)
if appropriate, modify velocity solve RHS in a problem-dependent way.
Definition: PythonInterface.cpp:586
virtual void primBC(FArrayBox &a_WGdnv, const FArrayBox &a_Wextrap, const FArrayBox &a_W, const int &a_dir, const Side::LoHiSide &a_side, const Real &a_time)
Set boundary fluxes.
Definition: PythonInterface.cpp:250
virtual void initializeIceGeometry(LevelSigmaCS &a_coords, const RealVect &a_dx, const RealVect &a_domainSize, const Real &a_time, const LevelSigmaCS *a_crseCoords, const int a_refRatio)
set up initial ice state
Definition: PythonInterface.cpp:445
virtual ~PythonIBC()
Definition: PythonInterface.cpp:219
PhysIBC-derived class that allows the internalEnergy to set a a user-defined python function f(x...
Definition: PythonInterface.H:351
Common virtual base class for internal energy transport IBC.
Definition: IceInternalEnergyIBC.H:29
virtual void setIceFractionBCs(LevelData< FArrayBox > &a_fraction, const ProblemDomain &a_domain, const RealVect &a_dx, Real a_time, Real a_dt)
set non-periodic ghost cells for ice fraction
Definition: PythonInterface.cpp:410
virtual void setSurfaceHeightBCs(LevelData< FArrayBox > &a_zSurface, LevelSigmaCS &a_coords, const ProblemDomain &a_domain, const RealVect &a_dx, Real a_time, Real a_dt)
set non-periodic ghost cells for surface height z_s.
Definition: PythonInterface.cpp:391
abstract class defining the surface flux interface
Definition: SurfaceFlux.H:39
PythonInterface::PythonIBC, a PhysIBC-derived class which allows the bedrock and topography to be set...
Definition: PythonInterface.H:70
Definition: PythonInterface.H:472
Basic Sigma fourth-order coordinate system on an AMR level.
Definition: LevelSigmaCS.H:48
void PythonEval(PyObject *a_pyFunc, Vector< Real > &a_value, Vector< Real > &a_arg, std::map< std::string, Real > *a_kwarg=NULL)
Definition: PythonInterface.cpp:28
void FillKwargs(std::map< std::string, Real > &a_kwarg, const AmrIceBase &a_amrIce, int a_level, const DataIterator &a_dit, const IntVect &a_iv)
Definition: PythonInterface.cpp:678
bool regridIceGeometry(LevelSigmaCS &a_coords, const RealVect &a_dx, const RealVect &a_domainSize, const Real &a_time, const LevelSigmaCS *a_crseCoords, const int a_refRatio)
set up topography, etc at regrid time
Definition: PythonInterface.cpp:491
virtual void define(const ProblemDomain &a_domain, const Real &a_dx)
Define the object.
Definition: PythonInterface.cpp:236
Virtual base class for basal friction relations.
Definition: BasalFrictionRelation.H:27
Definition: PythonInterface.H:47
Definition: PythonInterface.H:517
void InitializePythonFunction(PyObject **a_pFunc, PyObject *a_pModule, const std::string &a_pyFuncName)
Definition: PythonInterface.cpp:144
void InitializePythonModule(PyObject **a_pModule, const std::string &a_pyModuleName)
Definition: PythonInterface.cpp:118
Definition: BasalFriction.H:28
abstract base class for amr ice sheet models (AmrIce, AMRIceControl)
Definition: AmrIceBase.H:21
Use a python function to evaluate the surface flux.
Definition: PythonInterface.H:292
virtual void initialize(LevelData< FArrayBox > &a_U)
Set up initial conditions.
Definition: PythonInterface.cpp:243
virtual void setBdrySlopes(FArrayBox &a_dW, const FArrayBox &a_W, const int &a_dir, const Real &a_time)
Set boundary slopes.
Definition: PythonInterface.cpp:288
virtual IceThicknessIBC * new_thicknessIBC()
Factory method - this object is its own factory.
Definition: PythonInterface.cpp:645