请稍侯

kiwi_info

20 January 2014 编辑本文

Kiwi info:

GIT repository branch
kiwi master
kiwi_asa
kiwi_asa_dev
kiwi_asa_bug

an example

$cat test_sa1.sh
../minimizer <<EOF                             #   !  dip   .and.  strike  
  make clean                                   #
  set_effective_dt  1.0                        #  params ctrl discretize size
  set_source_location -F1 -L30.52/83.75        #  src coordinate
  set_source_params_vs eikonal_modify -F1 -M3.35E+18/180/45/-5 -L8000.0/5000.0r
  set_inversion_method slipgen -K0.8  #-G # -P0.5  # -G -S0.8  #  random generate slip-distribution 
  generate_static_data -Vn -F5.0/5.0/5.0       #  random generate obs coordinate
  output_static_data unfilter syn              #  calculate syn data
  plot source                                  #  
  sh plot_gmt.sh                               #  plot the figure
  cp plot_gmt.sh plot_gmt1.sh                  #
  cp a.ps a1.ps                                #   
  #---------------------------- 
  # quit                       #
  #-------inverse modelling----                #
  set_source_params_vs eikonal_modify -F1 -M3.35E+18/180/40/0 -L8000.0/5000.0r
  set_inversion_method sa1  -C1/1/0/1  -N100/1000/0 -R0.5/0 -S0.1 -T100/100
                         #  -Cv1/v2/v3/[/v4[v5]]   ! v1:iselect v2:ioptimize. v3: imisfit v4:ireduction: v5:istartmodel
  #quit
  r_st1 unfilter*.h5  # as filtered data      #  read data
  get_misfits_static                          #  get_result.
  output_static_data filter syn               #  output_result
  plot source                                 #  
  sh plot_gmt.sh                                  #  plot the figure
  mv plot_gmt.sh plot_gmt2.sh                         #  
  mv a.ps a2.ps                               #  
  quit                                        #  release memory
EOF

#h5dump -d /t_static_single_dataset/disp  unfilter*.h5 > tmp.info
#h5dump -d /t_static_single_dataset/disp  filter*.h5   >> tmp.info

set_source_location

Set source spacial and Temporal ref point: lat, lon, time.

syntax:

set_source_location -F<n> -L<lat>/<lon> [-T<time>]

Parameters:

lat: latitude in degree.
lon: longitude in degree.
time: optional default: 0.

info

set_source_location( options_vs,ok ) in minimizer_engine.f90
call psm_set_origin_and_time( psm,orign,ref_time) in parameterized_source.f90
type(t_geo_coords),intent(in) :: origin # coord in radius

call psm_set_default_constrains( psm )
psm -> origin -> thickness:
default constrains: top: 1.5km, bottom: thickness.

set_source_params_vs

set source parameters

syntax:

set_source_params_vs <clean|bilateral|eikonal|...> options

examples

set_source_params_vs eikonal_modify -F1 -M3.35E+18/180/45/-5 -L8000.0/5000.0r

info

call parse_psm_params => real:dimension(:) :: sourceparams
call psm_set =>

call psm_set_eikonal parameter of eikonal_modify:
-F :
[-R<t0>/<x>/<y>/<z>] :
[-M<m>/<strike0>[:<strike1>]/<dip0>[:<dip1>]/<rake>] :
[-B<bord_shift_x/bord_shift_y>] :
[-L<bord-semi-length>/[<bord-semi-width>][e|r]] : default:
[-H<nukl-shift-x/nukl-shift-y>[c|r]] : default:
[-V<relative-rupture-velocity>[/<Vs>]] : discretize 中用到
[-T<rise_time>] :
[-D<nx_cutoff/ny_cutoff>] : [2~HUGE(1)) : HUGE(1): 只用来限制cgrid
[-K] :

subroutine psm_set_eikonal_modify( psm, params, normalized, only_moment_changed)

params ==> new_params ==> psm_params_cache_eikonal_modfify params ==> new_params ==> psm%params

psm_to_discretize_eikonal_modify

discrete source

info

subroutine psm_to_discretize_eikonal_modify( psm, shortest_doi,ok )

shortest_doi

shortest_doi set_effective_dt => effective_dt (全局变量)
update_source_discrete
=> call psm_to_discretize_wrap( list_node%psm, effective_dt, ok )

call psm_to_grid_size( psm, shortest_doi , ok ) : 计算 Δ Nx,Ny call psm_make_eikonal_grid( psm, psm%egrid, ok ) : 分配空间,算rupture front call psm_downsample_grid( psm, psm%egrid, psm%cgrid ) : 下采样

