Repository: Qiskit/qiskit

Issue:
The copy method of quantum circuit does not update the circuit name
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Informations

- **Qiskit Terra version**: the master branch
- **Python version**: 3.7.1
- **Operating system**: macOS 10.13

### What is the current behavior?
The introduced `copy` method did not update the circuit name of the copy.


### Steps to reproduce the problem
Here is the script
```python
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit import compile, execute
from qiskit import Aer

qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc = QuantumCircuit(qr, cr)
qc.h(qr[0])

qc2 = qc.copy()
qc2.cx(qr[0], qr[1])

print(qc.name)
print(qc2.name)

job = execute([qc, qc2], backend=Aer.get_backend('statevector_simulator'))
result = job.result()

res_qc = result.get_statevector(qc)
res_qc2 = result.get_statevector(qc2)

print(res_qc)
print(res_qc2)
```

```
circuit0
circuit0
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
[0.70710678+0.j 0.70710678+0.j 0.        +0.j 0.        +0.j]
```

The `res_qc` and `res_qc2` are the same since the `get_statevector` method retrieves results by circuit name.

### What is the expected behavior?
The copied circuit should have a new name.


### Suggested solutions
Based on the constructor to create a new name.
```python
def copy(self):
        """ Returns a deepcopy of the circuit"""
        qc = deepcopy(self)
        name = self.cls_prefix() + str(self.cls_instances())
        # pylint: disable=not-callable
        # (known pylint bug: https://github.com/PyCQA/pylint/issues/1699)
        if sys.platform != "win32" and \
           isinstance(mp.current_process(), mp.context.ForkProcess):
            name += '-{}'.format(mp.current_process().pid)
        self._increment_instances()
        qc.name = name
        # update the name of circuit.
        return qc
```

If it is okay, I can issue an PR to fix it. Thanks.



Discussion:
Hmm... This bring the issue of the meaning of copy. What would you think about something like `qc2 = qc.copy(name='aNewName')`?
@chunfuchen also you can just retrieve result by index (of your execution list):
```
get_statevector(1)
```
Maybe I misunderstand the intention to have the `copy` method but I think the above script would be used if users want to save the line to create the same circuit and then add more gates on top of that.

I always used `qc2 = qc + QuantumCircuit()` to create another circuit with the same registers and gates but with different name. 

@ajavadia yes, your suggestion works.

I can still use my old way to get a circuit whose registers and gates are identical to the other one.
The copy method was based on the request in #1688, and so was simply meant to be a deep copy of the circuit which suggests the name should be maintained. I think an approach such as the one @1ucian0 suggested could be beneficial though.  
Is there a use case for coping with a new name? CC @nonhermitian, as the #1688 submitter. Otherwise, we can close this as `wont fix`
I personally use the copy for creating circuits with and without measurements. I do not think that I have ever used the curcuit name as an index. 
In that case, I would go with the optional parameter with the name, defaulting in the same name as source circuit. Agreed?
I think it is good to have that. @1ucian0 

Resolving patch:
diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py
--- a/qiskit/circuit/quantumcircuit.py
+++ b/qiskit/circuit/quantumcircuit.py
@@ -388,9 +388,18 @@ def num_tensor_factors(self):
         dag = circuit_to_dag(self)
         return dag.num_tensor_factors()
 
-    def copy(self):
-        """ Returns a deepcopy of the circuit"""
-        return deepcopy(self)
+    def copy(self, name=None):
+        """
+        Args:
+          name (str): name to be given to the copied circuit, if None then the name stays the same
+        Returns:
+          QuantumCircuit: a deepcopy of the current circuit, with the name updated if
+                          it was provided
+        """
+        cpy = deepcopy(self)
+        if name:
+            cpy.name = name
+        return cpy
 
     @staticmethod
     def from_qasm_file(path):


Test patch: