18 #include "libmesh/mesh.h" 19 #include "libmesh/elem.h" 20 #include "libmesh/node.h" 21 #include "libmesh/petsc_macro.h" 22 #include "petscblaslapack.h" 26 unsigned int n_qpoints,
28 :
XFEMCutElem(elem, n_qpoints, n_sides), _efa_elem2d(CEMelem, true)
38 Point node_coor(0.0, 0.0, 0.0);
39 std::vector<EFANode *> master_nodes;
40 std::vector<Point> master_points;
41 std::vector<double> master_weights;
44 for (
unsigned int i = 0; i < master_nodes.size(); ++i)
48 Node * node =
_nodes[master_nodes[i]->id()];
50 node = displaced_mesh->node_ptr(node->id());
51 Point node_p((*node)(0), (*node)(1), 0.0);
52 master_points.push_back(node_p);
57 for (
unsigned int i = 0; i < master_nodes.size(); ++i)
58 node_coor += master_weights[i] * master_points[i];
74 frag_vol += 0.5 * (edge_p1(0) - edge_p2(0)) * (edge_p1(1) + edge_p2(1));
92 if (
edge->containsNode(node_1) &&
edge->containsNode(node_2))
96 frag_surf = (edge_p1 - edge_p2).
norm();
108 std::vector<Point> elem_nodes(
_n_nodes, Point(0.0, 0.0, 0.0));
109 std::vector<std::vector<Real>> wsg;
111 for (
unsigned int i = 0; i <
_n_nodes; ++i)
112 elem_nodes[i] = (*
_nodes[i]);
116 std::vector<std::vector<Real>> tsg;
121 for (
unsigned int i = 0; i < wsg.size(); ++i)
131 Point orig(0.0, 0.0, 0.0);
132 std::vector<std::vector<EFANode *>> cut_line_nodes;
137 std::vector<EFANode *> node_line(2,
nullptr);
140 cut_line_nodes.push_back(node_line);
143 if (cut_line_nodes.size() == 0)
144 mooseError(
"no cut line found in this element");
145 if (plane_id < cut_line_nodes.size())
153 Point normal(0.0, 0.0, 0.0);
154 std::vector<std::vector<EFANode *>> cut_line_nodes;
159 std::vector<EFANode *> node_line(2,
nullptr);
162 cut_line_nodes.push_back(node_line);
165 if (cut_line_nodes.size() == 0)
166 mooseError(
"no cut line found in this element");
167 if (plane_id < cut_line_nodes.size())
171 Point cut_line = cut_line_p2 - cut_line_p1;
172 Real len = std::sqrt(cut_line.norm_sq());
174 normal = Point(cut_line(1), -cut_line(0), 0.0);
182 Point & direction)
const 185 std::vector<EFANode *> cut_line_nodes;
190 std::vector<EFANode *> node_line(2,
nullptr);
193 if (node_line[1]->
id() == tip_id)
195 cut_line_nodes.push_back(node_line[0]);
196 cut_line_nodes.push_back(node_line[1]);
198 else if (node_line[0]->
id() == tip_id)
200 node_line[1] = node_line[0];
202 cut_line_nodes.push_back(node_line[0]);
203 cut_line_nodes.push_back(node_line[1]);
207 if (cut_line_nodes.size() == 0)
208 mooseError(
"no cut line found in this element");
212 Point cut_line = cut_line_p2 - cut_line_p1;
213 Real len = std::sqrt(cut_line.norm_sq());
215 origin = cut_line_p2;
216 direction = Point(cut_line(0), cut_line(1), 0.0);
221 MeshBase * displaced_mesh)
const 226 std::vector<Point> edge_points(2, Point(0.0, 0.0, 0.0));
231 frag_faces.push_back(edge_points);
244 unsigned int counter = 0;
256 unsigned int nnd_pe = frag->
numEdges();
257 std::vector<Point> frag_points(nnd_pe, Point(0.0, 0.0, 0.0));
260 for (
unsigned int j = 0;
j < nnd_pe; ++
j)
264 Point xcrd(0.0, 0.0, 0.0);
265 for (
unsigned int j = 0;
j < nnd_pe; ++
j)
266 xcrd += frag_points[
j];
267 xcrd *= (1.0 / nnd_pe);
270 if ((nnd_pe == 3) || (nnd_pe == 4))
272 std::vector<std::vector<Real>> sg2;
273 std::vector<std::vector<Real>> shape(nnd_pe, std::vector<Real>(3, 0.0));
275 for (
unsigned int l = 0; l < sg2.size(); ++l)
278 std::vector<Real> tsg_line(3, 0.0);
279 for (
unsigned int k = 0;
k < nnd_pe; ++
k)
281 tsg_line[0] += shape[
k][2] * frag_points[
k](0);
282 tsg_line[1] += shape[
k][2] * frag_points[
k](1);
285 tsg_line[2] = sg2[l][3] * jac;
287 tsg_line[2] = sg2[l][2] * jac;
288 tsg.push_back(tsg_line);
291 else if (nnd_pe >= 5)
293 for (
unsigned int j = 0;
j < nnd_pe; ++
j)
295 std::vector<std::vector<Real>> shape(3, std::vector<Real>(3, 0.0));
296 std::vector<Point> subtri_points(3, Point(0.0, 0.0, 0.0));
298 int jplus1 =
j < nnd_pe - 1 ?
j + 1 : 0;
299 subtri_points[0] = xcrd;
300 subtri_points[1] = frag_points[
j];
301 subtri_points[2] = frag_points[jplus1];
303 std::vector<std::vector<Real>> sg2;
305 for (
unsigned int l = 0; l < sg2.size(); ++l)
308 std::vector<Real> tsg_line(3, 0.0);
309 for (
unsigned int k = 0;
k < 3; ++
k)
311 tsg_line[0] += shape[
k][2] * subtri_points[
k](0);
312 tsg_line[1] += shape[
k][2] * subtri_points[
k](1);
314 tsg_line[2] = sg2[l][3] * jac;
315 tsg.push_back(tsg_line);
326 std::vector<Point> & elem_nodes,
327 std::vector<std::vector<Real>> & tsg,
328 std::vector<std::vector<Real>> & wsg)
331 std::vector<std::vector<Real>> shape(nen, std::vector<Real>(3, 0.0));
332 std::vector<std::vector<Real>> wss;
337 for (
unsigned int i = 0; i <
_qp_points.size(); i++)
348 for (
unsigned int i = 0; i <
_qp_points.size(); i++)
360 wsg.resize(wss.size());
361 for (
unsigned int i = 0; i < wsg.size(); ++i)
362 wsg[i].resize(3, 0.0);
364 std::vector<Real> old_weights(wss.size(), 0.0);
366 for (
unsigned int l = 0; l < wsg.size(); ++l)
370 old_weights[l] = wss[l][2] * jac;
372 old_weights[l] = wss[l][3] * jac;
375 for (
unsigned int k = 0;
k < nen; ++
k)
377 wsg[l][0] += shape[
k][2] * elem_nodes[
k](0);
378 wsg[l][1] += shape[
k][2] * elem_nodes[
k](1);
384 A =
new Real[wsg.size() * wsg.size()];
386 for (
unsigned int i = 0; i < wsg.size(); ++i)
390 A[1 + ind] = wsg[i][0];
392 A[2 + ind] = wsg[i][1];
394 A[3 + ind] = wsg[i][0] * wsg[i][1];
396 A[4 + ind] = wsg[i][0] * wsg[i][0];
398 A[5 + ind] = wsg[i][1] * wsg[i][1];
400 mooseError(
"Q-points of more than 6 are not allowed now!");
405 b =
new Real[wsg.size()];
406 for (
unsigned int i = 0; i < wsg.size(); ++i)
408 for (
unsigned int i = 0; i < tsg.size(); ++i)
412 b[1] += tsg[i][2] * tsg[i][0];
414 b[2] += tsg[i][2] * tsg[i][1];
416 b[3] += tsg[i][2] * tsg[i][0] * tsg[i][1];
418 b[4] += tsg[i][2] * tsg[i][0] * tsg[i][0];
420 b[5] += tsg[i][2] * tsg[i][1] * tsg[i][1];
422 mooseError(
"Q-points of more than 6 are not allowed now!");
425 PetscBLASInt nrhs = 1;
427 PetscBLASInt n = wsg.size();
428 std::vector<PetscBLASInt> ipiv(n);
430 LAPACKgesv_(&n, &nrhs,
A, &n, &ipiv[0],
b, &n, &
info);
432 for (
unsigned int i = 0; i < wsg.size(); ++i)
433 wsg[i][2] =
b[i] / old_weights[i];
443 std::vector<Point> & intersectionPoints,
444 MeshBase * displaced_mesh)
const 446 intersectionPoints.resize(2);
449 std::vector<std::vector<EFANode *>> cut_line_nodes;
454 std::vector<EFANode *> node_line(2,
nullptr);
457 cut_line_nodes.push_back(node_line);
460 if (cut_line_nodes.size() == 0)
461 mooseError(
"No cut line found in this element");
463 if (plane_id < cut_line_nodes.size())
465 intersectionPoints[0] =
getNodeCoordinates(cut_line_nodes[plane_id][0], displaced_mesh);
466 intersectionPoints[1] =
getNodeCoordinates(cut_line_nodes[plane_id][1], displaced_mesh);
std::vector< Real > _elem_side_area
void shapeFunc2D(unsigned int nen, std::vector< Real > &ss, std::vector< Point > &xl, std::vector< std::vector< Real >> &shp, Real &xsj, bool natl_flg)
virtual void computeMomentFittingWeights()
void mooseError(Args &&... args)
std::vector< Point > _qp_points
unsigned int numEdges() const
EFAEdge * getEdge(unsigned int edge_id) const
bool isEdgeInterior(unsigned int edge_id) const
XFEMCutElem2D(Elem *elem, const EFAElement2D *const CEMelem, unsigned int n_qpoints, unsigned int n_sides)
Constructor initializes XFEMCutElem2D object.
virtual Point getNodeCoordinates(EFANode *node, MeshBase *displaced_mesh=nullptr) const
virtual unsigned int numCutPlanes() const
EFAFragment2D * getFragment(unsigned int frag_id) const
void solveMomentFitting(unsigned int nen, unsigned int nqp, std::vector< Point > &elem_nodes, std::vector< std::vector< Real >> &tsg, std::vector< std::vector< Real >> &wsg)
virtual Point getCutPlaneNormal(unsigned int plane_id, MeshBase *displaced_mesh=nullptr) const
virtual const EFAElement * getEFAElement() const
std::vector< Real > _qp_weights
virtual void getFragmentFaces(std::vector< std::vector< Point >> &frag_faces, MeshBase *displaced_mesh=nullptr) const
virtual void computePhysicalVolumeFraction()
Computes the volume fraction of the element fragment.
std::vector< Real > _new_weights
quadrature weights from volume fraction and moment fitting
virtual void getCrackTipOriginAndDirection(unsigned tip_id, Point &origin, Point &direction) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void stdQuadr2D(unsigned int nen, unsigned int iord, std::vector< std::vector< Real >> &sg2)
void getPhysicalQuadraturePoints(std::vector< std::vector< Real >> &tsg)
std::vector< Node * > _nodes
virtual bool isPartial() const
virtual void getMasterInfo(EFANode *node, std::vector< EFANode *> &master_nodes, std::vector< double > &master_weights) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
EFAEdge * getEdge(unsigned int edge_id) const
std::vector< Real > _physical_areafrac
EFANode * getNode(unsigned int index) const
static const std::string k
virtual Point getCutPlaneOrigin(unsigned int plane_id, MeshBase *displaced_mesh=nullptr) const
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
virtual void getIntersectionInfo(unsigned int plane_id, Point &normal, std::vector< Point > &intersectionPoints, MeshBase *displaced_mesh=nullptr) const
virtual void computePhysicalFaceAreaFraction(unsigned int side)
Computes the surface area fraction of the element side.