source: issm/trunk/src/c/objects/Inputs/TriaVertexForcing.cpp@ 8375

Last change on this file since 8375 was 8375, checked in by Mathieu Morlighem, 14 years ago

trunk: fixed TriaVertexForcing GetParameter error

File size: 14.2 KB
Line 
1/*!\file TriaVertexForcing.c
2 * \brief: implementation of the TriaVertexForcing 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 "stdio.h"
12#include <string.h>
13#include "../objects.h"
14#include "../../EnumDefinitions/EnumDefinitions.h"
15#include "../../shared/shared.h"
16#include "../../Container/Container.h"
17#include "../../include/include.h"
18
19/*TriaVertexForcing constructors and destructor*/
20/*FUNCTION TriaVertexForcing::TriaVertexForcing(){{{1*/
21TriaVertexForcing::TriaVertexForcing(){
22 enum_type=NoneEnum;
23 values=NULL;
24 numtimesteps=0;
25 parameters=NULL;
26 return;
27}
28/*}}}*/
29/*FUNCTION TriaVertexForcing::TriaVertexForcing(int in_enum_type,double* time0values,double time0,int numtimesteps,Parameters* parameters){{{1*/
30TriaVertexForcing::TriaVertexForcing(int in_enum_type,double* time0values,double time0,int in_numtimesteps,Parameters* parameters)
31 :TriaRef(1)
32{
33
34 /*Set TriaRef*/
35 this->SetElementType(P1Enum,0);
36 this->element_type=P1Enum;
37
38 /*Set Enum*/
39 enum_type=in_enum_type;
40
41 /*Allocate values and timesteps, and set first time step values: */
42 this->numtimesteps=in_numtimesteps;
43 this->values=(double*)xmalloc(this->numtimesteps*3*sizeof(double));
44 this->timesteps=(double*)xmalloc(this->numtimesteps*sizeof(double));
45 this->values[0]=time0values[0];
46 this->values[1]=time0values[1];
47 this->values[2]=time0values[2];
48 this->timesteps[0]=time0;
49
50 this->parameters=parameters;
51
52}
53/*}}}*/
54/*FUNCTION TriaVertexForcing::TriaVertexForcing(int in_enum_type,double* in_values,double* in_time,int numtimesteps,Parameters* parameters){{{1*/
55TriaVertexForcing::TriaVertexForcing(int in_enum_type,double* in_values,double* in_time,int in_numtimesteps,Parameters* parameters)
56 :TriaRef(1)
57{
58
59 /*Set TriaRef*/
60 this->SetElementType(P1Enum,0);
61 this->element_type=P1Enum;
62
63 /*Set Enum*/
64 enum_type=in_enum_type;
65
66 /*Allocate values and timesteps, and copy: */
67 this->numtimesteps=in_numtimesteps;
68 this->values=(double*)xmalloc(this->numtimesteps*3*sizeof(double));
69 this->timesteps=(double*)xmalloc(this->numtimesteps*sizeof(double));
70
71 memcpy(this->values,in_values,numtimesteps*3*sizeof(double));
72 memcpy(this->timesteps,in_time,numtimesteps*sizeof(double));
73
74 this->parameters=parameters;
75
76}
77/*}}}*/
78/*FUNCTION TriaVertexForcing::~TriaVertexForcing(){{{1*/
79TriaVertexForcing::~TriaVertexForcing(){
80 xfree((void**)&this->values);
81 xfree((void**)&this->timesteps);
82 parameters=NULL;
83 return;
84}
85/*}}}*/
86/*FUNCTION TriaVertexForcing::AddTimeValues(double* values,int step,double time);{{{1*/
87void TriaVertexForcing::AddTimeValues(double* values,int step,double time){
88
89 /*insert values at time step: */
90 if (step<0)_error_("timestep should start at least at time 0!");
91 if (step>numtimesteps-1)_error_("timestep cannot be more than number of time steps");
92
93 /*go ahead and plug: */
94 this->timesteps[step]=time;
95 this->values[3*step+0]=values[0];
96 this->values[3*step+1]=values[1];
97 this->values[3*step+2]=values[2];
98}
99/*}}}*/
100
101/*Object virtual functions definitions:*/
102/*FUNCTION TriaVertexForcing::Echo {{{1*/
103void TriaVertexForcing::Echo(void){
104 this->DeepEcho();
105}
106/*}}}*/
107/*FUNCTION TriaVertexForcing::DeepEcho{{{1*/
108void TriaVertexForcing::DeepEcho(void){
109
110 int i;
111
112 printf("TriaVertexForcing:\n");
113 printf(" enum: %i (%s)\n",this->enum_type,EnumToStringx(this->enum_type));
114 printf(" numtimesteps: %i\n",this->numtimesteps);
115 for(i=0;i<this->numtimesteps;i++){
116 printf(" time: %g values: [%g %g %g]\n",this->timesteps[i],this->values[3*i+0],this->values[3*i+1],this->values[3*i+2]);
117 }
118}
119/*}}}*/
120/*FUNCTION TriaVertexForcing::Id{{{1*/
121int TriaVertexForcing::Id(void){ return -1; }
122/*}}}*/
123/*FUNCTION TriaVertexForcing::MyRank{{{1*/
124int TriaVertexForcing::MyRank(void){
125 extern int my_rank;
126 return my_rank;
127}
128/*}}}*/
129/*FUNCTION TriaVertexForcing::Marshall{{{1*/
130void TriaVertexForcing::Marshall(char** pmarshalled_dataset){
131
132 char* marshalled_dataset=NULL;
133 int enum_value=0;
134
135 /*recover marshalled_dataset: */
136 marshalled_dataset=*pmarshalled_dataset;
137
138 /*get enum value of TriaVertexForcing: */
139 enum_value=TriaVertexForcingEnum;
140
141 /*marshall enum: */
142 memcpy(marshalled_dataset,&enum_value,sizeof(enum_value));marshalled_dataset+=sizeof(enum_value);
143
144 /*marshall TriaVertexForcing data: */
145 memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
146 memcpy(marshalled_dataset,&numtimesteps,sizeof(numtimesteps));marshalled_dataset+=sizeof(numtimesteps);
147 memcpy(marshalled_dataset,values,numtimesteps*3*sizeof(double));marshalled_dataset+=numtimesteps*3*sizeof(double);
148 memcpy(marshalled_dataset,timesteps,numtimesteps*sizeof(double));marshalled_dataset+=numtimesteps*sizeof(double);
149
150 *pmarshalled_dataset=marshalled_dataset;
151}
152/*}}}*/
153/*FUNCTION TriaVertexForcing::MarshallSize{{{1*/
154int TriaVertexForcing::MarshallSize(){
155
156 return
157 +sizeof(enum_type)+
158 +sizeof(numtimesteps)+
159 3*numtimesteps*sizeof(double)+
160 numtimesteps*sizeof(double)+
161 +sizeof(int); //sizeof(int) for enum value
162}
163/*}}}*/
164/*FUNCTION TriaVertexForcing::Demarshall{{{1*/
165void TriaVertexForcing::Demarshall(char** pmarshalled_dataset){
166
167 char* marshalled_dataset=NULL;
168 int i;
169
170 /*recover marshalled_dataset: */
171 marshalled_dataset=*pmarshalled_dataset;
172
173 /*this time, no need to get enum type, the pointer directly points to the beginning of the
174 *object data (thanks to DataSet::Demarshall):*/
175 memcpy(&enum_type,marshalled_dataset,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
176 memcpy(&numtimesteps,marshalled_dataset,sizeof(numtimesteps));marshalled_dataset+=sizeof(numtimesteps);
177 /*allocate: */
178 timesteps=(double*)xmalloc(numtimesteps*sizeof(double));
179 values=(double*)xmalloc(numtimesteps*3*sizeof(double));
180
181 memcpy(values,marshalled_dataset,3*numtimesteps*sizeof(double));marshalled_dataset+=3*numtimesteps*sizeof(double);
182 memcpy(timesteps,marshalled_dataset,numtimesteps*sizeof(double));marshalled_dataset+=numtimesteps*sizeof(double);
183
184 /*return: */
185 *pmarshalled_dataset=marshalled_dataset;
186 return;
187}
188/*}}}*/
189/*FUNCTION TriaVertexForcing::Enum{{{1*/
190int TriaVertexForcing::Enum(void){
191
192 return TriaVertexForcingEnum;
193
194}
195/*}}}*/
196/*FUNCTION TriaVertexForcing::copy{{{1*/
197Object* TriaVertexForcing::copy() {
198
199 return new TriaVertexForcing(this->enum_type,this->values,this->timesteps,this->numtimesteps,this->parameters);
200
201}
202/*}}}*/
203
204/*TriaVertexForcing management*/
205/*FUNCTION TriaVertexForcing::EnumType{{{1*/
206int TriaVertexForcing::EnumType(void){
207
208 return this->enum_type;
209
210}
211/*}}}*/
212/*FUNCTION TriaVertexForcing::SpawnTriaInput{{{1*/
213Input* TriaVertexForcing::SpawnTriaInput(int* indices){
214
215 /*output*/
216 TriaVertexForcing* outforcing=NULL;
217
218 /*Create new Tria forcing (copy of current forcing)*/
219 outforcing=new TriaVertexForcing(this->enum_type,this->values,this->timesteps,this->numtimesteps,this->parameters);
220
221 /*Assign output*/
222 return outforcing;
223
224}
225/*}}}*/
226/*FUNCTION TriaVertexForcing::SpawnResult{{{1*/
227ElementResult* TriaVertexForcing::SpawnResult(int step, double time){
228
229 double triavalues[3];
230
231 /*Ok, we want to spawn a TriaVertexElementResult. We have the time, just get
232 *the correct values at the three nodes: */
233 this->GetTimeValues(&triavalues[0],time);
234
235 return new TriaVertexElementResult(this->enum_type,&triavalues[0],step,time);
236
237}
238/*}}}*/
239
240/*Object functions*/
241/*FUNCTION TriaVertexForcing::GetParameterValue(double* pvalue,GaussTria* gauss){{{1*/
242void TriaVertexForcing::GetParameterValue(double* pvalue,GaussTria* gauss){
243
244 double time;
245 double triavalues[3];
246
247 /*First, recover current time from parameters: */
248 parameters->FindParam(&time,TimeEnum);
249
250 /*Retrieve interpolated values for this time step: */
251 this->GetTimeValues(&triavalues[0],time);
252
253 /*Call TriaRef function*/
254 TriaRef::GetParameterValue(pvalue,&triavalues[0],gauss);
255
256}
257/*}}}*/
258/*FUNCTION TriaVertexForcing::GetParameterDerivativeValue(double* p, double* xyz_list, GaussTria* gauss){{{1*/
259void TriaVertexForcing::GetParameterDerivativeValue(double* p, double* xyz_list, GaussTria* gauss){
260
261 double time;
262 double triavalues[3];
263
264 /*First, recover current time from parameters: */
265 parameters->FindParam(&time,TimeEnum);
266
267 /*Retrieve interpolated values for this time step: */
268 this->GetTimeValues(&triavalues[0],time);
269
270 /*Call TriaRef function*/
271 TriaRef::GetParameterDerivativeValue(p,&triavalues[0],xyz_list,gauss);
272}
273/*}}}*/
274/*FUNCTION TriaVertexForcing::ChangeEnum{{{1*/
275void TriaVertexForcing::ChangeEnum(int newenumtype){
276 this->enum_type=newenumtype;
277}
278/*}}}*/
279/*FUNCTION TriaVertexForcing::GetParameterAverage{{{1*/
280void TriaVertexForcing::GetParameterAverage(double* pvalue){
281
282 double time;
283 double triavalues[3];
284
285 /*First, recover current time from parameters: */
286 parameters->FindParam(&time,TimeEnum);
287
288 /*Retrieve interpolated values for this time step: */
289 this->GetTimeValues(&triavalues[0],time);
290
291 *pvalue=1./3.*(triavalues[0]+triavalues[1]+triavalues[2]);
292}
293/*}}}*/
294
295/*Intermediary*/
296/*FUNCTION TriaVertexForcing::SquareMin{{{1*/
297void TriaVertexForcing::SquareMin(double* psquaremin, bool process_units,Parameters* parameters){
298
299 int i;
300 const int numnodes=3;
301 double valuescopy[numnodes];
302 double squaremin;
303 double time;
304
305 /*First, recover current time from parameters: */
306 parameters->FindParam(&time,TimeEnum);
307
308 /*Retrieve interpolated values for this time step: */
309 this->GetTimeValues(&valuescopy[0],time);
310
311 /*Process units if requested: */
312 if(process_units)UnitConversion(&valuescopy[0],numnodes,IuToExtEnum,enum_type,parameters);
313
314 /*Now, figure out minimum of valuescopy: */
315 squaremin=pow(valuescopy[0],2);
316 for(i=1;i<numnodes;i++){
317 if(pow(valuescopy[i],2)<squaremin)squaremin=pow(valuescopy[i],2);
318 }
319 /*Assign output pointers:*/
320 *psquaremin=squaremin;
321}
322/*}}}*/
323/*FUNCTION TriaVertexForcing::InfinityNorm{{{1*/
324double TriaVertexForcing::InfinityNorm(void){
325
326 /*Output*/
327 double norm=0;
328 const int numnodes=3;
329 double time;
330 double triavalues[3];
331
332 /*First, recover current time from parameters: */
333 parameters->FindParam(&time,TimeEnum);
334
335 /*Retrieve interpolated values for this time step: */
336 this->GetTimeValues(&triavalues[0],time);
337
338 for(int i=0;i<numnodes;i++) if(fabs(triavalues[i])>norm) norm=fabs(triavalues[i]);
339 return norm;
340}
341/*}}}*/
342/*FUNCTION TriaVertexForcing::Max{{{1*/
343double TriaVertexForcing::Max(void){
344
345 const int numnodes=3;
346 double max;
347 double time;
348 double triavalues[3];
349
350 /*First, recover current time from parameters: */
351 parameters->FindParam(&time,TimeEnum);
352
353 /*Retrieve interpolated values for this time step: */
354 this->GetTimeValues(&triavalues[0],time);
355
356 max=triavalues[0];
357
358 for(int i=1;i<numnodes;i++){
359 if(triavalues[i]>max) max=triavalues[i];
360 }
361 return max;
362}
363/*}}}*/
364/*FUNCTION TriaVertexForcing::MaxAbs{{{1*/
365double TriaVertexForcing::MaxAbs(void){
366
367 const int numnodes=3;
368 double max;
369 double time;
370 double triavalues[3];
371
372 /*First, recover current time from parameters: */
373 parameters->FindParam(&time,TimeEnum);
374
375 /*Retrieve interpolated values for this time step: */
376 this->GetTimeValues(&triavalues[0],time);
377
378
379 max=fabs(triavalues[0]);
380
381 for(int i=1;i<numnodes;i++){
382 if(fabs(triavalues[i])>max) max=fabs(triavalues[i]);
383 }
384 return max;
385}
386/*}}}*/
387/*FUNCTION TriaVertexForcing::Min{{{1*/
388double TriaVertexForcing::Min(void){
389
390 const int numnodes=3;
391 double min;
392 double time;
393 double triavalues[3];
394
395 /*First, recover current time from parameters: */
396 parameters->FindParam(&time,TimeEnum);
397
398 /*Retrieve interpolated values for this time step: */
399 this->GetTimeValues(&triavalues[0],time);
400
401 min=triavalues[0];
402
403 for(int i=1;i<numnodes;i++){
404 if(triavalues[i]<min) min=triavalues[i];
405 }
406 return min;
407}
408/*}}}*/
409/*FUNCTION TriaVertexForcing::MinAbs{{{1*/
410double TriaVertexForcing::MinAbs(void){
411
412 const int numnodes=3;
413 double min;
414 double time;
415 double triavalues[3];
416
417 /*First, recover current time from parameters: */
418 parameters->FindParam(&time,TimeEnum);
419
420 /*Retrieve interpolated values for this time step: */
421 this->GetTimeValues(&triavalues[0],time);
422
423 min=fabs(triavalues[0]);
424
425 for(int i=1;i<numnodes;i++){
426 if(fabs(triavalues[i])<min) min=fabs(triavalues[i]);
427 }
428 return min;
429}
430/*}}}*/
431/*FUNCTION TriaVertexForcing::GetVectorFromInputs{{{1*/
432void TriaVertexForcing::GetVectorFromInputs(Vec vector,int* doflist){
433
434 const int numvertices=3;
435 double time;
436 double triavalues[3];
437
438 /*First, recover current time from parameters: */
439 parameters->FindParam(&time,TimeEnum);
440
441 /*Retrieve interpolated values for this time step: */
442 this->GetTimeValues(&triavalues[0],time);
443
444 VecSetValues(vector,numvertices,doflist,(const double*)&triavalues[0],INSERT_VALUES);
445
446} /*}}}*/
447/*FUNCTION TriaVertexForcing::GetTimeValues{{{1*/
448void TriaVertexForcing::GetTimeValues(double* outvalues,double intime){
449
450 int i,j;
451 double deltat;
452 double alpha;
453 bool found=false;
454
455 /*Ok, we have the time, go through the timesteps, and figure out which interval we
456 *fall within. Then interpolate the values on this interval: */
457 if(intime<this->timesteps[0]){
458 /*get values for the first time: */
459 outvalues[0]=this->values[3*0+0];
460 outvalues[1]=this->values[3*0+1];
461 outvalues[2]=this->values[3*0+2];
462 found=true;
463 }
464 else if(intime>this->timesteps[this->numtimesteps-1]){
465 /*get values for the last time: */
466 outvalues[0]=this->values[3*(this->numtimesteps-1)+0];
467 outvalues[1]=this->values[3*(this->numtimesteps-1)+1];
468 outvalues[2]=this->values[3*(this->numtimesteps-1)+2];
469 found=true;
470 }
471 else{
472 /*Find which interval we fall within: */
473 for(i=0;i<this->numtimesteps;i++){
474 if(intime==this->timesteps[i]){
475 /*We are right on one step time: */
476 outvalues[0]=this->values[3*i+0];
477 outvalues[1]=this->values[3*i+1];
478 outvalues[2]=this->values[3*i+2];
479 found=true;
480 break; //we are done with the time interpolation.
481 }
482 else{
483 if(this->timesteps[i]<intime && intime<this->timesteps[i+1]){
484 /*ok, we have the interval ]i:i+1[. Interpolate linearly for now: */
485 deltat=this->timesteps[i+1]-this->timesteps[i];
486 alpha=(intime-this->timesteps[i])/deltat;
487 for(j=0;j<3;j++){
488 outvalues[j]=this->values[3*i+j]+alpha*(this->values[3*(i+1)+j]-this->values[3*i+j]);
489 }
490 found=true;
491 break;
492 }
493 else continue; //keep looking on the next interval
494 }
495 }
496 }
497 if(!found)_error_("did not find time interval on which to interpolate forcing values!");
498
499}
500/*}}}*/
501/*FUNCTION TriaVertexForcing::Configure{{{1*/
502void TriaVertexForcing::Configure(Parameters* parameters){
503 this->parameters=parameters;
504}
505/*}}}*/
Note: See TracBrowser for help on using the repository browser.