8 #include <apfDynamicMatrix.h>
9 #include <apfNumbering.h>
42 inline void getProps(
double*rho,
double*nu,
double deltaT)
58 apf::Matrix3x3 KJtemp(1.0,0.5,0.0,0.5,1.0,0.0,0.0,0.0,1.0);
63 double c1 = pow(2,1./3.);
65 apf::Matrix3x3 KJtemp(c1,c2,c2,c2,c1,c2,c2,c2,c1);
72 if(PCU_Comm_Self()==0)
73 std::cout<<
"The beginning of the VMS\n";
77 nsd = m->getDimension();
82 apf::Field* velf = m->findField(
"velocity");
84 apf::Field* pref = m->findField(
"p");
87 if(m->findField(
"velocity_old")!=NULL)
88 velf_old = m->findField(
"velocity_old");
91 if(PCU_Comm_Self()==0)
92 std::cout<<
"WARNING: old velocity field not found. Will proceed as if unsteady term is 0. \n";
97 if(PCU_Comm_Self()==0)
98 std::cout<<
"Got the solution fields\n";
107 apf::Field* vmsErr = apf::createField(m,
"VMSL2",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
109 vmsErrH1 = apf::createField(m,
"VMSH1",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
111 if(PCU_Comm_Self()==0)
112 std::cout<<
"Created the error fields\n";
121 apf::MeshElement* element;
122 apf::Element* visc_elem, *pres_elem,*velo_elem,*vof_elem,*velo_elem_old;
133 apf::MeshIterator* iter = m->begin(
nsd);
134 apf::MeshEntity* ent;
139 double VMSerrTotalH1 = 0.0;
140 while( (ent = m->iterate(iter)) ){
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);
149 double strongResidualTauL2;
151 double areaCheck=0.0;
152 numqpt=apf::countIntPoints(element,
int_order);
213 qpt[0] = 0.0; qpt[1] = 0.0; qpt[2] = 0.0;
214 for(
int i=0; i<
nsd; i++)
215 qpt[i] = 1./(
nsd+1.0);
233 double tempVal = tempResidual.getLength();
234 apf::getJacobian(element,qpt,J);
238 Jdet=fabs(apf::getJacobianDeterminant(J,
nsd));
239 gij = apf::transpose(invJ)*(KJ*invJ);
243 double VMSerrH1 = nu_err*tempVal*sqrt(apf::measure(m,ent));
245 apf::setScalar(vmsErrH1,ent,0,VMSerrH1);
248 VMSerrTotalH1 = VMSerrTotalH1+VMSerrH1*VMSerrH1;
251 apf::destroyElement(pres_elem);
252 apf::destroyElement(velo_elem);
253 apf::destroyElement(velo_elem_old);
255 apf::destroyMeshElement(element);
260 PCU_Add_Doubles(&VMSerrTotalH1,1);
261 if(PCU_Comm_Self()==0)
262 std::cout<<std::scientific<<std::setprecision(15)<<
"Total Error H1 "<<sqrt(VMSerrTotalH1)<<std::endl;
264 total_error_out = sqrt(VMSerrTotalH1);
265 apf::destroyField(vmsErr);
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++){
275 stabTerm2 += info.
gij[i][j]*info.
gij[i][j];
280 double nu_err = 1.0/sqrt(info.
visc_val*sqrt(stabTerm1) + stabTerm2);
285 apf::Vector3 grad_pres;
286 apf::getGrad(info.
pres_elem,qpt,grad_pres);
288 apf::Vector3 vel_vect;
289 apf::getVector(info.
velo_elem,qpt,vel_vect);
290 apf::Vector3 vel_vect_old;
292 apf::Matrix3x3 grad_vel;
293 apf::getVectorGrad(info.
velo_elem,qpt,grad_vel);
294 grad_vel = apf::transpose(grad_vel);
296 apf::Vector3 tempConv;
297 apf::Vector3 tempDiff;
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];
304 tempConv[i] = tempConv[i] - info.
g[i];
306 apf::Vector3 tempResidual = (tempConv + grad_pres/info.
density);
308 tempResidual = tempResidual + (vel_vect-vel_vect_old)/
dt_err;