import gradio as gr import os import numpy as np from groq import Groq from dotenv import load_dotenv import plotly.graph_objects as go # Load API Key load_dotenv() client = Groq(api_key=os.getenv("GROQ_API_KEY")) # Functions for Antenna Calculations def calculate_microstrip_patch(frequency, permittivity, thickness, tangent_loss): c = 3e8 # Speed of light in m/s wavelength = c / frequency effective_wavelength = wavelength / np.sqrt(permittivity) patch_length = effective_wavelength / 2 patch_width = wavelength / (2 * np.sqrt(1 + permittivity)) return patch_length, patch_width, thickness def calculate_dipole(frequency): c = 3e8 # Speed of light in m/s wavelength = c / frequency dipole_length = wavelength / 2 return dipole_length def calculate_s11(frequency): # Simulate S11 (just an example function for demonstration) s11 = -20 + 5 * np.cos(2 * np.pi * frequency / 10) return s11 def calculate_directivity_and_gain(frequency): directivity = 6.0 + 0.5 * np.log10(frequency) # Approximation realized_gain = directivity - 1.5 # Efficiency loss return directivity, realized_gain def radiation_pattern(theta, frequency): gain = 10 * np.log10(np.abs(np.sin(np.radians(theta))) + 1e-9) return gain # Graphing Functions def plot_3d_microstrip_patch(patch_length, patch_width, thickness): fig = go.Figure() # Patch fig.add_trace(go.Surface( z=[[0, 0], [0, 0]], x=[[0, patch_width], [0, patch_width]], y=[[0, 0], [patch_length, patch_length]], colorscale="Viridis", name="Patch" )) # Substrate fig.add_trace(go.Surface( z=[[-thickness, -thickness], [-thickness, -thickness]], x=[[0, patch_width], [0, patch_width]], y=[[0, 0], [patch_length, patch_length]], colorscale="Blues", name="Substrate" )) # Ground fig.add_trace(go.Surface( z=[[-thickness, -thickness], [-thickness, -thickness]], x=[[0, patch_width], [0, patch_width]], y=[[0, 0], [patch_length, patch_length]], colorscale="Greens", name="Ground" )) fig.update_traces(showscale=False) fig.update_layout(title="3D Microstrip Patch Antenna", showlegend=False) return fig def plot_s11_graph(frequencies, s11_values): fig = go.Figure() fig.add_trace(go.Scatter(x=frequencies, y=s11_values, mode='lines', name="S11")) fig.update_layout(title="Frequency vs. S11", xaxis_title="Frequency (GHz)", yaxis_title="S11 (dB)") return fig def plot_directivity_and_gain(frequencies, directivities, gains): fig = go.Figure() fig.add_trace(go.Scatter(x=frequencies, y=directivities, mode='lines', name="Directivity")) fig.add_trace(go.Scatter(x=frequencies, y=gains, mode='lines', name="Realized Gain")) fig.update_layout(title="Frequency vs. Directivity and Realized Gain", xaxis_title="Frequency (GHz)", yaxis_title="Gain (dBi)") return fig def plot_radiation_pattern(theta, gain_pattern): fig = go.Figure() fig.add_trace(go.Scatter(x=theta, y=gain_pattern, mode='lines', name="Radiation Pattern")) fig.update_layout(title="Radiation Pattern", xaxis_title="Degrees", yaxis_title="Gain (dBi)") return fig # Main Function def design_antenna(antenna_type, frequency, permittivity, thickness, tangent_loss, impedance): frequency_hz = frequency * 1e9 frequencies = np.linspace(frequency - 0.5, frequency + 0.5, 100) if antenna_type == "Microstrip Patch": patch_length, patch_width, thickness = calculate_microstrip_patch(frequency_hz, permittivity, thickness, tangent_loss) s11_values = [calculate_s11(f) for f in frequencies] directivities, gains = zip(*[calculate_directivity_and_gain(f) for f in frequencies]) theta = np.linspace(-180, 180, 360) gain_pattern = radiation_pattern(theta, frequency_hz) s11_graph = plot_s11_graph(frequencies, s11_values) directivity_gain_graph = plot_directivity_and_gain(frequencies, directivities, gains) radiation_graph = plot_radiation_pattern(theta, gain_pattern) antenna_3d = plot_3d_microstrip_patch(patch_length, patch_width, thickness) output = ( f"Design Type: Microstrip Patch Antenna\n" f"Operating Frequency: {frequency:.2f} GHz\n" f"S11 at Operating Frequency: {s11_values[len(s11_values)//2]:.2f} dB\n" f"Patch Dimensions: {patch_length:.2f} m x {patch_width:.2f} m x {thickness:.2f} m\n" f"Input Impedance: {impedance} Ohms" ) elif antenna_type == "Dipole": dipole_length = calculate_dipole(frequency_hz) s11_values = [calculate_s11(f) for f in frequencies] directivities, gains = zip(*[calculate_directivity_and_gain(f) for f in frequencies]) theta = np.linspace(-180, 180, 360) gain_pattern = radiation_pattern(theta, frequency_hz) s11_graph = plot_s11_graph(frequencies, s11_values) directivity_gain_graph = plot_directivity_and_gain(frequencies, directivities, gains) radiation_graph = plot_radiation_pattern(theta, gain_pattern) antenna_3d = None # Dipole does not have a 3D plot output = ( f"Design Type: Dipole Antenna\n" f"Operating Frequency: {frequency:.2f} GHz\n" f"S11 at Operating Frequency: {s11_values[len(s11_values)//2]:.2f} dB\n" f"Dipole Length: {dipole_length:.2f} m\n" f"Input Impedance: {impedance} Ohms" ) return output, s11_graph, directivity_gain_graph, radiation_graph, antenna_3d # Gradio Interface with gr.Blocks() as demo: gr.Markdown("# Antenna Design Tool with Groq API") antenna_type = gr.Dropdown(["Microstrip Patch", "Dipole"], label="Select Antenna Type") frequency = gr.Slider(1.0, 10.0, step=0.1, label="Operating Frequency (GHz)") permittivity = gr.Number(value=4.4, label="Substrate Permittivity") thickness = gr.Number(value=0.01, label="Substrate Thickness (m)") tangent_loss = gr.Number(value=0.02, label="Substrate Tangent Loss (tan δ)", step=0.01) impedance = gr.Dropdown([50, 73], label="Input Impedance (Ohms)", value=50) design_button = gr.Button("Design Antenna") output_text = gr.Textbox(label="Design Results") s11_plot = gr.Plot(label="S11 Plot") directivity_gain_plot = gr.Plot(label="Directivity and Gain Plot") radiation_pattern_plot = gr.Plot(label="Radiation Pattern") antenna_3d_display = gr.Plot(label="3D Antenna Visualization") design_button.click( design_antenna, inputs=[antenna_type, frequency, permittivity, thickness, tangent_loss, impedance], outputs=[output_text, s11_plot, directivity_gain_plot, radiation_pattern_plot, antenna_3d_display] ) demo.launch()