Major update: Computing average IPVar over time period, rewriting last time...
Major update: Computing average IPVar over time period, rewriting last time step value with time averaged value
Merge request reports
Activity
40 40 return *this; 41 41 }; 42 42 virtual double get(const int i) const{return 0.;} // Allow to get any component defined in the ipvariable 43 virtual double & getRef(const int i){ static double temp = 0.0; return temp; }; // Allow to get access to any component value defined in the ipvariable 3844 avgValue += IPVariableOverTime.at(t).at(eleNum).at(j); 3845 } 3846 } 3847 avgValue /= count; 3848 tempMap.emplace(j, avgValue); 3849 } 3850 avgIPVariable.emplace(eleNum, tempMap); 3851 } 3852 } 3853 } 3854 } 3855 Msg::Info("Done computing average IPVariable over time period"); 3856 } 3857 3858 void nonLinearMechSolver::rewriteIPDataOnPhysical(const std::map< std::size_t, std::map< int, double > > & avgIPVariable) 3859 { Note: Process implemented such that at last time step in EM solver we compute the average value of given IPVariable over a given time period. Then we rewrite the said IPVariable value at the last time step with averaged value. With this, after saveInternalState procedure the averaged value will be imported as an initial value in TM solver after loadInternalState.
To rewrite the last step value of IPVarialbe we had to implement a new getRef function.
3881 3882 for (int idom = 0; idom < domainVector.size(); idom++) 3883 { 3884 partDomain *dom = domainVector[idom]; 3885 if (dom->g_find(ele)) 3886 { 3887 IntPt *GP; 3888 const int npts = dom->getBulkGaussIntegrationRule()->getIntPoints(ele, &GP); 3889 3890 // loop over each Gauss point 3891 for (int j = 0; j < npts; j++) 3892 { 3893 // here can check GP against std::map coordinates for correctness 3894 3895 double & ThermalEMFieldSource = ips[j]->getState(IPStateBase::current)->getRef(IPField::Output(ipval)); 3896 ThermalEMFieldSource = avgIPVariable.at(eleNum).at(j); 3818 for (int idom = 0; idom < domainVector.size(); idom++) 3819 { 3820 partDomain *dom = domainVector[idom]; 3821 if (dom->g_find(ele)) 3822 { 3823 IntPt *GP; 3824 const int npts = dom->getBulkGaussIntegrationRule()->getIntPoints(ele, &GP); 3825 std::map< int, double > tempMap; 3826 3827 // loop over each Gauss point 3828 for (int j = 0; j < npts; j++) 3829 { 3830 double avgValue = 0.0; 3831 int count = 0; 3832 3833 // here can check GP against std::map coordinates for correctness Need to update for this check
Can check current GP coords against stored std::map coords for correct element (in between undeformed and deformed mesh case).
Edited by Vinayak Gholap
3848 3849 if(t >= tstart && t <= tend) 3849 3850 { 3850 3851 count++; 3852 sum_dt += t; 3851 3853 3852 3854 // compute average of IPVariable over given time period 3853 avgValue += IPVariableOverTime.at(t).at(eleNum).at(j); 3855 //avgValue += IPVariableOverTime.at(t).at(eleNum).at(j); 3856 3857 // sum(w_AV * dt) 3858 avgValue += (IPVariableOverTime.at(t).at(eleNum).at(j)) * t; 3854 3859 } 3855 3860 } 3856 avgValue /= count; 3861 //avgValue /= count; 3862 avgValue /= sum_dt; 3847 3850 { 3848 3851 const double t = it->first; 3852 t_i = it->first; 3849 3853 if(t >= tstart && t <= tend) 3850 3854 { 3851 3855 count++; 3852 sum_dt += t; 3856 dt = (t_i - t_0); 3857 sum_dt += dt; 3853 3858 3854 3859 // compute average of IPVariable over given time period 3855 3860 //avgValue += IPVariableOverTime.at(t).at(eleNum).at(j); 3856 3861 3857 3862 // sum(w_AV * dt) 3858 avgValue += (IPVariableOverTime.at(t).at(eleNum).at(j)) * t; 3863 avgValue += (IPVariableOverTime.at(t).at(eleNum).at(j)) * dt; Mistake: w_AV * current time
Correction: w_AV * time-step size
Note: If time-step size dt is constant, this leads to mean of w_AV.
Edited by Vinayak Gholap
58 58 # material law: vacuum/free space region 59 59 lawnumvac = 3 60 60 rhovac = 1.2 61 Gvac=156.e0 # Shear modulus 61 Gvac=156.e1 # Shear modulus 62 62 Muvac = 0.35 # Poisson ratio 63 63 Evac= 2.0 * Gvac * (1.0 + Muvac) #youngs modulus 64 64 alphavac = betavac = gammavac = 0. # parameter of anisotropy 65 cpvac= 1012.*rhovac 66 Kxvac=Kyvac=Kzvac= 26.e-3 # thermal conductivity tensor components 65 cpvac= 1.e-12 #1012.*rhovac Note: Cannot use cp = 0. for air in strong coupling test since solver fails to converge due to stiffness matrix.
Edited by Vinayak Gholap
65 65 Muvac = 0.35 # Poisson ratio (same as SMP) 66 66 Evac= 2.0 * Gvac * (1.0 + Muvac) #youngs modulus 67 67 alphavac = betavac = gammavac = 0. # parameter of anisotropy 68 cpvac= 1012.*rhovac 69 Kxvac=Kyvac=Kzvac= 26.e-3 # thermal conductivity tensor components 68 cpvac= 0.0 #1012.*rhovac 82 82 sol = 2 # Gmm=0 (default) Taucs=1 PETsc=2 83 83 soltype = 1 # StaticLinear=0 (default) StaticNonLinear=1 84 84 #EMncycles = 5; # num of sinusoidal cycles of EM frequency application 85 nstep = 80 # 8*EMncycles # number of step (used only if soltype=1) 85 nstep = 200 # 8*EMncycles # number of step (used only if soltype=1) 86 86 ftime = 5.e-3 # EMncycles/freq; # according to characteristic time 87 87 #EMftime = EMncycles/freq # Final time (used only if soltype=1) 88 88 tol=1.e-6 # relative tolerance for NR scheme (used only if soltype=1) 89 89 nstepArch=1 # Number of step between 2 archiving (used only if soltype=1) 90 90 fullDg = 0 #O = CG, 1 = DG 91 91 beta1 = 1000. 92 eqRatio =1.e8 92 eqRatio =1.e0 259 Rint = {200*cm, Min 0.15, Max 0.9, Step 0.1, Name StrCat[pp2, "7Inner [m]"], 260 Visible (Flag_Infinity==1), Highlight Str[colorpp] }, 261 Rext = {280*cm, Min Rint, Max 1, Step 0.1, Name StrCat[pp2, StrCat["8", label_Rext]], 262 Visible 1, Highlight Str[colorpp] } 263 ]; 264 /* 265 lc0 = Pi*Rint/6; // air 266 Characteristic Length { PointsOf{ Volume{v4}; } } = lc0; 267 268 lc1 = 2*wcoil/2; // coil 269 Characteristic Length { PointsOf{ Volume{e(1)}; } } = lc1; 270 */ 271 //Mesh 2; 272 //Mesh 3; 273 //Mesh.SaveAll = 1; 274 //Save "mergedMesh.msh"; Added new merge mesh file which:
- Takes new point, curve, curve loop, surface, surface loop and volume IDs automatically.
- Uses Transfinite Curve and Transfinite Surface for coil domain
- Extrudes coil domain using Layers
Earlier merge mesh file resulted in errors due to existing IDs for points and curves that were hand-coded numbers.
401 403 ThermalEMFieldSource += (sourceVectorField(i) * ((An(i) - A0(i)) * invdh) /*+ H(i) * (Bn(i) - B0(i)) * invdh*/); 402 404 405 // to debug weak vs strong coupling results by 406 // using analytical EM thermal source in SMP only with 407 // A²/2 being mean value that is calculated 408 // in weak coupling for considered parameter values 409 410 /* 411 if(this->_num == 1) // if SMP 412 // A² cos²(2 pi f t) 413 // A²/2 = Mean value over one period = 3559017.23076498 414 ThermalEMFieldSource = 2.0 * 2227580. * std::cos(2.0 * M_PI * _freqEM * ctime) * 415 std::cos(2.0 * M_PI * _freqEM * ctime); 416 else 417 ThermalEMFieldSource = 0.0; 418 */ Note: I will need to update the value used depending on f, I used.
Use when comparing the resulting thermal field in SMP with EM thermal source computed analytically in the strong coupling test example (only SMP domain with no resolution of EM fields) with EM value (A²/2) imported from weak coupling test.
390 390 STensorOperation::zero(dqdF); 391 391 392 STensor3 Ft; 393 STensorOperation::unity(Ft); 394 //if (!evaluateCurlField) 395 //Ft = Fn; 396 392 397 for(int i=0;i<3;i++) 393 398 { 394 399 fluxT(i)=0.; 395 400 for(int j=0;j<3;j++) 401 //for(int k = 0; k < 3; ++k) 396 402 { 397 fluxT(i)+=(_k(i,j)+_l0(i,j)*_seebeck*_seebeck*T)*gradT(j)+_l0(i,j)*_seebeck*T*gradV(j); 398 fluxjy(i)+=(_k(i,j)+_l0(i,j)*_seebeck*_seebeck*T+_l0(i,j)*_seebeck*V)*gradT(j)+(_l0(i,j)*V+_l0(i,j)*_seebeck*T)*gradV(j); 403 fluxT(i)+=(_k(i,j)+_l0(i,j)*_seebeck*_seebeck*T)*gradT(j)+_l0(i,j)*_seebeck*T/**Ft(k,j)*/*gradV(j); 1 #coding-Utf-8-*- 2 from gmshpy import * 3 4 5 #from dG3DpyDebug import* 6 from dG3Dpy import* 7 8 #script to launch unit test to debug strong vs weak coupling in SMP 9 10 # Here strong coupled EM-TM in SMP only with analytically computed EM thermal source 11 # No solution of EM fields but directly EM thermal source is imported to 12 # resolve TM in SMP 13 14 # Need to uncomment in mlawLinearEMTM 15 # wAV = A² cos² (2 pi f t) 16 # with A²/2 = mean computed over one period for considered f, I from weak coupling test 807 // derivatives with deformation gradient 808 if(stiff) 809 { 810 for(int K = 0; K< 3; K++) 811 { 812 for(int m = 0; m< 3; m++) 813 { 814 for(int N = 0; N< 3; N++) 815 { 816 for(int P = 0; P < 3; ++P) 817 { 818 for(int Q = 0; Q < 3; ++Q) 819 { 820 for(int L = 0; L< 3; L++) 821 { 822 // missing mult with dFrefdFn 829 dedF(K,m,N) -= FRefInv(K,Q) * lt(P,L) * dFRefdFn(Q,P,m,N) * ((An(L) - A0(L)) * invdh); 830 dedF(K,m,N) -= FRefInv(L,Q) * lt(K,P) * dFRefdFn(Q,P,m,N) * ((An(L) - A0(L)) * invdh); 831 dedF(K,m,N) += FRefInv(P,Q) * lt(K,L) * dFRefdFn(Q,P,m,N) * ((An(L) - A0(L)) * invdh); 832 833 dqdF(K,m,N) -= FRefInv(K,Q) * lt(P,L) * dFRefdFn(Q,P,m,N) * _seebeck * T * gradV(L); 834 dqdF(K,m,N) -= FRefInv(L,Q) * lt(K,P) * dFRefdFn(Q,P,m,N) * _seebeck * T * gradV(L); 835 dqdF(K,m,N) += FRefInv(P,Q) * lt(K,L) * dFRefdFn(Q,P,m,N) * _seebeck * T * gradV(L); 836 dqdF(K,m,N) -= FRefInv(K,Q) * lt(P,L) * dFRefdFn(Q,P,m,N) * _seebeck * _seebeck * T * gradT(L); 837 dqdF(K,m,N) -= FRefInv(L,Q) * lt(K,P) * dFRefdFn(Q,P,m,N) * _seebeck * _seebeck * T * gradT(L); 838 dqdF(K,m,N) += FRefInv(P,Q) * lt(K,L) * dFRefdFn(Q,P,m,N) * _seebeck * _seebeck * T * gradT(L); 839 dqdF(K,m,N) -= FRefInv(K,Q) * lt(P,L) * dFRefdFn(Q,P,m,N) * _seebeck * T * ((An(L) - A0(L)) * invdh); 840 dqdF(K,m,N) -= FRefInv(L,Q) * lt(K,P) * dFRefdFn(Q,P,m,N) * _seebeck * T * ((An(L) - A0(L)) * invdh); 841 dqdF(K,m,N) += FRefInv(P,Q) * lt(K,L) * dFRefdFn(Q,P,m,N) * _seebeck * T * ((An(L) - A0(L)) * invdh); 842 843 // need to check this 844 dHdF(K,m,N) -= FRefInv(P,Q) * nut(K,L) * dFRefdFn(Q,P,m,N) * B(L); 476 508 { 477 509 for(int j = 0; j< 3; j++) 478 510 { 479 lt(K,L) += Fn(K,i) * _l0(i,j) * Fn(L,j); 480 nut(K,L) += Fninv(i,K) * _nu0(i,j) * Fninv(j,L); // <<-- Diff transformation 481 mut(K,L) += Fn(K,i) * _mu0(i,j) * Fn(L,j); 511 // considering pull-back to reference config 512 lt(K,L) += FRefInv(K,i) * _l0(i,j) * FRefInv(L,j); 513 nut(K,L) += FRef(i,K) * _nu0(i,j) * FRef(j,L); // <<-- Diff transformation 514 mut(K,L) += FRefInv(K,i) * _mu0(i,j) * FRefInv(L,j); 515 516 kt(K,L) += FRefInv(K,i) * k_(i,j) * FRefInv(L,j); 517 518 // considering push-forward to intermediate config Here I might need a flag to decide if pull-back or push-forward for relevant properties.
In strong coupling: always pull-back to ref config for all props. In weak coupling: might be push-forward to intermediate config for EM props in EM problem and pull-back for TM props to ref config in TM problem.
96 96 Printf("surf = %g", e(9)); 97 97 */ 98 98 99 Transfinite Surface {e(2),e(3),e(4),e(5),e(6),e(7),e(8),e(9)}; 99 //#Transfinite Surface {e(2),e(3),e(4),e(5),e(6),e(7),e(8),e(9)}; 61 61 # material law: vacuum/free space region 62 62 lawnumvac = 7 63 63 rhovac = 1.2 64 Gvac=156.e1 # Shear modulus (1.e-5 less than SMP) 65 Muvac = 0.35 # Poisson ratio (same as SMP) 64 Gvac=156.e3 # Shear modulus (1.e-5 less than SMP) 65 Muvac = 0.45 # Poisson ratio (same as SMP) 127 128 128 129 # ElecMag Generic Thermo-Mech law for smp 129 130 lawsmp = ElecMagGenericThermoMechanicsDG3DMaterialLaw(lawnum+2,rho,alpha,beta,gamma,lx,ly,lz,seebeck,v0,mag_mu_x, 130 mag_mu_y,mag_mu_z,magpot0_x,magpot0_y, magpot0_z, Irms, freq, nTurnsCoil, coilLx, coilLy, coilLz, coilW,useFluxT,evaluateCurlField) 131 mag_mu_y,mag_mu_z,magpot0_x,magpot0_y, magpot0_z, Irms, freq, nTurnsCoil, coilLx, coilLy, coilLz, coilW,useFluxT,evaluateCurlField,evaluateTemperature) 131 132 132 133 lawsmp.setThermoMechanicalMaterialLaw(lawTM); 134 lawsmp.setApplyReferenceF(False); 70 71 71 72 # material law for smp 72 73 # Mechanical law 73 sy0=1e10 74 sy0=1e16 74 75 h=1.e9 75 76 harden = LinearExponentialJ2IsotropicHardening(1, sy0, h, 0., 10.) 76 77 lawMech = J2LinearDG3DMaterialLaw(lawnum,rho,E_matrix,Mu,harden) 78 lawMech.setStrainOrder(-1) 77 79 78 80 # Generic Thermo-Mech law 79 81 lawTM = GenericThermoMechanicsDG3DMaterialLaw(lawnum+1,rho,alpha,beta,gamma,tinitial,Kx,Ky,Kz,alphaTherm,alphaTherm,alphaTherm,cp) 80 82 lawTM.setMechanicalMaterialLaw(lawMech); 81 lawTM.setApplyReferenceF(True); 83 lawTM.setApplyReferenceF(False); 74 74 Surface(s1) = {cl1, cl2}; 75 75 //+ 76 76 77 Transfinite Curve {c1,c2,c3,c4} = 11 Using Progression 1; 238 240 mysolver.addDomain(SMP_field) 239 241 mysolver.addDomain(Inductor_field) 240 242 mysolver.addDomain(Vacuum_field) 241 mysolver.addMaterialLaw(lawsmp) 243 mysolver.addMaterialLaw(pertLawsmp) 242 244 mysolver.addMaterialLaw(lawind) 243 mysolver.addMaterialLaw(lawvac) 245 mysolver.addMaterialLaw(pertLawvac) 217 218 mysolver.addDomain(SMP_field) 218 219 mysolver.addDomain(Inductor_field) 219 220 mysolver.addDomain(Vacuum_field) 220 mysolver.addMaterialLaw(lawsmp) 221 mysolver.addMaterialLaw(pertLawsmp) 221 222 mysolver.addMaterialLaw(lawind) 222 mysolver.addMaterialLaw(lawvac) 223 mysolver.addMaterialLaw(pertLawvac) In weak coupling EM problem: -Push forward from Reference config to intermediate config with F_TM -Pull-back from current config to intermediate config with Fn = I (since no deformations in weak coupling EM problem) -applyReferenceF = True for SMP domain only
In weak coupling TM problem: -Pull-back from current to reference config with Fn = F_TM (applyReferenceF = False)
In strong coupling: -Always Pull-back with Fn and with applyReferenceF = False
558 567 STensorOperation::multSTensor3(FRefTranspose,FRef,C); 559 568 STensorOperation::multSTensor3(C,C,C_squared); 560 const double vacuum_permeability = 4.0 * M_PI * 1.e-7; 561 569 570 // in case of strong coupling 562 571 for(unsigned int i = 0; i < 3; ++i) 563 572 for(unsigned int j = 0; j < 3; ++j) 564 573 { 565 nu_ref(i,j) = 1.0/(2.0 * JacRef * vacuum_permeability) * C(i,j) 566 - (rho)/(_mu_7) * I2(i,j) 567 - (rho)/(_mu_8) * C(i,j) 568 - (rho)/(_mu_9) * C_squared(i,j); 574 nu_ref(i,j) = 1.0/(JacRef * vacuum_permeability) * C(i,j) 575 + (2.0 * rho)/(_mu_7) * I2(i,j) 576 + (2.0 * rho)/(_mu_8) * C(i,j) 577 + (2.0 * rho)/(_mu_9) * C_squared(i,j); 596 605 { 597 606 // considering pull-back from intermediate to reference config 598 607 lt(K,L) += FnInv(K,i) * ltTemp(i,j) * FnInv(L,j); 599 nut(K,L) += Fn(i,K) * nutTemp(i,j) * Fn(j,L); // <<-- Diff transformation 600 mut(K,L) += FnInv(K,i) * mutTemp(i,j) * FnInv(L,j); 601 602 608 kt(K,L) += FnInv(K,i) * ktTemp(i,j) * FnInv(L,j); 609 //--nut(K,L) += Fn(i,K) * nutTemp(i,j) * Fn(j,L); // <<-- Diff transformation 610 //--mut(K,L) += FnInv(K,i) * mutTemp(i,j) * FnInv(L,j); 611 nu_ref(K,L) += Fn(i,K) * nutTemp(i,j) * Fn(j,L); 961 963 dqdF(K,m,N) -= FRefInv(L,Q) * lt(K,P) * dFRefdFn(Q,P,m,N) * _seebeck * T * ((An(L) - A0(L)) * invdh); 962 964 dqdF(K,m,N) += FRefInv(P,Q) * lt(K,L) * dFRefdFn(Q,P,m,N) * _seebeck * T * ((An(L) - A0(L)) * invdh); 963 965 964 // need to check this 966 // need to check this after using nu_ref 965 967 dHdF(K,m,N) -= FRefInv(P,Q) * nut(K,L) * dFRefdFn(Q,P,m,N) * B(L); mentioned in commit 9111dd45