/[escript]/trunk/downunder/py_src/regularizations.py
ViewVC logotype

Annotation of /trunk/downunder/py_src/regularizations.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4213 - (hide annotations)
Tue Feb 19 01:16:29 2013 UTC (7 years, 5 months ago) by caltinay
File MIME type: text/x-python
File size: 20477 byte(s)
Some cleanup and more consistent logging.

1 caltinay 3946
2 jfenwick 3981 ##############################################################################
3 caltinay 3946 #
4 jfenwick 4154 # Copyright (c) 2003-2013 by University of Queensland
5 jfenwick 3981 # http://www.uq.edu.au
6 caltinay 3946 #
7     # Primary Business: Queensland, Australia
8     # Licensed under the Open Software License version 3.0
9     # http://www.opensource.org/licenses/osl-3.0.php
10     #
11 jfenwick 3981 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12     # Development since 2012 by School of Earth Sciences
13     #
14     ##############################################################################
15 caltinay 3946
16 jfenwick 4154 __copyright__="""Copyright (c) 2003-2013 by University of Queensland
17 jfenwick 3981 http://www.uq.edu.au
18 caltinay 3946 Primary Business: Queensland, Australia"""
19     __license__="""Licensed under the Open Software License version 3.0
20     http://www.opensource.org/licenses/osl-3.0.php"""
21     __url__="https://launchpad.net/escript-finley"
22    
23 caltinay 3947 __all__ = ['Regularization']
24    
25 gross 4074 from costfunctions import CostFunction
26    
27 caltinay 3946 import numpy as np
28 caltinay 4211 from esys.escript import Function, outer, Data, Scalar, grad, inner, integrate, interpolate, kronecker, boundingBoxEdgeLengths, vol, sqrt, length
29 gross 4074 from esys.escript.linearPDEs import LinearPDE, IllegalCoefficientValue
30     from esys.escript.pdetools import ArithmeticTuple
31 caltinay 3946
32 gross 4074 class Regularization(CostFunction):
33 caltinay 3946 """
34 caltinay 4097 The regularization term for the level set function ``m`` within the cost
35     function J for an inversion:
36    
37 gross 4099 *J(m)=1/2 * sum_k imtegrate( mu[k] * ( w0[k] * m_k**2 * w1[k,i] * m_{k,i}**2) + sum_l<k mu_c[l,k] wc[l,k] * | curl(m_k) x curl(m_l) |^2*
38 caltinay 4097
39 gross 4099 where w0[k], w1[k,i] and wc[k,l] are non-negative weighting factors and
40     mu[k] and mu_c[l,k] are trade-off factors which may be altered
41     during the inversion. The weighting factors are normalized such that their
42 caltinay 4097 integrals over the domain are constant:
43    
44 gross 4099 *integrate(w0[k] + inner(w1[k,:],1/L[:]**2))=scale[k]* volume(domain)*
45     *integrate(wc[l,k]*1/L**4)=scale_c[k]* volume(domain) *
46 caltinay 4097
47 caltinay 3946 """
48 caltinay 4097 def __init__(self, domain, numLevelSets=1,
49 gross 4099 w0=None, w1=None, wc=None,
50 caltinay 4097 location_of_set_m=Data(),
51 gross 4099 useDiagonalHessianApproximation=False, tol=1e-8,
52     scale=None, scale_c=None):
53 caltinay 4007 """
54 caltinay 4095 initialization.
55 caltinay 4097
56     :param domain: domain
57 gross 4074 :type domain: `Domain`
58     :param numLevelSets: number of level sets
59     :type numLevelSets: ``int``
60 gross 4099 :param w0: weighting factor for the m**2 term. If not set zero is assumed.
61     :type w0: ``Scalar`` if ``numLevelSets`` == 1 or `Data` object of shape
62 caltinay 4097 (``numLevelSets`` ,) if ``numLevelSets`` > 1
63 gross 4099 :param w1: weighting factor for the grad(m_i) terms. If not set zero is assumed
64     :type w1: ``Vector`` if ``numLevelSets`` == 1 or `Data` object of shape
65 caltinay 4097 (``numLevelSets`` , DIM) if ``numLevelSets`` > 1
66 gross 4099 :param wc: weighting factor for the cross gradient terms. If not set
67 caltinay 4097 zero is assumed. Used for the case if ``numLevelSets`` > 1
68 gross 4099 only. Only values ``wc[l,k]`` in the lower triangle (l<k)
69 caltinay 4097 are used.
70 gross 4099 :type wc: `Data` object of shape (``numLevelSets`` , ``numLevelSets``)
71 caltinay 4097 :param location_of_set_m: marks location of zero values of the level
72     set function ``m`` by a positive entry.
73     :type location_of_set_m: ``Scalar`` if ``numLevelSets`` == 1 or `Data`
74     object of shape (``numLevelSets`` ,) if ``numLevelSets`` > 1
75 gross 4099 :param useDiagonalHessianApproximation: if True cross gradient terms
76 caltinay 4097 between level set components are ignored when calculating
77     approximations of the inverse of the Hessian Operator.
78     This can speed-up the calculation of the inverse but may
79     lead to an increase of the number of iteration steps in the
80     inversion.
81 gross 4074 :type useDiagonalHessianApproximation: ``bool``
82 caltinay 4097 :param tol: tolerance when solving the PDE for the inverse of the
83     Hessian Operator
84 gross 4074 :type tol: positive ``float``
85 caltinay 4213
86     :param scale: weighting factor for level set function variation terms. If not set one is used.
87 gross 4099 :type scale: ``Scalar`` if ``numLevelSets`` == 1 or `Data` object of shape
88     (``numLevelSets`` ,) if ``numLevelSets`` > 1
89     :param scale_c: scale for the cross gradient terms. If not set
90     one is assumed. Used for the case if ``numLevelSets`` > 1
91     only. Only values ``scale_c[l,k]`` in the lower triangle (l<k)
92     are used.
93     :type scale_c: `Data` object of shape (``numLevelSets`` , ``numLevelSets``)
94 caltinay 4095
95 caltinay 4007 """
96 gross 4099 if w0 == None and w1==None:
97     raise ValueError("Values for w0 or for w1 must be given.")
98 caltinay 4132 if wc == None and numLevelSets>1:
99     raise ValueError("Values for wc must be given.")
100 caltinay 4097
101 caltinay 3946 self.__domain=domain
102 gross 4074 DIM=self.__domain.getDim()
103     self.__numLevelSets=numLevelSets
104 caltinay 4213
105 caltinay 4095 self.__pde=LinearPDE(self.__domain, numEquations=self.__numLevelSets)
106 gross 4074 self.__pde.getSolverOptions().setTolerance(tol)
107     self.__pde.setSymmetryOn()
108     try:
109 caltinay 4097 self.__pde.setValue(q=location_of_set_m)
110     except IllegalCoefficientValue:
111     raise ValueError("Unable to set location of fixed level set function.")
112 caltinay 4213
113     # =========== check the shape of the scales: ========================
114 gross 4099 if scale is None:
115 caltinay 4132 if numLevelSets == 1 :
116     scale = 1.
117 gross 4074 else:
118 caltinay 4132 scale = np.ones((numLevelSets,))
119     else:
120     scale=np.asarray(scale)
121     if numLevelSets == 1 :
122     if scale.shape == ():
123     if not scale > 0 :
124     raise ValueError("Value for scale must be positive.")
125     else:
126     raise ValueError("Unexpected shape %s for scale."%scale.shape)
127     else:
128     if scale.shape is (numLevelSets,):
129     if not min(scale) > 0:
130     raise ValueError("All value for scale must be positive.")
131     else:
132     raise ValueError("Unexpected shape %s for scale."%scale.shape)
133 caltinay 4213
134 gross 4099 if scale_c is None or numLevelSets < 2:
135 caltinay 4132 scale_c = np.ones((numLevelSets,numLevelSets))
136     else:
137     scale_c=np.asarray(scale_c)
138     if scale_c.shape == (numLevelSets,numLevelSets):
139     if not all( [ [ scale_c[l,k] > 0. for l in xrange(k) ] for k in xrange(1,numLevelSets) ]):
140     raise ValueError("All values in the lower triangle of scale_c must be positive.")
141 gross 4099 else:
142 caltinay 4132 raise ValueError("Unexpected shape %s for scale."%scale_c.shape)
143 caltinay 4213 # ===== check the shape of the weights: =============================
144 gross 4099 if w0 is not None:
145 caltinay 4132 w0 = interpolate(w0,self.__pde.getFunctionSpaceForCoefficient('D'))
146     s0=w0.getShape()
147     if numLevelSets == 1 :
148     if not s0 == () :
149     raise ValueError("Unexpected shape %s for weight w0."%s0)
150 gross 4099 else:
151 caltinay 4132 if not s0 == (numLevelSets,):
152 caltinay 4213 raise ValueError("Unexpected shape %s for weight w0."%s0)
153    
154 caltinay 4132 if not w1 is None:
155     w1 = interpolate(w1,self.__pde.getFunctionSpaceForCoefficient('A'))
156     s1=w1.getShape()
157     if numLevelSets is 1 :
158     if not s1 == (DIM,) :
159     raise ValueError("Unexpected shape %s for weight w1."%s1)
160 gross 4099 else:
161 caltinay 4132 if not s1 == (numLevelSets,DIM):
162 caltinay 4213 raise ValueError("Unexpected shape %s for weight w1."%s1)
163    
164     if numLevelSets == 1:
165 gross 4099 wc=None
166     else:
167     wc = interpolate(wc,self.__pde.getFunctionSpaceForCoefficient('A'))
168     sc=wc.getShape()
169 gross 4124 if not sc == (numLevelSets, numLevelSets):
170     raise ValueError("Unexpected shape %s for weight wc."%(sc,))
171 caltinay 4213 # ============= now we rescale weights: =============================
172 gross 4099 L2s=np.asarray(boundingBoxEdgeLengths(domain))**2
173     L4=1/np.sum(1/L2s)**2
174 caltinay 4213 if numLevelSets == 1:
175 gross 4099 A=0
176     if w0 is not None:
177 caltinay 4132 A = integrate(w0)
178     if w1 is not None:
179     A += integrate(inner(w1, 1/L2s))
180     if A > 0:
181     f = scale/A
182     if w0 is not None:
183     w0*=f
184     if w1 is not None:
185     w1*=f
186 gross 4099 else:
187 caltinay 4213 raise ValueError("Non-positive weighting factor detected.")
188 gross 4099 else:
189 gross 4124
190 caltinay 4132 for k in xrange(numLevelSets):
191     A=0
192 gross 4099 if w0 is not None:
193 caltinay 4132 A = integrate(w0[k])
194     if w1 is not None:
195     A += integrate(inner(w1[k,:], 1/L2s))
196     if A > 0:
197     f = scale[k]/A
198     if w0 is not None:
199     w0[k]*=f
200     if w1 is not None:
201     w1[k,:]*=f
202 caltinay 4095 else:
203 caltinay 4213 raise ValueError("Non-positive weighting factor for level set component %d detected."%k)
204    
205 caltinay 4132 # and now the cross-gradient:
206     if wc is not None:
207 caltinay 4213 for l in xrange(k):
208 caltinay 4132 A = integrate(wc[l,k])/L4
209     if A > 0:
210     f = scale_c[l,k]/A
211     wc[l,k]*=f
212 gross 4124 # else:
213 caltinay 4213 # raise ValueError("Non-positive weighting factor for cross-gradient level set components %d and %d detected."%(l,k))
214    
215 gross 4099 self.__w0=w0
216     self.__w1=w1
217     self.__wc=wc
218 caltinay 4097
219 caltinay 4213 self.__pde_is_set=False
220 gross 4099 if self.__numLevelSets > 1:
221     self.__useDiagonalHessianApproximation=useDiagonalHessianApproximation
222     else:
223     self.__useDiagonalHessianApproximation=True
224     self._update_Hessian=True
225 caltinay 4097
226 gross 4099 self.__num_tradeoff_factors=numLevelSets+((numLevelSets-1)*numLevelSets)/2
227     self.setTradeOffFactors()
228 gross 4102 self.__vol_d=vol(self.__domain)
229 caltinay 4213
230 gross 4074 def getDomain(self):
231 caltinay 3946 """
232 caltinay 4097 returns the domain of the regularization term
233    
234 gross 4074 :rtype: ``Domain``
235 caltinay 3946 """
236 gross 4074 return self.__domain
237 caltinay 4097
238 gross 4074 def getNumLevelSets(self):
239     """
240 caltinay 4097 returns the number of level set functions
241    
242 gross 4074 :rtype: ``int``
243     """
244     return self.__numLevelSets
245 caltinay 3946
246 gross 4074 def getPDE(self):
247 caltinay 4007 """
248 gross 4074 returns the linear PDE to be solved for the Hessian Operator inverse
249 caltinay 4097
250     :rtype: `LinearPDE`
251 caltinay 4007 """
252 gross 4074 return self.__pde
253 caltinay 4213
254 gross 4074 def getDualProduct(self, m, r):
255     """
256 caltinay 4097 returns the dual product of a gradient represented by X=r[1] and Y=r[0]
257     with a level set function m:
258    
259 gross 4074 *Y_i*m_i + X_ij*m_{i,j}*
260 caltinay 4097
261     :type m: `Data`
262     :type r: `ArithmeticTuple`
263     :rtype: ``float``
264 gross 4074 """
265     A=0
266     if not r[0].isEmpty(): A+=integrate(inner(r[0], m))
267     if not r[1].isEmpty(): A+=integrate(inner(r[1], grad(m)))
268 caltinay 4095 return A
269 gross 4099 def getNumTradeOffFactors(self):
270     """
271     returns the number of trade-off factors being used.
272 caltinay 3946
273 gross 4099 :rtype: ``int``
274     """
275     return self.__num_tradeoff_factors
276    
277     def setTradeOffFactors(self, mu=None):
278     """
279     sets the trade-off factors for the level-set variation and the cross-gradient
280 caltinay 4213
281     :param mu: new values for the trade-off factors where values mu[:numLevelSets] are the
282     trade-off factors for the level-set variation and the remaining values for
283 gross 4099 the cross-gradient part with mu_c[l,k]=mu[numLevelSets+l+((k-1)*k)/2] (l<k).
284     If no values for mu is given ones are used. Values must be positive.
285     :type mu: ``list`` of ``float`` or ```numpy.array```
286     """
287     numLS=self.getNumLevelSets()
288     numTF=self.getNumTradeOffFactors()
289     if mu is None:
290 caltinay 4132 mu = np.ones((numTF,))
291     else:
292     mu = np.asarray(mu)
293 gross 4099
294 caltinay 4132 if mu.shape == (numTF,):
295     self.setTradeOffFactorsForVariation(mu[:numLS])
296     mu_c2=np.zeros((numLS,numLS))
297     for k in xrange(numLS):
298     for l in xrange(k):
299 caltinay 4213 mu_c2[l,k] = mu[numLS+l+((k-1)*k)/2]
300 caltinay 4132 self.setTradeOffFactorsForCrossGradient(mu_c2)
301     elif mu.shape == () and numLS ==1:
302     self.setTradeOffFactorsForVariation(mu)
303     else:
304 caltinay 4213 raise ValueError("Unexpected shape %s for mu."%(mu.shape,))
305    
306 gross 4099 def setTradeOffFactorsForVariation(self, mu=None):
307     """
308     sets the trade-off factors for the level-set variation part
309 caltinay 4213
310 gross 4099 :param mu: new values for the trade-off factors. Values must be positive.
311 caltinay 4132 :type mu: ``float``, ``list`` of ``float`` or ```numpy.array```
312 gross 4099 """
313     numLS=self.getNumLevelSets()
314     if mu is None:
315 caltinay 4132 if numLS == 1:
316     mu = 1.
317     else:
318     mu = np.ones((numLS,))
319 gross 4099
320 caltinay 4132 mu=np.asarray(mu)
321     if numLS == 1:
322 caltinay 4213 if mu.shape == (1,): mu=mu[0]
323 caltinay 4132 if mu.shape == ():
324     if mu > 0:
325     self.__mu= mu
326     self._new_mu=True
327     else:
328 caltinay 4213 raise ValueError("Value for trade-off factor must be positive.")
329 gross 4099 else:
330 caltinay 4132 raise ValueError("Unexpected shape %s for mu."%mu.shape)
331     else:
332     if mu.shape == (numLS,):
333     if min(mu) > 0:
334     self.__mu= mu
335     self._new_mu=True
336     else:
337     raise ValueError("All value for mu must be positive.")
338     else:
339 caltinay 4213 raise ValueError("Unexpected shape %s for trade-off factor."%mu.shape)
340 gross 4099
341     def setTradeOffFactorsForCrossGradient(self, mu_c=None):
342     """
343 caltinay 4132 sets the trade-off factors for the cross-gradient terms
344 caltinay 4213
345 caltinay 4132 :param mu_c: new values for the trade-off factors for the cross-gradient
346     terms. Values must be positive. If no value is given ones
347     are used. Onky value mu_c[l,k] for l<k are used.
348     :type mu_c: ``float``, ``list`` of ``float`` or ``numpy.array``
349 gross 4099 """
350     numLS=self.getNumLevelSets()
351     if mu_c is None or numLS < 2:
352 caltinay 4132 self.__mu_c = np.ones((numLS,numLS))
353     if isinstance(mu_c, float) or isinstance(mu_c, int):
354     self.__mu_c = np.zeros((numLS,numLS))
355 caltinay 4213 self.__mu_c[:,:]=mu_c
356 caltinay 4132 else:
357     mu_c=np.asarray(mu_c)
358     if mu_c.shape == (numLS,numLS):
359     if not all( [ [ mu_c[l,k] > 0. for l in xrange(k) ] for k in xrange(1,numLS) ]):
360     raise ValueError("All trade-off factors in the lower triangle of mu_c must be positive.")
361     else:
362     self.__mu_c = mu_c
363     self._new_mu=True
364 gross 4099 else:
365 caltinay 4132 raise ValueError("Unexpected shape %s for mu."%mu_c.shape)
366 caltinay 4213
367 gross 4099 def getArguments(self, m):
368     """
369     """
370     return ( grad(m),)
371    
372 gross 4074 def getValue(self, m, grad_m):
373 caltinay 4007 """
374 caltinay 4097 returns the value of the cost function J with respect to m.
375    
376 gross 4074 :rtype: ``float``
377 caltinay 4007 """
378 gross 4099 mu=self.__mu
379     mu_c=self.__mu_c
380 gross 4074 DIM=self.getDomain().getDim()
381     numLS=self.getNumLevelSets()
382 caltinay 4097
383 caltinay 3946 A=0
384 gross 4099 if self.__w0 is not None:
385     A+=inner(integrate(m**2 * self.__w0), mu)
386 caltinay 4097
387 gross 4099 if self.__w1 is not None:
388 caltinay 4095 if numLS == 1:
389 gross 4099 A+=integrate(inner(grad_m**2, self.__w1))*mu
390 caltinay 4095 else:
391     for k in xrange(numLS):
392 gross 4099 A+=mu[k]*integrate(inner(grad_m[k,:]**2,self.__w1[k,:]))
393 caltinay 4213
394 gross 4099 if numLS > 1:
395 caltinay 4097 for k in xrange(numLS):
396     gk=grad_m[k,:]
397     len_gk=length(gk)
398     for l in xrange(k):
399     gl=grad_m[l,:]
400 gross 4099 A+= mu_c[l,k] * integrate( self.__wc[l,k] * ( len_gk * length(gl) )**2 - inner(gk, gl)**2 )
401 gross 4074 return A/2
402 caltinay 4097
403 gross 4074 def getGradient(self, m, grad_m):
404     """
405 caltinay 4097 returns the gradient of the cost function J with respect to m.
406     The function returns Y_k=dPsi/dm_k and X_kj=dPsi/dm_kj
407 gross 4074 """
408 caltinay 4097
409 gross 4099 mu=self.__mu
410     mu_c=self.__mu_c
411 gross 4074 DIM=self.getDomain().getDim()
412     numLS=self.getNumLevelSets()
413 caltinay 4097
414 caltinay 4211 grad_m=grad(m, Function(m.getDomain()))
415 gross 4099 if self.__w0 is not None:
416     Y = m * self.__w0 * mu
417 caltinay 4095 else:
418 caltinay 4132 if numLS == 1:
419     Y = Scalar(0, grad_m.getFunctionSpace())
420     else:
421 gross 4122 Y = Data(0, (numLS,) , grad_m.getFunctionSpace())
422 caltinay 3946
423 gross 4099 if self.__w1 is not None:
424 caltinay 4132 X=grad_m*self.__w1
425 caltinay 4095 if numLS == 1:
426 gross 4099 X=grad_m* self.__w1*mu
427 caltinay 4095 else:
428     for k in xrange(numLS):
429 gross 4099 X[k,:]*=mu[k]
430 caltinay 4095 else:
431 gross 4122 X = Data(0, grad_m.getShape(), grad_m.getFunctionSpace())
432 caltinay 4213
433 gross 4122 # cross gradient terms:
434 caltinay 4213 if numLS > 1:
435 caltinay 4132 for k in xrange(numLS):
436     grad_m_k=grad_m[k,:]
437     l2_grad_m_k = length(grad_m_k)**2
438     for l in xrange(k):
439     grad_m_l=grad_m[l,:]
440     l2_grad_m_l = length(grad_m_l)**2
441     grad_m_lk = inner(grad_m_l, grad_m_k)
442     f= mu_c[l,k]* self.__wc[l,k]
443     X[l,:] += f * ( l2_grad_m_l * grad_m_l - grad_m_lk * grad_m_k )
444     X[k,:] += f * ( l2_grad_m_k * grad_m_k - grad_m_lk * grad_m_l )
445 caltinay 4213
446 gross 4074 return ArithmeticTuple(Y, X)
447 caltinay 4097
448 gross 4074 def getInverseHessianApproximation(self, m, r, grad_m):
449     """
450     """
451     if self._new_mu or self._update_Hessian:
452 caltinay 4097
453 caltinay 4095 self._new_mu=False
454     self._update_Hessian=False
455 gross 4099 mu=self.__mu
456     mu_c=self.__mu_c
457 caltinay 4097
458 gross 4074 DIM=self.getDomain().getDim()
459     numLS=self.getNumLevelSets()
460 gross 4099 if self.__w0 is not None:
461 caltinay 4095 if numLS == 1:
462 gross 4099 D=self.__w0 * mu
463 caltinay 4097 else:
464 gross 4074 D=self.getPDE().createCoefficient("D")
465 gross 4099 for k in xrange(numLS): D[k,k]=self.__w0[k] * mu[k]
466 caltinay 4095 self.getPDE().setValue(D=D)
467 caltinay 3946
468 caltinay 4095 A=self.getPDE().createCoefficient("A")
469 gross 4099 if self.__w1 is not None:
470 caltinay 4095 if numLS == 1:
471 gross 4099 for i in xrange(DIM): A[i,i]=self.__w1[i] * mu
472 caltinay 4095 else:
473 caltinay 4097 for k in xrange(numLS):
474 gross 4099 for i in xrange(DIM): A[k,i,k,i]=self.__w1[k,i] * mu[k]
475 caltinay 4213
476 gross 4099 if numLS > 1:
477 caltinay 4132 for k in xrange(numLS):
478     grad_m_k=grad_m[k,:]
479     l2_grad_m_k = length(grad_m_k)**2
480     o_kk=outer(grad_m_k, grad_m_k)
481     for l in xrange(k):
482     grad_m_l=grad_m[l,:]
483     l2_grad_m_l = length(grad_m_l)**2
484     i_lk = inner(grad_m_l, grad_m_k)
485     o_lk = outer(grad_m_l, grad_m_k)
486     o_kl = outer(grad_m_k, grad_m_l)
487     o_ll=outer(grad_m_l, grad_m_l)
488     f= mu_c[l,k]* self.__wc[l,k]
489 caltinay 4213
490 caltinay 4132 A[l,:,l,:] += f * ( l2_grad_m_k * kronecker(DIM) - o_kk )
491     A[l,:,k,:] += f * ( 2 * o_lk - o_kl - i_lk * kronecker(DIM) )
492     A[k,:,l,:] += f * ( 2 * o_kl - o_lk - i_lk * kronecker(DIM) )
493     A[k,:,k,:] += f * ( l2_grad_m_l * kronecker(DIM) - o_ll )
494 gross 4074 self.getPDE().setValue(A=A)
495 gross 4102 #self.getPDE().resetRightHandSideCoefficients()
496     #self.getPDE().setValue(X=r[1])
497     #print "X only: ",self.getPDE().getSolution()
498     #self.getPDE().resetRightHandSideCoefficients()
499     #self.getPDE().setValue(Y=r[0])
500     #print "Y only: ",self.getPDE().getSolution()
501 caltinay 4097
502 gross 4079 self.getPDE().resetRightHandSideCoefficients()
503 gross 4074 self.getPDE().setValue(X=r[1], Y=r[0])
504     return self.getPDE().getSolution()
505 caltinay 4097
506 gross 4074 def updateHessian(self):
507     """
508     notify the class to recalculate the Hessian operator
509     """
510 caltinay 4095 if not self.__useDiagonalHessianApproximation:
511     self._update_Hessian=True
512 caltinay 4213
513 gross 4100 def getNorm(self, m):
514     """
515     returns the norm of ``m``
516    
517     :param m: level set function
518     :type m: `Data`
519     :rtype: ``float``
520     """
521 caltinay 4132 return sqrt(integrate(length(m)**2)/self.__vol_d)
522 caltinay 4213

  ViewVC Help
Powered by ViewVC 1.1.26