package org.opensha2.gmm; import static java.lang.Math.exp; import static java.lang.Math.log; import static java.lang.Math.max; import static java.lang.Math.sqrt; import static org.opensha2.gmm.FaultStyle.REVERSE; import static org.opensha2.gmm.FaultStyle.UNKNOWN; import static org.opensha2.gmm.GmmInput.Field.MW; import static org.opensha2.gmm.GmmInput.Field.RAKE; import static org.opensha2.gmm.GmmInput.Field.RRUP; import static org.opensha2.gmm.GmmInput.Field.VS30; import org.opensha2.eq.fault.Faults; import org.opensha2.gmm.GmmInput.Constraints; import com.google.common.collect.Range; import java.util.Map; /** * Implementation of the Campbell & Bozorgnia (2003) ground motion model for * shallow earthquakes in active continental crust. In keeping with prior NSHMP * implementations of this older model, only soft rock sites are supported * (V𝗌30 = 760 m/s) following specific guidance by the model authors. Longer * periods are also not implemented here due to a dependency on Boore, Joyner & * Fumal (1997) whose longest period is 2 sec. This implementation also ignores * the author's suggestion to use 'uncorrected' PGA values when computing PGA * and uses 'corrected' values for both PGA and spectral acceleration. * * <p><b>Note:</b> Direct instantiation of {@code GroundMotionModel}s is * prohibited. Use {@link Gmm#instance(Imt)} to retrieve an instance for a * desired {@link Imt}. * * <p><b>Reference:</b> Campbell, K.W., and Bozorgnia, Y., 2003, Updated * near-source ground-motion (attenuation) relations for the horizontal and * vertical components of peak ground acceleration and acceleration response * spectra: Bulletin of Seismological Society of America, v. 93, n. 1, p. * 314-331. * * <p><b>doi:</b> <a href="http://dx.doi.org/10.1785/0120020029"> * 10.1785/0120020029</a> * * <p><b>Errata doi:</b> <a href="http://dx.doi.org/10.1785/0120030143"> * 10.1785/0120030143</a> and <a href="http://dx.doi.org/10.1785/0120030099"> * 10.1785/0120030099</a> * * <p><b>Component:</b> average horizontal * * @author Allison Shumway * @author Peter Powers * @see Gmm#CB_03 */ public class CampbellBozorgnia_2003 implements GroundMotionModel { static final String NAME = "Campbell & Bozorgnia (2003)"; static final Constraints CONSTRAINTS = Constraints.builder() .set(MW, Range.closed(5.8, 8.0)) .set(RRUP, Range.closed(0.0, 300.0)) .set(RAKE, Faults.RAKE_RANGE) .set(VS30, Range.singleton(760.0)) .build(); static final CoefficientContainer COEFFS; static { COEFFS = new CoefficientContainer("CB03.csv"); } private static final class Coefficients { final double c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c13, c14, c15, c16; // unused // final double c4, c12, c17, n, r2; Coefficients(Imt imt, CoefficientContainer cc) { Map<String, Double> coeffs = cc.get(imt); c1 = coeffs.get("c1"); c2 = coeffs.get("c2"); c3 = coeffs.get("c3"); c4 = coeffs.get("c4"); c5 = coeffs.get("c5"); c6 = coeffs.get("c6"); c7 = coeffs.get("c7"); c8 = coeffs.get("c8"); c9 = coeffs.get("c9"); c10 = coeffs.get("c10"); c11 = coeffs.get("c11"); c13 = coeffs.get("c13"); c14 = coeffs.get("c14"); c15 = coeffs.get("c15"); c16 = coeffs.get("c16"); } } private static final class CoefficientsBjf97 { final double bv; CoefficientsBjf97(Imt imt, CoefficientContainer cc) { Map<String, Double> coeffs = cc.get(imt); bv = coeffs.get("bv"); } } private final Coefficients coeffs; private final CoefficientsBjf97 coeffsBjf97; private final double revStyleTerm; private final double unkStyleTerm; private final double gS; private final double f4; CampbellBozorgnia_2003(final Imt imt) { coeffs = new Coefficients(imt, COEFFS); coeffsBjf97 = new CoefficientsBjf97(imt, BooreEtAl_1997.COEFFS); revStyleTerm = 0.5 * coeffs.c10 + 0.5 * coeffs.c11; unkStyleTerm = 0.25 * coeffs.c10 + 0.25 * coeffs.c11; gS = coeffs.c5 + 0.5 * coeffs.c6 + 0.5 * coeffs.c7; f4 = 0.5 * coeffs.c13 + 0.5 * coeffs.c14 + coeffsBjf97.bv * log(760.0 / 620.0); } @Override public ScalarGroundMotion calc(GmmInput in) { double μ = calcMean(coeffs, in); double σ = calcStdDev(coeffs.c16, in.Mw); return DefaultScalarGroundMotion.create(μ, σ); } private final double calcMean( final Coefficients c, final GmmInput in) { double Mw = in.Mw; // magnitude scaling double mTerm = (8.5 - Mw) * (8.5 - Mw); double f1 = c.c2 * Mw + c.c3 * mTerm; // distance scaling - per verbal communication with Ken Campbell it // is ok to approximate rSeis by constraining rRup to be >= 3.0 km. // (see also Campbell 1997) double rSeis = max(in.rRup, 3.0); double rTerm = gS * exp(c.c8 * Mw + c.c9 * mTerm); double f2 = rSeis * rSeis + rTerm * rTerm; // focal mechanism FaultStyle style = GmmUtils.rakeToFaultStyle_NSHMP(in.rake); double f3 = (style == REVERSE) ? revStyleTerm : (style == UNKNOWN) ? unkStyleTerm : 0.0; // far-source effect of local site conditions // (pre-calculated) // hanging-wall effect double HW = (in.rJB < 5.0 && in.dip <= 70.0) ? (5.0 - in.rJB) / 5.0 : 0.0; double hwM = (Mw > 6.5) ? 1.0 : (Mw >= 5.5) ? Mw - 5.5 : 0.0; double hwR = (rSeis < 8.0) ? c.c15 * (rSeis / 8.0) : c.c15; double f5 = HW * f3 * hwM * hwR; return c.c1 + f1 + c.c4 * log(sqrt(f2)) + f3 + f4 + f5; } private static final double calcStdDev(final double c16, final double Mw) { return c16 - ((Mw < 7.4) ? 0.07 * Mw : 0.518); } }