Example #1
0
void CSourcePieceWise_TurbSA::ComputeResidual(double *val_residual, double **val_Jacobian_i, double **val_Jacobian_j, CConfig *config) {
  
  
  if (incompressible) { Density_i = DensityInc_i; }
  else { Density_i = U_i[0]; }
  
  val_residual[0] = 0.0;
  Production = 0;
  Destruction = 0;
  CrossProduction = 0;
  val_Jacobian_i[0][0] = 0.0;
  
  /*--- Computation of vorticity ---*/
  Vorticity = (PrimVar_Grad_i[2][0]-PrimVar_Grad_i[1][1])*(PrimVar_Grad_i[2][0]-PrimVar_Grad_i[1][1]);
  if (nDim == 3) Vorticity += ( (PrimVar_Grad_i[3][1]-PrimVar_Grad_i[2][2])*(PrimVar_Grad_i[3][1]-PrimVar_Grad_i[2][2]) + (PrimVar_Grad_i[1][2]-PrimVar_Grad_i[3][0])*(PrimVar_Grad_i[1][2]-PrimVar_Grad_i[3][0]) );
  Omega = sqrt(Vorticity);
  
  /*--- Rotational correction term ---*/
  if (rotating_frame) {
    div = PrimVar_Grad_i[1][0] + PrimVar_Grad_i[2][1];
    if (nDim == 3) div += PrimVar_Grad_i[3][2];
    StrainMag = 0.0;
    // add diagonals
    StrainMag += pow(PrimVar_Grad_i[1][0] - 1.0/3.0*div,2.0);
    StrainMag += pow(PrimVar_Grad_i[2][1] - 1.0/3.0*div,2.0);
    if (nDim == 3) StrainMag += pow(PrimVar_Grad_i[3][2] - 1.0/3.0*div,2.0);
    // add off diagonals
    StrainMag += 2.0*pow(0.5*(PrimVar_Grad_i[1][1]+PrimVar_Grad_i[2][0]),2.0);
    if (nDim == 3) {
      StrainMag += 2.0*pow(0.5*(PrimVar_Grad_i[1][2]+PrimVar_Grad_i[3][0]),2.0);
      StrainMag += 2.0*pow(0.5*(PrimVar_Grad_i[2][2]+PrimVar_Grad_i[3][1]),2.0);
    }
    StrainMag = sqrt(2.0*StrainMag);
    Omega += 2.0*min(0.0,StrainMag-Omega);
  }
  
  if (dist_i > 1e-10) {
    
    /*--- Production term ---*/
    dist_i_2 = dist_i*dist_i;
    nu = Laminar_Viscosity_i/Density_i;
    Ji = TurbVar_i[0]/nu;
    Ji_2 = Ji*Ji;
    Ji_3 = Ji_2*Ji;
    fv1 = Ji_3/(Ji_3+cv1_3);
    fv2 = 1.0 - Ji/(1.0+Ji*fv1);
    S = Omega;
    inv_k2_d2 = 1.0/(k2*dist_i_2);
    
    Shat = S + TurbVar_i[0]*fv2*inv_k2_d2;
    inv_Shat = 1.0/max(Shat, 1.0e-10);
    
    /*--- Production term ---*/;
    if (!transition) Production = cb1*Shat*TurbVar_i[0]*Volume;
    else Production = cb1*Shat*TurbVar_i[0]*Volume*intermittency;
    
    /*--- Destruction term ---*/
    
    r = min(TurbVar_i[0]*inv_Shat*inv_k2_d2,10.0);
    g = r + cw2*(pow(r,6.0)-r);
    g_6 =	pow(g,6.0);
    glim = pow((1.0+cw3_6)/(g_6+cw3_6),1.0/6.0);
    fw = g*glim;
    
    if (!transition) Destruction = cw1*fw*TurbVar_i[0]*TurbVar_i[0]/dist_i_2*Volume;
    else Destruction = cw1*fw*TurbVar_i[0]*TurbVar_i[0]/dist_i_2*Volume*min(max(intermittency,0.1),1.0);
    
    /*--- Diffusion term ---*/
    
    norm2_Grad = 0.0;
    for (iDim = 0; iDim < nDim; iDim++)
      norm2_Grad += TurbVar_Grad_i[0][iDim]*TurbVar_Grad_i[0][iDim];
    CrossProduction = cb2_sigma*norm2_Grad*Volume;
    
    val_residual[0] = Production - Destruction + CrossProduction;
    
    /*--- Implicit part ---*/
    
    /*--- Production term ---*/
    dfv1 = 3.0*Ji_2*cv1_3/(nu*pow(Ji_3+cv1_3,2.));
    dfv2 = -(1/nu-Ji_2*dfv1)/pow(1.+Ji*fv1,2.);
    if ( Shat <= 1.0e-10 ) dShat = 0.0;
    else dShat = (fv2+TurbVar_i[0]*dfv2)*inv_k2_d2;
    val_Jacobian_i[0][0] += cb1*(TurbVar_i[0]*dShat+Shat)*Volume;
    
    /*--- Destruction term ---*/
    dr = (Shat-TurbVar_i[0]*dShat)*inv_Shat*inv_Shat*inv_k2_d2;
    if (r == 10.0) dr = 0.0;
    dg = dr*(1.+cw2*(6.*pow(r,5.)-1.));
    dfw = dg*glim*(1.-g_6/(g_6+cw3_6));
    val_Jacobian_i[0][0] -= cw1*(dfw*TurbVar_i[0] +	2.*fw)*TurbVar_i[0]/dist_i_2*Volume;
  }
  
  for (int i =0; i < nDim; i++){
    for (int j=0; j < nDim; j++){
      DUiDXj[i][j] = PrimVar_Grad_i[i+1][j];
    }
    DNuhatDXj[i] = TurbVar_Grad_i[0][i];
  }
  
  SAInputs->Set(DUiDXj, DNuhatDXj, rotating_frame, transition, dist_i, Laminar_Viscosity_i, Density_i, TurbVar_i[0], intermittency);
  
  
  SpalartAllmarasSourceTerm(SAInputs, SAConstants, testResidual, testJacobian);
  
  for (int i=0; i < nResidual; i++){
    testResidual[i] *= Volume;
  }
  
  for (int i=0; i < nJacobian; i++){
    testJacobian[i] *= Volume;
  }
  
  // Check if the old and new match
  //for (int i = 0; i < nResidual; i++){
  if (abs(Production - testResidual[0]) > 1e-15){
    cout << "Production doesn't match" << endl;
    cout << "diff is " << Production - testResidual[0] << endl;
    exit(10);
  }
  if (abs(Destruction - testResidual[1]) > 1e-15){
    cout << "Destruction doesn't match" << endl;
    exit(10);
  }
  if (abs(CrossProduction - testResidual[2]) > 1e-15){
    cout << "cpp Cross " <<  CrossProduction << endl;
    cout << "Func cross " << testResidual[2] << endl;
    cout << "dist_i " << dist_i << endl;
    cout << "Cross production doesn't match" << endl;
    exit(10);
  }
  if (abs(val_residual[0]-testResidual[3]) > 1e-15){
    cout << "Val residual is " << val_residual[0] << endl;
    cout << "Test residual is " << testResidual[3] << endl;
    cout << "Diff is " << val_residual[0] - testResidual[3] << endl;
    cout << "Full residual doesn't match" << endl;
    exit(10);
  }
}
Example #2
0
void CSourcePieceWise_TurbML::ComputeResidual(double *val_residual, double **val_Jacobian_i, double **val_Jacobian_j, CConfig *config) {
  
  if (incompressible) { Density_i = DensityInc_i; }
  else { Density_i = U_i[0]; }
  
  /* Intialize */
  // Note that the Production, destruction, etc. are all volume independent
  val_residual[0] = 0.0;
  SAProduction = 0;
  SADestruction = 0;
  SACrossProduction = 0;
  SASource = 0;
  MLProduction = 0;
  MLDestruction = 0;
  MLCrossProduction = 0;
  MLSource = 0;
  SourceDiff = 0;
  val_Jacobian_i[0][0] = 0.0;
  
  for (int i =0; i < nDim; i++){
    for (int j=0; j < nDim; j++){
      DUiDXj[i][j] = PrimVar_Grad_i[i+1][j];
    }
    DNuhatDXj[i] = TurbVar_Grad_i[0][i];
  }
  
  /* Call Spalart-Allmaras (for comparison) */
  SAInputs->Set(DUiDXj, DNuhatDXj, rotating_frame, transition, dist_i, Laminar_Viscosity_i, Density_i, TurbVar_i[0], intermittency);
  
  SpalartAllmarasSourceTerm(SAInputs, SAConstants, testResidual, testJacobian);
  
  SAProduction = testResidual[0];
  SADestruction = testResidual[1];
  SACrossProduction = testResidual[2];
  SASource = testResidual[3];
  
  for (int i=0; i < nResidual; i++){
    testResidual[i] *= Volume;
  }
  
  for (int i=0; i < nJacobian; i++){
    testJacobian[i] *= Volume;
  }
  
  /* Call turbulence model */
  // Get all the variables
  int nInputMLVariables = 9;
  int nOutputMLVariables = 1;
  double * input = new double[nInputMLVariables];
  for (int i = 0; i < nInputMLVariables; i++){
    input[i] = 0;
  }
  int ctr = 0;
  input[ctr] = Laminar_Viscosity_i/Density_i;
  ctr++;
  input[ctr] = TurbVar_i[0];
  ctr++;
  input[ctr] = dist_i;
  ctr++;
  for (iDim = 0; iDim < nDim; iDim++){
    input[ctr] = TurbVar_Grad_i[0][iDim];
    ctr++;
  }
  for (iDim = 0; iDim < nDim; iDim ++){
    for (int jDim = 0; jDim < nDim; jDim++){
      input[ctr] = PrimVar_Grad_i[iDim+1][iDim];
      ctr++;
    }
  }
  if (ctr != nInputMLVariables){
    cout << "Improper number of variables put into ctr"<< endl;
    exit(1);
  }
  double *output = new double[nOutputMLVariables];
  for (int i=0; i < nOutputMLVariables; i++){
    output[i] = 0;
  }
  
  this->MLModel->Predict(input, output);
  
  // Should add some sort of switch in the future
  MLSource = output[0];
  SourceDiff = MLSource - SASource;
  
  // Rescale by volume
  output[0] = output[0]*Volume;
  
  /*
  double slideIter = 500.0;
  double extiter = double(config->GetExtIter());
  if (extiter > slideIter){
    extiter = slideIter;
  }
  val_residual[0] = testResidual[3]*(slideIter - extiter)/slideIter + output[0] * extiter/slideIter;
  */
  //  cout.precision(15);
  /*
   cout <<"ml pred is " << output[0] << endl;
   cout << "real SA is " << testResidual[3] << endl;
   cout << "val resid is " << val_residual[0] << endl;
   */
  
  val_residual[0] = output[0];
  val_residual[0] = testResidual[3];
  //val_Jacobian_i[0][0] = testJacobian[0];
  
  delete input;
  delete output;
}
void CSourcePieceWise_TurbML::ComputeResidual(double *val_residual, double **val_Jacobian_i, double **val_Jacobian_j, CConfig *config) {
  
  if (incompressible) {
    Density_i = V_i[nDim+1];
    Laminar_Viscosity_i = V_i[nDim+3];
  }
  else {
    Density_i = V_i[nDim+2];
    Laminar_Viscosity_i = V_i[nDim+5];
  }
  
  /* Intialize */
  // Note that the Production, destruction, etc. are all volume independent
  
  for (int i= 0; i < nResidual; i++){
    SAResidual[i] = 0;
    SANondimResidual[i] = 0;
    Residual[i] = 0;
    NondimResidual[i] = 0;
    ResidualDiff[i] = 0;
    NondimResidualDiff[i] = 0;
  }
  
  val_residual[0] = 0.0;
  val_Jacobian_i[0][0] = 0.0;
  
  NuhatGradNorm = 0;
  for (int i =0; i < nDim; i++){
    for (int j=0; j < nDim; j++){
      DUiDXj[i][j] = PrimVar_Grad_i[i+1][j];
    }
    DNuhatDXj[i] = TurbVar_Grad_i[0][i];
    NuhatGradNorm += TurbVar_Grad_i[0][i] * TurbVar_Grad_i[0][i];
  }
  
  /* Call Spalart-Allmaras (for comparison) */
  SAInputs->Set(DUiDXj, DNuhatDXj, rotating_frame, transition, dist_i, Laminar_Viscosity_i, Density_i, TurbVar_i[0], intermittency);
  
  SpalartAllmarasSourceTerm(SAInputs, SAConstants,SAResidual, SAJacobian, SAOtherOutputs);
  this->SANondimInputs -> Set(SAInputs);

  for (int i=0; i < nResidual; i++){
    SANondimResidual[i] = SAResidual[i];
  }
  SANondimInputs->NondimensionalizeSource(nResidual, SANondimResidual);
  
  int nInputMLVariables = 0;
  int nOutputMLVariables = 0;
  double* netInput = NULL;
  double* netOutput = NULL;
  
  if (featureset.compare("SA") == 0){
    // Set the output equal to the spalart allmaras output.
    for (int i = 0; i < nResidual; i++){
      Residual[i] = SAResidual[i];
      NondimResidual[i] = SANondimResidual[i];
    }
  }else if (featureset.compare("nondim_production")==0){
    nInputMLVariables = 2;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = SANondimInputs->Chi;
    netInput[1] = SANondimInputs->OmegaBar;
    
    // Predict using Nnet
    MLModel->Predict(netInput, netOutput);

    // Gather all the appropriate variables
    NondimResidual[0] = netOutput[0];
    NondimResidual[1] = SANondimResidual[1];
    NondimResidual[2] = SANondimResidual[2];
    NondimResidual[3] = NondimResidual[0] - NondimResidual[1] + NondimResidual[2];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
      //cout << "NondimResidual " << i <<" "<< NondimResidual[i] << endl;
    }
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
    /*
    for (int i=0; i < nResidual; i++){
      cout << "DimResidual " << i << " " << Residual[i] << endl;
    }
     */
  }else if(featureset.compare("nondim_production_log") == 0){
    nInputMLVariables = 2;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = log10(SANondimInputs->Chi);
    netInput[1] = log10(SANondimInputs->OmegaBar);
    
    // Predict using Nnet
    MLModel->Predict(netInput, netOutput);
    
    // Gather all the appropriate variables
    NondimResidual[0] = netOutput[0];
    NondimResidual[1] = SANondimResidual[1];
    NondimResidual[2] = SANondimResidual[2];
    NondimResidual[3] = NondimResidual[0] - NondimResidual[1] + NondimResidual[2];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
//      cout << "NondimResidual " << i << NondimResidual[i] << endl;
    }
    
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
  /*
    for (int i=0; i < nResidual; i++){
      cout << "DimResidual " << i << Residual[i] << endl;
    }
   */
  }else if(featureset.compare("nondim_production_logchi") == 0){
    nInputMLVariables = 2;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = log10(SANondimInputs->Chi);
    netInput[1] = SANondimInputs->OmegaBar;
    
    // Predict using Nnet
    MLModel->Predict(netInput, netOutput);
    
    // Gather all the appropriate variables
    NondimResidual[0] = netOutput[0];
    NondimResidual[1] = SANondimResidual[1];
    NondimResidual[2] = SANondimResidual[2];
    NondimResidual[3] = NondimResidual[0] - NondimResidual[1] + NondimResidual[2];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
    }
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
  }else if(featureset.compare("production")==0){
    nInputMLVariables = 3;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = SANondimInputs->Chi;
    netInput[1] = SANondimInputs->OmegaBar;
    netInput[2] = SANondimInputs->SourceNondim;
    
//    cout << "Net inputs ";
//    for (int i = 0; i < 3; i++){
//      cout << "\t" << netInput[i];
//    }
//    cout << endl;
    
    // Predict using Nnet
    MLModel->Predict(netInput, netOutput);
    
    // Gather the appropriate values
    Residual[0] = netOutput[0];
    Residual[1] = SAResidual[1];
    Residual[2] = SAResidual[2];
    Residual[3] = Residual[0] - Residual[1] + Residual[2];

//    cout << "ML Production " << Residual[0] << endl;
//    cout << "SA Production " << SAResidual[0] << endl;
    
    for (int i=0; i < nResidual; i++){
      NondimResidual[i] = Residual[i];
    }
    SANondimInputs->NondimensionalizeSource(nResidual, NondimResidual);
    
  }else if (featureset.compare("nondim_destruction")==0){
    nInputMLVariables = 2;
    nOutputMLVariables = 1;
    
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = SANondimInputs->Chi;
    netInput[1] = SANondimInputs->OmegaBar;
    
    MLModel->Predict(netInput, netOutput);
    
    NondimResidual[0] = SANondimResidual[0];
    NondimResidual[1] = netOutput[0];
    NondimResidual[2] = SANondimResidual[2];
    NondimResidual[3] = NondimResidual[0] - NondimResidual[1] + NondimResidual[2];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
    }
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
  }else if(featureset.compare("destruction")==0){
      nInputMLVariables = 3;
      nOutputMLVariables = 1;
      netInput = new double[nInputMLVariables];
      netOutput = new double[nOutputMLVariables];
      
      netInput[0] = SANondimInputs->Chi;
      netInput[1] = SANondimInputs->OmegaBar;
      netInput[2] = SANondimInputs->SourceNondim;
      
      // Predict using Nnet
      MLModel->Predict(netInput, netOutput);
      
      // Gather the appropriate values
      Residual[0] = SAResidual[0];
      Residual[1] = netOutput[1];
      Residual[2] = SAResidual[2];
      Residual[3] = Residual[0] - Residual[1] + Residual[2];
      
      for (int i=0; i < nResidual; i++){
        NondimResidual[i] = Residual[i];
      }
      SANondimInputs->NondimensionalizeSource(nResidual, NondimResidual);
  }else if (featureset.compare("nondim_crossproduction")==0){
    nInputMLVariables = 2;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = SANondimInputs->Chi;
    netInput[1] = SANondimInputs->NuHatGradNormBar;
    
    //cout << "IN nondim_crossproduction " << endl;
    //  cout << "chi " << netInput[0] <<  endl;
    //    cout << "grad norm bar "<< netInput[1] << endl;
    
    MLModel->Predict(netInput, netOutput);
    
    NondimResidual[0] = SANondimResidual[0];
    NondimResidual[1] = SANondimResidual[1];
    NondimResidual[2] = netOutput[0];
    NondimResidual[3] = NondimResidual[0] - NondimResidual[1] + NondimResidual[2];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
    }
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
  }else if (featureset.compare("nondim_source")==0){
    nInputMLVariables = 3;
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    netInput[0] = SANondimInputs->Chi;
    netInput[1] = SANondimInputs->OmegaBar;
    netInput[2] = SANondimInputs->NuHatGradNormBar;
  
    // Predict using Nnet
    MLModel->Predict(netInput, netOutput);
    
    NondimResidual[0] = 0;
    NondimResidual[1] = 0;
    NondimResidual[2] = 0;
    NondimResidual[3] = netOutput[0];
    
    for (int i=0; i < nResidual; i++){
      Residual[i] = NondimResidual[i];
    }
    SANondimInputs->DimensionalizeSource(nResidual, Residual);
  }else if (featureset.compare("fw_les_2")==0){
    nOutputMLVariables = 1;
    netInput = new double[nInputMLVariables];
    netOutput = new double[nOutputMLVariables];
    
    double chi = SANondimInputs->Chi;
    double omegaBar = SANondimInputs->OmegaBar;
    // Karthik nondimensionalizes by d / vhat whereas I do by /(v + vhat)
    omegaBar *= 1 + 1/chi;
    
    netInput[0] = chi;
    netInput[1] = omegaBar;
    
    MLModel->Predict(netInput, netOutput);
    
    double safw = SAOtherOutputs->fw;
    double newfw = netOutput[0];
    if (newfw < -1){
      newfw = 1;
    }
    if (newfw > 6){
      newfw = 6;
    }
    // The output is the value of fw. Need to replace the destruction term with the new computation
    double turbKinVisc = SAInputs->Turbulent_Kinematic_Viscosity;
    double dist2 = SAInputs->dist * SAInputs->dist;
    double newdestruction = SAConstants->cw1 * (newfw +safw) * turbKinVisc * turbKinVisc / dist2;
    
    for (int i= 0; i < nResidual; i++){
      Residual[i] = SAResidual[i];
    }
    Residual[1] = newdestruction;
    Residual[3] = Residual[0] + Residual[1] + Residual[2];
    
    for (int i= 0; i < nResidual; i++){
      NondimResidual[i] = Residual[i];
    }
    SANondimInputs->NondimensionalizeSource(nResidual, NondimResidual);
    
  }else{
    cout << "None of the conditions met" << endl;
    cout << "featureset is " << featureset << endl;
    throw "ML_Turb_Model_Nondimensionalization not recognized";
  }
  delete [] netInput;
  delete [] netOutput;
  
  // Hack if the wall distance is too low
  if (dist_i < 1e-10){
    for (int i= 0; i < nResidual; i++){
      Residual[i] = 0;
      NondimResidual[i] = 0;
    }
  }
  
  
  // Now that we have found the ML Residual and the SA residual, see if there are
  // any special hacks that we should use
  
  unsigned short nStrings = config->GetNumML_Turb_Model_Extra();
  string *extraString = config->GetML_Turb_Model_Extra();
  
  if (nStrings > 0){
    if (extraString[0].compare("FlatplateBlOnlyCutoff") == 0){
        // Only use ML in the boundary layer and have a sharp cutoff
      if ((Coord_i[0] < 0) || (Coord_i[1]) > 0.06 ){
        // Not in the BL, so just use the SA residual
        for (int i = 0; i < nResidual; i++){
          Residual[i] = SAResidual[i];
          NondimResidual[i] = SANondimResidual[i];
        }
      }
    }
  }
  
  
//  cout << "SA nondim cross production " << SANondimResidual[2] << endl;
//    cout << "Nondim cross production " << NondimResidual[2] << endl;
//    cout << "SA cross production " << SAResidual[2] << endl;
//    cout << "Cross production " << Residual[2] << endl;
  
  // Compute the differences
  for (int i = 0; i < nResidual; i++){
    ResidualDiff[i] = Residual[i] - SAResidual[i];
    NondimResidualDiff[i] = NondimResidual[i] - SANondimResidual[i];
  }
  
  // Store The residual for the outer structure
  val_residual[0] = Residual[3] * Volume;
  val_Jacobian_i[0][0] = SAJacobian[0] * Volume;
  
  /*
  cout << "Sa resid ";
  for (int i = 0; i < nResidual; i++){
    cout << SAResidual[i] << "\t";
  }
  cout << endl;
  cout << "Ml resid ";
  for (int i = 0; i < nResidual; i++){
    cout << Residual[i] << "\t";
  }
  cout << endl;
   */
}