def getDerivative(self, m): """ returns the derivative of the mapping for m """ # return self.__sigma0 * self.__k # return self.__sigma0*self.__k*exp(self.__k*m) return (self.__sigma0 * self.__k * self.a * exp(-self.__k * m)) / (1 + exp(-self.__k * m)) ** 2
def createAbsorptionLayerFunction(x, absorption_zone=300 * U.m, absorption_cut=1.e-2, top_absorption=False): """ Creates a distribution which is one in the interior of the domain of `x` and is falling down to the value 'absorption_cut' over a margin of thickness 'absorption_zone' toward each boundary except the top of the domain. :param x: location of points in the domain :type x: `escript.Data` :param absorption_zone: thickness of the absorption zone :param absorption_cut: value of decay function on domain boundary :return: function on 'x' which is one in the iterior and decays to almost zero over a margin toward the boundary. """ if absorption_zone is None or absorption_zone == 0: return 1 dom = x.getDomain() bb = escript.boundingBox(dom) DIM = dom.getDim() decay = -escript.log(absorption_cut) / absorption_zone**2 f = 1 for i in range(DIM): x_i = x[i] x_l = x_i - (bb[i][0] + absorption_zone) m_l = escript.whereNegative(x_l) f = f * ((escript.exp(-decay * (x_l * m_l)**2) - 1) * m_l + 1) if top_absorption or not DIM - 1 == i: x_r = (bb[i][1] - absorption_zone) - x_i m_r = escript.whereNegative(x_r) f = f * ((escript.exp(-decay * (x_r * m_r)**2) - 1) * m_r + 1) return f
def getDerivative(self, m): """ returns the derivative of the mapping for m """ # return self.__sigma0 * self.__k # return self.__sigma0*self.__k*exp(self.__k*m) return (self.__sigma0 * self.__k * self.a * exp(-self.__k * m)) / (1 + exp(-self.__k * m))**2
def getDerivative(self, m): """ returns the value for the derivative of the mapping for m """ e = exp(m[0] + self.Mr) return (e * cos(m[1] + self.Mi)) * [[1, 0], [0, 1]] + ( e * sin(m[1] + self.Mi)) * [[0, -1], [1, 0]]
def getVelocity(self, t): """ get the velocity f'(t) at time `t` """ e2 = (self.__s * (t - self.__t0))**2 return (-3 + 2 * e2) * escript.exp(-e2) * 2 * self.__s**2 * (t - self.__t0)
def getValue(self, m): print("in get value inf(m)=", inf(m), " sup(m)=", sup(m)) # s=self.__sigma0 + (self.__sigma0 * self.__k*m) # s=self.__sigma0*exp(self.__k*m) #### use sigmoid mapping s = (self.__sigma0 * self.a / (1 + exp(-self.__k * m))) + self.minVal print("in get value inf(s)=", inf(s), " sup(s)=", sup(s)) if sup(s) != 0 and inf(s) != 0: print("in get value 1/inf(s)=", 1.0 / inf(s), " 1/sup(s)=", 1.0 / sup(s)) return s
def getValue(self, m): print("in get value inf(m)=", inf(m), " sup(m)=", sup(m)) # s=self.__sigma0 + (self.__sigma0 * self.__k*m) # s=self.__sigma0*exp(self.__k*m) #### use sigmoid mapping s = (self.__sigma0 * self.a / (1 + exp(-self.__k * m))) + self.minVal print("in get value inf(s)=", inf(s), " sup(s)=", sup(s)) if sup(s) != 0 and inf(s) != 0: print("in get value 1/inf(s)=", 1. / inf(s), " 1/sup(s)=", 1. / sup(s)) return s
def out(self): """ Generate the Gaussian profile Link against this method to get the output of this model. """ x = self.domain.getX() dim = self.domain.getDim() l = length(x - self.x_c[:dim]) m = whereNegative(l - self.r) return (m + (1. - m) * exp(-log(2.) * (l / self.width)**2)) * self.A
def out(self): """ Generate the Gaussian profile Link against this method to get the output of this model. """ x = self.domain.getX() dim = self.domain.getDim() l = length(x-self.x_c[:dim]) m = whereNegative(l-self.r) return (m+(1.-m)*exp(-log(2.)*(l/self.width)**2))*self.A
def calculate_viscosity(C, T=20.0): """ Calculate fluid viscosity following Batzle & Wang (1992). """ viscosity = 1e-3 * ( 0.1 + 0.333 * C + (1.65 + 91.9 * C**3) * es.exp(-(0.42 * (C**0.8 - 0.17)**2 + 0.045) * T**0.8)) return viscosity
def getDerivative(self, m): """ returns the value for the derivative of the mapping for m """ e = exp(m[0] + self.Mr) return (e * cos(m[1] + self.Mi)) * [[1, 0], [0, 1]] + (e * sin(m[1] + self.Mi)) * [[0, -1], [1, 0]]
def __init__(self, domain, omega, x, Z, eta=None, w0=1., mu=4 * math.pi * 1e-7, sigma0=0.01, airLayerLevel=None, fixAirLayer=False, coordinates=None, tol=1e-8, saveMemory=False, directSolver=True): """ initializes a new forward model. :param domain: domain of the model :type domain: `Domain` :param omega: frequency :type omega: positive ``float`` :param x: coordinates of measurements :type x: ``list`` of ``tuple`` with ``float`` :param Z: measured impedance (possibly scaled) :type Z: ``list`` of ``complex`` :param eta: spatial confidence radius :type eta: positive ``float`` or ``list`` of positive ``float`` :param w0: confidence factors for meassurements. :type w0: ``None`` or a list of positive ``float`` :param mu: permeability :type mu: ``float`` :param sigma0: background conductivity :type sigma0: ``float`` :param airLayerLevel: position of the air layer from to bottom of the domain. If not set the air layer starts at the top of the domain :type airLayerLevel: ``float`` or ``None`` :param fixAirLayer: fix air layer (TM mode) :type fixAirLayer: ``bool`` :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`` :param saveMemory: if true stiffness matrix is deleted after solution of the PDE to minimize memory use. This will require more compute time as the matrix needs to be reallocated at each iteration. :type saveMemory: ``bool`` :param directSolver: if true a direct solver (rather than an iterative solver) will be used to solve the PDE :type directSolver: ``bool`` """ super(MT2DBase, self).__init__() self.__trafo = coords.makeTransformation(domain, coordinates) if not self.getCoordinateTransformation().isCartesian(): raise ValueError( "Non-Cartesian coordinates are not supported yet.") if len(x) != len(Z): raise ValueError( "Number of data points and number of impedance values don't match." ) if eta is None: eta = escript.sup(domain.getSize()) * 0.45 if isinstance(eta, float) or isinstance(eta, int): eta = [float(eta)] * len(Z) elif not len(eta) == len(Z): raise ValueError( "Number of confidence radii and number of impedance values don't match." ) if isinstance(w0, float) or isinstance(w0, int): w0 = [float(w0)] * len(Z) elif not len(w0) == len(Z): raise ValueError( "Number of confidence factors and number of impedance values don't match." ) self.__domain = domain self._omega_mu = omega * mu self._ks = escript.sqrt(self._omega_mu * sigma0 / 2.) xx = escript.Function(domain).getX() totalS = 0 self._Z = [ escript.Scalar(0., escript.Function(domain)), escript.Scalar(0., escript.Function(domain)) ] self._weight = escript.Scalar(0., escript.Function(domain)) for s in range(len(Z)): chi = self.getWeightingFactor(xx, 1., x[s], eta[s]) f = escript.integrate(chi) if f < eta[s]**2 * 0.01: raise ValueError( "Zero weight (almost) for data point %s. Change eta or refine mesh." % (s, )) w02 = w0[s] / f totalS += w02 self._Z[0] += chi * Z[s].real self._Z[1] += chi * Z[s].imag self._weight += chi * w02 / (abs(Z[s])**2) if not totalS > 0: raise ValueError( "Scaling of weight factors failed as sum is zero.") DIM = domain.getDim() z = domain.getX()[DIM - 1] self._ztop = escript.sup(z) self._zbottom = escript.inf(z) if airLayerLevel is None: airLayerLevel = self._ztop self._airLayerLevel = airLayerLevel # botton: mask0 = escript.whereZero(z - self._zbottom) r = mask0 * [ escript.exp(self._ks * (self._zbottom - airLayerLevel)) * escript.cos(self._ks * (self._zbottom - airLayerLevel)), escript.exp(self._ks * (self._zbottom - airLayerLevel)) * escript.sin(self._ks * (self._zbottom - airLayerLevel)) ] #top: if fixAirLayer: mask1 = escript.whereNonNegative(z - airLayerLevel) r += mask1 * [1, 0] else: mask1 = escript.whereZero(z - self._ztop) r += mask1 * [ self._ks * (self._ztop - airLayerLevel) + 1, self._ks * (self._ztop - airLayerLevel) ] self._q = (mask0 + mask1) * [1, 1] self._r = r #==================================== self.__tol = tol self._directSolver = directSolver self._saveMemory = saveMemory self.__pde = None if not saveMemory: self.__pde = self.setUpPDE()
def getValue(self, t): """ get value of wavelet at time `t` """ e2 = (self.__s * (t - self.__t0))**2 return (1 - 2 * e2) * escript.exp(-e2)
def getAcceleration(self, t): """ get the acceleration f''(t) at time `t` """ e2 = (self.__s * (t - self.__t0))**2 return 2 * self.__s**2 * (-4 * e2**2 + 12 * e2 - 3) * escript.exp(-e2)
def getDerivative(self, m): """ returns the derivative of the mapping for m """ return self.__sigma0 * self.__a * exp(self.__a * m)
def getValue(self, m): """ returns the value of the mapping for m """ return self.__sigma0 * exp(self.__a * m)
def getValue(self, m): """ returns the value of the mapping for m """ return exp(m[0] + self.Mr) * (cos(m[1] + self.Mi) * [1, 0] + sin(m[1] + self.Mi) * [0, 1])