|
@@ -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);
|