// 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; }
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 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; }
// This is the function we writs the bulk of the code in void FDTD(Field &EM, int final_time, double eps, std::ofstream& output){ double loss = 0.00; double Cour = 1 / sqrt(2), ppw; int numtry = 10; Loss lass; createloss2d(lass, eps, Cour, loss); Loss1d lass1d; createloss1d(lass1d, eps, Cour, loss); // Time looping for (int q = 0; q < numtry; q++){ ppw = 5 + (1/(double)numtry) * q; for (int t = 0; t < final_time; t++){ Hupdate2d(EM, lass, t); TFSF(EM, lass, lass1d, Cour, ppw); Eupdate2d(EM,lass,t); ABCcheck(EM, lass); // Outputting to a file int check = 30000; if (t % check == 0 && t != 0){ for (size_t dx = 0; dx < spacex; dx++){ for (size_t dy = 0; dy < spacey; dy++){ output << t << '\t' << dx <<'\t' << dy << '\t' << EM.Ez(dx, dy) << '\n'; // '\t' << EM.Hy(dx, dy) // << '\t' << EM.Hx(dx, dy) << '\t' << '\n'; } } output << '\n' << '\n'; } } } }
// 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; }