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

📄 syngen.cc

📁 二维射线追踪地震层析成像
💻 CC
字号:
/* * syngen.cc - forward traveltime calculation  *  * Jun Korenaga, MIT/WHOI * January 1999 */#include <iostream>#include <fstream>#include <string>#include <cmath>#include <ctime>#include "syngen.h"#include "betaspline.h"#include "traveltime.h"SyntheticTraveltimeGenerator2d::SyntheticTraveltimeGenerator2d(    SlownessMesh2d& m, const char* ifn,    int xorder, int zorder, double clen, int nintp, double cg_tol, double br_tol)    : smesh(m), graph(smesh,xorder,zorder),      betasp(1,0,nintp), bend(smesh,betasp,cg_tol,br_tol),      nrefl(0), do_full_refl(false),      outray(false), use_clock(false), verbose_level(-1){    if (clen>0.0) graph.refineIfLong(clen);    start_i.reserve(2); end_i.reserve(2);    interp.reserve(2);    bathyp = new Interface2d(smesh);    graph_only = false;    read_file(ifn);}void SyntheticTraveltimeGenerator2d::graphOnly(){    graph_only = true;}void SyntheticTraveltimeGenerator2d::conduct(){    ofstream *rout_p;    if (outray) rout_p = new ofstream(rayfn);	    Array1d<Point2d> path;    const int max_np = int(2*sqrt(float(smesh.numNodes())));    path.reserve(max_np);    Array1d<double> modelv, tmp_modelv;    if (do_full_refl){	modelv.resize(smesh.numNodes());	tmp_modelv.resize(smesh.numNodes());	smesh.get(modelv);	int nx(smesh.Nx()), nz(smesh.Nz());	double pwater = 1.0/1.5;	tmp_modelv = modelv;	Array1d<int> irefl(nx);	for (int i=1; i<=nx; i++){	    Point2d p = smesh.nodePos(smesh.nodeIndex(i,1));	    double reflz = reflp->z(p.x());	    irefl(i) = nz;	    for (int k=1; k<=nz; k++){		if (smesh.nodePos(smesh.nodeIndex(i,k)).y()>reflz){		    irefl(i) = k;		    break;		}	    }	}	for (int i=1; i<=nx; i++){	    for (int k=2; k<=nz; k++){		if (k==irefl(i)){		    // this is to make the velocity at the node just below the reflector to		    // be the same sa the velocity just above. If I use pwater for this node,		    // there would be a unwanted low velocity gradient surrounding the reflector.		    tmp_modelv(smesh.nodeIndex(i,k)) = tmp_modelv(smesh.nodeIndex(i,k-1));		}else if (k>irefl(i)){		    tmp_modelv(smesh.nodeIndex(i,k)) = pwater;		}	    }	}    }        graph_time=bend_time=0.0;        for (int isrc=1; isrc<=src.size(); isrc++){	if (verbose_level>=0){	    cerr << "isrc=" << isrc << " nrec=" << rcv(isrc).size()		 << " ";	}	// limit range first	double xmin=smesh.xmax();	double xmax=smesh.xmin();	for (int ircv=1; ircv<=rcv(isrc).size(); ircv++){	    double x = rcv(isrc)(ircv).x();	    if (x < xmin) xmin = x;	    if (x > xmax) xmax = x;	}	double srcx=src(isrc).x();	if (srcx < xmin) xmin = srcx;	if (srcx > xmax) xmax = srcx;	graph.limitRange(xmin,xmax);	if (verbose_level>=1){	    cerr << "xrange=(" << xmin << "," << xmax << ") ";	}	clock_t start_t = clock();	graph.solve(src(isrc));	bool is_refl_solved=false;	clock_t end_t=clock();	graph_time += end_t-start_t;	start_t = clock();	double graph_refl_time=0;	for (int ircv=1; ircv<=rcv(isrc).size(); ircv++){	    Point2d r = rcv(isrc)(ircv);	    double orig_t, final_t;	    int icode = raytype(isrc)(ircv);	    if (icode == 0){ // refraction		if (smesh.inWater(r)){		    if (verbose_level>=0) cerr << "*";		    int i0, i1;		    graph.pickPathThruWater(r,path,i0,i1);		    start_i.resize(1); end_i.resize(1); interp.resize(1);		    start_i(1) = i0; end_i(1) = i1; interp(1) = bathyp;		    if (graph_only){			final_t = calcTravelTime(smesh,path,betasp.numIntp());		    }else{			int iterbend=bend.refine(path,orig_t,final_t,						 start_i, end_i, interp);			if (verbose_level>=1) cerr << "(" << iterbend << ")";		    }		}else{		    if (verbose_level>=0) cerr << ".";		    graph.pickPath(r,path);		    if (graph_only){			final_t = calcTravelTime(smesh,path,betasp.numIntp());		    }else{			const int nfac=1;			int iterbend=bend.refine(path,orig_t,final_t,nfac);			if (verbose_level>=1) cerr << "(" << iterbend << ")";		    }		}	    }else if (icode == 1){ // reflection		if (nrefl==0){		    error("SyntheticTraveltimeGenerator2d:: reflector not specified.");		}		if (do_full_refl){		    // temporarily replace sub-reflector velocity field		    // with water velocity		    smesh.set(tmp_modelv);		}		if (!is_refl_solved){		    clock_t start_t=clock();		    graph.solve_refl(src(isrc), *reflp);		    clock_t end_t=clock();		    graph_refl_time = end_t-start_t;		    graph_time += graph_refl_time;		    		    is_refl_solved = true;		}		if (smesh.inWater(r)){		    if (verbose_level>=0) cerr << "#";		    int i0, i1, ir0, ir1;		    graph.pickReflPathThruWater(r,path,i0,i1,ir0,ir1);		    start_i.resize(2); end_i.resize(2); interp.resize(2);		    start_i(1) = i0; end_i(1) = i1; interp(1) = bathyp;		    start_i(2) = ir0; end_i(2) = ir1; interp(2) = reflp;		    if (graph_only){			final_t = calcTravelTime(smesh,path,betasp.numIntp());		    }else{			int iterbend=bend.refine(path,orig_t,final_t,						 start_i, end_i, interp);			if (verbose_level>=1) cerr << "(" << iterbend << ")";		    }		}else{		    if (verbose_level>=0) cerr << "+";		    int ir0, ir1;		    graph.pickReflPath(r,path,ir0,ir1);		    start_i.resize(1); end_i.resize(1); interp.resize(1);		    start_i(1) = ir0; end_i(1) = ir1; interp(1) = reflp;		    if (graph_only){			final_t = calcTravelTime(smesh,path,betasp.numIntp());		    }else{			int iterbend=bend.refine(path,orig_t,final_t,						 start_i, end_i, interp);			if (verbose_level>=1) cerr << "(" << iterbend << ")";		    }		}		if (do_full_refl){		    // revert to the original smesh		    smesh.set(modelv);		}	    }else{		error("SyntheticTraveltimeGenerator2d:: illegal raycode detected.");	    }	    if (outray){		*rout_p << ">\n";		if (graph_only){		    for (int i=1; i<=path.size(); i++){			*rout_p << path(i).x() << " " << path(i).y() << '\n';		    }		}else{		    printCurve(*rout_p,path,betasp);		}	    }	    syn_ttime(isrc)(ircv) = final_t;	}	if (verbose_level>=0) cerr << '\n';	end_t = clock();	bend_time += end_t-start_t-graph_refl_time;    }    graph_time /= CLOCKS_PER_SEC;    bend_time /= CLOCKS_PER_SEC;    if (use_clock){	ofstream os(timefn);	os << "graph_time " << graph_time << " sec " 	   << "bend_time " << bend_time << " sec \n";    }    if (outray) rout_p->flush(); // make sure all rays are printed out.}void SyntheticTraveltimeGenerator2d::outputRay(const char* fn){ outray=true; rayfn=fn; }void SyntheticTraveltimeGenerator2d::useClock(const char* fn){ use_clock=true; timefn=fn; }void SyntheticTraveltimeGenerator2d::setVerbose(int i){ verbose_level = i; }void SyntheticTraveltimeGenerator2d::read_file(const char* ifn){    ifstream in(ifn);    if (!in){	cerr << "SyntheticTraveltimeGenerator2d::cannot open " << ifn << "\n";	exit(1);    }    int iline=0;    string first;    in >> first; iline++;    if (!isdigit(*first.c_str()))	error("SyntheticTraveltimeGenerator2d::first line should be nsrc");    int nsrc = atoi(first.c_str());    if (nsrc<=0) error("SyntheticTraveltimeGenerator2d::invalid nsrc");    src.resize(nsrc); rcv.resize(nsrc);    raytype.resize(nsrc);    syn_ttime.resize(nsrc); obs_ttime.resize(nsrc); obs_dt.resize(nsrc);    int isrc=0;    while(in){	char flag;	double x, y;	int nrcv;	in >> flag >> x >> y >> nrcv; iline++;	if (flag!='s'){	    cerr << "SyntheticTraveltimeGenerator2d::bad input (s) at l."		 << iline << '\n';	    exit(1);	}	isrc++;	src(isrc).set(x,y);	rcv(isrc).resize(nrcv); raytype(isrc).resize(nrcv);	syn_ttime(isrc).resize(nrcv);	obs_ttime(isrc).resize(nrcv); obs_dt(isrc).resize(nrcv);	for (int ircv=1; ircv<=nrcv; ircv++){	    int n;	    double ttime_val, dt_val;	    in >> flag >> x >> y >> n >> ttime_val >> dt_val; iline++;	    if (flag!='r'){		cerr << "SyntheticTraveltimeGenerator2d::bad input (r) at l."		     << iline << '\n';		exit(1);	    }	    rcv(isrc)(ircv).set(x,y);	    raytype(isrc)(ircv) = n;	    obs_ttime(isrc)(ircv) = ttime_val;	    obs_dt(isrc)(ircv) = dt_val;	}	if (isrc==nsrc) break;    }    if (isrc != nsrc) error("SyntheticTraveltimeGenerator2d::mismatch in nsrc");}voidSyntheticTraveltimeGenerator2d::readRefl(const char* fn){    reflp = new Interface2d(fn);    nrefl = 1;}voidSyntheticTraveltimeGenerator2d::doFullRefl(){    do_full_refl = true;    graph.do_refl_downward();}    voidSyntheticTraveltimeGenerator2d::printSource(ostream& os) const{    for (int isrc=1; isrc<=src.size(); isrc++){	os << src(isrc).x() << " "	   << src(isrc).y() << '\n';    }}voidSyntheticTraveltimeGenerator2d::printSynTime(ostream& os, double vred) const{    for (int isrc=1; isrc<=src.size(); isrc++){	os << ">\n";	for (int ircv=1; ircv<=rcv(isrc).size(); ircv++){	    double redtime = syn_ttime(isrc)(ircv);	    if (vred!=0){		redtime -= abs(rcv(isrc)(ircv).x()-src(isrc).x())/vred;	    }	    if (ircv>1 &&		raytype(isrc)(ircv)!=raytype(isrc)(ircv-1)) os << ">\n";	    os << rcv(isrc)(ircv).x() << " " << redtime << '\n';	}    }}voidSyntheticTraveltimeGenerator2d::printObsTime(ostream& os, double vred) const{    for (int isrc=1; isrc<=src.size(); isrc++){	os << ">\n";	for (int ircv=1; ircv<=rcv(isrc).size(); ircv++){	    double redtime = obs_ttime(isrc)(ircv);	    if (vred!=0){		redtime -= abs(rcv(isrc)(ircv).x()-src(isrc).x())/vred;	    }	    if (ircv>1 &&		raytype(isrc)(ircv)!=raytype(isrc)(ircv-1)) os << ">\n";	    os << rcv(isrc)(ircv).x() << " " << redtime << " "	       << obs_dt(isrc)(ircv) << '\n';	}    }}void SyntheticTraveltimeGenerator2d::printDiff(ostream& os, double& misfit, double& chisq) const{    misfit = 0.0;    chisq = 0.0;    int ndata=0;    for (int isrc=1; isrc<=src.size(); isrc++){	for (int ircv=1; ircv<=rcv(isrc).size(); ircv++){	    double tdiff, tdiff2;	    tdiff = obs_ttime(isrc)(ircv)-syn_ttime(isrc)(ircv);	    tdiff2 = tdiff*tdiff;	    misfit += tdiff2;	    if (obs_dt(isrc)(ircv)==0.0){		cerr << "SyntheticTraveltimeGenerator2d::printDiff - zero error found at "		     << "isrc=" << isrc << ", ircv=" << ircv << '\n';		exit(1);	    }	    double obsdt2 = obs_dt(isrc)(ircv)*obs_dt(isrc)(ircv);	    chisq += tdiff2/obsdt2;	    os << tdiff << " " << tdiff/obs_dt(isrc)(ircv) << '\n';	    ndata++;	}    }    misfit = sqrt(misfit/ndata);    chisq = chisq/ndata;    os << "# t_misfit " << misfit << '\n';    os << "# chisq " << chisq << '\n';}ostream&operator<<(ostream& out, const SyntheticTraveltimeGenerator2d& syn){    const double syn_dt = 0.01; // assume 10 ms error        out << syn.src.size() << '\n';     for (int isrc=1; isrc<=syn.src.size(); isrc++){	out << 's' << " "	    << syn.src(isrc).x() << " "	    << syn.src(isrc).y() << " "	    << syn.rcv(isrc).size() << '\n';	for (int ircv=1; ircv<=syn.rcv(isrc).size(); ircv++){	    out << 'r' << " "		<< syn.rcv(isrc)(ircv).x() << " "		<< syn.rcv(isrc)(ircv).y() << " "		<< syn.raytype(isrc)(ircv) << " "		<< syn.syn_ttime(isrc)(ircv) << " "		<< syn_dt << '\n';	}    }}

⌨️ 快捷键说明

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