/* Copyright (C) 2001 Gopal Narayanan This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * microstrip.c - Puts up window for microstrip and * performs the associated calculations */ #include #include #include #include #include #include "unitscombo.h" #include "coax.h" gboolean doutfixed, dinfixed; extern void error_mes (char *); /* * get_coax_sub * get and assign coax substrate parameters * into coax structure */ void get_coax_sub (trans_win *cwin, coax *cx) { if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->subparam_text[0])), "%g", &cx->er) != 1) error_mes("Error: cx->er"); if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->subparam_text[1])), "%g", &cx->mur) != 1) error_mes("Error: cx->mur"); if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->subparam_text[2])), "%g", &cx->tand) != 1) error_mes("Error: cx->tand"); if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->subparam_text[3])), "%g", &cx->sigma) != 1) error_mes("Error: cx->sigma"); } /* * get_coax_comp * get and assign coax component parameters * into coax structure */ void get_coax_comp (trans_win *cwin, coax *cx) { short curr_unit; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->component_param_text[0])), "%g", &cx->f) != 1) error_mes("Error: cx->f"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->component_param_combo[0])->entry))); cx->f = cx->f * conv_freq[curr_unit][FREQ_HZ]; } /* * get_coax_elec * get and assign coax electrical parameters * into coax structure */ void get_coax_elec (trans_win *cwin, coax *cx) { short curr_unit; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->electrical_param_text[0])), "%g", &cx->Z0) != 1) error_mes("Error: cx->Z0"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->electrical_param_combo[0])->entry))); cx->Z0 = cx->Z0 * conv_res[curr_unit][RES_OHM]; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->electrical_param_text[1])), "%g", &cx->ang_l) != 1) error_mes("Error: cx->ang_l"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->electrical_param_combo[1])->entry))); cx->ang_l = cx->ang_l * conv_ang[curr_unit][ANG_RAD]; } /* * get_coax_phys * get and assign coax physical parameters * into coax structure */ void get_coax_phys (trans_win *cwin, coax *cx) { short curr_unit; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->physical_param_text[0])), "%g", &cx->din) != 1) error_mes("Error: cx->din"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->physical_param_combo[0])->entry))); cx->din = cx->din * conv_length[curr_unit][LENGTH_M]; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->physical_param_text[1])), "%g", &cx->dout) != 1) error_mes("Error: cx->dout"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->physical_param_combo[1])->entry))); cx->dout = cx->dout * conv_length[curr_unit][LENGTH_M]; if (sscanf (gtk_entry_get_text(GTK_ENTRY (cwin->physical_param_text[2])), "%g", &cx->l) != 1) error_mes("Error: cx->l"); curr_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->physical_param_combo[2])->entry))); cx->l = cx->l * conv_length[curr_unit][LENGTH_M]; } void fixdin (GtkWidget *parent, trans_win *cwin) { gtk_label_set_text (GTK_LABEL (GTK_BIN (parent)->child), "Fixed"); gtk_widget_set_sensitive (GTK_WIDGET (parent), FALSE); gtk_label_set_text (GTK_LABEL (GTK_BIN (cwin->physical_param_fix[1])->child), "Fix"); gtk_widget_set_sensitive (GTK_WIDGET (cwin->physical_param_fix[1]), TRUE); dinfixed = TRUE; doutfixed = FALSE; } void fixdout (GtkWidget *parent, trans_win *cwin) { gtk_label_set_text (GTK_LABEL (GTK_BIN (parent)->child), "Fixed"); gtk_widget_set_sensitive (GTK_WIDGET (parent), FALSE); gtk_label_set_text (GTK_LABEL (GTK_BIN (cwin->physical_param_fix[0])->child), "Fix"); gtk_widget_set_sensitive (GTK_WIDGET (cwin->physical_param_fix[0]), TRUE); dinfixed = FALSE; doutfixed = TRUE; } gfloat alphad_coax (coax *cx) { gfloat f, er, tand, ad; f = cx->f; er = cx->er; tand = cx->tand; ad = (M_PI/C0) * f * sqrt(er) * tand; ad = ad * 8.686; return ad; } gfloat alphac_coax (coax *cx) { gfloat er, mur, din, dout; gfloat f, Rs, sigma; gfloat ac; er = cx->er; mur = cx->mur; sigma = cx->sigma; f = cx->f; din = cx->din; dout = cx->dout; Rs = sqrt((M_PI * f * mur* MU0)/sigma); ac = (0.5 * sqrt(er)) * (((1/din) + (1/dout))/log(dout/din)) * (Rs/(120. * M_PI)); ac = ac * 8.686; return ac; } /* * analyze_coax - analysis function */ void analyze_coax (GtkWidget *parent, trans_win *cwin) { gchar *text, *results, *temp; coax *cx; short required_unit; gfloat lambda_g; short m, n; gfloat fc; /*allocate memory for text */ if ((text = (char *) malloc(10*sizeof(char))) == NULL){ perror("text error: malloc"); exit(-1); } /*allocate memory for pointer cx */ if ((cx = g_malloc(sizeof *cx)) != NULL) { /* Get and assign substrate parameters */ get_coax_sub(cwin, cx); /* Get and assign component parameters */ get_coax_comp(cwin, cx); /* Get and assign physical parameters */ get_coax_phys(cwin, cx); if (cx->din != 0.0){ cx->Z0 = (60.0/sqrt(cx->er))*log(cx->dout/cx->din); } lambda_g = (C0/(cx->f))/sqrt(cx->er * cx->mur); /* calculate electrical angle */ cx->ang_l = (2.0 * M_PI * cx->l)/lambda_g; /* in radians */ cx->atten_dielectric = alphad_coax (cx) * cx->l; cx->atten_cond = alphac_coax (cx) * cx->l; required_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (cwin->electrical_param_combo[0])->entry))); sprintf(text,"%g", (float) (cx->Z0 * conv_res[RES_OHM][required_unit])); gtk_entry_set_text (GTK_ENTRY (cwin->electrical_param_text[0]), text); required_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(cwin->electrical_param_combo[1])->entry))); sprintf(text,"%g", (float) (cx->ang_l * conv_ang[ANG_RAD][required_unit])); gtk_entry_set_text (GTK_ENTRY (cwin->electrical_param_text[1]), text); free(text); if ((text = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } if ((results = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } if ((temp = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } sprintf(results,"Conductor Losses = %.4g dB\n", cx->atten_cond); sprintf(text, "Dielectric Losses = %.4g dB\n", cx->atten_dielectric); strcat(results, text); n = 1; fc = C0 / (M_PI * (cx->dout + cx->din)/(float) n); if (fc <= cx->f) { strcpy(text, "\nWarning: The following additional \nTE modes can propagate:\n TE(1,1) "); strcat(results, text); strcpy(text, " "); m = 2; fc = C0 / (2 * (cx->dout - cx->din)/(float) (m-1)); while ((fc <= cx->f) && (m<10)) { sprintf(temp, "TE(n,%d) ",m); strcat(text,temp); m++; fc = C0 / (2 * (cx->dout - cx->din)/(float) (m-1)); } strcat(results, text); strcat(results,"\n\n"); } m = 1; fc = C0 / (2 * (cx->dout - cx->din)/(float) m); if (fc <= cx->f) { strcpy(text, "\nWarning: The following additional \nTM modes can propagate:\n"); strcat(results, text); strcpy(text, " "); while ((fc <= cx->f) && (m<10)) { sprintf(temp, "TM(n,%d) ",m); strcat(text,temp); m++; fc = C0 / (2 * (cx->dout - cx->din)/(float) m); } strcat(results,text); strcat(results,"\n"); } gtk_label_set (GTK_LABEL (cwin->results_text), results); free(results); free(text); free(temp); if (statusexists){ if (statusint != CONSISTENT) { gtk_label_set_text (GTK_LABEL (cwin->status), "Values are consistent"); } } statusint = CONSISTENT; } else { perror("malloc cx"); exit (-1); } } /* * synthesize_coax - synthesis function */ void synthesize_coax (GtkWidget *parent, trans_win *cwin) { gchar *text, *results, *temp; coax *cx; short required_unit; gfloat lambda_g; gfloat f, er, din, dout, Z0; gfloat fc; short m, n; /*allocate memory for text */ if ((text = (char *) malloc(10*sizeof(char))) == NULL){ perror("text error: malloc"); exit (-1); } /* allocate memory for cx */ if ((cx = g_malloc (sizeof *cx)) != NULL) { /* Get and assign substrate parameters */ get_coax_sub(cwin, cx); /* Get and assign component parameters */ get_coax_comp(cwin, cx); /* Get and assign electrical parameters */ get_coax_elec (cwin, cx); /* Get and assign physical parameters */ get_coax_phys(cwin, cx); f = cx->f; din = cx->din; dout = cx->dout; Z0 = cx->Z0; er = cx->er; if (doutfixed) { /* solve for din */ cx->din = dout / exp(Z0*sqrt(er)/60.0); required_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(cwin->physical_param_combo[0])->entry))); sprintf(text,"%g", (float) (cx->din * conv_length[LENGTH_M][required_unit])); gtk_entry_set_text (GTK_ENTRY (cwin->physical_param_text[0]), text); } else { /* solve for dout */ cx->dout = din * exp(Z0*sqrt(er)/60.0); required_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(cwin->physical_param_combo[1])->entry))); sprintf(text,"%g", (float) (cx->dout * conv_length[LENGTH_M][required_unit])); gtk_entry_set_text (GTK_ENTRY (cwin->physical_param_text[1]), text); } lambda_g = (C0/(cx->f))/sqrt(cx->er * cx->mur); /* calculate physical length */ cx->l = (lambda_g * cx->ang_l)/(2.0 * M_PI); /* in m */ required_unit = getunit (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(cwin->physical_param_combo[2])->entry))); sprintf(text,"%g", (float) (cx->l * conv_length[LENGTH_M][required_unit])); gtk_entry_set_text (GTK_ENTRY (cwin->physical_param_text[2]), text); cx->atten_dielectric = alphad_coax (cx) * cx->l; cx->atten_cond = alphac_coax (cx) * cx->l; free(text); if ((text = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } if ((results = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } if ((temp = (char *) malloc(1000*sizeof(char))) == NULL){ perror("results text error: malloc"); exit (-1); } sprintf(results,"Conductor Losses = %.4g dB\n", cx->atten_cond); sprintf(text, "Dielectric Losses = %.4g dB\n", cx->atten_dielectric); strcat(results, text); n = 1; fc = C0 / (M_PI * (cx->dout + cx->din)/(float) n); if (fc <= cx->f) { strcpy(text, "\nWarning: The following additional \nTE modes can propagate:\n TE(1,1) "); strcat(results, text); strcpy(text, " "); m = 2; fc = C0 / (2 * (cx->dout - cx->din)/(float) (m-1)); while ((fc <= cx->f) && (m<10)) { sprintf(temp, "TE(n,%d) ",m); strcat(text,temp); m++; fc = C0 / (2 * (cx->dout - cx->din)/(float) (m-1)); } strcat(results, text); strcat(results,"\n\n"); } m = 1; fc = C0 / (2 * (cx->dout - cx->din)/(float) m); if (fc <= cx->f) { strcpy(text, "\nWarning: The following additional \nTM modes can propagate:\n"); strcat(results, text); strcpy(text, " "); while ((fc <= cx->f) && (m<10)) { sprintf(temp, "TM(n,%d) ",m); strcat(text,temp); m++; fc = C0 / (2 * (cx->dout - cx->din)/(float) m); } strcat(results,text); strcat(results,"\n"); } gtk_label_set (GTK_LABEL (cwin->results_text), results); free(results); free(text); free(temp); if (statusexists){ if (statusint != CONSISTENT) { gtk_label_set_text (GTK_LABEL (cwin->status), "Values are consistent"); } } statusint = CONSISTENT; } else { perror("malloc cx"); exit (-1); } } /* * the window aspect */ void coax_win (GtkWidget *parent) { short row; /* if there is a window that already exists kill it first */ if (main_body_window != NULL) { gtk_widget_destroy(main_body_window); g_free (twin); twin = g_malloc(sizeof(*twin)); } setup_transgui(COAX, parent, twin); gtk_label_set_text (GTK_LABEL (GTK_BIN (twin->physical_param_fix[1])->child), "Fixed"); gtk_widget_set_sensitive (GTK_WIDGET (twin->physical_param_fix[1]), FALSE); doutfixed = TRUE; dinfixed = FALSE; for (row = 0; row<=1; row++) { switch(row) { case 0: gtk_signal_connect (GTK_OBJECT (twin->physical_param_fix[row]), "clicked", GTK_SIGNAL_FUNC (fixdin), twin); break; case 1: gtk_signal_connect (GTK_OBJECT (twin->physical_param_fix[row]), "clicked", GTK_SIGNAL_FUNC (fixdout), twin); break; } } gtk_signal_connect (GTK_OBJECT (twin->Analbutton), "clicked", GTK_SIGNAL_FUNC (analyze_coax), twin); gtk_signal_connect (GTK_OBJECT (twin->Synbutton), "clicked", GTK_SIGNAL_FUNC (synthesize_coax), twin); if (statusint == INCONSISTENT) { analyze_coax(parent, (trans_win *) twin); } for (row = 0; row<=1; row++){ gtk_signal_connect (GTK_OBJECT (twin->electrical_param_text[row]), "changed", GTK_SIGNAL_FUNC (setstatus), twin); } }