package org.opensha2.gmm; import static java.lang.Math.log; import static java.lang.Math.sqrt; import static org.opensha2.gmm.GmmInput.Field.DIP; import static org.opensha2.gmm.GmmInput.Field.MW; import static org.opensha2.gmm.GmmInput.Field.RAKE; import static org.opensha2.gmm.GmmInput.Field.RJB; 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 Abrahamson & Silva (1997) 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). * * <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> Abrahamson, N. A. and W.J. Silva, 1997, Empirical * response spectral attenuation relations for shallow crustal earthquakes: * Seismological Research Letters, v. 68, n. 1, p. 94-127. * * <p><b>doi:</b> <a href="http://dx.doi.org/10.1785/gssrl.68.1.94"> * 10.1785/gssrl.68.1.94</a> * * <p><b>Component:</b> average horizontal * * @author Allison Shumway * @author Peter Powers * @see Gmm#AS_97 */ public class AbrahamsonSilva_1997 implements GroundMotionModel { static final String NAME = "Abrahamson & Silva (1997)"; static final Constraints CONSTRAINTS = Constraints.builder() .set(MW, Range.closed(4.0, 8.0)) .set(RJB, Range.closed(0.0, 300.0)) .set(RRUP, Range.closed(0.0, 300.0)) .set(DIP, Faults.DIP_RANGE) .set(RAKE, Faults.RAKE_RANGE) .set(VS30, Range.singleton(760.0)) .build(); static final CoefficientContainer COEFFS = new CoefficientContainer("AS97.csv"); private static final double A2 = 0.512; private static final double A4 = 0.144; private static final double A13 = 0.17; private static final double C1 = 6.4; private static final class Coefficients { final double a1, a3, a5, a6, a9, a12, b5, b6, c4; // same for all periods; replaced with constant // final double a2, a4, a13, c1, c5, n; // unused // final double a10, a11; Coefficients(Imt imt, CoefficientContainer cc) { Map<String, Double> coeffs = cc.get(imt); a1 = coeffs.get("a1"); a3 = coeffs.get("a3"); a5 = coeffs.get("a5"); a6 = coeffs.get("a6"); a9 = coeffs.get("a9"); a12 = coeffs.get("a12"); b5 = coeffs.get("b5"); b6 = coeffs.get("b6"); c4 = coeffs.get("c4"); } } private final Coefficients coeffs; AbrahamsonSilva_1997(final Imt imt) { coeffs = new Coefficients(imt, COEFFS); } @Override public ScalarGroundMotion calc(final GmmInput in) { double μ = calcMean(coeffs, in); double σ = calcStdDev(coeffs, in.Mw); return DefaultScalarGroundMotion.create(μ, σ); } private static final double calcMean(final Coefficients c, final GmmInput in) { // frequently used method locals double Mw = in.Mw; double rRup = in.rRup; double rake = in.rake; // base model double R = sqrt(rRup * rRup + c.c4 * c.c4); double f1 = c.a1 + (((Mw <= C1) ? A2 : A4) * (Mw - C1)) + (c.a12 * (8.5 - Mw) * (8.5 - Mw)) + (c.a3 + A13 * (Mw - C1)) * log(R); // style-of-faulting term - use rake to determine F; the values below // were derived from the OpenSHA implementation for which guidance was // supplied by Norm Abrahamson double f3 = 0.0; if (rake > 67.5 && rake < 112.5) { f3 = calcFaultStyle(c, Mw); } else if (rake > 22.5 && rake < 157.5) { f3 = 0.5 * calcFaultStyle(c, Mw); } // hanging-wall term double f4 = 0.0; if (in.rJB == 0.0 && in.dip < 90.0) { double hwM = (Mw >= 6.5) ? 1.0 : (Mw > 5.5) ? Mw - 5.5 : 0.0; double hwR = 0.0; if (rRup < 4.0) { hwR = 0.0; } else if (rRup < 8.0) { hwR = c.a9 * (rRup - 4.0) / 4.0; } else if (rRup < 18.0) { hwR = c.a9; } else if (rRup < 25.0) { hwR = c.a9 * (1.0 - (rRup - 18.0) / 7.0); } f4 = hwM * hwR; } // no site response term required for rock (f5) return f1 + f3 + f4; } private static double calcFaultStyle(final Coefficients c, final double Mw) { return (Mw <= 5.8) ? c.a5 : (Mw < C1) ? c.a5 + (c.a6 - c.a5) / (C1 - 5.8) : c.a6; } private static double calcStdDev(final Coefficients c, final double Mw) { return (Mw <= 5.0) ? c.b5 : (Mw < 7.0) ? c.b5 - c.b6 * (Mw - 5.0) : c.b5 - 2 * c.b6; } }