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