Line data Source code
1 : // Copyright (C) 2015 Technische Universitaet Muenchen 2 : // This file is part of the Mamico project. For conditions of distribution 3 : // and use, please see the copyright notice in Mamico's main folder, or at 4 : // www5.in.tum.de/mamico 5 : 6 : template <class LinkedCell, unsigned int dim> 7 24 : coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::LinkedCellContainer( 8 24 : tarch::la::Vector<dim, unsigned int> numberLinkedCellsPerCouplingCell, coupling::interface::MDSolverInterface<LinkedCell, dim>* mdSolverInterface) { 9 24 : _couplingCellsWithLinkedCells = initLinkedCellContainer(numberLinkedCellsPerCouplingCell, mdSolverInterface); 10 24 : CellContainer<I02, dim>::_couplingCells = initCouplingCells(); 11 : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES) 12 : std::cout << "LinkedCellContainer of type " << I02::TNAME << " initialised..." << std::endl; 13 : #endif 14 24 : } 15 : 16 : template <class LinkedCell, unsigned int dim> 17 20 : coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::~LinkedCellContainer() { 18 : // de-init all coupling cells and then free the allocated memory (C-style array) 19 20 : if (_couplingCellsWithLinkedCells != NULL) { 20 20 : auto size = coupling::datastructures::CellContainer<I02, dim>::_couplingCells.size(); 21 19620 : for (unsigned int i = 0; i < size; i++) { 22 19600 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* cell = &_couplingCellsWithLinkedCells[i]; 23 19600 : cell->~CouplingCellWithLinkedCells(); 24 : } 25 20 : free(_couplingCellsWithLinkedCells); 26 20 : _couplingCellsWithLinkedCells = NULL; 27 : } 28 20 : } 29 : 30 : template <class LinkedCell, unsigned int dim> 31 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* 32 4 : coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::getLinkedCellContainer() { 33 4 : return _couplingCellsWithLinkedCells; 34 : } 35 : 36 : template <class LinkedCell, unsigned int dim> 37 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* 38 24 : coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::initLinkedCellContainer( 39 : tarch::la::Vector<dim, unsigned int> numberLinkedCellsPerCouplingCell, coupling::interface::MDSolverInterface<LinkedCell, dim>* mdSolverInterface) const { 40 : // determine local number of coupling cells 41 24 : unsigned int numberCouplingCells = I02::linearNumberCellsInDomain; 42 : 43 : // determine end coordinate for inner loop over linked cells (contained in each coupling cell) 44 24 : const tarch::la::Vector<3, unsigned int> endInnerLoop = coupling::initRange<dim>(numberLinkedCellsPerCouplingCell); 45 : 46 : // allocate coupling cells 47 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* cells = 48 24 : (coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>*)malloc( 49 24 : sizeof(coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>) * numberCouplingCells); 50 24 : if (cells == NULL) { 51 0 : std::cout << "ERROR coupling::datastructures::LinkedCellContainer::initCouplingCells(): cells==NULL!" << std::endl; 52 0 : exit(EXIT_FAILURE); 53 : } 54 : 55 : // call constructor on each coupling cell 56 19732 : for (unsigned int i = 0; i < numberCouplingCells; i++) { 57 : // initialise coupling cell 58 39416 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* newCell = 59 19708 : new (&cells[i]) coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>(numberLinkedCellsPerCouplingCell); 60 19708 : if (newCell == NULL) { 61 0 : std::cout << "ERROR coupling::datastructures::LinkedCellContainer::initLinkedCellContainer(): newCell==NULL" << std::endl; 62 0 : exit(EXIT_FAILURE); 63 : } 64 : } 65 : 66 8668 : for (auto idx : I10()) { 67 8644 : unsigned int item = I02{idx}.get(); 68 : 69 : #if (COUPLING_MD_ERROR == COUPLING_MD_YES) 70 8644 : if (item >= numberCouplingCells) { 71 0 : std::cout << "I02::numberCellsInDomain = " << I02::numberCellsInDomain << std::endl; 72 0 : std::cout << "I10::numberCellsInDomain = " << I10::numberCellsInDomain << std::endl; 73 0 : std::cout << "item = " << item << std::endl; 74 0 : std::cout << "numberCouplingCells = " << numberCouplingCells << std::endl; 75 0 : throw std::runtime_error(std::string("LinkedCellContainer::initLinkedCellContainer: item out of range!")); 76 : } 77 : #endif 78 : 79 : // loop over linked cells inside this coupling cell 80 8644 : unsigned int linkedCounter = 0; 81 8644 : tarch::la::Vector<3, unsigned int> linkedLoop(0); 82 25928 : for (linkedLoop[2] = 0; linkedLoop[2] < endInnerLoop[2]; linkedLoop[2]++) { 83 51848 : for (linkedLoop[1] = 0; linkedLoop[1] < endInnerLoop[1]; linkedLoop[1]++) { 84 103688 : for (linkedLoop[0] = 0; linkedLoop[0] < endInnerLoop[0]; linkedLoop[0]++) { 85 69124 : tarch::la::Vector<dim, unsigned int> linkedCellIndex = coupling::initDimVector<dim>(linkedLoop); 86 69124 : cells[item].addLinkedCell(mdSolverInterface->getLinkedCell(idx, linkedCellIndex, numberLinkedCellsPerCouplingCell), linkedCounter); 87 : 88 69124 : linkedCounter++; 89 : } 90 : } 91 : } // loop (linked cells in coupling cell) 92 : } // loop (inner coupling cells) 93 : 94 24 : return cells; 95 : } 96 : template <class LinkedCell, unsigned int dim> 97 24 : std::vector<coupling::datastructures::CouplingCell<dim>*> coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::initCouplingCells() const { 98 24 : unsigned int numberCells = I02::linearNumberCellsInDomain; 99 : // init vector with pointers to cells-with-linked-cells 100 24 : std::vector<coupling::datastructures::CouplingCell<dim>*> couplingCells; 101 19732 : for (unsigned int i = 0; i < numberCells; i++) { 102 19708 : coupling::datastructures::CouplingCell<dim>* cell = dynamic_cast<coupling::datastructures::CouplingCell<dim>*>(&_couplingCellsWithLinkedCells[i]); 103 19708 : if (cell == NULL) { 104 0 : std::cout << "ERROR coupling::datastructures::LinkedCellContainer::initCouplingCells(): dynamic_cast failed!" << std::endl; 105 0 : exit(EXIT_FAILURE); 106 : } 107 19708 : couplingCells.push_back(cell); 108 : } 109 24 : return couplingCells; 110 0 : } 111 : 112 : template <class LinkedCell, unsigned int dim> 113 : template <class A> 114 4 : void coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::applyToLocalNonGhostCouplingCellsWithLinkedCells(A& a) { 115 4 : a.beginCellIteration(); 116 1732 : for (auto idx : I10()) 117 1728 : a.apply(_couplingCellsWithLinkedCells[I02{idx}.get()], idx); 118 0 : a.endCellIteration(); 119 4 : } 120 : 121 : template <class LinkedCell, unsigned int dim> 122 : template <class A> 123 4 : void coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::applyToLocalGhostCouplingCellsWithLinkedCells(A& a) { 124 4 : a.beginCellIteration(); 125 3924 : for (auto idx : I02()) 126 3920 : if (!I10::contains(idx)) 127 2192 : a.apply(_couplingCellsWithLinkedCells[idx.get()], idx); 128 0 : a.endCellIteration(); 129 4 : } 130 : 131 : template <class LinkedCell, unsigned int dim> 132 : template <class A> 133 4 : void coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::applyToAllLocalCouplingCellsWithLinkedCells(A& a) { 134 4 : a.beginCellIteration(); 135 3924 : for (auto idx : I02()) 136 3920 : a.apply(_couplingCellsWithLinkedCells[idx.get()], idx); 137 : a.endCellIteration(); 138 4 : } 139 : 140 : template <class LinkedCell, unsigned int dim> 141 : template <class A> 142 4 : void coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::applyToFirstLayerOfGlobalNonGhostCellsWithLinkedCells(A& a) { 143 4 : a.beginCellIteration(); 144 1732 : for (auto idx : I10()) { 145 : // get global coordinate of local cell 146 8640 : auto globalCoord = (tarch::la::Vector<dim, unsigned>)I01{idx}.get(); 147 1728 : bool isBoundary = false; 148 6912 : for (unsigned int d = 0; d < dim; d++) { 149 5548 : isBoundary = isBoundary || (globalCoord[d] == 1) || (globalCoord[d] == I09::numberCellsInDomain[d]); 150 : } 151 1728 : if (isBoundary) 152 728 : a.apply(_couplingCellsWithLinkedCells[I02{idx}.get()], idx); 153 : } 154 0 : a.endCellIteration(); 155 4 : } 156 : 157 : template <class LinkedCell, unsigned int dim> 158 : template <class A> 159 24 : void coupling::datastructures::LinkedCellContainer<LinkedCell, dim>::applyXLayersOfGlobalNonGhostCellsWithLinkedCells(A& a, unsigned int layers2Use) { 160 : // global coordinate of first non-ghost cell 161 48 : const tarch::la::Vector<dim, unsigned int> globalLowerLeftCorner(1 + layers2Use); 162 : // global coordinate of last non-ghost cell 163 24 : const tarch::la::Vector<dim, unsigned int> globalUpperRightCorner(I09::numberCellsInDomain - tarch::la::Vector<dim, unsigned int>(layers2Use)); 164 24 : a.beginCellIteration(); 165 10416 : for (auto idx : I10()) { 166 : // get global coordinate of local cell 167 51840 : auto globalCoord = (tarch::la::Vector<dim, unsigned>)I01{idx}.get(); 168 10368 : bool isBoundary = false; 169 41472 : for (unsigned int d = 0; d < dim; d++) { 170 35388 : isBoundary = isBoundary || (globalCoord[d] < globalLowerLeftCorner[d]) || (globalCoord[d] > globalUpperRightCorner[d]); 171 : } 172 10368 : if (isBoundary) 173 8568 : a.apply(_couplingCellsWithLinkedCells[I02{idx}.get()], idx); 174 : } 175 0 : a.endCellIteration(); 176 24 : }