├── GUI_Matlab_with_SSH ├── 1.png ├── 2.png ├── 3.png └── README.md ├── How_to_use_Eigen_in_Matlab ├── README.md ├── README.pdf └── eigen_staggerfd_single.cpp ├── README.md ├── Use Q&A ├── about_forward_modeling ├── CSG1.png ├── CSG2.png ├── PINN1.png ├── PINN2.png ├── PINN3.png ├── PINN4.png ├── PINN5.png ├── README.md ├── README.pdf ├── model1.png ├── net.png └── vs.png └── newenvironment /GUI_Matlab_with_SSH/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/GUI_Matlab_with_SSH/1.png -------------------------------------------------------------------------------- /GUI_Matlab_with_SSH/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/GUI_Matlab_with_SSH/2.png -------------------------------------------------------------------------------- /GUI_Matlab_with_SSH/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/GUI_Matlab_with_SSH/3.png -------------------------------------------------------------------------------- /GUI_Matlab_with_SSH/README.md: -------------------------------------------------------------------------------- 1 | # GUI_Matlab_with_SSH 2 | 3 | windows安装xming(https://sourceforge.net/projects/xming/) 4 | ![1](1.png) 5 | 6 | 只需要一路下一页。工作时只有一个小图标。 7 | 8 | ![2](2.png) 9 | 10 | 打开PowerShell,输入: 11 | ```bash 12 | ssh -R 6002:127.0.0.1:6000 user@222.27.79.19 13 | ``` 14 | 其中 -R 将远端6002端口映射到本地6000端口,user是用户名,222.27.79.19是被远程登录电脑的IP 15 | 登陆后输入 16 | ```bash 17 | export DISPLAY=127.0.0.1:2.0 18 | ``` 19 | 然后输入 20 | ```bash 21 | xclock 22 | ``` 23 | 就能看见 24 | 25 | ![3](3.png) 26 | 然后输入 27 | ```bash 28 | matlab 29 | ``` 30 | 就🆗 31 | 32 | 值得注意的是,DISPLAY环境变量将自动设置为:0:0 33 | 我们设置的DISPLAY=127.0.0.1:2.0中2.0的2和ssh中6002的2是同一个数字,具体可以搜索linux DISPLAY。 34 | 总之在实验室ssh能不用GUI就不要用,因为2.4gHz信号干扰太多,每天更换信道还是很卡 35 | 36 | # 其他命令 37 | ssh user2@localhost -p 33 -o ProxyCommand='ssh -p 32 User@222.27.79.26 -W %h:%p' [111](https://my.oschina.net/foreverich/blog/657075) 38 | -------------------------------------------------------------------------------- /How_to_use_Eigen_in_Matlab/README.md: -------------------------------------------------------------------------------- 1 | #
使用指南
2 | [为什么要在Matlab中使用Eigen。](https://github.com/trinitite271/Notes/tree/main/about_forward_modeling) 3 | 4 | Matlab中转换为单精度数据: 5 | ```matlab 6 | single(x) 7 | ``` 8 | Eigen本身非常容易使用,实现算法只要简单熟悉很快就能上手[Quick reference guide.](https://eigen.tuxfamily.org/dox/group__QuickRefPage.html) 9 | 10 | 如果我们想像Matlab函数一样调用,通过matlab工作区输入变量,并且返回的变量也能储存在工作区,matlab官方文档有提供一些例子,包括c和c++版本,但是这些例子并不好用,也不太好扩展。 11 | 因此问题的难点就在于如何转换Matlab矩阵为Eigen矩阵或者说:如何将输入的Matlab工作区变量转换为Eigen可用的形式。 12 | 13 | ### 输入参数 14 | 对于输入矩阵,Matlab官方社区有如下解决方案: 15 | > ```c++ 16 | > //! Extracts the pointer to underlying data from the non-const iterator (`TypedIterator`). 17 | >/*! This function does not throw any exceptions. */ 18 | > template 19 | > inline T* toPointer(const matlab::data::TypedIterator& it) MW_NOEXCEPT { 20 | > static_assert(std::is_arithmetic::value && !std::is_const::value, 21 | > "Template argument T must be a std::is_arithmetic and non-const type."); 22 | > return it.operator->(); 23 | > } 24 | > template 25 | > inline T* getPointer(matlab::data::TypedArray& arr) MW_NOEXCEPT { 26 | > static_assert(std::is_arithmetic::value, "Template argument T must be a std::is_arithmetic type."); 27 | > return toPointer(arr.begin()); 28 | > } 29 | > template 30 | > inline const T* getPointer(const matlab::data::TypedArray& arr) MW_NOEXCEPT { 31 | > return getPointer(const_cast&>(arr)); 32 | > } 33 | >``` 34 | 35 | 实际使用时在程序开头插入该模板,[具体插入位置。](https://github.com/trinitite271/Notes/blob/main/How_to_use_Eigen_in_Matlab/eigen_staggerfd_single.cpp)使用时,只需要: 36 | ```c++ 37 | matlab::data::TypedArray ca_input = std::move(inputs[2]); 38 | auto ca_ptr = getPointer(ca_input); 39 | MatrixXf ca = Map(ca_ptr,nzbc,nxbc); 40 | ``` 41 | ```inputs[2]```中 2 表示第三个输入变量,如下所示,ca作为eigen_staggerfd_single函数的第三个输入变量,在Eigen程序中成功输入。 42 | 43 | ```matlab 44 | [seismo_u,seismo_w,~]= eigen_staggerfd_single(input_vector,temp,ca,cl,cm,cm1,b,b1,s); 45 | ``` 46 | 除此之外,```int nt = inputs[0][0];``` 也能直接读取第一个输入变量的第一个数并转换为整数。这里input_vector是一个向量。 47 | 48 | ### 输出参数 49 | 50 | 输出数据时要把Eigen转换为Matlab,在[Matlab文档中:](https://ww2.mathworks.cn/help/matlab/apiref/matlab.data.arrayfactory.html#bvn7dve-1) 51 | >createArray 52 | template 53 | TypedArray createArray(ArrayDimensions dims) 54 | template 55 | TypedArray createArray(ArrayDimensions dims, 56 | ItType begin, 57 | ItType end, 58 | InputLayout inputLayout) 59 | template 60 | TypedArray createArray(ArrayDimensions dims, 61 | const T* const begin, 62 | const T* const end) 63 | template 64 | TypedArray createArray(ArrayDimensions dims, 65 | > std::initializer_list data) 66 | 67 | 因此输出数据首先得到输出数据的维度,假设要输出一个nt*ng的矩阵,首先: 68 | ```c++ 69 | std::vector size_output(1,nt); 70 | size_output.insert(size_output.end(),ng); 71 | ``` 72 | 得到矩阵维度,然后: 73 | ```c++ 74 | float* eig_seismo_u_ptr = seismo_u.data(); 75 | outputs[0] = factory.createArray(size_output,eig_seismo_u_ptr,eig_seismo_u_ptr + number_elements); 76 | ``` 77 | 78 | 这里 seismo_u是要输出的矩阵,eig_seismo_u_ptr和eig_seismo_u_ptr + number_elements包括要输出的所有数据,number_elements为输出变量的元素个数,这里就是nt*ng. 79 | Eigen 似乎并不支持三维张量,但是通过也能将二维矩阵输出成三维张量,具体见代码。 80 | 81 | ### 调试过程 82 | 实现过程中格外要注意的是各种变量的维度是否匹配,一旦错误Matlab直接崩溃。直接在matlab中编写,在matlab中调试,调试起来并不方便。Eigen使用起来也比较友好,不过有些API官方也标注了还需要改进,用起来的效果也就不是很好。 83 | 编译程序只需要: 84 | ```matlab 85 | mex '-I\Intel\mkl\latest\include' eigen_e2drtm_single.cpp 86 | ``` 87 | ### 适用条件 88 | 矩阵计算等Eigen优化好的算法。不适用于FFT等。 89 | -------------------------------------------------------------------------------- /How_to_use_Eigen_in_Matlab/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/How_to_use_Eigen_in_Matlab/README.pdf -------------------------------------------------------------------------------- /How_to_use_Eigen_in_Matlab/eigen_staggerfd_single.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *zhangchang2317@mails.jlu.edu.cn 3 | * 4 | * 5 | *2021/11/4 Changchun 6 | * staggerfd 7 | */ 8 | #define EIGEN_USE_MKL_ALL 9 | #include "mex.hpp" 10 | #include "mexAdapter.hpp" 11 | #include "MatlabDataArray.hpp" 12 | #include "Eigen/Dense" 13 | #include "Eigen/Core" 14 | #include "Eigen/Cholesky" 15 | #include 16 | #include "type_traits" 17 | 18 | // using namespace matlab::data; 19 | using namespace std; 20 | using namespace Eigen; 21 | using matlab::mex::ArgumentList; 22 | class MexFunction : public matlab::mex::Function { 23 | // // // // // // // // // // // // // // // // // // // // // // 24 | //! Extracts the pointer to underlying data from the non-const iterator (`TypedIterator`). 25 | /*! This function does not throw any exceptions. */ 26 | template 27 | inline T* toPointer(const matlab::data::TypedIterator& it) MW_NOEXCEPT { 28 | static_assert(std::is_arithmetic::value && !std::is_const::value, 29 | "Template argument T must be a std::is_arithmetic and non-const type."); 30 | return it.operator->(); 31 | } 32 | template 33 | inline T* getPointer(matlab::data::TypedArray& arr) MW_NOEXCEPT { 34 | static_assert(std::is_arithmetic::value, "Template argument T must be a std::is_arithmetic type."); 35 | return toPointer(arr.begin()); 36 | } 37 | template 38 | inline const T* getPointer(const matlab::data::TypedArray& arr) MW_NOEXCEPT { 39 | return getPointer(const_cast&>(arr)); 40 | } 41 | // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // 42 | public: 43 | 44 | void operator()(matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs) { 45 | matlab::data::ArrayFactory factory; 46 | /* input: nt 47 | * nzbc 48 | * nxbc 49 | * dtx 50 | * temp 51 | * ng 52 | * ca 53 | * cl 54 | * cm 55 | * b 56 | * s 57 | * sourcetype 58 | *Eigen init: 59 | * uu 60 | * ww 61 | * xx 62 | * xz 63 | * zz 64 | * fux 65 | * fuz 66 | * bwx 67 | * bwz 68 | *return: 69 | * seismo_w 70 | * seismo_u 71 | * wavefield_gradient 72 | */ 73 | // Input constant from matlab workspace: nt, nzbc, nxbc, dtx, ng, source_type_num, fd_order_num 74 | int nt = inputs[0][0]; 75 | int nzbc = inputs[0][1]; 76 | int nxbc = inputs[0][2]; 77 | float dtx = inputs[0][3]; 78 | int ng = inputs[0][4]; 79 | int sz = inputs[0][5];sz--; 80 | int sx = inputs[0][6];sx--; 81 | int gz = inputs[0][7];gz--; 82 | int gx = inputs[0][8];gx--; 83 | int dg = inputs[0][9]; 84 | int source_type_num = inputs[0][10]; 85 | int fd_order_num = inputs[0][11]; 86 | int number_elements = nt*ng; 87 | int length_geophone = ng*dg; 88 | int nt_interval = inputs[0][12]; 89 | int nz = inputs[0][13]; 90 | int nx = inputs[0][14]; 91 | int format_num = inputs[0][15]; 92 | int nbc = (nxbc-nx)/2; 93 | int num_nt_record = nt/nt_interval; 94 | int wavefield_elements = num_nt_record*nx*nz; 95 | // Input variables from matlab workspace: temp ca cl cm b s 96 | matlab::data::TypedArray temp_input = std::move(inputs[1]); 97 | auto temp_ptr = getPointer(temp_input); 98 | std::vector size_input; 99 | size_input = temp_input.getDimensions(); 100 | MatrixXf temp = Map(temp_ptr,nzbc,nxbc); 101 | 102 | matlab::data::TypedArray ca_input = std::move(inputs[2]); 103 | auto ca_ptr = getPointer(ca_input); 104 | MatrixXf ca = Map(ca_ptr,nzbc,nxbc); 105 | 106 | matlab::data::TypedArray cl_input = std::move(inputs[3]); 107 | auto cl_ptr = getPointer(cl_input); 108 | MatrixXf cl = Map(cl_ptr,nzbc,nxbc); 109 | 110 | matlab::data::TypedArray cm_input = std::move(inputs[4]); 111 | auto cm_ptr = getPointer(cm_input); 112 | MatrixXf cm = Map(cm_ptr,nzbc,nxbc); 113 | 114 | matlab::data::TypedArray cm1_input = std::move(inputs[5]); 115 | auto cm1_ptr = getPointer(cm1_input); 116 | MatrixXf cm1 = Map(cm1_ptr,nzbc,nxbc); 117 | 118 | matlab::data::TypedArray b_input = std::move(inputs[6]); 119 | auto b_ptr = getPointer(b_input); 120 | MatrixXf b = Map(b_ptr,nzbc,nxbc); 121 | 122 | matlab::data::TypedArray b1_input = std::move(inputs[7]); 123 | auto b1_ptr = getPointer(b1_input); 124 | MatrixXf b1 = Map(b1_ptr,nzbc,nxbc); 125 | 126 | matlab::data::TypedArray s_input = std::move(inputs[8]); 127 | auto s_ptr = getPointer(s_input); 128 | VectorXf s = Map(s_ptr,nt,1); 129 | // Eigen Initialising input variables: uu, ww, xx, xz, zz 130 | MatrixXf uu(nzbc,nxbc); 131 | uu << MatrixXf::Zero(nzbc,nxbc); 132 | MatrixXf ww(nzbc,nxbc); 133 | ww << MatrixXf::Zero(nzbc,nxbc); 134 | MatrixXf xx(nzbc,nxbc); 135 | xx << MatrixXf::Zero(nzbc,nxbc); 136 | MatrixXf xz(nzbc,nxbc); 137 | xz << MatrixXf::Zero(nzbc,nxbc); 138 | MatrixXf zz(nzbc,nxbc); 139 | zz << MatrixXf::Zero(nzbc,nxbc); 140 | // Eigen Initialising input variables: fux, fuz, bwx, bwz 141 | MatrixXf fux(nzbc,nxbc); 142 | fux << MatrixXf::Zero(nzbc,nxbc); 143 | MatrixXf fuz(nzbc,nxbc); 144 | fuz << MatrixXf::Zero(nzbc,nxbc); 145 | MatrixXf bwx(nzbc,nxbc); 146 | bwx << MatrixXf::Zero(nzbc,nxbc); 147 | MatrixXf bwz(nzbc,nxbc); 148 | bwz << MatrixXf::Zero(nzbc,nxbc); 149 | // Eigen Initialising output variables: seismo_w, seismo_u 150 | MatrixXf seismo_w(nt,ng); 151 | seismo_w << MatrixXf::Zero(nt,ng); 152 | MatrixXf seismo_u(nt,ng); 153 | seismo_u << MatrixXf::Zero(nt,ng); 154 | 155 | MatrixXf wavefield_gradient_fux(nz,nx*num_nt_record); 156 | wavefield_gradient_fux << MatrixXf::Zero(nz,nx*num_nt_record); 157 | MatrixXf wavefield_gradient_fuz(nz,nx*num_nt_record); 158 | wavefield_gradient_fuz << MatrixXf::Zero(nz,nx*num_nt_record); 159 | MatrixXf wavefield_gradient_bwx(nz,nx*num_nt_record); 160 | wavefield_gradient_bwx << MatrixXf::Zero(nz,nx*num_nt_record); 161 | MatrixXf wavefield_gradient_bwz(nz,nx*num_nt_record); 162 | wavefield_gradient_bwz << MatrixXf::Zero(nz,nx*num_nt_record); 163 | 164 | // Eigen zero_vector for free surface zz 165 | VectorXf zero_vector(nxbc); 166 | zero_vector << VectorXf::Zero(nxbc); 167 | VectorXf geophone_vector(nxbc); 168 | geophone_vector << VectorXf::Zero(nxbc); 169 | int k;int i;int pad_top; 170 | if(fd_order_num==22){ 171 | k = nzbc-2; i = nxbc-2; pad_top = 1;} 172 | else if(fd_order_num==24){ 173 | k = nzbc-4; i = nxbc-4; pad_top = 2;} 174 | else if(fd_order_num==26){ 175 | k = nzbc-6; i = nxbc-6; pad_top = 3;} 176 | else if(fd_order_num==28){ 177 | k = nzbc-8; i = nxbc-8; pad_top = 4;} 178 | 179 | float S41 = 1.1250; float S42 = -0.0416666667; 180 | float S61 = 1.17187; float S62 = -6.51042E-2; float S63 = 4.68750E-3; 181 | float S81 = 1.19629; float S82 = -7.97526E-2; float S83 = 9.57031E-3; float S84 = -6.97545E-4; 182 | // forward differential iterations 183 | for( int it = 0; it < nt; it++ ){ 184 | // if(source_type_num == 1){ 185 | // xx(sz,sx)=xx(sz,sx)+s(it); 186 | // zz(sz,sx)=zz(sz,sx)+s(it);} 187 | // else if(source_type_num == 2){ 188 | // uu(sz,sx)=uu(sz,sx)+s(it); 189 | // uu(sz-1,sx)=uu(sz-1,sx)-s(it); 190 | // ww(sz,sx)=ww(sz,sx)+s(it); 191 | // ww(sz,sx+1)=ww(sz,sx+1)+s(it);} 192 | // else if(source_type_num == 3){ 193 | // uu(sz,sx)=uu(sz,sx)+s(it); 194 | // ww(sz,sx)=ww(sz,sx)+s(it);} 195 | // else if(source_type_num == 4){ 196 | // zz(sz,sx)=zz(sz,sx)+s(it);} 197 | // else if(source_type_num == 5){ 198 | // ww(sz,sx)=s(it);} 199 | 200 | if (fd_order_num == 22){ 201 | uu.block(1,1,k,i) = temp.block(1,1,k,i).cwiseProduct(uu.block(1,1,k,i)) + b.block(1,1,k,i).cwiseProduct( 202 | xx.block(1,1+1,k,i) - xx.block(1,1,k,i) + xz.block(1,1,k,i) - xz.block(1-1,1,k,i)); 203 | ww.block(1,1,k,i) = temp.block(1,1,k,i).cwiseProduct(ww.block(1,1,k,i)) + b1.block(1,1,k,i).cwiseProduct( 204 | xz.block(1,1,k,i) - xz.block(1,1-1,k,i) + zz.block(1+1,1,k,i) - zz.block(1,1,k,i));} 205 | else if(fd_order_num == 24){ 206 | uu.block(2,2,k,i) = temp.block(2,2,k,i).cwiseProduct(uu.block(2,2,k,i)) + b.block(2,2,k,i).cwiseProduct( 207 | S41*(xx.block(2,2,k,i) - xx.block(2,2-1,k,i)) + S42*(xx.block(2,2+1,k,i) - xx.block(2,2-2,k,i)) + 208 | S41*(xz.block(2,2,k,i) - xz.block(2-1,2,k,i)) + S42*(xz.block(2+1,2,k,i) - xz.block(2-2,2,k,i))); 209 | ww.block(2,2,k,i) = temp.block(2,2,k,i).cwiseProduct(ww.block(2,2,k,i)) + b1.block(2,2,k,i).cwiseProduct( 210 | S41*(xz.block(2,2+1,k,i) - xz.block(2,2,k,i)) + S42*(xz.block(2,2+2,k,i) - xz.block(2,2-1,k,i)) + 211 | S41*(zz.block(2+1,2,k,i) - zz.block(2,2,k,i)) + S42*(zz.block(2+2,2,k,i) - zz.block(2-1,2,k,i)));} 212 | else if(fd_order_num == 26){ 213 | uu.block(3,3,k,i) = temp.block(3,3,k,i).cwiseProduct(uu.block(3,3,k,i)) + b.block(3,3,k,i).cwiseProduct( 214 | S61*(xx.block(3,3,k,i) - xx.block(3,3-1,k,i)) + S62*(xx.block(3,3+1,k,i) - xx.block(3,3-2,k,i)) + 215 | S63*(xx.block(3,3+2,k,i) - xx.block(3,3-3,k,i)) + S61*(xz.block(3,3,k,i) - xz.block(3-1,3,k,i)) + 216 | S62*(xz.block(3+1,3,k,i) - xz.block(3-2,3,k,i)) + S63*(xz.block(3+2,3,k,i) - xz.block(3-3,3,k,i))); 217 | ww.block(3,3,k,i) = temp.block(3,3,k,i).cwiseProduct(ww.block(3,3,k,i)) + b1.block(3,3,k,i).cwiseProduct( 218 | S61*(xz.block(3,3+1,k,i) - xz.block(3,3,k,i)) + S62*(xz.block(3,3+2,k,i) - xz.block(3,3-1,k,i)) + 219 | S63*(xz.block(3,3+3,k,i) - xz.block(3,3-2,k,i)) + S61*(zz.block(3+1,3,k,i) - zz.block(3,3,k,i)) + 220 | S62*(zz.block(3+2,3,k,i) - zz.block(3-1,3,k,i)) + S63*(zz.block(3+3,3,k,i) - zz.block(3-2,3,k,i)));} 221 | else if(fd_order_num == 28){ 222 | uu.block(4,4,k,i) = temp.block(4,4,k,i).cwiseProduct(uu.block(4,4,k,i)) + b.block(4,4,k,i).cwiseProduct( 223 | S81*(xx.block(4,4,k,i) - xx.block(4,4-1,k,i)) + S82*(xx.block(4,4+1,k,i) - xx.block(4,4-2,k,i)) + 224 | S83*(xx.block(4,4+2,k,i) - xx.block(4,4-3,k,i)) + S84*(xx.block(4,4+3,k,i) - xx.block(4,4-4,k,i)) + 225 | S81*(xz.block(4,4,k,i) - xz.block(4-1,4,k,i)) + S82*(xz.block(4+1,4,k,i) - xz.block(4-2,4,k,i)) + 226 | S83*(xz.block(4+2,4,k,i) - xz.block(4-3,4,k,i)) + S84*(xz.block(4+3,4,k,i) - xz.block(4-4,4,k,i))); 227 | ww.block(4,4,k,i) = temp.block(4,4,k,i).cwiseProduct(ww.block(4,4,k,i)) + b1.block(4,4,k,i).cwiseProduct( 228 | S81*(xz.block(4,4+1,k,i) - xz.block(4,4,k,i)) + S82*(xz.block(4,4+2,k,i) - xz.block(4,4-1,k,i)) + 229 | S83*(xz.block(4,4+3,k,i) - xz.block(4,4-2,k,i)) + S84*(xz.block(4,4+4,k,i) - xz.block(4,4-3,k,i)) + 230 | S81*(zz.block(4+1,4,k,i) - zz.block(4,4,k,i)) + S82*(zz.block(4+2,4,k,i) - zz.block(4-1,4,k,i)) + 231 | S83*(zz.block(4+3,4,k,i) - zz.block(4-2,4,k,i)) + S84*(zz.block(4+4,4,k,i) - zz.block(4-3,4,k,i)));} 232 | // if (fd_order==22) 233 | // uu(k,i)=temp(k,i).*uu(k,i)+b(k,i).*(S21*(xx(k,i+1)-xx(k,i)+... 234 | // xz(k,i)-xz(k-1,i))); 235 | // ww(k,i)=temp(k,i).*ww(k,i)+b1(k,i).*(S21*(xz(k,i)-xz(k,i-1)+... 236 | // zz(k+1,i)-zz(k,i))); 237 | // elseif (fd_order==24) 238 | // uu(k,i)=temp(k,i).*uu(k,i)+b(k,i).*(S41*(xx(k,i)-xx(k,i-1))+S42*(xx(k,i+1)-xx(k,i-2))+... 239 | // S41*(xz(k,i)-xz(k-1,i))+S42*(xz(k+1,i)-xz(k-2,i))); 240 | // 241 | // ww(k,i)=temp(k,i).*ww(k,i)+b(k,i).*(S41*(xz(k,i+1)-xz(k,i))+S42*(xz(k,i+2)-xz(k,i-1))+... 242 | // S41*(zz(k+1,i)-zz(k,i))+S42*(zz(k+2,i)-zz(k-1,i))); 243 | // elseif (fd_order==26) 244 | // uu(k,i)=temp(k,i).*uu(k,i)+b(k,i).*(S61*(xx(k,i)-xx(k,i-1))+S62*(xx(k,i+1)-xx(k,i-2))+... 245 | // +S63*(xx(k,i+2)-xx(k,i-3))+S61*(xz(k,i)-xz(k-1,i))+S62*... 246 | // (xz(k+1,i)-xz(k-2,i))+S63*(xz(k+2,i)-xz(k-3,i))); 247 | // 248 | // ww(k,i)=temp(k,i).*ww(k,i)+b(k,i).*(S61*(xz(k,i+1)-xz(k,i))+S62*(xz(k,i+2)-xz(k,i-1))+... 249 | // +S63*(xz(k,i+3)-xz(k,i-2))+S61*(zz(k+1,i)-zz(k,i))+S62*... 250 | // (zz(k+2,i)-zz(k-1,i))+S63*(zz(k+3,i)-zz(k-2,i))); 251 | // elseif (fd_order==28) 252 | // uu(k,i)=temp(k,i).*uu(k,i)+b(k,i).*(S81*(xx(k,i)-xx(k,i-1))+S82*(xx(k,i+1)-xx(k,i-2))+... 253 | // +S83*(xx(k,i+2)-xx(k,i-3))+S84*(xx(k,i+3)-xx(k,i-4))+... 254 | // S81*(xz(k,i)-xz(k-1,i))+S82*(xz(k+1,i)-xz(k-2,i))+S83*(xz(k+2,i)-xz(k-3,i))+... 255 | // S84*(xz(k+3,i)-xz(k-4,i))); 256 | // 257 | // ww(k,i)=temp(k,i).*ww(k,i)+b(k,i).*(S81*(xz(k,i+1)-xz(k,i))+S82*(xz(k,i+2)-xz(k,i-1))+... 258 | // S83*(xz(k,i+3)-xz(k,i-2))+S84*(xz(k,i+4)-xz(k,i-3))+... 259 | // S81*(zz(k+1,i)-zz(k,i))+S82*(zz(k+2,i)-zz(k-1,i))+S83*(zz(k+3,i)-zz(k-2,i))+... 260 | // S84*(zz(k+4,i)-zz(k-3,i))); 261 | // end 262 | if(source_type_num == 1){ 263 | xx(sz,sx)=xx(sz,sx)+s(it); 264 | zz(sz,sx)=zz(sz,sx)+s(it);} 265 | else if(source_type_num == 2){ 266 | uu(sz,sx)=uu(sz,sx)+s(it); 267 | uu(sz-1,sx)=uu(sz-1,sx)-s(it); 268 | ww(sz,sx)=ww(sz,sx)+s(it); 269 | ww(sz,sx+1)=ww(sz,sx+1)+s(it);} 270 | else if(source_type_num == 3){ 271 | uu(sz,sx)=uu(sz,sx)+s(it); 272 | ww(sz,sx)=ww(sz,sx)+s(it);} 273 | else if(source_type_num == 4){ 274 | zz(sz,sx)=zz(sz,sx)+s(it);} 275 | else if(source_type_num == 5){ 276 | ww(sz,sx)=s(it);} 277 | 278 | if(fd_order_num == 22){ 279 | fux.block(1,1,k,i) = uu.block(1,1,k,i) - uu.block(1,1-1,k,i); 280 | fuz.block(1,1,k,i) = uu.block(1+1,1,k,i) - uu.block(1,1,k,i); 281 | bwx.block(1,1,k,i) = ww.block(1,1+1,k,i) - ww.block(1,1,k,i); 282 | bwz.block(1,1,k,i) = ww.block(1,1,k,i) - ww.block(1-1,1,k,i);} 283 | else if(fd_order_num == 24){ 284 | fux.block(2,2,k,i) = S41*(uu.block(2,2+1,k,i) - uu.block(2,2,k,i)) + S42*(uu.block(2,2+2,k,i) - uu.block(2,2-1,k,i)); 285 | fuz.block(2,2,k,i) = S41*(uu.block(2+1,2,k,i) - uu.block(2,2,k,i)) + S42*(uu.block(2+2,2,k,i) - uu.block(2-1,2,k,i)); 286 | bwx.block(2,2,k,i) = S41*(ww.block(2,2,k,i) - ww.block(2,2-1,k,i)) + S42*(ww.block(2,2+1,k,i) - ww.block(2,2-2,k,i)); 287 | bwz.block(2,2,k,i) = S41*(ww.block(2,2,k,i) - ww.block(2-1,2,k,i)) + S42*(ww.block(2+1,2,k,i) - ww.block(2-2,2,k,i));} 288 | else if(fd_order_num == 26){ 289 | fux.block(3,3,k,i) = S61*(uu.block(3,3+1,k,i) - uu.block(3,3,k,i)) + S62*(uu.block(3,3+2,k,i) - uu.block(3,3-1,k,i))+ 290 | S63*(uu.block(3,3+3,k,i) - uu.block(3,3-2,k,i)); 291 | fuz.block(3,3,k,i) = S61*(uu.block(3+1,3,k,i) - uu.block(3,3,k,i)) + S62*(uu.block(3+2,3,k,i) - uu.block(3-1,3,k,i))+ 292 | S63*(uu.block(3+3,3,k,i) - uu.block(3-2,3,k,i)); 293 | bwx.block(3,3,k,i) = S61*(ww.block(3,3,k,i) - ww.block(3,3-1,k,i)) + S62*(ww.block(3,3+1,k,i) - ww.block(3,3-2,k,i))+ 294 | S63*(ww.block(3,3+2,k,i) - ww.block(3,3-3,k,i)); 295 | bwz.block(3,3,k,i) = S61*(ww.block(3,3,k,i) - ww.block(3-1,3,k,i)) + S62*(ww.block(3+1,3,k,i) - ww.block(3-2,3,k,i))+ 296 | S63*(ww.block(3+2,3,k,i) - ww.block(3-3,3,k,i));} 297 | else if(fd_order_num == 28){ 298 | fux.block(4,4,k,i) = S81*(uu.block(4,4+1,k,i) - uu.block(4,4,k,i)) + S82*(uu.block(4,4+2,k,i) - uu.block(4,4-1,k,i))+ 299 | S83*(uu.block(4,4+3,k,i) - uu.block(4,4-2,k,i)) + S84*(uu.block(4,4+4,k,i) - uu.block(4,4-3,k,i)); 300 | fuz.block(4,4,k,i) = S81*(uu.block(4+1,4,k,i) - uu.block(4,4,k,i)) + S82*(uu.block(4+2,4,k,i) - uu.block(4-1,4,k,i))+ 301 | S83*(uu.block(4+3,4,k,i) - uu.block(4-2,4,k,i)) + S84*(uu.block(4+4,4,k,i) - uu.block(4-3,4,k,i)); 302 | bwx.block(4,4,k,i) = S81*(ww.block(4,4,k,i) - ww.block(4,4-1,k,i)) + S82*(ww.block(4,4+1,k,i) - ww.block(4,4-2,k,i))+ 303 | S83*(ww.block(4,4+2,k,i) - ww.block(4,4-3,k,i)) + S84*(ww.block(4,4+3,k,i) - ww.block(4,4-4,k,i)); 304 | bwz.block(4,4,k,i) = S81*(ww.block(4,4,k,i) - ww.block(4-1,4,k,i)) + S82*(ww.block(4+1,4,k,i) - ww.block(4-2,4,k,i))+ 305 | S83*(ww.block(4+2,4,k,i) - ww.block(4-3,4,k,i)) + S84*(ww.block(4+3,4,k,i) - ww.block(4-4,4,k,i));} 306 | // fux(k,i)=S21*(uu(k,i)-uu(k,i-1)); 307 | // fuz(k,i)=S21*(uu(k+1,i)-uu(k,i)); 308 | // bwx(k,i)=S21*(ww(k,i+1)-ww(k,i)); 309 | // bwz(k,i)=S21*(ww(k,i)-ww(k-1,i)); 310 | xx=temp.cwiseProduct(xx) + (ca.cwiseProduct(fux) + cl.cwiseProduct(bwz))*dtx; 311 | zz=temp.cwiseProduct(zz) + (ca.cwiseProduct(bwz) + cl.cwiseProduct(fux))*dtx; 312 | xz=temp.cwiseProduct(xz) + (cm1.cwiseProduct(fuz + bwx))*dtx; 313 | // xx=temp.*xx+(ca.*fux+cl.*bwz)*dtx; 314 | // zz=temp.*zz+(ca.*bwz+cl.*fux)*dtx; 315 | // xz=temp.*xz+cm.*(fuz+bwx)*dtx; 316 | zz.row(pad_top) = zero_vector;//临时修改5.20 317 | // zz(pad_top,:)=0.0; 318 | geophone_vector=ww.row(gz); 319 | seismo_w.row(it) = geophone_vector(seq(gx,gx+length_geophone,dg)); 320 | geophone_vector=uu.row(gz); 321 | seismo_u.row(it) = geophone_vector(seq(gx,gx+length_geophone,dg)); 322 | if(it%nt_interval==0){ 323 | wavefield_gradient_fux.block(0,nx*it/nt_interval,nz,nx)=fux.block(pad_top+1,nbc,nz,nx); 324 | wavefield_gradient_fuz.block(0,nx*it/nt_interval,nz,nx)=fuz.block(pad_top+1,nbc,nz,nx); 325 | wavefield_gradient_bwx.block(0,nx*it/nt_interval,nz,nx)=bwx.block(pad_top+1,nbc,nz,nx); 326 | wavefield_gradient_bwz.block(0,nx*it/nt_interval,nz,nx)=bwz.block(pad_top+1,nbc,nz,nx); 327 | } 328 | // for ig=1:ng 329 | // seismo_w(it,ig)=ww(gz(ig),gx(ig)); 330 | // seismo_u(it,ig)=uu(gz(ig),gx(ig)); 331 | // end 332 | 333 | } 334 | 335 | float* eig_seismo_u_ptr = seismo_u.data(); 336 | float* eig_seismo_w_ptr2 = seismo_w.data(); 337 | // float* eig_ww_ptr2 = ww.data(); 338 | std::vector size_output(1,nt); 339 | // size_output.insert(size_output.begin(),nt); 340 | size_output.insert(size_output.end(),ng); 341 | std::vector size_output_wavefield(1,nz); 342 | if(format_num==2){ 343 | size_output_wavefield.insert(size_output_wavefield.end(),nx*num_nt_record);} //export output wavefield gradient as 2D matrix; easy to calculate adjoint source with eigen; 344 | else if(format_num==3){ 345 | size_output_wavefield.insert(size_output_wavefield.end(),nx); 346 | size_output_wavefield.insert(size_output_wavefield.end(),num_nt_record);}//export output wavefield gradient as 3D matrix; It has same format as original matlab code; 347 | float* wavefield_gradient_fux_ptr1 = wavefield_gradient_fux.data(); 348 | float* wavefield_gradient_fuz_ptr2 = wavefield_gradient_fuz.data(); 349 | float* wavefield_gradient_bwx_ptr3 = wavefield_gradient_bwx.data(); 350 | float* wavefield_gradient_bwz_ptr4 = wavefield_gradient_bwz.data(); 351 | matlab::data::StructArray S = factory.createStructArray({ 1,1 }, { "fux", "fuz","bwx","bwz" }); 352 | S[0]["fux"] = factory.createArray(size_output_wavefield,wavefield_gradient_fux_ptr1,wavefield_gradient_fux_ptr1+wavefield_elements);//It is column-major so that the shape of fux can be automaticly reshaped in 3D matrix. 353 | S[0]["fuz"] = factory.createArray(size_output_wavefield,wavefield_gradient_fuz_ptr2,wavefield_gradient_fuz_ptr2+wavefield_elements); 354 | S[0]["bwx"] = factory.createArray(size_output_wavefield,wavefield_gradient_bwx_ptr3,wavefield_gradient_bwx_ptr3+wavefield_elements); 355 | S[0]["bwz"] = factory.createArray(size_output_wavefield,wavefield_gradient_bwz_ptr4,wavefield_gradient_bwz_ptr4+wavefield_elements); 356 | 357 | outputs[0] = factory.createArray(size_output,eig_seismo_u_ptr,eig_seismo_u_ptr + number_elements); 358 | outputs[1] = factory.createArray(size_output,eig_seismo_w_ptr2,eig_seismo_w_ptr2 + number_elements); 359 | outputs[2] = S; 360 | } 361 | 362 | void arrayProduct(matlab::data::TypedArray& matrix, float multiplier) { 363 | // cout <<"matrix:" << matrix << endl; 364 | // cout <<"&matrix:" << & matrix << endl; 365 | } 366 | 367 | 368 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notes 2 | Some notes. 3 | -------------------------------------------------------------------------------- /Use Q&A: -------------------------------------------------------------------------------- 1 | Q&A 2 | 3 | 如果运行伴随源的时候出现如下问题(在./scratch/solver/mainsolver/adj_solver.log): Sorry, approximate elastic Hessian kernels not yet fully implemented for GPU simulations! 4 | 临时的解决方案是,只计算Hessian1,不计算Hessian2(反正我们也不需要) 5 | 在 ./seisflows/seisflows/solver/specfem.py中搜索: SIMULATION_TYPE 6 | 当 SIMULATION_TYPE == 1 7 | 添加 setpar(key="APPROXIMATE_HESS_KL", val=".true.", file="DATA/Par_file") 8 | 当 SIMULATION_TYPE == 3 9 | 添加 setpar(key="APPROXIMATE_HESS_KL", val=".false.", file="DATA/Par_file") 10 | 11 | 最后的效果应该是 12 | 13 | setpar(key="SIMULATION_TYPE", val="1", file="DATA/Par_file") 14 | setpar(key="APPROXIMATE_HESS_KL", val=".true.", file="DATA/Par_file") 15 | setpar(key="SAVE_FORWARD", val=f".{str(flag_save_forward).lower()}.", 16 | file="DATA/Par_file") 17 | (中间省略代码) 18 | setpar(key="SIMULATION_TYPE", val="3", file="DATA/Par_file") 19 | setpar(key="APPROXIMATE_HESS_KL", val=".false.", file="DATA/Par_file") 20 | setpar(key="SAVE_FORWARD", val=".false.", file="DATA/Par_file") 21 | 22 | 23 | 长久的方案是等待SPECFEM支持 24 | 25 | ### Q&A 26 | 27 | **Q:** What should I do if I encounter the following issue while running the adjoint source (in `./scratch/solver/mainsolver/adj_solver.log`): 28 | `Sorry, approximate elastic Hessian kernels not yet fully implemented for GPU simulations!`? 29 | 30 | **A:** 31 | As a temporary solution, you can compute only Hessian1 and skip Hessian2 (since we don't need it anyway). 32 | 33 | 1. In `./seisflows/seisflows/solver/specfem.py`, search for: `SIMULATION_TYPE`. 34 | 2. When `SIMULATION_TYPE == 1`, add: 35 | ```python 36 | setpar(key="APPROXIMATE_HESS_KL", val=".true.", file="DATA/Par_file") 37 | ``` 38 | 3. When `SIMULATION_TYPE == 3`, add: 39 | ```python 40 | setpar(key="APPROXIMATE_HESS_KL", val=".false.", file="DATA/Par_file") 41 | ``` 42 | 43 | The final implementation should look like this: 44 | 45 | ```python 46 | setpar(key="SIMULATION_TYPE", val="1", file="DATA/Par_file") 47 | setpar(key="APPROXIMATE_HESS_KL", val=".true.", file="DATA/Par_file") 48 | setpar(key="SAVE_FORWARD", val=f".{str(flag_save_forward).lower()}.", file="DATA/Par_file") 49 | # (omitted code) 50 | setpar(key="SIMULATION_TYPE", val="3", file="DATA/Par_file") 51 | setpar(key="APPROXIMATE_HESS_KL", val=".false.", file="DATA/Par_file") 52 | setpar(key="SAVE_FORWARD", val=".false.", file="DATA/Par_file") 53 | ``` 54 | 55 | **Long-term Solution:** 56 | Wait for SPECFEM to fully support this feature in future updates. 57 | -------------------------------------------------------------------------------- /about_forward_modeling/CSG1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/CSG1.png -------------------------------------------------------------------------------- /about_forward_modeling/CSG2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/CSG2.png -------------------------------------------------------------------------------- /about_forward_modeling/PINN1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/PINN1.png -------------------------------------------------------------------------------- /about_forward_modeling/PINN2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/PINN2.png -------------------------------------------------------------------------------- /about_forward_modeling/PINN3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/PINN3.png -------------------------------------------------------------------------------- /about_forward_modeling/PINN4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/PINN4.png -------------------------------------------------------------------------------- /about_forward_modeling/PINN5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/PINN5.png -------------------------------------------------------------------------------- /about_forward_modeling/README.md: -------------------------------------------------------------------------------- 1 | #
地震正演方法讨论
2 |
张敞 2021622054
3 | 4 | ## 前言 5 | 地球物理问题通常通过反演手段获得地下介质的物性参数,进而推断地下地质结构。正反演在实际工作中相辅相成,只有正演波场越接近实际波场,反演才能得到更准确的介质参数。地震反演中对于介质波速较为敏感,而对密度等信息不敏感。在基于波动方程的地震正演方法中,按照数学方法分类有有限差分方法和有限元方法。按照近似方程分类可以分成声波方程,弹性波方程,粘弹性方程等等。除了基础的数值计算方法外,物理约束的神经网络(Physics Informed Neural Network, PINN)也能够达到地震正演的目的,不过这种方法声称没有数值色散误差和方程近似带来的误差,但它巨大的计算量和可能有其他误差存在导致这种方法并不实用。除了关心正演方法的精度外,正演方法的计算效率也至关重要。如果一个正演方法速度有很大提升,则整个反演过程会节约大量时间(反传过程只要轻微改动),进而测试更多模型,解决更多实际问题。本文列举一些速度模型分别在声波方程和弹性波方程下的有限差分正演结果,PINN正演模拟结果以及实用技术带来的正演效率提升。 6 | ## 模型正演结果 7 | 如图一所示为一个常规二维速度模型,速度从1000m/s变化到2500m/s。模型大小为26*120m。 8 | ![model1](./model1.png) 9 | 图一:纵波速度模型 10 | 11 | 正演过程中,为了满足稳定性条件: 12 | $$ 13 | dx < \frac{\min v}{f*12} 14 | $$ 15 | 其中$f$为雷克子波主频,$\min v$为模型中的最小速度,在主频为30Hz的情况下一个网格最大代表2.78m的实际距离。这里采用1m间距的网格点,因此网格大小为26*120。除了空间网格要满足稳定性条件防止色散误差外,时间步长也要满足稳定性条件: 16 | $$ 17 | dt< \frac{dx}{2\times \max v} 18 | $$ 19 | 这里采用$dt=2e-4$。使用22阶有限差分进行计算,得到的单炮记录如图二所示: 20 | ![CSG1](./CSG1.png) 21 | 图二:声波方程单炮记录。 22 | 图中能看到两个速度界面间的起伏产生的反射波,初至波以及由于边界产生的一些散射。 23 | 24 | 对于弹性波方程,与声波方程不同之处在于弹性波方程正演需要输入横波速度$vs$如图三所示: 25 | 26 | ![vs](./vs.png) 27 | 图三:横波速度模型。 28 | 如图所示,横波速度与纵波速度保持了恒定的泊松比,横波速度根据经验公式$vp=1.732 \times vs$计算。 29 | 弹性波计算通常采用交错网格的有限差分方法,将应力与速度分成两套网格,每次迭代依次计算应力与速度,能够达到更高的计算精度。因此在震源的设置上可以将子波添加到速度或者应力分量。基于弹性波方程得到的垂直分量CSG如图四所示: 30 | 31 | ![CSG2](./CSG2.png) 32 | 图四:弹性波CSG垂直分量。 33 | 图中能够看到由于自由边界产生的面波,界面反射产生的反射波,以及初至波等等。 34 | 35 | ## PINN 正演模拟 36 | 在地震或雷达中PINN通常用一个全连接神经网络直接输出波形振幅相对于空间位置和时间的映射关系,在此基础上利用神经网络框架(如Tensorflow或Pytorch)的自动微分功能使映射关系满足要模拟波场的物理关系,如边值条件,波动方程等等。PINN的网络结构如图五所示: 37 | ![net](./net.png) 38 | 图五:PINN网络结构示意图。 39 | 在X,Z分量输入波形的空间位置,t输入对应时刻,就能得到波形的振幅。现今各种神经网络框架都基于计算图进行正反传计算,计算图会自动记录每个计算节点,如果求输出关于输入的导数就会得到: 40 | $$ 41 | \begin{bmatrix} 42 | \frac{\partial \phi }{\partial x} &\frac{\partial \phi }{\partial z} & \frac{\partial \phi }{\partial t}\\ \\ 43 | \frac{\partial \phi }{\partial x} &\frac{\partial \phi }{\partial z} & \frac{\partial \phi }{\partial t}\\ \vdots& \vdots & \vdots\\ 44 | \frac{\partial \phi }{\partial x} &\frac{\partial \phi }{\partial z} & \frac{\partial \phi }{\partial t}\\ 45 | \end{bmatrix}. 46 | $$ 47 | 计算图能够符号化保存每个节点的计算步骤,因此很轻松能够计算出各个输出变量与输入变量间的导数关系,进一步将导数值作为约束条件添加到神经网络优化训练的目标函数中,也就达到了物理约束的目的。图六图七展示了一个PINN网络模拟的地震波在不同时刻下的波场快照和拟合曲线对比: 48 | ![pinn1](./PINN1.png) 49 | ![pinn2](./PINN2.png) 50 | ![pinn3](./PINN3.png) 51 | 52 | 图六:PINN在t=0,0.015,0.15s的波场快照。 53 | 54 | ![pinn4](./PINN4.png) 55 | ![pinn5](./PINN5.png) 56 | 图七:PINN拟合曲线与输入数据的拟合情况。 57 | 由PINN的实现过程可知,PINN这种方法的确没有传统方法的误差。但PINN将物理条件作为约束添加到目标函数增加了训练过程中最优化问题的复杂度,增加了新的误差。此外,PINN的泛化能力也是瓶颈之一。例如在地震中,不同炮点的波场完全不同,只能用多个PINN或者设计更加复杂的网络结构,这进一步增加了PINN训练过程的复杂程度。训练网络通常采用数值方法作为训练样本,这也限制了PINN能达到的最大精度。 58 | 59 | ## 编程语言与计算效率 60 | 为了在最少的时间获取最多的性能,充分利用已有的API来获得更多的性能是一种合理的做法。Matlab是一种解释性语言,为了较好的用户交互而部分牺牲了速度上的优势,体现为循环的计算较慢。但Matlab对内置命令指令集级别的优化和矩阵计算的自动并行让其他语言难以望其项背。Eigen是一个免费的c++的矩阵运算库,有着清晰和直观的API,同样指令集级别的优化有着不输于Matlab的矩阵运算速度。MKL(Intel Math Kernel Library)是适用于Intel CPU的一个经过高度优化的,大量并行化的数学计算库。Matlab内置了MKL: 61 | ```matlab 62 | version -lapack 63 | ans = 64 | 65 | 'Intel(R) Math Kernel Library Version 2019.0.3 Product Build 20190125 for 66 | Intel(R) 64 architecture applications, CNR branch AVX512_E1, supporting 67 | Linear Algebra PACKage (LAPACK 3.7.0)' 68 | ``` 69 | 可以看到启动了每个时钟周期内可以打包32次双精度和64次单精度浮点运算的AVX512指令集。而Eigen可以启动MKL作为后端对特定区间大小矩阵获得更高的计算效率: 70 | ```c++ 71 | #define EIGEN_USE_MKL_ALL 72 | ``` 73 | 因此,将有限差分中复杂的矩阵计算交给Eigen,整体利用Maltab框架,就能最大程度的兼顾交互性和计算效率。表一为使用Matlab与使用c++ Eigen MKL多次有限差分正演的时间消耗对比。 74 | | 网格大小 | Mex单精度(s) | Mex双精度(s) |Matlab单精度(s) | Matlab双精度(s) | 75 | | :----: | :----: | :----: | :----: | :----: | 76 | | 58x184 | 10.4 | 22.5 | 42.1 |50.1| 77 | |88x244 | 14.3 | | 141.2 | | 78 | |128x324 | 71.4 | |392.6 | | 79 | |178x424 | 236 | |1213.4 | | 80 | |142x1280 | 583 | |2780 | | 81 | 表一:不同精度、网格下Matlab与C++一次正演消耗时间对比(不同网格大小nt不同)。 82 | 83 | ## 总结 84 | 本文探讨了地震正演中会遇到的多种问题,包括传统有限差分模型正演效果,物理约束神经网络正演的优势劣势,以及对于正演性能的讨论。 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /about_forward_modeling/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/README.pdf -------------------------------------------------------------------------------- /about_forward_modeling/model1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/model1.png -------------------------------------------------------------------------------- /about_forward_modeling/net.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/net.png -------------------------------------------------------------------------------- /about_forward_modeling/vs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trinitite271/Notes/114491d58288bbb288d15414f527e70f4e2c3473/about_forward_modeling/vs.png -------------------------------------------------------------------------------- /newenvironment: -------------------------------------------------------------------------------- 1 | record new environment set up in KFUPM 2 | 3 | **install conda** 4 | mkdir -p ~/miniconda3 5 | wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh 6 | bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 7 | rm ~/miniconda3/miniconda.sh 8 | 9 | source ~/miniconda3/bin/activate 10 | 11 | conda init --all 12 | 13 | **install jupyter** 14 | conda activate base 15 | conda install jupyter 16 | conda install nb_conda_kernels 17 | conda activate seisflows 18 | conda install ipykernel 19 | conda activate base 20 | screen -S zc 21 | jupyter notebook --no-browser --port=8765 22 | (in another shell) ssh -N -L 8765:localhost:8765 ec9252605@10.77.14.239 23 | 24 | Press and hold Ctrl, then press and hold A, and finally press D to exit screen. 25 | 26 | 27 | **get specfem and seisflow** 28 | git clone --branch devel https://github.com/adjtomo/seisflows.git 29 | cd seisflows 30 | conda env create -f environment.yml 31 | conda activate seisflows 32 | cd ~ 33 | git clone --recursive --branch devel https://github.com/SPECFEM/specfem2d.git 34 | 35 | 36 | **install pytorch** 37 | conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia 38 | 39 | 40 | **set up remote** 41 | xclock 42 | export DISPLAY=127.0.0.1:25.0(add to ~/.bashrc) 43 | ssh -R 6025:127.0.0.1:6000 ec9252605@10.77.14.239 44 | 45 | 46 | **install matlab** 47 | wget ‘https://esd.mathworks.com/R2024b/Release/3/licensed_software/installers/matlab_R2024b_Linux.zip?__gda__=1737641281_7b2e7ddf493d784af85cae911c7b755b&dl_id=cHbA3cp3&ext=.zip’ 48 | unzip https://esd.mathworks.com/R2024b/Release/3/licensed_software/installers/matlab_R2024b_Linux.zip?__gda__=1737641281_7b2e7ddf493d784af85cae911c7b755b&dl_id=cHbA3cp3&ext=.zip -d matlabinstall 49 | cd matlabinstall 50 | ./install 51 | 52 | 53 | **intel complier** 54 | # wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/163da6e4-56eb-4948-aba3-debcec61c064/l_BaseKit_p_2024.0.1.46_offline.sh 55 | # wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/7deeaac4-f605-4bcf-a81b-ea7531577c61/l_BaseKit_p_2023.1.0.46401_offline.sh 56 | wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/67c08c98-f311-4068-8b85-15d79c4f277a/l_HPCKit_p_2024.0.1.38_offline.sh 57 | wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/163da6e4-56eb-4948-aba3-debcec61c064/l_BaseKit_p_2024.0.1.46_offline.sh 58 | sh ./l_BaseKit_p_2024.0.1.46_offline.sh 59 | sh ./l_HPCKit_p_2024.0.1.38_offline.sh 60 | 61 | **cuda118** 62 | wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run 63 | sh ./cuda_11.8.0_520.61.05_linux.run 64 | 65 | **config SPECFEM CPU&GPU** 66 | # source /data/zhangchang/intel/oneapi/setvars.sh 67 | # ./configure FC=ifort MPIFC=mpiifort --with-mpi 68 | ./configure FC=gfortran CC=gcc MPIFC=mpif90 --with-mpi --with-cuda=cuda11 CUDA_LIB=/usr/local/cuda/lib64 --enable-vectorization 69 | make all 70 | 71 | **debug** 72 | # python -m pdb /data/zhangchang/seisflows/seisflows/system/runscripts/submit --workdir /data/zhangchang/projects/VGdataGPSTinv --parameter_file parameters.yaml 73 | python -m pdb /csim1/zhangchang/seisflow_devel/seisflows/system/runscripts/submit --workdir /csim1/zhangchang/shenzhenGPSTinv --parameter_file parameters.yaml 74 | os.environ['DISPLAY'] = '127.0.0.1:25.0';import matplotlib;matplotlib.use('TkAgg');plt.figure();plt.show() 75 | plt.imshow(grad_output2, cmap='jet', aspect='auto');plt.colorbar();plt.show() 76 | 77 | 78 | 79 | 80 | --------------------------------------------------------------------------------