Exemple #1
0
//! \brief compute compute the source term of the collision
//! model: electric force + true collisions
void VlasovP_Lagrangian_Source(const real* x, const real t, const real* w, 
			       real* source, int m) {
  real E=w[_INDEX_EX]; // electric field
  real Md[_INDEX_MAX_KIN+1];
  real db[_INDEX_MAX_KIN+1];
  for(int iv=0;iv<_INDEX_MAX_KIN+1;iv++){
    Md[iv]=0;
    db[iv]=0;
  }
    
  for(int iv=0;iv<_INDEX_MAX_KIN+1;iv++){
    source[iv]=0;
  }
  // no source on the potential for the moment
  source[_INDEX_PHI]=0;
  source[_INDEX_EX]=0;
  source[_INDEX_RHO]=0; //rho init
  source[_INDEX_VELOCITY]=0; // u init
  source[_INDEX_PRESSURE]=0; // p init
  source[_INDEX_TEMP]=0; 
  // loop on the finite emlements
  for(int iel=0;iel<_NB_ELEM_V;iel++){
    // loop on the local glops
    for(int kloc=0;kloc<_DEG_V+1;kloc++){
      real omega=wglop(_DEG_V,kloc);
      int kpg=kloc+iel*_DEG_V;
      Md[kpg]+=omega*_DV;
      for(int iloc=0;iloc<_DEG_V+1;iloc++){
	int ipg=iloc+iel*_DEG_V;
	source[ipg]+=E*omega*w[kpg]*dlag(_DEG_V,iloc,kloc);
	if (iloc==kloc) db[ipg]+=E*omega*dlag(_DEG_V,iloc,kloc);
      }
    }
  }

  // upwinding
  if (E>0){
    source[_INDEX_MAX_KIN]-=E*w[_INDEX_MAX_KIN];
    db[_INDEX_MAX_KIN]-=E;
  }
  else {
    source[0]-=-E*w[0];
    db[0]-=-E;
  }

  for(int iv=0;iv<_INDEX_MAX_KIN+1;iv++){
    source[iv]/=Md[iv];
    //printf("%f ",source[iv]);
  }
}
Exemple #2
0
void ADERTimeStep(ADERDG* adg)
{
  double dt = adg->dt_small;

  // first, predict the values of w at an intermediate time step
  for(int ie = 1;ie <= _NBELEMS_IN; ie++) {
    Predictor(adg, ie, dt / 2);
  }

  // init the derivative to zero
  for(int ie = 1; ie<= _NBELEMS_IN; ie++) {
    for(int i = 0; i < _NGLOPS; i++) {
      for(int iv = 0; iv < _M; iv++) {
	adg->dtw[ie][i][iv]=0;
      }
    }
  }

  // impose the exact values on boundary left and right cells
  double x = adg->face[0];
  double t = adg->tnow + dt / 2 ;
  ExactSol(x, t, adg->wpred[0][_D]); // _D = last point of left cell 

  x = adg->face[_NBFACES-1];

  // 0 = first point of right cell
  ExactSol(x, t, adg->wpred[_NBELEMS_IN + 1][0]); 

  // compute the face flux terms
  // loop on the faces
  for(int i = 0; i < _NBFACES; i++){
    double *wL, *wR;
    double flux[_M];
    int ie = i;
    wL = adg->wpred[ie][_D]; // _D = last point of left cell 
    wR = adg->wpred[ie+1][0];  // 0 = first point of right cell
    NumFlux(wL, wR, flux);
    for (int k = 0; k < _M; k++){
      adg->dtw[ie][_D][k] -=  flux[k];  
      adg->dtw[ie+1][0][k] +=  flux[k];  
    }
  }

  // compute the volume terms
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    double h = adg->face[ie] - adg->face[ie-1];
    // loop on the glops i 
    for(int i = 0; i < _NGLOPS; i++){
      
      // integration weight
      double omega = wglop(_D, i) * h;
      
      // flux at glop i
      double flux[_M];
      NumFlux(adg->wpred[ie][i], adg->wpred[ie][i], flux);
      
      // loop on the basis functions j
      for(int j = 0; j < _D+1; j++){
	// derivative of basis function j at glop i
	double dd = dlag(_D, j, i) / h;
	for (int k = 0; k < _M; k++){
	  adg->dtw[ie][j][k] += omega * dd * flux[k];
	}
      }
    }
  }    
   
  // divide by the mass matrix
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    double h = adg->face[ie] - adg->face[ie-1];
    for(int i = 0; i < _NGLOPS; i++){
      double omega = wglop(_D, i) * h;
      for (int k = 0; k < _M; k++){
	adg->dtw[ie][i][k] /= omega;
      }
    }
    
  }
  
  // update wnext and 
  // copy wnext into wnow for the next time step
  for(int ie = 1; ie<= _NBELEMS_IN; ie++){
    for(int i = 0; i < _NGLOPS; i++){
      for(int iv = 0; iv < _M; iv++){
	adg->wnext[ie][i][iv] =
	  adg->wnow[ie][i][iv] + dt * adg->dtw[ie][i][iv];
	adg->wnow[ie][i][iv] = adg->wnext[ie][i][iv];
      }
    }
  }
 
}
Exemple #3
0
// compute the Discontinuous Galerkin volume terms
// fast version
void* DGVolume(void* mc){

  MacroCell* mcell = (MacroCell*) mc;

  Field* f= mcell->field;

  // loop on the elements
  for (int ie=mcell->first_cell;ie<mcell->last_cell_p1;ie++){
    // get the physical nodes of element ie
    double physnode[20][3];
    for(int inoloc=0;inoloc<20;inoloc++){
      int ino=f->macromesh.elem2node[20*ie+inoloc];
      physnode[inoloc][0]=f->macromesh.node[3*ino+0];
      physnode[inoloc][1]=f->macromesh.node[3*ino+1];
      physnode[inoloc][2]=f->macromesh.node[3*ino+2];
    }

    const int m = f->model.m;
    const int deg[3]={f->interp_param[1],
		      f->interp_param[2],
		      f->interp_param[3]};
    const int npg[3] = {deg[0]+1,
			deg[1]+1,
			deg[2]+1};
    const int nraf[3]={f->interp_param[4],
		       f->interp_param[5],
		       f->interp_param[6]};

    const unsigned int sc_npg=npg[0]*npg[1]*npg[2];

    int f_interp_param[8]= {f->interp_param[0],
			    f->interp_param[1],
			    f->interp_param[2],
			    f->interp_param[3],
			    f->interp_param[4],
			    f->interp_param[5],
			    f->interp_param[6],
			    f->interp_param[7]};

    // loop on the subcells
    for(int icL0 = 0; icL0 < nraf[0]; icL0++){
      for(int icL1 = 0; icL1 < nraf[1]; icL1++){
	for(int icL2 = 0; icL2 < nraf[2]; icL2++){

	  int icL[3] = {icL0,icL1,icL2};
	  // get the L subcell id
	  int ncL=icL[0]+nraf[0]*(icL[1]+nraf[1]*icL[2]);
	  // first glop index in the subcell
	  int offsetL=npg[0]*npg[1]*npg[2]*ncL;

	  // compute all of the xref for the subcell
	  double *xref0 = malloc(sc_npg * sizeof(double));
	  double *xref1 = malloc(sc_npg * sizeof(double));
	  double *xref2 = malloc(sc_npg * sizeof(double));
	  double *omega = malloc(sc_npg * sizeof(double));
	  int *imems = malloc(m * sc_npg * sizeof(int));
	  int pos=0;
	  for(unsigned int p=0; p < sc_npg; ++p) {
	    double xref[3];
	    double tomega;

	    ref_pg_vol(f->interp_param+1,offsetL+p,xref,&tomega,NULL);
	    xref0[p] = xref[0];
	    xref1[p] = xref[1];
	    xref2[p] = xref[2];
	    omega[p] = tomega;
	    
	    for(int im=0; im < m; ++im) {
	      imems[pos++] = f->varindex(f_interp_param,ie,offsetL+p,im);
	    }
	  }

	  // loop in the "cross" in the three directions
	  for(int dim0 = 0; dim0 < 3; dim0++){
	    // point p at which we compute the flux
    
	    for(int p0 = 0; p0 < npg[0]; p0++){
	      for(int p1 = 0; p1 < npg[1]; p1++){
		for(int p2 = 0; p2 < npg[2]; p2++){
		  double wL[m],flux[m];
		  int p[3]={p0,p1,p2};
		  int ipgL=offsetL+p[0]+npg[0]*(p[1]+npg[1]*p[2]);
		  for(int iv=0; iv < m; iv++){
		    ///int imemL=f->varindex(f_interp_param,ie,ipgL,iv);
		    wL[iv] = f->wn[imems[m*(ipgL-offsetL)+iv]]; /// big bug !!!!

		    //wL[iv] = f->wn[imemL];
		  }
		  int q[3]={p[0],p[1],p[2]};
		  // loop on the direction dim0 on the "cross"
		  for(int iq = 0; iq < npg[dim0]; iq++){
		    q[dim0]=(p[dim0]+iq)%npg[dim0];
		    double dphiref[3]={0,0,0};
		    // compute grad phi_q at glop p
		    dphiref[dim0]=dlag(deg[dim0],q[dim0],p[dim0])*nraf[dim0];

		    double xrefL[3]={xref0[ipgL-offsetL],
		    		     xref1[ipgL-offsetL],
		    		     xref2[ipgL-offsetL]};
		    double wpgL=omega[ipgL-offsetL];
		    /* double xrefL[3], wpgL; */
		    /* ref_pg_vol(f->interp_param+1,ipgL,xrefL,&wpgL,NULL); */

		    // mapping from the ref glop to the physical glop
		    double dtau[3][3],codtau[3][3],dphiL[3];
		    Ref2Phy(physnode,
			    xrefL,
			    dphiref,  // dphiref
			    -1,    // ifa                                 
			    NULL,  // xphy  
			    dtau,
			    codtau,
			    dphiL,  // dphi
			    NULL);  // vnds   
    
		    f->model.NumFlux(wL,wL,dphiL,flux);

		    int ipgR=offsetL+q[0]+npg[0]*(q[1]+npg[1]*q[2]);
		    for(int iv=0; iv < m; iv++){
		      //int imemR=f->varindex(f_interp_param,ie,ipgR,iv);
		      f->dtwn[imems[m*(ipgR-offsetL)+iv]]+=flux[iv]*wpgL;
		    }
		  } // iq
		} // p2
	      } // p1
	    } // p0
	    
	  } // dim loop
	  
	  free(omega);
	  free(xref0);
	  free(xref1);
	  free(xref2);
	  free(imems);

	} // icl2
      } //icl1
    } // icl0
  }

  return NULL;


}