source: issm/trunk-jpl/src/c/classes/objects/Inputs/Inputs.cpp@ 14996

Last change on this file since 14996 was 14996, checked in by Eric.Larour, 12 years ago

CHG: integrated Container/ directory into src/c/classes/objects directory. No reason to have the containers
and the objects that they contain defined in different places.

File size: 11.3 KB
Line 
1/*
2 * \file Inputs.c
3 * \brief: implementation of the Inputs class, derived from DataSet class
4 */
5
6/*Headers: {{{*/
7#ifdef HAVE_CONFIG_H
8 #include <config.h>
9#else
10#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
11#endif
12
13#include "./Input.h"
14#include "./Inputs.h"
15#include "../../../shared/shared.h"
16
17using namespace std;
18/*}}}*/
19
20/*Object constructors and destructor*/
21/*FUNCTION Inputs::Inputs(){{{*/
22Inputs::Inputs(){
23 return;
24}
25/*}}}*/
26/*FUNCTION Inputs::~Inputs(){{{*/
27Inputs::~Inputs(){
28 return;
29}
30/*}}}*/
31
32/*Object management*/
33/*FUNCTION Inputs::GetInputValue(bool* pvalue,int enum-type){{{*/
34void Inputs::GetInputValue(bool* pvalue,int enum_type){
35
36 vector<Object*>::iterator object;
37 Input* input=NULL;
38 bool found=false;
39
40 /*Go through inputs and check whether any input with the same name is already in: */
41 for ( object=objects.begin() ; object < objects.end(); object++ ){
42
43 input=dynamic_cast<Input*>(*object);
44 if (input->InstanceEnum()==enum_type){
45 found=true;
46 break;
47 }
48 }
49
50 if (!found){
51 /*we could not find an input with the correct enum type. No defaults values were provided,
52 * error out: */
53 _error_("could not find input with enum type " << enum_type << " (" << EnumToStringx(enum_type) << ")");
54 }
55
56 /*Ok, we have an input if we made it here, request the input to return the value: */
57 input->GetInputValue(pvalue);
58
59}
60/*}}}*/
61/*FUNCTION Inputs::GetInputValue(int* pvalue,int enum-type){{{*/
62void Inputs::GetInputValue(int* pvalue,int enum_type){
63
64 vector<Object*>::iterator object;
65 Input* input=NULL;
66 bool found=false;
67
68 /*Go through inputs and check whether any input with the same name is already in: */
69 for ( object=objects.begin() ; object < objects.end(); object++ ){
70
71 input=dynamic_cast<Input*>(*object);
72 if (input->InstanceEnum()==enum_type){
73 found=true;
74 break;
75 }
76 }
77
78 if (!found){
79 /*we could not find an input with the correct enum type. No defaults values were provided,
80 * error out: */
81 _error_("could not find input with enum type " << enum_type << " (" << EnumToStringx(enum_type) << ")");
82 }
83
84 /*Ok, we have an input if we made it here, request the input to return the value: */
85 input->GetInputValue(pvalue);
86
87}
88/*}}}*/
89/*FUNCTION Inputs::GetInputValue(IssmDouble* pvalue,int enum-type){{{*/
90void Inputs::GetInputValue(IssmDouble* pvalue,int enum_type){
91
92 vector<Object*>::iterator object;
93 Input* input=NULL;
94 bool found=false;
95
96 /*Go through inputs and check whether any input with the same name is already in: */
97 for ( object=objects.begin() ; object < objects.end(); object++ ){
98
99 input=dynamic_cast<Input*>(*object);
100 if (input->InstanceEnum()==enum_type){
101 found=true;
102 break;
103 }
104 }
105
106 if (!found){
107 /*we could not find an input with the correct enum type. No defaults values were provided,
108 * error out: */
109 _error_("could not find input with enum type " << enum_type << " (" << EnumToStringx(enum_type) << ")");
110 }
111
112 /*Ok, we have an input if we made it here, request the input to return the value: */
113 input->GetInputValue(pvalue);
114
115}
116/*}}}*/
117/*FUNCTION Inputs::GetInputAverage{{{*/
118void Inputs::GetInputAverage(IssmDouble* pvalue,int enum_type){
119
120 vector<Object*>::iterator object;
121 Input* input=NULL;
122 bool found=false;
123
124 /*Go through inputs and check whether any input with the same name is already in: */
125 for ( object=objects.begin() ; object < objects.end(); object++ ){
126
127 input=dynamic_cast<Input*>(*object);
128 if (input->InstanceEnum()==enum_type){
129 found=true;
130 break;
131 }
132 }
133
134 if (!found){
135 /*we could not find an input with the correct enum type. No defaults values were provided,
136 * error out: */
137 _error_("could not find input with enum type " << enum_type << " (" << EnumToStringx(enum_type) << ")");
138 }
139
140 /*Ok, we have an input if we made it here, request the input to return the value: */
141 input->GetInputAverage(pvalue);
142
143}
144/*}}}*/
145/*FUNCTION Inputs::AddInput{{{*/
146int Inputs::AddInput(Input* in_input){
147
148 /*First, go through dataset of inputs and check whether any input
149 * with the same name is already in. If so, erase the corresponding
150 * object before adding this new one: */
151 vector<Object*>::iterator object;
152 Input* input=NULL;
153
154 /*In debugging mode, check that the input is not a NULL pointer*/
155 _assert_(in_input);
156
157 for ( object=objects.begin() ; object < objects.end(); object++ ){
158
159 input=dynamic_cast<Input*>(*object);
160
161 if (input->InstanceEnum()==in_input->InstanceEnum()){
162 this->DeleteObject(input);
163 break;
164 }
165 }
166 this->AddObject(in_input);
167
168 return 1;
169}
170/*}}}*/
171/*FUNCTION Inputs::ChangeEnum{{{*/
172void Inputs::ChangeEnum(int oldenumtype,int newenumtype){
173
174 /*Go through dataset of inputs and look for input with
175 * same enum as input enum, once found, just change its name */
176 vector<Object*>::iterator object;
177 Input* input=NULL;
178
179 /*Delete existing input of newenumtype if it exists*/
180 for ( object=objects.begin() ; object < objects.end(); object++ ){
181 input=dynamic_cast<Input*>(*object);
182
183 if (input->InstanceEnum()==newenumtype){
184 this->DeleteObject(input);
185 break;
186 }
187 }
188
189 /*Change enum_type of input of oldenumtype*/
190 for ( object=objects.begin() ; object < objects.end(); object++ ){
191
192 input=dynamic_cast<Input*>(*object);
193
194 if (input->InstanceEnum()==oldenumtype){
195 input->ChangeEnum(newenumtype);
196 break;
197 }
198 }
199}
200/*}}}*/
201/*FUNCTION Inputs::ConstrainMin{{{*/
202void Inputs::ConstrainMin(int constrain_enum, IssmDouble minimum){
203
204 /*Find x and y inputs: */
205 Input* constrain_input=dynamic_cast<Input*>(this->GetInput(constrain_enum));
206
207 /*some checks: */
208 if(!constrain_input) _error_("input " << EnumToStringx(constrain_enum) << " could not be found!");
209
210 /*Apply ContrainMin: */
211 constrain_input->ConstrainMin(minimum);
212}
213/*}}}*/
214/*FUNCTION Inputs::InfinityNorm{{{*/
215IssmDouble Inputs::InfinityNorm(int enumtype){
216
217 /*Output*/
218 IssmDouble norm;
219
220 /*Get input*/
221 Input* input=dynamic_cast<Input*>(this->GetInput(enumtype));
222
223 /*Apply ContrainMin: */
224 if (input){
225 norm=input->InfinityNorm();
226 }
227 else{
228 norm=0;
229 }
230
231 /*Return output*/
232 return norm;
233}
234/*}}}*/
235/*FUNCTION Inputs::Max{{{*/
236IssmDouble Inputs::Max(int enumtype){
237
238 /*Output*/
239 IssmDouble max;
240
241 /*Get input*/
242 Input* input=dynamic_cast<Input*>(this->GetInput(enumtype));
243
244 /*Apply ContrainMin: */
245 if (input){
246 max=input->Max();
247 }
248 else{
249 _error_("Input " << EnumToStringx(enumtype) << " not found");
250 }
251
252 /*Return output*/
253 return max;
254}
255/*}}}*/
256/*FUNCTION Inputs::MaxAbs{{{*/
257IssmDouble Inputs::MaxAbs(int enumtype){
258
259 /*Output*/
260 IssmDouble max;
261
262 /*Get input*/
263 Input* input=dynamic_cast<Input*>(this->GetInput(enumtype));
264
265 /*Apply ContrainMin: */
266 if (input){
267 max=input->MaxAbs();
268 }
269 else{
270 _error_("Input " << EnumToStringx(enumtype) << " not found");
271 }
272
273 /*Return output*/
274 return max;
275}
276/*}}}*/
277/*FUNCTION Inputs::Min{{{*/
278IssmDouble Inputs::Min(int enumtype){
279
280 /*Output*/
281 IssmDouble min;
282
283 /*Get input*/
284 Input* input=dynamic_cast<Input*>(this->GetInput(enumtype));
285
286 /*Apply ContrainMin: */
287 if (input){
288 min=input->Min();
289 }
290 else{
291 _error_("Input " << EnumToStringx(enumtype) << " not found");
292 }
293
294 /*Return output*/
295 return min;
296}
297/*}}}*/
298/*FUNCTION Inputs::MinAbs{{{*/
299IssmDouble Inputs::MinAbs(int enumtype){
300
301 /*Output*/
302 IssmDouble min;
303
304 /*Get input*/
305 Input* input=dynamic_cast<Input*>(this->GetInput(enumtype));
306
307 /*Apply ContrainMin: */
308 if (input){
309 min=input->MinAbs();
310 }
311 else{
312 _error_("Input " << EnumToStringx(enumtype) << " not found");
313 }
314
315 /*Return output*/
316 return min;
317}
318/*}}}*/
319/*FUNCTION Inputs::GetInput{{{*/
320Input* Inputs::GetInput(int enum_name){
321
322 vector<Object*>::iterator object;
323 Input* input=NULL;
324
325 for ( object=objects.begin() ; object < objects.end(); object++ ){
326
327 input=dynamic_cast<Input*>(*object);
328
329 if (input->InstanceEnum()==enum_name){
330 return input;
331 }
332 }
333 return NULL;
334}
335/*}}}*/
336/*FUNCTION Inputs::DeleteInput{{{*/
337int Inputs::DeleteInput(int enum_type){
338
339 vector<Object*>::iterator object;
340 Input* input=NULL;
341
342 for ( object=objects.begin() ; object < objects.end(); object++ ){
343
344 input=dynamic_cast<Input*>(*object);
345
346 if (input->InstanceEnum()==enum_type){
347 this->DeleteObject(input);
348 break;
349 }
350 }
351
352 return 1;
353
354}
355/*}}}*/
356/*FUNCTION Inputs::DuplicateInput{{{*/
357void Inputs::DuplicateInput(int original_enum,int new_enum){
358
359 /*Make a copy of the original input: */
360 Input* original=dynamic_cast<Input*>(this->GetInput(original_enum));
361 if(!original)_error_("could not find input with enum: " << EnumToStringx(original_enum));
362 Input* copy=dynamic_cast<Input*>(original->copy());
363
364 /*Change copy enum to reinitialized_enum: */
365 copy->ChangeEnum(new_enum);
366
367 /*Add copy into inputs, it will wipe off the one already there: */
368 this->AddInput(dynamic_cast<Input*>(copy));
369}
370/*}}}*/
371/*FUNCTION Inputs::SpawnTriaInputs{{{*/
372Inputs* Inputs::SpawnTriaInputs(int* indices){
373
374 /*Intermediary*/
375 vector<Object*>::iterator object;
376 Input* inputin=NULL;
377 Input* inputout=NULL;
378
379 /*Output*/
380 Inputs* newinputs=new Inputs();
381
382 /*Go through inputs and call Spawn function*/
383 for ( object=objects.begin() ; object < objects.end(); object++ ){
384
385 /*Create new input*/
386 inputin=dynamic_cast<Input*>(*object);
387 inputout=inputin->SpawnTriaInput(indices);
388
389 /*Add input to new inputs*/
390 newinputs->AddObject(inputout);
391 }
392
393 /*Assign output pointer*/
394 return newinputs;
395}
396/*}}}*/
397/*FUNCTION Inputs::AXPY{{{*/
398void Inputs::AXPY(int MeshYEnum, IssmDouble scalar, int MeshXEnum){
399
400 /*Find x and y inputs: */
401 Input* xinput=dynamic_cast<Input*>(this->GetInput(MeshXEnum));
402 Input* yinput=dynamic_cast<Input*>(this->GetInput(MeshYEnum));
403
404 /*some checks: */
405 if(!xinput) _error_("input " << EnumToStringx(MeshXEnum) << " could not be found!");
406 if(!yinput) _error_("input " << EnumToStringx(MeshYEnum) << " could not be found!");
407
408 /*Apply AXPY: */
409 yinput->AXPY(xinput,scalar);
410}
411/*}}}*/
412/*FUNCTION Inputs::Configure{{{*/
413void Inputs::Configure(Parameters* parameters){
414
415 vector<Object*>::iterator object;
416 Input* input=NULL;
417
418 for ( object=objects.begin() ; object < objects.end(); object++ ){
419
420 input=dynamic_cast<Input*>(*object);
421 input->Configure(parameters);
422
423 }
424
425}
426/*}}}*/
427
428/*Methods relating to inputs: */
429void IsInputConverged(IssmDouble* peps, Input** new_inputs,Input** old_inputs,int num_inputs,int criterion_enum){ /*{{{*/
430
431 /*figure out convergence at the input level.
432 We are given a list of inputs, new and old, and a criterion, and using the
433 inputs, we return the value of the criterion test, which will be used at the
434 solution level to determine convergence.
435 */
436
437 int i,j;
438
439 /*output: */
440 IssmDouble eps;
441
442 /*intermediary: */
443 IssmDouble *newvalues = NULL;
444 IssmDouble *oldvalues = NULL;
445 int num_values;
446 IssmDouble ndu = 0;
447 IssmDouble nu = 0;
448
449 if(criterion_enum==RelativeEnum){
450
451 /*conpute ndu/du (where u could be velocity, pressure, temperature, etc ...): */
452 for(i=0;i<num_inputs;i++){
453
454 /*in debugging mode, check that the inputs are of the same type*/
455 _assert_(new_inputs[i]->ObjectEnum()==old_inputs[i]->ObjectEnum());
456
457 /*Get pointers*/
458 new_inputs[i]->GetValuesPtr(&newvalues,&num_values);
459 old_inputs[i]->GetValuesPtr(&oldvalues,&num_values);
460 for(j=0;j<num_values;j++){
461 ndu+=pow(newvalues[j]-oldvalues[j],2);
462 nu+=pow(oldvalues[j],2);
463 }
464 }
465
466 /*take square root: */
467 ndu=sqrt(ndu);
468 nu=sqrt(nu);
469
470 /*now, compute eps: */
471 if(reCast<bool>(nu))eps=ndu/nu;
472 else eps=0;
473 }
474 else _error_("convergence criterion " << EnumToStringx(criterion_enum) << " not supported yet!");
475
476 /*Assign output pointers:*/
477 *peps=eps;
478}
479/*}}}*/
Note: See TracBrowser for help on using the repository browser.