@@ -350,6 +350,21 @@ bool fields_chunk::needs_W_notowned(component c) {
350350 return false ;
351351}
352352
353+ /* approximate comparisons of phases to 1 or -1. exp(ix) * exp(-ix) is not exactly 1
354+ due to roundoff errors, but we want to treat it equal for the purpose of determining
355+ the boundary conditions, because we have optimized b.c.'s for phase +1 and -1, and
356+ roundoff errors on the order of 1e-13 are not significant relative to the truncation
357+ errors in meep anyway. (the alternative would be to accumulate symmetry phases more
358+ accurately by adding exponents rather than multiplying). */
359+ static bool phase_isclose (std::complex <double > thephase, double realphase) {
360+ return fabs (thephase.imag ()) < 1e-13 && fabs (thephase.real () - realphase) < 1e-13 ;
361+ }
362+ static connect_phase connect_phase_from_phase (std::complex <double > thephase) {
363+ return phase_isclose (thephase, 1.0 ) ? CONNECT_COPY
364+ : phase_isclose (thephase, -1.0 ) ? CONNECT_NEGATE
365+ : CONNECT_PHASE;
366+ }
367+
353368void fields::connect_the_chunks () {
354369 /* For some of the chunks, H==B, and we definitely don't need to
355370 send B between two such chunks. We'll still send B when
@@ -405,9 +420,7 @@ void fields::connect_the_chunks() {
405420 if ((chunks[i]->is_mine () || chunks[j]->is_mine ()) && chunks[j]->gv .owns (here) &&
406421 !(is_B (corig) && is_B (c) && B_redundant[5 * i + corig - Bx] &&
407422 B_redundant[5 * j + c - Bx])) {
408- const connect_phase ip = thephase == 1.0
409- ? CONNECT_COPY
410- : (thephase == -1.0 ? CONNECT_NEGATE : CONNECT_PHASE);
423+ const connect_phase ip = connect_phase_from_phase (thephase);
411424 comm_sizes[{type (c), ip, pair_j_to_i}] += num_reals_per_voxel;
412425
413426 if (needs_W_notowned[corig]) {
@@ -468,9 +481,8 @@ void fields::connect_the_chunks() {
468481 IVEC_LOOP_ILOC (vi, here);
469482 component c = corig;
470483 // We're looking at a border element...
471- std::complex <double > thephase_double;
472- if (locate_component_point (&c, &here, &thephase_double) && !on_metal_boundary (here)) {
473- std::complex <realnum> thephase (thephase_double.real (), thephase_double.imag ());
484+ std::complex <double > thephase;
485+ if (locate_component_point (&c, &here, &thephase) && !on_metal_boundary (here)) {
474486 for (int j = 0 ; j < num_chunks; j++) {
475487 const std::pair<int , int > pair_j_to_i{j, i};
476488 const bool i_is_mine = chunks[i]->is_mine ();
@@ -494,10 +506,7 @@ void fields::connect_the_chunks() {
494506 if (chunks[j]->gv .owns (here) &&
495507 !(is_B (corig) && is_B (c) && B_redundant[5 * i + corig - Bx] &&
496508 B_redundant[5 * j + c - Bx])) {
497- const connect_phase ip =
498- thephase == static_cast <realnum>(1.0 )
499- ? CONNECT_COPY
500- : (thephase == static_cast <realnum>(-1.0 ) ? CONNECT_NEGATE : CONNECT_PHASE);
509+ const connect_phase ip = connect_phase_from_phase (thephase);
501510 const ptrdiff_t m = chunks[j]->gv .index (c, here);
502511
503512 {
0 commit comments