File: subsidence.py

package info (click to toggle)
python-escript 5.6-10
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 144,304 kB
  • sloc: python: 592,074; cpp: 136,909; ansic: 18,675; javascript: 9,411; xml: 3,384; sh: 738; makefile: 207
file content (134 lines) | stat: -rw-r--r-- 4,528 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
##############################################################################
#
# Copyright (c) 2003-2018 by The University of Queensland
# http://www.uq.edu.au
#
# Primary Business: Queensland, Australia
# Licensed under the Apache License, version 2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Development until 2012 by Earth Systems Science Computational Center (ESSCC)
# Development 2012-2013 by School of Earth Sciences
# Development from 2014 by Centre for Geoscience Computing (GeoComp)
#
##############################################################################

"""Forward model for Subsidence modelling"""
from __future__ import division, print_function

__copyright__="""Copyright (c) 2003-2018 by The University of Queensland
http://www.uq.edu.au
Primary Business: Queensland, Australia"""
__license__="""Licensed under the Apache License, version 2.0
http://www.apache.org/licenses/LICENSE-2.0"""
__url__="https://launchpad.net/escript-finley"

__all__ = ['Subsidence']

from .base import ForwardModel
from esys.escript import Data, FunctionOnBoundary
from esys.escript.linearPDEs import LinearPDESystem
from esys.escript.util import *


class Subsidence(ForwardModel):
    """
    Forward Model for subsidence inversion minimizing
    integrate( (inner(w,u)-d)**2)
    where u is the surface displacement due to a pressure change P
    """
    def __init__(self, domain, w, d, lam, mu, coordinates=None, tol=1e-8):
        """
        Creates a new subsidence on the given domain

        :param domain: domain of the model
        :type domain: `Domain`
        :param w: data weighting factors and direction
        :type w: ``Vector`` with ``FunctionOnBoundary``
        :param d: displacement measured at surface
        :type d: ``Scalar`` with ``FunctionOnBoundary``
        :param lam: 1st Lame coefficient
        :type lam: ``Scalar`` with ``Function``
        :param lam: 2st Lame coefficient/Shear modulus
        :type lam: ``Scalar`` with ``Function``
        :param coordinates: defines coordinate system to be used (not supported yet))
        :type coordinates: `ReferenceSystem` or `SpatialCoordinateTransformation`
        :param tol: tolerance of underlying PDE
        :type tol: positive ``float``
        """
        super(Subsidence, self).__init__()
        DIM=domain.getDim()

        self.__pde=LinearPDESystem(domain)
        self.__pde.setSymmetryOn()
        self.__pde.getSolverOptions().setTolerance(tol)
        #... set coefficients ...
        C=self.__pde.createCoefficient('A')
        for i in range(DIM):
            for j in range(DIM):
                C[i,i,j,j]+=lam
                C[i,j,i,j]+=mu
                C[i,j,j,i]+=mu
        x=domain.getX()
        msk=whereZero(x[DIM-1])*kronecker(DIM)[DIM-1]
        for i in range(DIM-1):
            xi=x[i]
            msk+=(whereZero(xi-inf(xi))+whereZero(xi-sup(xi))) *kronecker(DIM)[i]
        self.__pde.setValue(A=C,q=msk)

        self.__w=interpolate(w, FunctionOnBoundary(domain))
        self.__d=interpolate(d, FunctionOnBoundary(domain))

    def rescaleWeights(self, scale=1., P_scale=1.):
        """
        rescales the weights
        
        :param scale: scale of data weighting factors
        :type scale: positive ``float``
        :param P_scale: scale of pressure increment
        :type P_scale: ``Scalar``
        """
        pass

    def getArguments(self, P):
        """
        Returns precomputed values shared by `getDefect()` and `getGradient()`.

        :param P: pressure
        :type P: ``Scalar``
        :return: displacement u
        :rtype: ``Vector``
        """
        DIM=self.__pde.getDim()
        self.__pde.setValue(y=Data(),X=P*kronecker(DIM))
        u= self.__pde.getSolution()
        return u,

    def getDefect(self, P,u):
        """
        Returns the value of the defect.

        :param P: pressure
        :type P: ``Scalar``
        :param u: corresponding displacement
        :type u: ``Vector``
        :rtype: ``float``
        """
        return 0.5*integrate((inner(u,self.__w)-self.__d)**2)

    def getGradient(self, P, u):
        """
        Returns the gradient of the defect with respect to susceptibility.

        :param P: pressure
        :type P: ``Scalar``
        :param u: corresponding displacement
        :type u: ``Vector``
        :rtype: ``Scalar``
        """
        d=inner(u,self.__w)-self.__d
        self.__pde.setValue(y=d*self.__w,X=Data())
        ustar=self.__pde.getSolution()

        return div(ustar)