From 9fa1943a2fd6a74bebdeb21a78511ab854998bd0 Mon Sep 17 00:00:00 2001 From: Jason Altekruse <jaltekruse@usgs.gov> Date: Mon, 3 Feb 2025 14:37:01 -0700 Subject: [PATCH] implementation of Spudich et al. (1999) for PRVI 2003 --- .../gov/usgs/earthquake/nshmp/gmm/Gmm.java | 7 + .../nshmp/gmm/SpudichEtAl_1999_PRVI.java | 121 ++++++++++++++++++ src/main/resources/gmm/coeffs/SEA99-PRVI.csv | 8 ++ .../usgs/earthquake/nshmp/gmm/SEA99_test.java | 47 +++++++ src/test/resources/gmm/sea99-inputs.csv | 7 + src/test/resources/gmm/sea99-results.csv | 24 ++++ 6 files changed, 214 insertions(+) create mode 100644 src/main/java/gov/usgs/earthquake/nshmp/gmm/SpudichEtAl_1999_PRVI.java create mode 100644 src/main/resources/gmm/coeffs/SEA99-PRVI.csv create mode 100644 src/test/java/gov/usgs/earthquake/nshmp/gmm/SEA99_test.java create mode 100644 src/test/resources/gmm/sea99-inputs.csv create mode 100644 src/test/resources/gmm/sea99-results.csv diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java index 9b23bb1c..f21baae8 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java @@ -1563,6 +1563,13 @@ public enum Gmm { UsgsPrviBackbone2025.COEFFS_SIGMA_SUBDUCTION, UsgsPrviBackbone2025.SlabTotal.CONSTRAINTS), + /* PRVI 2003 */ + SEA99_PRVI( + SpudichEtAl_1999_PRVI.class, + SpudichEtAl_1999_PRVI.NAME, + SpudichEtAl_1999_PRVI.COEFFS, + SpudichEtAl_1999_PRVI.CONSTRAINTS), + /* Combined: must be declared after any dependent models above. */ /** 2021 Hawaii weight-averaged GMM for deep earthquakes. */ diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/SpudichEtAl_1999_PRVI.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/SpudichEtAl_1999_PRVI.java new file mode 100644 index 00000000..c9b5dbfa --- /dev/null +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/SpudichEtAl_1999_PRVI.java @@ -0,0 +1,121 @@ +package gov.usgs.earthquake.nshmp.gmm; + +import static gov.usgs.earthquake.nshmp.Maths.TWO_PI; +import static gov.usgs.earthquake.nshmp.gmm.GmmInput.Field.MW; +import static gov.usgs.earthquake.nshmp.gmm.GmmInput.Field.RAKE; +import static gov.usgs.earthquake.nshmp.gmm.GmmInput.Field.RJB; +import static gov.usgs.earthquake.nshmp.gmm.GmmInput.Field.VS30; +import static gov.usgs.earthquake.nshmp.gmm.GmmUtils.BASE_10_TO_E; +import static java.lang.Math.log10; +import static java.lang.Math.sqrt; + +import java.util.Map; + +import com.google.common.collect.Range; + +import gov.usgs.earthquake.nshmp.Faults; +import gov.usgs.earthquake.nshmp.gmm.GmmInput.Constraints; +import gov.usgs.earthquake.nshmp.tree.LogicTree; + +/** + * PRVI-specific implementation of the Spudich et al. (1999) ground motion model + * for extensional tectonic regimes. This implementation was created to match a + * fortran implementation rather than adhere to the published model. For + * example, an errata published in 2005 corrects a sigma term, however this was + * not available for the 2003 PRVI model. + * + * Additional periods, not needed for PRVI 2003, are included to test + * implementation against Spudich et al. (1999) Table 3. + * + * <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> Spudich, P., Joyner, W.B., Lindh, A.G., Boore, D.M., + * Margaris, B.M., and Fletcher, J.B., 1999, SEA99: A revised ground motion + * prediction relation for use in extensional tectonic regimes, Bull. Seis. Soc. + * Am, v. 5, p. 1156-1170. + * + * <p><b>Component:</b> random horizontal + * + * @author U.S. Geological Survey + * @see Gmm#SEA99 + */ +public class SpudichEtAl_1999_PRVI implements GroundMotionModel { + + static final String NAME = "Spudich et al. (1999) : PRVI"; + + static final Constraints CONSTRAINTS = Constraints.builder() + .set(MW, Range.closed(4.0, 8.0)) // paper specifies M 5.0-707 + .set(RJB, Range.closed(0.0, 80.0)) // paper specifies Rjb 0-100 km + .set(RAKE, Faults.RAKE_RANGE) + .set(VS30, Range.singleton(760.0)) + .build(); + + static final CoefficientContainer COEFFS = new CoefficientContainer("SEA99-PRVI.csv"); + + private static final class Coefficients { + + final Imt imt; + final double b1, b2, b3, b5, h, σ; + + Coefficients(Imt imt, CoefficientContainer cc) { + this.imt = imt; + Map<String, Double> coeffs = cc.get(imt); + b1 = coeffs.get("b1"); + b2 = coeffs.get("b2"); + b3 = coeffs.get("b3"); + b5 = coeffs.get("b5"); + h = coeffs.get("h"); + σ = coeffs.get("sigma"); + } + } + + private final Coefficients coeffs; + + SpudichEtAl_1999_PRVI(Imt imt) { + coeffs = new Coefficients(imt, COEFFS); + } + + boolean interfaceZone() { + return false; + } + + @Override + public Imt imt() { + return coeffs.imt; + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + double μ = calcMean(coeffs, in); + return GroundMotions.createTree(μ, coeffs.σ); + } + + private final double calcMean(Coefficients c, GmmInput in) { + double mFac = in.Mw - 6.0; + double r = sqrt(in.rJB * in.rJB + c.h * c.h); + + double μlog10 = c.b1 + c.b2 * mFac + c.b3 * mFac * mFac + c.b5 * log10(r); + + // double μlog10orig = μlog10; + + /* convert from PSV in cm/sec to PSA in g - from hazgridXnga.samoa.f */ + if (c.imt != Imt.PGA) { + μlog10 = μlog10 + log10(TWO_PI / (980.0 * c.imt.period())); + } + + // if (c.imt == Imt.PGA && in.rJB == 0.0 && in.Mw == 5.5) { + // System.out.printf("Imt,Mw,Rjb,μlog10o,μlog10,μo,μ,σ\n"); + // } + // double μo = μlog10orig * BASE_10_TO_E; + // double μ = μlog10 * BASE_10_TO_E; + // System.out.printf("%s,%.1f,%.1f,%.6e,%.6e,%.6e,%.6e,%.4f\n", + // c.imt.name(), in.Mw, in.rJB, + // μlog10orig, μlog10, exp(μo), exp(μ), c.σ); + + // convert log10 to ln + return μlog10 * BASE_10_TO_E; + } + +} diff --git a/src/main/resources/gmm/coeffs/SEA99-PRVI.csv b/src/main/resources/gmm/coeffs/SEA99-PRVI.csv new file mode 100644 index 00000000..e3db4aad --- /dev/null +++ b/src/main/resources/gmm/coeffs/SEA99-PRVI.csv @@ -0,0 +1,8 @@ +T, b1, b2, b3, b4, b5, b6, h, sigma +PGA, 0.299, 0.229, 0.000, 0.0, -1.052, 0.112, 7.27, 0.224 +0.1, 2.144, 0.327, -0.098, 0.0, -1.250, 0.064, 9.99, 0.295 +0.2, 2.224, 0.309, -0.090, 0.0, -1.047, 0.088, 8.63, 0.262 +0.3, 2.263, 0.334, -0.070, 0.0, -1.020, 0.121, 7.72, 0.263 +0.5, 2.292, 0.384, -0.039, 0.0, -1.038, 0.166, 6.70, 0.275 +1.0, 2.276, 0.450, -0.014, 0.0, -1.083, 0.210, 6.01, 0.301 +2.0, 2.168, 0.471, -0.037, 0.0, -1.049, 0.197, 6.71, 0.341 diff --git a/src/test/java/gov/usgs/earthquake/nshmp/gmm/SEA99_test.java b/src/test/java/gov/usgs/earthquake/nshmp/gmm/SEA99_test.java new file mode 100644 index 00000000..a5c35892 --- /dev/null +++ b/src/test/java/gov/usgs/earthquake/nshmp/gmm/SEA99_test.java @@ -0,0 +1,47 @@ +package gov.usgs.earthquake.nshmp.gmm; + +import static gov.usgs.earthquake.nshmp.gmm.Gmm.SEA99_PRVI; +import static gov.usgs.earthquake.nshmp.gmm.Imt.PGA; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA0P1; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA0P5; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA2P0; + +import java.io.IOException; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +public class SEA99_test implements ArgumentsProvider { + + private static String GMM_INPUTS = "/gmm/sea99-inputs.csv"; + private static String GMM_RESULTS = "/gmm/sea99-results.csv"; + // Validated results against Spudich et al. (1999) Table 3 + + @ParameterizedTest(name = "({index}) {0} {2} {1}") + @ArgumentsSource(SEA99_test.class) + void test(int index, Gmm gmm, Imt imt, double exMedian, double exSigma, String inputs) { + GmmTest.test(index, gmm, imt, exMedian, exSigma, inputs); + } + + @Override + public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception { + return GmmTest.loadResults(GMM_RESULTS, GMM_INPUTS); + } + + /* Result generation sets */ + private static Set<Gmm> gmms = EnumSet.of(SEA99_PRVI); + + // private static Set<Imt> imts = SpudichEtAl_1999_PRVI.COEFFS.imts(); + private static Set<Imt> imts = EnumSet.of(PGA, SA0P1, SA0P5, SA2P0); + + public static void main(String[] args) throws IOException { + GmmTest.generateResults(gmms, imts, GMM_INPUTS, GMM_RESULTS); + System.out.println("Done generating results"); + } +} diff --git a/src/test/resources/gmm/sea99-inputs.csv b/src/test/resources/gmm/sea99-inputs.csv new file mode 100644 index 00000000..3853b913 --- /dev/null +++ b/src/test/resources/gmm/sea99-inputs.csv @@ -0,0 +1,7 @@ +#Mw,rjB,rRup,rX,dip,width,zTor,zHyp,rake,vs30,z1p0,z2p5,zSed +5.5,0.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN +5.5,70.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN +6.5,0.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN +6.5,70.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN +7.5,0.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN +7.5,70.0,0,0,90,1,1,1,1,760,NaN,NaN,NaN diff --git a/src/test/resources/gmm/sea99-results.csv b/src/test/resources/gmm/sea99-results.csv new file mode 100644 index 00000000..64c63bc0 --- /dev/null +++ b/src/test/resources/gmm/sea99-results.csv @@ -0,0 +1,24 @@ +0-SEA99_PRVI-PGA,0.1897430161,0.2240000000 +1-SEA99_PRVI-PGA,0.0174183111,0.2240000000 +2-SEA99_PRVI-PGA,0.3214887646,0.2240000000 +3-SEA99_PRVI-PGA,0.0295125030,0.2240000000 +4-SEA99_PRVI-PGA,0.5447105663,0.2240000000 +5-SEA99_PRVI-PGA,0.0500041494,0.2240000000 +0-SEA99_PRVI-SA0P1,0.3262097462,0.2950000000 +1-SEA99_PRVI-SA0P1,0.0282558510,0.2950000000 +2-SEA99_PRVI-SA0P1,0.6926230371,0.2950000000 +3-SEA99_PRVI-SA0P1,0.0599940792,0.2950000000 +4-SEA99_PRVI-SA0P1,0.9364766051,0.2950000000 +5-SEA99_PRVI-SA0P1,0.0811163484,0.2950000000 +0-SEA99_PRVI-SA0P5,0.2191634575,0.2750000000 +1-SEA99_PRVI-SA0P5,0.0190970592,0.2750000000 +2-SEA99_PRVI-SA0P5,0.5306010965,0.2750000000 +3-SEA99_PRVI-SA0P5,0.0462345351,0.2750000000 +4-SEA99_PRVI-SA0P5,1.0734161944,0.2750000000 +5-SEA99_PRVI-SA0P5,0.0935333512,0.2750000000 +0-SEA99_PRVI-SA2P0,0.0364705131,0.3410000000 +1-SEA99_PRVI-SA2P0,0.0031015763,0.3410000000 +2-SEA99_PRVI-SA2P0,0.1078802324,0.3410000000 +3-SEA99_PRVI-SA2P0,0.0091745013,0.3410000000 +4-SEA99_PRVI-SA2P0,0.2691174589,0.3410000000 +5-SEA99_PRVI-SA2P0,0.0228866625,0.3410000000 -- GitLab