8 #include <apfDynamicMatrix.h>
9 #include <apfNumbering.h>
47 return val_0*(1-field_val)+val_1*field_val;
55 mesh->getAdjacent(face,0,verts);
58 for(
int i=0;i<verts.getSize();i++){
59 mesh->getPoint(verts[i],0,vtxs[i]);
62 if(mesh->getDimension()==2){
68 normal = apf::cross(a,b);
70 return normal.normalize();
76 return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
85 temp = temp + a[i][j]*b[i][j];
92 bool isInTet(apf::Mesh* mesh, apf::MeshEntity* ent, apf::Vector3 pt)
99 mesh->getAdjacent(ent,0,verts);
100 apf::Vector3 vtxs[4];
101 for(
int i=0;i<4;i++){
102 mesh->getPoint(verts[i],0,vtxs[i]);
105 c[0] = vtxs[1]-vtxs[0];
106 c[1] = vtxs[2]-vtxs[0];
107 c[2] = vtxs[3]-vtxs[0];
110 apf::Matrix3x3 K,Kinv;
112 for(
int i=0;i<3;i++){
113 for(
int j=0;j<3;j++){
119 apf::DynamicMatrix Kinv_dyn = apf::fromMatrix(Kinv);
120 apf::DynamicVector F_dyn = apf::fromVector(F);
121 apf::DynamicVector uvw;
122 apf::multiply(Kinv_dyn,F_dyn,uvw);
123 if(uvw[0] >= 0 && uvw[1] >=0 && uvw[2] >=0 && (uvw[0]+uvw[1]+uvw[2])<=1) isin = 1;
127 bool isInSimplex(apf::Mesh* mesh, apf::MeshEntity* ent, apf::Vector3 pt,
int dim)
132 int numverts = dim+1;
134 mesh->getAdjacent(ent,0,verts);
135 apf::Vector3 vtxs[4];
136 for(
int i=0;i<numverts;i++){
137 mesh->getPoint(verts[i],0,vtxs[i]);
141 c[0] = vtxs[1]-vtxs[0];
142 c[1] = vtxs[2]-vtxs[0];
146 c[0] = vtxs[1]-vtxs[0];
147 c[1] = vtxs[2]-vtxs[0];
148 c[2] = vtxs[3]-vtxs[0];
152 apf::Matrix3x3 K(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
154 apf::Vector3 F(0.0,0.0,0.0);
155 for(
int i=0;i<dim;i++){
156 for(
int j=0;j<dim;j++){
164 apf::DynamicMatrix Kinv_dyn = apf::fromMatrix(Kinv);
165 apf::DynamicVector F_dyn = apf::fromVector(F);
166 apf::DynamicVector uvw;
167 apf::multiply(Kinv_dyn,F_dyn,uvw);
169 if(uvw[0] >= 0 && uvw[1] >=0 && (uvw[0]+uvw[1])<=1) isin = 1;
172 if(uvw[0] >= 0 && uvw[1] >=0 && uvw[2] >=0 && (uvw[0]+uvw[1]+uvw[2])<=1) isin = 1;
197 void getLHS(Mat &K,apf::NewArray <apf::DynamicVector> &shdrv,
int nsd,
double weight,
double visc_val,
int nshl)
209 PetscScalar term1[nshl][nshl], term2[nshl][nshl];
211 for(
int s=0;
s<nshl;
s++){
212 for(
int t=0; t<nshl;t++){
214 for(
int j=0;j<nsd;j++){
215 temp+=shdrv[
s][j]*shdrv[t][j];
217 term1[
s][t] = temp*weight*visc_val;
221 for(
int i=0; i<nsd;i++){
222 for(
int j=0;j<nshl;j++){
225 MatSetValues(K,nshl,idx,nshl,idx,term1[0],ADD_VALUES);
227 int idxr[nshl],idxc[nshl];
228 for(
int i = 0; i< nsd;i++){
229 for(
int j=0; j< nsd;j++){
230 for(
int s=0;
s<nshl;
s++){
231 for(
int t=0;t<nshl;t++){
232 term2[
s][t] = shdrv[
s][j]*shdrv[t][i]*weight*visc_val;
235 for(
int count=0;count<nshl;count++){
236 idxr[count] = i*nshl+count;
237 idxc[count] = j*nshl+count;
239 MatSetValues(K,nshl,idxr,nshl,idxc,term2[0],ADD_VALUES);
244 void getRHS(Vec &F,apf::NewArray <double> &shpval,apf::NewArray <apf::DynamicVector> &shdrv,apf::Vector3 vel_vect,apf::Matrix3x3 grad_vel,
245 int nsd,
double weight,
int nshl,
246 double visc_val,
double density,apf::Vector3 grad_density,
double pressure,
268 for(
int i = 0; i<nsd; i++){
269 double temp_vect[nshl];
270 for(
int s=0;
s<nshl;
s++){
276 double force = (g[i]+0.0)*shpval[
s];
277 double pressure_force = pressure/density*shdrv[
s][i];
278 double a_rho_term = 0;
279 double b_rho_term = -pressure/(density*density)*grad_density[i]*shpval[
s];
283 for(
int j=0;j<nsd;j++){
284 a_term += -visc_val*shdrv[
s][j]*(grad_vel[i][j]+grad_vel[j][i]);
285 a_rho_term += visc_val*(grad_vel[i][j]+grad_vel[j][i])*shpval[
s]*grad_density[j]/(density);
286 c_term += -shpval[
s]*grad_vel[i][j]*vel_vect[j];
288 temp_vect[
s] = force+pressure_force+a_term+c_term;
290 temp_vect[
s] = temp_vect[
s]*weight;
292 VecSetValues(F,nshl,idx,temp_vect,ADD_VALUES);
314 std::cerr<<
"Begin computeDiffusiveFlux()"<<std::endl;
321 apf::MeshEntity* bent,*ent;
322 apf::MeshIterator* iter = m->begin(
nsd-1);
325 while(bent = m->iterate(iter)){
326 apf::MeshElement* b_elem;
327 b_elem = apf::createMeshElement(m,bent);
328 numbqpt = apf::countIntPoints(b_elem,
int_order);
329 apf::destroyMeshElement(b_elem);
334 diffFlux = m->createDoubleTag(
"diffFlux",numbqpt*
nsd*2);
335 apf::MeshElement* tempelem; apf::Element * tempvelo,*temppres,*tempvoff;
336 apf::MeshElement* b_elem;
337 apf::Adjacent adjFaces;
338 apf::Vector3 normal,centerdir;
340 double tempflux[numbqpt*
nsd];
341 double *flux; flux = (
double*) calloc(numbqpt*
nsd*2,
sizeof(
double));
342 apf::NewArray <double> shpval;
343 apf::NewArray <double> shpval_temp;
345 apf::FieldShape* err_shape = apf::getHierarchic(2);
346 apf::EntityShape* elem_shape;
347 apf::Vector3 bqpt,bqptl,bqptshp;
350 apf::Matrix3x3 tempgrad_velo;
351 apf::Matrix3x3 identity(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0);
353 iter=m->begin(
nsd-1);
354 while(ent=m->iterate(iter))
356 m->setDoubleTag(ent,diffFlux,flux);
362 std::cerr<<
"Initialized flux"<<std::endl;
365 iter = m->begin(
nsd);
367 while(ent = m->iterate(iter))
371 nshl=apf::countElementNodes(err_shape,m->getType(ent));
372 shpval_temp.allocate(nshl);
374 shpval.allocate(nshl);
375 elem_shape = err_shape->getEntityShape(m->getType(ent));
378 m->getAdjacent(ent,
nsd-1,adjFaces);
379 for(
int adjcount =0;adjcount<adjFaces.getSize();adjcount++){
380 bent = adjFaces[adjcount];
382 centerdir=apf::getLinearCentroid(m,ent)-apf::getLinearCentroid(m,bent);
384 if(
isInSimplex(m,ent,apf::project(normal,centerdir).normalize()*centerdir.getLength()+apf::getLinearCentroid(m,bent),
nsd)){
392 b_elem = apf::createMeshElement(m,bent);
393 tempelem = apf::createMeshElement(m,ent);
394 temppres = apf::createElement(pref,tempelem);
395 tempvelo = apf::createElement(velf,tempelem);
396 tempvoff = apf::createElement(voff,tempelem);
398 for(
int l = 0;l<numbqpt;l++)
400 apf::Vector3 bflux(0.0,0.0,0.0);
401 apf::Matrix3x3 tempbflux(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
402 apf::getIntPoint(b_elem,
int_order,l,bqpt);
403 weight = apf::getIntWeight(b_elem,
int_order,l);
404 apf::getJacobian(b_elem,bqpt,J);
405 Jdet=fabs(apf::getJacobianDeterminant(J,
nsd-1));
406 bqptl=apf::boundaryToElementXi(m,bent,ent,bqpt);
407 apf::getVectorGrad(tempvelo,bqptl,tempgrad_velo);
408 tempgrad_velo = apf::transpose(tempgrad_velo);
410 apf::ModelEntity* me=m->toModel(bent);
411 int tag = m->getModelTag(me);
412 apf::ModelEntity* boundary_face = m->findModelEntity(
nsd-1,tag);
414 if(me==boundary_face && has_gBC){
416 double fluxdata[4][numbqpt];
420 m->getIntTag(bent,
BCtag,&(BCtype[0]));
421 if((BCtype[1]+BCtype[2]+BCtype[3] != 3) && BCtype[1] == 1 ){
422 std::cerr <<
"diffusive flux not fully specified on face " <<
localNumber(bent) <<
'\n';
423 std::cerr <<
"BCtype "<<BCtype[1]<<
" "<<BCtype[2]<<
" "<<BCtype[3]<<std::endl;
426 if(BCtype[1]+BCtype[2]+BCtype[3] == 3){
427 for(
int i=1;i<
nsd+1;i++)
428 m->getDoubleTag(bent,
fluxtag[i],&(fluxdata[i][0]));
429 bflux = apf::Vector3(fluxdata[1][l],fluxdata[2][l],fluxdata[3][l]);
430 bflux = bflux-identity*apf::getScalar(temppres,bqptl)/
getMPvalue(apf::getScalar(tempvoff,bqptl),
rho_0,
rho_1)*normal;
433 tempbflux = (tempgrad_velo+apf::transpose(tempgrad_velo))*
getMPvalue(apf::getScalar(tempvoff,bqptl),
nu_0,
nu_1)
434 -identity*apf::getScalar(temppres,bqptl)/
getMPvalue(apf::getScalar(tempvoff,bqptl),
rho_0,
rho_1);
435 bflux = tempbflux*normal;
439 tempbflux = (tempgrad_velo+apf::transpose(tempgrad_velo))*
getMPvalue(apf::getScalar(tempvoff,bqptl),
nu_0,
nu_1)
440 -identity*apf::getScalar(temppres,bqptl)/
getMPvalue(apf::getScalar(tempvoff,bqptl),
rho_0,
rho_1);
441 bflux = tempbflux*normal;
443 bflux = bflux*weight*Jdet;
444 bflux.toArray(&(tempflux[l*
nsd]));
446 flux = (
double*) calloc(numbqpt*
nsd*2,
sizeof(
double));
447 m->getDoubleTag(bent,diffFlux,flux);
448 for (
int i=0;i<numbqpt*
nsd;i++){
449 flux[orientation*numbqpt*
nsd+i] = tempflux[i];
451 m->setDoubleTag(bent,diffFlux,flux);
453 apf::destroyMeshElement(tempelem);apf::destroyElement(tempvelo);apf::destroyElement(temppres); apf::destroyElement(tempvoff);
456 apf::ModelEntity* me=m->toModel(bent);
457 apf::ModelEntity* boundary_face = m->findModelEntity(
nsd-1,m->getModelTag(me));
459 if(m->isShared(bent))
461 m->getRemotes(bent,remotes);
462 for(apf::Copies::iterator it=remotes.begin(); it!=remotes.end();++it)
464 PCU_COMM_PACK(it->first, it->second);
465 PCU_COMM_PACK(it->first, orientation);
466 PCU_COMM_PACK(it->first, tempflux);
474 std::cerr<<
"Sending flux"<<std::endl;
476 flux = (
double*) calloc(numbqpt*
nsd*2,
sizeof(
double));
477 while(PCU_Comm_Receive())
479 PCU_COMM_UNPACK(bent);
480 PCU_COMM_UNPACK(orientation);
481 PCU_COMM_UNPACK(tempflux);
482 m->getDoubleTag(bent,diffFlux,flux);
483 for (
int i=0;i<numbqpt*
nsd;i++){
484 flux[orientation*numbqpt*
nsd+i] = flux[orientation*numbqpt*
nsd+i]+tempflux[i];
486 m->setDoubleTag(bent,diffFlux,flux);
491 std::cerr<<
"End computeDiffusiveFlux()"<<std::endl;
504 apf::NewArray <double> shpval;
505 apf::NewArray <double> shpval_temp;
508 apf::FieldShape* err_shape = apf::getHierarchic(2);
509 apf::EntityShape* elem_shape;
512 apf::Adjacent boundaries;
513 apf::MeshEntity* bent;
514 apf::MeshElement* b_elem;
515 apf::Vector3 bqpt,bqptl,bqptshp;
518 apf::Vector3 centerdir;
521 nshl=apf::countElementNodes(err_shape,m->getType(ent));
522 shpval_temp.allocate(nshl);
529 shpval.allocate(nshl);
530 elem_shape = err_shape->getEntityShape(m->getType(ent));
532 m->getAdjacent(ent,
nsd-1,boundaries);
533 for(
int adjcount =0;adjcount<boundaries.getSize();adjcount++){
535 apf::Vector3 bflux(0.0,0.0,0.0);
536 bent = boundaries[adjcount];
538 b_elem = apf::createMeshElement(m,bent);
540 centerdir=apf::getLinearCentroid(m,ent)-apf::getLinearCentroid(m,bent);
543 if(
isInSimplex(m,ent,apf::project(normal,centerdir).normalize()*centerdir.getLength()+apf::getLinearCentroid(m,bent),
nsd)){
544 normal = normal*-1.0;
547 apf::ModelEntity* me=m->toModel(bent);
548 int tag = m->getModelTag(me);
549 apf::ModelEntity* boundary_face = m->findModelEntity(
nsd-1,tag);
551 double flux_weight[2];
552 if(me==boundary_face){
553 if(orientation==0){flux_weight[0]=1; flux_weight[1]=0;}
554 else{flux_weight[0]=0; flux_weight[1]=-1;}
557 if(orientation==0){flux_weight[0]=(1-
a_kl); flux_weight[1]=
a_kl;}
558 else{ flux_weight[0]=-
a_kl; flux_weight[1]=-1*(1-
a_kl);}
561 int numbqpt = apf::countIntPoints(b_elem,
int_order);
562 flux = (
double*) calloc(numbqpt*
nsd*2,
sizeof(
double));
563 m->getDoubleTag(bent,diffFlux,flux);
564 for(
int l=0; l<numbqpt;l++){
565 apf::getIntPoint(b_elem,
int_order,l,bqpt);
566 bqptshp=apf::boundaryToElementXi(m,bent,ent,bqpt);
567 elem_shape->getValues(NULL,NULL,bqptshp,shpval_temp);
568 for(
int j=0;j<nshl;j++){shpval[j] = shpval_temp[hier_off+j];}
569 for(
int i=0;i<
nsd;i++){
570 for(
int s=0;
s<nshl;
s++){
571 endflux[i*nshl+
s] = endflux[i*nshl+
s]+(flux_weight[0]*flux[l*
nsd+i]+flux_weight[1]*flux[numbqpt*
nsd+l*
nsd+i])*shpval[
s];
587 apf::Field* visc = apf::createLagrangeField(m,
"viscosity",apf::SCALAR,1);
588 apf::MeshEntity* ent;
589 apf::MeshIterator* iter = m->begin(0);
590 double vof_val, visc_val;
591 while(ent = m->iterate(iter)){
592 vof_val=apf::getScalar(voff,ent,0);
594 apf::setScalar(visc, ent, 0,visc_val);
601 void setErrorField(apf::Field* estimate,Vec coef,apf::MeshEntity* ent,
int nsd,
int nshl)
604 apf::Mesh* m = apf::getMesh(estimate);
605 double coef_ez[nshl*nsd];
606 int ez_idx[nshl*nsd];
607 for(
int ez=0;ez<nshl*nsd;ez++){ez_idx[ez]=ez;}
608 VecGetValues(coef,nshl*nsd,ez_idx,coef_ez);
611 apf::Adjacent adjvert;
612 m->getAdjacent(ent,0,adjvert);
613 for(
int idx=0;idx<adjvert.getSize();idx++){
614 double coef_sub[3]={0,0,0};
615 apf::setVector(estimate,adjvert[idx],0,&coef_sub[0]);
618 apf::Adjacent adjedg;
619 m->getAdjacent(ent,1,adjedg);
620 for(
int idx=0;idx<nshl;idx++){
621 double coef_sub[3] ={coef_ez[idx],coef_ez[nshl+idx],coef_ez[nshl*2+idx]};
622 apf::setVector(estimate,adjedg[idx],0,&coef_sub[0]);
634 if(comm_rank==0) std::cout<<
"Start removing BC tags/data"<<std::endl;
635 apf::MeshEntity* ent;
636 apf::MeshIterator* fIter = m->begin(
nsd-1);
637 while(ent=m->iterate(fIter))
639 if(has_gBC && m->hasTag(ent,
BCtag)){
640 m->removeTag(ent,
BCtag);
643 if(i>0 && m->hasTag(ent,
fluxtag[i]))
647 if(m->hasTag(ent,diffFlux))
648 m->removeTag(ent,diffFlux);
653 m->destroyTag(
BCtag);
660 m->destroyTag(diffFlux);
661 if(comm_rank==0) std::cerr<<
"Destroyed BC and flux tags"<<std::endl;
677 nsd = m->getDimension();
680 apf::Field* voff = m->findField(
"vof");
682 apf::Field* velf = m->findField(
"velocity");
684 apf::Field* pref = m->findField(
"p");
696 freeField(errRho_reg);
697 freeField(errRel_reg);
699 err_reg = apf::createField(m,
"ErrorRegion",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
700 errRho_reg = apf::createField(m,
"ErrorDensity",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
701 errRel_reg = apf::createField(m,
"RelativeError",apf::SCALAR,apf::getVoronoiShape(
nsd,1));
709 apf::FieldShape* err_shape = apf::getHierarchic(
approx_order);
710 apf::Field * estimate = apf::createField(m,
"err_est", apf::VECTOR, err_shape);
711 apf::EntityShape* elem_shape;
713 apf::MeshElement* element;
714 apf::Element* visc_elem, *pres_elem,*velo_elem,*vof_elem;
715 apf::Element* est_elem;
718 apf::NewArray <double> shpval;
719 apf::NewArray <double> shpval_temp;
720 apf::NewArray <apf::Vector3> shgval;
722 apf::DynamicMatrix invJ_copy;
723 apf::NewArray <apf::DynamicVector> shdrv;
724 apf::NewArray <apf::DynamicVector> shgval_copy;
726 apf::MeshIterator* iter = m->begin(
nsd);
727 apf::MeshEntity* ent;
731 double err_est_total=0;
732 double u_norm_total=0;
734 while(ent = m->iterate(iter)){
736 elem_type = m->getType(ent);
737 if(!(elem_type != 4 || elem_type != 2)){
738 std::cout<<
"Not a Tri or Tet present"<<std::endl;
741 element = apf::createMeshElement(m,ent);
742 pres_elem = apf::createElement(pref,element);
743 velo_elem = apf::createElement(velf,element);
744 visc_elem = apf::createElement(visc,element);
745 vof_elem = apf::createElement(voff,element);
747 numqpt=apf::countIntPoints(element,
int_order);
748 nshl=apf::countElementNodes(err_shape,elem_type);
749 shgval.allocate(nshl);
750 shpval_temp.allocate(nshl);
757 nshl = nshl - hier_off;
759 shpval.allocate(nshl); shgval_copy.allocate(nshl); shdrv.allocate(nshl);
762 int ndofs = nshl*
nsd;
764 MatCreate(PETSC_COMM_SELF,&K);
765 MatSetSizes(K,ndofs,ndofs,ndofs,ndofs);
766 MatSetFromOptions(K);
771 VecCreate(PETSC_COMM_SELF,&F);
772 VecSetSizes(F,ndofs,ndofs);
776 for(
int k=0;k<numqpt;k++){
777 apf::getIntPoint(element,
int_order,k,qpt);
778 apf::getJacobian(element,qpt,J);
779 J = apf::transpose(J);
783 Jdet=fabs(apf::getJacobianDeterminant(J,
nsd));
784 weight = apf::getIntWeight(element,
int_order,k);
785 invJ_copy = apf::fromMatrix(invJ);
788 elem_shape = err_shape->getEntityShape(elem_type);
789 elem_shape->getValues(NULL,NULL,qpt,shpval_temp);
790 elem_shape->getLocalGradients(NULL,NULL,qpt,shgval);
792 for(
int i =0;i<nshl;i++){
793 shgval_copy[i] = apf::fromVector(shgval[i+hier_off]);
794 shpval[i] = shpval_temp[i+hier_off];
795 apf::multiply(shgval_copy[i],invJ_copy,shdrv[i]);
800 apf::Vector3 vel_vect;
801 apf::Matrix3x3 grad_vel;
802 apf::getVector(velo_elem,qpt,vel_vect);
803 apf::getVectorGrad(velo_elem,qpt,grad_vel);
804 grad_vel = apf::transpose(grad_vel);
805 apf::Vector3 grad_vof;
806 apf::getGrad(vof_elem,qpt,grad_vof);
809 double pressure = apf::getScalar(pres_elem,qpt);
810 double visc_val = apf::getScalar(visc_elem,qpt);
811 apf::Vector3 grad_rho = grad_vof*(
rho_1-
rho_0);
814 getLHS(K,shdrv,
nsd,weight,visc_val,nshl);
817 getRHS(F,shpval,shdrv,vel_vect,grad_vel,
nsd,weight,nshl,visc_val,density,grad_rho,pressure,g);
823 MatAssemblyBegin(K,MAT_FINAL_ASSEMBLY);
824 MatAssemblyEnd(K,MAT_FINAL_ASSEMBLY);
831 bflux = (
double*) calloc(ndofs,
sizeof(
double));
834 for(
int s=0;
s<ndofs;
s++){
837 VecSetValues(F,ndofs,F_idx,bflux,ADD_VALUES);
838 VecAssemblyBegin(F); VecAssemblyEnd(F);
841 VecCreate(PETSC_COMM_SELF,&coef);
842 VecSetSizes(coef,ndofs,ndofs);
846 KSPCreate(PETSC_COMM_SELF,&ksp);
847 KSPSetOperators(ksp,K,K);
848 KSPSetType(ksp,KSPPREONLY);
852 KSPSetFromOptions(ksp);
854 KSPSolve(ksp,F,coef);
865 apf::Matrix3x3 phi_ij;
866 apf::Matrix3x3 vel_ij;
867 apf::Vector3 vel_vect;
868 apf::Vector3 grad_vof;
870 est_elem= apf::createElement(estimate,element);
871 for(
int k=0; k<numqpt;k++){
872 apf::getIntPoint(element,
int_order,k,qpt);
873 apf::getJacobian(element,qpt,J);
876 invJ = apf::transpose(invJ);
877 Jdet=fabs(apf::getJacobianDeterminant(J,
nsd));
878 weight = apf::getIntWeight(element,
int_order,k);
879 invJ_copy = apf::fromMatrix(invJ);
882 elem_shape = err_shape->getEntityShape(elem_type);
883 elem_shape->getValues(NULL,NULL,qpt,shpval_temp);
884 elem_shape->getLocalGradients(NULL,NULL,qpt,shgval);
886 for(
int i =0;i<nshl;i++){
887 shgval_copy[i] = apf::fromVector(shgval[i+hier_off]);
888 shpval[i] = shpval_temp[i+hier_off];
889 apf::multiply(shgval_copy[i],invJ_copy,shdrv[i]);
891 double visc_val = apf::getScalar(visc_elem,qpt);
892 double pres_val = apf::getScalar(pres_elem,qpt);
894 apf::getVectorGrad(est_elem,qpt,phi_ij);
895 apf::getGrad(vof_elem,qpt,grad_vof);
896 apf::getVector(velo_elem,qpt,vel_vect);
897 apf::getVectorGrad(velo_elem,qpt,vel_ij);
898 vel_ij = apf::transpose(vel_ij);
899 phi_ij = apf::transpose(phi_ij);
901 Acomp = Acomp + visc_val*
getDotProduct(phi_ij,phi_ij+apf::transpose(phi_ij))*weight;
902 Bcomp = Bcomp + apf::getDiv(velo_elem,qpt)*apf::getDiv(velo_elem,qpt)*weight;
903 visc_avg = visc_avg + visc_val*weight;
904 u_norm = u_norm + visc_val*
getDotProduct(vel_ij,vel_ij+apf::transpose(vel_ij))*weight;
907 visc_avg = visc_avg*Jdet/apf::measure(element);
908 Acomp = Acomp*Jdet/visc_avg;
910 u_norm = u_norm/visc_avg*Jdet;
911 err_est = sqrt(Acomp);
913 apf::Vector3 err_in(err_est,Acomp,Bcomp);
915 apf::setScalar(err_reg,ent,0,err_est);
916 double errRho = err_est/sqrt(apf::measure(element));
917 apf::setScalar(errRho_reg,ent,0,errRho);
921 double err_rel = err_est/sqrt(u_norm);
922 apf::setScalar(errRel_reg,ent,0,err_rel);
924 err_est_total = err_est_total+(Acomp);
925 u_norm_total = u_norm_total + u_norm;
931 apf::destroyElement(visc_elem);apf::destroyElement(pres_elem);apf::destroyElement(velo_elem);apf::destroyElement(est_elem);apf::destroyElement(vof_elem);
934 PCU_Add_Doubles(&err_est_total,1);
935 PCU_Add_Doubles(&u_norm_total,1);
938 u_norm_total = sqrt(u_norm_total);
942 std::cerr<<std::setprecision(10)<<std::endl;
943 std::cerr<<
"Error estimate "<<
total_error<<std::endl;
944 std::cerr<<
"Error density maximum "<<
errRho_max<<std::endl;
945 std::cerr<<
"U_norm_total "<<u_norm_total<<std::endl;
950 std::cout<<
"outputting error field\n";
952 sprintf(namebuffer,
"err_reg_%i",
nEstimate);
953 apf::writeVtkFiles(namebuffer, m);
961 apf::destroyField(visc);
962 apf::destroyField(estimate);
965 std::cerr<<
"It cleared the ERM function.\n";