void tangential_arc(const Point &p0, const Point &p1, const Point &v0, Point &c, int &dir) { geoff_geometry::Point gp0(p0.x, p0.y); geoff_geometry::Point gp1(p1.x, p1.y); geoff_geometry::Vector2d gv0(v0.x, v0.y); geoff_geometry::Point gc; geoff_geometry::tangential_arc(gp0, gp1, gv0, gc, dir); c = Point(gc.x, gc.y); }
float cal_obj_derr_illum_grad(const FwiParams ¶ms, float *derr, /* output */ float *illum, /* output */ float *g1, /* output */ const float *wlt, const float *dobs, const EnquistAbc2d &fmMethod, const ShotPosition &allSrcPos, const ShotPosition &allGeoPos) { int nt = params.nt; int nz = params.nz; int nx = params.nx; int ng = params.ng; int ns = params.ns; std::vector<float> bndr = fmMethod.initBndryVector(nt); std::vector<float> dcal(ng, 0); /* calculated/synthetic seismic data */ std::vector<float> sp0(nz * nx); /* source wavefield p0 */ std::vector<float> sp1(nz * nx); /* source wavefield p1 */ std::vector<float> sp2(nz * nx); /* source wavefield p2 */ std::vector<float> gp0(nz * nx); /* geophone/receiver wavefield p0 */ std::vector<float> gp1(nz * nx); /* geophone/receiver wavefield p1 */ std::vector<float> gp2(nz * nx); /* geophone/receiver wavefield p2 */ std::vector<float> lap(nz * nx); /* laplace of the source wavefield */ for (int is = 0; is < ns; is++) { std::fill(sp0.begin(), sp0.end(), 0); std::fill(sp1.begin(), sp1.end(), 0); ShotPosition curSrcPos = allSrcPos.clip(is); for (int it = 0; it < nt; it++) { fmMethod.addSource(&sp1[0], &wlt[it], curSrcPos); fmMethod.stepForward(&sp0[0], &sp1[0], &sp2[0]); // cycle swap cycleSwap(sp0, sp1, sp2); fmMethod.writeBndry(&bndr[0], &sp0[0], it); fmMethod.recordSeis(&dcal[0], &sp0[0], allGeoPos); cal_residuals(&dcal[0], &dobs[is * nt * ng + it * ng], &derr[is * ng * nt + it * ng], ng); } std::swap(sp0, sp1); std::fill(gp0.begin(), gp0.end(), 0); std::fill(gp1.begin(), gp1.end(), 0); for (int it = nt - 1; it > -1; it--) { /// backward propagate source wavefield fmMethod.readBndry(&bndr[0], &sp1[0], it); fmMethod.stepBackward(illum, &lap[0], &sp0[0], &sp1[0], &sp2[0]); fmMethod.subSource(&sp1[0], &wlt[it], curSrcPos); /// forward propagate geophone wavefield fmMethod.addSource(&gp1[0], &derr[is * ng * nt + it * ng], allGeoPos); fmMethod.stepForward(&gp0[0], &gp1[0], &gp2[0]); /// calculate gradient cal_gradient(&g1[0], &lap[0], &gp1[0], nz, nx); cycleSwap(sp0, sp1, sp2); cycleSwap(gp0, gp1, gp2); } } /// output: derr, g1, illum float obj = cal_objective(&derr[0], ng * nt * ns); return obj; }