source: issm/branches/trunk-dlcheng-ASE/src/c/classes/Inputs/TriaInput.cpp

Last change on this file was 27956, checked in by dlcheng, 18 months ago

CHG: Collecting dlcheng-ASE branch changes to misfit calculation. Changes work with r27296 and not from the current revision r27954.

File size: 12.4 KB
Line 
1/*!\file TriaInput.c
2 * \brief: implementation of the TriaInput object
3 */
4
5#ifdef HAVE_CONFIG_H
6 #include <config.h>
7#else
8#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
9#endif
10
11#include "../classes.h"
12#include "../../shared/shared.h"
13#include "./TriaInput.h"
14
15/*TriaInput constructors and destructor*/
16TriaInput::TriaInput(void){/*{{{*/
17
18 this->numberofelements_local = -1;
19 this->numberofvertices_local = -1;
20 this->isserved = false;
21 this->isserved_collapsed= 0;
22 this->M = -1;
23 this->N = -1;
24 this->values = NULL;
25 this->element_values = NULL;
26
27}/*}}}*/
28TriaInput::TriaInput(int nbe_in,int nbv_in,int interp_in){/*{{{*/
29
30 _assert_(nbe_in>0);
31 _assert_(nbe_in<1e11);
32 _assert_(nbv_in>0);
33 _assert_(nbv_in<1e11);
34 this->numberofelements_local = nbe_in;
35 this->numberofvertices_local = nbv_in;
36 this->isserved = false;
37 this->isserved_collapsed = 0;
38
39 /*Reset takes care of the rest*/
40 this->Reset(interp_in);
41}/*}}}*/
42TriaInput::~TriaInput(){/*{{{*/
43 if(this->element_values) xDelete<IssmDouble>(this->element_values);
44 if(this->values) xDelete<IssmDouble>(this->values);
45}
46/*}}}*/
47void TriaInput::Reset(int interp_in){/*{{{*/
48
49 /*Clean up*/
50 if(this->values) xDelete<IssmDouble>(this->values);
51 if(this->element_values) xDelete<IssmDouble>(this->element_values);
52
53 /*Set interpolation*/
54 this->interpolation = interp_in;
55
56 /*Create Sizes*/
57 if(this->interpolation==P1Enum){
58 this->M = this->numberofvertices_local;
59 this->N = 1;
60 }
61 else{
62 this->M = this->numberofelements_local;
63 this->N = TriaRef::NumberofNodes(interp_in);
64 }
65
66 /*Allocate Pointers*/
67 this->values = xNewZeroInit<IssmDouble>(this->M*this->N);
68 this->element_values = xNewZeroInit<IssmDouble>(TriaRef::NumberofNodes(interp_in));
69}/*}}}*/
70
71/*Object virtual functions definitions:*/
72Input* TriaInput::copy() {/*{{{*/
73
74 TriaInput* output = new TriaInput(this->numberofelements_local,this->numberofvertices_local,this->interpolation);
75
76 xMemCpy<IssmDouble>(output->values,this->values,this->M*this->N);
77 xMemCpy<IssmDouble>(output->element_values,this->element_values,TriaRef::NumberofNodes(this->interpolation));
78
79 return output;
80}
81/*}}}*/
82void TriaInput::DeepEcho(void){/*{{{*/
83 _printf_("TriaInput Echo:\n");
84 _printf_(" interpolation: "<<EnumToStringx(this->interpolation)<<"\n");
85 _printf_(" Size: "<<M<<"x"<<N<<"\n");
86 _printf_(" isserved: "<<(isserved?"true":"false") << "\n");
87 _printf_(" isserved_collapsed: "<<isserved_collapsed << "\n");
88 if(isserved){
89 _printf_(" current values: ");
90 for(int i=0;i<3;i++) _printf_(" "<<this->element_values[i]);
91 _printf_("] ("<<EnumToStringx(this->interpolation)<<")\n");
92 }
93 printarray(this->values,this->M,this->N);
94 //_printf_(setw(15)<<" TriaInput "<<setw(25)<<left<<EnumToStringx(this->enum_type)<<" "<<(value?"true":"false") << "\n");
95}
96/*}}}*/
97void TriaInput::Echo(void){/*{{{*/
98 _printf_("TriaInput Echo:\n");
99 _printf_(" interpolation: "<<EnumToStringx(this->interpolation)<<"\n");
100 _printf_(" Size: "<<M<<"x"<<N<<"\n");
101 _printf_(" isserved: "<<(isserved?"true":"false") << "\n");
102 _printf_(" isserved_collapsed: "<<isserved_collapsed << "\n");
103 if(isserved){
104 _printf_(" current values: ");
105 _printf_("[ ");
106 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) _printf_(" "<<this->element_values[i]);
107 _printf_("] ("<<EnumToStringx(this->interpolation)<<")\n");
108 }
109}
110/*}}}*/
111int TriaInput::Id(void){/*{{{*/
112 return -1;
113}/*}}}*/
114void TriaInput::Marshall(MarshallHandle* marshallhandle){ /*{{{*/
115
116 int object_enum = TriaInputEnum;
117 marshallhandle->call(object_enum);
118
119 marshallhandle->call(this->numberofelements_local);
120 marshallhandle->call(this->numberofvertices_local);
121 marshallhandle->call(this->interpolation);
122 marshallhandle->call(this->M);
123 marshallhandle->call(this->N);
124 this->isserved = false;
125 this->isserved_collapsed = 0;
126 if(this->M*this->N){
127 marshallhandle->call(this->values,this->M*this->N);
128 }
129 else this->values = NULL;
130
131 if(marshallhandle->OperationNumber() == MARSHALLING_LOAD){
132 this->element_values = xNewZeroInit<IssmDouble>(TriaRef::NumberofNodes(this->interpolation));
133 }
134
135}
136/*}}}*/
137int TriaInput::ObjectEnum(void){/*{{{*/
138 return TriaInputEnum;
139}
140/*}}}*/
141
142/*TriaInput management*/
143void TriaInput::SetInput(int interp_in,int row,IssmDouble value_in){/*{{{*/
144
145 _assert_(this);
146 _assert_(row>=0);
147 _assert_(row<this->M);
148 _assert_(this->N==1);
149
150 this->values[row] = value_in;
151 this->isserved = false;
152}
153/*}}}*/
154void TriaInput::SetInput(int interp_in,int numindices,int* indices,IssmDouble* values_in){/*{{{*/
155
156 _assert_(this);
157 if(interp_in==P1Enum && this->interpolation==P1Enum){
158 _assert_(this->N==1);
159 for(int i=0;i<numindices;i++){
160 int row = indices[i];
161 _assert_(row>=0);
162 _assert_(row<this->M);
163 this->values[row] = values_in[i];
164 }
165 }
166 else if(interp_in==P0Enum && this->interpolation==P0Enum){
167 _assert_(this->N==1);
168 for(int i=0;i<numindices;i++){
169 int row = indices[i];
170 _assert_(row>=0);
171 _assert_(row<this->M);
172 this->values[row] = values_in[i];
173 }
174 }
175 else if(this->interpolation!=P1Enum && interp_in==P1Enum){
176 this->Reset(interp_in);
177 for(int i=0;i<numindices;i++){
178 int row = indices[i];
179 _assert_(row>=0);
180 _assert_(row<this->M);
181 this->values[row] = values_in[i];
182 }
183 }
184 else{
185 _error_("Cannot convert "<<EnumToStringx(this->interpolation)<<" to "<<EnumToStringx(interp_in));
186 }
187 this->isserved = false;
188}
189/*}}}*/
190void TriaInput::SetInput(int interp_in,int row,int numindices,IssmDouble* values_in){/*{{{*/
191
192 _assert_(this);
193 if(interp_in==this->interpolation){
194 _assert_(this->N==numindices);
195 }
196 else{
197 this->Reset(interp_in);
198 _assert_(this->N==numindices);
199 }
200 for(int i=0;i<numindices;i++) this->values[row*this->N+i] = values_in[i];
201 this->isserved = false;
202}
203/*}}}*/
204void TriaInput::Serve(int numindices,int* indices){/*{{{*/
205
206 _assert_(this);
207 _assert_(this->N==1);
208
209 for(int i=0;i<numindices;i++){
210 int row = indices[i];
211 _assert_(row>=0);
212 _assert_(row<this->M);
213 this->element_values[i] = this->values[row];
214 }
215
216 /*Set input as served*/
217 this->isserved = true;
218 this->isserved_collapsed = 0;
219}
220/*}}}*/
221void TriaInput::Serve(int row,int numindices){/*{{{*/
222
223 _assert_(this);
224 _assert_(this->N==numindices);
225 _assert_(row<this->M);
226 _assert_(row>=0);
227
228 for(int i=0;i<numindices;i++){
229 this->element_values[i] = this->values[row*this->N+i];
230 }
231
232 /*Set input as served*/
233 this->isserved = true;
234 this->isserved_collapsed = 0;
235} /*}}}*/
236void TriaInput::ServeCollapsed(int row,int id1,int id2){/*{{{*/
237
238 _assert_(this);
239 _assert_(this->N>=3);
240 _assert_(row<this->M);
241 _assert_(row>=0);
242 _assert_(id1>=0 && id1<3);
243 _assert_(id2>=0 && id2<3);
244
245 this->element_values[0] = this->values[row*this->N+id1];
246 this->element_values[1] = this->values[row*this->N+id2];
247
248 /*Set input as served*/
249 this->isserved = true;
250 this->isserved_collapsed = 1;
251}/*}}}*/
252void TriaInput::SetServeCollapsed(bool status){/*{{{*/
253 this->isserved_collapsed = 1;
254}/*}}}*/
255int TriaInput::GetInterpolation(){/*{{{*/
256 return this->interpolation;
257}/*}}}*/
258void TriaInput::GetInputAverage(IssmDouble* pvalue){/*{{{*/
259 _assert_(this);
260 _assert_(this->isserved);
261
262 int numnodes = this->NumberofNodes(this->interpolation);
263 if(this->isserved_collapsed) numnodes = 2;
264 IssmDouble numnodesd = reCast<int,IssmDouble>(numnodes);
265 IssmDouble value = 0.;
266
267 for(int i=0;i<numnodes;i++) value+=this->element_values[i];
268 value = value/numnodesd;
269
270 *pvalue=value;
271}/*}}}*/
272IssmDouble TriaInput::GetInputMin(void){/*{{{*/
273 _assert_(this);
274 _assert_(this->isserved);
275
276 int numnodes = this->NumberofNodes(this->interpolation);
277 if(this->isserved_collapsed) numnodes = 2;
278 IssmDouble min=this->element_values[0];
279
280 for(int i=1;i<numnodes;i++){
281 if(this->element_values[i]<min) min=this->element_values[i];
282 }
283 return min;
284}/*}}}*/
285IssmDouble TriaInput::GetInputMax(void){/*{{{*/
286 _assert_(this);
287 _assert_(this->isserved);
288
289 int numnodes = this->NumberofNodes(this->interpolation);
290 if(this->isserved_collapsed) numnodes = 2;
291 IssmDouble max=this->element_values[0];
292
293 for(int i=1;i<numnodes;i++){
294 if(this->element_values[i]>max) max=this->element_values[i];
295 }
296 return max;
297}/*}}}*/
298IssmDouble TriaInput::GetInputMaxAbs(void){/*{{{*/
299 _assert_(this);
300 _assert_(this->isserved);
301
302 int numnodes = this->NumberofNodes(this->interpolation);
303 if(this->isserved_collapsed) numnodes = 2;
304 IssmDouble maxabs=fabs(this->element_values[0]);
305
306 for(int i=1;i<numnodes;i++){
307 if(fabs(this->element_values[i])>maxabs) maxabs=fabs(this->element_values[i]);
308 }
309 return maxabs;
310}/*}}}*/
311void TriaInput::GetInputDerivativeValue(IssmDouble* derivativevalues, IssmDouble* xyz_list, Gauss* gauss){/*{{{*/
312 _assert_(this);
313 _assert_(this->isserved);
314
315 if(this->isserved_collapsed){
316 _assert_(gauss->Enum()==GaussSegEnum);
317 if(this->interpolation==P0Enum){
318 derivativevalues[0] = 0.;
319 }
320 else{
321 SegRef temp;
322 temp.GetInputDerivativeValue(derivativevalues,this->element_values,xyz_list,(GaussSeg*)gauss,P1Enum);
323 }
324 }
325 else{
326 _assert_(gauss->Enum()==GaussTriaEnum);
327 TriaRef::GetInputDerivativeValue(derivativevalues,this->element_values,xyz_list,(GaussTria*)gauss,this->interpolation);
328 }
329}/*}}}*/
330void TriaInput::GetInputValue(IssmDouble* pvalue,Gauss* gauss){/*{{{*/
331 _assert_(this);
332 _assert_(this->isserved);
333 if(this->isserved_collapsed){
334 _assert_(gauss->Enum()==GaussSegEnum);
335 if(this->interpolation==P0Enum){
336 *pvalue = this->element_values[0];
337 }
338 else{
339 SegRef temp;
340 temp.GetInputValue(pvalue,this->element_values,(GaussSeg*)gauss,P1Enum);
341 }
342 }
343 else{
344 _assert_(gauss->Enum()==GaussTriaEnum);
345 TriaRef::GetInputValue(pvalue,this->element_values,(GaussTria*)gauss,this->interpolation);
346 }
347}/*}}}*/
348int TriaInput::GetResultArraySize(void){/*{{{*/
349 return 1;
350}
351/*}}}*/
352int TriaInput::GetResultInterpolation(void){/*{{{*/
353 if(this->interpolation==P0Enum || this->interpolation==P0DGEnum){
354 return P0Enum;
355 }
356 return P1Enum;
357}/*}}}*/
358int TriaInput::GetResultNumberOfNodes(void){/*{{{*/
359 return TriaRef::NumberofNodes(this->interpolation);
360}
361/*}}}*/
362void TriaInput::Scale(IssmDouble alpha){/*{{{*/
363
364 for(int i=0;i<this->M*this->N;i++) this->values[i] = alpha*this->values[i];
365 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) this->element_values[i] = alpha*this->element_values[i];
366}
367/*}}}*/
368void TriaInput::Pow(IssmDouble alpha){/*{{{*/
369
370 for(int i=0;i<this->M*this->N;i++) this->values[i] = pow(this->values[i],alpha);
371 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) this->element_values[i] = pow(this->element_values[i],alpha);
372}
373/*}}}*/
374void TriaInput::AXPY(Input* xinput,IssmDouble alpha){/*{{{*/
375
376 /*xinput is of the same type, so cast it: */
377 if(xinput->ObjectEnum()!=TriaInputEnum) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
378 TriaInput* xtriainput=xDynamicCast<TriaInput*>(xinput);
379 if(xtriainput->GetInterpolation()!=this->interpolation) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
380
381 /*Carry out the AXPY operation depending on type:*/
382 for(int i=0;i<this->M*this->N;i++) this->values[i] = alpha*xtriainput->values[i] + this->values[i];
383 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) this->element_values[i] = alpha*xtriainput->element_values[i] + this->element_values[i];
384}
385/*}}}*/
386void TriaInput::Shift(IssmDouble alpha){/*{{{*/
387
388 /*Carry out the shift operation:*/
389 for(int i=0;i<this->M*this->N;i++) this->values[i] +=alpha;
390 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) this->element_values[i] += alpha;
391}
392/*}}}*/
393void TriaInput::PointWiseMult(Input* xinput){/*{{{*/
394
395 /*xinput is of the same type, so cast it: */
396 if(xinput->ObjectEnum()!=TriaInputEnum) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
397 TriaInput* xtriainput=xDynamicCast<TriaInput*>(xinput);
398 if(xtriainput->GetInterpolation()!=this->interpolation) _error_("Operation not permitted because xinput is of type " << EnumToStringx(xinput->ObjectEnum()));
399
400 /* we need to check that the vector sizes are identical*/
401 if(xtriainput->M!=this->M||xtriainput->N!=this->N) _error_("Operation not permitted because the inputs have different sizes");
402
403 /*Carry out the AXPY operation depending on type:*/
404 for(int i=0;i<this->M*this->N;i++) this->values[i] = xtriainput->values[i] * this->values[i];
405 for(int i=0;i<TriaRef::NumberofNodes(this->interpolation);i++) this->element_values[i] = xtriainput->element_values[i] * this->element_values[i];
406}
407/*}}}*/
408
409/*Object functions*/
Note: See TracBrowser for help on using the repository browser.