/[escript]/trunk/modellib/py_src/input.py
ViewVC logotype

Contents of /trunk/modellib/py_src/input.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6651 - (show annotations)
Wed Feb 7 02:12:08 2018 UTC (15 months, 1 week ago) by jfenwick
File MIME type: text/x-python
File size: 21075 byte(s)
Make everyone sad by touching all the files

Copyright dates update

1
2 ##############################################################################
3 #
4 # Copyright (c) 2003-2018 by The University of Queensland
5 # http://www.uq.edu.au
6 #
7 # Primary Business: Queensland, Australia
8 # Licensed under the Apache License, version 2.0
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 # Development 2012-2013 by School of Earth Sciences
13 # Development from 2014 by Centre for Geoscience Computing (GeoComp)
14 #
15 ##############################################################################
16
17 from __future__ import division, print_function
18
19 __copyright__="""Copyright (c) 2003-2018 by The University of Queensland
20 http://www.uq.edu.au
21 Primary Business: Queensland, Australia"""
22 __license__="""Licensed under the Apache License, version 2.0
23 http://www.apache.org/licenses/LICENSE-2.0"""
24 __url__="https://launchpad.net/escript-finley"
25
26 from esys.escript import length, wherePositive, whereNegative, exp, inf, sup
27 from esys.escript.modelframe import Model,ParameterSet
28 from esys.escript.linearPDEs import LinearPDE
29 from math import log
30 import numpy
31
32 class Sequencer(Model):
33 """
34 Runs through time until t_end is reached.
35
36 :ivar t_end: model is terminated when t_end is passed, default 1 (in).
37 :type t_end: ``float``
38 :ivar dt_max: maximum time step size, default `Model.UNDEF_DT` (in)
39 :type dt_max: ``float``
40 :ivar t: current time stamp (in/out). By default it is initialized with zero.
41 :type t: ``float``
42
43 """
44 def __init__(self,**kwargs):
45 """
46 """
47 super(Sequencer,self).__init__(**kwargs)
48 self.declareParameter(t=0.,
49 t_end=1.,
50 dt_max=Model.UNDEF_DT)
51
52 def doInitialization(self):
53 """
54 initialize time integration
55 """
56 self.__t_old = self.t
57
58 def doStepPreprocessing(self, dt):
59 self.t = self.__t_old+dt
60
61 def doStepPostprocessing(self, dt):
62 self.__t_old = self.t
63
64 def finalize(self):
65 """
66 returns true when `t` has reached `t_end`
67 """
68 return self.t >= self.t_end
69
70 def getSafeTimeStepSize(self, dt):
71 """
72 returns `dt_max`
73 """
74 return self.dt_max
75
76 class GaussianProfile(ParameterSet):
77 """
78 Generates a Gaussian profile at center x_c, width width and height A
79 over a domain
80
81 :note: Instance variable domain - domain
82 :note: Instance variable x_c - center of the Gaussian profile (default [0.,0.,0.])
83 :note: Instance variable A - (in) height of the profile. A maybe a vector. (default 1.)
84 :note: Instance variable width - (in) width of the profile (default 0.1)
85 :note: Instance variable r - (in) radius of the circle (default = 0)
86
87 In the case that the spatial dimension is two, The third component of
88 x_c is dropped.
89 """
90 def __init__(self,**kwargs):
91 super(GaussianProfile, self).__init__(**kwargs)
92 self.declareParameter(domain=None,
93 x_c=numpy.zeros([3]),
94 A=1.,
95 width=0.1,
96 r=0)
97
98 def out(self):
99 """
100 Generate the Gaussian profile
101
102 Link against this method to get the output of this model.
103 """
104 x = self.domain.getX()
105 dim = self.domain.getDim()
106 l = length(x-self.x_c[:dim])
107 m = whereNegative(l-self.r)
108
109 return (m+(1.-m)*exp(-log(2.)*(l/self.width)**2))*self.A
110
111 class InterpolateOverBox(ParameterSet):
112 """
113 Returns values at each time. The values are defined through given values
114 at time node. For two dimensional domains back values are ignored.
115
116 :note: Instance variable domain - domain
117 :note: Instance variable value_left_bottom_front - (in) value at left,bottom,front corner
118 :note: Instance variable value_right_bottom_front - (in) value at right, bottom, front corner
119 :note: Instance variable value_left_top_front - (in) value at left,top,front corner
120 :note: Instance variable value_right_top_front - (in) value at right,top,front corner
121 :note: Instance variable value_left_bottom_back - (in) value at left,bottom,back corner
122 :note: Instance variable value_right_bottom_back - (in) value at right,bottom,back corner
123 :note: Instance variable value_left_top_back - (in) value at left,top,back corner
124 :note: Instance variable value_right_top_back - (in) value at right,top,back corner
125 """
126
127 def __init__(self, **kwargs):
128 super(InterpolateOverBox, self).__init__(self)
129 self.declareParameter(domain=None,
130 value_left_bottom_front=0.,
131 value_right_bottom_front=0.,
132 value_left_top_front=0.,
133 value_right_top_front=0.,
134 value_left_bottom_back=0.,
135 value_right_bottom_back=0.,
136 value_left_top_back=0.,
137 value_right_top_back=0.)
138
139
140 def out(self):
141 """
142 values at domain locations by bilinear interpolation of the given values.
143
144 Link against this method to get the output of this model.
145 """
146 x = self.domain.getX()
147 if self.domain.getDim() == 2:
148 x0,x1=x[0],x[1]
149 left_bottom_front0,right_top_back0=inf(x0),sup(x0)
150 left_bottom_front1,right_top_back1=inf(x1),sup(x1)
151 f_right = (x0 - left_bottom_front0)/(right_top_back0 -left_bottom_front0)
152 f_left = 1. - f_right
153 f_top = (x1 - left_bottom_front1)/(right_top_back1 - left_bottom_front1)
154 f_bottom = 1. - f_top
155 out = f_left * f_bottom * self.value_left_bottom_front \
156 + f_right * f_bottom * self.value_right_bottom_front \
157 + f_left * f_top * self.value_left_top_front \
158 + f_right * f_top * self.value_right_top_front
159 else:
160 x0,x1,x2=x[0],x[1],x[2]
161 left_bottom_front0,right_top_back0=inf(x0),sup(x0)
162 left_bottom_front1,right_top_back1=inf(x1),sup(x1)
163 left_bottom_front2,right_top_back2=inf(x2),sup(x2)
164 f_right = (x0 - left_bottom_front0)/(right_top_back0 - left_bottom_front0)
165 f_left = 1. - f_right
166 f_top = (x1 - left_bottom_front1)/(right_top_back1 - left_bottom_front1)
167 f_bottom = 1. - f_top
168 f_back = (x2 - left_bottom_front1)/(right_top_back2 - left_bottom_front2)
169 f_front = 1. - f_back
170 out = f_left * f_bottom * f_front * self.value_left_bottom_front\
171 + f_right * f_bottom * f_front * self.value_right_bottom_front\
172 + f_left * f_top * f_front * self.value_left_top_front\
173 + f_right * f_top * f_front * self.value_right_top_front\
174 + f_left * f_bottom * f_back * self.value_left_bottom_back\
175 + f_right * f_bottom * f_back * self.value_right_bottom_back\
176 + f_left * f_top * f_back * self.value_left_top_back\
177 + f_right * f_top * f_back * self.value_right_top_back
178 return out
179
180
181 class InterpolatedTimeProfile(ParameterSet):
182 """
183
184 Returns values at each time. The values are defined through given
185 values at time node.
186
187 value[i] defines the value at time nodes[i]. Between nodes linear
188 interpolation is used.
189
190 For time t<nodes[0], value[0] is used and for t>nodes[l], values[l]
191 is used where l=len(nodes)-1.
192
193 :note: Instance variable t - (in) current time
194 :note: Instance variable node - (in) list of time nodes
195 :note: Instance variable values - (in) list of values at time nodes
196 """
197
198 def __init__(self,**kwargs):
199 super( InterpolatedTimeProfile, self).__init__(**kwargs)
200 self.declareParameter(t=0., \
201 nodes=[0.,1.],\
202 values=[1.,1.])
203 def out(self):
204 """
205 current value
206
207 Link against this method to get the output of this model.
208 """
209 l = len(self.nodes) - 1
210 t = self.t
211 if t <= self.nodes[0]:
212 return self.values[0]
213 else:
214 for i in range(1,l):
215 if t < self.nodes[i]:
216 m = (self.values[i-1] - self.values[i])/\
217 (self.nodes[i-1] - self.nodes[i])
218 return m*(t-self.nodes[i-1]) + self.values[i-1]
219 return self.values[l]
220
221 class ScalarDistributionFromTags(ParameterSet):
222 """
223 creates a scalar distribution on a domain from tags, If tag_map is given
224 the tags can be given a names and tag_map is used to map it into domain tags.
225
226 :ivar domain: domain
227 :type domain: `esys.escript.Domain`
228 :ivar default: default value
229 :ivar tag0: tag 0
230 :type tag0: ``int``
231 :ivar value0: value for tag 0
232 :type value0: ``float``
233 :ivar tag1: tag 1
234 :type tag1: ``int``
235 :ivar value1: value for tag 1
236 :type value1: ``float``
237 :ivar tag2: tag 2
238 :type tag2: ``int``
239 :ivar value2: value for tag 2
240 :type value2: ``float``
241 :ivar tag3: tag 3
242 :type tag3: ``int``
243 :ivar value3: value for tag 3
244 :type value3: ``float``
245 :ivar tag4: tag 4
246 :type tag4: ``int``
247 :ivar value4: value for tag 4
248 :type value4: ``float``
249 :ivar tag5: tag 5
250 :type tag5: ``int``
251 :ivar value5: value for tag 5
252 :type value5: ``float``
253 :ivar tag6: tag 6
254 :type tag6: ``int``
255 :ivar value6: value for tag 6
256 :type value6: ``float``
257 :ivar tag7: tag 7
258 :type tag7: ``int``
259 :ivar value7: value for tag 7
260 :type value7: ``float``
261 :ivar tag8: tag 8
262 :type tag8: ``int``
263 :ivar value8: value for tag 8
264 :type value8: ``float``
265 :ivar tag9: tag 9
266 :type tag9: ``int``
267 :ivar value9: value for tag 9
268 :type value9: ``float``
269 """
270 def __init__(self,**kwargs):
271 super(ScalarDistributionFromTags, self).__init__(**kwargs)
272 self.declareParameter(domain=None,
273 default=0.,
274 tag0=None,
275 value0=0.,
276 tag1=None,
277 value1=0.,
278 tag2=None,
279 value2=0.,
280 tag3=None,
281 value3=0.,
282 tag4=None,
283 value4=0.,
284 tag5=None,
285 value5=0.,
286 tag6=None,
287 value6=0.,
288 tag7=None,
289 value7=0.,
290 tag8=None,
291 value8=0.,
292 tag9=None,
293 value9=0.)
294
295
296 def out(self):
297 """
298 returns a `esys.escript.Data` object
299 Link against this method to get the output of this model.
300 """
301 d=Scalar(self.default,Function(self.domain))
302 if not self.tag0 is None: d.setTaggedValue(self.tag0,self.value0)
303 if not self.tag1 is None: d.setTaggedValue(self.tag1,self.value1)
304 if not self.tag2 is None: d.setTaggedValue(self.tag2,self.value2)
305 if not self.tag3 is None: d.setTaggedValue(self.tag3,self.value3)
306 if not self.tag4 is None: d.setTaggedValue(self.tag4,self.value4)
307 if not self.tag5 is None: d.setTaggedValue(self.tag5,self.value5)
308 if not self.tag6 is None: d.setTaggedValue(self.tag6,self.value6)
309 if not self.tag7 is None: d.setTaggedValue(self.tag7,self.value7)
310 if not self.tag8 is None: d.setTaggedValue(self.tag8,self.value8)
311 if not self.tag9 is None: d.setTaggedValue(self.tag9,self.value9)
312 return d
313
314 class SmoothScalarDistributionFromTags(ParameterSet):
315 """
316 creates a smooth scalar distribution on a domain from region tags
317
318 :ivar domain: domain
319 :type domain: `esys.escript.Domain`
320 :ivar default: default value
321 :ivar tag0: tag 0
322 :type tag0: ``int``
323 :ivar value0: value for tag 0
324 :type value0: ``float``
325 :ivar tag1: tag 1
326 :type tag1: ``int``
327 :ivar value1: value for tag 1
328 :type value1: ``float``
329 :ivar tag2: tag 2
330 :type tag2: ``int``
331 :ivar value2: value for tag 2
332 :type value2: ``float``
333 :ivar tag3: tag 3
334 :type tag3: ``int``
335 :ivar value3: value for tag 3
336 :type value3: ``float``
337 :ivar tag4: tag 4
338 :type tag4: ``int``
339 :ivar value4: value for tag 4
340 :type value4: ``float``
341 :ivar tag5: tag 5
342 :type tag5: ``int``
343 :ivar value5: value for tag 5
344 :type value5: ``float``
345 :ivar tag6: tag 6
346 :type tag6: ``int``
347 :ivar value6: value for tag 6
348 :type value6: ``float``
349 :ivar tag7: tag 7
350 :type tag7: ``int``
351 :ivar value7: value for tag 7
352 :type value7: ``float``
353 :ivar tag8: tag 8
354 :type tag8: ``int``
355 :ivar value8: value for tag 8
356 :type value8: ``float``
357 :ivar tag9: tag 9
358 :type tag9: ``int``
359 :ivar value9: value for tag 9
360 :type value9: ``float``
361 """
362 def __init__(self,**kwargs):
363 super(SmoothScalarDistributionFromTags, self).__init__(**kwargs)
364 self.declareParameter(domain=None,
365 default=0.,
366 tag0=None,
367 value0=0.,
368 tag1=None,
369 value1=0.,
370 tag2=None,
371 value2=0.,
372 tag3=None,
373 value3=0.,
374 tag4=None,
375 value4=0.,
376 tag5=None,
377 value5=0.,
378 tag6=None,
379 value6=0.,
380 tag7=None,
381 value7=0.,
382 tag8=None,
383 value8=0.,
384 tag9=None,
385 value9=0.)
386
387
388 def __update(self,tag,tag_value,value):
389 if self.__pde==None:
390 self.__pde=LinearPDE(self.domain,numSolutions=1)
391 mask=Scalar(0.,Function(self.domain))
392 mask.setTaggedValue(tag,1.)
393 self.__pde.setValue(Y=mask)
394 mask=wherePositive(abs(self.__pde.getRightHandSide()))
395 value*=(1.-mask)
396 value+=tag_value*mask
397 return value
398
399 def out(self):
400 """
401 returns a `esys.escript.Data` object
402 Link against this method to get the output of this model.
403 """
404 d=Scalar(self.default,Solution(self.domain))
405 self.__pde=None
406 if not self.tag0 is None: d=self.__update(self.tag0,self.value0,d)
407 if not self.tag1 is None: d=self.__update(self.tag1,self.value1,d)
408 if not self.tag2 is None: d=self.__update(self.tag2,self.value2,d)
409 if not self.tag3 is None: d=self.__update(self.tag3,self.value3,d)
410 if not self.tag4 is None: d=self.__update(self.tag4,self.value4,d)
411 if not self.tag5 is None: d=self.__update(self.tag5,self.value5,d)
412 if not self.tag6 is None: d=self.__update(self.tag6,self.value6,d)
413 if not self.tag7 is None: d=self.__update(self.tag7,self.value7,d)
414 if not self.tag8 is None: d=self.__update(self.tag8,self.value8,d)
415 if not self.tag9 is None: d=self.__update(self.tag9,self.value9,d)
416 return d
417
418 class LinearCombination(ParameterSet):
419 """
420 Returns a linear combination of the f0*v0+f1*v1+f2*v2+f3*v3+f4*v4
421
422 :ivar f0: numerical object or None, default=None (in)
423 :ivar v0: numerical object or None, default=None (in)
424 :ivar f1: numerical object or None, default=None (in)
425 :ivar v1: numerical object or None, default=None (in)
426 :ivar f2: numerical object or None, default=None (in)
427 :ivar v2: numerical object or None, default=None (in)
428 :ivar f3: numerical object or None, default=None (in)
429 :ivar v3: numerical object or None, default=None (in)
430 :ivar f4: numerical object or None, default=None (in)
431 :ivar v4: numerical object or None, default=None (in)
432 """
433 def __init__(self,**kwargs):
434 super(LinearCombination, self).__init__(**kwargs)
435 self.declareParameter(f0=None, \
436 v0=None, \
437 f1=None, \
438 v1=None, \
439 f2=None, \
440 v2=None, \
441 f3=None, \
442 v3=None, \
443 f4=None, \
444 v4=None)
445
446 def out(self):
447 """
448 returns f0*v0+f1*v1+f2*v2+f3*v3+f4*v4.
449 Link against this method to get the output of this model.
450 """
451 if not self.f0 is None and not self.v0 is None:
452 fv0 = self.f0*self.v0
453 else:
454 fv0 = None
455
456 if not self.f1 is None and not self.v1 is None:
457 fv1 = self.f1*self.v1
458 else:
459 fv1 = None
460
461 if not self.f2 is None and not self.v2 is None:
462 fv2 = f2*v2
463 else:
464 fv2 = None
465
466 if not self.f3 is None and not self.v3 is None:
467 fv3 = self.f3*self.v3
468 else:
469 fv3 = None
470
471 if not self.f4 is None and not self.v4 is None:
472 fv4 = self.f4*self.v4
473 else:
474 fv4 = None
475
476 if fv0 is None:
477 out = 0.
478 else:
479 out = fv0
480 if not fv1 is None:
481 out += fv1
482 if not fv2 is None:
483 out += fv2
484 if not fv3 is None:
485 out += fv3
486 return out
487
488 class MergeConstraints(ParameterSet):
489 """
490 Returns a linear combination of the f0*v0+f1*v1+f2*v2+f3*v3+f4*v4
491 """
492 def __init__(self,**kwargs):
493 super(MergeConstraints, self).__init__(**kwargs)
494 self.declareParameter(location_of_constraint0=None, \
495 value_of_constraint0=None, \
496 location_of_constraint1=None, \
497 value_of_constraint1=None, \
498 location_of_constraint2=None, \
499 value_of_constraint2=None, \
500 location_of_constraint3=None, \
501 value_of_constraint3=None, \
502 location_of_constraint4=None, \
503 value_of_constraint4=None)
504 def location_of_constraint(self):
505 """
506 return the values used to constrain a solution
507
508 :return: the mask marking the locations of the constraints
509 :rtype: `escript.Scalar`
510 """
511 out_loc=0
512 if not self.location_of_constraint0 is None:
513 out_loc=wherePositive(out_loc+wherePositive(self.location_of_constraint0))
514 if not self.location_of_constraint1 is None:
515 out_loc=wherePositive(out_loc+wherePositive(self.location_of_constraint1))
516 if not self.location_of_constraint2 is None:
517 out_loc=wherePositive(out_loc+wherePositive(self.location_of_constraint2))
518 if not self.location_of_constraint3 is None:
519 out_loc=wherePositive(out_loc+wherePositive(self.location_of_constraint3))
520 return out_loc
521
522 def value_of_constraint(self):
523 """
524 return the values used to constrain a solution
525
526 :return: values to be used at the locations of the constraints. If
527 ``value`` is not given ``None`` is rerturned.
528 :rtype: `escript.Scalar`
529 """
530 out_loc=0
531 out=0
532 if not self.location_of_constraint0 is None:
533 tmp=wherePositive(self.location_of_constraint0)
534 out=out*(1.-tmp)+self.value_of_constraint0*tmp
535 out_loc=wherePositive(out_loc+tmp)
536 if not self.location_of_constraint1 is None:
537 tmp=wherePositive(self.location_of_constraint1)
538 out=out*(1.-tmp)+self.value_of_constraint1*tmp
539 out_loc=wherePositive(out_loc+tmp)
540 if not self.location_of_constraint2 is None:
541 tmp=wherePositive(self.location_of_constraint2)
542 out=out*(1.-tmp)+self.value_of_constraint2*tmp
543 out_loc=wherePositive(out_loc+tmp)
544 if not self.location_of_constraint3 is None:
545 tmp=wherePositive(self.location_of_constraint3)
546 out=out*(1.-tmp)+self.value_of_constraint3*tmp
547 out_loc=wherePositive(out_loc+tmp)
548 return out
549 # vim: expandtab shiftwidth=4:

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26