// BHData.cpp : implementation file // #include "stdafx.h" #include "femm.h" #include "BHData.h" #include "fullmatrix.h" #include "BHPlot.h" #include "BHDatafile.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBHData dialog CBHData::CBHData(CWnd* pParent /*=NULL*/) : CDialog(CBHData::IDD, pParent) { //{{AFX_DATA_INIT(CBHData) m_Bdata = _T(""); m_Hdata = _T(""); m_BHname = _T(""); //}}AFX_DATA_INIT logplot=FALSE; } void CBHData::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBHData) DDX_Text(pDX, IDC_BDATA, m_Bdata); DDX_Text(pDX, IDC_HDATA, m_Hdata); DDX_Text(pDX, IDC_BHNAME, m_BHname); //}}AFX_DATA_MAP DDX_Control(pDX, IDC_BDATA, m_IDC_BDATA); DDX_Control(pDX, IDC_HDATA, m_IDC_HDATA); } BEGIN_MESSAGE_MAP(CBHData, CDialog) //{{AFX_MSG_MAP(CBHData) ON_BN_CLICKED(IDC_PLOT_BHCURVE, OnPlotBHcurve) ON_BN_CLICKED(IDC_LOGPLOT_BHCURVE, OnLogPlotBHcurve) ON_BN_CLICKED(IDC_READ_BHCURVE, OnReadBhcurve) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBHData message handlers void CBHData::StripBHData() { int k; char *buff,*nptr,*endptr; double z; B.RemoveAll(); H.RemoveAll(); BHpoints=0; if((m_Bdata.GetLength()==0) || (m_Hdata.GetLength()==0)) return; k=m_Bdata.GetLength()*2; buff=(char *)calloc(k,sizeof(char)); strcpy(buff,m_Bdata); nptr=buff; while (sscanf(nptr,"%lf",&z)!=EOF){ z=strtod(nptr,&endptr ); if(nptr==endptr) nptr++; //catch special case else nptr=endptr; if(B.GetSize()>0){ // enforce monotonicity if (z<=B[B.GetSize()-1]) break; } else if(z!=0) B.Add(0); B.Add(z); } free(buff); k=m_Hdata.GetLength()*2; buff=(char *)calloc(k,sizeof(char)); strcpy(buff,m_Hdata); nptr=buff; while (sscanf(nptr,"%lf",&z)!=EOF){ z=strtod(nptr,&endptr ); if(nptr==endptr) nptr++; else nptr=endptr; if(H.GetSize()>0){ if (z<=H[H.GetSize()-1]) break; } else if(z!=0) H.Add(0); H.Add(z); } BHpoints=(int) B.GetSize(); if ((int) H.GetSize()0) { u0=sqrt(u0); X0=-(c1 + u0)/(2.*c2); X1=(-c1 + u0)/(2.*c2); } //now, see if we've struck gold! if (((X0>=0.)&&(X0<=L))||((X1>=0.)&&(X1<=L))) CurveOK=FALSE; } if(CurveOK!=TRUE) //remedial action { // Smooth out input points // to get rid of rapid transitions; // Uses a 3-point moving average for(i=1;i3.*m1) || (slope[i]>3.*m2)) { H[i]=(8.*H[i]+H[i-1]+H[i+1])/10.; B[i]=(8.*B[i]+B[i-1]+B[i+1])/10.; bDone=FALSE; } } }while(!bDone); // do endpoints slope[0]=(H[1]-H[0])/(B[1]-B[0]); slope[i]=(H[i]-H[i-1])/(B[i]-B[i-1]); return; } */ double CBHData::GetH(double x) { double b,h,z,z2,l; int i; b=fabs(x); if ((BHpoints==0) || (b==0)) return 0; if(b>B[BHpoints-1]) return (H[BHpoints-1] + slope[BHpoints-1]*(b-B[BHpoints-1])); for(i=0;i=B[i]) && (b<=B[i+1])){ l=(B[i+1]-B[i]); z=(b-B[i])/l; z2=z*z; h=(1.-3.*z2+2.*z2*z)*H[i] + z*(1.-2.*z+z2)*l*slope[i] + z2*(3.-2.*z)*H[i+1] + z2*(z-1.)*l*slope[i+1]; return h; } return 0; } void CBHData::OnLogPlotBHcurve() { logplot=TRUE; OnPlotBHcurve(); } void CBHData::OnPlotBHcurve() { CBHPlot xyplot; int i; double b,db; BOOL logscale=logplot; logplot=FALSE; slope=NULL; UpdateData(); StripBHData(); if (BHpoints<3){ MsgBox("Must have at least 3 pairs of data points"); return; } // copy raw B-H data for plotting in comparison to // splined (and possibly smoothed) curve xyplot.NumPts=BHpoints; xyplot.Pts=(CComplex *)calloc(BHpoints,sizeof(CComplex)); for(i=0;iGetExecutablePath(); // Actually evaluate all the points on the line... if(xyplot.Create(101,2)==FALSE){ free(slope); return; } db=(B[BHpoints-1]-B[0])/100.; for(i=0,b=B[0];i<=100;i++,b+=db) { xyplot.M[i][1]=b; xyplot.M[i][0]=GetH(b); } sprintf(xyplot.lbls[0],"H, Amp/Meter"); sprintf(xyplot.lbls[1],"B, Tesla"); // Create the plot, send it to the clipboard, spawn viewer... CMetaFileDC Meta; Meta.CreateEnhanced(NULL,NULL,NULL,NULL); xyplot.MakePlot(&Meta,logscale); HENHMETAFILE hMeta=Meta.CloseEnhanced(); if (hMeta==NULL) MsgBox("No Handle..."); if (OpenClipboard()==FALSE) MsgBox("Cannot access the Clipboard"); else{ EmptyClipboard(); if(SetClipboardData(CF_ENHMETAFILE,hMeta)==NULL) { MsgBox("Couldn't SetClipboardData"); } CloseClipboard(); // fire up plot viewer; // ((CFemmApp *)AfxGetApp())->CreateNewDocument(8); // in this case call the external program rather than // displaying in the window. Since dialog is running modal, // it obscures the plotted BH curve--this is an annoying kludge. char CommandLine[MAX_PATH]; sprintf(CommandLine,"%sfemmplot.exe", (const char *) ((CFemmApp *)AfxGetApp())->GetExecutablePath()); STARTUPINFO StartupInfo2 = {0}; PROCESS_INFORMATION ProcessInfo2; StartupInfo2.cb = sizeof(STARTUPINFO); CreateProcess(NULL,CommandLine, NULL, NULL, FALSE,0, NULL, NULL, &StartupInfo2, &ProcessInfo2); CloseHandle(ProcessInfo2.hProcess); CloseHandle(ProcessInfo2.hThread); } if (slope!=NULL) free(slope); } void CBHData::OnReadBhcurve() { // TODO: Add your control notification handler code here CFileDialog *fname_dia; CString infile; fname_dia=new CFileDialog( TRUE, "dat | * ", infile, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Two column text data file (*.dat) | *.dat; *.DAT | All Files (*.*) | *.*||", NULL); if(fname_dia->DoModal()==IDCANCEL){ delete[] fname_dia; return; } infile=fname_dia->GetPathName(); delete[] fname_dia; CBHDatafile dlg; if(dlg.DoModal()==IDCANCEL) return; // read in data from text file; m_Bdata.Empty(); m_Hdata.Empty(); double bunits[]={1.,0.0001,0.1}; double hunits[]={1.,1000.,79.5775,79577.5}; char s[1024]; double b_in,h_in,b_off,h_off; b_off=0;h_off=0; FILE *fp=fopen(infile,"rt"); if (fp==NULL){ MsgBox("problem opening data file"); return; } do{ if(fgets(s,1024,fp)==NULL) break; if(dlg.BHOrder==0) sscanf(s,"%lf %lf",&b_in,&h_in); else sscanf(s,"%lf %lf",&h_in,&b_in); b_in *= bunits[dlg.BUnits]; if ((b_off==0) && (b_in<0)) b_off=fabs(b_in); b_in += b_off; h_in *= hunits[dlg.HUnits]; if ((h_off==0) && (h_in<0)) h_off=fabs(h_in); h_in += h_off; sprintf(s,"%f\r\n",b_in); m_Bdata += s; sprintf(s,"%f\r\n",h_in); m_Hdata += s; } while(1>0); SetDlgItemText(IDC_BDATA,m_Bdata); SetDlgItemText(IDC_HDATA,m_Hdata); fclose(fp); if(h_off!=0){ sprintf(s,"Suggested Hc = %.0f A/m",h_off); AfxMessageBox(s,MB_ICONINFORMATION); } }