proteus 1.9.0
C/C++/Fortran libraries
Loading...
Searching...
No Matches
VMS.cpp
Go to the documentation of this file.
1#include "MeshAdaptPUMI.h"
2#include <PCU.h>
3#include <petscksp.h>
4
5#include <apf.h>
6#include <apfMesh.h>
7#include <apfShape.h>
8#include <apfDynamicMatrix.h>
9#include <apfNumbering.h>
10
11#include <iostream>
12#include <fstream>
13
14//Global variables used to make it easier to pass these variables from MeshAdaptPUMIDrvr
15extern int approx_order; //shape function order
16extern int int_order; //integration order
17extern double nu_0,nu_1,rho_0,rho_1;
18double dt_err;
19
20struct Inputs{
21 apf::Vector3 vel_vect;
22 apf::Matrix3x3 gij;
23 apf::Matrix3x3 grad_vel;
24 apf::Vector3 grad_pres;
25 double visc_val;
26 double density;
27 int nsd;
28 apf::MeshElement* element;
29 apf::Element* pres_elem;
30 //apf::Element* visc_elem;
31 apf::Element* velo_elem;
32 //apf::Element* vof_elem;
33 apf::Element* velo_elem_old;
34 apf::Matrix3x3 KJ;
35 double* g;
36};
37
38double get_nu_err(struct Inputs info);
39apf::Vector3 getResidual(apf::Vector3 qpt,struct Inputs &info);
40
41
42inline void getProps(double*rho,double*nu,double deltaT)
43//Function used to transfer MeshAdaptPUMIDrvr variables into global variables
44{
45 rho_0 = rho[0];
46 nu_0 = nu[0];
47 rho_1 = rho[1];
48 nu_1 = nu[1];
49 dt_err = deltaT;
50 return;
51}
52
53apf::Matrix3x3 getKJ(int nsd)
54{
55//Jacobian correction matrix for proper metric tensor
56 if(nsd==2)
57 {
58 apf::Matrix3x3 KJtemp(1.0,0.5,0.0,0.5,1.0,0.0,0.0,0.0,1.0); //Jacobian correction matrix for proper metric tensor
59 return KJtemp;
60 }
61 else
62 {
63 double c1 = pow(2,1./3.); //1.259921049894873e+00;
64 double c2 = c1/2.0; //6.299605249474365e-01;
65 apf::Matrix3x3 KJtemp(c1,c2,c2,c2,c1,c2,c2,c2,c1);
66 return KJtemp;
67 }
68}
69
70void MeshAdaptPUMIDrvr::get_VMS_error(double &total_error_out)
71{
72 if(PCU_Comm_Self(PCUObj)==0)
73 std::cout<<"The beginning of the VMS\n";
74 getProps(rho,nu,delta_T);
77 nsd = m->getDimension();
78
79 //***** Get Solution Fields First *****//
80 //apf::Field* voff = m->findField("vof");
81 //assert(voff);
82 apf::Field* velf = m->findField("velocity");
83 assert(velf);
84 apf::Field* pref = m->findField("p");
85 assert(pref);
86 apf::Field* velf_old;
87 if(m->findField("velocity_old")!=NULL)
88 velf_old = m->findField("velocity_old");
89 else{
90 velf_old = velf;
91 if(PCU_Comm_Self(PCUObj)==0)
92 std::cout<<"WARNING: old velocity field not found. Will proceed as if unsteady term is 0. \n";
93 dt_err = 1.0;
94 }
95 assert(velf_old);
96 //***** *****//
97 if(PCU_Comm_Self(PCUObj)==0)
98 std::cout<<"Got the solution fields\n";
99 //***** Compute the viscosity field *****//
100/*
101 apf::Field* visc = getViscosityField(voff);
102 if(PCU_Comm_Self(PCUObj)==0)
103 std::cout<<"Got viscosity fields \n";
104*/
105 freeField(vmsErrH1);
106
107 apf::Field* vmsErr = apf::createField(m,"VMSL2",apf::SCALAR,apf::getVoronoiShape(nsd,1));
108 //vmsErrH1 = apf::createField(m,"VMSH1",apf::SCALAR,apf::getVoronoiShape(nsd,1));
109 vmsErrH1 = apf::createField(m,"VMSH1",apf::SCALAR,apf::getVoronoiShape(nsd,1));
110
111 if(PCU_Comm_Self(PCUObj)==0)
112 std::cout<<"Created the error fields\n";
113 //Start computing element quantities
114 int numqpt; //number of quadrature points
115 int nshl; //number of local shape functions
116 int elem_type; //what type of topology
117 double weight; //value container for the weight at each qpt
118 double Jdet;
119 //apf::EntityShape* elem_shape;
120 apf::Vector3 qpt; //container for quadrature points
121 apf::MeshElement* element;
122 apf::Element* visc_elem, *pres_elem,*velo_elem,*vof_elem,*velo_elem_old;
123 apf::Matrix3x3 J; //actual Jacobian matrix
124 apf::Matrix3x3 invJ; //inverse of Jacobian
125 apf::Matrix3x3 KJ = getKJ(nsd);
126 apf::Matrix3x3 gij; //actual Jacobian matrix
127
128
129 //apf::DynamicMatrix invJ_copy;
130 //apf::NewArray <apf::DynamicVector> shdrv;
131 //apf::NewArray <apf::DynamicVector> shgval_copy;
132
133 apf::MeshIterator* iter = m->begin(nsd); //loop over elements
134 apf::MeshEntity* ent;
135
136 int count = 0 ; //for debugging purposes
137 //Loop over elements and compute the VMS error in the L_2 norm
138 //double VMSerrTotalL2 = 0.0;
139 double VMSerrTotalH1 = 0.0;
140 while( (ent = m->iterate(iter)) ){
141
142 element = apf::createMeshElement(m,ent);
143 pres_elem = apf::createElement(pref,element);
144 velo_elem = apf::createElement(velf,element);
145 velo_elem_old = apf::createElement(velf_old,element);
146 //visc_elem = apf::createElement(visc,element);
147 //vof_elem = apf::createElement(voff,element);
148
149 double strongResidualTauL2;
150 double tau_m;
151 double areaCheck=0.0;
152 numqpt=apf::countIntPoints(element,int_order);
153
154/*
155 //Start the quadrature loop
156 for(int k=0;k<numqpt;k++){
157 apf::getIntPoint(element,int_order,k,qpt); //get a quadrature point and store in qpt
158 apf::getJacobian(element,qpt,J); //evaluate the Jacobian at the quadrature point
159 weight = apf::getIntWeight(element,int_order,k);
160 J = apf::transpose(J); //Is PUMI still defined in this way?
161 if(nsd==2)
162 J[2][2] = 1.0; //this is necessary to avoid singular matrix
163 invJ = invert(J);
164 Jdet=fabs(apf::getJacobianDeterminant(J,nsd));
165 gij = apf::transpose(invJ)*(KJ*invJ);
166
167 double pressure = apf::getScalar(pres_elem,qpt);
168 apf::Vector3 grad_pres;
169 apf::getGrad(pres_elem,qpt,grad_pres);
170 double visc_val = apf::getScalar(visc_elem,qpt);
171 apf::Vector3 vel_vect;
172 apf::getVector(velo_elem,qpt,vel_vect);
173 apf::Matrix3x3 grad_vel;
174 apf::getVectorGrad(velo_elem,qpt,grad_vel);
175 grad_vel = apf::transpose(grad_vel);
176
177 double C1 = 2.0; //constants for stabilization term
178 double C2 = 36.0;
179
180 double stabTerm1 = 0.0;
181 double stabTerm2 = 0.0;
182 for(int i=0;i<nsd;i++){
183 for(int j=0;j<nsd;j++){
184 stabTerm1 += vel_vect[i]*gij[i][j]*vel_vect[j];
185 stabTerm2 += gij[i][j]*gij[i][j];
186 }
187 }
188 stabTerm2 = C2*visc_val*visc_val*stabTerm2;
189 tau_m = 1/sqrt(stabTerm1 + stabTerm2);
190
191 //compute residual
192 apf::Vector3 tempConv;
193 apf::Vector3 tempDiff;
194 tempConv.zero();
195 tempDiff.zero();
196 for(int i=0;i<nsd;i++){
197 for(int j=0;j<nsd;j++){
198 tempConv[i] = tempConv[i] + vel_vect[j]*grad_vel[i][j];
199 }
200 }
201 double density = getMPvalue(apf::getScalar(vof_elem,qpt),rho_0,rho_1);
202 apf::Vector3 tempResidual = (tempConv + grad_pres/density);
203 double tempVal = tempResidual.getLength();
204 strongResidualTauL2 = tau_m*tau_m*tempVal*tempVal*weight*Jdet;
205
206 } //end qpt loop
207
208 double VMSerrL2 = sqrt(strongResidualTauL2);
209 apf::setScalar(vmsErr,ent,0,VMSerrL2);
210*/
211
212 //H1 error compute nu_err at centroid and compute residual
213 qpt[0] = 0.0; qpt[1] = 0.0; qpt[2] = 0.0; //ensure it is initialized to 0
214 for(int i=0; i<nsd; i++)
215 qpt[i] = 1./(nsd+1.0);
216
217 //double density = getMPvalue(apf::getScalar(vof_elem,qpt),rho_0,rho_1);
218 double density = rho[localNumber(ent)];
219 Inputs info;
220 info.element = element;
221 info.pres_elem = pres_elem;
222 //info.visc_elem = visc_elem;
223 info.velo_elem = velo_elem;
224 //info.vof_elem = vof_elem;
225 info.velo_elem_old = velo_elem_old;
226 info.KJ = KJ;
227 info.nsd = nsd;
228 info.density = density;
229 info.g = &g[0];
230
231 info.visc_val = nu[localNumber(ent)];
232 apf::Vector3 tempResidual = getResidual(qpt,info);
233 double tempVal = tempResidual.getLength();
234 apf::getJacobian(element,qpt,J);
235 if(nsd==2)
236 J[2][2] = 1.0; //this is necessary to avoid singular matrix
237 invJ = invert(J);
238 Jdet=fabs(apf::getJacobianDeterminant(J,nsd));
239 gij = apf::transpose(invJ)*(KJ*invJ);
240 info.gij = gij;
241
242 double nu_err = get_nu_err(info);
243 double VMSerrH1 = nu_err*tempVal*sqrt(apf::measure(m,ent));
244 //std::cout<<std::scientific<<std::setprecision(15)<<"H1 error for element "<<count<<" nu_err "<<nu_err<<" error "<<VMSerrH1<<std::endl;
245 apf::setScalar(vmsErrH1,ent,0,VMSerrH1);
246
247 //VMSerrTotalL2 = VMSerrTotalL2+VMSerrL2*VMSerrL2;
248 VMSerrTotalH1 = VMSerrTotalH1+VMSerrH1*VMSerrH1;
249
250 //apf::destroyElement(visc_elem);
251 apf::destroyElement(pres_elem);
252 apf::destroyElement(velo_elem);
253 apf::destroyElement(velo_elem_old);
254 //apf::destroyElement(vof_elem);
255 apf::destroyMeshElement(element);
256 count++;
257 } //end loop over elements
258
259 //PCU_Add_Doubles(PCUObj, &VMSerrTotalL2,1);
260 PCU_Add_Doubles(PCUObj, &VMSerrTotalH1,1);
261 if(PCU_Comm_Self(PCUObj)==0)
262 std::cout<<std::scientific<<std::setprecision(15)<<"Total Error H1 "<<sqrt(VMSerrTotalH1)<<std::endl;
263 total_error = sqrt(VMSerrTotalH1);
264 total_error_out = sqrt(VMSerrTotalH1);
265 apf::destroyField(vmsErr);
266 //apf::destroyField(visc);
267} //end function
268
269double get_nu_err(struct Inputs info){
270 double stabTerm1 = 0.0;
271 double stabTerm2 = 0.0;
272 for(int i=0;i<info.nsd;i++){
273 for(int j=0;j<info.nsd;j++){
274 stabTerm1 += info.vel_vect[i]*info.gij[i][j]*info.vel_vect[j];
275 stabTerm2 += info.gij[i][j]*info.gij[i][j];
276 }
277 }
278 double C_nu = 3.0;
279 stabTerm2 = C_nu*info.visc_val*info.visc_val*sqrt(stabTerm2);
280 double nu_err = 1.0/sqrt(info.visc_val*sqrt(stabTerm1) + stabTerm2);
281 return nu_err;
282}
283
284apf::Vector3 getResidual(apf::Vector3 qpt,struct Inputs &info){
285 apf::Vector3 grad_pres;
286 apf::getGrad(info.pres_elem,qpt,grad_pres);
287 //double visc_val = apf::getScalar(info.visc_elem,qpt);
288 apf::Vector3 vel_vect;
289 apf::getVector(info.velo_elem,qpt,vel_vect);
290 apf::Vector3 vel_vect_old;
291 apf::getVector(info.velo_elem_old,qpt,vel_vect_old);
292 apf::Matrix3x3 grad_vel;
293 apf::getVectorGrad(info.velo_elem,qpt,grad_vel);
294 grad_vel = apf::transpose(grad_vel);
295
296 apf::Vector3 tempConv;
297 apf::Vector3 tempDiff;
298 tempConv.zero();
299 tempDiff.zero();
300 for(int i=0;i<info.nsd;i++){
301 for(int j=0;j<info.nsd;j++){
302 tempConv[i] = tempConv[i] + vel_vect[j]*grad_vel[i][j];
303 }
304 tempConv[i] = tempConv[i] - info.g[i]; //body force contribution
305 }
306 apf::Vector3 tempResidual = (tempConv + grad_pres/info.density);
307 //acceleration term
308 tempResidual = tempResidual + (vel_vect-vel_vect_old)/dt_err;
309 //std::cout<<"What is the acceleration contribution? "<<(vel_vect-vel_vect_old)/dt_err<<std::endl;
310
311 info.vel_vect = vel_vect;
312 info.grad_vel = grad_vel;
313 //info.visc_val = visc_val;
314 info.grad_pres = grad_pres;
315
316 return tempResidual;
317}
void getProps(double *rho, double *nu)
int approx_order
double nu_0
double rho_1
int int_order
double nu_1
double rho_0
double get_nu_err(struct Inputs info)
Definition VMS.cpp:269
apf::Vector3 getResidual(apf::Vector3 qpt, struct Inputs &info)
Definition VMS.cpp:284
apf::Matrix3x3 getKJ(int nsd)
Definition VMS.cpp:53
double dt_err
Definition VMS.cpp:18
int localNumber(apf::MeshEntity *e)
void get_VMS_error(double &total_error_out)
Definition VMS.cpp:70
Definition VMS.cpp:20
apf::Matrix3x3 KJ
Definition VMS.cpp:34
apf::Element * pres_elem
Definition VMS.cpp:29
apf::Vector3 vel_vect
Definition VMS.cpp:21
apf::MeshElement * element
Definition VMS.cpp:28
apf::Matrix3x3 gij
Definition VMS.cpp:22
apf::Matrix3x3 grad_vel
Definition VMS.cpp:23
int nsd
Definition VMS.cpp:27
apf::Element * velo_elem_old
Definition VMS.cpp:33
apf::Vector3 grad_pres
Definition VMS.cpp:24
double * g
Definition VMS.cpp:35
double visc_val
Definition VMS.cpp:25
apf::Element * velo_elem
Definition VMS.cpp:31
double density
Definition VMS.cpp:26