#define RCSID "$Id: ExtendedGroup.c,v 1.14 2006/02/26 00:42:54 geuzaine Exp $" /* * Copyright (C) 1997-2006 P. Dular, C. Geuzaine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to . */ #include "GetDP.h" #include "ExtendedGroup.h" #include "Data_DefineE.h" #include "CurrentData.h" #include "GeoData.h" #include "Tools.h" int fcmp_int2(const void * a, const void * b) { static int result ; if ( ( result = ((struct TwoInt *)a)->Int1 - ((struct TwoInt *)b)->Int1 ) != 0 ) return result ; return ((struct TwoInt *)a)->Int2 - ((struct TwoInt *)b)->Int2 ; } int fcmp_absint2(const void * a, const void * b) { static int result ; if ( ( result = abs(((struct TwoInt *)a)->Int1) - abs(((struct TwoInt *)b)->Int1) ) != 0 ) return result ; return abs(((struct TwoInt *)a)->Int2) - abs(((struct TwoInt *)b)->Int2) ; } /* ------------------------------------------------------------------------ */ /* C h e c k _ I s E n t i t y I n E x t e n d e d G r o u p */ /* ------------------------------------------------------------------------ */ int Check_IsEntityInExtendedGroup(struct Group * Group_P, int Entity, int Flag) { GetDP_Begin("Check_IsEntityInExtendedGroup"); switch (Group_P->FunctionType) { case NODESOF : case EDGESOF : case FACETSOF : case VOLUMESOF : if ((Group_P->InitialList && !Group_P->ExtendedList) || (Group_P->InitialSuppList && !Group_P->ExtendedSuppList)) Generate_ExtendedGroup(Group_P) ; GetDP_Return((!Group_P->InitialList || (List_Search(Group_P->ExtendedList, &Entity, fcmp_int))) && (!Group_P->InitialSuppList || (! List_Search(Group_P->ExtendedSuppList, &Entity, fcmp_int)))) ; case ELEMENTSOF : case EDGESOFTREEIN : case FACETSOFTREEIN : if (!Group_P->ExtendedList) Generate_ExtendedGroup(Group_P) ; GetDP_Return( List_Search(Group_P->ExtendedList, &Entity, fcmp_int) ) ; case GROUPSOFNODESOF : case GROUPSOFEDGESOF : case REGION : case GLOBAL : GetDP_Return( (Flag)? List_Search(Group_P->InitialList, &Entity, fcmp_int) : 1 ) ; case GROUPSOFEDGESONNODESOF : if (!Group_P->InitialSuppList){ GetDP_Return(1) ; } GetDP_Return (! List_Search(Group_P->ExtendedSuppList, &Entity, fcmp_int)) ; default : Msg(GERROR, "Unknown function type for Group '%s'", Group_P->Name); GetDP_Return(-1) ; } } /* ------------------------------------------------------------------------ */ /* G e n e r a t e _ E x t e n d e d G r o u p */ /* ------------------------------------------------------------------------ */ void Generate_ExtendedGroup(struct Group * Group_P) { GetDP_Begin("Generate_ExtendedGroup"); Msg(INFO, " Generate ExtendedGroup '%s' (%s)", Group_P->Name, Get_StringForDefine(FunctionForGroup_Type, Group_P->FunctionType)) ; switch (Group_P->FunctionType) { case NODESOF : case EDGESOF : case FACETSOF : case VOLUMESOF : Generate_ElementaryEntities(Group_P->InitialList, &Group_P->ExtendedList, Group_P->FunctionType) ; Generate_ElementaryEntities(Group_P->InitialSuppList, &Group_P->ExtendedSuppList, Group_P->FunctionType) ; break ; case GROUPSOFEDGESONNODESOF : Generate_ElementaryEntities(Group_P->InitialList, &Group_P->ExtendedList, EDGESOF) ; Generate_ElementaryEntities(Group_P->InitialSuppList, &Group_P->ExtendedSuppList, NODESOF) ; break ; case GROUPSOFNODESOF : Generate_GroupsOfNodes(Group_P->InitialList, &Group_P->ExtendedList) ; break ; case ELEMENTSOF : Generate_Elements(Group_P->InitialList, Group_P->SuppListType, Group_P->InitialSuppList, &Group_P->ExtendedList) ; break ; case GROUPSOFEDGESOF : Generate_GroupsOfEdges(Group_P->InitialList, Group_P->SuppListType, Group_P->InitialSuppList, &Group_P->ExtendedList) ; break ; case EDGESOFTREEIN : Geo_GenerateEdgesOfTree(Group_P->InitialList, Group_P->InitialSuppList, &Group_P->ExtendedList) ; Geo_AddGroupForPRE(Group_P->Num) ; break ; case FACETSOFTREEIN : Geo_GenerateFacetsOfTree(Group_P->InitialList, Group_P->InitialSuppList, &Group_P->ExtendedList) ; Geo_AddGroupForPRE(Group_P->Num) ; break ; default : Msg(GERROR, "Unknown function type for Group '%s'", Group_P->Name) ; break; } GetDP_End ; } /* ------------------------------------------------------------------------ */ /* G e n e r a t e _ E l e m e n t a r y E n t i t i e s */ /* ------------------------------------------------------------------------ */ void Generate_ElementaryEntities (List_T * InitialList, List_T ** ExtendedList, int Type_Entity) { Tree_T * Entity_Tr ; struct Geo_Element * GeoElement ; int Nbr_Element, i_Element, Num_Entity ; int Nbr_Entity = 0, i_Entity, * Num_Entities = NULL; GetDP_Begin("Generate_ElementaryEntities"); if (InitialList != NULL) { Entity_Tr = Tree_Create(sizeof (int), fcmp_int) ; Nbr_Element = Geo_GetNbrGeoElements() ; for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialList, &GeoElement->Region, fcmp_int) ) { switch (Type_Entity) { case NODESOF : Nbr_Entity = GeoElement->NbrNodes ; Num_Entities = GeoElement->NumNodes ; break ; case EDGESOF : if (GeoElement->NbrEdges == 0) Geo_CreateEdgesOfElement(GeoElement) ; Nbr_Entity = GeoElement->NbrEdges ; Num_Entities = GeoElement->NumEdges ; break ; case FACETSOF : if (GeoElement->NbrEdges == 0) Geo_CreateEdgesOfElement(GeoElement) ; if (GeoElement->NbrFacets == 0) Geo_CreateFacetsOfElement(GeoElement) ; Nbr_Entity = GeoElement->NbrFacets ; Num_Entities = GeoElement->NumFacets ; break ; case VOLUMESOF : Nbr_Entity = 1 ; Num_Entities = &GeoElement->Num ; break ; } for (i_Entity = 0; i_Entity < Nbr_Entity ; i_Entity++) { Num_Entity = abs(Num_Entities[i_Entity]) ; if ( ! Tree_Search(Entity_Tr, &Num_Entity) ) Tree_Add(Entity_Tr, &Num_Entity) ; } } } *ExtendedList = Tree2List(Entity_Tr) ; Tree_Delete(Entity_Tr) ; } GetDP_End ; } /* ------------------------------------------------------------------------ */ /* G e n e r a t e _ G r o u p s O f N o d e s */ /* ------------------------------------------------------------------------ */ void Generate_GroupsOfNodes(List_T * InitialList, List_T ** ExtendedList) { Tree_T * Entity_Tr ; struct Geo_Element * GeoElement ; int Nbr_Element, i_Element, i_Entity ; struct TwoInt Num_GroupOfNodes ; GetDP_Begin("Generate_GroupsOfNodes"); Entity_Tr = Tree_Create(sizeof (struct TwoInt), fcmp_int2) ; Nbr_Element = Geo_GetNbrGeoElements() ; /* Msg(INFO, " Add Node :"); */ for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialList, &GeoElement->Region, fcmp_int) ) { Num_GroupOfNodes.Int2 = GeoElement->Region ; for (i_Entity = 0 ; i_Entity < GeoElement->NbrNodes ; i_Entity++) { Num_GroupOfNodes.Int1 = GeoElement->NumNodes[i_Entity] ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfNodes) ) { Tree_Add(Entity_Tr, &Num_GroupOfNodes) ; /* Msg(INFO, " (%d, %d)", Num_GroupOfNodes.Int1, Num_GroupOfNodes.Int2); */ } } } } *ExtendedList = Tree2List(Entity_Tr) ; Tree_Delete(Entity_Tr) ; GetDP_End ; } /* ------------------------------------------------------------------------ */ /* G e n e r a t e _ G r o u p s O f E d g e s */ /* ------------------------------------------------------------------------ */ void Generate_GroupsOfEdges(List_T * InitialList, int Type_SuppList, List_T * InitialSuppList, List_T ** ExtendedList) { Tree_T * Entity_Tr ; struct Geo_Element * GeoElement ; int Nbr_Element, i_Element, i_Entity, Num_Element ; int * Num_Nodes, Num_Node ; struct TwoInt Num_GroupOfEdges, * Key1_P, * Key2_P ; List_T * ExtendedAuxList ; struct Group * GroupForSupport_P ; GetDP_Begin("Generate_GroupsOfEdges"); Entity_Tr = Tree_Create(sizeof (struct TwoInt), fcmp_absint2) ; switch (Type_SuppList) { case SUPPLIST_INSUPPORT : if (List_Nbr(InitialList)) { Generate_GroupsOfNodes(InitialList, &ExtendedAuxList) ; /* Attention : ici, le Support est une liste d'elements ! */ GroupForSupport_P = (struct Group*) List_Pointer(Problem_S.Group, *((int *)List_Pointer(InitialSuppList, 0))) ; if (!GroupForSupport_P->ExtendedList) Generate_ExtendedGroup(GroupForSupport_P) ; Nbr_Element = List_Nbr(GroupForSupport_P->ExtendedList) ; for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { List_Read(GroupForSupport_P->ExtendedList, i_Element, &Num_Element) ; GeoElement = Geo_GetGeoElementOfNum(Num_Element) ; if (GeoElement->NbrEdges == 0) Geo_CreateEdgesOfElement(GeoElement) ; for (i_Entity = 0 ; i_Entity < GeoElement->NbrEdges ; i_Entity++) { Num_Nodes = Geo_GetNodesOfEdgeInElement(GeoElement, i_Entity) ; Num_Node = GeoElement->NumNodes[abs(Num_Nodes[0])-1] ; Key1_P = (struct TwoInt*)List_PQuery(ExtendedAuxList, &Num_Node, fcmp_int) ; Num_Node = GeoElement->NumNodes[abs(Num_Nodes[1])-1] ; Key2_P = (struct TwoInt*)List_PQuery(ExtendedAuxList, &Num_Node, fcmp_int) ; if (Key1_P && (!Key2_P || (Key2_P->Int2 != Key1_P->Int2))) { Num_GroupOfEdges.Int1 = - GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key1_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; } if (Key2_P && (!Key1_P || (Key1_P->Int2 != Key2_P->Int2))) { Num_GroupOfEdges.Int1 = GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key2_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; } /* if (Key1_P && !Key2_P) { Num_GroupOfEdges.Int1 = - GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key1_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; } else if (Key2_P && !Key1_P) { Num_GroupOfEdges.Int1 = GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key2_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; } else { if (Key1_P && Key2_P && Key1_P->Int2 != Key2_P->Int2) { Num_GroupOfEdges.Int1 = - GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key1_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) { Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; fprintf(stderr, "ADD 1 <========= %d %d %d\n", GeoElement->NumNodes[abs(Num_Nodes[0])-1], Num_GroupOfEdges.Int1, Num_GroupOfEdges.Int2); } Num_GroupOfEdges.Int1 = GeoElement->NumEdges[i_Entity] ; Num_GroupOfEdges.Int2 = Key2_P->Int2 ; if ( ! Tree_Search(Entity_Tr, &Num_GroupOfEdges) ) { Tree_Add(Entity_Tr, &Num_GroupOfEdges) ; fprintf(stderr, "ADD 2 <========= %d %d %d \n", GeoElement->NumNodes[abs(Num_Nodes[1])-1], Num_GroupOfEdges.Int1, Num_GroupOfEdges.Int2); } } } */ } } List_Delete(ExtendedAuxList) ; } break ; default : Msg(GERROR, "Bad GroupsOfEdges (supplementary list missing)") ; } *ExtendedList = Tree2List(Entity_Tr) ; Tree_Delete(Entity_Tr) ; /* for (i_Entity = 0 ; i_Entity < List_Nbr(*ExtendedList) ; i_Entity++) { List_Read(*ExtendedList, i_Entity, &Num_GroupOfEdges) ; Msg(INFO, " (%d, %d)", Num_GroupOfEdges.Int1, Num_GroupOfEdges.Int2) ; } */ GetDP_End ; } /* ------------------------------------------------------------------------ */ /* G e n e r a t e _ E l e m e n t s */ /* ------------------------------------------------------------------------ */ void Generate_Elements(List_T * InitialList, int Type_SuppList, List_T * InitialSuppList, List_T ** ExtendedList) { Tree_T * Entity_Tr ; struct Geo_Element * GeoElement, * GeoElement2 ; struct TwoInt Pair ; int k ; int Nbr_Element, i_Element, i_Element2, Nbr_Node, i_Node, i_Node2 ; List_T * ExtendedSuppList ; GetDP_Begin("Generate_Elements"); Nbr_Element = Geo_GetNbrGeoElements() ; switch (Type_SuppList) { case SUPPLIST_ONONESIDEOF : Entity_Tr = Tree_Create(sizeof(int), fcmp_int) ; if (List_Nbr(InitialSuppList)) { Generate_GroupsOfNodes(InitialSuppList, &ExtendedSuppList) ; for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialList, &GeoElement->Region, fcmp_int)) { Nbr_Node = GeoElement->NbrNodes ; for (i_Node = 0 ; i_Node < Nbr_Node ; i_Node++) if (List_Search(ExtendedSuppList, &(GeoElement->NumNodes[i_Node]), fcmp_int)) { Tree_Add(Entity_Tr, &GeoElement->Num) ; break ; /* at least one node of element is on surface Supp */ } } } /* + ne conserver que certains des elements qui viennent d'etre groupes ... ! */ List_Delete(ExtendedSuppList) ; } break ; case SUPPLIST_CONNECTEDTO : Entity_Tr = Tree_Create(sizeof(struct TwoInt), fcmp_int2) ; ExtendedSuppList = List_Create(100,100,sizeof(int)); for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialSuppList, &GeoElement->Region, fcmp_int)) List_Add(ExtendedSuppList, &i_Element); } for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialList, &GeoElement->Region, fcmp_int)){ for(i_Element2 = 0 ; i_Element2 < List_Nbr(ExtendedSuppList) ; i_Element2++){ GeoElement2 = Geo_GetGeoElement(*(int*)List_Pointer(ExtendedSuppList, i_Element2)) ; k = 0 ; for(i_Node2 = 0 ; i_Node2 < GeoElement2->NbrNodes ; i_Node2++){ for(i_Node = 0 ; i_Node < GeoElement->NbrNodes ; i_Node++){ if(GeoElement2->NumNodes[i_Node2] == GeoElement->NumNodes[i_Node]) k++; } } if(k == GeoElement2->NbrNodes){ Pair.Int1 = GeoElement2->Num ; /* Number of the the element on the boundary */ Pair.Int2 = i_Element ; /* Index of the element connected to all the nodes of the element on the boundary */ Tree_Add(Entity_Tr, &Pair); } } } } List_Delete(ExtendedSuppList) ; break ; case SUPPLIST_NONE : default : Entity_Tr = Tree_Create(sizeof(int), fcmp_int) ; for (i_Element = 0 ; i_Element < Nbr_Element ; i_Element++) { GeoElement = Geo_GetGeoElement(i_Element) ; if (List_Search(InitialList, &GeoElement->Region, fcmp_int)) Tree_Add(Entity_Tr, &GeoElement->Num) ; } break ; } *ExtendedList = Tree2List(Entity_Tr) ; Tree_Delete(Entity_Tr) ; GetDP_End ; }