spice21/comps/bsim4/
tran.rs

1use super::{Bsim4, Bsim4OpPoint};
2use crate::analysis::TranState;
3
4impl Bsim4 {
5    ///
6    /// Given the DC portion of an operating point,
7    /// add transient impedances and currents for all time-varying components
8    /// Argument `newop` is the partially-completed operating point,
9    /// with its (admittedly ill-defined) DC and charge parameters set.
10    ///
11    pub(crate) fn tran_op(&self, newop: &mut Bsim4OpPoint, tran_state: &TranState) {
12        let nqs_scaling_factor = 1.0e-9; // FIXME: lump this in an NQS thing
13
14        // Initially zero all capacitances and their impedances
15        // Many complicated paths through the code below do not assure they are otherwise initialized.
16        
17        let mut ceqqjd = 0.0;
18        let mut ceqqjs = 0.0;
19        let mut cqcheq = 0.0;
20        let mut cqdef = 0.0;
21
22        let mut gcdgb = 0.0;
23        let mut gcddb = 0.0;
24        let mut gcdsb = 0.0;
25        let mut gcdbb = 0.0;
26        let mut gcsgb = 0.0;
27        let mut gcsdb = 0.0;
28        let mut gcssb = 0.0;
29        let mut gcsbb = 0.0;
30        let mut gcggb = 0.0;
31        let mut gcgdb = 0.0;
32        let mut gcgsb = 0.0;
33        let mut gcgbb = 0.0;
34        let mut gcbdb = 0.0;
35        let mut gcbgb = 0.0;
36        let mut gcbsb = 0.0;
37        let mut gcbbb = 0.0;
38
39        let mut gcgmgmb = 0.0;
40        let mut gcgmdb = 0.0;
41        let mut gcgmsb = 0.0;
42        let mut gcgmbb = 0.0;
43        let mut gcdgmb = 0.0;
44        let mut gcsgmb = 0.0;
45        let mut gcbgmb = 0.0;
46        let mut gcdbdb = 0.0;
47        let mut gcsbsb = 0.0;
48
49        let mut gqdef = 0.0;
50        let mut gcqgb = 0.0;
51        let mut gcqdb = 0.0;
52        let mut gcqsb = 0.0;
53        let mut gcqbb = 0.0;
54        let mut ggtg = 0.0;
55        let mut ggtd = 0.0;
56        let mut ggtb = 0.0;
57        let mut ggts = 0.0;
58        let mut dxpart = if newop.mode > 0 { 0.4 } else { 0.6 };
59        let mut sxpart = 1.0 - dxpart;
60        let mut ddxpart_dVd = 0.0;
61        let mut ddxpart_dVg = 0.0;
62        let mut ddxpart_dVb = 0.0;
63        let mut ddxpart_dVs = 0.0;
64        let mut dsxpart_dVd = 0.0;
65        let mut dsxpart_dVg = 0.0;
66        let mut dsxpart_dVb = 0.0;
67        let mut dsxpart_dVs = 0.0;
68
69        let Bsim4OpPoint { qdrn, qgdo, qgso, qdef, .. } = *newop;
70        let Bsim4OpPoint { cgdo, cgso, .. } = *newop;
71        let Bsim4OpPoint {
72            vbs,
73            vbd,
74            vgb,
75            vgmb,
76            vbs_jct,
77            vbd_jct,
78            ..
79        } = *newop;
80
81        // TODO: the BSIM4 reference implementation essentially bakes numerical integration in here,
82        // ignoring the circuit/ analysis integration method.
83        // All of these impedances are calculated as g = C/dt, e.g. using Backward Euler.
84        // Figure out whether this is the implementation intent, or just for reference.
85
86        let ag0 = 1.0 / tran_state.dt;
87        if newop.mode > 0 {
88            if self.model.trnqsmod == 0 {
89                if self.model.rgatemod == 3 {
90                    gcgmgmb = (cgdo + cgso + self.size_params.cgbo) * ag0;
91                    gcgmdb = -cgdo * ag0;
92                    gcgmsb = -cgso * ag0;
93                    gcgmbb = -self.size_params.cgbo * ag0;
94
95                    gcdgmb = gcgmdb;
96                    gcsgmb = gcgmsb;
97                    gcbgmb = gcgmbb;
98
99                    gcggb = newop.cggb * ag0;
100                    gcgdb = newop.cgdb * ag0;
101                    gcgsb = newop.cgsb * ag0;
102                    gcgbb = -(gcggb + gcgdb + gcgsb);
103
104                    gcdgb = newop.cdgb * ag0;
105                    gcsgb = -(newop.cggb + newop.cbgb + newop.cdgb) * ag0;
106                    gcbgb = newop.cbgb * ag0; 
107                } else {
108                    // Default rgatemod==0
109                    gcggb = (newop.cggb + cgdo + cgso + self.size_params.cgbo) * ag0;
110                    gcgdb = (newop.cgdb - cgdo) * ag0;
111                    gcgsb = (newop.cgsb - cgso) * ag0;
112                    gcgbb = -(gcggb + gcgdb + gcgsb);
113
114                    gcdgb = (newop.cdgb - cgdo) * ag0;
115                    gcsgb = -(newop.cggb + newop.cbgb + newop.cdgb + cgso) * ag0;
116                    gcbgb = (newop.cbgb - self.size_params.cgbo) * ag0;
117
118                    gcdgmb = 0.0;
119                    gcsgmb = 0.0;
120                    gcbgmb = 0.0; 
121                }
122                gcddb = (newop.cddb + newop.capbd + cgdo) * ag0;
123                gcdsb = newop.cdsb * ag0;
124
125                gcsdb = -(newop.cgdb + newop.cbdb + newop.cddb) * ag0;
126                gcssb = (newop.capbs + cgso - (newop.cgsb + newop.cbsb + newop.cdsb)) * ag0;
127
128                if self.model.rbodymod == 0 {
129                    // Default model
130                    gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb);
131                    gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb);
132                    gcbdb = (newop.cbdb - newop.capbd) * ag0;
133                    gcbsb = (newop.cbsb - newop.capbs) * ag0;
134                    gcdbdb = 0.0;
135                    gcsbsb = 0.0;
136                } else {
137                    gcdbb = -(newop.cddb + newop.cdgb + newop.cdsb) * ag0;
138                    gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb) + newop.capbs * ag0;
139                    gcbdb = newop.cbdb * ag0;
140                    gcbsb = newop.cbsb * ag0;
141
142                    gcdbdb = -newop.capbd * ag0;
143                    gcsbsb = -newop.capbs * ag0;
144                }
145                gcbbb = -(gcbdb + gcbgb + gcbsb + gcbgmb);
146
147                ggtg = 0.0;
148                ggtd = 0.0;
149                ggtb = 0.0;
150                ggts = 0.0;
151                sxpart = 0.6;
152                dxpart = 0.4;
153                ddxpart_dVd = 0.0;
154                ddxpart_dVg = 0.0;
155                ddxpart_dVb = 0.0;
156                ddxpart_dVs = 0.0;
157                dsxpart_dVd = 0.0;
158                dsxpart_dVg = 0.0;
159                dsxpart_dVb = 0.0;
160                dsxpart_dVs = 0.0;
161            } else {
162                let qcheq = newop.qchqs;
163                let CoxWL = self.model_derived.coxe * self.size_params.weffCV * self.intp.nf * self.size_params.leffCV;
164                let T0 = qdef * nqs_scaling_factor / CoxWL;
165
166                ggtg = T0 * newop.gcrgg;
167                newop.gtg = ggtg;
168                ggtd = T0 * newop.gcrgd;
169                newop.gtd = ggtd;
170                ggts = T0 * newop.gcrgs;
171                newop.gts = ggts;
172                ggtb = T0 * newop.gcrgb;
173                newop.gtb = ggtb;
174                gqdef = nqs_scaling_factor * ag0;
175
176                gcqgb = newop.cqgb * ag0;
177                gcqdb = newop.cqdb * ag0;
178                gcqsb = newop.cqsb * ag0;
179                gcqbb = newop.cqbb * ag0;
180
181                if qcheq.abs() <= 1.0e-5 * CoxWL {
182                    if self.model.xpart < 0.5 {
183                        dxpart = 0.4;
184                    } else if self.model.xpart > 0.5 {
185                        dxpart = 0.0;
186                    } else {
187                        dxpart = 0.5;
188                    }
189                    ddxpart_dVd = 0.0;
190                    ddxpart_dVg = 0.0;
191                    ddxpart_dVb = 0.0;
192                    ddxpart_dVs = 0.0;
193                } else {
194                    dxpart = qdrn / qcheq;
195                    let Cdd = newop.cddb;
196                    let Csd = -(newop.cgdb + newop.cddb + newop.cbdb);
197                    ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
198                    let Cdg = newop.cdgb;
199                    let Csg = -(newop.cggb + newop.cdgb + newop.cbgb);
200                    ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
201
202                    let Cds = newop.cdsb;
203                    let Css = -(newop.cgsb + newop.cdsb + newop.cbsb);
204                    ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
205
206                    ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
207                }
208                sxpart = 1.0 - dxpart;
209                dsxpart_dVd = -ddxpart_dVd;
210                dsxpart_dVg = -ddxpart_dVg;
211                dsxpart_dVs = -ddxpart_dVs;
212                dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
213
214                if self.model.rgatemod == 3 {
215                    gcgmgmb = (cgdo + cgso + self.size_params.cgbo) * ag0;
216                    gcgmdb = -cgdo * ag0;
217                    gcgmsb = -cgso * ag0;
218                    gcgmbb = -self.size_params.cgbo * ag0;
219
220                    gcdgmb = gcgmdb;
221                    gcsgmb = gcgmsb;
222                    gcbgmb = gcgmbb;
223
224                    gcdgb = 0.0;
225                    gcsgb = 0.0;
226                    gcbgb = 0.0;
227                    gcggb = 0.0;
228                    gcgdb = 0.0;
229                    gcgsb = 0.0;
230                    gcgbb = 0.0; 
231                } else {
232                    gcggb = (cgdo + cgso + self.size_params.cgbo) * ag0;
233                    gcgdb = -cgdo * ag0;
234                    gcgsb = -cgso * ag0;
235                    gcgbb = -self.size_params.cgbo * ag0;
236
237                    gcdgb = gcgdb;
238                    gcsgb = gcgsb;
239                    gcbgb = gcgbb;
240                    gcdgmb = 0.0;
241                    gcsgmb = 0.0;
242                    gcbgmb = 0.0; 
243                }
244
245                gcddb = (newop.capbd + cgdo) * ag0;
246                gcdsb = 0.0;
247                gcsdb = 0.0;
248                gcssb = (newop.capbs + cgso) * ag0;
249
250                if self.model.rbodymod == 0 {
251                    gcdbb = -(gcdgb + gcddb + gcdgmb);
252                    gcsbb = -(gcsgb + gcssb + gcsgmb);
253                    gcbdb = -newop.capbd * ag0;
254                    gcbsb = -newop.capbs * ag0;
255                    gcdbdb = 0.0;
256                    gcsbsb = 0.0;
257                } else {
258                    gcdbb = 0.0;
259                    gcsbb = 0.0;
260                    gcbdb = 0.0;
261                    gcbsb = 0.0;
262                    gcdbdb = -newop.capbd * ag0;
263                    gcsbsb = -newop.capbs * ag0;
264                }
265                gcbbb = -(gcbdb + gcbgb + gcbsb + gcbgmb);
266            }
267        } else {
268            if self.model.trnqsmod == 0 {
269                if self.model.rgatemod == 3 {
270                    gcgmgmb = (cgdo + cgso + self.size_params.cgbo) * ag0;
271                    gcgmdb = -cgdo * ag0;
272                    gcgmsb = -cgso * ag0;
273                    gcgmbb = -self.size_params.cgbo * ag0;
274
275                    gcdgmb = gcgmdb;
276                    gcsgmb = gcgmsb;
277                    gcbgmb = gcgmbb;
278
279                    gcggb = newop.cggb * ag0;
280                    gcgdb = newop.cgsb * ag0;
281                    gcgsb = newop.cgdb * ag0;
282                    gcgbb = -(gcggb + gcgdb + gcgsb);
283
284                    gcdgb = -(newop.cggb + newop.cbgb + newop.cdgb) * ag0;
285                    gcsgb = newop.cdgb * ag0;
286                    gcbgb = newop.cbgb * ag0; 
287                } else {
288                    gcggb = (newop.cggb + cgdo + cgso + self.size_params.cgbo) * ag0;
289                    gcgdb = (newop.cgsb - cgdo) * ag0;
290                    gcgsb = (newop.cgdb - cgso) * ag0;
291                    gcgbb = -(gcggb + gcgdb + gcgsb);
292
293                    gcdgb = -(newop.cggb + newop.cbgb + newop.cdgb + cgdo) * ag0;
294                    gcsgb = (newop.cdgb - cgso) * ag0;
295                    gcbgb = (newop.cbgb - self.size_params.cgbo) * ag0;
296
297                    gcdgmb = 0.0;
298                    gcsgmb = 0.0;
299                    gcbgmb = 0.0; 
300                }
301                gcddb = (newop.capbd + cgdo - (newop.cgsb + newop.cbsb + newop.cdsb)) * ag0;
302                gcdsb = -(newop.cgdb + newop.cbdb + newop.cddb) * ag0;
303
304                gcsdb = newop.cdsb * ag0;
305                gcssb = (newop.cddb + newop.capbs + cgso) * ag0;
306
307                if self.model.rbodymod == 0 {
308                    gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb);
309                    gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb);
310                    gcbdb = (newop.cbsb - newop.capbd) * ag0;
311                    gcbsb = (newop.cbdb - newop.capbs) * ag0;
312                    gcdbdb = 0.0;
313                    gcsbsb = 0.0;
314                } else {
315                    gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb) + newop.capbd * ag0;
316                    gcsbb = -(newop.cddb + newop.cdgb + newop.cdsb) * ag0;
317                    gcbdb = newop.cbsb * ag0;
318                    gcbsb = newop.cbdb * ag0;
319                    gcdbdb = -newop.capbd * ag0;
320                    gcsbsb = -newop.capbs * ag0;
321                }
322                gcbbb = -(gcbgb + gcbdb + gcbsb + gcbgmb);
323
324                ggtg = 0.0;
325                ggtd = 0.0;
326                ggtb = 0.0;
327                ggts = 0.0;
328                sxpart = 0.4;
329                dxpart = 0.6;
330                ddxpart_dVd = 0.0;
331                ddxpart_dVg = 0.0;
332                ddxpart_dVb = 0.0;
333                ddxpart_dVs = 0.0;
334                dsxpart_dVd = 0.0;
335                dsxpart_dVg = 0.0;
336                dsxpart_dVb = 0.0;
337                dsxpart_dVs = 0.0;
338            } else {
339                let qcheq = newop.qchqs;
340                let CoxWL = self.model_derived.coxe * self.size_params.weffCV * self.intp.nf * self.size_params.leffCV;
341                let T0 = qdef * nqs_scaling_factor / CoxWL;
342                ggtg = T0 * newop.gcrgg;
343                newop.gtg = ggtg;
344                ggts = T0 * newop.gcrgd;
345                newop.gts = ggts;
346                ggtd = T0 * newop.gcrgs;
347                newop.gtd = ggtd;
348                ggtb = T0 * newop.gcrgb;
349                newop.gtb = ggtb;
350                gqdef = nqs_scaling_factor * ag0;
351
352                gcqgb = newop.cqgb * ag0;
353                gcqdb = newop.cqsb * ag0;
354                gcqsb = newop.cqdb * ag0;
355                gcqbb = newop.cqbb * ag0;
356
357                if qcheq.abs() <= 1.0e-5 * CoxWL {
358                    if self.model.xpart < 0.5 {
359                        sxpart = 0.4;
360                    } else if self.model.xpart > 0.5 {
361                        sxpart = 0.0;
362                    } else {
363                        sxpart = 0.5;
364                    }
365                    dsxpart_dVd = 0.0;
366                    dsxpart_dVg = 0.0;
367                    dsxpart_dVb = 0.0;
368                    dsxpart_dVs = 0.0;
369                } else {
370                    sxpart = qdrn / qcheq;
371                    let Css = newop.cddb;
372                    let Cds = -(newop.cgdb + newop.cddb + newop.cbdb);
373                    dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
374                    let Csg = newop.cdgb;
375                    let Cdg = -(newop.cggb + newop.cdgb + newop.cbgb);
376                    dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
377
378                    let Csd = newop.cdsb;
379                    let Cdd = -(newop.cgsb + newop.cdsb + newop.cbs);
380                    dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
381
382                    dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
383                }
384                dxpart = 1.0 - sxpart;
385                ddxpart_dVd = -dsxpart_dVd;
386                ddxpart_dVg = -dsxpart_dVg;
387                ddxpart_dVs = -dsxpart_dVs;
388                ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
389
390                if self.model.rgatemod == 3 {
391                    gcgmgmb = (cgdo + cgso + self.size_params.cgbo) * ag0;
392                    gcgmdb = -cgdo * ag0;
393                    gcgmsb = -cgso * ag0;
394                    gcgmbb = -self.size_params.cgbo * ag0;
395
396                    gcdgmb = gcgmdb;
397                    gcsgmb = gcgmsb;
398                    gcbgmb = gcgmbb;
399
400                    gcdgb = 0.0;
401                    gcsgb = 0.0;
402                    gcbgb = 0.0;
403                    gcggb = 0.0;
404                    gcgdb = 0.0;
405                    gcgsb = 0.0;
406                    gcgbb = 0.0; 
407                } else {
408                    gcggb = (cgdo + cgso + self.size_params.cgbo) * ag0;
409                    gcgdb = -cgdo * ag0;
410                    gcgsb = -cgso * ag0;
411                    gcgbb = -self.size_params.cgbo * ag0;
412
413                    gcdgb = gcgdb;
414                    gcsgb = gcgsb;
415                    gcbgb = gcgbb;
416                    gcdgmb = 0.0;
417                    gcsgmb = 0.0;
418                    gcbgmb = 0.0; 
419                }
420
421                gcddb = (newop.capbd + cgdo) * ag0;
422                gcdsb = 0.0;
423                gcsdb = 0.0;
424                gcssb = (newop.capbs + cgso) * ag0;
425                if self.model.rbodymod == 0 {
426                    gcdbb = -(gcdgb + gcddb + gcdgmb);
427                    gcsbb = -(gcsgb + gcssb + gcsgmb);
428                    gcbdb = -newop.capbd * ag0;
429                    gcbsb = -newop.capbs * ag0;
430                    gcdbdb = 0.0;
431                    gcsbsb = 0.0;
432                } else {
433                    gcdbb = 0.0;
434                    gcsbb = 0.0;
435                    gcbdb = 0.0;
436                    gcbsb = 0.0;
437                    gcdbdb = -newop.capbd * ag0;
438                    gcsbsb = -newop.capbs * ag0;
439                }
440                gcbbb = -(gcbdb + gcbgb + gcbsb + gcbgmb);
441            }
442        } 
443
444        // We borrow the BSIM4 reference implementation's practice here,
445        // of only using numerical integration to calculate `i = dq/dt`,
446        // Ignoring the impedance and RHS terms it calculates.
447        let (_g, i, _r) = tran_state.integrate(newop.qb - self.op.qb, 0.0, 0.0, self.op.cqb);
448        newop.cqb = i;
449        let (_g, i, _r) = tran_state.integrate(newop.qg - self.op.qg, 0.0, 0.0, self.op.cqg);
450        newop.cqg = i;
451        let (_g, i, _r) = tran_state.integrate(newop.qd - self.op.qd, 0.0, 0.0, self.op.cqd);
452        newop.cqd = i;
453        if self.model.trnqsmod != 0 {
454            newop.qcdump = qdef * nqs_scaling_factor;
455            let (_g, i, _r) = tran_state.integrate(newop.qcdump - self.op.qcdump, 0.0, 0.0, self.op.cqcdump);
456            newop.cqcdump = i;
457        }
458        if self.model.rgatemod == 3 {
459            let (_g, i, _r) = tran_state.integrate(newop.qgmid - self.op.qgmid, 0.0, 0.0, self.op.cqgmid);
460            newop.cqgmid = i;
461        }
462        if self.model.rbodymod != 0 {
463            let (_g, i, _r) = tran_state.integrate(newop.qbs - self.op.qbs, 0.0, 0.0, self.op.cqbs);
464            newop.cqbs = i;
465            let (_g, i, _r) = tran_state.integrate(newop.qbd - self.op.qbd, 0.0, 0.0, self.op.cqbd);
466            newop.cqbd = i;
467        }
468
469        // Calculate equivalent RHS current
470        let cqgate = newop.cqg;
471        let cqbody = newop.cqb;
472        let cqdrn = newop.cqd;
473
474        let mut ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
475        let mut ceqqd = cqdrn - gcdgb * vgb - gcdgmb * vgmb + (gcddb + gcdbdb) * vbd - gcdbdb * vbd_jct + gcdsb * vbs;
476        let mut ceqqb = cqbody - gcbgb * vgb - gcbgmb * vgmb + gcbdb * vbd + gcbsb * vbs;
477
478        if self.model.rgatemod == 3 {
479            newop.ceqqgmid = newop.cqgmid + gcgmdb * vbd + gcgmsb * vbs - gcgmgmb * vgmb;
480        }
481        if self.model.rbodymod != 0 {
482            newop.ceqqjs = newop.cqbs + gcsbsb * vbs_jct;
483            newop.ceqqjd = newop.cqbd + gcdbdb * vbd_jct;
484        }
485
486        if self.model.trnqsmod != 0 {
487            let (_g, i, _r) = tran_state.integrate(newop.qcheq - self.op.qcheq, 0.0, 0.0, self.op.cqcheq);
488            newop.cqcheq = i;
489
490            let T0 = ggtg * vgb - ggtd * vbd - ggts * vbs;
491            ceqqg += T0;
492            let T1 = qdef * newop.gtau;
493            ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd * vbd - ddxpart_dVs * vbs);
494            cqdef = newop.cqcdump - gqdef * qdef;
495            cqcheq = newop.cqcheq - (gcqgb * vgb - gcqdb * vbd - gcqsb * vbs) + T0;
496        }
497
498        newop.gqdef = gqdef;
499        newop.ggtg = ggtg;
500        newop.ggtd = ggtd;
501        newop.ggts = ggts;
502        newop.ggtb = ggtb;
503        newop.gcsbsb = gcsbsb;
504        newop.gcsbsb = gcsbsb;
505        newop.gcqsb = gcqsb;
506        newop.gcqdb = gcqdb;
507        newop.gcqgb = gcqgb;
508        newop.cqcheq = cqcheq;
509        newop.cqdef = cqdef;
510        newop.gcqbb = gcqbb;
511        newop.ceqqg = ceqqg;
512        newop.ceqqd = ceqqd;
513        newop.ceqqb = ceqqb;
514        newop.gcgbb = gcgbb;
515        newop.gcsbb = gcsbb;
516        newop.gcssb = gcssb;
517        newop.gcsgb = gcsgb;
518        newop.gcsdb = gcsdb;
519        newop.gcdbb = gcdbb;
520        newop.gcggb = gcggb;
521        newop.gcgdb = gcgdb;
522        newop.gcgsb = gcgsb;
523        newop.gcgsb = gcgsb;
524        newop.gcgmgmb = gcgmgmb;
525        newop.gcgmsb = gcgmsb;
526        newop.gcgmdb = gcgmdb;
527        newop.gcgmbb = gcgmbb;
528        newop.gcdgmb = gcdgmb;
529        newop.gcsgmb = gcsgmb;
530        newop.ddxpart_dVd = ddxpart_dVd;
531        newop.ddxpart_dVs = ddxpart_dVs;
532        newop.ddxpart_dVb = ddxpart_dVb;
533        newop.dsxpart_dVb = dsxpart_dVb;
534        newop.dsxpart_dVs = dsxpart_dVs;
535        newop.dsxpart_dVg = dsxpart_dVg;
536        newop.dsxpart_dVd = dsxpart_dVd;
537        newop.ddxpart_dVg = ddxpart_dVg;
538        newop.gcgmdb = gcgmdb;
539        newop.gcbgmb = gcbgmb;
540        newop.gcddb = gcddb;
541        newop.gcdgb = gcdgb;
542        newop.gcdsb = gcdsb;
543        newop.gcbdb = gcbdb;
544        newop.gcbgb = gcbgb;
545        newop.gcbsb = gcbsb;
546        newop.gcbbb = gcbbb;
547        newop.dxpart = dxpart;
548        newop.sxpart = sxpart;
549    }
550}