@@ -241,6 +241,29 @@ class ArcaneFemFunctions
241241 return { Center_x, Center_y, 0 };
242242 }
243243
244+ /* ---------------------------------------------------------------------------*/
245+ /* *
246+ * @brief Computes the barycenter (centroid) of a tetrahedron.
247+ *
248+ * This method calculates the barycenter of a tetrahedron defined by its nodes.
249+ * The barycenter is computed as the average of the vertices' coordinates.
250+ */
251+ /* ---------------------------------------------------------------------------*/
252+
253+ static inline Real3 computeBaryCenterTetra4 (Cell cell, const VariableNodeReal3& node_coord)
254+ {
255+ Real3 vertex0 = node_coord[cell.nodeId (0 )];
256+ Real3 vertex1 = node_coord[cell.nodeId (1 )];
257+ Real3 vertex2 = node_coord[cell.nodeId (2 )];
258+ Real3 vertex3 = node_coord[cell.nodeId (3 )];
259+
260+ Real Center_x = (vertex0.x + vertex1.x + vertex2.x + vertex3.x ) / 4 .;
261+ Real Center_y = (vertex0.y + vertex1.y + vertex2.y + vertex3.x ) / 4 .;
262+ Real Center_z = (vertex0.z + vertex1.z + vertex2.z + vertex3.z ) / 4 .;
263+
264+ return { Center_x, Center_y, Center_z };
265+ }
266+
244267 /* ---------------------------------------------------------------------------*/
245268 /* *
246269 * @brief Computes the length of the edge defined by a given face.
@@ -864,6 +887,36 @@ class ArcaneFemFunctions
864887 }
865888 }
866889
890+ /* ---------------------------------------------------------------------------*/
891+ /* *
892+ * @brief Applies a manufactured source term to the RHS vector.
893+ *
894+ * This method adds a manufactured source term to the RHS vector for each
895+ * node in the mesh. The contribution to each node is weighted by the area of
896+ * the cell and evenly distributed among the nodes of the cell.
897+ *
898+ * @param [IN] qdot : The constant source term.
899+ * @param [IN] mesh : The mesh containing all cells.
900+ * @param [IN] node_dof : DOF connectivity view.
901+ * @param [IN] node_coord : The coordinates of the nodes.
902+ * @param [OUT] rhs_values : The RHS values to update.
903+ */
904+ /* ---------------------------------------------------------------------------*/
905+
906+ static inline void applyManufacturedSourceToRhs (IBinaryMathFunctor<Real, Real3, Real>* manufactured_source, IMesh* mesh, const IndexedNodeDoFConnectivityView& node_dof, const VariableNodeReal3& node_coord, VariableDoFReal& rhs_values)
907+ {
908+ ENUMERATE_ (Cell, icell, mesh->allCells ()) {
909+ Cell cell = *icell;
910+ Real volume = ArcaneFemFunctions::MeshOperation::computeVolumeTetra4 (cell, node_coord);
911+ Real3 bcenter = ArcaneFemFunctions::MeshOperation::computeBaryCenterTetra4 (cell, node_coord);
912+
913+ for (Node node : cell.nodes ()) {
914+ if (node.isOwn ())
915+ rhs_values[node_dof.dofId (node, 0 )] += manufactured_source->apply (volume / cell.nbNode (), bcenter);
916+ }
917+ }
918+ }
919+
867920 /* ---------------------------------------------------------------------------*/
868921 /* *
869922 * @brief Applies Dirichlet boundary conditions to RHS and LHS.
@@ -993,6 +1046,40 @@ class ArcaneFemFunctions
9931046 }
9941047 }
9951048 }
1049+
1050+ /* ---------------------------------------------------------------------------*/
1051+ /* *
1052+ * @brief Applies Manufactured Dirichlet boundary conditions to RHS and LHS.
1053+ *
1054+ * Updates the LHS matrix and RHS vector to enforce the Dirichlet.
1055+ *
1056+ * - For LHS matrix `A`, the diagonal term for the Dirichlet DOF is set to `P`.
1057+ * - For RHS vector `b`, the Dirichlet DOF term is scaled by `P`.
1058+ *
1059+ * @param [IN] manufactured_dirichlet : External function for Dirichlet.
1060+ * @param [IN] group : Group of all external faces.
1061+ * @param [IN] bs : Boundary condition values.
1062+ * @param [IN] node_dof : DOF connectivity view.
1063+ * @param [IN] node_coord : Node coordinates.
1064+ * @param [OUT] m_linear_system : Linear system for LHS.
1065+ * @param [OUT] rhs_values RHS : RHS values to update.
1066+ */
1067+ /* ---------------------------------------------------------------------------*/
1068+ static inline void applyManufacturedDirichletToLhsAndRhs (IBinaryMathFunctor<Real, Real3, Real>* manufactured_dirichlet, Real /* lambda*/ , const FaceGroup& group, BC::IManufacturedSolution* bs, const IndexedNodeDoFConnectivityView& node_dof, const VariableNodeReal3& node_coord, DoFLinearSystem& m_linear_system, VariableDoFReal& rhs_values)
1069+ {
1070+ Real Penalty = bs->getPenalty ();
1071+
1072+ ENUMERATE_ (Face, iface, group) {
1073+ for (Node node : iface->nodes ()) {
1074+ if (node.isOwn ()) {
1075+ m_linear_system.matrixSetValue (node_dof.dofId (node, 0 ), node_dof.dofId (node, 0 ), Penalty);
1076+ double tt = 1 .;
1077+ Real u_g = Penalty * manufactured_dirichlet->apply (tt, node_coord[node]);
1078+ rhs_values[node_dof.dofId (node, 0 )] = u_g;
1079+ }
1080+ }
1081+ }
1082+ }
9961083 };
9971084
9981085 /* ---------------------------------------------------------------------------*/
0 commit comments