/[escript]/branches/trilinos_from_5897/dudley/src/NodeFile.cpp
ViewVC logotype

Contents of /branches/trilinos_from_5897/dudley/src/NodeFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6079 - (show annotations)
Mon Mar 21 12:22:38 2016 UTC (2 years, 11 months ago) by caltinay
File size: 6630 byte(s)
Big commit - making dudley much more like finley to make it more
managable. Fixed quite a few issues that had been fixed in finley.
Disposed of all ReducedNode/ReducedDOF entities that dudley never supported.
Compiles and passes tests.

1
2 /*****************************************************************************
3 *
4 * Copyright (c) 2003-2016 by The University of Queensland
5 * http://www.uq.edu.au
6 *
7 * Primary Business: Queensland, Australia
8 * Licensed under the Open Software License version 3.0
9 * http://www.opensource.org/licenses/osl-3.0.php
10 *
11 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 * Development 2012-2013 by School of Earth Sciences
13 * Development from 2014 by Centre for Geoscience Computing (GeoComp)
14 *
15 *****************************************************************************/
16
17 #include "NodeFile.h"
18
19 namespace dudley {
20
21 static std::pair<index_t,index_t> getGlobalRange(dim_t n, const index_t* id,
22 escript::JMPI mpiInfo)
23 {
24 std::pair<index_t,index_t> result(util::getMinMaxInt(1, n, id));
25
26 #ifdef ESYS_MPI
27 index_t global_id_range[2];
28 index_t id_range[2] = { -result.first, result.second };
29 MPI_Allreduce(id_range, global_id_range, 2, MPI_DIM_T, MPI_MAX,
30 mpiInfo->comm);
31 result.first = -global_id_range[0];
32 result.second = global_id_range[1];
33 #endif
34 if (result.second < result.first) {
35 result.first = -1;
36 result.second = 0;
37 }
38 return result;
39 }
40
41 NodeFile::NodeFile(int nDim, escript::JMPI mpiInfo) :
42 numNodes(0),
43 MPIInfo(mpiInfo),
44 numDim(nDim),
45 Id(NULL),
46 Tag(NULL),
47 globalDegreesOfFreedom(NULL),
48 Coordinates(NULL),
49 globalNodesIndex(NULL),
50 degreesOfFreedomId(NULL),
51 status(DUDLEY_INITIAL_STATUS)
52 {
53 }
54
55 NodeFile::~NodeFile()
56 {
57 freeTable();
58 }
59
60 void NodeFile::allocTable(dim_t NN)
61 {
62 if (numNodes > 0)
63 freeTable();
64
65 Id = new index_t[NN];
66 Coordinates = new escript::DataTypes::real_t[NN*numDim];
67 Tag = new int[NN];
68 globalDegreesOfFreedom = new index_t[NN];
69 globalNodesIndex = new index_t[NN];
70 degreesOfFreedomId = new index_t[NN];
71 numNodes = NN;
72
73 // this initialization makes sure that data are located on the right
74 // processor
75 #pragma omp parallel for
76 for (index_t n=0; n<numNodes; n++) {
77 Id[n] = -1;
78 for (int i=0; i<numDim; i++)
79 Coordinates[INDEX2(i,n,numDim)] = 0.;
80 Tag[n] = -1;
81 globalDegreesOfFreedom[n] = -1;
82 globalNodesIndex[n] = -1;
83 degreesOfFreedomId[n] = -1;
84 }
85 }
86
87 void NodeFile::freeTable()
88 {
89 delete[] Id;
90 delete[] Coordinates;
91 delete[] globalDegreesOfFreedom;
92 delete[] globalNodesIndex;
93 delete[] Tag;
94 delete[] degreesOfFreedomId;
95 nodesMapping.clear();
96 degreesOfFreedomMapping.clear();
97 nodesDistribution.reset();
98 dofDistribution.reset();
99 degreesOfFreedomConnector.reset();
100 numNodes = 0;
101 }
102
103 void NodeFile::copyTable(index_t offset, index_t idOffset, index_t dofOffset,
104 const NodeFile* in)
105 {
106 // check number of dimensions and table size
107 if (numDim != in->numDim)
108 throw escript::ValueError("NodeFile::copyTable: dimensions of node files don't match");
109
110 if (numNodes < in->numNodes + offset)
111 throw escript::ValueError("NodeFile::copyTable: node table is too small.");
112
113 #pragma omp parallel for
114 for (index_t n = 0; n < in->numNodes; n++) {
115 Id[offset + n] = in->Id[n] + idOffset;
116 Tag[offset + n] = in->Tag[n];
117 globalDegreesOfFreedom[offset + n] = in->globalDegreesOfFreedom[n] + dofOffset;
118 for (int i = 0; i < numDim; i++)
119 Coordinates[INDEX2(i, offset + n, numDim)] =
120 in->Coordinates[INDEX2(i, n, in->numDim)];
121 }
122 }
123
124 std::pair<index_t,index_t> NodeFile::getDOFRange() const
125 {
126 std::pair<index_t,index_t> result(util::getMinMaxInt(
127 1, numNodes, globalDegreesOfFreedom));
128 if (result.second < result.first) {
129 result.first = -1;
130 result.second = 0;
131 }
132 return result;
133 }
134
135 std::pair<index_t,index_t> NodeFile::getGlobalIdRange() const
136 {
137 return getGlobalRange(numNodes, Id, MPIInfo);
138 }
139
140 std::pair<index_t,index_t> NodeFile::getGlobalDOFRange() const
141 {
142 return getGlobalRange(numNodes, globalDegreesOfFreedom, MPIInfo);
143 }
144
145 std::pair<index_t,index_t> NodeFile::getGlobalNodeIDIndexRange() const
146 {
147 return getGlobalRange(numNodes, globalNodesIndex, MPIInfo);
148 }
149
150 void NodeFile::setCoordinates(const escript::Data& newX)
151 {
152 if (newX.getDataPointSize() != numDim) {
153 std::stringstream ss;
154 ss << "NodeFile::setCoordinates: number of dimensions of new "
155 "coordinates has to be " << numDim;
156 throw escript::ValueError(ss.str());
157 } else if (newX.getNumDataPointsPerSample() != 1 ||
158 newX.getNumSamples() != numNodes) {
159 std::stringstream ss;
160 ss << "NodeFile::setCoordinates: number of given nodes must be "
161 << numNodes;
162 throw escript::ValueError(ss.str());
163 } else {
164 const size_t numDim_size = numDim * sizeof(double);
165 ++status;
166 #pragma omp parallel for
167 for (index_t n = 0; n < numNodes; n++) {
168 memcpy(&Coordinates[INDEX2(0, n, numDim)],
169 newX.getSampleDataRO(n), numDim_size);
170 }
171 }
172 }
173
174 void NodeFile::setTags(int newTag, const escript::Data& mask)
175 {
176 if (1 != mask.getDataPointSize()) {
177 throw escript::ValueError("NodeFile::setTags: number of components of mask must be 1.");
178 } else if (mask.getNumDataPointsPerSample() != 1 ||
179 mask.getNumSamples() != numNodes) {
180 throw escript::ValueError("NodeFile::setTags: illegal number of samples of mask Data object");
181 }
182
183 #pragma omp parallel for
184 for (index_t n = 0; n < numNodes; n++) {
185 if (mask.getSampleDataRO(n)[0] > 0)
186 Tag[n] = newTag;
187 }
188 updateTagList();
189 }
190
191 void NodeFile::assignMPIRankToDOFs(int* mpiRankOfDOF,
192 const std::vector<index_t>& distribution)
193 {
194 int p_min = MPIInfo->size, p_max = -1;
195 // first we calculate the min and max DOF on this processor to reduce
196 // costs for searching
197 const std::pair<index_t,index_t> dofRange(getDOFRange());
198
199 for (int p = 0; p < MPIInfo->size; ++p) {
200 if (distribution[p] <= dofRange.first)
201 p_min = p;
202 if (distribution[p] <= dofRange.second)
203 p_max = p;
204 }
205 #pragma omp parallel for
206 for (index_t n = 0; n < numNodes; ++n) {
207 const index_t k = globalDegreesOfFreedom[n];
208 for (int p = p_min; p <= p_max; ++p) {
209 if (k < distribution[p + 1]) {
210 mpiRankOfDOF[n] = p;
211 break;
212 }
213 }
214 }
215 }
216
217 } // namespace dudley
218

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision
svn:mergeinfo /branches/4.0fordebian/dudley/src/NodeFile.cpp:5567-5588 /branches/lapack2681/finley/src/NodeFile.cpp:2682-2741 /branches/pasowrap/dudley/src/NodeFile.cpp:3661-3674 /branches/py3_attempt2/dudley/src/NodeFile.cpp:3871-3891 /branches/restext/finley/src/NodeFile.cpp:2610-2624 /branches/ripleygmg_from_3668/dudley/src/NodeFile.cpp:3669-3791 /branches/stage3.0/finley/src/NodeFile.cpp:2569-2590 /branches/symbolic_from_3470/dudley/src/NodeFile.cpp:3471-3974 /branches/symbolic_from_3470/ripley/test/python/dudley/src/NodeFile.cpp:3517-3974 /release/3.0/finley/src/NodeFile.cpp:2591-2601 /release/4.0/dudley/src/NodeFile.cpp:5380-5406 /trunk/dudley/src/NodeFile.cpp:4257-4344,5898-6007 /trunk/ripley/test/python/dudley/src/NodeFile.cpp:3480-3515

  ViewVC Help
Powered by ViewVC 1.1.26