@@ -760,17 +760,26 @@ def Mw(self):
760760 r"""Calculate the moment magnitude for a fault composed of subfaults."""
761761 return Mw (self .Mo ())
762762
763- def create_dtopography (self , x , y , times = [0. , 1. ], verbose = False ):
763+ def create_dtopography (self , x , y , times = [0. , 1. ], slip_tol = 0.001 ,
764+ verbose = False ):
764765 r"""Compute change in topography and construct a dtopography object.
765766
766767 Use subfaults' `okada` routine and add all
767768 deformations together.
768769
769770 Raises a ValueError exception if the *rupture_type* is an unknown type.
770771
772+ Subfaults are ignored if abs(subfault.slip) < slip_tol
773+
774+ If verbose == True then the subfault number is printed as each is
775+ processed to show progress. If verbose is an integer, then it is
776+ printed for the k'th subfault only if mod(k,verbose) == 0.
777+
771778 returns a :class`DTopography` object.
772779 """
773780
781+ nignore = 0 # to keep track of how many have abs(slip) < slip_tol
782+
774783 dtopo = DTopography ()
775784 dtopo .x = x
776785 dtopo .y = y
@@ -783,21 +792,31 @@ def create_dtopography(self, x, y, times=[0., 1.], verbose=False):
783792 print ("Making Okada dz for each of %s subfaults" \
784793 % len (self .subfaults ))
785794
786- for k ,subfault in enumerate (self .subfaults ):
787- if verbose :
788- sys .stdout .write ("%s.." % k )
789- sys .stdout .flush ()
790- subfault .okada (x ,y ) # sets subfault.dtopo with times=[0]
791- # and subfault.dtopo.dZ.shape[0] == 1
792- if verbose :
793- sys .stdout .write ("\n Done\n " )
795+ dz = numpy .zeros (X .shape ) # to accumulate dZ for static rupture
794796
795797 if self .rupture_type == 'static' :
798+
799+ for k ,subfault in enumerate (self .subfaults ):
800+ if verbose :
801+ if (type (verbose ) is int ) and (numpy .mod (k ,verbose ) != 0 ):
802+ pass
803+ else :
804+ sys .stdout .write ("%s.." % k )
805+ sys .stdout .flush ()
806+
807+ if abs (subfault .slip ) < slip_tol :
808+ nignore += 1
809+ else :
810+ dtopo_sub = subfault .okada (x ,y ,set_dtopo = False )
811+ # returns dtopo with times=[0] and dtopo.dZ.shape[0] == 1
812+
813+ dz += dtopo_sub .dZ [0 ,:,:]
814+
815+ if verbose :
816+ sys .stdout .write ("\n Done\n " )
817+
796818 if len (times ) > 2 :
797819 raise ValueError ("For static deformation, need len(times) <= 2" )
798- dz = numpy .zeros (X .shape )
799- for subfault in self .subfaults :
800- dz += subfault .dtopo .dZ [0 ,:,:]
801820
802821 if len (times ) == 1 :
803822 # only final deformation stored:
@@ -811,33 +830,47 @@ def create_dtopography(self, x, y, times=[0., 1.], verbose=False):
811830
812831 elif self .rupture_type in ['dynamic' ,'kinematic' ]:
813832
814- t_prev = - 1.e99
815- dzt = numpy .zeros (X .shape )
816- dZ = None
817- for t in times :
818- for k ,subfault in enumerate (self .subfaults ):
833+ # array subfault_frac[k,jt] will store fraction of subfault k
834+ # deformation to add to dZ[jt,:,:] at times[jt]:
835+ subfault_frac = numpy .zeros ((len (self .subfaults ),len (times )))
819836
820- rf = rise_fraction ([t_prev ,t ],
837+ # compute these values from rupture and rise times, without yet
838+ # computing deformations:
839+ for k ,subfault in enumerate (self .subfaults ):
840+ subfault_frac [k ,:] = rise_fraction (times ,
821841 subfault .rupture_time ,
822842 subfault .rise_time ,
823843 subfault .rise_time_starting ,
824844 subfault .rise_shape )
825845
826- dfrac = rf [ 1 ] - rf [ 0 ]
827- if dfrac > 0. :
828- dzt = dzt + dfrac * subfault . dtopo . dZ [ 0 ,:,:]
846+ # now loop over subfaults, applying Okada to get
847+ # deformation dtopo_sub due to single subfault, then loop
848+ # over times to apply this at each time:
829849
830- dzt = numpy .array (dzt , ndmin = 3 ) # convert to 3d array
831- if dZ is None :
832- dZ = dzt .copy ()
850+ dZ = numpy .zeros ([len (times )] + list (X .shape ))
851+
852+ for k ,subfault in enumerate (self .subfaults ):
853+ if abs (subfault .slip ) < slip_tol :
854+ nignore += 1
833855 else :
834- dZ = numpy .append (dZ , dzt , axis = 0 )
835- t_prev = t
856+ dtopo_sub = subfault .okada (x ,y ,set_dtopo = False )
857+ # returns dtopo with times=[0] and dtopo.dZ.shape[0] == 1
858+
859+ for jt ,t in enumerate (times ):
860+ dfrac = subfault_frac [k ,jt ] # fraction to add at t
861+
862+ if dfrac > 0. :
863+ dZ [jt ,:,:] += dfrac * dtopo_sub .dZ [0 ,:,:]
864+
836865 dtopo .dZ = dZ
837866
838867 else :
839868 raise ValueError ("Unrecognized rupture_type: %s" % self .rupture_type )
840869
870+ if verbose and nignore > 0 :
871+ print ('Ignored %i subfaults with abs(slip) < slip_tol = %.3fm' \
872+ % (nignore ,slip_tol ))
873+
841874 # Store for user
842875 self .dtopo = dtopo
843876
@@ -1682,12 +1715,18 @@ def _llz2utm(self,lon,lat,projection_zone=None):
16821715 return x ,y
16831716
16841717
1685- def okada (self , x , y ):
1718+ def okada (self , x , y , set_dtopo = True ):
16861719 r"""
16871720 Apply Okada to this subfault and return a DTopography object.
16881721
16891722 :Input:
16901723 - x,y are 1d arrays
1724+ - set_dtopo (bool): If True, also set self.dtopo = dtopo, the
1725+ DTopography object created.
1726+ Defaults to True for backward compatibility, but create_dtopography
1727+ has been refactored so it is no longer necessary to save dtopo
1728+ for each subfault separately, which may use too much memory if
1729+ there are many subfaults with fine resolution dtopo files.
16911730 :Output:
16921731 - DTopography object with dZ array of shape (1,len(x),len(y))
16931732 with single static displacement and times = [0.].
@@ -1774,7 +1813,8 @@ def okada(self, x, y):
17741813 dtopo .Y = Y
17751814 dtopo .dZ = numpy .array (dz , ndmin = 3 )
17761815 dtopo .times = [0. ]
1777- self .dtopo = dtopo
1816+ if set_dtopo :
1817+ self .dtopo = dtopo
17781818
17791819 elif self .coordinate_specification == 'triangular' :
17801820
@@ -1866,7 +1906,8 @@ def okada(self, x, y):
18661906 dtopo .dY = numpy .array (dY , ndmin = 3 )
18671907 dtopo .dZ = numpy .array (dZ , ndmin = 3 )
18681908 dtopo .times = [0. ]
1869- self .dtopo = dtopo
1909+ if set_dtopo :
1910+ self .dtopo = dtopo
18701911
18711912 return dtopo
18721913
0 commit comments