<h2>Double nodes on groups boundaries</h2>
\n Double nodes on shared faces between groups of volumes and create flat elements on demand.
-\n The list of groups must describe a partition of the mesh volumes. The nodes of the internal
-faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced
+\n The list of groups must contain at least two groups. The groups have to be disjoint: no common element into two different groups.
+\n The nodes of the internal faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced
by flat elements.
\n Triangles are transformed into prisms, and quadrangles into hexahedrons.
\n The flat elements are stored in groups of volumes.
+These groups are named according to the position of the group in the list:
+the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
+If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
+All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
+The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
\n
\n This example represents an iron cable (a thin cylinder) in a concrete bloc (a big cylinder).
/*!
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
- * The list of groups must describe a partition of the mesh volumes.
- * The nodes of the internal faces at the boundaries of the groups are doubled.
- * In option, the internal faces are replaced by flat elements.
- * Triangles are transformed in prisms, and quadrangles in hexahedrons.
- * The flat elements are stored in groups of volumes.
+ * The list of groups must contain at least two groups. The groups have to be disjoint: no common element into two different groups.
+ * The nodes of the internal faces at the boundaries of the groups are doubled. Optionally, the internal faces are replaced by flat elements.
+ * Triangles are transformed into prisms, and quadrangles into hexahedrons.
+ * The flat elements are stored in groups of volumes. These groups are named according to the position of the group in the list:
+ * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
+ * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
+ * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
+ * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
* @param theElems - list of groups of volumes, where a group of volume is a set of
* SMDS_MeshElements sorted by Id.
* @param createJointElems - if TRUE, create the elements
std::set<int> emptySet;
emptyMap.clear();
+ MESSAGE(".. Number of domains :"<<theElems.size());
+
+ // Check if the domains do not share an element
+ for (int idom = 0; idom < theElems.size()-1; idom++)
+ {
+// MESSAGE("... Check of domain #" << idom);
+ const TIDSortedElemSet& domain = theElems[idom];
+ TIDSortedElemSet::const_iterator elemItr = domain.begin();
+ for (; elemItr != domain.end(); ++elemItr)
+ {
+ SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
+ int idombisdeb = idom + 1 ;
+ for (int idombis = idombisdeb; idombis < theElems.size(); idombis++) // check if the element belongs to a domain further in the list
+ {
+ const TIDSortedElemSet& domainbis = theElems[idombis];
+ if ( domainbis.count(anElem) )
+ {
+ MESSAGE(".... Domain #" << idom);
+ MESSAGE(".... Domain #" << idombis);
+ throw SALOME_Exception("The domains are not disjoint.");
+ return false ;
+ }
+ }
+ }
+ }
+
for (int idom = 0; idom < theElems.size(); idom++)
{
// and corresponding volume of this domain, for each shared face.
// a volume has a face shared by 2 domains if it has a neighbor which is not in his domain.
- //MESSAGE("Domain " << idom);
+ MESSAGE("... Neighbors of domain #" << idom);
const TIDSortedElemSet& domain = theElems[idom];
TIDSortedElemSet::const_iterator elemItr = domain.begin();
for (; elemItr != domain.end(); ++elemItr)
const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
if (! domain.count(elem)) // neighbor is in another domain : face is shared
{
- DownIdType face(downIds[n], downTypes[n]);
- if (!faceDomains.count(face))
- faceDomains[face] = emptyMap; // create an empty entry for face
- if (!faceDomains[face].count(idom))
- {
- faceDomains[face][idom] = vtkId; // volume associated to face in this domain
- celldom[vtkId] = idom;
- //MESSAGE(" cell with a border " << vtkId << " domain " << idom);
- }
+ bool ok = false ;
+ for (int idombis = 0; idombis < theElems.size(); idombis++) // check if the neighbor belongs to another domain of the list
+ {
+ // MESSAGE("Domain " << idombis);
+ const TIDSortedElemSet& domainbis = theElems[idombis];
+ if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept
+ }
+ if ( ok ) // the characteristics of the face is stored
+ {
+ DownIdType face(downIds[n], downTypes[n]);
+ if (!faceDomains.count(face))
+ faceDomains[face] = emptyMap; // create an empty entry for face
+ if (!faceDomains[face].count(idom))
+ {
+ faceDomains[face][idom] = vtkId; // volume associated to face in this domain
+ celldom[vtkId] = idom;
+ //MESSAGE(" cell with a border " << vtkId << " domain " << idom);
+ }
+ }
}
}
}
std::map<int, std::vector<int> > mutipleNodes; // nodes multi domains with domain order
std::map<int, std::vector<int> > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains)
+ MESSAGE(".. Duplication of the nodes");
for (int idomain = 0; idomain < theElems.size(); idomain++)
{
itface = faceDomains.begin();
}
}
+ MESSAGE(".. Creation of elements");
for (int idomain = 0; idomain < theElems.size(); idomain++)
{
itface = faceDomains.begin();
std::map<int, std::map<long,int> > nodeQuadDomains;
std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
+ MESSAGE(".. Creation of elements: simple junction");
if (createJointElems)
{
int idg;
// iterate on mutipleNodesToFace
// iterate on edgesMultiDomains
+ MESSAGE(".. Creation of elements: multiple junction");
if (createJointElems)
{
// --- iterate on mutipleNodesToFace
faceOrEdgeDom.clear();
feDom.clear();
+ MESSAGE(".. Modification of elements");
for (int idomain = 0; idomain < theElems.size(); idomain++)
{
std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
//================================================================================
/*!
- * \brief Double nodes on shared faces between groups of volumes and create flat
- * elements on demand.
- * The list of groups must describe a partition of the mesh volumes.
+ * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+ * The list of groups must contain at least two groups. The groups have to be disjoint:
+ * no common element into two different groups.
* The nodes of the internal faces at the boundaries of the groups are doubled.
- * In option, the internal faces are replaced by flat elements.
- * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * Optionally, the internal faces are replaced by flat elements.
+ * Triangles are transformed into prisms, and quadrangles into hexahedrons.
* The flat elements are stored in groups of volumes.
+ * These groups are named according to the position of the group in the list:
+ * the group j_n_p is the group of the flat elements that are built between the group #n and the group #p in the list.
+ * If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
+ * All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
+ * The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
* @param theDomains - list of groups of volumes
* @param createJointElems - if TRUE, create the elements
* @return TRUE if operation has been completed successfully, FALSE otherwise
SMESHDS_Mesh* aMeshDS = getMeshDS();
+ // MESSAGE("theDomains.length = "<<theDomains.length());
+ if ( theDomains.length() <= 1 )
+ THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
vector<TIDSortedElemSet> domains;
domains.clear();