psm_to_grid_size:

1
2
3
4
5
6
7
8
delta=min(100.max(shortest_doi,0.5)/2.,4000.)   ! delta_max=4km     ; delta_min= 1000.25=25m
nxf=floor(2.0bord_semi_x/delta)                 ! 2.02265/50=90    ;
nyf=floor(2.0bord_semi_y/delta)                 ! 2.03150/50=126
if(nxf.le.1) nxf=2 ; if(bord_semi_x.eq.0) nxf=1  ! line source
if(nyf.le.1) nyf=2 ; if(bord_semi_y.eq.0) nyf=1  ! line source
!print ,‘–> nxf,nyf’ ,nxf,nyf  ! 90,126
delta_x = 2.0bord_semi_x/nxf  !
delta_y = 2.0*bord_semi_y/nyf  !

如果100计算则 delta 大概 = shortest_doi*50m, 目前采用的是比较笨的方法,egrid采用100m/s,cgrid采用rup_min_vs,反演格点采用cgrid,画图采用采用egrid,更为合理的是采用插值画图,避免使用egrid,但是因为边界的限制是随机的,任意的,计算边界采用了较小格点。先用bord_seim_x,bord_seim_y,effective_dt,100m/s 决定delta,然后考虑边界限制,获取几何边界,然后再一次计算delta.同时,算走时,用小格点精确点,还是需要用egrid

期望更新:画图是采用基函数插值渲染, 第三步 psm_downsample_grid. 为egrid=>cgrid,应该弄个双向的,增加个插值cgrid=>egrid,ie: psm_resample_grid(decimate|stretch) .

how normalized work.

set_inversion_method < sa1 | slipgen | nnls | svd >

expected update

回调函数,设置统一接口

sa1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
set_inversion_method sa1 -C0/0/0 -N10/100 -P0.25 -R0.5/0.25/0.5/0.5 -S0.1 -Ts0.03 -Tr0.95 -V
  [-C<iselect>/<ioptimize>/<imisfit>/[<ireduction>[/<imodel>]]]  :
      iselect:   -1: one params 0: one fault 1: all params :
      ioptimize: 0: GSA   1: ASA   2: MCMC :
      imisfit:   0: MSE   1: BAYESIAN :
      irecduction: 0:ASA  1: EXP
      imodel: 0:UNIFORM  1: RANDOM 3: OLD
  [-L]  : Layer model instead of halfspace
  [-Mi<0|1|2>]  : initial model: 0:uniform, 1:random, 2:old value,  have not implement.
  [-N<nsteps>/<niterations>/[<init_ntiral>]]   :
  [-O]  : output result each step to sa_out.hd5
  [-P<val>] : poisson ratio
  [-R<moment>[/<rake>[/<fronttime>[/<risetime>]]]]:factor set range (upper and lower boundary)
  [-Q<val>] : quench factor -Q1.0
  [-S] : smooth_factor [0.0 ~ +inf)
  [-Ts<val>] : Ts: set temperature scale factor
  [-Tr<val>] : Tr: set reduction factor, for -C <ireduction>=0
  [-T<i1>/<i2>/<i3>]  : set terminal condition, have not implement
  [-T<n>/<m>]  : tune facor -T<100.0>/<100.0>  n=kf, m=tb/t
  [-V]  : Verbose mode will plot result after each circle
  [-W<mcmc_ratio>]  : Makov Chain Width
  [-Z]  : Layer model instead of halfspace

expected update:

for seismic data.

slipgen

1
2
3
4
5
6
7
set_inversion_method slipgen  [-K<kvalue>] [-P<factor>] [-R] [-W<c|e>] [-G] [-S<value>]
  [-K<1.0>]  : k^-2 parameter: (0.0~1.0)
  [-P<0.0>]  : rake perturbation factor: (0.0~1.0)
  [-R]       : texture risetime, auto-determined by moment distribution
  [-W<c>]    : save in which grid, c:cgrid, e:egrid
  [-S<0.5>]  : spike model, value spike_location
  [-G]       : random generator layout of derterminstic part 5X3 array

expected update:

inversion flow

数据流

  • a example of dataflow: update_flow
    command: get_misfit.
    update_misfits

    update_syn_probes

    update_syn_probes #

    update_database ?
     # update_source_distribution 和 update_database 应该兑换下位置.
    update_receivers
    update_source_distribution
     # check inversion method. and invoke slip_distribution_ivnersion_wrap.

    update_source_discrete
    update_database

  • a example of dataflow: dirtyfy_flow
    command: set_database
    dirtyfy_database

    dirtyfy_source_distribution

    dirtyfy_syn_probes
    dirtyfy_syn_probes.

