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 39416 : coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* newCell =
57 39416 : new (&cells[i]) coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>(numberLinkedCellsPerCouplingCell);
58 : if (newCell == NULL) {
59 : std::cout << "ERROR coupling::datastructures::LinkedCellContainer::initLinkedCellContainer(): newCell==NULL" << std::endl;
60 : 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 24 : 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 : }
|