⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zeltform.cc

📁 二维射线追踪地震层析成像
💻 CC
字号:
/* * zeltform.cc *  * Jun Korenaga, MIT/WHOI * January 1999 */#include "zeltform.h"#include <iostream>#include <fstream>#include <list>#include <cstdio>#include <cstdlib>#include <cstring>#include <util.h>#include <error.h>TrapezoidCell2d::TrapezoidCell2d(double _x1, double _x2,				 double _z1, double _z2, double _z3, double _z4,				 double _v1, double _v2, double _v3, double _v4)    : x1(_x1), x2(_x2), v1(_v1), v2(_v2), v3(_v3), v4(_v4){    double rdx = 1.0/(x1-x2);    s1 = (_z1-_z2)*rdx;    b1 = _z1-s1*x1;    s2 = (_z3-_z4)*rdx;    b2 = _z3-s2*x1;    c1 = s2*(x2*v1-x1*v2)+b2*(v2-v1)-s1*(x2*v3-x1*v4)-b1*(v4-v3);    c2 = s2*(v2-v1)-s1*(v4-v3);    c3 = x1*v2-x2*v1+x2*v3-x1*v4;    c4 = v1-v2+v4-v3;    c5 = b2*(x2*v1-x1*v2)-b1*(x2*v3-x1*v4);    c6 = (s2-s1)*(x2-x1);    c7 = (b2-b1)*(x2-x1);// check//    double vv1 = at(Point2d(x1,_z1));//    double vv2 = at(Point2d(x2,_z2));//    double vv3 = at(Point2d(x1,_z3));//    double vv4 = at(Point2d(x2,_z4));//    cerr << "input: " << v1 << " " << v2 << " " << v3 << " " << v4 << '\n';//    cerr << "out: " << vv1 << " " << vv2 << " " << vv3 << " " << vv4 << '\n';//    cerr << '\n';    }bool TrapezoidCell2d::isIn(const Point2d& p) const{    double x=p.x(), z=p.y();    if (x<x1 || x>x2) return false;    double zup = s1*x+b1;    double zdown = s2*x+b2;    if (z<zup || z>zdown) return false;    return true;}double TrapezoidCell2d::at(const Point2d& p) const{    double x=p.x(), z=p.y();    double val1 = (c1+c2*x)*x + (c3+c4*x)*z + c5;    double val2 = c6*x+c7;    return val1/val2;}void TrapezoidCell2d::dumpCell(ostream& os) const{    os << x1 << " " << x1*s1+b1 << '\n';    os << x2 << " " << x2*s1+b1 << '\n';    os << x2 << " " << x2*s2+b2 << '\n';    os << x1 << " " << x1*s2+b2 << '\n';}ZeltVelocityModel2d::ZeltVelocityModel2d(char *fn){    ifstream s(fn);    if (!s){	cerr << "ZeltVelocityModel2d::can't open " << fn << '\n';	exit(1);    }    node_p.resize(3);    node_p(1) = &depth_node;    node_p(2) = &vupper_node;    node_p(3) = &vlower_node;        char line[MaxStr];    Array1d<double> tmp_val;    int itype = 1;    int ilayer = 1;    node_p(itype)->push_back(new ZNode2d);    while (s.getline(line,MaxStr)){	// read x coordinate line	int nx=readLine(line,tmp_val);	for (int i=2; i<=tmp_val.size(); i++){	    (*node_p(itype))(ilayer)->x.push_back(tmp_val(i));	}	// read value line	s.getline(line,MaxStr);	int nv=readLine(line,tmp_val);	if (nx!=nv) error("ZeltVelocityModel2d::invalid input file");	for (int i=2; i<=tmp_val.size(); i++){	    (*node_p(itype))(ilayer)->val.push_back(tmp_val(i));	}	int cont_flag = int(tmp_val(1));	// read inversion flag line (do nothing for this line)	if (!s.getline(line,MaxStr)) break; // end of v.in	if (cont_flag == 0){	    if (itype == 3){		itype = 1; ilayer++;	    }else{		itype++;	    }	    node_p(itype)->push_back(new ZNode2d);	}    }    int nlayer=ilayer;    for (ilayer=1; ilayer<nlayer; ilayer++){	list<double> xs;	for (int itype=1; itype<=3; itype++){	    const Array1d<double>* xp = &((*node_p(itype))(ilayer)->x);	    for (int i=1; i<=xp->size(); i++){		xs.push_back((*xp)(i));	    }	}	const Array1d<double>* xp = &((*node_p(1))(ilayer+1)->x);	for (int i=1; i<=xp->size(); i++){	    xs.push_back((*xp)(i));	}	xs.sort();	xs.unique();	list<double>::const_iterator p1 = xs.begin();	list<double>::const_iterator p2 = xs.begin(); p2++;	while(p2!=xs.end()){	    double x1 = *p1++; 	    double x2 = *p2++; 	    double z1 = interp((*node_p(1))(ilayer), x1);	    double z2 = interp((*node_p(1))(ilayer), x2);	    double z3 = interp((*node_p(1))(ilayer+1), x1);	    double z4 = interp((*node_p(1))(ilayer+1), x2);	    double v1 = interp((*node_p(2))(ilayer), x1);	    double v2 = interp((*node_p(2))(ilayer), x2);	    double v3 = interp((*node_p(3))(ilayer), x1);	    double v4 = interp((*node_p(3))(ilayer), x2);	    cells.push_back(new TrapezoidCell2d(x1,x2,z1,z2,z3,z4,						v1,v2,v3,v4));	}    }        // check the above (by printing out)//     for (int i=1; i<=node_p(1)->size(); i++){// 	cout << "ilayer=" << i << '\n';// 	int itype_max;// 	if (i<node_p(1)->size()){// 	    itype_max = 3;// 	}else{// 	    itype_max = 1;// 	}// 	for (int itype=1; itype<=itype_max; itype++){// 	    cout << "itype=" << itype << '\n';// 	    Array1d<double>* xp = &((*node_p(itype))(i)->x);// 	    Array1d<double>* vp = &((*node_p(itype))(i)->val);// 	    for (int j=1; j<=xp->size(); j++){// 		cout << "(" << (*xp)(j) << "," << (*vp)(j) << ") ";// 	    }// 	    cout << '\n';// 	}//     }	}    double ZeltVelocityModel2d::at(double x, double z) const{    Point2d p(x,z);    for (int i=1; i<=cells.size(); i++){	if (cells(i)->isIn(p)) return cells(i)->at(p);    }    cerr << "ZeltVelocityModel2d::at - failed at ("	 << x << "," << z << ")\n";    exit(1);}void ZeltVelocityModel2d::getTopo(int ilayer, double dx,				  Array1d<double>& xs,				  Array1d<double>& ts) const{    if (ilayer<1 || ilayer>node_p(1)->size())	error("ZeltVelocityModel2d::getTopo - invalid layer number");        const Array1d<double>* xp = &((*node_p(1))(ilayer)->x);    const Array1d<double>* vp = &((*node_p(1))(ilayer)->val);    xs.resize(0); ts.resize(0);    for (int i=1; i<xp->size(); i++){	double DX = (*xp)(i+1)-(*xp)(i);	int ndiv = int(DX/dx+0.5);	double ddx = DX/ndiv;	for (int j=0; j<ndiv; j++){	    double x = (*xp)(i)+j*ddx;	    double t = interp((*node_p(1))(ilayer), x);	    xs.push_back(x);	    ts.push_back(t);	}    }    xs.push_back(xp->back());    ts.push_back(vp->back());}void ZeltVelocityModel2d::dumpNodes(const char* fn) const{    char dfn[MaxStr], vfn[MaxStr], cfn[MaxStr];    sprintf(dfn, "%s.dnodes", fn);    sprintf(vfn, "%s.vnodes", fn);    sprintf(cfn, "%s.cells", fn);    ofstream ds(dfn), vs(vfn), cs(cfn);    for (int ilayer=1; ilayer<=node_p(1)->size(); ilayer++){	const Array1d<double>* xp = &((*node_p(1))(ilayer)->x);	const Array1d<double>* vp = &((*node_p(1))(ilayer)->val);	for (int i=1; i<=xp->size(); i++){	    double x = (*xp)(i);	    double z = (*vp)(i);	    ds << x << " " << z << '\n';	}    }    for (int ilayer=1; ilayer<=node_p(2)->size(); ilayer++){	const Array1d<double>* xp = &((*node_p(2))(ilayer)->x);	for (int i=1; i<=xp->size(); i++){	    double x = (*xp)(i);	    double z = interp((*node_p(1))(ilayer),x);	    vs << x << " " << z << '\n';	}    }    for (int ilayer=1; ilayer<=node_p(3)->size(); ilayer++){	const Array1d<double>* xp = &((*node_p(3))(ilayer)->x);	for (int i=1; i<=xp->size(); i++){	    double x = (*xp)(i);	    double z = interp((*node_p(1))(ilayer),x);	    vs << x << " " << z << '\n';	}    }    for (int i=1; i<=cells.size(); i++){	cs << ">\n";	cells(i)->dumpCell(cs);    }}int ZeltVelocityModel2d::readLine(char *line, Array1d<double>& tmp){    tmp.resize(0);    char *word = strtok(line, " ");    while (word != NULL){	tmp.push_back(atof(word));	word = strtok(NULL, " ");    }    return tmp.size();}double ZeltVelocityModel2d::interp(const ZNode2d* p, double x) const{    const double eps = 1e-6;    const int nx=p->x.size();    if (nx==1){	return p->val(1);    }    for (int i=1; i<nx; i++){	double xnode=p->x(i);	double xnode2=p->x(i+1);		if (i==1 && (x-xnode)<=eps){ // to the left	    return p->val.front();	}else if (i==(nx-1) && (x-xnode2)>=eps){ // to the right	    return p->val.back();	}else if (abs(x-xnode)<eps){ // on a grid	    return p->val(i);	}else if (abs(x-xnode2)<eps){ // on a grid	    return p->val(i+1); 	}else if (x > xnode && x < xnode2){ // interpolate	    double r = (x-xnode)/(xnode2-xnode);	    double dv = (p->val(i+1))-(p->val(i));	    return p->val(i)+r*dv;	}    }    cerr << "x=" << x << " nx=" << nx << '\n';    for (int i=1; i<=nx; i++){	cerr << p->x(i) << ", ";    }    cerr << '\n';    error("ZeltVelocityModel2d::interp - impossible!");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -