Changeset 8654
- Timestamp:
- 06/17/11 09:01:02 (14 years ago)
- Location:
- issm/trunk/src/c/objects
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/objects/Elements/Penta.cpp
r8653 r8654 3874 3874 } 3875 3875 /*}}}*/ 3876 /*FUNCTION Penta::GetBasalElement{{{1*/ 3877 Penta* Penta::GetBasalElement(void){ 3878 3879 /*Output*/ 3880 Penta* penta=NULL; 3881 3882 /*Go through all elements till the bed is reached*/ 3883 penta=this; 3884 for(;;){ 3885 /*Stop if we have reached the surface, else, take lower penta*/ 3886 if (penta->IsOnBed()) break; 3887 3888 /* get lower Penta*/ 3889 penta=penta->GetLowerElement(); 3890 _assert_(penta->Id()!=this->id); 3891 } 3892 3893 /*return output*/ 3894 return penta; 3895 } 3896 /*}}}*/ 3897 /*FUNCTION Penta::GetDofList {{{1*/ 3898 void Penta::GetDofList(int** pdoflist,int approximation_enum,int setenum){ 3899 3900 int i,j,count=0; 3901 int numberofdofs=0; 3902 int* doflist=NULL; 3903 3904 /*First, figure out size of doflist: */ 3905 for(i=0;i<6;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum); 3906 3907 /*Allocate: */ 3908 doflist=(int*)xmalloc(numberofdofs*sizeof(int)); 3909 3910 /*Populate: */ 3911 count=0; 3912 for(i=0;i<6;i++){ 3913 nodes[i]->GetDofList(doflist+count,approximation_enum,setenum); 3914 count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum); 3915 } 3916 3917 /*Assign output pointers:*/ 3918 *pdoflist=doflist; 3919 } 3920 /*}}}*/ 3921 /*FUNCTION Penta::GetDofList1 {{{1*/ 3922 void Penta::GetDofList1(int* doflist){ 3923 3924 int i; 3925 for(i=0;i<6;i++) doflist[i]=nodes[i]->GetDofList1(); 3926 3927 } 3928 /*}}}*/ 3929 /*FUNCTION Penta::GetElementType {{{1*/ 3930 int Penta::GetElementType(){ 3931 3932 /*return PentaRef field*/ 3933 return this->element_type; 3934 } 3935 /*}}}*/ 3936 /*FUNCTION Penta::GetHorizontalNeighboorSids {{{1*/ 3937 int* Penta::GetHorizontalNeighboorSids(){ 3938 3939 /*return PentaRef field*/ 3940 return &this->horizontalneighborsids[0]; 3941 3942 } 3943 /*}}}*/ 3944 /*FUNCTION Penta::GetLowerElement{{{1*/ 3945 Penta* Penta::GetLowerElement(void){ 3946 3947 Penta* upper_penta=NULL; 3948 3949 upper_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above 3950 3951 return upper_penta; 3952 } 3953 /*}}}*/ 3954 /*FUNCTION Penta::GetNodeIndex {{{1*/ 3955 int Penta::GetNodeIndex(Node* node){ 3956 3957 _assert_(nodes); 3958 for(int i=0;i<NUMVERTICES;i++){ 3959 if(node==nodes[i]) 3960 return i; 3961 } 3962 _error_("Node provided not found among element nodes"); 3963 3964 } 3965 /*}}}*/ 3966 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/ 3967 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype){ 3968 3969 /*Intermediaries*/ 3970 double value[NUMVERTICES]; 3971 GaussPenta *gauss = NULL; 3972 3973 /*Recover input*/ 3974 Input* input=inputs->GetInput(enumtype); 3975 if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype)); 3976 3977 /*Checks in debugging mode*/ 3978 _assert_(pvalue); 3979 3980 /* Start looping on the number of vertices: */ 3981 gauss=new GaussPenta(); 3982 for (int iv=0;iv<NUMVERTICES;iv++){ 3983 gauss->GaussVertex(iv); 3984 input->GetParameterValue(&pvalue[iv],gauss); 3985 } 3986 3987 /*clean-up*/ 3988 delete gauss; 3989 } 3990 /*}}}*/ 3991 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/ 3992 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){ 3993 3994 /*Intermediaries*/ 3995 double value[NUMVERTICES]; 3996 GaussPenta *gauss = NULL; 3997 3998 /*Recover input*/ 3999 Input* input=inputs->GetInput(enumtype); 4000 4001 /*Checks in debugging mode*/ 4002 _assert_(pvalue); 4003 4004 /* Start looping on the number of vertices: */ 4005 if (input){ 4006 gauss=new GaussPenta(); 4007 for (int iv=0;iv<NUMVERTICES;iv++){ 4008 gauss->GaussVertex(iv); 4009 input->GetParameterValue(&pvalue[iv],gauss); 4010 } 4011 } 4012 else{ 4013 for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue; 4014 } 4015 4016 /*clean-up*/ 4017 delete gauss; 4018 } 4019 /*}}}*/ 4020 /*FUNCTION Penta::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/ 4021 void Penta::GetParameterValue(double* pvalue,Node* node,int enumtype){ 4022 4023 Input* input=inputs->GetInput(enumtype); 4024 if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype)); 4025 4026 GaussPenta* gauss=new GaussPenta(); 4027 gauss->GaussVertex(this->GetNodeIndex(node)); 4028 4029 input->GetParameterValue(pvalue,gauss); 4030 delete gauss; 4031 } 4032 /*}}}*/ 4033 /*FUNCTION Penta::GetPhi {{{1*/ 4034 void Penta::GetPhi(double* phi, double* epsilon, double viscosity){ 4035 /*Compute deformational heating from epsilon and viscosity */ 4036 4037 double epsilon_matrix[3][3]; 4038 double epsilon_eff; 4039 double epsilon_sqr[3][3]; 4040 4041 /* Build epsilon matrix */ 4042 epsilon_matrix[0][0]=*(epsilon+0); 4043 epsilon_matrix[1][0]=*(epsilon+3); 4044 epsilon_matrix[2][0]=*(epsilon+4); 4045 epsilon_matrix[0][1]=*(epsilon+3); 4046 epsilon_matrix[1][1]=*(epsilon+1); 4047 epsilon_matrix[2][1]=*(epsilon+5); 4048 epsilon_matrix[0][2]=*(epsilon+4); 4049 epsilon_matrix[1][2]=*(epsilon+5); 4050 epsilon_matrix[2][2]=*(epsilon+2); 4051 4052 /* Effective value of epsilon_matrix */ 4053 epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2); 4054 epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2); 4055 epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2); 4056 epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2); 4057 epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2); 4058 epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2); 4059 epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2); 4060 epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2); 4061 epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2); 4062 epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5); 4063 4064 /*Phi = Tr(sigma * eps) 4065 * = Tr(sigma'* eps) 4066 * = 2 * eps_eff * sigma'_eff 4067 * = 4 * mu * eps_eff ^2*/ 4068 *phi=4*pow(epsilon_eff,2.0)*viscosity; 4069 } 4070 /*}}}*/ 4071 /*FUNCTION Penta::GetSidList{{{1*/ 4072 void Penta::GetSidList(int* sidlist){ 4073 4074 int i; 4075 for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList(); 4076 4077 } 4078 /*}}}*/ 4079 /*FUNCTION Penta::GetSolutionFromInputs{{{1*/ 4080 void Penta::GetSolutionFromInputs(Vec solution){ 4081 4082 int analysis_type; 4083 4084 /*retrive parameters: */ 4085 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 4086 4087 /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */ 4088 if (analysis_type==DiagnosticHorizAnalysisEnum){ 4089 int approximation; 4090 inputs->GetParameterValue(&approximation,ApproximationEnum); 4091 if(approximation==StokesApproximationEnum || approximation==NoneApproximationEnum){ 4092 GetSolutionFromInputsDiagnosticStokes(solution); 4093 } 4094 else if (approximation==MacAyealApproximationEnum || approximation==PattynApproximationEnum || approximation==HutterApproximationEnum){ 4095 GetSolutionFromInputsDiagnosticHoriz(solution); 4096 } 4097 else if (approximation==MacAyealPattynApproximationEnum || approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){ 4098 return; //the elements around will create the solution 4099 } 4100 } 4101 else if(analysis_type==DiagnosticHutterAnalysisEnum){ 4102 GetSolutionFromInputsDiagnosticHutter(solution); 4103 } 4104 else if(analysis_type==DiagnosticVertAnalysisEnum){ 4105 GetSolutionFromInputsDiagnosticVert(solution); 4106 } 4107 else if(analysis_type==ThermalAnalysisEnum){ 4108 GetSolutionFromInputsThermal(solution); 4109 } 4110 else if(analysis_type==EnthalpyAnalysisEnum){ 4111 GetSolutionFromInputsEnthalpy(solution); 4112 } 4113 else{ 4114 _error_("analysis: %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); 4115 } 4116 } 4117 /*}}}*/ 4118 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHoriz{{{1*/ 4119 void Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){ 4120 4121 const int numdof=NDOF2*NUMVERTICES; 4122 4123 int i; 4124 int approximation; 4125 int* doflist=NULL; 4126 double vx,vy; 4127 double values[numdof]; 4128 GaussPenta* gauss; 4129 4130 /*Get approximation enum and dof list: */ 4131 inputs->GetParameterValue(&approximation,ApproximationEnum); 4132 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4133 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4134 4135 /*If the element is a coupling, do nothing: every node is also on an other elements 4136 * (as coupling is between MacAyeal and Pattyn) so the other element will take care of it*/ 4137 GetDofList(&doflist,approximation,GsetEnum); 4138 4139 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4140 /*P1 element only for now*/ 4141 gauss=new GaussPenta(); 4142 for(i=0;i<NUMVERTICES;i++){ 4143 4144 /*Recover vx and vy*/ 4145 gauss->GaussVertex(i); 4146 vx_input->GetParameterValue(&vx,gauss); 4147 vy_input->GetParameterValue(&vy,gauss); 4148 values[i*NDOF2+0]=vx; 4149 values[i*NDOF2+1]=vy; 4150 } 4151 4152 /*Add value to global vector*/ 4153 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4154 4155 /*Free ressources:*/ 4156 delete gauss; 4157 xfree((void**)&doflist); 4158 } 4159 /*}}}*/ 4160 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHutter{{{1*/ 4161 void Penta::GetSolutionFromInputsDiagnosticHutter(Vec solution){ 4162 4163 const int numdof=NDOF2*NUMVERTICES; 4164 4165 int i; 4166 int* doflist=NULL; 4167 double vx,vy; 4168 double values[numdof]; 4169 GaussPenta* gauss=NULL; 4170 4171 /*Get dof list: */ 4172 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4173 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4174 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4175 4176 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4177 /*P1 element only for now*/ 4178 gauss=new GaussPenta(); 4179 for(i=0;i<NUMVERTICES;i++){ 4180 /*Recover vx and vy*/ 4181 gauss->GaussVertex(i); 4182 vx_input->GetParameterValue(&vx,gauss); 4183 vy_input->GetParameterValue(&vy,gauss); 4184 values[i*NDOF2+0]=vx; 4185 values[i*NDOF2+1]=vy; 4186 } 4187 4188 /*Add value to global vector*/ 4189 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4190 4191 /*Free ressources:*/ 4192 delete gauss; 4193 xfree((void**)&doflist); 4194 } 4195 /*}}}*/ 4196 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticVert{{{1*/ 4197 void Penta::GetSolutionFromInputsDiagnosticVert(Vec solution){ 4198 4199 const int numdof=NDOF1*NUMVERTICES; 4200 4201 int i; 4202 int* doflist=NULL; 4203 double vz; 4204 double values[numdof]; 4205 GaussPenta* gauss=NULL; 4206 4207 /*Get dof list: */ 4208 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4209 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input); 4210 4211 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4212 /*P1 element only for now*/ 4213 gauss=new GaussPenta(); 4214 for(i=0;i<NUMVERTICES;i++){ 4215 /*Recover vz */ 4216 gauss->GaussVertex(i); 4217 vz_input->GetParameterValue(&vz,gauss); 4218 values[i]=vz; 4219 } 4220 4221 /*Add value to global vector*/ 4222 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4223 4224 /*Free ressources:*/ 4225 delete gauss; 4226 xfree((void**)&doflist); 4227 } 4228 /*}}}*/ 4229 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticStokes{{{1*/ 4230 void Penta::GetSolutionFromInputsDiagnosticStokes(Vec solution){ 4231 4232 const int numdof=NDOF4*NUMVERTICES; 4233 4234 int i; 4235 int* doflist=NULL; 4236 double vx,vy,vz,p; 4237 double stokesreconditioning; 4238 double values[numdof]; 4239 GaussPenta *gauss; 4240 4241 /*Get dof list: */ 4242 GetDofList(&doflist,StokesApproximationEnum,GsetEnum); 4243 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4244 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4245 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input); 4246 Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input); 4247 4248 /*Recondition pressure: */ 4249 this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum); 4250 4251 /*Ok, we have vx vy vz and P in values, fill in vx vy vz P arrays: */ 4252 /*P1 element only for now*/ 4253 gauss=new GaussPenta(); 4254 for(i=0;i<NUMVERTICES;i++){ 4255 gauss->GaussVertex(i); 4256 vx_input->GetParameterValue(&vx,gauss); 4257 vy_input->GetParameterValue(&vy,gauss); 4258 vz_input->GetParameterValue(&vz,gauss); 4259 p_input ->GetParameterValue(&p ,gauss); 4260 values[i*NDOF4+0]=vx; 4261 values[i*NDOF4+1]=vy; 4262 values[i*NDOF4+2]=vz; 4263 values[i*NDOF4+3]=p/stokesreconditioning; 4264 } 4265 4266 /*Add value to global vector*/ 4267 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4268 4269 /*Free ressources:*/ 4270 delete gauss; 4271 xfree((void**)&doflist); 4272 } 4273 /*}}}*/ 4274 /*FUNCTION Penta::GetSolutionFromInputsThermal{{{1*/ 4275 void Penta::GetSolutionFromInputsThermal(Vec solution){ 4276 4277 const int numdof=NDOF1*NUMVERTICES; 4278 4279 int i; 4280 int* doflist=NULL; 4281 double values[numdof]; 4282 double temp; 4283 GaussPenta *gauss=NULL; 4284 4285 /*Get dof list: */ 4286 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4287 Input* t_input=inputs->GetInput(TemperatureEnum); _assert_(t_input); 4288 4289 gauss=new GaussPenta(); 4290 for(i=0;i<NUMVERTICES;i++){ 4291 /*Recover temperature*/ 4292 gauss->GaussVertex(i); 4293 t_input->GetParameterValue(&temp,gauss); 4294 values[i]=temp; 4295 } 4296 4297 /*Add value to global vector*/ 4298 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4299 4300 /*Free ressources:*/ 4301 delete gauss; 4302 xfree((void**)&doflist); 4303 } 4304 /*}}}*/ 4305 /*FUNCTION Penta::GetSolutionFromInputsEnthalpy{{{1*/ 4306 void Penta::GetSolutionFromInputsEnthalpy(Vec solution){ 4307 4308 const int numdof=NDOF1*NUMVERTICES; 4309 4310 int i; 4311 int* doflist=NULL; 4312 double values[numdof]; 4313 double enthalpy; 4314 GaussPenta *gauss=NULL; 4315 4316 /*Get dof list: */ 4317 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4318 Input* h_input=inputs->GetInput(EnthalpyEnum); _assert_(h_input); 4319 4320 gauss=new GaussPenta(); 4321 for(i=0;i<NUMVERTICES;i++){ 4322 /*Recover temperature*/ 4323 gauss->GaussVertex(i); 4324 h_input->GetParameterValue(&enthalpy,gauss); 4325 values[i]=enthalpy; 4326 } 4327 4328 /*Add value to global vector*/ 4329 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4330 4331 /*Free ressources:*/ 4332 delete gauss; 4333 xfree((void**)&doflist); 4334 } 4335 /*}}}*/ 4336 /*FUNCTION Penta::GetStabilizationParameter {{{1*/ 4337 double Penta::GetStabilizationParameter(double u, double v, double w, double diameter, double rho_ice, double heatcapacity, double thermalconductivity){ 4338 /*Compute stabilization parameter*/ 4339 4340 double normu; 4341 double tau_parameter; 4342 4343 normu=pow(pow(u,2)+pow(v,2)+pow(w,2),0.5); 4344 if(normu*diameter/(3*2*thermalconductivity/(rho_ice*heatcapacity))<1){ 4345 tau_parameter=pow(diameter,2)/(3*2*2*thermalconductivity/(rho_ice*heatcapacity)); 4346 } 4347 else tau_parameter=diameter/(2*normu); 4348 4349 return tau_parameter; 4350 } 4351 /*}}}*/ 4352 /*FUNCTION Penta::GetStrainRate3dPattyn{{{1*/ 4353 void Penta::GetStrainRate3dPattyn(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input){ 4354 /*Compute the 3d Blatter/PattynStrain Rate (5 components): 4355 * 4356 * epsilon=[exx eyy exy exz eyz] 4357 * 4358 * with exz=1/2 du/dz 4359 * eyz=1/2 dv/dz 4360 * 4361 * the contribution of vz is neglected 4362 */ 4363 4364 int i; 4365 double epsilonvx[5]; 4366 double epsilonvy[5]; 4367 4368 /*Check that both inputs have been found*/ 4369 if (!vx_input || !vy_input){ 4370 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input); 4371 } 4372 4373 /*Get strain rate assuming that epsilon has been allocated*/ 4374 vx_input->GetVxStrainRate3dPattyn(epsilonvx,xyz_list,gauss); 4375 vy_input->GetVyStrainRate3dPattyn(epsilonvy,xyz_list,gauss); 4376 4377 /*Sum all contributions*/ 4378 for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]; 4379 } 4380 /*}}}*/ 4381 /*FUNCTION Penta::GetStrainRate3d{{{1*/ 4382 void Penta::GetStrainRate3d(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input){ 4383 /*Compute the 3d Strain Rate (6 components): 4384 * 4385 * epsilon=[exx eyy ezz exy exz eyz] 4386 */ 4387 4388 int i; 4389 double epsilonvx[6]; 4390 double epsilonvy[6]; 4391 double epsilonvz[6]; 4392 4393 /*Check that both inputs have been found*/ 4394 if (!vx_input || !vy_input || !vz_input){ 4395 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p, vz: %p\n",vx_input,vy_input,vz_input); 4396 } 4397 4398 /*Get strain rate assuming that epsilon has been allocated*/ 4399 vx_input->GetVxStrainRate3d(epsilonvx,xyz_list,gauss); 4400 vy_input->GetVyStrainRate3d(epsilonvy,xyz_list,gauss); 4401 vz_input->GetVzStrainRate3d(epsilonvz,xyz_list,gauss); 4402 4403 /*Sum all contributions*/ 4404 for(i=0;i<6;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]+epsilonvz[i]; 4405 } 4406 /*}}}*/ 4407 /*FUNCTION Penta::GetUpperElement{{{1*/ 4408 Penta* Penta::GetUpperElement(void){ 4409 4410 Penta* upper_penta=NULL; 4411 4412 upper_penta=(Penta*)verticalneighbors[1]; //first one under, second one above 4413 4414 return upper_penta; 4415 } 4416 /*}}}*/ 4417 /*FUNCTION Penta::GetVectorFromInputs{{{1*/ 4418 void Penta::GetVectorFromInputs(Vec vector,int input_enum){ 4419 4420 int doflist1[NUMVERTICES]; 4421 4422 /*Get out if this is not an element input*/ 4423 if (!IsInput(input_enum)) return; 4424 4425 /*Prepare index list*/ 4426 this->GetDofList1(&doflist1[0]); 4427 4428 /*Get input (either in element or material)*/ 4429 Input* input=inputs->GetInput(input_enum); 4430 if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum)); 4431 4432 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */ 4433 input->GetVectorFromInputs(vector,&doflist1[0]); 4434 } 4435 /*}}}*/ 4436 /*FUNCTION Penta::GetZcoord {{{1*/ 4437 double Penta::GetZcoord(GaussPenta* gauss){ 4438 4439 int i; 4440 double z; 4441 double xyz_list[NUMVERTICES][3]; 4442 double z_list[NUMVERTICES]; 4443 4444 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES); 4445 for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2]; 4446 PentaRef::GetParameterValue(&z,z_list,gauss); 4447 4448 return z; 4449 } 4450 /*}}}*/ 3876 4451 /*FUNCTION Penta::Gradj {{{1*/ 3877 4452 void Penta::Gradj(Vec gradient,int control_type){ … … 3888 4463 3889 4464 case DragCoefficientEnum: 3890 3891 4465 inputs->GetParameterValue(&approximation,ApproximationEnum); 3892 if(IsOnShelf() || !IsOnBed()) return;3893 3894 4466 switch(approximation){ 3895 4467 case MacAyealApproximationEnum: 3896 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria. 3897 tria->GradjDragMacAyeal(gradient); 3898 delete tria->matice; delete tria; 4468 GradjDragMacAyeal(gradient); 3899 4469 break; 3900 4470 case PattynApproximationEnum: 3901 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria. 3902 tria->GradjDragMacAyeal(gradient); 3903 delete tria->matice; delete tria; 3904 //GradjDragPattyn(gradient); 4471 GradjDragPattyn(gradient); 3905 4472 break; 3906 4473 case StokesApproximationEnum: 3907 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria. 3908 tria->GradjDragStokes(gradient); 3909 delete tria->matice; delete tria; 3910 //GradjDragStokes(gradient); 4474 GradjDragStokes(gradient); 3911 4475 break; 3912 4476 case NoneApproximationEnum: … … 3921 4485 inputs->GetParameterValue(&approximation,ApproximationEnum); 3922 4486 switch(approximation){ 3923 3924 4487 case MacAyealApproximationEnum: 3925 3926 /*This element should be collapsed into a tria element at its base*/ 3927 if (!IsOnBed()) return; 3928 3929 /*Depth Average B*/ 3930 this->InputDepthAverageAtBase(RheologyBEnum,RheologyBbarEnum,MaterialsEnum); 3931 3932 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face). 3933 tria->GradjBMacAyeal(gradient); 3934 delete tria->matice; delete tria; 3935 3936 /*delete B average*/ 3937 this->matice->inputs->DeleteInput(RheologyBbarEnum); 4488 GradjBbarMacAyeal(gradient); 3938 4489 break; 3939 case PattynApproximationEnum: case StokesApproximationEnum: 3940 3941 /*Gradient is computed on bed only (Bbar)*/ 3942 if (!IsOnBed()) return; 3943 3944 /*Depth Average B*/ 3945 this->InputDepthAverageAtBase(RheologyBEnum,RheologyBbarEnum,MaterialsEnum); 3946 3947 /*B is a 2d field, use MacAyeal(2d) gradient even if it is Stokes or Pattyn*/ 3948 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face). 3949 tria->GradjBMacAyeal(gradient); 3950 delete tria->matice; delete tria; 3951 3952 /*delete B average*/ 3953 this->matice->inputs->DeleteInput(RheologyBbarEnum); 4490 case PattynApproximationEnum: 4491 GradjBbarPattyn(gradient); 3954 4492 break; 3955 4493 case StokesApproximationEnum: 4494 GradjBbarStokes(gradient); 4495 break; 3956 4496 case NoneApproximationEnum: 3957 4497 /*Gradient is 0*/ … … 3999 4539 } 4000 4540 /*}}}*/ 4001 /*FUNCTION Penta::GetBasalElement{{{1*/ 4002 Penta* Penta::GetBasalElement(void){ 4003 4004 /*Output*/ 4005 Penta* penta=NULL; 4006 4007 /*Go through all elements till the bed is reached*/ 4008 penta=this; 4009 for(;;){ 4010 /*Stop if we have reached the surface, else, take lower penta*/ 4011 if (penta->IsOnBed()) break; 4012 4013 /* get lower Penta*/ 4014 penta=penta->GetLowerElement(); 4015 _assert_(penta->Id()!=this->id); 4016 } 4017 4018 /*return output*/ 4019 return penta; 4020 } 4021 /*}}}*/ 4022 /*FUNCTION Penta::GetDofList {{{1*/ 4023 void Penta::GetDofList(int** pdoflist,int approximation_enum,int setenum){ 4024 4025 int i,j,count=0; 4026 int numberofdofs=0; 4027 int* doflist=NULL; 4028 4029 /*First, figure out size of doflist: */ 4030 for(i=0;i<6;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum); 4031 4032 /*Allocate: */ 4033 doflist=(int*)xmalloc(numberofdofs*sizeof(int)); 4034 4035 /*Populate: */ 4036 count=0; 4037 for(i=0;i<6;i++){ 4038 nodes[i]->GetDofList(doflist+count,approximation_enum,setenum); 4039 count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum); 4040 } 4041 4042 /*Assign output pointers:*/ 4043 *pdoflist=doflist; 4044 } 4045 /*}}}*/ 4046 /*FUNCTION Penta::GetDofList1 {{{1*/ 4047 void Penta::GetDofList1(int* doflist){ 4048 4049 int i; 4050 for(i=0;i<6;i++) doflist[i]=nodes[i]->GetDofList1(); 4051 4052 } 4053 /*}}}*/ 4054 /*FUNCTION Penta::GetElementType {{{1*/ 4055 int Penta::GetElementType(){ 4056 4057 /*return PentaRef field*/ 4058 return this->element_type; 4059 } 4060 /*}}}*/ 4061 /*FUNCTION Penta::GetHorizontalNeighboorSids {{{1*/ 4062 int* Penta::GetHorizontalNeighboorSids(){ 4063 4064 /*return PentaRef field*/ 4065 return &this->horizontalneighborsids[0]; 4066 4067 } 4068 /*}}}*/ 4069 /*FUNCTION Penta::GetLowerElement{{{1*/ 4070 Penta* Penta::GetLowerElement(void){ 4071 4072 Penta* upper_penta=NULL; 4073 4074 upper_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above 4075 4076 return upper_penta; 4077 } 4078 /*}}}*/ 4079 /*FUNCTION Penta::GetNodeIndex {{{1*/ 4080 int Penta::GetNodeIndex(Node* node){ 4081 4082 _assert_(nodes); 4083 for(int i=0;i<NUMVERTICES;i++){ 4084 if(node==nodes[i]) 4085 return i; 4086 } 4087 _error_("Node provided not found among element nodes"); 4088 4089 } 4090 /*}}}*/ 4091 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/ 4092 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype){ 4093 4094 /*Intermediaries*/ 4095 double value[NUMVERTICES]; 4096 GaussPenta *gauss = NULL; 4097 4098 /*Recover input*/ 4099 Input* input=inputs->GetInput(enumtype); 4100 if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype)); 4101 4102 /*Checks in debugging mode*/ 4103 _assert_(pvalue); 4104 4105 /* Start looping on the number of vertices: */ 4106 gauss=new GaussPenta(); 4107 for (int iv=0;iv<NUMVERTICES;iv++){ 4108 gauss->GaussVertex(iv); 4109 input->GetParameterValue(&pvalue[iv],gauss); 4110 } 4111 4112 /*clean-up*/ 4113 delete gauss; 4114 } 4115 /*}}}*/ 4116 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/ 4117 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){ 4118 4119 /*Intermediaries*/ 4120 double value[NUMVERTICES]; 4121 GaussPenta *gauss = NULL; 4122 4123 /*Recover input*/ 4124 Input* input=inputs->GetInput(enumtype); 4125 4126 /*Checks in debugging mode*/ 4127 _assert_(pvalue); 4128 4129 /* Start looping on the number of vertices: */ 4130 if (input){ 4131 gauss=new GaussPenta(); 4132 for (int iv=0;iv<NUMVERTICES;iv++){ 4133 gauss->GaussVertex(iv); 4134 input->GetParameterValue(&pvalue[iv],gauss); 4135 } 4136 } 4137 else{ 4138 for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue; 4139 } 4140 4141 /*clean-up*/ 4142 delete gauss; 4143 } 4144 /*}}}*/ 4145 /*FUNCTION Penta::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/ 4146 void Penta::GetParameterValue(double* pvalue,Node* node,int enumtype){ 4147 4148 Input* input=inputs->GetInput(enumtype); 4149 if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype)); 4150 4151 GaussPenta* gauss=new GaussPenta(); 4152 gauss->GaussVertex(this->GetNodeIndex(node)); 4153 4154 input->GetParameterValue(pvalue,gauss); 4155 delete gauss; 4156 } 4157 /*}}}*/ 4158 /*FUNCTION Penta::GetPhi {{{1*/ 4159 void Penta::GetPhi(double* phi, double* epsilon, double viscosity){ 4160 /*Compute deformational heating from epsilon and viscosity */ 4161 4162 double epsilon_matrix[3][3]; 4163 double epsilon_eff; 4164 double epsilon_sqr[3][3]; 4165 4166 /* Build epsilon matrix */ 4167 epsilon_matrix[0][0]=*(epsilon+0); 4168 epsilon_matrix[1][0]=*(epsilon+3); 4169 epsilon_matrix[2][0]=*(epsilon+4); 4170 epsilon_matrix[0][1]=*(epsilon+3); 4171 epsilon_matrix[1][1]=*(epsilon+1); 4172 epsilon_matrix[2][1]=*(epsilon+5); 4173 epsilon_matrix[0][2]=*(epsilon+4); 4174 epsilon_matrix[1][2]=*(epsilon+5); 4175 epsilon_matrix[2][2]=*(epsilon+2); 4176 4177 /* Effective value of epsilon_matrix */ 4178 epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2); 4179 epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2); 4180 epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2); 4181 epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2); 4182 epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2); 4183 epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2); 4184 epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2); 4185 epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2); 4186 epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2); 4187 epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5); 4188 4189 /*Phi = Tr(sigma * eps) 4190 * = Tr(sigma'* eps) 4191 * = 2 * eps_eff * sigma'_eff 4192 * = 4 * mu * eps_eff ^2*/ 4193 *phi=4*pow(epsilon_eff,2.0)*viscosity; 4194 } 4195 /*}}}*/ 4196 /*FUNCTION Penta::GetSidList{{{1*/ 4197 void Penta::GetSidList(int* sidlist){ 4198 4199 int i; 4200 for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList(); 4201 4202 } 4203 /*}}}*/ 4204 /*FUNCTION Penta::GetSolutionFromInputs{{{1*/ 4205 void Penta::GetSolutionFromInputs(Vec solution){ 4206 4207 int analysis_type; 4208 4209 /*retrive parameters: */ 4541 /*FUNCTION Penta::GradjDragMacAyeal {{{1*/ 4542 void Penta::GradjDragMacAyeal(Vec gradient){ 4543 4544 /*Gradient is 0 if on shelf or not on bed*/ 4545 if(IsOnShelf() || !IsOnBed()) return; 4546 4547 /*Spawn tria*/ 4548 Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria. 4549 tria->GradjDragMacAyeal(gradient); 4550 delete tria->matice; delete tria; 4551 4552 } /*}}}*/ 4553 /*FUNCTION Penta::GradjDragPattyn {{{1*/ 4554 void Penta::GradjDragPattyn(Vec gradient){ 4555 4556 int i,j,ig; 4557 int drag_type,analysis_type; 4558 int doflist1[NUMVERTICES]; 4559 double vx,vy,lambda,mu,alpha_complement,Jdet; 4560 double bed,thickness,Neff,drag; 4561 double xyz_list[NUMVERTICES][3]; 4562 double xyz_list_tria[NUMVERTICES2D][3]={0.0}; 4563 double dk[NDOF2]; 4564 double grade_g[NUMVERTICES]={0.0}; 4565 double grade_g_gaussian[NUMVERTICES]; 4566 double basis[6]; 4567 Friction* friction=NULL; 4568 GaussPenta *gauss=NULL; 4569 4570 /*Gradient is 0 if on shelf or not on bed*/ 4571 if(IsOnShelf() || !IsOnBed()) return; 4572 4573 /*Retrieve all inputs and parameters*/ 4210 4574 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 4211 4212 /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */ 4213 if (analysis_type==DiagnosticHorizAnalysisEnum){ 4214 int approximation; 4215 inputs->GetParameterValue(&approximation,ApproximationEnum); 4216 if(approximation==StokesApproximationEnum || approximation==NoneApproximationEnum){ 4217 GetSolutionFromInputsDiagnosticStokes(solution); 4218 } 4219 else if (approximation==MacAyealApproximationEnum || approximation==PattynApproximationEnum || approximation==HutterApproximationEnum){ 4220 GetSolutionFromInputsDiagnosticHoriz(solution); 4221 } 4222 else if (approximation==MacAyealPattynApproximationEnum || approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){ 4223 return; //the elements around will create the solution 4224 } 4225 } 4226 else if(analysis_type==DiagnosticHutterAnalysisEnum){ 4227 GetSolutionFromInputsDiagnosticHutter(solution); 4228 } 4229 else if(analysis_type==DiagnosticVertAnalysisEnum){ 4230 GetSolutionFromInputsDiagnosticVert(solution); 4231 } 4232 else if(analysis_type==ThermalAnalysisEnum){ 4233 GetSolutionFromInputsThermal(solution); 4234 } 4235 else if(analysis_type==EnthalpyAnalysisEnum){ 4236 GetSolutionFromInputsEnthalpy(solution); 4237 } 4238 else{ 4239 _error_("analysis: %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); 4240 } 4241 } 4242 /*}}}*/ 4243 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHoriz{{{1*/ 4244 void Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){ 4245 4246 const int numdof=NDOF2*NUMVERTICES; 4247 4248 int i; 4249 int approximation; 4250 int* doflist=NULL; 4251 double vx,vy; 4252 double values[numdof]; 4253 GaussPenta* gauss; 4254 4255 /*Get approximation enum and dof list: */ 4256 inputs->GetParameterValue(&approximation,ApproximationEnum); 4257 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4258 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4259 4260 /*If the element is a coupling, do nothing: every node is also on an other elements 4261 * (as coupling is between MacAyeal and Pattyn) so the other element will take care of it*/ 4262 GetDofList(&doflist,approximation,GsetEnum); 4263 4264 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4265 /*P1 element only for now*/ 4266 gauss=new GaussPenta(); 4267 for(i=0;i<NUMVERTICES;i++){ 4268 4269 /*Recover vx and vy*/ 4270 gauss->GaussVertex(i); 4575 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES); 4576 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<2;j++) xyz_list_tria[i][j]=xyz_list[i][j]; 4577 GetDofList1(&doflist1[0]); 4578 Input* adjointx_input=inputs->GetInput(AdjointxEnum); _assert_(adjointx_input); 4579 Input* adjointy_input=inputs->GetInput(AdjointyEnum); _assert_(adjointy_input); 4580 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4581 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4582 Input* dragcoefficient_input=inputs->GetInput(DragCoefficientEnum); _assert_(dragcoefficient_input); 4583 4584 /*Build frictoin element, needed later: */ 4585 inputs->GetParameterValue(&drag_type,DragTypeEnum); 4586 friction=new Friction("2d",inputs,matpar,analysis_type); 4587 4588 /* Start looping on the number of gaussian points: */ 4589 gauss=new GaussPenta(0,1,2,4); 4590 for (ig=gauss->begin();ig<gauss->end();ig++){ 4591 4592 gauss->GaussPoint(ig); 4593 4594 GetTriaJacobianDeterminant(&Jdet, &xyz_list_tria[0][0],gauss); 4595 GetNodalFunctionsP1(basis, gauss); 4596 4597 /*Build alpha_complement_list: */ 4598 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum); 4599 else alpha_complement=0; 4600 4601 dragcoefficient_input->GetParameterValue(&drag, gauss); 4602 adjointx_input->GetParameterValue(&lambda, gauss); 4603 adjointy_input->GetParameterValue(&mu, gauss); 4271 4604 vx_input->GetParameterValue(&vx,gauss); 4272 4605 vy_input->GetParameterValue(&vy,gauss); 4273 values[i*NDOF2+0]=vx; 4274 values[i*NDOF2+1]=vy; 4275 } 4276 4277 /*Add value to global vector*/ 4278 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4279 4280 /*Free ressources:*/ 4606 dragcoefficient_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss); 4607 4608 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */ 4609 for (i=0;i<NUMVERTICES;i++){ 4610 grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss->weight*basis[i]; /*basis are 0 for the 3 upper nodes*/ 4611 } 4612 4613 /*Add gradje_g_gaussian vector to gradje_g: */ 4614 for(i=0;i<NUMVERTICES;i++){ 4615 _assert_(!isnan(grade_g[i])); 4616 grade_g[i]+=grade_g_gaussian[i]; 4617 } 4618 } 4619 VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES); 4620 4621 /*Clean up and return*/ 4281 4622 delete gauss; 4282 xfree((void**)&doflist); 4283 } 4284 /*}}}*/ 4285 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHutter{{{1*/ 4286 void Penta::GetSolutionFromInputsDiagnosticHutter(Vec solution){ 4287 4288 const int numdof=NDOF2*NUMVERTICES; 4289 4290 int i; 4291 int* doflist=NULL; 4292 double vx,vy; 4293 double values[numdof]; 4294 GaussPenta* gauss=NULL; 4295 4296 /*Get dof list: */ 4297 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4298 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4299 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4300 4301 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4302 /*P1 element only for now*/ 4303 gauss=new GaussPenta(); 4304 for(i=0;i<NUMVERTICES;i++){ 4305 /*Recover vx and vy*/ 4306 gauss->GaussVertex(i); 4307 vx_input->GetParameterValue(&vx,gauss); 4308 vy_input->GetParameterValue(&vy,gauss); 4309 values[i*NDOF2+0]=vx; 4310 values[i*NDOF2+1]=vy; 4311 } 4312 4313 /*Add value to global vector*/ 4314 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4315 4316 /*Free ressources:*/ 4623 delete friction; 4624 } 4625 /*}}}*/ 4626 /*FUNCTION Penta::GradjDragStokes {{{1*/ 4627 void Penta::GradjDragStokes(Vec gradient){ 4628 4629 int i,j,ig; 4630 int drag_type,analysis_type; 4631 int doflist1[NUMVERTICES]; 4632 double bed,thickness,Neff; 4633 double lambda,mu,xi,Jdet,vx,vy,vz; 4634 double alpha_complement,drag; 4635 double surface_normal[3],bed_normal[3]; 4636 double xyz_list[NUMVERTICES][3]; 4637 double xyz_list_tria[NUMVERTICES2D][3]={0.0}; 4638 double dk[NDOF2]; 4639 double basis[6]; 4640 double grade_g[NUMVERTICES]={0.0}; 4641 double grade_g_gaussian[NUMVERTICES]; 4642 Friction* friction=NULL; 4643 GaussPenta* gauss=NULL; 4644 4645 /*Gradient is 0 if on shelf or not on bed*/ 4646 if(IsOnShelf() || !IsOnBed()) return; 4647 4648 /*Retrieve all inputs and parameters*/ 4649 parameters->FindParam(&analysis_type,AnalysisTypeEnum); 4650 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES); 4651 for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<2;j++) xyz_list_tria[i][j]=xyz_list[i][j]; 4652 GetDofList1(&doflist1[0]); 4653 inputs->GetParameterValue(&drag_type,DragTypeEnum); 4654 Input* drag_input =inputs->GetInput(DragCoefficientEnum); _assert_(drag_input); 4655 Input* vx_input =inputs->GetInput(VxEnum); _assert_(vx_input); 4656 Input* vy_input =inputs->GetInput(VyEnum); _assert_(vy_input); 4657 Input* vz_input =inputs->GetInput(VzEnum); _assert_(vz_input); 4658 Input* adjointx_input=inputs->GetInput(AdjointxEnum); _assert_(adjointx_input); 4659 Input* adjointy_input=inputs->GetInput(AdjointyEnum); _assert_(adjointy_input); 4660 Input* adjointz_input=inputs->GetInput(AdjointzEnum); _assert_(adjointz_input); 4661 4662 /*Build frictoin element, needed later: */ 4663 inputs->GetParameterValue(&drag_type,DragTypeEnum); 4664 friction=new Friction("2d",inputs,matpar,analysis_type); 4665 4666 /* Start looping on the number of gaussian points: */ 4667 gauss=new GaussPenta(0,1,2,4); 4668 for(ig=gauss->begin();ig<gauss->end();ig++){ 4669 4670 gauss->GaussPoint(ig); 4671 4672 /*Recover alpha_complement and drag: */ 4673 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum); 4674 else alpha_complement=0; 4675 drag_input->GetParameterValue(&drag,gauss); 4676 4677 /*recover lambda mu and xi: */ 4678 adjointx_input->GetParameterValue(&lambda,gauss); 4679 adjointy_input->GetParameterValue(&mu ,gauss); 4680 adjointz_input->GetParameterValue(&xi ,gauss); 4681 4682 /*recover vx vy and vz: */ 4683 vx_input->GetParameterValue(&vx, gauss); 4684 vy_input->GetParameterValue(&vy, gauss); 4685 vz_input->GetParameterValue(&vz, gauss); 4686 4687 /*Get normal vector to the bed */ 4688 SurfaceNormal(&surface_normal[0],xyz_list_tria); 4689 4690 bed_normal[0]=-surface_normal[0]; //Function is for upper surface, so the normal to the bed is the opposite of the result 4691 bed_normal[1]=-surface_normal[1]; 4692 bed_normal[2]=-surface_normal[2]; 4693 4694 /* Get Jacobian determinant: */ 4695 GetTriaJacobianDeterminant(&Jdet,&xyz_list_tria[0][0],gauss); 4696 GetNodalFunctionsP1(basis, gauss); 4697 4698 /*Get k derivative: dk/dx */ 4699 drag_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss); 4700 4701 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */ 4702 for (i=0;i<NUMVERTICES;i++){ 4703 //standard gradient dJ/dki 4704 grade_g_gaussian[i]=( 4705 -lambda*(2*drag*alpha_complement*(vx - vz*bed_normal[0]*bed_normal[2])) 4706 -mu *(2*drag*alpha_complement*(vy - vz*bed_normal[1]*bed_normal[2])) 4707 -xi *(2*drag*alpha_complement*(-vx*bed_normal[0]*bed_normal[2]-vy*bed_normal[1]*bed_normal[2])) 4708 )*Jdet*gauss->weight*basis[i]; 4709 } 4710 4711 /*Add gradje_g_gaussian vector to gradje_g: */ 4712 for( i=0; i<NUMVERTICES; i++)grade_g[i]+=grade_g_gaussian[i]; 4713 } 4714 4715 VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES); 4716 4717 delete friction; 4317 4718 delete gauss; 4318 xfree((void**)&doflist); 4319 } 4320 /*}}}*/ 4321 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticVert{{{1*/ 4322 void Penta::GetSolutionFromInputsDiagnosticVert(Vec solution){ 4323 4324 const int numdof=NDOF1*NUMVERTICES; 4325 4326 int i; 4327 int* doflist=NULL; 4328 double vz; 4329 double values[numdof]; 4330 GaussPenta* gauss=NULL; 4331 4332 /*Get dof list: */ 4333 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4334 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input); 4335 4336 /*Ok, we have vx and vy in values, fill in vx and vy arrays: */ 4337 /*P1 element only for now*/ 4338 gauss=new GaussPenta(); 4339 for(i=0;i<NUMVERTICES;i++){ 4340 /*Recover vz */ 4341 gauss->GaussVertex(i); 4342 vz_input->GetParameterValue(&vz,gauss); 4343 values[i]=vz; 4344 } 4345 4346 /*Add value to global vector*/ 4347 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4348 4349 /*Free ressources:*/ 4350 delete gauss; 4351 xfree((void**)&doflist); 4352 } 4353 /*}}}*/ 4354 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticStokes{{{1*/ 4355 void Penta::GetSolutionFromInputsDiagnosticStokes(Vec solution){ 4356 4357 const int numdof=NDOF4*NUMVERTICES; 4358 4359 int i; 4360 int* doflist=NULL; 4361 double vx,vy,vz,p; 4362 double stokesreconditioning; 4363 double values[numdof]; 4364 GaussPenta *gauss; 4365 4366 /*Get dof list: */ 4367 GetDofList(&doflist,StokesApproximationEnum,GsetEnum); 4368 Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input); 4369 Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input); 4370 Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input); 4371 Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input); 4372 4373 /*Recondition pressure: */ 4374 this->parameters->FindParam(&stokesreconditioning,StokesReconditioningEnum); 4375 4376 /*Ok, we have vx vy vz and P in values, fill in vx vy vz P arrays: */ 4377 /*P1 element only for now*/ 4378 gauss=new GaussPenta(); 4379 for(i=0;i<NUMVERTICES;i++){ 4380 gauss->GaussVertex(i); 4381 vx_input->GetParameterValue(&vx,gauss); 4382 vy_input->GetParameterValue(&vy,gauss); 4383 vz_input->GetParameterValue(&vz,gauss); 4384 p_input ->GetParameterValue(&p ,gauss); 4385 values[i*NDOF4+0]=vx; 4386 values[i*NDOF4+1]=vy; 4387 values[i*NDOF4+2]=vz; 4388 values[i*NDOF4+3]=p/stokesreconditioning; 4389 } 4390 4391 /*Add value to global vector*/ 4392 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4393 4394 /*Free ressources:*/ 4395 delete gauss; 4396 xfree((void**)&doflist); 4397 } 4398 /*}}}*/ 4399 /*FUNCTION Penta::GetSolutionFromInputsThermal{{{1*/ 4400 void Penta::GetSolutionFromInputsThermal(Vec solution){ 4401 4402 const int numdof=NDOF1*NUMVERTICES; 4403 4404 int i; 4405 int* doflist=NULL; 4406 double values[numdof]; 4407 double temp; 4408 GaussPenta *gauss=NULL; 4409 4410 /*Get dof list: */ 4411 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4412 Input* t_input=inputs->GetInput(TemperatureEnum); _assert_(t_input); 4413 4414 gauss=new GaussPenta(); 4415 for(i=0;i<NUMVERTICES;i++){ 4416 /*Recover temperature*/ 4417 gauss->GaussVertex(i); 4418 t_input->GetParameterValue(&temp,gauss); 4419 values[i]=temp; 4420 } 4421 4422 /*Add value to global vector*/ 4423 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4424 4425 /*Free ressources:*/ 4426 delete gauss; 4427 xfree((void**)&doflist); 4428 } 4429 /*}}}*/ 4430 /*FUNCTION Penta::GetSolutionFromInputsEnthalpy{{{1*/ 4431 void Penta::GetSolutionFromInputsEnthalpy(Vec solution){ 4432 4433 const int numdof=NDOF1*NUMVERTICES; 4434 4435 int i; 4436 int* doflist=NULL; 4437 double values[numdof]; 4438 double enthalpy; 4439 GaussPenta *gauss=NULL; 4440 4441 /*Get dof list: */ 4442 GetDofList(&doflist,NoneApproximationEnum,GsetEnum); 4443 Input* h_input=inputs->GetInput(EnthalpyEnum); _assert_(h_input); 4444 4445 gauss=new GaussPenta(); 4446 for(i=0;i<NUMVERTICES;i++){ 4447 /*Recover temperature*/ 4448 gauss->GaussVertex(i); 4449 h_input->GetParameterValue(&enthalpy,gauss); 4450 values[i]=enthalpy; 4451 } 4452 4453 /*Add value to global vector*/ 4454 VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES); 4455 4456 /*Free ressources:*/ 4457 delete gauss; 4458 xfree((void**)&doflist); 4459 } 4460 /*}}}*/ 4461 /*FUNCTION Penta::GetStabilizationParameter {{{1*/ 4462 double Penta::GetStabilizationParameter(double u, double v, double w, double diameter, double rho_ice, double heatcapacity, double thermalconductivity){ 4463 /*Compute stabilization parameter*/ 4464 4465 double normu; 4466 double tau_parameter; 4467 4468 normu=pow(pow(u,2)+pow(v,2)+pow(w,2),0.5); 4469 if(normu*diameter/(3*2*thermalconductivity/(rho_ice*heatcapacity))<1){ 4470 tau_parameter=pow(diameter,2)/(3*2*2*thermalconductivity/(rho_ice*heatcapacity)); 4471 } 4472 else tau_parameter=diameter/(2*normu); 4473 4474 return tau_parameter; 4475 } 4476 /*}}}*/ 4477 /*FUNCTION Penta::GetStrainRate3dPattyn{{{1*/ 4478 void Penta::GetStrainRate3dPattyn(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input){ 4479 /*Compute the 3d Blatter/PattynStrain Rate (5 components): 4480 * 4481 * epsilon=[exx eyy exy exz eyz] 4482 * 4483 * with exz=1/2 du/dz 4484 * eyz=1/2 dv/dz 4485 * 4486 * the contribution of vz is neglected 4487 */ 4488 4489 int i; 4490 double epsilonvx[5]; 4491 double epsilonvy[5]; 4492 4493 /*Check that both inputs have been found*/ 4494 if (!vx_input || !vy_input){ 4495 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input); 4496 } 4497 4498 /*Get strain rate assuming that epsilon has been allocated*/ 4499 vx_input->GetVxStrainRate3dPattyn(epsilonvx,xyz_list,gauss); 4500 vy_input->GetVyStrainRate3dPattyn(epsilonvy,xyz_list,gauss); 4501 4502 /*Sum all contributions*/ 4503 for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]; 4504 } 4505 /*}}}*/ 4506 /*FUNCTION Penta::GetStrainRate3d{{{1*/ 4507 void Penta::GetStrainRate3d(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input){ 4508 /*Compute the 3d Strain Rate (6 components): 4509 * 4510 * epsilon=[exx eyy ezz exy exz eyz] 4511 */ 4512 4513 int i; 4514 double epsilonvx[6]; 4515 double epsilonvy[6]; 4516 double epsilonvz[6]; 4517 4518 /*Check that both inputs have been found*/ 4519 if (!vx_input || !vy_input || !vz_input){ 4520 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p, vz: %p\n",vx_input,vy_input,vz_input); 4521 } 4522 4523 /*Get strain rate assuming that epsilon has been allocated*/ 4524 vx_input->GetVxStrainRate3d(epsilonvx,xyz_list,gauss); 4525 vy_input->GetVyStrainRate3d(epsilonvy,xyz_list,gauss); 4526 vz_input->GetVzStrainRate3d(epsilonvz,xyz_list,gauss); 4527 4528 /*Sum all contributions*/ 4529 for(i=0;i<6;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]+epsilonvz[i]; 4530 } 4531 /*}}}*/ 4532 /*FUNCTION Penta::GetUpperElement{{{1*/ 4533 Penta* Penta::GetUpperElement(void){ 4534 4535 Penta* upper_penta=NULL; 4536 4537 upper_penta=(Penta*)verticalneighbors[1]; //first one under, second one above 4538 4539 return upper_penta; 4540 } 4541 /*}}}*/ 4542 /*FUNCTION Penta::GetVectorFromInputs{{{1*/ 4543 void Penta::GetVectorFromInputs(Vec vector,int input_enum){ 4544 4545 int doflist1[NUMVERTICES]; 4546 4547 /*Get out if this is not an element input*/ 4548 if (!IsInput(input_enum)) return; 4549 4550 /*Prepare index list*/ 4551 this->GetDofList1(&doflist1[0]); 4552 4553 /*Get input (either in element or material)*/ 4554 Input* input=inputs->GetInput(input_enum); 4555 if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum)); 4556 4557 /*We found the enum. Use its values to fill into the vector, using the vertices ids: */ 4558 input->GetVectorFromInputs(vector,&doflist1[0]); 4559 } 4560 /*}}}*/ 4561 /*FUNCTION Penta::GetZcoord {{{1*/ 4562 double Penta::GetZcoord(GaussPenta* gauss){ 4563 4564 int i; 4565 double z; 4566 double xyz_list[NUMVERTICES][3]; 4567 double z_list[NUMVERTICES]; 4568 4569 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES); 4570 for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2]; 4571 PentaRef::GetParameterValue(&z,z_list,gauss); 4572 4573 return z; 4574 } 4575 /*}}}*/ 4719 } 4720 /*}}}*/ 4721 /*FUNCTION Penta::GradjBbarMacAyeal {{{1*/ 4722 void Penta::GradjBbarMacAyeal(Vec gradient){ 4723 4724 /*This element should be collapsed into a tria element at its base*/ 4725 if (!IsOnBed()) return; 4726 4727 /*Depth Average B*/ 4728 this->InputDepthAverageAtBase(RheologyBEnum,RheologyBbarEnum,MaterialsEnum); 4729 4730 /*Collapse element to the base*/ 4731 Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face). 4732 tria->GradjBMacAyeal(gradient); 4733 delete tria->matice; delete tria; 4734 4735 /*delete Average B*/ 4736 this->matice->inputs->DeleteInput(RheologyBbarEnum); 4737 4738 } /*}}}*/ 4739 /*FUNCTION Penta::GradjBbarPattyn {{{1*/ 4740 void Penta::GradjBbarPattyn(Vec gradient){ 4741 4742 /*Gradient is computed on bed only (Bbar)*/ 4743 if (!IsOnBed()) return; 4744 4745 /*Depth Average B*/ 4746 this->InputDepthAverageAtBase(RheologyBEnum,RheologyBbarEnum,MaterialsEnum); 4747 4748 /*Collapse element to the base*/ 4749 Tria* tria=(Tria*)SpawnTria(0,1,2); 4750 tria->GradjBMacAyeal(gradient); //We use MacAyeal as an estimate for now 4751 delete tria->matice; delete tria; 4752 4753 /*delete Average B*/ 4754 this->matice->inputs->DeleteInput(RheologyBbarEnum); 4755 } /*}}}*/ 4756 /*FUNCTION Penta::GradjBbarStokes {{{1*/ 4757 void Penta::GradjBbarStokes(Vec gradient){ 4758 4759 /*Gradient is computed on bed only (Bbar)*/ 4760 if (!IsOnBed()) return; 4761 4762 /*Depth Average B*/ 4763 this->InputDepthAverageAtBase(RheologyBEnum,RheologyBbarEnum,MaterialsEnum); 4764 4765 /*Collapse element to the base*/ 4766 Tria* tria=(Tria*)SpawnTria(0,1,2); 4767 tria->GradjBMacAyeal(gradient); //We use MacAyeal as an estimate for now 4768 delete tria->matice; delete tria; 4769 4770 /*delete Average B*/ 4771 this->matice->inputs->DeleteInput(RheologyBbarEnum); 4772 } /*}}}*/ 4576 4773 /*FUNCTION Penta::Sid {{{1*/ 4577 4774 int Penta::Sid(){ -
issm/trunk/src/c/objects/Elements/Penta.h
r8647 r8654 88 88 void GetVectorFromInputs(Vec vector,int NameEnum); 89 89 void Gradj(Vec gradient,int control_type); 90 void GradjDragMacAyeal(Vec gradient); 91 void GradjDragPattyn(Vec gradient); 92 void GradjDragStokes(Vec gradient); 93 void GradjBbarMacAyeal(Vec gradient); 94 void GradjBbarPattyn(Vec gradient); 95 void GradjBbarStokes(Vec gradient); 90 96 int Sid(); 91 97 void InputControlUpdate(double scalar,bool save_parameter); -
issm/trunk/src/c/objects/Elements/PentaRef.cpp
r8653 r8654 1044 1044 *Jdet=SQRT3/6.0*pow(pow(((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)),2.0)+pow(((z2-z1)*(x3-x1)-(x2-x1)*(z3-z1)),2.0)+pow(((x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)),2.0),0.5); 1045 1045 if(*Jdet<0) _error_("negative jacobian determinant!"); 1046 1047 1046 } 1048 1047 /*}}}*/ -
issm/trunk/src/c/objects/Elements/Tria.cpp
r8653 r8654 2993 2993 double xyz_list[NUMVERTICES][3]; 2994 2994 double basis[3],epsilon[3]; 2995 double dbasis[NDOF2][NUMVERTICES];2996 2995 double grad[NUMVERTICES]={0.0}; 2997 2996 GaussTria *gauss = NULL; … … 3027 3026 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss); 3028 3027 GetNodalFunctions(basis,gauss); 3029 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);3030 3028 3031 3029 /*standard gradient dJ/dki*/ … … 3050 3048 double bed,thickness,Neff,drag; 3051 3049 double xyz_list[NUMVERTICES][3]; 3052 double dbasis[NDOF2][NUMVERTICES];3053 3050 double dk[NDOF2]; 3054 3051 double grade_g[NUMVERTICES]={0.0}; … … 3085 3082 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss); 3086 3083 GetNodalFunctions(basis, gauss); 3087 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);3088 3084 3089 3085 /*Build alpha_complement_list: */ … … 3109 3105 } 3110 3106 } 3111 3112 3107 VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES); 3113 3108 … … 3115 3110 delete gauss; 3116 3111 delete friction; 3117 }3118 /*}}}*/3119 /*FUNCTION Tria::GradjDragStokes {{{1*/3120 void Tria::GradjDragStokes(Vec gradient){3121 3122 int i,ig;3123 int drag_type,analysis_type;3124 int doflist1[NUMVERTICES];3125 double bed,thickness,Neff;3126 double lambda,mu,xi,Jdet,vx,vy,vz;3127 double alpha_complement,drag;3128 double surface_normal[3],bed_normal[3];3129 double xyz_list[NUMVERTICES][3];3130 double dbasis[NDOF2][NUMVERTICES];3131 double dk[NDOF2];3132 double basis[3];3133 double epsilon[3]; /* epsilon=[exx,eyy,exy];*/3134 double grade_g[NUMVERTICES]={0.0};3135 double grade_g_gaussian[NUMVERTICES];3136 Friction* friction=NULL;3137 GaussTria* gauss=NULL;3138 3139 /*retrive parameters: */3140 parameters->FindParam(&analysis_type,AnalysisTypeEnum);3141 3142 /*retrieve inputs :*/3143 inputs->GetParameterValue(&drag_type,DragTypeEnum);3144 Input* drag_input =inputs->GetInput(DragCoefficientEnum); _assert_(drag_input);3145 Input* vx_input =inputs->GetInput(VxEnum); _assert_(vx_input);3146 Input* vy_input =inputs->GetInput(VyEnum); _assert_(vy_input);3147 Input* vz_input =inputs->GetInput(VzEnum); _assert_(vz_input);3148 Input* adjointx_input=inputs->GetInput(AdjointxEnum); _assert_(adjointx_input);3149 Input* adjointy_input=inputs->GetInput(AdjointyEnum); _assert_(adjointy_input);3150 Input* adjointz_input=inputs->GetInput(AdjointzEnum); _assert_(adjointz_input);3151 3152 /*Get out if shelf*/3153 if(IsOnShelf())return;3154 3155 /* Get node coordinates and dof list: */3156 GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);3157 GetDofList1(&doflist1[0]);3158 3159 /*Build frictoin element, needed later: */3160 inputs->GetParameterValue(&drag_type,DragTypeEnum);3161 friction=new Friction("2d",inputs,matpar,analysis_type);3162 3163 /* Start looping on the number of gaussian points: */3164 gauss=new GaussTria(4);3165 for(ig=gauss->begin();ig<gauss->end();ig++){3166 3167 gauss->GaussPoint(ig);3168 3169 /*Recover alpha_complement and drag: */3170 if (drag_type==2) friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum);3171 else alpha_complement=0;3172 drag_input->GetParameterValue(&drag,gauss);3173 3174 /*recover lambda mu and xi: */3175 adjointx_input->GetParameterValue(&lambda,gauss);3176 adjointy_input->GetParameterValue(&mu ,gauss);3177 adjointz_input->GetParameterValue(&xi ,gauss);3178 3179 /*recover vx vy and vz: */3180 vx_input->GetParameterValue(&vx, gauss);3181 vy_input->GetParameterValue(&vy, gauss);3182 vz_input->GetParameterValue(&vz, gauss);3183 3184 /*Get normal vector to the bed */3185 SurfaceNormal(&surface_normal[0],xyz_list);3186 3187 bed_normal[0]=-surface_normal[0]; //Program is for surface, so the normal to the bed is the opposite of the result3188 bed_normal[1]=-surface_normal[1];3189 bed_normal[2]=-surface_normal[2];3190 3191 /* Get Jacobian determinant: */3192 GetJacobianDeterminant3d(&Jdet, &xyz_list[0][0],gauss);3193 3194 /* Get nodal functions value at gaussian point:*/3195 GetNodalFunctions(basis, gauss);3196 3197 /*Get nodal functions derivatives*/3198 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);3199 3200 /*Get k derivative: dk/dx */3201 drag_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);3202 3203 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */3204 for (i=0;i<NUMVERTICES;i++){3205 //standard gradient dJ/dki3206 grade_g_gaussian[i]=(3207 -lambda*(2*drag*alpha_complement*(vx - vz*bed_normal[0]*bed_normal[2]))3208 -mu *(2*drag*alpha_complement*(vy - vz*bed_normal[1]*bed_normal[2]))3209 -xi *(2*drag*alpha_complement*(-vx*bed_normal[0]*bed_normal[2]-vy*bed_normal[1]*bed_normal[2]))3210 )*Jdet*gauss->weight*basis[i];3211 }3212 3213 /*Add gradje_g_gaussian vector to gradje_g: */3214 for( i=0; i<NUMVERTICES; i++)grade_g[i]+=grade_g_gaussian[i];3215 }3216 3217 VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);3218 3219 delete friction;3220 delete gauss;3221 3112 } 3222 3113 /*}}}*/ … … 3290 3181 double thickness,Jdet; 3291 3182 double basis[3]; 3292 double dbasis[NDOF2][NUMVERTICES];3293 3183 double Dlambda[2],dp[2]; 3294 3184 double xyz_list[NUMVERTICES][3]; … … 3312 3202 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss); 3313 3203 GetNodalFunctions(basis, gauss); 3314 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);3315 3204 3316 3205 adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss); … … 3335 3224 double thickness,Jdet; 3336 3225 double basis[3]; 3337 double dbasis[NDOF2][NUMVERTICES];3338 3226 double Dlambda[2],dp[2]; 3339 3227 double xyz_list[NUMVERTICES][3]; … … 3357 3245 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss); 3358 3246 GetNodalFunctions(basis, gauss); 3359 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);3360 3247 3361 3248 adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss); … … 5371 5258 double xyz_list[NUMVERTICES][3]; 5372 5259 GaussTria *gauss = NULL; 5373 double dbasis[NDOF2][NUMVERTICES];5374 5260 double dH[2]; 5375 5261 … … 5391 5277 /* Get Jacobian determinant: */ 5392 5278 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss); 5393 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);5394 5279 5395 5280 /*Get parameters at gauss point*/ -
issm/trunk/src/c/objects/Loads/Friction.cpp
r8224 r8654 185 185 } 186 186 /*}}}*/ 187 /*FUNCTION Friction::GetAlphaComplement {{{1*/187 /*FUNCTION Friction::GetAlphaComplement(double* palpha_complement, GaussTria* gauss,int vxenum,int vyenum) {{{1*/ 188 188 void Friction::GetAlphaComplement(double* palpha_complement, GaussTria* gauss,int vxenum,int vyenum){ 189 189 … … 239 239 if(vmag==0 && (s-1)<0) _error_("velocity is 0 ans (s-1)=%g<0, alpha_complement is Inf",s-1); 240 240 241 alpha_complement=pow(Neff,r)*pow(vmag,(s-1)); 242 _assert_(!isnan(alpha_complement)); 241 alpha_complement=pow(Neff,r)*pow(vmag,(s-1)); _assert_(!isnan(alpha_complement)); 243 242 244 243 /*Assign output pointers:*/ 245 244 *palpha_complement=alpha_complement; 246 245 } 246 /*}}}*/ 247 /*FUNCTION Friction::GetAlphaComplement(double* palpha_complement, GaussPenta* gauss,int vxenum,int vyenum) {{{1*/ 248 void Friction::GetAlphaComplement(double* palpha_complement, GaussPenta* gauss,int vxenum,int vyenum){ 249 250 /* FrictionGetAlpha2 computes alpha2= drag^2 * Neff ^r * vel ^s, with Neff=rho_ice*g*thickness+rho_ice*g*bed, r=q/p and s=1/p. 251 * FrictionGetAlphaComplement is used in control methods on drag, and it computes: 252 * alpha_complement= Neff ^r * vel ^s*/ 253 254 /*diverse: */ 255 int i; 256 double Neff; 257 double r,s; 258 double vx; 259 double vy; 260 double vmag; 261 double drag_p,drag_q; 262 double drag_coefficient; 263 double bed,thickness; 264 double gravity,rho_ice,rho_water; 265 double alpha_complement; 266 267 /*Recover parameters: */ 268 inputs->GetParameterValue(&drag_p,DragPEnum); 269 inputs->GetParameterValue(&drag_q,DragQEnum); 270 this->GetParameterValue(&thickness, gauss,ThicknessEnum); 271 this->GetParameterValue(&bed, gauss,BedEnum); 272 this->GetParameterValue(&drag_coefficient, gauss,DragCoefficientEnum); 273 274 /*Get material parameters: */ 275 gravity=matpar->GetG(); 276 rho_ice=matpar->GetRhoIce(); 277 rho_water=matpar->GetRhoWater(); 278 279 280 //compute r and q coefficients: */ 281 r=drag_q/drag_p; 282 s=1./drag_p; 283 284 //From bed and thickness, compute effective pressure when drag is viscous: 285 Neff=gravity*(rho_ice*thickness+rho_water*bed); 286 287 /*If effective pressure becomes negative, sliding becomes unstable (Paterson 4th edition p 148). This is because 288 the water pressure is so high, the ice sheet elevates over its ice bumps and slides. But the limit behaviour 289 for friction should be an ice shelf sliding (no basal drag). Therefore, for any effective pressure Neff < 0, we should 290 replace it by Neff=0 (ie, equival it to an ice shelf)*/ 291 if (Neff<0)Neff=0; 292 293 //We need the velocity magnitude to evaluate the basal stress: 294 this->GetParameterValue(&vx, gauss,vxenum); 295 this->GetParameterValue(&vy, gauss,vyenum); 296 vmag=sqrt(pow(vx,2)+pow(vy,2)); 297 298 /*Checks that s-1>0 if v=0*/ 299 if(vmag==0 && (s-1)<0) _error_("velocity is 0 ans (s-1)=%g<0, alpha_complement is Inf",s-1); 300 301 alpha_complement=pow(Neff,r)*pow(vmag,(s-1)); _assert_(!isnan(alpha_complement)); 302 303 /*Assign output pointers:*/ 304 *palpha_complement=alpha_complement; 247 305 } 248 306 /*}}}*/ -
issm/trunk/src/c/objects/Loads/Friction.h
r5749 r8654 30 30 void GetAlpha2(double* palpha2, GaussPenta* gauss,int vxenum,int vyenum,int vzenum); 31 31 void GetAlphaComplement(double* alpha_complement, GaussTria* gauss,int vxenum,int vyenum); 32 void GetAlphaComplement(double* alpha_complement, GaussPenta* gauss,int vxenum,int vyenum); 32 33 void GetParameterValue(double* pvalue,GaussTria* gauss,int enum_type); 33 34 void GetParameterValue(double* pvalue,GaussPenta* gauss,int enum_type);
Note:
See TracChangeset
for help on using the changeset viewer.