void TaskPointTest::Run() { GeoPoint gp1(Angle::degrees(fixed(20)), Angle::degrees(fixed(50))); GeoPoint gp2(Angle::degrees(fixed(21)), Angle::degrees(fixed(50))); DummyTaskPoint tp1(TaskPoint::AST, gp1, fixed(1234)); DummyTaskPoint tp2(TaskPoint::AAT, gp2, fixed(1337)); DummyTaskPoint tp3(TaskPoint::START, gp1, fixed(1234)); DummyTaskPoint tp4(TaskPoint::FINISH, gp2, fixed(1337)); ok1(tp1.IsIntermediatePoint()); ok1(tp1.GetType() == TaskPoint::AST); ok1(equals(tp1.GetBaseElevation(), 1234)); ok1(!tp1.HasTarget()); ok1(equals(tp1.Distance(gp2), gp1.distance(gp2))); ok1(equals(tp1.GetLocation(), gp1)); ok1(tp2.IsIntermediatePoint()); ok1(tp2.GetType() == TaskPoint::AAT); ok1(tp2.HasTarget()); ok1(!tp3.IsIntermediatePoint()); ok1(tp3.GetType() == TaskPoint::START); ok1(!tp3.HasTarget()); ok1(!tp4.IsIntermediatePoint()); ok1(tp4.GetType() == TaskPoint::FINISH); ok1(!tp4.HasTarget()); }
int main() { MagneticField * field = new ConstMagneticField; { // going back and forth gtp2 should be identical to gpt1.... GlobalPoint gp1(1,0,0); GlobalVector gv1(1,1,-1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); double bz = field->inTesla(gp1).z() * 2.99792458e-3; GlobalPoint np(0.504471, -0.498494, 0.497014); GlobalTrajectoryParameters gtpN = ClosestApproachInRPhi::newTrajectory(np,gtp1,bz); GlobalTrajectoryParameters gtp2 = ClosestApproachInRPhi::newTrajectory(gp1,gtpN,bz); std::cout << gtp1 << std::endl; std::cout << gtpN << std::endl; std::cout << gtp2 << std::endl; std::cout << std::endl; } { std::cout <<"opposite sign, same direction, same origin: the two circles are tangent to each other at gp1\n" << std::endl; GlobalPoint gp1(0,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); GlobalPoint gp2(0,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,-1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<" not crossing: the pcas are on the line connecting the two centers\n" <<"the momenta at the respective pcas shall be parallel as they are perpendicular to the same line\n" <<"(the one connecting the two centers)\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,-1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<"crossing (only opposite changes w.r.t. previous)\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,-1,field); compute(gtp1,gtp2); std::cout << std::endl; } { std::cout <<"crossing\n" << std::endl; GlobalPoint gp1(-1,0,0); GlobalVector gv1(1,1,1); GlobalTrajectoryParameters gtp1(gp1,gv1,-1,field); GlobalPoint gp2(1,0,0); GlobalVector gv2(-1,1,-1); GlobalTrajectoryParameters gtp2(gp2,gv2,1,field); compute(gtp1,gtp2); std::cout << std::endl; } return 0; }
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; }