@@ -67,18 +67,20 @@ void HCurlFETransformation<OutputShape>::map_phi(const unsigned int dim,
6767 {
6868 const std ::vector < Real > & dxidx_map = fe .get_fe_map ().get_dxidx ();
6969 const std ::vector < Real > & dxidy_map = fe .get_fe_map ().get_dxidy ();
70+ const std ::vector < Real > & dxidz_map = fe .get_fe_map ().get_dxidz ();
7071
7172 const std ::vector < Real > & detadx_map = fe .get_fe_map ().get_detadx ();
7273 const std ::vector < Real > & detady_map = fe .get_fe_map ().get_detady ();
74+ const std ::vector < Real > & detadz_map = fe .get_fe_map ().get_detadz ();
7375
74- // FIXME: Need to update for 2D elements in 3D space
7576 // phi = (dx/dxi)^-T * \hat{phi}
76- // In 2D:
77- // (dx/dxi)^{-1} = [ dxi/dx dxi/dy
78- // deta/dx deta/dy ]
77+ // In 2D (embedded in 3D) :
78+ // (dx/dxi)^{-1} = [ dxi/dx dxi/dy dxi/dz
79+ // deta/dx deta/dy deta/dz ]
7980 //
80- // so: dxi/dx^{-T} * \hat{phi} = [ dxi/dx deta/dx [ \hat{phi}_xi
81- // dxi/dy deta/dy ] \hat{phi}_eta ]
81+ // so: dxi/dx^{-T} * \hat{phi} = [ dxi/dx deta/dx [ \hat{phi}_xi
82+ // dxi/dy deta/dy \hat{phi}_eta ]
83+ // dxi/dz deta/dz ]
8284 //
8385 // or in indicial notation: phi_j = xi_{i,j}*\hat{phi}_i
8486 for (auto i : index_range (phi ))
@@ -95,6 +97,8 @@ void HCurlFETransformation<OutputShape>::map_phi(const unsigned int dim,
9597 phi [i ][p ](0 ) = dxidx_map [p ]* phi_ref .slice (0 ) + detadx_map [p ]* phi_ref .slice (1 );
9698
9799 phi [i ][p ](1 ) = dxidy_map [p ]* phi_ref .slice (0 ) + detady_map [p ]* phi_ref .slice (1 );
100+
101+ phi [i ][p ](2 ) = dxidz_map [p ]* phi_ref .slice (0 ) + detadz_map [p ]* phi_ref .slice (1 );
98102 }
99103
100104 break ;
@@ -168,18 +172,27 @@ void HCurlFETransformation<OutputShape>::map_curl(const unsigned int dim,
168172
169173 case 2 :
170174 {
175+ const std ::vector < Real > & dxidx_map = fe .get_fe_map ().get_dxidx ();
176+ const std ::vector < Real > & dxidy_map = fe .get_fe_map ().get_dxidy ();
177+ const std ::vector < Real > & dxidz_map = fe .get_fe_map ().get_dxidz ();
178+
179+ const std ::vector < Real > & detadx_map = fe .get_fe_map ().get_detadx ();
180+ const std ::vector < Real > & detady_map = fe .get_fe_map ().get_detady ();
181+ const std ::vector < Real > & detadz_map = fe .get_fe_map ().get_detadz ();
182+
171183 const std ::vector < std ::vector < OutputShape >> & dphi_dxi = fe .get_dphidxi ();
172184 const std ::vector < std ::vector < OutputShape >> & dphi_deta = fe .get_dphideta ();
173185
174- const std ::vector < Real > & J = fe .get_fe_map ().get_jacobian ();
175-
176- // FIXME: I don't think this is valid for 2D elements in 3D space
177- // In 2D: curl(phi) = J^{-1} * curl(\hat{phi})
186+ // In 2D (embedded in 3D): curl(phi)_j = C(j) * curl(\hat{phi}) where C(j)
187+ // is the jth column cofactor of (dx/dxi)^{-1} = [ dxi/dx dxi/dy dxi/dz
188+ // deta/dx deta/dy deta/dz ]
178189 for (auto i : index_range (curl_phi ))
179190 for (auto p : index_range (curl_phi [i ]))
180191 {
181- curl_phi [i ][p ].slice (0 ) = curl_phi [i ][p ].slice (1 ) = 0.0 ;
182- curl_phi [i ][p ].slice (2 ) = ( dphi_dxi [i ][p ].slice (1 ) - dphi_deta [i ][p ].slice (0 ) )/J [p ];
192+ const Real curl_ref = dphi_dxi [i ][p ].slice (1 ) - dphi_deta [i ][p ].slice (0 );
193+ curl_phi [i ][p ].slice (0 ) = curl_ref * (dxidy_map [p ]* detadz_map [p ] - dxidz_map [p ]* detady_map [p ]);
194+ curl_phi [i ][p ].slice (1 ) = curl_ref * - (dxidx_map [p ]* detadz_map [p ] - dxidz_map [p ]* detadx_map [p ]);
195+ curl_phi [i ][p ].slice (2 ) = curl_ref * (dxidx_map [p ]* detady_map [p ] - dxidy_map [p ]* detadx_map [p ]);
183196 }
184197
185198 break ;
0 commit comments