To solve this problem, we first need to define the decision variables and the objective function. Let's denote the number of acres grown with ylang ylang as \(Y\) and the number of acres grown with vanilla as \(V\). The profit per acre for ylang ylang is $150, and for vanilla, it is $100. Therefore, the total profit can be represented as \(150Y + 100V\).

The constraints given are:
1. The producer must grow at least 10 acres of ylang ylang: \(Y \geq 10\)
2. The producer must grow at least 20 acres of vanilla: \(V \geq 20\)
3. The total land available is 100 acres: \(Y + V \leq 100\)
4. The amount of ylang ylang grown cannot be more than twice the amount of vanilla: \(Y \leq 2V\)

The objective is to maximize the profit, which means we want to find the values of \(Y\) and \(V\) that make \(150Y + 100V\) as large as possible under these constraints.

Here's how we can represent this problem in Gurobi using Python:

```python
from gurobipy import *

# Create a model
m = Model("Essential_Oil_Producer")

# Define the decision variables
Y = m.addVar(vtype=GRB.CONTINUOUS, name="Ylang_Ylang_Acres")
V = m.addVar(vtype=GRB.CONTINUOUS, name="Vanilla_Acres")

# Set the objective function to maximize profit
m.setObjective(150*Y + 100*V, GRB.MAXIMIZE)

# Add constraints
m.addConstr(Y >= 10, "Min_Ylang_Ylang")
m.addConstr(V >= 20, "Min_Vanilla")
m.addConstr(Y + V <= 100, "Total_Land")
m.addConstr(Y <= 2*V, "Ylang_to_Vanilla_Ratio")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Ylang Ylang Acres: {Y.x}")
    print(f"Vanilla Acres: {V.x}")
    print(f"Total Profit: ${150*Y.x + 100*V.x:.2f}")
else:
    print("No optimal solution found")
```