Line data Source code
1 : /*
2 : * Copyright (c) 2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UG_field_impl__
34 : #define __H__UG_field_impl__
35 :
36 : #include <cstring>
37 : #include <algorithm>
38 :
39 : namespace ug{
40 :
41 0 : template <class T> Field<T>::
42 : Field() :
43 0 : m_width(0),
44 0 : m_height(0),
45 0 : m_capacity(0),
46 0 : m_data(NULL)
47 : {
48 : }
49 :
50 0 : template <class T> Field<T>::
51 : Field(size_t width, size_t height) :
52 0 : m_width(width),
53 0 : m_height(height)
54 : {
55 0 : m_capacity = m_width * m_height;
56 0 : m_data = new T[m_capacity];
57 0 : }
58 :
59 0 : template <class T> Field<T>::
60 : Field(size_t width, size_t height, const T& value) :
61 0 : m_width(width),
62 0 : m_height(height)
63 : {
64 0 : m_capacity = m_width * m_height;
65 0 : m_data = new T[m_capacity];
66 : fill_all(value);
67 0 : }
68 :
69 0 : template <class T> Field<T>::
70 : Field(const Field& f){
71 0 : m_width = f.width();
72 0 : m_height = f.height();
73 0 : m_capacity = m_width * m_height;
74 0 : m_data = new T[m_capacity];
75 0 : memcpy(m_data, f.data(), m_capacity * sizeof(T));
76 0 : }
77 :
78 : template <class T> Field<T>::
79 : ~Field(){
80 0 : if(m_data)
81 0 : delete[] m_data;
82 0 : }
83 :
84 : template <class T> Field<T>& Field<T>::
85 : operator=(const Field& f){
86 : m_width = f.m_width;
87 : m_height = f.m_height;
88 : if(m_data && (m_capacity != m_width * m_height)){
89 : delete[] m_data;
90 : m_data = NULL;
91 : }
92 : m_capacity = m_width * m_height;
93 : if(!m_data)
94 : m_data = new T[m_capacity];
95 : memcpy(m_data, f.data(), m_capacity * sizeof(T));
96 : return *this;
97 : }
98 :
99 0 : template <class T> void Field<T>::
100 : resize_no_copy(size_t width, size_t height){
101 :
102 0 : if(width * height > m_capacity){
103 0 : if(m_data)
104 0 : delete[] m_data;
105 0 : m_capacity += width * height;
106 0 : m_data = new T[m_capacity];
107 : }
108 0 : m_width = width;
109 0 : m_height = height;
110 0 : }
111 :
112 : template <class T> T& Field<T>::
113 : at(size_t x, size_t y){
114 0 : return m_data[array_index(x, y)];
115 : }
116 :
117 : template <class T> const T& Field<T>::
118 : at(size_t x, size_t y) const{
119 0 : return m_data[array_index(x, y)];
120 : }
121 :
122 : template <class T> void Field<T>::
123 : fill(size_t x, size_t y, size_t w, size_t h, const T& value)
124 : {
125 : using std::min;
126 : using std::max;
127 :
128 : const size_t xEnd = max(x + w, m_width);
129 : const size_t yEnd = max(y + h, m_height);
130 :
131 : for(size_t iy = max(y, size_t(0)); iy < yEnd; ++iy){
132 : for(size_t ix = max(x, size_t(0)); ix < xEnd; ++ix){
133 : m_data[array_index(ix, iy)] = value;
134 : }
135 : }
136 : }
137 :
138 : template <class T> void Field<T>::
139 : fill_all(const T& value)
140 : {
141 : const size_t dataSize = size();
142 0 : for(size_t i = 0; i < dataSize; ++i)
143 0 : m_data[i] = value;
144 : }
145 :
146 : template <class T> void Field<T>::
147 : copy(size_t x, size_t y, const Field& f){
148 : using std::min;
149 : using std::max;
150 :
151 : const size_t xEnd = max(x + f.width(), m_width);
152 : const size_t yEnd = max(y + f.height(), m_height);
153 :
154 : for(size_t iy = max(y, size_t(0)); iy < yEnd; ++iy){
155 : for(size_t ix = max(x, size_t(0)); ix < xEnd; ++ix){
156 : m_data[array_index(ix, iy)] = f.at(ix, iy);
157 : }
158 : }
159 : }
160 :
161 : template <class T> void Field<T>::
162 : swap(Field& f){
163 : using std::swap;
164 : swap(m_width, f.m_width);
165 : swap(m_height, f.m_height);
166 : swap(m_capacity, f.m_capacity);
167 : swap(m_data, f.m_data);
168 : }
169 :
170 :
171 : template <class T> size_t Field<T>::
172 : array_index(size_t x, size_t y) const{
173 0 : return x + y * m_width;
174 : }
175 :
176 :
177 : template <class T>
178 : template <class Archive>
179 0 : void Field<T>::
180 : save( Archive& ar, const unsigned int version) const
181 : {
182 0 : ar & m_width;
183 0 : ar & m_height;
184 : const size_t s = size();
185 0 : for(size_t i = 0; i < s; ++i){
186 0 : ar & m_data[i];
187 : }
188 0 : }
189 :
190 : template <class T>
191 : template <class Archive>
192 0 : void Field<T>::
193 : load( Archive& ar, const unsigned int version)
194 : {
195 0 : size_t w = 0, h = 0;
196 : ar & w;
197 : ar & h;
198 0 : resize_no_copy(w, h);
199 : const size_t s = size();
200 0 : for(size_t i = 0; i < s; ++i){
201 0 : ar & m_data[i];
202 : }
203 0 : }
204 :
205 : }// end of namespace
206 :
207 : #endif //__H__UG_field_impl__
|