Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.12 KB | None | 0 0
  1. """
  2. Example Thetis configuration with traitlets
  3. """
  4.  
  5. from traitlets.config.configurable import Configurable
  6. from traitlets import *
  7.  
  8. from thetis import FiredrakeConstant as Constant
  9. from thetis import FiredrakeFunction as Function
  10.  
  11.  
  12. class PositiveInteger(Integer):
  13. def info(self):
  14. return u'a positive integer'
  15.  
  16. def validate(self, obj, proposal):
  17. super(PositiveInteger, self).validate(obj, proposal)
  18. assert proposal > 0, self.error(obj, proposal)
  19. return proposal
  20.  
  21.  
  22. class PositiveFloat(Float):
  23. def info(self):
  24. return u'a positive float'
  25.  
  26. def validate(self, obj, proposal):
  27. super(PositiveFloat, self).validate(obj, proposal)
  28. assert proposal > 0.0, self.error(obj, proposal)
  29. return proposal
  30.  
  31.  
  32. class BoundedInteger(Integer):
  33. def __init__(self, default_value=Undefined, bounds=None, **kwargs):
  34. super(BoundedInteger, self).__init__(default_value, **kwargs)
  35. self.minval = bounds[0]
  36. self.maxval = bounds[1]
  37.  
  38. def info(self):
  39. return u'an integer between {:} and {:}'.format(self.minval, self.maxval)
  40.  
  41. def validate(self, obj, proposal):
  42. super(BoundedInteger, self).validate(obj, proposal)
  43. assert proposal >= self.minval, self.error(obj, proposal)
  44. assert proposal <= self.maxval, self.error(obj, proposal)
  45. return proposal
  46.  
  47.  
  48. class BoundedFloat(Float):
  49. def __init__(self, default_value=Undefined, bounds=None, **kwargs):
  50. self.minval = bounds[0]
  51. self.maxval = bounds[1]
  52. super(BoundedFloat, self).__init__(default_value, **kwargs)
  53.  
  54. def info(self):
  55. return u'a float between {:} and {:}'.format(self.minval, self.maxval)
  56.  
  57. def validate(self, obj, proposal):
  58. super(BoundedFloat, self).validate(obj, proposal)
  59. assert proposal >= self.minval, self.error(obj, proposal)
  60. assert proposal <= self.maxval, self.error(obj, proposal)
  61. return proposal
  62.  
  63.  
  64. class FiredrakeConstant(TraitType):
  65. default_value = None
  66. info_text = 'a Firedrake Constant'
  67.  
  68. def validate(self, obj, value):
  69. if isinstance(value, Constant):
  70. return value
  71. self.error(obj, value)
  72.  
  73. def default_value_repr(self):
  74. return 'Constant({:})'.format(self.default_value.dat.data[0])
  75.  
  76.  
  77. class FiredrakeCoefficient(TraitType):
  78. default_value = None
  79. info_text = 'a Firedrake Constant or Function'
  80.  
  81. def validate(self, obj, value):
  82. if isinstance(value, (Constant, Function)):
  83. return value
  84. self.error(obj, value)
  85.  
  86. def default_value_repr(self):
  87. if isinstance(self.default_value, Constant):
  88. return 'Constant({:})'.format(self.default_value.dat.data[0])
  89. return 'Function'
  90.  
  91.  
  92. class FrozenHasTraits(HasTraits):
  93. """
  94. A HasTraits class that only allows adding new attributes in the class
  95. definition or when self._isfrozen is False.
  96. """
  97. _isfrozen = False
  98. def __init__(self, *args, **kwargs):
  99. super(FrozenHasTraits, self).__init__(*args, **kwargs)
  100. self._isfrozen = True
  101.  
  102. def __setattr__(self, key, value):
  103. if self._isfrozen and not hasattr(self, key):
  104. raise TypeError('Adding new attribute "{:}" to {:} class is forbidden'.format(key, self.__class__.__name__))
  105. super(FrozenHasTraits, self).__setattr__(key, value)
  106.  
  107.  
  108. class FrozenConfigurable(Configurable):
  109. """
  110. A Configurable class that only allows adding new attributes in the class
  111. definition or when self._isfrozen is False.
  112. """
  113. _isfrozen = False
  114. def __init__(self, *args, **kwargs):
  115. super(FrozenConfigurable, self).__init__(*args, **kwargs)
  116. self._isfrozen = True
  117.  
  118. def __setattr__(self, key, value):
  119. if self._isfrozen and not hasattr(self, key):
  120. raise TypeError('Adding new attribute "{:}" to {:} class is forbidden'.format(key, self.__class__.__name__))
  121. super(FrozenConfigurable, self).__setattr__(key, value)
  122.  
  123.  
  124. class TimeStepperOptions(FrozenHasTraits):
  125. """Base class for all time stepper options"""
  126.  
  127.  
  128. class CrankNicolsonOptions(TimeStepperOptions):
  129. implicitness_theta = BoundedFloat(default_value=0.5, bounds=[0.5, 1.0], help='implicitness parameter theta. Value 0.5 implies Crank-Nicolson scheme, 1.0 implies fully implicit formulation.')
  130.  
  131.  
  132. class ExplicitTimestepperOptions(TimeStepperOptions):
  133. use_automatic_timestep = Bool(True, help='Set time step automatically based on local CFL conditions.')
  134.  
  135. class GLSModelOptions(FrozenHasTraits):
  136. """Class for all time stepper options"""
  137. pass
  138.  
  139. class TimeStepperOptionsTrait(TraitType):
  140. default_value = ExplicitTimestepperOptions()
  141. info_text = 'a TimeStepperOptions instance'
  142.  
  143. def validate(self, obj, value):
  144. if isinstance(value, TimeStepperOptions):
  145. return value
  146. self.error(obj, value)
  147.  
  148. class SubOptions(FrozenHasTraits):
  149.  
  150. @observe('name')
  151. def _observe_name(self, change):
  152. old = change['old']
  153. newval = change['new']
  154. for target_trait, choices in self.children:
  155. if newval in choices:
  156. self.__setattr__(target_trait, choices[newval])
  157.  
  158. def __init__(self, valid_values=[], default_value=None, help=None, children=None):
  159. name = Enum(valid_values,
  160. default_value=default_value,
  161. help=help).tag(config=True)
  162. self.add_traits(name=name)
  163.  
  164. self.children = children
  165. # check completeness of children
  166. for target_trait, choices in self.children:
  167. for value in valid_values:
  168. assert value in choices, 'Cannot find key "{:}" in "{:}" dictionary'.format(value, target_trait)
  169.  
  170. # set defaults
  171. assert default_value is not None
  172. for target_trait, choices in self.children:
  173. trait = choices[default_value]
  174. self.__setattr__(target_trait, trait)
  175.  
  176. self._isfrozen = True
  177.  
  178.  
  179. def attach_paired_options(options_name_trait, options_value_trait, default_values):
  180. """Attach paired options to a Configurable object.
  181.  
  182. :arg options_name_trait: a tuple (name, Trait) for the options name (a choice).
  183. :arg options_value_trait: a tuple (name, Trait) for the options value (some configurable object)
  184. :arg default_values: a dict mapping valid values for the options name to valid defaults for the options value."""
  185.  
  186. name, name_trait = options_name_trait
  187. value, value_trait = options_value_trait
  188.  
  189. def _observer(self, change):
  190. "Observer called when the choice option is updated."
  191. setattr(self, value, default_values[change["new"]])
  192.  
  193. def _default(self):
  194. "Dynamic default value setter"
  195. if hasattr(name_trait, 'default_value') and name_trait.default_value is not None:
  196. return default_values[name_trait.default_value]
  197.  
  198. obs_handler = ObserveHandler(name, type="change")
  199. def_handler = DefaultHandler(value)
  200.  
  201. def update_class(cls):
  202. "Programmatically update the class"
  203. # Set the new class attributes
  204. setattr(cls, name, name_trait)
  205. setattr(cls, value, value_trait)
  206. setattr(cls, "_%s_observer" % name, obs_handler(_observer))
  207. setattr(cls, "_%s_default" % value, def_handler(_default))
  208. # Mimic the magic metaclass voodoo.
  209. name_trait.class_init(cls, name)
  210. value_trait.class_init(cls, value)
  211. obs_handler.class_init(cls, "_%s_observer" % name)
  212. def_handler.class_init(cls, "_%s_default" % value)
  213.  
  214. return cls
  215. return update_class
  216.  
  217.  
  218. @attach_paired_options(("timestepper_type",
  219. Enum(['SSPRK22', 'CrankNicolson'],
  220. default_value='SSPRK22',
  221. help='Name of the time integrator').tag(config=True)
  222. ), ("timestepper_options",
  223. Instance(TimeStepperOptions, args=()).tag(config=True)),
  224. {
  225. 'CrankNicolson': CrankNicolsonOptions(),
  226. 'SSPRK22': ExplicitTimestepperOptions(),
  227. })
  228. @attach_paired_options(("turbulence_model_type",
  229. Enum(['gls'],
  230. default_value='gls',
  231. help='Type of vertical turbulence model').tag(config=True)
  232. ), ("gls_options",
  233. Instance(GLSModelOptions, args=()).tag(config=True)),
  234. {
  235. 'CrankNicolson': CrankNicolsonOptions(),
  236. 'SSPRK22': ExplicitTimestepperOptions(),
  237. })
  238. class ModelOptions(FrozenConfigurable):
  239. polynomial_degree = PositiveInteger(1, help='Polynomial degree of elements').tag(config=True)
  240. element_family = Enum(
  241. ['dg-dg', 'rt-dg', 'dg-cg'],
  242. default_value='dg-dg',
  243. help="""Finite element family
  244.  
  245. 2D solver supports 'dg-dg', 'rt-dg', or 'dg-cg' velocity-pressure pairs.
  246. 3D solver supports 'dg-dg', or 'rt-dg' velocity-pressure pairs."""
  247. ).tag(config=True)
  248.  
  249. use_nonlinear_equations = Bool(True, help='Use nonlinear shallow water equations').tag(config=True)
  250. solve_salinity = Bool(True, help='Solve salinity transport').tag(config=True)
  251. solve_temperature = Bool(True, help='Solve temperature transport').tag(config=True)
  252. use_implicit_vertical_diffusion = Bool(True, help='Solve vertical diffusion and viscosity implicitly').tag(config=True)
  253. use_bottom_friction = Bool(True, help='Apply log layer bottom stress in the 3D model').tag(config=True)
  254. use_parabolic_viscosity = Bool(
  255. False,
  256. help="""Use idealized parabolic eddy viscosity
  257.  
  258. See :class:`.ParabolicViscosity`""").tag(config=True)
  259. use_grad_div_viscosity_term = Bool(
  260. False,
  261. help=r"""Include :math:`\nabla (\nu_h \nabla \cdot \bar{\textbf{u}})` term in the depth-averaged viscosity
  262.  
  263. See :class:`.shallowwater_eq.HorizontalViscosityTerm` for details.""").tag(config=True)
  264. use_grad_depth_viscosity_term = Bool(
  265. True,
  266. help=r"""Include :math:`\nabla H` term in the depth-averaged viscosity
  267.  
  268. See :class:`.shallowwater_eq.HorizontalViscosityTerm` for details.""").tag(config=True)
  269.  
  270. use_ale_moving_mesh = Bool(
  271. True, help="Use ALE formulation where 3D mesh tracks free surface").tag(config=True)
  272.  
  273. use_linearized_semi_implicit_2d = Bool(
  274. False, help="Use linearized semi-implicit time integration for the horizontal mode").tag(config=True)
  275. shallow_water_theta = BoundedFloat(
  276. 0.5, bounds=[0.5, 1.0], help='Theta parameter for shallow water semi-implicit scheme').tag(config=True)
  277. use_turbulence = Bool(
  278. False, help="Activate turbulence model in the 3D model").tag(config=True)
  279. use_smooth_eddy_viscosity = Bool(
  280. False, help="Cast eddy viscosity to p1 space instead of p0").tag(config=True)
  281.  
  282. use_turbulence_advection = Bool(
  283. False, help="Advect TKE and Psi in the GLS turbulence model").tag(config=True)
  284. use_baroclinic_formulation = Bool(
  285. False, help="Compute internal pressure gradient in momentum equation").tag(config=True)
  286. use_smagorinsky_viscosity = Bool(
  287. False, help="Use Smagorinsky horisontal viscosity parametrization").tag(config=True)
  288. smagorinsky_coefficient = FiredrakeConstant(
  289. Constant(0.1),
  290. help="""Smagorinsky viscosity coefficient :math:`C_S`
  291.  
  292. See :class:`.SmagorinskyViscosity`.""").tag(config=True)
  293.  
  294. use_limiter_for_tracers = Bool(
  295. False, help="Apply P1DG limiter for tracer fields").tag(config=True)
  296. use_lax_friedrichs_velocity = Bool(
  297. True, help="use Lax Friedrichs stabilisation in horizontal momentum advection.").tag(config=True)
  298. lax_friedrichs_velocity_scaling_factor = FiredrakeConstant(
  299. Constant(1.0), help="Scaling factor for Lax Friedrichs stabilisation term in horiozonal momentum advection.").tag(config=True)
  300. use_lax_friedrichs_tracer = Bool(
  301. True, help="Use Lax Friedrichs stabilisation in tracer advection.").tag(config=True)
  302. lax_friedrichs_tracer_scaling_factor = FiredrakeConstant(
  303. Constant(1.0), help="Scaling factor for tracer Lax Friedrichs stability term.").tag(config=True)
  304. check_volume_conservation_2d = Bool(
  305. False, help="""
  306. Compute volume of the 2D mode at every export
  307.  
  308. 2D volume is defined as the integral of the water elevation field.
  309. Prints deviation from the initial volume to stdout.
  310. """).tag(config=True)
  311. check_volume_conservation_3d = Bool(
  312. False, help="""
  313. Compute volume of the 3D domain at every export
  314.  
  315. Prints deviation from the initial volume to stdout.
  316. """).tag(config=True)
  317. check_salinity_conservation = Bool(
  318. False, help="""
  319. Compute total salinity mass at every export
  320.  
  321. Prints deviation from the initial mass to stdout.
  322. """).tag(config=True)
  323. check_salinity_overshoot = Bool(
  324. False, help="""
  325. Compute salinity overshoots at every export
  326.  
  327. Prints overshoot values that exceed the initial range to stdout.
  328. """).tag(config=True)
  329. check_temperature_conservation = Bool(
  330. False, help="""
  331. Compute total temperature mass at every export
  332.  
  333. Prints deviation from the initial mass to stdout.
  334. """).tag(config=True)
  335. check_temperature_overshoot = Bool(
  336. False, help="""
  337. Compute temperature overshoots at every export
  338.  
  339. Prints overshoot values that exceed the initial range to stdout.
  340. """).tag(config=True)
  341. log_output = Bool(
  342. True, help="Redirect all output to log file in output directory").tag(config=True)
  343. timestep = PositiveFloat(
  344. 10.0, help="Time step").tag(config=True)
  345. timestep_2d = PositiveFloat(
  346. 10.0, help="""
  347. Time step of the 2d mode
  348.  
  349. This option is only used in the 3d solver, if 2d mode is solved
  350. explicitly.
  351. """).tag(config=True)
  352. use_automatic_timestep = Bool(
  353. True, help="""
  354. Set time step automatically.
  355.  
  356. Solver computes the largest stable time step based on user-defined
  357. velocity and viscosity scales. See
  358. :attr:`horizontal_velocity_scale`,
  359. :attr:`vertical_velocity_scale`,
  360. :attr:`horizontal_viscosity_scale`.
  361. """).tag(config=True)
  362. cfl_2d = PositiveFloat(
  363. 1.0, help="Factor to scale the 2d time step OBSOLETE").tag(config=True) # TODO OBSOLETE
  364. cfl_3d = PositiveFloat(
  365. 1.0, help="Factor to scale the 2d time step OBSOLETE").tag(config=True) # TODO OBSOLETE
  366. simulation_export_time = PositiveFloat(
  367. 100.0, help="""
  368. Export interval in seconds
  369.  
  370. All fields in fields_to_export list will be stored to disk and
  371. diagnostics will be computed
  372. """).tag(config=True)
  373. simulation_end_time = PositiveFloat(
  374. 1000.0, help="Simulation duration in seconds").tag(config=True)
  375. horizontal_velocity_scale = FiredrakeConstant(
  376. Constant(0.1), help="""
  377. Maximum horizontal velocity magnitude
  378.  
  379. Used to compute max stable advection time step.
  380. """).tag(config=True)
  381. vertical_velocity_scale = FiredrakeConstant(
  382. Constant(1e-4), help="""
  383. Maximum vertical velocity magnitude
  384.  
  385. Used to compute max stable advection time step.
  386. """).tag(config=True)
  387. horizontal_viscosity_scale = FiredrakeConstant(
  388. Constant(1.0), help="""
  389. Maximum horizontal viscosity
  390.  
  391. Used to compute max stable diffusion time step.
  392. """).tag(config=True)
  393. output_directory = Unicode(
  394. 'outputs', help="Directory where model output files are stored").tag(config=True)
  395. no_exports = Bool(
  396. False, help="""
  397. Do not store any outputs to disk
  398.  
  399. Disables VTK and HDF5 field outputs. and HDF5 diagnostic outputs.
  400. Used in CI test suite.
  401. """).tag(config=True)
  402. export_diagnostics = Bool(
  403. True, help="Store diagnostic variables to disk in HDF5 format").tag(config=True)
  404. use_quadratic_pressure = Bool(
  405. False, help="""
  406. Use P2DGxP2 space for baroclinic head.
  407.  
  408. If element_family='dg-dg', P2DGxP1DG space is also used for the internal
  409. pressure gradient.
  410.  
  411. This is useful to alleviate bathymetry-induced pressure gradient errors.
  412. If False, the baroclinic head is in the tracer space, and internal
  413. pressure gradient is in the velocity space.
  414. """).tag(config=True)
  415. use_quadratic_density = Bool(
  416. False, help="""
  417. Water density is projected to P2DGxP2 space.
  418.  
  419. This reduces pressure gradient errors associated with nonlinear
  420. equation of state.
  421. If False, density is computed point-wise in the tracer space.
  422. """).tag(config=True)
  423. fields_to_export = List(
  424. trait=Unicode,
  425. default_value=['elev_2d', 'uv_2d', 'uv_3d', 'w_3d'],
  426. help="Fields to export in VTK format").tag(config=True)
  427. fields_to_export_hdf5 = List(
  428. trait=Unicode,
  429. default_value=[],
  430. help="Fields to export in HDF5 format").tag(config=True)
  431. verbose = Integer(0, help="Verbosity level").tag(config=True)
  432. linear_drag_coefficient = FiredrakeCoefficient(
  433. None, allow_none=True, help=r"""
  434. 2D linear drag parameter :math:`L`
  435.  
  436. Bottom stress is :math:`\tau_b/\rho_0 = -L \mathbf{u} H`
  437. """).tag(config=True)
  438. quadratic_drag_coefficient = FiredrakeCoefficient(
  439. None, allow_none=True, help=r"""
  440. Dimensionless 2D quadratic drag parameter :math:`C_D`
  441.  
  442. Bottom stress is :math:`\tau_b/\rho_0 = -C_D |\mathbf{u}|\mathbf{u}`
  443. """).tag(config=True)
  444. manning_drag_coefficient = FiredrakeCoefficient(
  445. None, allow_none=True, help=r"""
  446. Manning-Strickler 2D quadratic drag parameter :math:`\mu`
  447.  
  448. Bottom stress is :math:`\tau_b/\rho_0 = -g \mu^2 |\mathbf{u}|\mathbf{u}/H^{1/3}`
  449. """).tag(config=True)
  450. use_wetting_and_drying = Bool(
  451. False, help=r"""bool: Turn on wetting and drying
  452.  
  453. Uses the wetting and drying scheme from Karna et al (2011).
  454. If ``True``, one should also set :attr:`wetting_and_drying_alpha` to control the bathymetry displacement.
  455. """).tag(config=True)
  456. wetting_and_drying_alpha = FiredrakeConstant(
  457. Constant(0.5), help=r"""
  458. Coefficient: Wetting and drying parameter :math:`alpha`.
  459.  
  460. Used in bathymetry displacement function that ensures positive water depths. Unit is meters.
  461. """).tag(config=True)
  462. horizontal_diffusivity = FiredrakeCoefficient(
  463. None, allow_none=True, help="Horizontal diffusivity for tracers").tag(config=True)
  464. vertical_diffusivity = FiredrakeCoefficient(
  465. None, allow_none=True, help="Vertical diffusivity for tracers").tag(config=True)
  466. horizontal_viscosity = FiredrakeCoefficient(
  467. None, allow_none=True, help="Horizontal viscosity").tag(config=True)
  468. vertical_viscosity = FiredrakeCoefficient(
  469. None, allow_none=True, help="Vertical viscosity").tag(config=True)
  470. coriolis_frequency = FiredrakeCoefficient(
  471. None, allow_none=True, help="2D Coriolis parameter").tag(config=True)
  472. wind_stress = FiredrakeCoefficient(
  473. None, allow_none=True, help="Stress at free surface (2D vector function)").tag(config=True)
  474. atmospheric_pressure = FiredrakeCoefficient(
  475. None, allow_none=True, help="Atmospheric pressure at free surface, in pascals").tag(config=True)
  476. momentum_source_2d = FiredrakeCoefficient(
  477. None, allow_none=True, help="Source term for 2D momentum equation").tag(config=True)
  478. momentum_source_3d = FiredrakeCoefficient(
  479. None, allow_none=True, help="Source term for 3D momentum equation").tag(config=True)
  480. volume_source_2d = FiredrakeCoefficient(
  481. None, allow_none=True, help="Source term for 2D continuity equation").tag(config=True)
  482. salinity_source_3d = FiredrakeCoefficient(
  483. None, allow_none=True, help="Source term for salinity equation").tag(config=True)
  484. temperature_source_3d = FiredrakeCoefficient(
  485. None, allow_none=True, help="Source term for temperature equation").tag(config=True)
  486. constant_temperature = FiredrakeConstant(
  487. Constant(10.0), help="Constant temperature if temperature is not solved").tag(config=True)
  488. constant_salinity = FiredrakeConstant(
  489. Constant(0.0), help="Constant salinity if salinity is not solved").tag(config=True)
  490.  
  491. options = ModelOptions()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement