Source code for openquake.hazardlib.correlation

# The Hazard Library
# Copyright (C) 2012-2016 GEM Foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
Module :mod:`openquake.hazardlib.correlation` defines correlation models for
spatially-distributed ground-shaking intensities.
"""
import abc
import numpy

from openquake.hazardlib.imt import SA, PGA
from openquake.baselib.python3compat import with_metaclass


[docs]class BaseCorrelationModel(with_metaclass(abc.ABCMeta)): """ Base class for correlation models for spatially-distributed ground-shaking intensities. """ @abc.abstractmethod
[docs] def get_lower_triangle_correlation_matrix(self, sites, imt): """ Get lower-triangle matrix as a result of Cholesky-decomposition of correlation matrix. The resulting matrix should have zeros on values above the main diagonal. The actual implementations of :class:`BaseCorrelationModel` interface might calculate the matrix considering site collection and IMT (like :class:`JB2009CorrelationModel` does) or might have it pre-constructed for a specific site collection and IMT, in which case they will need to make sure that parameters to this function match parameters that were used to pre-calculate decomposed correlation matrix. :param sites: :class:`~openquake.hazardlib.site.SiteCollection` to create correlation matrix for. :param imt: Intensity measure type object, see :mod:`openquake.hazardlib.imt`. """
[docs] def apply_correlation(self, sites, imt, residuals): """ Apply correlation to randomly sampled residuals. :param sites: :class:`~openquake.hazardlib.site.SiteCollection` residuals were sampled for. :param imt: Intensity measure type object, see :mod:`openquake.hazardlib.imt`. :param residuals: 2d numpy array of sampled residuals, where first dimension represents sites (the length as ``sites`` parameter) and second one represents different realizations (samples). :returns: Array of the same structure and semantics as ``residuals`` but with correlations applied. """ # intra-event residual for a single relization is a product # of lower-triangle decomposed correlation matrix and vector # of N random numbers (where N is equal to number of sites). # we need to do that multiplication once per realization # with the same matrix and different vectors. corma = self.get_lower_triangle_correlation_matrix(sites, imt) return numpy.dot(corma, residuals)
[docs]class JB2009CorrelationModel(BaseCorrelationModel): """ "Correlation model for spatially distributed ground-motion intensities" by Nirmal Jayaram and Jack W. Baker. Published in Earthquake Engineering and Structural Dynamics 2009; 38, pages 1687-1708. :param vs30_clustering: Boolean value to indicate whether "Case 1" or "Case 2" from page 1700 should be applied. ``True`` value means that Vs 30 values show or are expected to show clustering ("Case 2"), ``False`` means otherwise. """ def __init__(self, vs30_clustering): self.vs30_clustering = vs30_clustering super(JB2009CorrelationModel, self).__init__() def _get_correlation_matrix(self, sites, imt): """ Calculate correlation matrix for a given sites collection. Correlation depends on spectral period, Vs 30 clustering behaviour and distance between sites. Parameters are the same as for :meth:`BaseCorrelationModel.get_lower_triangle_correlation_matrix`. """ distances = sites.mesh.get_distance_matrix() return self._get_correlation_model(distances, imt) def _get_correlation_model(self, distances, imt): """ Returns the correlation model for a set of distances, given the appropriate period :param numpy.ndarray distances: Distance matrix :param float period: Period of spectral acceleration """ if isinstance(imt, SA): period = imt.period else: assert isinstance(imt, PGA), imt period = 0 # formulae are from page 1700 if period < 1: if not self.vs30_clustering: # case 1, eq. (17) b = 8.5 + 17.2 * period else: # case 2, eq. (18) b = 40.7 - 15.0 * period else: # both cases, eq. (19) b = 22.0 + 3.7 * period # eq. (20) return numpy.exp((- 3.0 / b) * distances)
[docs] def get_lower_triangle_correlation_matrix(self, sites, imt): """ See :meth:`BaseCorrelationModel.get_lower_triangle_correlation_matrix`. """ return numpy.linalg.cholesky(self._get_correlation_matrix(sites, imt))