void Eupdate2d(Field &EM, Loss &lass, int t){ // update electric field #pragma omp parallel for for (size_t dx = 1; dx < spacex - 1; dx++){ for (size_t dy = 1; dy < spacey - 1; dy++){ EM.Ez(dx,dy) = lass.EzE(dx,dy) * EM.Ez(dx,dy) + lass.EzH(dx,dy) * ((EM.Hy(dx, dy) - EM.Hy(dx - 1, dy)) - (EM.Hx(dx,dy) - EM.Hx(dx, dy - 1))); } } //return EM; }
// 2 dimensional functions for E / H movement Field Hupdate2d(Field EM, Loss lass, int t){ // update magnetic field, x direction for (size_t dx = 0; dx < spacex - 1; dx++){ for (size_t dy = 0; dy < spacey - 1; dy++){ EM.Hz(dx,dy) = lass.HzH(dx,dy) * EM.Hz(dx, dy) + lass.HzE(dx,dy) * ((EM.Ex(dx, dy + 1) - EM.Ex(dx, dy)) - (EM.Ey(dx + 1,dy) - EM.Ey(dx, dy))); } } return EM; }
Field Eupdate2d(Field EM, Loss lass, int t){ // update electric field for (size_t dx = 0; dx < spacex - 1; dx++){ for (size_t dy = 1; dy < spacey - 1; dy++){ EM.Ex(dx,dy) = lass.ExE(dx,dy) * EM.Ex(dx,dy) + lass.ExH(dx,dy) * (EM.Hz(dx, dy) - EM.Hz(dx, dy - 1)); } } for (size_t dx = 1; dx < spacex - 1; dx++){ for (size_t dy = 0; dy < spacey - 1; dy++){ EM.Ey(dx,dy) = lass.EyE(dx,dy) * EM.Ey(dx,dy) - lass.EyH(dx,dy) * (EM.Hz(dx, dy) - EM.Hz(dx - 1, dy)); } } return EM; }
// TFSF boundaries void TFSF(Field &EM, Loss &lass, Loss1d &lass1d, double Cour, double ppw){ int dx, dy, loc = 0; // TFSF boundary Bound first, last; first.x = 10; last.x = 1990; first.y = 10; last.y = 1490; // Update along right edge! dx = last.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Hy(dx,dy) += lass.HyE(dx, dy) * EM.Ez1d[dx]; } // Updating along left edge dx = first.x - 1; for (int dy = first.y; dy <= last.y; dy++){ EM.Hy(dx,dy) -= lass.HyE(dx, dy) * EM.Ez1d[dx+1]; } // Updating along top dy = last.y; for (int dx = first.x; dx <= last.x; dx++){ EM.Hx(dx,dy) -= lass.HxE(dx, dy) * EM.Ez1d[dx]; } // Update along bot dy = first.y - 1; for (int dx = first.x; dx <= last.x; dx++){ EM.Hx(dx,dy) += lass.HxE(dx, dy) * EM.Ez1d[dx]; } // Insert 1d grid stuff here. Update magnetic and electric field Hupdate1d(EM, lass1d, EM.t); Eupdate1d(EM, lass1d, EM.t); //EM.Ez1d[10] = ricker(EM.t,0, Cour); EM.Ez1d[10] = planewave(EM.t, loc, Cour, ppw); EM.t++; std::cout << EM.t << '\n'; // Check mag instead of ricker. // Update along right dx = last.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Ez(dx, dy) += lass.EzH(dx, dy) * EM.Hy1d[dx]; } // Updating Ez along left dx = first.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Ez(dx, dy) -= lass.EzH(dx, dy) * EM.Hy1d[dx - 1]; } //return EM; }
// TFSF boundaries Field TFSF(Field EM, Loss lass, Loss1d lass1d, double Cour){ int dx, dy; // TFSF boundary Bound first, last; first.x = 10; last.x = 390; first.y = 10; last.y = 190; // Update along right dx = last.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Hz(dx, dy) -= lass.HzE(dx, dy) * EM.Ey1d[dx]; } // Updating Hz along left dx = first.x - 1; for (int dy = first.y; dy <= last.y; dy++){ EM.Hz(dx, dy) += lass.HzE(dx, dy) * EM.Ey1d[dx + 1]; } // Insert 1d grid stuff here. Update magnetic and electric field Hupdate1d(EM, lass1d, EM.t); Eupdate1d(EM, lass1d, EM.t); //EM.Ey1d[10] = ricker(EM.t,0, Cour); EM.Ey1d[10] = planewave(EM.t, 15, Cour, 30, 40); EM.t++; std::cout << EM.t << '\n'; // Check mag instead of ricker. // Update along right edge! dx = last.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Ey(dx,dy) -= lass.EyH(dx, dy) * EM.Hz1d[dx]; } // Updating along left edge dx = first.x; for (int dy = first.y; dy <= last.y; dy++){ EM.Ey(dx,dy) += lass.EyH(dx, dy) * EM.Hz1d[dx-1]; } // Updating along top dy = last.y; for (int dx = first.x; dx <= last.x; dx++){ EM.Ex(dx,dy) += lass.ExH(dx, dy) * EM.Hz1d[dx]; } // Update along bot dy = first.y; for (int dx = first.x; dx <= last.x; dx++){ EM.Ex(dx,dy) -= lass.ExH(dx, dy) * EM.Hz1d[dx]; } return EM; }
// 2 dimensional functions for E / H movement void Hupdate2d(Field &EM, Loss &lass, int t){ // update magnetic field, x direction #pragma omp parallel for for (size_t dx = 0; dx < spacex; dx++){ for (size_t dy = 0; dy < spacey - 1; dy++){ EM.Hx(dx,dy) = lass.HxH(dx,dy) * EM.Hx(dx, dy) - lass.HxE(dx,dy) * (EM.Ez(dx,dy + 1) - EM.Ez(dx,dy)); } } // update magnetic field, y direction #pragma omp parallel for for (size_t dx = 0; dx < spacex - 1; dx++){ for (size_t dy = 0; dy < spacey; dy++){ EM.Hy(dx,dy) = lass.HyH(dx,dy) * EM.Hy(dx,dy) + lass.HyE(dx,dy) * (EM.Ez(dx + 1,dy) - EM.Ez(dx,dy)); } } //return EM; }
int main(int argc, char** argv) { try { util::ProgramOptions::init(argc, argv); logger::LogManager::init(); Hdf5CragStore cragStore(optionProjectFile.as<std::string>()); Hdf5VolumeStore volumeStore(optionProjectFile.as<std::string>()); Crag crag; cragStore.retrieveCrag(crag); NodeFeatures nodeFeatures(crag); EdgeFeatures edgeFeatures(crag); LOG_USER(logger::out) << "reading features" << std::endl; cragStore.retrieveNodeFeatures(crag, nodeFeatures); cragStore.retrieveEdgeFeatures(crag, edgeFeatures); BundleOptimizer::Parameters parameters; parameters.lambda = optionRegularizerWeight; parameters.epsStrategy = BundleOptimizer::EpsFromGap; BundleOptimizer optimizer(parameters); BestEffort* bestEffort = 0; OverlapLoss* overlapLoss = 0; if (optionBestEffortFromProjectFile) { LOG_USER(logger::out) << "reading best-effort" << std::endl; bestEffort = new BestEffort(crag); vigra::HDF5File project( optionProjectFile.as<std::string>(), vigra::HDF5File::OpenMode::ReadWrite); project.cd("best_effort"); vigra::ArrayVector<int> beNodes; vigra::MultiArray<2, int> beEdges; project.readAndResize("nodes", beNodes); project.readAndResize("edges", beEdges); std::set<int> nodes; for (int n : beNodes) nodes.insert(n); std::set<std::pair<int, int>> edges; for (int i = 0; i < beEdges.shape(1); i++) edges.insert( std::make_pair( std::min(beEdges(i, 0), beEdges(i, 1)), std::max(beEdges(i, 0), beEdges(i, 1)))); for (Crag::NodeIt n(crag); n != lemon::INVALID; ++n) bestEffort->node[n] = nodes.count(crag.id(n)); for (Crag::EdgeIt e(crag); e != lemon::INVALID; ++e) bestEffort->edge[e] = edges.count( std::make_pair( std::min(crag.id(crag.u(e)), crag.id(crag.v(e))), std::max(crag.id(crag.u(e)), crag.id(crag.v(e))))); } else { LOG_USER(logger::out) << "reading ground-truth" << std::endl; ExplicitVolume<int> groundTruth; volumeStore.retrieveGroundTruth(groundTruth); LOG_USER(logger::out) << "finding best-effort solution" << std::endl; overlapLoss = new OverlapLoss(crag, groundTruth); bestEffort = new BestEffort(crag, *overlapLoss); } Loss* loss = 0; bool destructLoss = false; if (optionLoss.as<std::string>() == "hamming") { LOG_USER(logger::out) << "using Hamming loss" << std::endl; loss = new HammingLoss(crag, *bestEffort); destructLoss = true; } else if (optionLoss.as<std::string>() == "overlap") { LOG_USER(logger::out) << "using overlap loss" << std::endl; if (!overlapLoss) { LOG_USER(logger::out) << "reading ground-truth" << std::endl; ExplicitVolume<int> groundTruth; volumeStore.retrieveGroundTruth(groundTruth); LOG_USER(logger::out) << "finding best-effort solution" << std::endl; overlapLoss = new OverlapLoss(crag, groundTruth); } loss = overlapLoss; } else { LOG_ERROR(logger::out) << "unknown loss: " << optionLoss.as<std::string>() << std::endl; return 1; } if (optionNormalizeLoss) { LOG_USER(logger::out) << "normalizing loss..." << std::endl; loss->normalize(crag, MultiCut::Parameters()); } Oracle oracle( crag, nodeFeatures, edgeFeatures, *loss, *bestEffort); std::vector<double> weights(nodeFeatures.dims() + edgeFeatures.dims(), 0); optimizer.optimize(oracle, weights); storeVector(weights, optionFeatureWeights); if (destructLoss && loss != 0) delete loss; if (overlapLoss) delete overlapLoss; if (bestEffort) delete bestEffort; } catch (boost::exception& e) { handleException(e, std::cerr); } }
// This is the function we writs the bulk of the code in void FDTD(Field EM, const int final_time, const double eps, const int space, Loss lass, std::ofstream& output){ // For magnetic field: // double offset = 0.00005; // for electric field: double offset = 0.05; double loss = 0.0; double Cour = 1.0 / sqrt(2.0); // Relative permittivity for (int dx = 0; dx < space; dx++){ for (int dy = 0; dy < space; dy++){ if (dx > 100 && dx < 150){ lass.EzH(dx, dy) = Cour * eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = Cour / eps; lass.HxE(dx, dy) = Cour / eps; lass.HxH(dx, dy) = 1.0; /* lass.EzH(dx, dy) = eps / 9.0 /(1.0 - loss); lass.EzE(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyH(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyE(dx, dy) = (1.0 / eps) / (1.0 + loss); lass.HxE(dx, dy) = (1.0 / eps) / (1.0 + loss); lass.HxH(dx, dy) = (1.0 - loss) / (1.0 + loss); */ } else{ lass.EzH(dx, dy) = Cour * eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = Cour / eps; lass.HxE(dx, dy) = Cour / eps; lass.HxH(dx, dy) = 1.0; /* lass.EzH(dx, dy) = eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = (1.0 / eps); lass.HxE(dx, dy) = (1.0 / eps); lass.HxH(dx, dy) = 1.0; */ } } } // Time looping for (int t = 0; t < final_time; t++){ // Linking the final two elements for an ABC for (int da = 0; da < space; da++){ EM.Hy(da,space - 1) = EM.Hy(da,space - 2); EM.Hx(space - 1,da) = EM.Hx(space - 2,da); } // update magnetic field, y direction for (int dx = 0; dx < space - 1; dx++){ for (int dy = 0; dy < space; dy++){ EM.Hy(dx,dy) = lass.HyH(dx,dy) * EM.Hy(dx,dy) + lass.HyE(dx,dy) * (EM.Ez(dx + 1,dy) - EM.Ez(dx,dy)); } } // update magnetic field, x direction for (int dx = 0; dx < space; dx++){ for (int dy = 0; dy < space - 1; dy++){ EM.Hx(dx,dy) = lass.HxH(dx,dy) * EM.Hx(dx, dy) + lass.HxE(dx,dy) * (EM.Ez(dx,dy + 1) - EM.Ez(dx,dy)); } } // Correction to the H field for the TFSF boundary // Hy[49] -= exp(-(t - 40.) * (t - 40.)/100.0) / eps; // Hy[49] -= sin((t-10.0)*0.2)*0.0005; // Linking the first two elements in the electric field for (int dy = 0; dy < space; dy++){ EM.Ez(0,dy) = EM.Ez(1,dy); EM.Ez(space - 1,dy) = EM.Ez(space - 2,dy); } // update electric field for (int dx = 1; dx < space - 1; dx++){ for (int dy = 1; dy < space - 1; dy++){ EM.Ez(dx,dy) = lass.EzE(dx,dy) * EM.Ez(dx,dy) + lass.EzH[dx] * (EM.Hy(dx, dy) - EM.Hy(dx - 1, dy) - EM.Hx(dx,dy) - EM.Hx(dx, dy - 1)); } } // set src for next step for (int dy = 0; dy < space; dy++){ EM.Ez(50,dy) += exp(-((t + 1 - 40.) * (t + 1 - 40.))/100.0); } // EM.Ez[0] = 0; // Ez[50] += sin((t - 10.0 + 1)*0.2)*0.0005; /* if (t > 0){ Ez[50] = sin(0.1 * t) / (0.1 * t); } else{ Ez[50] = 1; } */ if (t % 50 == 0){ for (int dx = 0; dx < space; dx = dx + 50){ for (int dy = 0; dy < space; dy = dy + 50){ output << t << '\t' << dx <<'\t' << dy << '\t' << EM.Ez(dx, dy) << '\n'; //output << Ez(dx,dy) + (t * offset) << '\n'; //output << Hy[dx] + (t * offset) << '\n'; } } output << '\n' << '\n'; } } }
// Checking Absorbing Boundary Conditions (ABC) void ABCcheck(Field &EM, Loss &lass){ // defining constant for ABC double c1, c2, c3, temp1, temp2; temp1 = sqrt(lass.EzH(0,0) * lass.HyE(0,0)); temp2 = 1.0 / temp1 + 2.0 + temp1; c1 = -(1.0 / temp1 - 2.0 + temp1) / temp2; c2 = -2.0 * (temp1 - 1.0 / temp1) / temp2; c3 = 4.0 * (temp1 + 1.0 / temp1) / temp2; size_t dx, dy; // Setting ABC for top for (dx = 0; dx < spacex; dx++){ EM.Ez(dx, spacey - 1) = c1 * (EM.Ez(dx, spacey - 3) + EM.Etop(0, 1, dx)) + c2 * (EM.Etop(0, 0, dx) + EM.Etop(2, 0 , dx) -EM.Ez(dx,spacey - 2) -EM.Etop(1, 1, dx)) + c3 * EM.Etop(1, 0, dx) - EM.Etop(2, 1, dx); // memorizing fields... for (dy = 0; dy < 3; dy++){ EM.Etop(dy, 1, dx) = EM.Etop(dy, 0, dx); EM.Etop(dy, 0, dx) = EM.Ez(dx, spacey - 1 - dy); } } // Setting ABC for bottom for (dx = 0; dx < spacex; dx++){ EM.Ez(dx,0) = c1 * (EM.Ez(dx, 2) + EM.Ebot(0, 1, dx)) + c2 * (EM.Ebot(0, 0, dx) + EM.Ebot(2, 0 , dx) -EM.Ez(dx,1) -EM.Ebot(1, 1, dx)) + c3 * EM.Ebot(1, 0, dx) - EM.Ebot(2, 1, dx); // memorizing fields... for (dy = 0; dy < 3; dy++){ EM.Ebot(dy, 1, dx) = EM.Ebot(dy, 0, dx); EM.Ebot(dy, 0, dx) = EM.Ez(dx, dy); } } // ABC on right for (dy = 0; dy < spacey; dy++){ EM.Ez(spacex - 1,dy) = c1 * (EM.Ez(spacex - 3,dy) + EM.Eright(0, 1, dy)) + c2 * (EM.Eright(0, 0, dy) + EM.Eright(2, 0 , dy) -EM.Ez(spacex - 2,dy) -EM.Eright(1, 1, dy)) + c3 * EM.Eright(1, 0, dy) - EM.Eright(2, 1, dy); // memorizing fields... for (dx = 0; dx < 3; dx++){ EM.Eright(dx, 1, dy) = EM.Eright(dx, 0, dy); EM.Eright(dx, 0, dy) = EM.Ez(spacex - 1 - dx, dy); } } // Setting ABC for left side of grid. Woo! for (dy = 0; dy < spacey; dy++){ EM.Ez(0,dy) = c1 * (EM.Ez(2,dy) + EM.Eleft(0, 1, dy)) + c2 * (EM.Eleft(0, 0, dy) + EM.Eleft(2, 0 , dy) -EM.Ez(1,dy) -EM.Eleft(1, 1, dy)) + c3 * EM.Eleft(1, 0, dy) - EM.Eleft(2, 1, dy); // memorizing fields... for (dx = 0; dx < 3; dx++){ EM.Eleft(dx, 1, dy) = EM.Eleft(dx, 0, dy); EM.Eleft(dx, 0, dy) = EM.Ez(dx, dy); } } // return EM; }
// Creating loss void createloss2d(Loss &lass, double eps, double Cour, double loss){ double radius = 400; int sourcex = 450, sourcex2 = 250; int sourcey = 750, sourcey2 = 100; double dist, var, Q, epsp, mup, dist2, var_old; double cutoff = 1.5; for (size_t dx = 0; dx < spacex; dx++){ for (size_t dy = 0; dy < spacey; dy++){ dist = sqrt((dx - sourcex)*(dx - sourcex) + (dy - sourcey)*(dy - sourcey)); dist2 = sqrt((dx - sourcex2)*(dx - sourcex2) + (dy - sourcey2)*(dy - sourcey2)); // if (dx > 100 && dx < 150 && dy > 75 && dy < 125){ if (dist < radius){ // if (dist > 100000000){ Q = cbrt(-(radius / dist) + sqrt((radius/dist) * (radius/dist) + (1.0/27.0))); var = (Q - (1.0 / (3.0 * Q))) * (Q - (1.0 / (3.0 * Q))); // var = radius / dist; // var = 1.1; if (abs(var - var_old) > cutoff){ var = var_old; } if (var > 10){ var = 10; } if (isnan(var)){ var = var_old; } epsp = eps / (var * var); mup = 1 / (var * var); /* lass.EzH(dx, dy) = Cour * eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = Cour / eps; lass.HxE(dx, dy) = Cour / eps; lass.HxH(dx, dy) = 1.0; */ lass.EzH(dx, dy) = Cour * epsp /(1.0 - loss); lass.EzE(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyH(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyE(dx, dy) = Cour * (mup / eps) / (1.0 + loss); lass.HxE(dx, dy) = Cour * (mup / eps) / (1.0 + loss); lass.HxH(dx, dy) = (1.0 - loss) / (1.0 + loss); /* // PEC stuff lass.EzH(dx, dy) = 0; lass.EzE(dx, dy) = 0; lass.HyH(dx, dy) = 0; lass.HyE(dx, dy) = 0; lass.HxE(dx, dy) = 0; lass.HxH(dx, dy) = 0; */ var_old = var; } else{ /* lass.EzH(dx, dy) = Cour * eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = Cour / eps; lass.HxE(dx, dy) = Cour / eps; lass.HxH(dx, dy) = 1.0; lass.EzH(dx, dy) = Cour * eps /(1.0 - loss); lass.EzE(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyH(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.HyE(dx, dy) = Cour * (1.0 / eps) / (1.0 + loss); lass.HxE(dx, dy) = Cour * (1.0 / eps) / (1.0 + loss); lass.HxH(dx, dy) = (1.0 - loss) / (1.0 + loss); */ lass.EzH(dx, dy) = Cour * eps; lass.EzE(dx, dy) = 1.0; lass.HyH(dx, dy) = 1.0; lass.HyE(dx, dy) = Cour * (1.0 / eps); lass.HxE(dx, dy) = Cour * (1.0 / eps); lass.HxH(dx, dy) = 1.0; } } } //return lass; }
// Creating loss Loss createloss2d(Loss lass, double eps, double Cour, double loss){ double radius = 40; int sourcex = 200, sourcex2 = 100; int sourcey = 100, sourcey2 = 100; double dist, var, Q, epsp, mup, dist2; for (size_t dx = 0; dx < spacex; dx++){ for (size_t dy = 0; dy < spacey; dy++){ dist = sqrt((dx - sourcex)*(dx - sourcex) + (dy - sourcey)*(dy - sourcey)); dist2 = sqrt((dx - sourcex2)*(dx - sourcex2) + (dy - sourcey2)*(dy - sourcey2)); // if (dx > 100 && dx < 150 && dy > 75 && dy < 125){ if (dist < radius){ Q = cbrt(-(radius / dist) + sqrt((radius/dist) * (radius/dist) + (1.0/27.0))); var = (Q - (1.0 / (3.0 * Q))) * (Q - (1.0/ (3.0 * Q))); // var = 1.4; if (abs(var) > 1000){ var = 1000; } if (isnan(var)){ var = 1000; } epsp = eps / (var * var); mup = 1 / (var * var); lass.ExH(dx, dy) = Cour * epsp /(1.0 - loss); lass.ExE(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.EyE(dx, dy) = (1.0 - loss) / (1.0 + loss); lass.EyH(dx, dy) = Cour * epsp / (1.0 + loss); lass.HzE(dx, dy) = Cour * (mup / eps) / (1.0 + loss); lass.HzH(dx, dy) = (1.0 - loss) / (1.0 + loss); /* // PEC stuff -- not complete! lass.ExH(dx, dy) = 0; lass.ExE(dx, dy) = 0; lass.HzH(dx, dy) = 0; lass.HzE(dx, dy) = 0; lass.ExE(dx, dy) = 0; lass.ExH(dx, dy) = 0; */ } else{ lass.ExH(dx, dy) = Cour * eps; lass.ExE(dx, dy) = 1.0; lass.EyE(dx, dy) = 1.0; lass.EyH(dx, dy) = Cour * eps; lass.HzE(dx, dy) = Cour / eps; lass.HzH(dx, dy) = 1.0; } } } return lass; }