1) set_inversion_method_vs

调用: parse_inversion_params_wrap: parse to structure ctrl and real array params
compare params with ctrl_inversion%params_1 if not equal dirtyfy_source_distribution.

2) slip_distribution_inversion_wrap

不检测数据流。

slipgen 和 uniform 是伪反演。不需要obs data。直接texture moment. 给定moment,用来正演 syn data。 slipgen: 产生随机模型,用来测试其他方法 uniform:通过调用 lm, grid-search. 来正演, 断层参数

nnls,svd,sa,asa, baysian. 实际反演滑动分布。

method info refs.
uniform    
slipgen    
     
nnls seismic data.  
svd geodetic data.  
sa joint.  
asa joint.  
baysian joint.  

psm_to_slip_distribution_slipgen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
          
current_node=>list_head ; i_sign=1 do while(associated(current_node)) psm=>current_node%psm current_node=>current_node%next

         ....

         call psm_transfer_params(psm%sourcetype,psm%params,i_sign)  
         ! i.e. copy psm%params =&gt;  psm_params_cache_eikonal_modify

         grid%psm_sourcetype=psm%sourcetype 
         ! save a copy to grid%psm_params
         call psm_transfer_params(psm%sourcetype,grid%psm_params,-i_sign)

         ...

         call psm_get(psm,rake=rake0,risetime=risetime )

         ...

         call texture_moment()   # dummy function

         call texture_slip_slipgen(ctrl_slipgen%sdin,ctrl_slipgen%kvalue)
         call texture_rake(rake0)
         call texture_risetime(risetime)! rake, risetime,moment.
     end do<span class="w">

psm_to_slip_distribution_uniform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
          
current_node=>list_head ; i_sign=1 do while(associated(current_node)) psm=>current_node%psm current_node=>current_node%next grid=>psm%cgrid

         call psm_transfer_params(psm%sourcetype,psm%params,i_sign) 
         ! update specific params structure

         grid%psm_sourcetype=psm%sourcetype 
         ! save a copy to grid%psm_params
         call psm_transfer_params(psm%sourcetype,grid%psm_params,-i_sign)

         call texture_moment()   # dummy function 

     end do<span class="w">

psm_to_slip_distribution_nnls

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
          
! count Number of discrete-source current_node=>list_head ; is=0; i_sign=1 do while(associated(current_node)) … is=is+1 … end do ! while

   ! count Number of obs data.
    do ireceiver=1, nreceivers.
       nobs = nobs + span_ref/delta 
    end do 

   ! allocate memory  Ax=B 
      allocate(A,B,X, ...) 

   ! calculate green A.
      make_seismogram(sub_tdsm, ... )

   ! calculate obs B
      B(i:j)=strip%data(i&amp;prime;:j&amp;prime;)

   ! set_constrains
      .... 

   ! invoke
     call nnls(...)

   ! deallocate memory.
     ....

   ! save result.
     ....<span class="w">

psm_to_slip_distribution_svd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
          
! count Number of discrete-source current_node=>list_head ; is=0; i_sign=1 do while(associated(current_node)) … is=is+1 … end do ! while

   ! count N-obs
     nobs=0; ndataset=size(obs_datasets)
     do loop=1,ndataset
        nobs=nobs+size((obs_datasets(loop)%obs))
     end do

   ! allocate memory
     allocate(AA,BB,XX,DD ...) 

   ! construct AA ... DD ...
     .... 

   ! call SVD
     ....

   ! deallocate momery
     ....

   ! save result
     ....<span class="w">

psm_to_slip_distribution_sa1

psm_to_slip_distribution_baysian


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
          
subroutine calculate_and_scale_seismogram() delta: db%dt,

receiver:: type(t_receiver), dimension(:), allocatable :: receivers { ! receiver.f90 type(t_strip),dimension(:) allocatable :: displacement { ! sparse_trace.f90 real(kind=real_kind), dimension(:), allocatable :: data
} } !—————————————————————————————————————– ! real, dimension(:) :: t_receiver :: receivers%t_strip displacement%data ! should update_to:
! real, dimension(:) :: t_receiver :: receivers%t_trace :: traces%t_strip :: stripsdata !—————————————————————————————————————–

