Ejemplo n.º 1
0
TPZMultiphysicsInterfaceElement * TPZMultiphysicsElement::CreateInterface(int side)
{
	//  LOGPZ_INFO(logger, "Entering CreateInterface");
	TPZMultiphysicsInterfaceElement * newcreatedinterface = NULL;
	
	TPZGeoEl *ref = Reference();
	if(!ref) {
		LOGPZ_WARN(logger, "Exiting CreateInterface Null reference reached - NULL interface returned");
		return newcreatedinterface;
	}
	
	TPZCompElSide thisside(this,side);
	TPZStack<TPZCompElSide> list;
	list.Resize(0);
	thisside.EqualLevelElementList(list,0,0);//retorna distinto ao atual ou nulo
	int64_t size = list.NElements();
	//espera-se ter os elementos computacionais esquerdo e direito
	//ja criados antes de criar o elemento interface
    // try to create an interface element between myself and an equal sized neighbour
    for (int64_t is=0; is<size; is++)
    {
		//Interface has the same material of the neighbour with lesser dimension.
		//It makes the interface have the same material of boundary conditions (TPZCompElDisc with interface dimension)
		int matid;
		int thisdim = this->Dimension();
		int neighbourdim = list[is].Element()->Dimension();
        
        if(thisdim != neighbourdim)
        {
            if (thisdim < neighbourdim)
            {
                // return the material id of boundary condition IF the associated material is derived from bndcond
                TPZMaterial *mat = this->Material();
                TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat);
                if(bnd)
                {
                    matid = this->Material()->Id();
                }
                else
                {
                    matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(),list[0].Element()->Reference()->MaterialId());
                    continue;
                }
            }
			else
            {
                TPZMaterial *mat = list[is].Element()->Material();
                TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat);
                if (bnd) {
                    matid = bnd->Id();
                }
                else {
                    matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(), list[0].Element()->Reference()->MaterialId());
                    continue;
                }
            }
        }else
        {
            matid = this->Mesh()->Reference()->InterfaceMaterial(this->Reference()->MaterialId(), list[0].Element()->Reference()->MaterialId());
            if(matid == GMESHNOMATERIAL)
            {
                continue;
            }
        }
		
		int64_t index;
		
		
		TPZGeoEl *gel = ref->CreateBCGeoEl(side,matid); //isto acertou as vizinhanas da interface geometrica com o atual
		if(!gel){
			DebugStop();
#ifdef LOG4CXX
            if (logger->isDebugEnabled())
			{
				std::stringstream sout;
				sout << "CreateBCGeoEl devolveu zero!@@@@";
				LOGPZ_DEBUG(logger,sout.str());
			}
#endif
		}
        bool withmem = fMesh->ApproxSpace().NeedsMemory();
		if(Dimension() > list[is].Reference().Dimension()) {
			//o de volume eh o direito caso um deles seja BC
			//a normal aponta para fora do contorno
			TPZCompElSide thiscompelside(this, thisside.Side());
			TPZCompElSide neighcompelside(list[is]);
            if (!withmem) {
                newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,thiscompelside,neighcompelside);
            }
            else
            {
                newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,thiscompelside,neighcompelside);
            }
		} else {
			//caso contrario ou caso ambos sejam de volume
			TPZCompElSide thiscompelside(this, thisside.Side());
			TPZCompElSide neighcompelside(list[is]);
            if (!withmem) {
                newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,neighcompelside,thiscompelside);
            }
            else
            {
                newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,neighcompelside,thiscompelside);
            }
		}
		
		
		
		return newcreatedinterface;
	}
	
	//If there is no equal or lower level element, we try the lower elements.
	//Higher elements will not be considered by this method. In that case the interface must be created by the neighbour.
	TPZCompElSide lower = thisside.LowerLevelElementList(0);
	if(lower.Exists()){
		//Interface has the same material of the neighbour with lesser dimension.
		//It makes the interface has the same material of boundary conditions (TPZCompElDisc with interface dimension)
		int matid = GMESHNOMATERIAL;
		int thisdim = this->Dimension();
		int neighbourdim = lower.Element()->Dimension();
        matid = this->Mesh()->Reference()->InterfaceMaterial(this->Material()->Id(), lower.Element()->Material()->Id() );
		
		if (matid == GMESHNOMATERIAL && thisdim == neighbourdim){
			//      matid = this->Material()->Id();
            //break;
        }
        else if(matid == GMESHNOMATERIAL && thisdim != neighbourdim)
        {
			if (thisdim < neighbourdim) 
            {
                // return the material id of boundary condition IF the associated material is derived from bndcond
                TPZMaterial *mat = this->Material();
                TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat);
                if(bnd)
                {
                    matid = this->Material()->Id();
                }
                else {
                    //continue;
                }
            }
			else 
            {
                TPZMaterial *mat = lower.Element()->Material();
                TPZBndCond *bnd = dynamic_cast<TPZBndCond *>(mat);
                if (bnd) {
                    matid = bnd->Id();
                }
                else {
                    //continue;
                }
            }
		}
		
        // return zero
        if(matid == GMESHNOMATERIAL)
        {
            return newcreatedinterface;
        }
		
		TPZCompEl *lowcel = lower.Element();
		//int lowside = lower.Side();
		//existem esquerdo e direito: this e lower
		TPZGeoEl *gel = ref->CreateBCGeoEl(side,matid);
		int64_t index;
		
        bool withmem = fMesh->ApproxSpace().NeedsMemory();
        
		if(Dimension() > lowcel->Dimension()){
			//para que o elemento esquerdo seja de volume
			TPZCompElSide thiscompelside(this, thisside.Side());
			TPZCompElSide lowcelcompelside(lower);
            if (!withmem) {
                newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,thiscompelside,lowcelcompelside);
            }
            else
            {
                newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,thiscompelside,lowcelcompelside);
            }
		} else {
			TPZCompElSide thiscompelside(this, thisside.Side());
			TPZCompElSide lowcelcompelside(lower);
#ifdef LOG4CXX_KEEP
            if (logger->isDebugEnabled())
			{
				std::stringstream sout;
				sout << __PRETTY_FUNCTION__ << " left element";
				sout << lowcelcompelside << thiscompelside;
				sout << "Left Element ";
				lowcelcompelside.Element()->Print(sout);
				sout << "Right Element ";
				thiscompelside.Element()->Print(sout);
				LOGPZ_DEBUG(logger,sout.str())
			}
#endif
            if (!withmem)
            {
                newcreatedinterface = new TPZMultiphysicsInterfaceElement(*fMesh,gel,index,lowcelcompelside,thiscompelside);
            }
            else
            {
                newcreatedinterface = new TPZCompElWithMem<TPZMultiphysicsInterfaceElement>(*fMesh,gel,index,lowcelcompelside,thiscompelside);
            }
		}