Dhairya Malhotra 5 年之前
父节点
当前提交
87ee5e93bf
共有 1 个文件被更改,包括 92 次插入11 次删除
  1. 92 11
      include/sctl/boundary_quadrature.hpp

+ 92 - 11
include/sctl/boundary_quadrature.hpp

@@ -2841,11 +2841,11 @@ template <class Real, Integer ORDER=10> class Stellarator {
       SCTL_ASSERT(Nsurf*2 == NtNp_.Dim());
 
       Long Nelem = 0;
-      elem_dsp.ReInit(Nsurf);
-      if (elem_dsp.Dim()) elem_dsp[0] = 0;
+      elem_dsp.ReInit(Nsurf+1);
+      elem_dsp[0] = 0;
       for (Long i = 0; i < Nsurf; i++) {
         Nelem += NtNp_[i*2+0]*NtNp_[i*2+1];
-        if (i+1 < Nsurf) elem_dsp[i+1] = Nelem;
+        elem_dsp[i+1] = Nelem;
       }
       elements.ReInit(Nelem);
       for (Long i = 0; i < Nsurf; i++) {
@@ -2854,7 +2854,7 @@ template <class Real, Integer ORDER=10> class Stellarator {
     }
 
     Long ElemIdx(Long s, Long t, Long p) {
-      SCTL_ASSERT(0 <= s && s < elem_dsp.Dim());
+      SCTL_ASSERT(0 <= s && s < Nsurf());
       SCTL_ASSERT(0 <= t && t < NtNp_[s*2+0]);
       SCTL_ASSERT(0 <= p && p < NtNp_[s*2+1]);
       return elem_dsp[s] + t*NtNp_[s*2+1] + p;
@@ -2870,7 +2870,7 @@ template <class Real, Integer ORDER=10> class Stellarator {
     }
 
     Long Nsurf() const {
-      return elem_dsp.Dim();
+      return elem_dsp.Dim()-1;
     }
     Long ElemDsp(Long s) const {
       return elem_dsp[s];
@@ -2935,12 +2935,12 @@ template <class Real, Integer ORDER=10> class Stellarator {
 
         compute_invA(S.sigma, S.alpha, S.beta, S, flux_tor_[i], flux_pol_[i], comm);
         S.B = compute_B(S, S.sigma, S.alpha, S.beta);
-        { // Write VTU
+        if (0) { // Write VTU
           VTUData vtu;
           vtu.AddElems(S.GetElemList(), S.sigma, ORDER);
           vtu.WriteVTK("sigma"+std::to_string(i), comm);
         }
-        { // Write VTU
+        if (0) { // Write VTU
           VTUData vtu;
           vtu.AddElems(S.GetElemList(), S.B, ORDER);
           vtu.WriteVTK("B"+std::to_string(i), comm);
@@ -3567,7 +3567,7 @@ template <class Real, Integer ORDER=10> class Stellarator {
           const Long elem_dsp = (i==0 ? 0 : S_.ElemDsp(i-1));
           const Long Nnodes = ElemBasis::Size();
           auto dgdnu_ = compute_gradient(Svec[i]);
-          { // Write VTU
+          if (0) { // Write VTU
             VTUData vtu;
             vtu.AddElems(Svec[i].GetElemList(), dgdnu_, ORDER);
             vtu.WriteVTK("dgdnu-"+std::to_string(i), comm);
@@ -3731,10 +3731,91 @@ template <class Real, Integer ORDER=10> class Stellarator {
         //pressure[1] = 0;
       }
 
-      //{ // find equilibrium flux surfaces
+      { // find equilibrium flux surfaces
+        const Long Nnodes = ElemBasis::Size();
+        const Long Nelem = S.NElem();
+        const Long Nsurf = S.Nsurf();
 
-      //  return;
-      //}
+        Long iter = 0;
+        Real dt = 0.1;
+        while (1) { // time-step
+          Vector<ElemBasis> normal, area_elem;
+          compute_norm_area_elem(S, normal, area_elem);
+          Vector<ElemBasis> dgdnu = compute_gradient(S, pressure, flux_tor, flux_pol)*(-1);
+          //Vector<ElemBasis> dgdnu = compute_pressure_jump(S, pressure, flux_tor, flux_pol)*(-1);
+
+          Vector<ElemBasis> dXdt(dgdnu.Dim()*COORD_DIM);
+          { // Set dXdt
+            dXdt = 0;
+            for (Long i = 0; i < S.ElemDsp(Nsurf-1); i++) {
+              for (Long j = 0; j < Nnodes; j++) {
+                dXdt[i*COORD_DIM+0][j] = normal[i*COORD_DIM+0][j] * dgdnu[i][j];
+                dXdt[i*COORD_DIM+1][j] = normal[i*COORD_DIM+1][j] * dgdnu[i][j];
+                dXdt[i*COORD_DIM+2][j] = normal[i*COORD_DIM+2][j] * dgdnu[i][j];
+              }
+            }
+          }
+
+          { // Update S, dt
+            Stellarator<Real,ORDER> S0 = S, S1 = S, S2 = S;
+            for (Long i = 0; i < S.NElem(); i++) {
+              for (Long j = 0; j < Nnodes; j++) {
+                S0.Elem(i, 0)[j] += 0.0 * dt * dXdt[i*COORD_DIM+0][j];
+                S0.Elem(i, 1)[j] += 0.0 * dt * dXdt[i*COORD_DIM+1][j];
+                S0.Elem(i, 2)[j] += 0.0 * dt * dXdt[i*COORD_DIM+2][j];
+
+                S1.Elem(i, 0)[j] += 0.5 * dt * dXdt[i*COORD_DIM+0][j];
+                S1.Elem(i, 1)[j] += 0.5 * dt * dXdt[i*COORD_DIM+1][j];
+                S1.Elem(i, 2)[j] += 0.5 * dt * dXdt[i*COORD_DIM+2][j];
+
+                S2.Elem(i, 0)[j] += 1.0 * dt * dXdt[i*COORD_DIM+0][j];
+                S2.Elem(i, 1)[j] += 1.0 * dt * dXdt[i*COORD_DIM+1][j];
+                S2.Elem(i, 2)[j] += 1.0 * dt * dXdt[i*COORD_DIM+2][j];
+              }
+            }
+            Real g0 = compute_g(S0, pressure, flux_tor, flux_pol);
+            Real g1 = compute_g(S1, pressure, flux_tor, flux_pol);
+            Real g2 = compute_g(S2, pressure, flux_tor, flux_pol);
+            { // Calculate optimal step size dt
+              Real a = 2*g0 - 4*g1 + 2*g2;
+              Real b =-3*g0 + 4*g1 -   g2;
+              Real c = g0;
+              Real s = -b/(2*a);
+              dt *= s;
+
+              Real g_ = a*s*s + b*s + c;
+              std::cout<<"g = "<<g_<<' ';
+              std::cout<<g0<<' ';
+              std::cout<<g1<<' ';
+              std::cout<<g2<<' ';
+              std::cout<<dt<<'\n';
+            }
+
+            for (Long i = 0; i < S.NElem(); i++) {
+              for (Long j = 0; j < Nnodes; j++) {
+                S.Elem(i, 0)[j] += dt * dXdt[i*COORD_DIM+0][j];
+                S.Elem(i, 1)[j] += dt * dXdt[i*COORD_DIM+1][j];
+                S.Elem(i, 2)[j] += dt * dXdt[i*COORD_DIM+2][j];
+              }
+            }
+          }
+          iter++;
+
+          Vector<ElemBasis> pressure_jump = compute_pressure_jump(S, pressure, flux_tor, flux_pol);
+          { // Write VTU
+            VTUData vtu;
+            vtu.AddElems(S.GetElemList(), dgdnu, ORDER);
+            vtu.WriteVTK("dgdnu"+std::to_string(iter), comm);
+          }
+          { // Write VTU
+            VTUData vtu;
+            vtu.AddElems(S.GetElemList(), pressure_jump, ORDER);
+            vtu.WriteVTK("pressure_jump"+std::to_string(iter), comm);
+          }
+        }
+
+        return;
+      }
 
       { // Verify using finite difference approximation
         Vector<ElemBasis> dgdnu = compute_gradient(S, pressure, flux_tor, flux_pol);