File size: 6,955 Bytes
3a2281e
 
 
 
 
 
 
 
 
 
 
 
a47b35c
3a2281e
 
 
 
 
86383ac
3a2281e
a47b35c
688a3e3
 
a47b35c
688a3e3
 
3a2281e
86383ac
3a2281e
 
 
 
 
 
 
50e6e92
 
 
 
 
3a2281e
 
 
 
 
50e6e92
 
 
 
 
 
 
 
 
 
3a2281e
50e6e92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a2281e
50e6e92
 
 
 
 
 
 
 
 
3a2281e
 
 
 
 
 
 
 
 
 
 
 
86383ac
3a2281e
 
 
 
 
 
 
 
 
 
b9367b8
3a2281e
86383ac
50e6e92
86383ac
3a2281e
86383ac
 
 
50e6e92
3a2281e
 
50e6e92
86383ac
 
a47b35c
3a2281e
688a3e3
a47b35c
50e6e92
 
688a3e3
50e6e92
86383ac
a47b35c
688a3e3
50e6e92
 
 
 
 
 
3a2281e
 
 
 
 
86383ac
688a3e3
3a2281e
 
 
86383ac
a47b35c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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, tangent_loss

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):
    s11 = -20 + 5 * np.cos(2 * np.pi * frequency / 10)  # Mock S11 values
    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, antenna_type):
    if antenna_type == "Microstrip Patch":
        gain = 10 * np.log10(np.abs(np.sin(np.radians(theta))) + 1e-9) * frequency / 1e9
    elif antenna_type == "Dipole":
        gain = 10 * np.log10(np.abs(np.cos(np.radians(theta))) ** 2 + 1e-9)
    return gain

# Graphing Functions
def plot_3d_microstrip_patch(patch_length, patch_width, thickness):
    fig = go.Figure()

    # Substrate
    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="Blues", name="Substrate"
    ))

    # Patch (on upper layer of 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="Viridis", name="Radiation Patch"
    ))

    # Ground (on lower layer of 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="Greens", name="Ground Plane"
    ))

    fig.update_traces(showscale=False)
    fig.update_layout(title="3D Microstrip Patch Antenna", showlegend=True)
    return fig

def plot_3d_dipole(dipole_length):
    fig = go.Figure()

    # Dipole elements
    fig.add_trace(go.Scatter3d(
        x=[0, dipole_length / 2, 0, -dipole_length / 2],
        y=[0, 0, 0, 0],
        z=[0, 0, 0, 0],
        mode="lines+markers",
        line=dict(color="blue", width=5),
        name="Dipole Elements"
    ))

    fig.update_layout(
        title="3D Dipole Antenna",
        scene=dict(
            xaxis_title="X-axis",
            yaxis_title="Y-axis",
            zaxis_title="Z-axis"
        )
    )
    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 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) * 1e9  # Adjust to Hz
    theta = np.linspace(-180, 180, 360)

    if antenna_type == "Microstrip Patch":
        patch_length, patch_width, thickness, tangent_loss = calculate_microstrip_patch(
            frequency_hz, permittivity, thickness, tangent_loss
        )
        radiation_gain = radiation_pattern(theta, frequency_hz, antenna_type)
        antenna_3d = plot_3d_microstrip_patch(patch_length, patch_width, thickness)
        output = (
            f"Microstrip Patch Antenna\n"
            f"Patch Dimensions: {patch_length:.3f} m x {patch_width:.3f} m x {thickness:.3f} m\n"
            f"Tangent Loss: {tangent_loss}\n"
            f"Input Impedance: {impedance} Ohms"
        )
    elif antenna_type == "Dipole":
        dipole_length = calculate_dipole(frequency_hz)
        radiation_gain = radiation_pattern(theta, frequency_hz, antenna_type)
        antenna_3d = plot_3d_dipole(dipole_length)
        output = (
            f"Dipole Antenna\n"
            f"Dipole Length: {dipole_length:.3f} m\n"
            f"Input Impedance: {impedance} Ohms"
        )

    s11_values = [calculate_s11(f) for f in frequencies]
    directivities, gains = zip(*[calculate_directivity_and_gain(f) for f in frequencies])
    s11_graph = plot_s11_graph(frequencies / 1e9, s11_values)
    directivity_gain_graph = plot_directivity_and_gain(frequencies / 1e9, directivities, gains)
    radiation_graph = plot_radiation_pattern(theta, radiation_gain)
    
    return output, s11_graph, directivity_gain_graph, radiation_graph, antenna_3d

# Gradio Interface
with gr.Blocks() as demo:
    gr.Markdown("# Antenna Design Tool")
    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="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()