'use strict' ; import { Matrix } from './matrix' ; import { Vector } from './vector' ; const _BEACHBALL_METHODS = { 'smi:ci.anss.org/momentTensor/TMTS' : 'TMTS' , 'smi:nc.anss.org/momentTensor/TMTS' : 'TMTS' , 'smi:nc.anss.org/momentTensor/TMTS-ISO' : 'TMTS-ISO' , 'smi:uu.anss.org/momentTensor/TDMT' : 'TDMT' } ; const _D2R = Math . PI / 180 ; const _R2D = 180 / Math . PI ; param mtt { Number } param mpp { Number } param mrr { Number } param mrt { Number } param mrp { Number } param mtp { Number } export class Tensor { param v1 { Vector } param v2 { Vector } return { Object } static calculatePlane ( v1 , v2 ) { v1 = v1 . unit ( ) ; v2 = v2 . unit ( ) ; if ( v1 . z ( ) > 0 ) { v1 = v1 . multiply ( - 1 ) ; v2 = v2 . multiply ( - 1 ) ; } return { dip : Math . acos ( - v1 . z ( ) ) * _R2D , rake : Math . atan2 ( - v2 . z ( ) , v2 . cross ( v1 ) . z ( ) ) * _R2D , strike : Tensor . range ( Math . atan2 ( - v1 . x ( ) , v1 . y ( ) ) , 0 , 2 * Math . PI ) * _R2D } ; } param product { Product } static fromProduct ( product ) { let depth , duration , props , type , tensor ; if ( ! product ) { return null ; } tensor = null ; type = product . type ; props = product . properties || { } ; if ( type === 'focal-mechanism' ) { tensor = Tensor . fromStrikeDipRake ( Number ( props [ 'nodal-plane-1-strike' ] ) , Number ( props [ 'nodal-plane-1-dip' ] ) , Number ( props [ 'nodal-plane-1-rake' ] || props [ 'nodal-plane-1-slip' ] || 0 ) , Number ( props [ 'scalar-moment' ] || Math . SQRT2 ) ) ; } else if ( type === 'moment-tensor' ) { tensor = new Tensor ( { mpp : Number ( props [ 'tensor-mpp' ] ) , mrp : Number ( props [ 'tensor-mrp' ] ) , mrr : Number ( props [ 'tensor-mrr' ] ) , mrt : Number ( props [ 'tensor-mrt' ] ) , mtp : Number ( props [ 'tensor-mtp' ] ) , mtt : Number ( props [ 'tensor-mtt' ] ) } ) ; depth = props [ 'derived-depth' ] ; if ( ! depth ) { depth = props . depth ; } tensor . depth = depth ; duration = props [ 'sourcetime-duration' ] ; if ( duration ) { tensor . halfDuration = duration / 2 ; } } if ( tensor ) { tensor . product = product ; type = props [ 'derived-magnitude-type' ] ; if ( ! type ) { type = props [ 'beachball-type' ] ; if ( type && _BEACHBALL_METHODS . hasOwnProperty ( type ) ) { type = _BEACHBALL_METHODS [ type ] ; } } if ( type ) { tensor . type = type ; } } return tensor ; } param strike { Number } param dip { Number } param rake { Number } param moment { Number } return static fromStrikeDipRake ( strike , dip , rake , moment ) { let c2d , c2s , cd , cr , cs , d , mxx , mxy , mxz , myy , myz , mzz , r , s , s2d , s2s , sd , sr , ss ; s = strike * _D2R ; ss = Math . sin ( s ) ; cs = Math . cos ( s ) ; s2s = Math . sin ( 2 * s ) ; c2s = Math . cos ( 2 * s ) ; d = dip * _D2R ; sd = Math . sin ( d ) ; cd = Math . cos ( d ) ; s2d = Math . sin ( 2 * d ) ; c2d = Math . cos ( 2 * d ) ; r = ( rake % 90 !== 0 ? rake : rake + 1e-15 ) * _D2R ; sr = Math . sin ( r ) ; cr = Math . cos ( r ) ; mxx = - 1 * ( sd * cr * s2s + s2d * sr * ss * ss ) ; mxy = sd * cr * c2s + s2d * sr * s2s * 0.5 ; mxz = - 1 * ( cd * cr * cs + c2d * sr * ss ) ; myy = sd * cr * s2s - s2d * sr * cs * cs ; myz = - 1 * ( cd * cr * ss - c2d * sr * cs ) ; mzz = s2d * sr ; return new Tensor ( { mpp : myy * moment , mrp : - myz * moment , mrr : mzz * moment , mrt : mxz * moment , mtp : - mxy * moment , mtt : mxx * moment } ) ; } param value { Number } param min { Number } param max { Number } return { Number } static range ( value , min , max ) { const span = max - min ; while ( value < min ) { value += span ; } while ( value >= max ) { value -= span ; } return value ; } param v1 { any } param v2 { any } static sortEigenvalues ( v1 , v2 ) { let v1mag , v2mag ; v1mag = v1 . eigenvalue ; v2mag = v2 . eigenvalue ; if ( v1mag < v2mag ) { return 1 ; } else if ( v1mag > v2mag ) { return - 1 ; } else { return 0 ; } } depth : any ; exponent : number ; fCLVD : number ; forceNormal : number ; forceStrikeSlip : number ; forceThrust : number ; halfDuration : any ; magnitude : number ; matrix : Matrix ; moment : number ; momentLog10 : number ; mpp : number ; mrp : number ; mrr : number ; mrt : number ; mtp : number ; mtt : number ; N : any ; NP1 : any ; NP2 : any ; P : any ; percentDC : number ; product : any = null ; scale : number ; T : any ; type : any ; units = 'N-m' ; constructor ( options ) { let eigen , exponent , l , moment , momentLog10 , mpp , mrr , mrt , mrp , mtp , mtt , n , p , t ; this . mtt = mtt = options . mtt || options . mxx || 0 ; this . mpp = mpp = options . mpp || options . myy || 0 ; this . mrr = mrr = options . mrr || options . mzz || 0 ; this . mrt = mrt = options . mrt || options . mxz || 0 ; this . mrp = mrp = options . mrp || - options . myz || 0 ; this . mtp = mtp = options . mtp || - options . mxy || 0 ; this . units = 'N-m' ; this . moment = moment = Math . sqrt ( 0.5 * ( mrr * mrr + mtt * mtt + mpp * mpp + 2 * ( mrt * mrt + mrp * mrp + mtp * mtp ) ) ) ; this . momentLog10 = momentLog10 = Math . log ( moment ) / Math . LN10 ; this . exponent = exponent = parseInt ( momentLog10 , 10 ) ; this . scale = Math . pow ( 10 , exponent ) ; this . magnitude = ( 2 / 3 ) * ( momentLog10 - 9.1 ) ; this . matrix = new Matrix ( [ mtt , - mtp , mrt , - mtp , mpp , - mrp , mrt , - mrp , mrr ] , 3 , 3 ) ; eigen = this . matrix . jacobi ( ) ; eigen . sort ( Tensor . sortEigenvalues ) ; this . T = t = eigen [ 0 ] ; this . N = n = eigen [ 1 ] ; this . P = p = eigen [ 2 ] ; this . fCLVD = n . eigenvalue / Math . max ( Math . abs ( t . eigenvalue ) , Math . abs ( p . eigenvalue ) ) ; this . percentDC = Math . abs ( 1 - Math . abs ( this . fCLVD ) / 0.5 ) ; this . forceThrust = Math . pow ( Math . sin ( t . vector . plunge ( ) ) , 2 ) ; this . forceStrikeSlip = Math . pow ( Math . sin ( n . vector . plunge ( ) ) , 2 ) ; this . forceNormal = Math . pow ( Math . sin ( p . vector . plunge ( ) ) , 2 ) ; l = t . vector . subtract ( p . vector ) . unit ( ) ; n = t . vector . add ( p . vector ) . unit ( ) ; this . NP1 = Tensor . calculatePlane ( l , n ) ; this . NP2 = Tensor . calculatePlane ( n , l ) ; this . T . name = 'T' ; this . N . name = 'N' ; this . P . name = 'P' ; this . NP1 . name = 'NP1' ; this . NP2 . name = 'NP2' ; } }