! source :: type(t_list_node), pointer :: current_node = list_head { type(t_list_node), pointer :: next=>NULL() type(t_psm) :: psm { type(t_eikonal_grid) :: egrid { grid%moments(nsd,nx,ny,nw) } type(t_eikonal_grid) :: cgrid } logical :: xxx_dirty,xxx_inited } !————————————————————————————— if(ctrl_inversion%imethod(2)==slip_inversion_method_slipgen) then if(.not.ctrl_slipgen%cgrid) grid=>psm%egrid ! slipgen may save result in find grid
end if !————————————————————————————— grid=>cgrid or grid=>egrid

! info: step_1: if cgrid%duration > effective_dt. then discretize each subfault to several part. ! info: step_2: apply risetime ! info: step_3:
{ do iy=1:ny,ix=1:nx

  ! step_1:
    duration=grid%durations(ix,iy) ; egrid%duration=0;  cgrid%duration
    call discretize_subfault_time( duration, 0.0,  effective_dt, t_weights, t_offsets,nsrc)    ! rectangular
    allocate(sub_tdsm%centroids(nsrc))

  ! step_2:
    if(ctrl_inversion%imethod(2)==slip_inversion_method_nnls) then  ! n triangular stf
                    call discretize_subfault_time(risetime,  deltat, tweights, toffsets,nt) ! for strip_fold
    else  ! one rectangular stf( source time function )
                    call discretize_subfault_time(0.0,risetime,  deltat, tweights, toffsets,nt) ! for strip_fold 
    end if

  ! step_3: 
         forall(it=1:nsrc) ! same geocoordinate.
                    sub_tdsm%centroids(it)%north = grid%points(1,ix,iy)
                    sub_tdsm%centroids(it)%east  = grid%points(2,ix,iy)
                    sub_tdsm%centroids(it)%depth = grid%points(3,ix,iy)
         end forall


      do iw=1,nw ! asa,slipgen,uniform:  nw=svd =1,   mtw: nw &gt;= 1
                    !print *, 'debug minimizer_engine.f90 1566 iw',iw
          FORALL(it=1:nsrc) sub_tdsm%centroids(it)%time  =  &amp;
                    grid%times(ix,iy) + &amp;  ! times reference, relative time
                    origin_time-grid%center_time  + &amp; ! due to origin%(time,x,y,z)  is centeroid location
                    t_offsets(it)       + &amp; ! offset by nsrc        
                    (iw-1)*0.5*risetime + &amp; ! offset by nw
                    real(psm%ref_time)   ! new ref scheme
      end do

end do }

end subroutine

shortest_doi

cgrid 和 egrid

egrid: cgrid:

time reference

psm {
   psm%ref_time <= suppose to be centroid time
   psm%grid {
       psm%grid%center_time=0.0    <=  centroid_time: ref_point is eipcenter
                                       inversed from uniform moments distribution by kiwi tool,
                                       despite of uniform or non-uniform distribution.
       psm%grid%time(ix,iy)=0.0    <=  solve by eikonal equation,  ref_point is  "psm%grid%initialpoint"

   }
}


set_source_location -F<n> -L<lat>/<lon>  -T<ref_time>    
set_source_params source_eikonal_modify  -R<t0>/<x>/<y>/<z>  
                                         -M<m>/<strike0>[:<strike1>]/<dip0>[:<dip1>]/<rake>]  
                                         -H<nukl-shift-x/nukl-shift-y>[c|r]   
                                         ....



sub_tdsm%centroids(it)%time  =  real(psm%ref_time)   &  ! set_source_location `[-T<ref>]`                                    origin of coordinate system.
                             +  origin_time          &  ! set_source_params source_eikonal_modify  `[-R<t0>[/<x>/<y>/<z>]]`  origin of coordinate on fault on fault.
                             -  grid%center_time     &  ! time diff between center_point and hypocenter.                   
                             +  grid%times(ix,iy)    &  ! time diff reference, relative time                                
                             +  (iw-1)*0.5*risetime  &  ! offset by nw  (ctrl%nnls%width_per_window)
                             +  t_offsets(it)        &  ! offset by nsrc

Notes:

kiwi tool set_source_params -R<t0>/<x>/<y>/<z> ... is the coordinate of center_point. so we need to subtract the grid%center_time. in fact -R<t0>/<x>/<y>/<z> where <t0> and <x/y/z> is independent coordinate, can be seprate to conect to different point. For example: <t0> be the coordinate of hypocenter or centroid point. In order to keep consistent with kiwi tool. so suppose it be the center point.