@@ -58,39 +58,57 @@ TranslationalPeriodicBC::TranslationalPeriodicBC(int i_surf, int j_surf)
5858 // The following blocks will resolve the type of each surface and compute the
5959 // appropriate translation vector
6060
61- // Check for a pair of x-planes
62- if (const auto * xplane1 = dynamic_cast <const SurfaceXPlane*>(&surf1)) {
63- if (const auto * xplane2 = dynamic_cast <const SurfaceXPlane*>(&surf2)) {
64- translation_ = {xplane2->x0_ - xplane1->x0_ , 0 , 0 };
65- } else {
66- throw std::invalid_argument (fmt::format (" Invalid pair of periodic "
67- " surfaces ({} and {}). For a translational periodic BC, both surfaces "
68- " must be of the same type (e.g. both x-plane)." , surf1.id_ , surf2.id_ ));
69- }
61+ // Make sure the first surface has an appropriate type.
62+ if (const auto * ptr = dynamic_cast <const SurfaceXPlane*>(&surf1)) {
63+ } else if (const auto * ptr = dynamic_cast <const SurfaceYPlane*>(&surf1)) {
64+ } else if (const auto * ptr = dynamic_cast <const SurfaceZPlane*>(&surf1)) {
65+ } else if (const auto * ptr = dynamic_cast <const SurfacePlane*>(&surf1)) {
66+ } else {
67+ throw std::invalid_argument (fmt::format (" Surface {} is an invalid type for "
68+ " translational periodic BCs. Only planes are supported for these BCs." ,
69+ surf1.id_ ));
70+ }
7071
71- // Check for a pair of y-planes
72- } else if (const auto * yplane1 = dynamic_cast <const SurfaceYPlane*>(&surf1)) {
73- if (const auto * yplane2 = dynamic_cast <const SurfaceYPlane*>(&surf2)) {
74- translation_ = {0 , yplane2->y0_ - yplane1->y0_ , 0 };
75- } else {
76- throw std::invalid_argument (fmt::format (" Invalid pair of periodic "
77- " surfaces ({} and {}). For a translational periodic BC, both surfaces "
78- " must be of the same type (e.g. both x-plane)." , surf1.id_ , surf2.id_ ));
79- }
72+ // Make sure the second surface has an appropriate type.
73+ if (const auto * ptr = dynamic_cast <const SurfaceXPlane*>(&surf2)) {
74+ } else if (const auto * ptr = dynamic_cast <const SurfaceYPlane*>(&surf2)) {
75+ } else if (const auto * ptr = dynamic_cast <const SurfaceZPlane*>(&surf2)) {
76+ } else if (const auto * ptr = dynamic_cast <const SurfacePlane*>(&surf2)) {
77+ } else {
78+ throw std::invalid_argument (fmt::format (" Surface {} is an invalid type for "
79+ " translational periodic BCs. Only planes are supported for these BCs." ,
80+ surf2.id_ ));
81+ }
8082
81- // Check for a pair of z-planes
82- } else if (const auto * zplane1 = dynamic_cast <const SurfaceZPlane*>(&surf1)) {
83- if (const auto * zplane2 = dynamic_cast <const SurfaceZPlane*>(&surf2)) {
84- translation_ = {0 , 0 , zplane2->z0_ - zplane1->z0_ };
85- } else {
86- throw std::invalid_argument (fmt::format (" Invalid pair of periodic "
87- " surfaces ({} and {}). For a translational periodic BC, both surfaces "
88- " must be of the same type (e.g. both x-plane)." , surf1.id_ , surf2.id_ ));
89- }
83+ // Compute the distance from the first surface to the origin. Check the
84+ // surface evaluate function to decide if the distance is positive, negative,
85+ // or zero.
86+ Position origin {0 , 0 , 0 };
87+ Direction u = surf1.normal (origin);
88+ double d1;
89+ double e1 = surf1.evaluate (origin);
90+ if (e1 > FP_COINCIDENT ) {
91+ d1 = -surf1.distance (origin, -u, false );
92+ } else if (e1 < -FP_COINCIDENT ) {
93+ d1 = surf1.distance (origin, u, false );
94+ } else {
95+ d1 = 0.0 ;
9096 }
9197
92- // TODO: Check for a pair of general planes
98+ // Compute the distance from the second surface to the origin.
99+ double d2;
100+ double e2 = surf2.evaluate (origin);
101+ if (e2 > FP_COINCIDENT ) {
102+ d2 = -surf2.distance (origin, -u, false );
103+ } else if (e2 < -FP_COINCIDENT ) {
104+ d2 = surf2.distance (origin, u, false );
105+ } else {
106+ d2 = 0.0 ;
107+ }
93108
109+ // Set the translation vector; it's length is the difference in the two
110+ // distances.
111+ translation_ = u * (d2 - d1);
94112}
95113
96114void
0 commit comments